-- GetItemTransmogrifyInfo(item link/item id/item name)
 --   returns: canBeChanged, noChangeReason, canBeSource, noSourceReason
 -- CanTransmogrifyItemWithItem(target item link/target item id/target item name, source item link/source item id/source item name)
 --   returns: canBeTransmogrified, failReason
 
 UIPanelWindows["TransmogrifyFrame"] =	{ area = "left", pushable = 0 };
 
 local FLYOUT_BUTTON_HIDE_DELAY_TIME = 0.1;
 
 local BUTTONS = { };
 
 function TransmogrifyFrame_Show()
 	ShowUIPanel(TransmogrifyFrame);
 	if ( not TransmogrifyFrame:IsShown() ) then
 		CloseTransmogrifyFrame();
 	end
 end
 
 function TransmogrifyFrame_Hide()
 	HideUIPanel(TransmogrifyFrame);
 end
 
 function TransmogrifyFrame_OnLoad(self)
 	TransmogrifyArtFrameTitleText:SetText(TRANSMOGRIFY);
 	TransmogrifyArtFrameTitleBg:SetDrawLayer("BACKGROUND", -1);
 	TransmogrifyArtFrameTopTileStreaks:Hide();
 	TransmogrifyArtFrameBg:Hide();
 	SetPortraitToTexture(TransmogrifyArtFramePortrait, "Interface\\Icons\\INV_Arcane_Orb");
 
 	RaiseFrameLevel(TransmogrifyArtFrame);
 	RaiseFrameLevelByTwo(TransmogrifyFrameButtonFrame);
 	TransmogrifyArtFrameCloseButton:SetScript("OnClick", function() HideUIPanel(TransmogrifyFrame); end);
 	
 	self:RegisterEvent("TRANSMOGRIFY_UPDATE");
 	self:RegisterEvent("TRANSMOGRIFY_SUCCESS");
 	self:RegisterEvent("TRANSMOGRIFY_BIND_CONFIRM");
 
 	-- flyout settings
 	self.flyoutSettings = {
 		onClickFunc = TransmogrifyItemFlyoutButton_OnClick,
 		getItemsFunc =  TransmogrifyItemFlyout_GetItems,
 		hasPopouts = false,
 		parent = TransmogrifyFrame,
 		anchorX = 0,
 		anchorY = -3,
 		verticalAnchorX = 0,
 		verticalAnchorY = 0,
 		keepShownOnClick = true,
 	};
 end
 
 function TransmogrifyFrame_OnEvent(self, event, ...)
 	if ( event == "TRANSMOGRIFY_UPDATE" ) then
 		local slot = ...;
 		-- play sound?
 		local button = BUTTONS[slot];
 		if ( button ) then
 			local isTransmogrified, canTransmogrify, cannotTransmogrifyReason, hasPending, hasUndo = GetTransmogrifySlotInfo(button.id);
 			if ( hasUndo ) then
 				PlaySound("UI_Transmogrify_Undo");
 			elseif ( not hasPending ) then
 				if ( button.hadUndo ) then
 					PlaySound("UI_Transmogrify_Redo");
 					button.hadUndo = nil;
 				end
 			end
 		end
 		if ( TransmogrifyConfirmationPopup:IsShown() and TransmogrifyConfirmationPopup.slot == slot ) then
 			TransmogrifyConfirmationPopup.slot = nil;		-- to keep popup from clearing slot on hide
 			StaticPopupSpecial_Hide(TransmogrifyConfirmationPopup);
 		end
 		TransmogrifyFrame_Update(self);
 	elseif ( event == "BAG_UPDATE" ) then
 		ValidateTransmogrifications();
 	elseif ( event == "PLAYER_EQUIPMENT_CHANGED" ) then
 		ValidateTransmogrifications();
 		local slot, hasItem = ...;
 		if ( slot == INVSLOT_TABARD or slot == INVSLOT_BODY ) then
 			if ( hasItem ) then
