TRADE_SKILLS_DISPLAYED = 8;
 TRADE_SKILL_GUILD_CRAFTERS_DISPLAYED = 10;
 MAX_TRADE_SKILL_REAGENTS = 8;
 TRADE_SKILL_HEIGHT = 16;
 TRADE_SKILL_TEXT_WIDTH = 270;
 TRADE_SKILL_SKILLUP_TEXT_WIDTH = 30;
 TRADE_SKILL_LINKED_NAME_WIDTH = 120;
 SUB_SKILL_BAR_WIDTH = 60;
 
 TradeSkillTypePrefix = {
 ["optimal"] = " [+++] ",
 ["medium"] = " [++] ",
 ["easy"] = " [+] ",
 ["trivial"] = " ", 
 ["header"] = " ",
 ["subheader"] = " ",
+["nodifficulty"] = " ",
 }
 
 TradeSkillTypeColor = { };
 TradeSkillTypeColor["optimal"]	= { r = 1.00, g = 0.50, b = 0.25,	font = GameFontNormalLeftOrange };
 TradeSkillTypeColor["medium"]	= { r = 1.00, g = 1.00, b = 0.00,	font = GameFontNormalLeftYellow };
 TradeSkillTypeColor["easy"]		= { r = 0.25, g = 0.75, b = 0.25,	font = GameFontNormalLeftLightGreen };
 TradeSkillTypeColor["trivial"]	= { r = 0.50, g = 0.50, b = 0.50,	font = GameFontNormalLeftGrey };
 TradeSkillTypeColor["header"]	= { r = 1.00, g = 0.82, b = 0,		font = GameFontNormalLeft };
 TradeSkillTypeColor["subheader"]= { r = 1.00, g = 0.82, b = 0,		font = GameFontNormalLeft };
+TradeSkillTypeColor["nodifficulty"] = { r = 0.96, g = 0.96, b = 0.96, font = GameFontNormalLeftGrey };
 
 UIPanelWindows["TradeSkillFrame"] = {area = "left", pushable = 3, showFailedFunc = "TradeSkillFrame_ShowFailed" };
 
 CURRENT_TRADESKILL = "";
 
 local SUBSKILL_RANKS = { };				-- tracks subskill ranks for figuring out which one just skilled up in order to flash the rank numbers
 local SUBSKILL_FLASH_BAR;				-- the subskill progress bar that's currently flashing
 local SUBSKILL_FLASH_NAME;				-- the name of the subskill that's currently flashing
 local SUBSKILL_FLASH_ELAPSED_TIME;		-- current elapsed time for the flash
 local SUBSKILL_FLASH_DURATION = 1;		-- how long the flash should take
 
 function TradeSkillFrame_Show()
 	ShowUIPanel(TradeSkillFrame);
 	TradeSkillCreateButton:Disable();
 	TradeSkillCreateAllButton:Disable();
 	local tsIndex = 0;
 	if ( GetTradeSkillSelectionIndex() == 0 ) then
 		tsIndex = GetFirstTradeSkill();
 	else
 		tsIndex = GetTradeSkillSelectionIndex();
 	end	
 	TradeSkillFrame_SetSelection(tsIndex);
 	
 	FauxScrollFrame_SetOffset(TradeSkillListScrollFrame, 0);
 	TradeSkillListScrollFrameScrollBar.doNotHide = true;
 	TradeSkillListScrollFrameScrollBar:SetMinMaxValues(0, 0); 
 	TradeSkillListScrollFrameScrollBar:SetValue(0);
 	if ( IsTradeSkillGuild() ) then
 		TradeSkillFramePortrait:Hide();
 		TradeSkillFrameTabardBackground:Show();
 		TradeSkillFrameTabardEmblem:Show();
 		TradeSkillFrameTabardBorder:Show();
 		SetLargeGuildTabardTextures("player", TradeSkillFrameTabardEmblem, TradeSkillFrameTabardBackground, TradeSkillFrameTabardBorder);
 	else
 		TradeSkillFrameTabardBackground:Hide();
 		TradeSkillFrameTabardEmblem:Hide();
 		TradeSkillFrameTabardBorder:Hide();
 		TradeSkillFramePortrait:Show();
 		SetPortraitToTexture(TradeSkillFramePortrait, GetTradeSkillTexture() );
 	end
 	TradeSkillOnlyShowMakeable(TradeSkillFrame.filterTbl.hasMaterials);
 	TradeSkillOnlyShowSkillUps(TradeSkillFrame.filterTbl.hasSkillUp);
 	TradeSkillFrame_Update();
 
 	TradeSkillSetFilter(-1, -1);		
 	-- Moved to the bottom to prevent addons which hook it from blocking tradeskills
 	CloseDropDownMenus();
 end
 
 function TradeSkillFrame_Hide()
 	HideUIPanel(TradeSkillFrame);
 end
 
 function TradeSkillFrame_ShowFailed(self)
 	CloseTradeSkill();
 end
 
 function TradeSkillFrame_OnUpdate(self, elapsed)
 	if ( SUBSKILL_FLASH_BAR ) then
 		SUBSKILL_FLASH_ELAPSED_TIME = SUBSKILL_FLASH_ELAPSED_TIME + elapsed;
 		if ( SUBSKILL_FLASH_ELAPSED_TIME > SUBSKILL_FLASH_DURATION ) then
 			TradeSkilSubSkillRank_StopFlash();
 		else
 			local alpha = math.sin(SUBSKILL_FLASH_ELAPSED_TIME * math.pi / SUBSKILL_FLASH_DURATION);	-- just a half-sine curve
 			SUBSKILL_FLASH_BAR.Rank:SetAlpha(alpha);
 			SUBSKILL_FLASH_BAR.Rank:SetText(SUBSKILL_FLASH_BAR.currentRank.."/"..SUBSKILL_FLASH_BAR.maxRank);
 		end
 	end
 	TradeSkillFrame_PlaytimeUpdate();
 end
 
 
 function TradeSkillFrameButton_OnEnter(self)
 	self.count:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
 	self.skillup.icon:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
 	self.skillup.countText:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
 	
 	self.text:SetFontObject(GameFontHighlightLeft);
 	self.text:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
 	if ( self.SubSkillRankBar.currentRank and self.SubSkillRankBar.maxRank) then
 		if ( self.SubSkillRankBar == SUBSKILL_FLASH_BAR ) then
 			TradeSkilSubSkillRank_StopFlash();
 		end
 		self.SubSkillRankBar.Rank:SetText(self.SubSkillRankBar.currentRank.."/"..self.SubSkillRankBar.maxRank);
 	end
 end
 
 
 function TradeSkillFrameButton_OnLeave(self)
 	if ( not self.isHighlighted ) then
 		self.count:SetVertexColor(self.r, self.g, self.b);
 		self.skillup.icon:SetVertexColor(self.r, self.g, self.b);
 		self.skillup.countText:SetVertexColor(self.r, self.g, self.b);
 		
 		self.text:SetFontObject(self.font);
 		self.text:SetVertexColor(self.r, self.g, self.b);
 	end
 	self.SubSkillRankBar.Rank:SetText("");
 end
 
 function TradeSkillFrame_OnEvent(self, event, ...)
 	if ( not TradeSkillFrame:IsShown() ) then
 		return;
 	end
 	if ( event == "TRADE_SKILL_UPDATE" or event == "TRADE_SKILL_FILTER_UPDATE" ) then
 		TradeSkillCreateButton:Disable();
 		TradeSkillCreateAllButton:Disable();
 		if ( (event ~= "TRADE_SKILL_FILTER_UPDATE") and (GetTradeSkillSelectionIndex() > 1) and (GetTradeSkillSelectionIndex() <= GetNumTradeSkills()) ) then
 			TradeSkillFrame_SetSelection(GetTradeSkillSelectionIndex());
 		else
 			TradeSkillFrame_SetSelection(GetFirstTradeSkill());
 		end
 		TradeSkillFrame_Update();
 	elseif ( event == "UNIT_PORTRAIT_UPDATE" ) then
 		local arg1 = ...;
 		if ( not arg1 or arg1 == "player" ) then
 			SetPortraitTexture(TradeSkillFramePortrait, "player");
 		end
 	elseif ( event == "UPDATE_TRADESKILL_RECAST" ) then
 		TradeSkillInputBox:SetNumber(GetTradeskillRepeatCount());
 	elseif ( event == "GUILD_RECIPE_KNOWN_BY_MEMBERS" ) then
 		if ( TradeSkillGuildFrame.queriedSkill == TradeSkillFrame.selectedSkill ) then
 			TradeSkillGuildFrame:Show();
 		end
 	elseif ( event == "TRADE_SKILL_NAME_UPDATE" ) then
 		TradeSkillFrame_SetLinkName();
 	elseif ( event == "DISPLAY_SIZE_CHANGED" ) then
 		TradeSkillFrame_Update();
 	end
 end
 
 function TradeSkillFrame_Update()
 	local numTradeSkills = GetNumTradeSkills();
 	local skillOffset = FauxScrollFrame_GetOffset(TradeSkillListScrollFrame);
 	local name, rank, maxRank = GetTradeSkillLine();
     local isTradeSkillGuild = IsTradeSkillGuild();