-				local itemID = GetInventoryItemID("player", slot);
-				TransmogrifyModelFrame:TryOn(itemID);
+				local itemID, itemAppearanceModID = GetInventoryItemID("player", slot);
+				TransmogrifyModelFrame:TryOn(itemID, nil, itemAppearanceModID);
 			else
 				TransmogrifyModelFrame:UndressSlot(slot);
 			end
 		end
 	elseif ( event == "TRANSMOGRIFY_CLOSE" ) then
 		self:Hide();
 	elseif ( event == "TRANSMOGRIFY_SUCCESS" ) then
 		local slot = ...;
 		local button = BUTTONS[slot];
 		if ( button ) then
 			TransmogrifyFrame_AnimateSlotButton(button);
 			TransmogrifyFrame_UpdateSlotButton(button);
 			TransmogrifyFrame_UpdateApplyButton();
 		end
 	elseif ( event == "TRANSMOGRIFY_BIND_CONFIRM" ) then
 		TransmogrifyConfirmationPopup_Show(...);
 	elseif ( event == "UNIT_MODEL_CHANGED" ) then
 		local unit = ...;
 		if ( unit == "player" ) then
 			local hasAlternateForm, inAlternateForm = HasAlternateForm();
 			if ( self.alternateForm ~= inAlternateForm ) then
 				self.alternateForm = inAlternateForm;
 				TransmogrifyModelFrame:SetUnit("player");
 				TransmogrifyFrame_Update(self);
 			end
 		end
 	end
 end
 
 function TransmogrifyFrame_OnShow(self)
 	PlaySound("UI_EtherealWindow_Open");
 	self:RegisterEvent("PLAYER_EQUIPMENT_CHANGED");
 	self:RegisterEvent("BAG_UPDATE");
 	local hasAlternateForm, inAlternateForm = HasAlternateForm();
 	if ( hasAlternateForm ) then
 		self:RegisterEvent("UNIT_MODEL_CHANGED");
 		self.alternateForm = inAlternateForm;
 	end
 	TransmogrifyModelFrame:SetUnit("player");
 	Model_Reset(TransmogrifyModelFrame);
 	self.headSlot.displayHelm = ShowingHelm();
 	self.backSlot.displayCloak = ShowingCloak();
 	TransmogrifyFrame_Update(self);
 end
 
 function TransmogrifyFrame_OnHide(self)
 	PlaySound("UI_EtherealWindow_Close");
 	StaticPopupSpecial_Hide(TransmogrifyConfirmationPopup);
 	for _, button in pairs(BUTTONS) do
 		button.popoutButton:Hide();
 	end
 	self:UnregisterEvent("PLAYER_EQUIPMENT_CHANGED");
 	self:UnregisterEvent("BAG_UPDATE");
 	self:UnregisterEvent("UNIT_MODEL_CHANGED");
 	CloseTransmogrifyFrame();
 end
 
 function TransmogrifyFrame_GetAnimationFrame()
 	local name, frame;
 	local i = 1;
 	while true do
 		name = "TransmogrifyAnimation"..i;
 		frame = _G[name];
 		if ( frame ) then
 			if ( not frame:IsShown() ) then
 				return frame;
 			end
 		else
 			frame = CreateFrame("Frame", name, TransmogrifyFrame, "TransmogrifyAnimationFrameTemplate");
 			return frame;
 		end
 		i = i + 1;
 		assert(i < 20);
 	end
 end
 
 function TransmogrifyFrame_GetPendingFrame()
 	local name, frame;
 	local i = 1;
 	while true do
 		name = "TransmogrifyPending"..i;
 		frame = _G[name];
 		if ( frame ) then
 			if ( not frame:IsShown() ) then
 				return frame;
 			end
 		else
 			frame = CreateFrame("Frame", name, TransmogrifyFrame, "TransmogrifyPendingFrameTemplate");
 			return frame;
 		end
 		i = i + 1;
 		assert(i < 20);
 	end
 end
 
 function TransmogrifyFrame_AnimateSlotButton(button)
 	-- don't do anything if this button already has an animation frame;
 	if ( button.animationFrame ) then
 		return;
 	end
 	local animationFrame = TransmogrifyFrame_GetAnimationFrame();
 	animationFrame:SetParent(button);
 	animationFrame:SetPoint("CENTER");
 	button.animationFrame = animationFrame;
 	local isTransmogrified = GetTransmogrifySlotInfo(button.id);
 	if ( isTransmogrified ) then
 		animationFrame.transition:Show();
 	else
 		animationFrame.transition:Hide();
 	end
 	animationFrame:Show();
 	animationFrame.anim:Play();
 end
 
 function TransmogrifySlotButton_OnLoad(self)
 	self:RegisterForClicks("LeftButtonUp", "RightButtonUp");
 	self:RegisterForDrag("LeftButton");
 	local slotName = strsub(self:GetName(), 18);
 	local id, textureName = GetInventorySlotInfo(slotName);
 	self.id = id;
 	self.defaultTexture = textureName;
 	self.icon:SetTexture(textureName);
 	self.verticalFlyout = VERTICAL_FLYOUTS[id];
 	BUTTONS[id] = self;
 	RaiseFrameLevelByTwo(self);
 
 	local popoutButton = self.popoutButton;
 	if ( popoutButton ) then
 		if ( self.verticalFlyout ) then
 			popoutButton:SetHeight(16);
 			popoutButton:SetWidth(38);
 			
 			popoutButton:GetNormalTexture():SetTexCoord(0.15625, 0.84375, 0.5, 0);
 			popoutButton:GetHighlightTexture():SetTexCoord(0.15625, 0.84375, 1, 0.5);
 			popoutButton:ClearAllPoints();
 			popoutButton:SetPoint("TOP", self, "BOTTOM", 0, 0);
 		else
 			popoutButton:SetHeight(38);
 			popoutButton:SetWidth(16);
 			
 			popoutButton:GetNormalTexture():SetTexCoord(0.15625, 0.5, 0.84375, 0.5, 0.15625, 0, 0.84375, 0);
 			popoutButton:GetHighlightTexture():SetTexCoord(0.15625, 1, 0.84375, 1, 0.15625, 0.5, 0.84375, 0.5);
 			popoutButton:ClearAllPoints();
 			popoutButton:SetPoint("LEFT", self, "RIGHT", 0, 0);
 		end
 	end
 end
 
 function TransmogrifySlotButton_OnEvent(self, event, ...)
 	if ( event == "MODIFIER_STATE_CHANGED" ) then
 		if ( IsModifiedClick("SHOWITEMFLYOUT") and self:IsMouseOver() ) then
 			TransmogrifySlotButton_OnEnter(self);
 		end
 	end
 end
 
 function TransmogrifySlotButton_OnClick(self, button)
 	local isTransmogrified, canTransmogrify, cannotTransmogrifyReason, hasPending, hasUndo = GetTransmogrifySlotInfo(self.id);
 	-- save for sound to play on TRANSMOGRIFY_UPDATE event
 	self.hadUndo = hasUndo;
 	if ( button == "RightButton" ) then
 		ClearTransmogrifySlot(self.id);
 	else
 		ClickTransmogrifySlot(self.id);
 	end
 	self.undoIcon:Hide();
 	TransmogrifySlotButton_OnEnter(self);
 end
 
 function TransmogrifySlotButton_OnEnter(self)
 	local isTransmogrified, canTransmogrify, cannotTransmogrifyReason, hasPending, hasUndo = GetTransmogrifySlotInfo(self.id);
 	local cursorItem = GetCursorInfo();
 	if ( cursorItem ~= "item" and isTransmogrified and not ( hasPending or hasUndo ) ) then
 		self.undoIcon:Show();
 	end
 
 	self:RegisterEvent("MODIFIER_STATE_CHANGED");
 	EquipmentFlyout_UpdateFlyout(self);
 	if ( not EquipmentFlyout_SetTooltipAnchor(self) ) then
 		GameTooltip:SetOwner(self, "ANCHOR_RIGHT", 14, 0);
 	end
 	if ( hasPending or hasUndo ) then
 		GameTooltip:SetTransmogrifyItem(self.id);
 	elseif ( not canTransmogrify ) then
 		local slotName = _G[strupper(strsub(self:GetName(), 18))];
 		GameTooltip:SetText(slotName);
 		local errorMsg = _G["TRANSMOGRIFY_INVALID_REASON"..cannotTransmogrifyReason];
 		if ( errorMsg ) then