+	local isNPCCrafting = IsNPCCrafting() and maxRank == 0;
 	
 	if ( CURRENT_TRADESKILL ~= name ) then
 		StopTradeSkillRepeat();
 		if ( CURRENT_TRADESKILL ~= "" ) then
 			-- To fix problem with switching between two tradeskills
 			UIDropDownMenu_Initialize(TradeSkillFilterDropDown, TradeSkillFilterDropDown_Initialize);
 			--TradeSkillSetFilter(-1, -1);
 			
 			--UIDropDownMenu_SetSelectedID(TradeSkillFilterDropDown, 1);
 
 			--UIDropDownMenu_Initialize(TradeSkillSubClassDropDown, TradeSkillSubClassDropDown_Initialize);
 			--UIDropDownMenu_SetSelectedID(TradeSkillSubClassDropDown, 1);
 		end
 		CURRENT_TRADESKILL = name;
 	end
 
 	if ( not IsTradeSkillReady() ) then
 		numTradeSkills = 0;
 		TradeSkillFrameSearchBox:SetEnabled(false);
 		TradeSkillFilterButton:SetEnabled(false);
 		TradeSkillLinkButton:SetEnabled(false);
 		TradeSkillFrame.RetrievingFrame:Show();
 	else
 		TradeSkillFrameSearchBox:SetEnabled(true);
 		TradeSkillFilterButton:SetEnabled(true);
 		TradeSkillLinkButton:SetEnabled(true);
 		TradeSkillFrame.RetrievingFrame:Hide();
 	end
 
 	-- If no tradeskills
 	if ( numTradeSkills == 0 ) then
 		TradeSkillFrameTitleText:SetFormattedText(TRADE_SKILL_TITLE, GetTradeSkillLine());
 		TradeSkillSkillName:Hide();
 		TradeSkillSkillIcon:Hide();
 		TradeSkillRequirementLabel:Hide();
 		TradeSkillRequirementText:SetText("");
 		TradeSkillCollapseAllButton:Disable();
 		for i=1, MAX_TRADE_SKILL_REAGENTS, 1 do
 			_G["TradeSkillReagent"..i]:Hide();
 		end
 	else
 		TradeSkillSkillName:Show();
 		TradeSkillSkillIcon:Show();
 		TradeSkillCollapseAllButton:Enable();
 	end
 
 	
 	TradeSkillHighlightFrame:Hide();
-	local skillName, skillType, numAvailable, isExpanded, altVerb, numSkillUps, indentLevel, showProgressBar, currentRank, maxRank, startingRank;
-	local skillIndex, skillButton, skillButtonText, skillButtonCount, skillButtonNumSkillUps, skillButtonNumSkillUpsIcon, skillButtonNumSkillUpsText, skillButtonSubSkillRankBar;
+	local skillName, skillType, numAvailable, isExpanded, altVerb, numSkillUps, indentLevel, showProgressBar, currentRank, maxRank, startingRank, displayAsUnavailable;
+	local skillIndex, skillButton, skillButtonText, skillButtonCount, skillButtonNumSkillUps, skillButtonNumSkillUpsIcon, skillButtonNumSkillUpsText, skillButtonSubSkillRankBar, skillButtonLockedIcon;
 	local nameWidth, countWidth, usedWidth;
 	
 	local skillNamePrefix = " ";
 	local diplayedSkills = TRADE_SKILLS_DISPLAYED;
 	local hasFilterBar = TradeSkillFilterBar:IsShown();
 	local numList = numTradeSkills;
 	if  hasFilterBar then
 		diplayedSkills = TRADE_SKILLS_DISPLAYED - 1;
 		numList = numList+1;
 	end	
 	local buttonIndex = 0;
 
 	-- ScrollFrame update
 	FauxScrollFrame_Update(TradeSkillListScrollFrame, numList, TRADE_SKILLS_DISPLAYED, TRADE_SKILL_HEIGHT, nil, nil, nil, TradeSkillHighlightFrame, 293, 316, true );
 	
 	for i=1, diplayedSkills, 1 do
 		skillIndex = i + skillOffset;
-		skillName, skillType, numAvailable, isExpanded, altVerb, numSkillUps, indentLevel, showProgressBar, currentRank, maxRank, startingRank = GetTradeSkillInfo(skillIndex);
+		skillName, skillType, numAvailable, isExpanded, altVerb, numSkillUps, indentLevel, showProgressBar, currentRank, maxRank, startingRank, displayAsUnavailable = GetTradeSkillInfo(skillIndex);
 
 		if hasFilterBar then
 			buttonIndex = i+1;
 		else
 			buttonIndex = i;
 		end
 		
 		skillButton = _G["TradeSkillSkill"..buttonIndex];
 		skillButtonText = _G["TradeSkillSkill"..buttonIndex.."Text"];
 		skillButtonCount = _G["TradeSkillSkill"..buttonIndex.."Count"];
 		skillButtonNumSkillUps = _G["TradeSkillSkill"..buttonIndex.."NumSkillUps"];
 		skillButtonNumSkillUpsText = _G["TradeSkillSkill"..buttonIndex.."NumSkillUpsText"];
 		skillButtonNumSkillUpsIcon = _G["TradeSkillSkill"..buttonIndex.."NumSkillUpsIcon"];
 		skillButtonSubSkillRankBar = _G["TradeSkillSkill"..buttonIndex.."SubSkillRankBar"];
+		skillButtonLockedIcon = _G["TradeSkillSkill"..buttonIndex.."LockedIcon"];
 		if ( skillIndex <= numTradeSkills ) then
 			--turn on the multiskill icon
-			if not isTradeSkillGuild and numSkillUps > 1 and skillType=="optimal" then
+			if not isTradeSkillGuild and not isNPCCrafting and numSkillUps > 1 and skillType=="optimal" then
 				skillButtonNumSkillUps:Show();
 				skillButtonNumSkillUpsText:SetText(numSkillUps);
 				usedWidth = TRADE_SKILL_SKILLUP_TEXT_WIDTH;
 			else 
 				skillButtonNumSkillUps:Hide();
 				usedWidth = 0;
 			end
+			
+			-- display a lock icon when the recipe is shown, but unavailable
+			if ( displayAsUnavailable ) then
+				skillButtonLockedIcon:Show();
+				usedWidth = TRADE_SKILL_SKILLUP_TEXT_WIDTH;
+			else
+				skillButtonLockedIcon:Hide();
+			end
 
 			local color;
-			-- override colors for guild
-			if ( isTradeSkillGuild and skillType ~= "header" and skillType ~= "subheader" ) then
-				color = TradeSkillTypeColor["easy"];
+			-- override colors for guild and NPC crafting
+			if ( ( isTradeSkillGuild or isNPCCrafting ) and skillType ~= "header" and skillType ~= "subheader" ) then
+				if ( isTradeSkillGuild ) then
+					color = TradeSkillTypeColor["easy"];
+				else
+					color = TradeSkillTypeColor["nodifficulty"];
+				end
 			else
 				color = TradeSkillTypeColor[skillType];
 			end
 			if ( color ) then
 				skillButton:SetNormalFontObject(color.font);
 				skillButtonText:SetVertexColor(color.r, color.g, color.b);
 				skillButtonCount:SetVertexColor(color.r, color.g, color.b);
 				skillButton.r = color.r;
 				skillButton.g = color.g;
 				skillButton.b = color.b;
 				skillButton.font = color.font;
 				skillButtonNumSkillUpsText:SetVertexColor(color.r, color.g, color.b);
 				skillButtonNumSkillUpsIcon:SetVertexColor(color.r, color.g, color.b);
 			end
 			
 			if ( ENABLE_COLORBLIND_MODE == "1" ) then
 				skillNamePrefix = TradeSkillTypePrefix[skillType] or " ";
 			end
 			
 			local textWidth = TRADE_SKILL_TEXT_WIDTH;
 			if(indentLevel ~= 0) then
 				textWidth = TRADE_SKILL_TEXT_WIDTH - 20;
 				skillButton:GetNormalTexture():SetPoint("LEFT", 23, 0);
 				skillButton:GetDisabledTexture():SetPoint("LEFT", 23, 0);
 				skillButton:GetHighlightTexture():SetPoint("LEFT", 23, 0);
 			else
 				skillButton:GetNormalTexture():SetPoint("LEFT", 3, 0);
 				skillButton:GetDisabledTexture():SetPoint("LEFT", 3, 0);
 				skillButton:GetHighlightTexture():SetPoint("LEFT", 3, 0);
 			end
 
 			skillButton:SetID(skillIndex);
 			skillButton:Show();
 
 			skillButtonSubSkillRankBar:Hide();
 			if ( skillButtonSubSkillRankBar == SUBSKILL_FLASH_BAR and skillName ~= SUBSKILL_FLASH_NAME ) then
 				-- we were flashing this bar and now we're reusing it for another skill, kill the flash
 				TradeSkilSubSkillRank_StopFlash();
 			end
 
 			-- Handle headers
 			if ( skillType == "header" or skillType == "subheader" ) then
 				--probably only want to show progress bar for categories (headers)
 				if ( showProgressBar ) then
 					skillButtonSubSkillRankBar:Show();
 					TradeSkilSubSkillRank_Set(skillButtonSubSkillRankBar, skillName, currentRank, startingRank, maxRank);
 					textWidth = textWidth - SUB_SKILL_BAR_WIDTH;
 				end
 
 				skillButtonText:SetWidth(textWidth);
 				skillButton:SetText(skillName);
 				skillButtonCount:SetText("");
 				if ( isExpanded ) then
 					skillButton:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up");
 				else
 					skillButton:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
 				end
 				_G["TradeSkillSkill"..buttonIndex.."Highlight"]:SetTexture("Interface\\Buttons\\UI-PlusButton-Hilight");
 				skillButton:UnlockHighlight();
 				skillButton.isHighlighted = false;
 			else
 				if ( not skillName ) then
 					return;
 				end
 				skillButton:SetNormalTexture("");
 				_G["TradeSkillSkill"..buttonIndex.."Highlight"]:SetTexture("");
 				if ( numAvailable <= 0 ) then
 					skillButton:SetText(skillNamePrefix..skillName);
 					skillButtonCount:SetText("");
 					textWidth = textWidth - usedWidth;
 				else
 					skillName = skillNamePrefix..skillName;
 					skillButtonCount:SetText("["..numAvailable.."]");
 					TradeSkillFrameDummyString:SetText(skillName);
 					nameWidth = TradeSkillFrameDummyString:GetWidth();
 					countWidth = skillButtonCount:GetWidth();
 					skillButtonText:SetText(skillName);
 					if ( nameWidth + 2 + countWidth > textWidth - usedWidth ) then
 						textWidth = textWidth - 2 - countWidth - usedWidth;
 					else
 						textWidth = 0;
 					end
 				end
 				skillButtonText:SetWidth(textWidth);
 				-- Place the highlight and lock the highlight state
 				if ( GetTradeSkillSelectionIndex() == skillIndex ) then
 					TradeSkillHighlightFrame:SetPoint("TOPLEFT", "TradeSkillSkill"..buttonIndex, "TOPLEFT", 0, 0);
 					TradeSkillHighlightFrame:Show();
 					skillButtonText:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
 					skillButtonCount:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
 					
 					skillButtonNumSkillUpsText:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
 					skillButtonNumSkillUpsIcon:SetVertexColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
 					skillButton:LockHighlight();
 					skillButton.isHighlighted = true;
 				else
 					skillButton:UnlockHighlight();
 					skillButton.isHighlighted = false;
 				end
 			end
 		else
 			skillButton:Hide();
 		end
 	end
 	
 	
 	-- Set the expand/collapse all button texture
 	local numHeaders = 0;
 	local notExpanded = 0;
 	for i=1, numTradeSkills, 1 do
 		local skillName, skillType, numAvailable, isExpanded, altVerb = GetTradeSkillInfo(i);
 		if ( skillName and (skillType == "header" or skillType == "subheader") ) then
 			numHeaders = numHeaders + 1;
 			if ( not isExpanded ) then
 				notExpanded = notExpanded + 1;
 			end
 		end
 		if ( GetTradeSkillSelectionIndex() == i ) then
 			-- Set the max makeable items for the create all button
 			TradeSkillFrame.numAvailable = math.abs(numAvailable);
 		end
 	end
 	-- If all headers are not expanded then show collapse button, otherwise show the expand button
 	if ( notExpanded ~= numHeaders ) then
 		TradeSkillCollapseAllButton.collapsed = nil;
 		TradeSkillCollapseAllButton:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up");
 	else
 		TradeSkillCollapseAllButton.collapsed = 1;
 		TradeSkillCollapseAllButton:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up");
 	end
 end
 
 function TradeSkilSubSkillRank_Set(rankBar, skillName, currentRank, startingRank, maxRank)
 	if ( SUBSKILL_RANKS[skillName] and currentRank > SUBSKILL_RANKS[skillName] and TradeSkillFrame:IsShown() ) then
 		-- this bar needs to have skill rank flashing unless the mouse is already over
 		rankBar.Rank:SetText(currentRank.."/"..rankBar.maxRank);
 		if ( not rankBar:GetParent():IsMouseOver() ) then
 			TradeSkilSubSkillRank_StartFlash(rankBar, skillName);
 		end
 	elseif ( not rankBar:GetParent():IsMouseOver() ) then
 		rankBar.Rank:SetText("");
 	end
 	SUBSKILL_RANKS[skillName] = currentRank;
 	rankBar:SetMinMaxValues(startingRank, maxRank);
 	rankBar:SetValue(currentRank);
 	rankBar.currentRank = currentRank;
 	rankBar.maxRank = maxRank;
 end
 
 function TradeSkilSubSkillRank_StartFlash(rankBar, skillName)
 	TradeSkilSubSkillRank_StopFlash();
 	SUBSKILL_FLASH_BAR = rankBar;
 	SUBSKILL_FLASH_NAME = skillName;
 	SUBSKILL_FLASH_ELAPSED_TIME = 0;
 end
 
 function TradeSkilSubSkillRank_StopFlash()
 	if ( SUBSKILL_FLASH_BAR ) then
 		if ( not SUBSKILL_FLASH_BAR:GetParent():IsMouseOver() ) then
 			SUBSKILL_FLASH_BAR.Rank:SetText("");
 		end
 		SUBSKILL_FLASH_BAR.Rank:SetAlpha(1);
 		SUBSKILL_FLASH_BAR = nil;
 		SUBSKILL_FLASH_ELAPSED_TIME = nil;
 	end
 end
 
 function TradeSkillFrame_SetSelection(id)
 	if ( not IsTradeSkillReady() ) then
 		id = 0;
 	end
 