-			GameTooltip:AddLine(errorMsg, RED_FONT_COLOR.r, RED_FONT_COLOR.g, RED_FONT_COLOR.b, 1, 1);
+			GameTooltip:AddLine(errorMsg, RED_FONT_COLOR.r, RED_FONT_COLOR.g, RED_FONT_COLOR.b, true);
 		end
 		GameTooltip:Show();
 	else
 		local hasItem = GameTooltip:SetInventoryItem("player", self.id);
 	end
 	if ( canTransmogrify ) then
 		self.popoutButton:Show();
 		self.popoutButton.persistTime = nil;
 	end
 	TransmogrifyModelFrame.controlFrame:Show();
 end
 
 function TransmogrifySlotButton_OnLeave(self)
 	self:UnregisterEvent("MODIFIER_STATE_CHANGED");
 	TransmogrifyModelFrame.controlFrame:Hide();
 	self.undoIcon:Hide();
 	self.popoutButton.persistTime = 0;
 	GameTooltip:Hide();
 end
 
 function TransmogrifyFrame_Update(self)
 
 	for _, button in pairs(BUTTONS) do
 		TransmogrifyFrame_UpdateSlotButton(button);
 	end
 	TransmogrifyFrame_UpdateApplyButton();
 end
 
 function TransmogrifyFrame_UpdateApplyButton()
 	local cost, numChanges = GetTransmogrifyCost();
 	local canApply;
 	if ( cost > GetMoney() ) then
 		SetMoneyFrameColor("TransmogrifyMoneyFrame", "red");
 	else
 		SetMoneyFrameColor("TransmogrifyMoneyFrame");
 		if (numChanges > 0 ) then
 			canApply = true;
 		end
 	end
 	if ( TransmogrifyConfirmationPopup:IsShown() ) then
 		canApply = false;
 	end
 	MoneyFrame_Update("TransmogrifyMoneyFrame", cost);
 	if ( canApply ) then
 		TransmogrifyApplyButton:Enable();
 	else
 		TransmogrifyApplyButton:Disable();
 	end
 end
 
 function TransmogrifyFrame_UpdateSlotButton(button)