-	local skillName, skillType, numAvailable, isExpanded, altVerb = GetTradeSkillInfo(id);
+	local skillName, skillType, numAvailable, isExpanded, altVerb, numSkillUps, indentLevel, showProgressBar, currentRank, maxRank, startingRank, displayAsUnavailable, unavailableString = GetTradeSkillInfo(id);
 	local creatable = 1;
 	if ( not skillName ) then
 		creatable = nil;
 	end
 	TradeSkillHighlightFrame:Show();
 	TradeSkillGuildFrame.queriedSkill = nil;		-- always cancel any pending queries
 	TradeSkillGuildFrame:Hide();
 	if ( skillType == "header" or skillType == "subheader" ) then
 		TradeSkillHighlightFrame:Hide();
 		if ( isExpanded ) then
 			CollapseTradeSkillSubClass(id);
 		else
 			ExpandTradeSkillSubClass(id);
 		end
 		return;
 	end
 	TradeSkillFrame.selectedSkill = id;
 	SelectTradeSkill(id);
 	if ( GetTradeSkillSelectionIndex() > GetNumTradeSkills() ) then
 		return;
 	end
 	
 	TradeSkillSkillName:SetText(skillName);
-	local cooldown, isDayCooldown = GetTradeSkillCooldown(id);
-	
-	if ( not cooldown ) then
-		TradeSkillSkillCooldown:SetText("");
-	elseif ( not isDayCooldown ) then
-		TradeSkillSkillCooldown:SetText(COOLDOWN_REMAINING.." "..SecondsToTime(cooldown));
-	elseif ( cooldown > 60 * 60 * 24 ) then	--Cooldown is greater than 1 day.
-		TradeSkillSkillCooldown:SetText(COOLDOWN_REMAINING.." "..SecondsToTime(cooldown, true, false, 1, true));
+	local cooldown, isDayCooldown, charges, maxCharges = GetTradeSkillCooldown(id);
+	if( maxCharges > 0 and (charges > 0 or not cooldown) )then
+		TradeSkillSkillCooldown:SetText(format(TRADESKILL_CHARGES_REMAINING, charges, maxCharges));
+		TradeSkillSkillCooldown:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
+	elseif( displayAsUnavailable )then
+		TradeSkillSkillCooldown:SetTextColor(RED_FONT_COLOR.r, RED_FONT_COLOR.g, RED_FONT_COLOR.b);
+		TradeSkillSkillCooldown:SetText(unavailableString);
+		creatable = nil;
 	else
-		TradeSkillSkillCooldown:SetText(COOLDOWN_EXPIRES_AT_MIDNIGHT);
+		TradeSkillSkillCooldown:SetTextColor(RED_FONT_COLOR.r, RED_FONT_COLOR.g, RED_FONT_COLOR.b);
+		if ( not cooldown ) then
+			TradeSkillSkillCooldown:SetText("");
+		elseif ( not isDayCooldown ) then
+			TradeSkillSkillCooldown:SetText(COOLDOWN_REMAINING.." "..SecondsToTime(cooldown));
+		elseif ( cooldown > 60 * 60 * 24 ) then	--Cooldown is greater than 1 day.
+			TradeSkillSkillCooldown:SetText(COOLDOWN_REMAINING.." "..SecondsToTime(cooldown, true, false, 1, true));
+		else
+			TradeSkillSkillCooldown:SetText(COOLDOWN_EXPIRES_AT_MIDNIGHT);
+		end
 	end
 
 	TradeSkillSkillIcon:SetNormalTexture(GetTradeSkillIcon(id));
 	local minMade,maxMade = GetTradeSkillNumMade(id);
 	if ( maxMade > 1 ) then
 		if ( minMade == maxMade ) then
 			TradeSkillSkillIconCount:SetText(minMade);
 		else
 			TradeSkillSkillIconCount:SetText(minMade.."-"..maxMade);
 		end
 		if ( TradeSkillSkillIconCount:GetWidth() > 39 ) then
 			TradeSkillSkillIconCount:SetText("~"..floor((minMade + maxMade)/2));
 		end
 	else
 		TradeSkillSkillIconCount:SetText("");
 	end
 
 	-- Reagents
 	local numReagents = GetTradeSkillNumReagents(id);
 	if(numReagents > 0) then
 		TradeSkillReagentLabel:Show();
 	else
 		TradeSkillReagentLabel:Hide();
 	end
 	for i=1, numReagents, 1 do
 		local reagentName, reagentTexture, reagentCount, playerReagentCount = GetTradeSkillReagentInfo(id, i);
 		local reagent = _G["TradeSkillReagent"..i]
 		local name = _G["TradeSkillReagent"..i.."Name"];
 		local count = _G["TradeSkillReagent"..i.."Count"];
 		if ( not reagentName or not reagentTexture ) then
 			reagent:Hide();
 		else
 			reagent:Show();
 			SetItemButtonTexture(reagent, reagentTexture);
 			name:SetText(reagentName);
 			-- Grayout items
 			if ( playerReagentCount < reagentCount ) then
 				SetItemButtonTextureVertexColor(reagent, 0.5, 0.5, 0.5);
 				name:SetTextColor(GRAY_FONT_COLOR.r, GRAY_FONT_COLOR.g, GRAY_FONT_COLOR.b);
 				creatable = nil;
 			else
 				SetItemButtonTextureVertexColor(reagent, 1.0, 1.0, 1.0);
 				name:SetTextColor(HIGHLIGHT_FONT_COLOR.r, HIGHLIGHT_FONT_COLOR.g, HIGHLIGHT_FONT_COLOR.b);
 			end
 			if ( playerReagentCount >= 100 ) then
 				playerReagentCount = "*";
 			end
 			count:SetText(playerReagentCount.." /"..reagentCount);
 			--fix text overflow when the reagent count is too high
-			if (math.floor(count:GetStringWidth()) > math.floor(reagent.icon:GetWidth() + .5)) then 
+			if (math.floor(count:GetStringWidth()) > math.floor(reagent.Icon:GetWidth() + .5)) then 
 			--round count width down because the leftmost number can overflow slightly without looking bad
 			--round icon width because it should always be an int, but sometimes it's a slightly off float
 				count:SetText(playerReagentCount.."\n/"..reagentCount);
 			end
 		end
 	end
 	-- Place reagent label
 	local reagentToAnchorTo = numReagents;
 	if ( (numReagents > 0) and (mod(numReagents, 2) == 0) ) then
 		reagentToAnchorTo = reagentToAnchorTo - 1;
 	end
 	
 	for i=numReagents + 1, MAX_TRADE_SKILL_REAGENTS, 1 do
 		_G["TradeSkillReagent"..i]:Hide();
 	end
 
 	local spellFocus = BuildColoredListString(GetTradeSkillTools(id));
 	if ( spellFocus ) then
 		TradeSkillRequirementLabel:Show();
 		TradeSkillRequirementText:SetText(spellFocus);
 	else
 		TradeSkillRequirementLabel:Hide();
 		TradeSkillRequirementText:SetText("");
 	end
 
 	if ( creatable ) then
 		TradeSkillCreateButton:Enable();
 		TradeSkillCreateAllButton:Enable();
 	else
 		TradeSkillCreateButton:Disable();
 		TradeSkillCreateAllButton:Disable();
 	end
 	
 	if ( GetTradeSkillDescription(id) ) then
 		TradeSkillDescription:SetText(GetTradeSkillDescription(id))
 		TradeSkillReagentLabel:SetPoint("TOPLEFT", "TradeSkillDescription", "BOTTOMLEFT", 0, -10);
 	else
 		TradeSkillDescription:SetText(" ");
 		TradeSkillReagentLabel:SetPoint("TOPLEFT", "TradeSkillDescription", "TOPLEFT", 0, 0);
 	end
 	-- Reset the number of items to be created
 	TradeSkillInputBox:SetNumber(GetTradeskillRepeatCount());
 
 
 	local skillLineName, skillLineRank, skillLineMaxRank, skillLineModifier = GetTradeSkillLine();
 	local color;
 	
 	--Hide inapplicable buttons if we are inspecting. Otherwise show them
 	if ( IsTradeSkillGuild() ) then
 		-- highlight color
 		color = TradeSkillTypeColor["easy"];
 		-- title
 		TradeSkillFrameTitleText:SetFormattedText(GUILD_TRADE_SKILL_TITLE, skillLineName);
 		-- bottom bar
 		TradeSkillCreateButton:Hide();
 		TradeSkillCreateAllButton:Hide();
 		TradeSkillDecrementButton:Hide();
 		TradeSkillInputBox:Hide();
 		TradeSkillIncrementButton:Hide();
 		TradeSkillLinkButton:Hide();
 		TradeSkillViewGuildCraftersButton:Show();
 		if ( GetTradeSkillSelectionIndex() > 0 ) then
 			TradeSkillViewGuildCraftersButton:Enable();
 		else
 			TradeSkillViewGuildCraftersButton:Disable();
 		end
 		-- status bar
 		TradeSkillRankFrame:Hide();	
 	else
 		-- highlight color
 		color = TradeSkillTypeColor[skillType];
 		-- title
 		TradeSkillFrameTitleText:SetFormattedText(TRADE_SKILL_TITLE, skillLineName);
 		-- bottom bar
 		TradeSkillViewGuildCraftersButton:Hide();
 		-- status bar
 		TradeSkillRankFrame:SetStatusBarColor(0.0, 0.0, 1.0, 0.5);
 		TradeSkillRankFrameBackground:SetVertexColor(0.0, 0.0, 0.75, 0.5);
 		TradeSkillRankFrame:SetMinMaxValues(0, skillLineMaxRank);
 		TradeSkillRankFrame:SetValue(skillLineRank);
 		if ( skillLineModifier > 0 ) then
 			TradeSkillRankFrameSkillRank:SetFormattedText(TRADESKILL_RANK_WITH_MODIFIER, skillLineRank, skillLineModifier, skillLineMaxRank);
 		else
 			TradeSkillRankFrameSkillRank:SetFormattedText(TRADESKILL_RANK, skillLineRank, skillLineMaxRank);
 		end
 		
 		if IsTrialAccount() then
 			local _, _, profCap = GetRestrictedAccountData();
 			if skillLineRank >= profCap then
 				local text = TradeSkillRankFrameSkillRank:GetText();
 				text = text.." "..RED_FONT_COLOR_CODE..TRIAL_CAPPED
 				TradeSkillRankFrameSkillRank:SetText(text);
 			end
 		end
 
 		TradeSkillRankFrame:Show();
 		