-	local isTransmogrified, canTransmogrify, cannotTransmogrifyReason, hasPending, hasUndo, visibleItemID, textureName = GetTransmogrifySlotInfo(button.id);
+	local isTransmogrified, canTransmogrify, cannotTransmogrifyReason, hasPending, hasUndo, visibleItemID, textureName, visibleItemAppearanceModID = GetTransmogrifySlotInfo(button.id);
 	local hasChange = hasPending or hasUndo;
 
 	if ( canTransmogrify ) then
 		button.icon:SetTexture(textureName);
 		button.noItem:Hide();
 	else
 		button.icon:SetTexture(button.defaultTexture);
 		button.noItem:Show();
 	end
 
 	-- desaturate icon if it's not transmogrified
 	if ( isTransmogrified or hasPending ) then
 		button.icon:SetDesaturated(false);
 	else
 		button.icon:SetDesaturated(true);
 	end
 
 	-- show altered texture if the item is transmogrified and doesn't have a pending transmogrification or is animating
 	if ( isTransmogrified and not hasChange and not button.animationFrame ) then
 		button.altTexture:Show();
 	else
 		button.altTexture:Hide();
 	end
 
 	-- show ants frame is the item has a pending transmogrification and is not animating
 	if ( hasChange and not button.animationFrame ) then
 		local pendingFrame = button.pendingFrame;
 		if ( not pendingFrame ) then
 			pendingFrame = TransmogrifyFrame_GetPendingFrame();
 			pendingFrame:SetParent(button);
 			pendingFrame:SetPoint("CENTER");
 			button.pendingFrame = pendingFrame;
 		end
 		pendingFrame:Show();
 		if ( hasUndo ) then
 			pendingFrame.undo:Show();
 		else
 			pendingFrame.undo:Hide();
 		end
 	elseif ( button.pendingFrame ) then
 		button.pendingFrame:Hide();
 		button.pendingFrame = nil;
 	end
 	
 
 	local showModel = true;
 	if (button.id == INVSLOT_HEAD and not button.displayHelm) then
 		if ( hasChange ) then
 			button.displayHelm = true;
 		else
 			showModel = false;
 		end
 	end
 	if (button.id == INVSLOT_BACK and not button.displayCloak) then
 		if ( hasChange ) then
 			button.displayCloak = true;
 		else
 			showModel = false;
 		end
 	end
 	if ( showModel ) then
 		if ( visibleItemID and visibleItemID > 0 ) then
 			local slot;
 			if ( button.id == INVSLOT_MAINHAND ) then
 				slot = "mainhand";
 			elseif ( button.id == INVSLOT_OFFHAND ) then
 				slot = "offhand";
 			end