+		if ( IsNPCCrafting() and skillLineMaxRank == 0 ) then
+			TradeSkillRankFrame:Hide();
+			color = TradeSkillTypeColor["nodifficulty"];
+		end
+		
 		local linked = IsTradeSkillLinked();
 		if ( linked ) then
 			TradeSkillCreateButton:Hide();
 			TradeSkillCreateAllButton:Hide();
 			TradeSkillDecrementButton:Hide();
 			TradeSkillInputBox:Hide();
 			TradeSkillIncrementButton:Hide();
 			TradeSkillLinkButton:Hide();
 		else		
 			--Change button names and show/hide them depending on if this tradeskill creates an item or casts something
 			if ( not altVerb ) then
 				--Its an item with 'Create'
 				TradeSkillCreateAllButton:Show();
 				TradeSkillDecrementButton:Show();
 				TradeSkillInputBox:Show();
 				TradeSkillIncrementButton:Show();
 			else
 				--Its something else
 				TradeSkillCreateAllButton:Hide();
 				TradeSkillDecrementButton:Hide();
 				TradeSkillInputBox:Hide();
 				TradeSkillIncrementButton:Hide();				
 				--TradeSkillFrameBottomLeftTexture:SetTexture([[Interface\ClassTrainerFrame\UI-ClassTrainer-BotLeft]]);
 				--TradeSkillFrameBottomRightTexture:SetTexture([[Interface\ClassTrainerFrame\UI-ClassTrainer-BotRight]]);
 			end
 			if ( GetTradeSkillListLink() ) then
 				TradeSkillLinkButton:Show();
 			else
 				TradeSkillLinkButton:Hide();
 			end
 			TradeSkillCreateButton:SetText(altVerb or CREATE_PROFESSION);
 			TradeSkillCreateButton:Show();
 		end
 	end
 	TradeSkillFrame_SetLinkName();
 	if ( color ) then
 		TradeSkillHighlight:SetVertexColor(color.r, color.g, color.b);
 	end	
 end
 
 function TradeSkillFrame_SetLinkName()
 	local linked, linkedName = IsTradeSkillLinked();
 	TradeSkillFrameTitleText:ClearAllPoints();
 	if ( linkedName ) then
 		TradeSkillLinkNameButton:Show();
 		local linkedText = "["..linkedName.."]";
 		TradeSkillFrameDummyString:Show();
 		TradeSkillFrameDummyString:Hide();
 		TradeSkillFrameDummyString:SetText(linkedText);
 		local linkedNameWidth = TradeSkillFrameDummyString:GetWidth();
 		if linkedNameWidth > TRADE_SKILL_LINKED_NAME_WIDTH then
 			linkedNameWidth = TRADE_SKILL_LINKED_NAME_WIDTH;
 		end
 		TradeSkillLinkNameButton:SetWidth(linkedNameWidth);
 		TradeSkillLinkNameButtonTitleText:SetWidth(linkedNameWidth);
 		TradeSkillLinkNameButtonTitleText:SetText(linkedText);
 		TradeSkillLinkNameButton.linkedName = linkedName;
 		TradeSkillFrameTitleText:SetPoint("TOP", -linkedNameWidth/2,  -4);
 	else
 		TradeSkillLinkNameButton:Hide();
 		TradeSkillFrameTitleText:SetPoint("TOP", 0,  -4);
 	end
 end
 
 function TradeSkillSkillButton_OnClick(self, button)
 	if ( button == "LeftButton" ) then
 		TradeSkillFrame_SetSelection(self:GetID());
 		TradeSkillFrame_Update();
 	end
 end
 
 function TradeSkillSearch_OnTextChanged(self)
 	local text = self:GetText();
 	
 	if ( text == SEARCH ) then
 		SetTradeSkillItemNameFilter("");
 		return;
 	end
 
 	local minLevel, maxLevel;
 	local approxLevel = strmatch(text, "^~(%d+)");
 	if ( approxLevel ) then
 		minLevel = approxLevel - 2;
 		maxLevel = approxLevel + 2;
 	else
 		minLevel, maxLevel = strmatch(text, "^(%d+)%s*-*%s*(%d*)$");
 	end
 	if ( minLevel ) then
 		if ( maxLevel == "" or maxLevel < minLevel ) then
 			maxLevel = minLevel;
 		end
 		SetTradeSkillItemNameFilter(nil);
 		SetTradeSkillItemLevelFilter(minLevel, maxLevel);
 	else
 		SetTradeSkillItemLevelFilter(0, 0);
 		SetTradeSkillItemNameFilter(text);
 	end
 end
 
 function TradeSkillCollapseAllButton_OnClick(self)
 	if (self.collapsed) then
 		self.collapsed = nil;
 		ExpandTradeSkillSubClass(0);
 	else
 		self.collapsed = 1;
 		TradeSkillListScrollFrameScrollBar:SetValue(0);
 		CollapseTradeSkillSubClass(0);
 	end
 end
 
 
 -- DROP DOWN MENU MAGIC
 
 
 -- function TradeSkillSubClassDropDown_OnLoad(self)
 	-- SetTradeSkillSubClassFilter(0, 1, 1);
 	-- UIDropDownMenu_Initialize(self, TradeSkillSubClassDropDown_Initialize);
 	-- UIDropDownMenu_SetWidth(self, 120);
 	-- UIDropDownMenu_SetSelectedID(self, 1);
 -- end
 
 -- function TradeSkillSubClassDropDown_Initialize()
 	-- TradeSkillFilterFrame_LoadSubClasses(GetTradeSkillSubClasses());
 -- end
 
 -- function TradeSkillFilterFrame_LoadSubClasses(...)
 	-- local selectedID = UIDropDownMenu_GetSelectedID(TradeSkillSubClassDropDown);
 	-- local numSubClasses = select("#", ...);
 	-- local allChecked = GetTradeSkillSubClassFilter(0);
 
 	-- -- the first button in the list is going to be an "all subclasses" button
 	-- local info = UIDropDownMenu_CreateInfo();
 	-- info.text = ALL_SUBCLASSES;
 	-- info.func = TradeSkillSubClassDropDownButton_OnClick;
 	-- -- select this button if nothing else was selected
 	-- info.checked = allChecked and (selectedID == nil or selectedID == 1);
 	-- UIDropDownMenu_AddButton(info);
 	-- if ( info.checked ) then
 		-- UIDropDownMenu_SetText(TradeSkillSubClassDropDown, ALL_SUBCLASSES);
 	-- end
 
 	-- local checked;
 	-- for i=1, select("#", ...), 1 do
 		-- -- if there are no filters then don't check any individual subclasses
 		-- if ( allChecked ) then
 			-- checked = nil;
 		-- else
 			-- checked = GetTradeSkillSubClassFilter(i);
 			-- if ( checked ) then
 				-- UIDropDownMenu_SetText(TradeSkillSubClassDropDown, select(i, ...));
 			-- end
 		-- end
 		-- info.text = select(i, ...);
 		-- info.func = TradeSkillSubClassDropDownButton_OnClick;
 		-- info.checked = checked;
 		-- UIDropDownMenu_AddButton(info);
 	-- end
 -- end
 
 function TradeSkillFilterDropDown_OnLoad(self)
 	UIDropDownMenu_Initialize(self, TradeSkillFilterDropDown_Initialize, "MENU");
 	TradeSkillFilterDropDownText:SetJustifyH("CENTER");
 	TradeSkillFilterDropDownButton:Show();
 end
 
 
 function TradeSkillUpdateFilterBar(subName, slotName)
 
 	local filterText = "";
 	if TradeSkillFrame.filterTbl.hasMaterials then 
 		filterText = filterText..CRAFT_IS_MAKEABLE;
 	end
 	
 	if TradeSkillFrame.filterTbl.hasSkillUp then 
 		if filterText ~= "" then filterText = filterText..", "; end
 		filterText = filterText..TRADESKILL_FILTER_HAS_SKILL_UP;
 	end
 
 	if TradeSkillFrame.filterTbl.subClassValue > 0 then 	
 		if filterText ~= "" then filterText = filterText..", "; end 
 		if not subName then
 			subName = TradeSkillFrame.filterTbl.subClassText;
 		end
 		filterText = filterText..subName;
 		TradeSkillFrame.filterTbl.subClassText = subName;
 	end
 	
 	if TradeSkillFrame.filterTbl.slotValue > 0 then 
 		if filterText ~= "" then filterText = filterText..", "; end
 		if not slotName then
 			slotName = TradeSkillFrame.filterTbl.slotText;
 		end
 		filterText = filterText..slotName;
 		TradeSkillFrame.filterTbl.slotText = slotName;
 	end
 
 	 if filterText == "" then
 		TradeSkillFilterBar:Hide();
 		TradeSkillSkill1:Show();
 		
 	else
 		TradeSkillFilterBar:Show();	
 		TradeSkillSkill1:Hide();
 		TradeSkillFilterBarText:SetText(FILTER..": "..filterText);
 	end
 
 	TradeSkillListScrollFrameScrollBar:SetValue(0);
 	FauxScrollFrame_SetOffset(TradeSkillListScrollFrame, 0);
 	TradeSkillFrame_Update();
 end
 
 function TradeSkillSetFilter(subclass, slot, subName, slotName, subclassCategory)
 
 	TradeSkillFrame.filterTbl.subClassValue = subclass;
 	TradeSkillFrame.filterTbl.slotValue = slot;
 
 	SetTradeSkillCategoryFilter(subclass, subclassCategory);
 	SetTradeSkillInvSlotFilter(slot, 1, 1);
 
 	
 	TradeSkillUpdateFilterBar(subName, slotName);
 	CloseDropDownMenus();
 end
 
 
 function TradeSkillFilterDropDown_Initialize(self, level)
 	
 	local info = UIDropDownMenu_CreateInfo();
 	
 	if level == 1 then
 	
 		info.text = CRAFT_IS_MAKEABLE
 		info.func = 	function() 
 							TradeSkillFrame.filterTbl.hasMaterials  = not TradeSkillFrame.filterTbl.hasMaterials;
 							TradeSkillOnlyShowMakeable(TradeSkillFrame.filterTbl.hasMaterials);  
 							TradeSkillUpdateFilterBar();
 						end 
 		info.keepShownOnClick = true;
 		info.checked = 	TradeSkillFrame.filterTbl.hasMaterials
 		info.isNotRadio = true;
 		UIDropDownMenu_AddButton(info, level)
 		
-		if ( not IsTradeSkillGuild() ) then
+		local name, rank, skillLineMaxRank = GetTradeSkillLine();
+		local isNPCCrafting = IsNPCCrafting() and skillLineMaxRank == 0;
+		
+		if ( not IsTradeSkillGuild() and not isNPCCrafting ) then
 			info.text = TRADESKILL_FILTER_HAS_SKILL_UP;
 			info.func = 	function() 
 								TradeSkillFrame.filterTbl.hasSkillUp  = not TradeSkillFrame.filterTbl.hasSkillUp;
 								TradeSkillOnlyShowSkillUps(TradeSkillFrame.filterTbl.hasSkillUp);
 								TradeSkillUpdateFilterBar();
 							end 
 			info.keepShownOnClick = true;
 			info.checked = 	TradeSkillFrame.filterTbl.hasSkillUp;
 			info.isNotRadio = true;
 			UIDropDownMenu_AddButton(info, level);
 		end
 		
 		info.checked = 	nil;
 		info.isNotRadio = nil;
 				
 		info.text = TRADESKILL_FILTER_SLOTS
 		info.func =  nil;
 		info.notCheckable = true;
 		info.keepShownOnClick = false;
 		info.hasArrow = true;	
 		info.value = 1;
 		UIDropDownMenu_AddButton(info, level)
 				
 		info.text = TRADESKILL_FILTER_SUBCLASS
 		info.func =  nil;
 		info.notCheckable = true;
 		info.keepShownOnClick = false;
 		info.hasArrow = true;
 		info.value = 2;
 		UIDropDownMenu_AddButton(info, level)
 	
 	elseif level == 2 then
 		if UIDROPDOWNMENU_MENU_VALUE == 1 then
 			local slots = { GetTradeSkillSubClassFilteredSlots(0) };
 			local subslots = {};
 			for i,slot in pairs(slots) do
 				info.text = slot;
 				info.func =  function() TradeSkillSetFilter(0, i, "", slots[i]); end;
 				info.notCheckable = true;
 				info.hasArrow = false;	
 				UIDropDownMenu_AddButton(info, level);
 			end
 		elseif UIDROPDOWNMENU_MENU_VALUE == 2 then
 			local subClasses = { GetTradeSkillSubClasses() };
 			local subslots = {};
 			for i,subClass in pairs(subClasses) do
 				info.text = subClass;
 				info.func =  function() TradeSkillSetFilter(i, 0, subClasses[i], "", 0); end
 				info.notCheckable = true;
 				subslots  = { GetTradeSkillSubCategories(i) };
 				info.hasArrow = #subslots > 1;
 				info.value = i;
 				UIDropDownMenu_AddButton(info, level);
 			end
 		end
 	elseif level == 3 then	
 		local subClasses = { GetTradeSkillSubClasses() };
 		local subslots;
 		subslots = { GetTradeSkillSubCategories(UIDROPDOWNMENU_MENU_VALUE) };
 		for i,slot in pairs(subslots) do
 			info.text = slot;
 			info.func =  function() TradeSkillSetFilter(UIDROPDOWNMENU_MENU_VALUE, 0, subClasses[UIDROPDOWNMENU_MENU_VALUE], subslots[i], i); end
 			info.notCheckable = true;
 			info.value = {UIDROPDOWNMENU_MENU_VALUE, i};
 			UIDropDownMenu_AddButton(info, level);
 		end
 	end
 
 end
 
 -- function TradeSkillFilterFrame_InvSlotName(...)
 	-- for i=1, select("#", ...), 1 do
 		-- if ( GetTradeSkillInvSlotFilter(i) ) then
 			-- return select(i, ...);
 		-- end
 	-- end
 -- end
 
 -- function TradeSkillSubClassDropDownButton_OnClick(self)
 	-- UIDropDownMenu_SetSelectedID(TradeSkillSubClassDropDown, self:GetID());
 	-- SetTradeSkillSubClassFilter(self:GetID() - 1, 1, 1);
 	-- if ( self:GetID() ~= 1 ) then
 		-- if ( TradeSkillFilterFrame_InvSlotName(GetTradeSkillInvSlots()) ~= TradeSkillFilterDropDown.selected ) then
 			-- SetTradeSkillInvSlotFilter(0, 1, 1);
 			-- UIDropDownMenu_SetSelectedID(TradeSkillFilterDropDown, 1);
 			-- UIDropDownMenu_SetText(TradeSkillFilterDropDown, FILTER);
 		-- end
 	-- end
 	-- TradeSkillListScrollFrameScrollBar:SetValue(0);
 	-- FauxScrollFrame_SetOffset(TradeSkillListScrollFrame, 0);
 	-- TradeSkillFrame_Update();
 -- end
 
 -- function TradeSkillFilterDropDownButton_OnClick(self)
 	-- UIDropDownMenu_SetSelectedID(TradeSkillFilterDropDown, self:GetID());
 	-- SetTradeSkillInvSlotFilter(self:GetID() - 1, 1, 1);
 	-- --TradeSkillFilterDropDown.selected = TradeSkillFilterFrame_InvSlotName(GetTradeSkillInvSlots());
 	-- TradeSkillListScrollFrameScrollBar:SetValue(0);
 	-- FauxScrollFrame_SetOffset(TradeSkillListScrollFrame, 0);
 	-- TradeSkillFrame_Update();
 -- end
 
 function TradeSkillFrameIncrement_OnClick()
 	if ( TradeSkillInputBox:GetNumber() < 100 ) then
 		TradeSkillInputBox:SetNumber(TradeSkillInputBox:GetNumber() + 1);
 	end
 end
 
 function TradeSkillFrameDecrement_OnClick()
 	if ( TradeSkillInputBox:GetNumber() > 0 ) then
 		TradeSkillInputBox:SetNumber(TradeSkillInputBox:GetNumber() - 1);
 	end
 end
 
 function TradeSkillItem_OnEnter(self)
 	if ( TradeSkillFrame.selectedSkill ~= 0 ) then
 		GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
 		GameTooltip:SetTradeSkillItem(TradeSkillFrame.selectedSkill);
 	end
 	CursorUpdate(self);
 end
 
 function TradeSkillFrame_PlaytimeUpdate()
 	if ( PartialPlayTime() ) then
 		TradeSkillCreateButton:Disable();
 		if (not TradeSkillCreateButtonMask:IsShown()) then
 			TradeSkillCreateButtonMask:Show();
 			TradeSkillCreateButtonMask.tooltip = format(PLAYTIME_TIRED_ABILITY, REQUIRED_REST_HOURS - floor(GetBillingTimeRested()/60));
 		end
 	
 		TradeSkillCreateAllButton:Disable();
 		if (not TradeSkillCreateAllButtonMask:IsShown()) then
 			TradeSkillCreateAllButtonMask:Show();
 			TradeSkillCreateAllButtonMask.tooltip = format(PLAYTIME_TIRED_ABILITY, REQUIRED_REST_HOURS - floor(GetBillingTimeRested()/60));
 		end
 	elseif ( NoPlayTime() ) then
 		TradeSkillCreateButton:Disable();
 		if (not TradeSkillCreateButtonMask:IsShown()) then
 			TradeSkillCreateButtonMask:Show();
 			TradeSkillCreateButtonMask.tooltip = format(PLAYTIME_UNHEALTHY_ABILITY, REQUIRED_REST_HOURS - floor(GetBillingTimeRested()/60));
 		end
 	
 		TradeSkillCreateAllButton:Disable();
 		if (not TradeSkillCreateAllButtonMask:IsShown()) then
 			TradeSkillCreateAllButtonMask:Show();
 			TradeSkillCreateAllButtonMask.tooltip = format(PLAYTIME_UNHEALTHY_ABILITY, REQUIRED_REST_HOURS - floor(GetBillingTimeRested()/60));
 		end
 	else
 		if (TradeSkillCreateButtonMask:IsShown() or TradeSkillCreateAllButtonMask:IsShown()) then
 			TradeSkillCreateButtonMask:Hide();
 			TradeSkillCreateButtonMask.tooltip = nil;
 
 			TradeSkillCreateAllButtonMask:Hide();
 			TradeSkillCreateAllButtonMask.tooltip = nil;
 
 			TradeSkillFrame_SetSelection(TradeSkillFrame.selectedSkill);
 			TradeSkillFrame_Update()
 		end
 	end
 end
 
 function TradeSkillLinkDropDown_LinkPost(self, chan)
 	local link = GetTradeSkillListLink();
 	if link then 
 		ChatFrame_OpenChat(chan.." "..link, DEFAULT_CHAT_FRAME);
 	end
 end
 
 
 function TradeSkillLinkDropDown_OnLoad(self)
 	UIDropDownMenu_Initialize(self, TradeSkillLinkDropDown_Init, "MENU");
 end
 
 function TradeSkillLinkDropDown_Init(self, level)
 
 	local info = UIDropDownMenu_CreateInfo();	
 	info.notCheckable = true;	
 	info.text = TRADESKILL_POST;
 	info.isTitle = 1;
 	UIDropDownMenu_AddButton(info);
 	info.isTitle = nil;
 	
 	info = UIDropDownMenu_CreateInfo();	
 	info.notCheckable = true;
 	info.func = TradeSkillLinkDropDown_LinkPost
 	
 	info.text = GUILD;
 	info.arg1 = SLASH_GUILD1;
 	info.disabled = not IsInGuild();
 	UIDropDownMenu_AddButton(info);
 	
 	info.text = PARTY;
 	info.arg1 = SLASH_PARTY1;
 	info.disabled = GetNumSubgroupMembers() == 0;
 	UIDropDownMenu_AddButton(info);
 	
 	info.text = RAID;
 	info.disabled = not IsInRaid();
 	info.arg1 = SLASH_RAID1;
 	UIDropDownMenu_AddButton(info);
 	-- info.text = SAY;
 	-- info.arg1 = SLASH_SAY1;
 	-- UIDropDownMenu_AddButton(info);
 	
 	info.disabled = false
 	local name;
 	local chanels = {GetChannelList()};
 	local channelCount = #chanels/2;
 	for i=1, MAX_CHANNEL_BUTTONS, 1 do
 		if ( i <= channelCount) then
 			info.text = chanels[i*2];
 			info.arg1 = "/"..chanels[(i-1)*2 + 1];
 			UIDropDownMenu_AddButton(info);
 		end
 	end
 end
 
 --
 -- Guild Crafters
 --
 
 function TradeSkillViewGuildCraftersButton_OnClick()
 	TradeSkillGuildFrame.queriedSkill = TradeSkillFrame.selectedSkill;
 	QueryGuildMembersForRecipe();
 end
 
 function TradeSkillGuildFrame_OnShow()
 	TradeSkillGuildCraftersFrameScrollBar:SetValue(0);
 	TradeSkillGuildCraftersFrame_Update();
 end
 
 function TradeSkillGuildCraftersFrame_Update()
 	local skillLineID, recipeID, numMembers = GetGuildRecipeInfoPostQuery();
 	local offset = FauxScrollFrame_GetOffset(TradeSkillGuildCraftersFrame);