-			TransmogrifyModelFrame:TryOn(visibleItemID, slot);
+			TransmogrifyModelFrame:TryOn(visibleItemID, slot, visibleItemAppearanceModID);
 		else
 			if ( button.id == INVSLOT_RANGED ) then
 				-- clear both hands
 				TransmogrifyModelFrame:UndressSlot(INVSLOT_MAINHAND);
 				TransmogrifyModelFrame:UndressSlot(INVSLOT_OFFHAND);
 			else
 				TransmogrifyModelFrame:UndressSlot(button.id);
 			end
 		end
 	end
 end
 
 function TransmogrifyItemFlyoutButton_OnClick(self)
 	if ( self.location ) then
-		local player, bank, bags, voidStorage, slot, bag = EquipmentManager_UnpackLocation(self.location);
+		local player, bank, bags, voidStorage, slot, bag, tab, voidSlot = EquipmentManager_UnpackLocation(self.location);
 		if ( voidStorage ) then
-			UseVoidItemForTransmogrify(slot, EquipmentFlyoutFrame.button.id);
+			UseVoidItemForTransmogrify(tab, voidSlot, EquipmentFlyoutFrame.button.id);
 		elseif ( bag ) then
 			UseItemForTransmogrify(bag, slot, EquipmentFlyoutFrame.button.id);
 		else
 			UseItemForTransmogrify(nil, slot, EquipmentFlyoutFrame.button.id);
 		end
 	end
 end
 
 function TransmogrifyItemFlyout_GetItems(slot, itemTable)
 	GetInventoryItemsForSlot(slot, itemTable, "transmogrify");
 end
 
 function TransmogrifyConfirmationPopup_Show(slot, sourceItemLink, destinationItemLink)
 	local popup = TransmogrifyConfirmationPopup;
 	local baseHeight;
 	if ( sourceItemLink and destinationItemLink ) then
 		TransmogrifyConfirmationPopup_SetItem(popup.ItemFrame1, sourceItemLink);
 		TransmogrifyConfirmationPopup_SetItem(popup.ItemFrame2, destinationItemLink);
 		popup.Text:SetText(TRANSMOGRIFY_BIND_CONFIRMATION_BOTH.."\n"..CONFIRM_CONTINUE);
 		baseHeight = 160;
 	else
 		popup.ItemFrame2:Hide();
 		if ( sourceItemLink ) then
 			TransmogrifyConfirmationPopup_SetItem(popup.ItemFrame1, sourceItemLink);
 			popup.Text:SetText(TRANSMOGRIFY_BIND_CONFIRMATION_SOURCE.."\n"..CONFIRM_CONTINUE);
 		else
 			TransmogrifyConfirmationPopup_SetItem(popup.ItemFrame1, destinationItemLink);
 			popup.Text:SetText(TRANSMOGRIFY_BIND_CONFIRMATION_DESTINATION.."\n"..CONFIRM_CONTINUE);
 		end
 		baseHeight = 115;
 	end
 	popup:SetHeight(baseHeight + popup.Text:GetHeight());
 	StaticPopupSpecial_Show(popup);
 	popup.slot = slot;
 	TransmogrifyApplyButton:Disable();
 end
 
 function TransmogrifyConfirmationPopup_SetItem(itemFrame, itemLink)
 	local itemName, _, itemQuality, _, _, _, _, _, _, texture = GetItemInfo(itemLink);
 	local r, g, b = GetItemQualityColor(itemQuality or 1);
 	itemFrame.Text:SetText(itemName);
 	itemFrame.Text:SetTextColor(r, g, b);
 	itemFrame.icon:SetTexture(texture);
 	itemFrame:Show();
 	itemFrame.link = itemLink;
 end
 
 function TransmogrifyFrame_CloseFlyout()
 	local flyout = EquipmentFlyoutFrame;
 	if ( flyout:IsShown() ) then
 		local flyoutSettings = flyout.button:GetParent().flyoutSettings;
 		if ( flyoutSettings and flyoutSettings.parent == TransmogrifyFrame ) then
 			EquipmentFlyoutFrame:Hide();
 		end
 	end
 end
 
 function TransmogrifySlotFlyoutButton_OnUpdate(self, elapsed)
 	if ( self.persistTime and not self.flyoutLocked ) then
 		if ( not EquipmentFlyoutFrame:IsShown() or EquipmentFlyoutFrame.button ~= self:GetParent() ) then
 			self.persistTime = self.persistTime + elapsed;
 			if ( self.persistTime >= FLYOUT_BUTTON_HIDE_DELAY_TIME ) then
 				self:Hide();
 			end
 		end
 	end
 end
\ No newline at end of file