-	local index, button, name, classFileName, online;
+	local index, button, displayName, fullName, classFileName, online;
 	
 	for i = 1, TRADE_SKILL_GUILD_CRAFTERS_DISPLAYED, 1 do
 		index = i + offset;
 		button = _G["TradeSkillGuildCrafter"..i];
 		if ( index > numMembers ) then
 			button:Hide();
 		else
 			displayName, fullName, classFileName, online = GetGuildRecipeMember(index);
 			button:SetText(displayName);
 			if ( online ) then
 				button:Enable();
 				if ( classFileName ) then
 					local classColor = RAID_CLASS_COLORS[classFileName];
 					_G["TradeSkillGuildCrafter"..i.."Text"]:SetTextColor(classColor.r, classColor.g, classColor.b);				
 				end
 			else
 				button:Disable();
 			end
 			button:Show();
 			button.name = fullName;
 		end
 	end
 	FauxScrollFrame_Update(TradeSkillGuildCraftersFrame, numMembers, TRADE_SKILL_GUILD_CRAFTERS_DISPLAYED, TRADE_SKILL_HEIGHT);
 end
 
 function TradeSkillRetrievingFrame_OnUpdate(self, elapsed)
 	if ( not self.timer ) then
 		self.timer = 0.3;
 	elseif ( self.timer < 0 ) then
 		local dotCount = self.dotCount or 0;
 		dotCount = dotCount + 1;
 		if ( dotCount > 3 ) then
 			dotCount = 0;
 		end
 		self.Dots:SetText(string.rep(".", dotCount));
 		self.dotCount = dotCount;
 		self.timer = 0.3;
 	else
 		self.timer = self.timer - elapsed;
 	end
-end
\ No newline at end of file
+end
+
+function TradeSkillFrameLockIcon_OnEnter(self)
+	local skillName, skillType, numAvailable, isExpanded, altVerb, numSkillUps, indentLevel, showProgressBar, currentRank, maxRank, startingRank, displayAsUnavailable, unavailableString = GetTradeSkillInfo(self:GetID());
+	
+	if(unavailableString and unavailableString ~= "") then
+		GameTooltip:SetOwner(self, "ANCHOR_RIGHT");
+		GameTooltip:AddLine(unavailableString, NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b, true);
+		GameTooltip:Show();
+	end
+end
+
+function TradeSkillFrameLockIcon_OnLeave(self)
+	GameTooltip:Hide();
+end