@@ -11,7 +11,7 @@ VISIBLE_CONTAINER_SPACING = 3;
 CONTAINER_OFFSET_Y = 70;
 CONTAINER_OFFSET_X = 0;
 CONTAINER_SCALE = 0.75;
-BACKPACK_HEIGHT = 240;
+BACKPACK_HEIGHT = 251;
 
 function ContainerFrame_OnLoad(self)
 	self:RegisterEvent("BAG_OPEN");
@@ -43,6 +43,8 @@ function ContainerFrame_OnEvent(self, ev
 		end
 	elseif ( event == "BAG_UPDATE_COOLDOWN" ) then
 		ContainerFrame_UpdateCooldowns(self);
+	elseif ( event == "BAG_NEW_ITEMS_UPDATED") then
+		ContainerFrame_Update(self);
 	elseif ( event == "QUEST_ACCEPTED" or (event == "UNIT_QUEST_LOG_CHANGED" and arg1 == "player") ) then
 		if (self:IsShown()) then
 			ContainerFrame_Update(self);
@@ -51,6 +53,10 @@ function ContainerFrame_OnEvent(self, ev
 		UpdateContainerFrameAnchors();
 	elseif ( event == "INVENTORY_SEARCH_UPDATE" ) then
 		ContainerFrame_UpdateSearchResults(self);
+	elseif ( event == "BAG_SLOT_FLAGS_UPDATED" ) then
+		if (self:IsShown() and self.FilterDropDown:IsShown()) then
+			UIDropDownMenu_RefreshAll(self.FilterDropDown);
+		end
 	end
 end
 
@@ -107,17 +113,21 @@ function ContainerFrame_OnHide(self)
 	self:UnregisterEvent("BAG_UPDATE_COOLDOWN");
 	self:UnregisterEvent("DISPLAY_SIZE_CHANGED");
 	self:UnregisterEvent("INVENTORY_SEARCH_UPDATE");
+	self:UnregisterEvent("BAG_NEW_ITEMS_UPDATED");
+	self:UnregisterEvent("BAG_SLOT_FLAGS_UPDATED");
+
+	UpdateNewItemList(self);
 
 	if ( self:GetID() == 0 ) then
-		MainMenuBarBackpackButton:SetChecked(0);
+		MainMenuBarBackpackButton:SetChecked(false);
 	else
 		local bagButton = _G["CharacterBag"..(self:GetID() - 1).."Slot"];
 		if ( bagButton ) then
-			bagButton:SetChecked(0);
+			bagButton:SetChecked(false);
 		else
 			-- If its a bank bag then update its highlight
 			
-			UpdateBagButtonHighlight(self:GetID()); 
+			UpdateBagButtonHighlight(self:GetID() - NUM_BAG_SLOTS); 
 		end
 	end
 	ContainerFrame1.bagsShown = ContainerFrame1.bagsShown - 1;
@@ -143,6 +153,13 @@ function ContainerFrame_OnHide(self)
 		UpdateMicroButtons();
 		PlaySound("KeyRingClose");
 	else
+		if ( self:GetID() == 0 ) then
+			SetCVarBitfield("closedInfoFrames", LE_FRAME_TUTORIAL_CLEAN_UP_BAGS, true);
+		end
+		if ( BagHelpBox:IsShown() and BagHelpBox.owner == self ) then
+			BagHelpBox.owner = nil;
+			BagHelpBox:Hide();
+		end
 		PlaySound("igBackPackClose");
 	end
 end
@@ -153,16 +170,28 @@ function ContainerFrame_OnShow(self)
 	self:RegisterEvent("BAG_UPDATE_COOLDOWN");
 	self:RegisterEvent("DISPLAY_SIZE_CHANGED");
 	self:RegisterEvent("INVENTORY_SEARCH_UPDATE");
+	self:RegisterEvent("BAG_NEW_ITEMS_UPDATED");
+	self:RegisterEvent("BAG_SLOT_FLAGS_UPDATED");
 
 	if ( self:GetID() == 0 ) then
-		MainMenuBarBackpackButton:SetChecked(1);
+		if ( not GetCVarBitfield("closedInfoFrames", LE_FRAME_TUTORIAL_CLEAN_UP_BAGS) ) then
+			BagHelpBox:ClearAllPoints();
+			BagHelpBox:SetPoint("RIGHT", BagItemAutoSortButton, "LEFT", -24, 0);
+			BagHelpBox.Text:SetText(CLEAN_UP_BAGS_TUTORIAL);
+			BagHelpBox.owner = self;
+			BagHelpBox:Show();
+		end
+		MainMenuBarBackpackButton:SetChecked(true);
 	elseif ( self:GetID() <= NUM_BAG_SLOTS ) then 
 		local button = _G["CharacterBag"..(self:GetID() - 1).."Slot"];
 		if ( button ) then
-			button:SetChecked(1);
+			button:SetChecked(true);
+		end
+		if ( not ContainerFrame1.allBags ) then
+			CheckBagSettingsTutorial();
 		end
 	else
-		UpdateBagButtonHighlight(self:GetID());
+		UpdateBagButtonHighlight(self:GetID() - NUM_BAG_SLOTS);
 	end
 	ContainerFrame1.bags[ContainerFrame1.bagsShown + 1] = self:GetName();
 	ContainerFrame1.bagsShown = ContainerFrame1.bagsShown + 1;
@@ -200,6 +229,9 @@ function OpenBag(id)
 		if ( not containerShowing ) then
 			ContainerFrame_GenerateFrame(ContainerFrame_GetOpenFrame(), size, id);
 		end
+		if (not ContainerFrame1.allBags) then
+			CheckBagSettingsTutorial();
+		end
 	end
 end
 
@@ -253,7 +285,6 @@ function CloseBackpack()
 	for i=1, NUM_CONTAINER_FRAMES, 1 do
 		local containerFrame = _G["ContainerFrame"..i];
 		if ( containerFrame:IsShown() and (containerFrame:GetID() == 0) and (ContainerFrame1.backpackWasOpen == nil) ) then
-			UpdateNewItemList(containerFrame);
 			containerFrame:Hide();
 			return;
 		end
@@ -271,6 +302,50 @@ function UpdateNewItemList(containerFram
 	end
 end
 
+function CheckBagSettingsTutorial()
+	if (GetCVarBitfield("closedInfoFrames", LE_FRAME_TUTORIAL_CLEAN_UP_BAGS) and not GetCVarBitfield("closedInfoFrames", LE_FRAME_TUTORIAL_BAG_SETTINGS)) then
+		local frame;
+		if (ContainerFrame4:IsShown() and ContainerFrame4:GetID() ~= 0) then
+			frame = ContainerFrame4;
+		else
+			for i=NUM_CONTAINER_FRAMES, 1, -1 do
+				if ( _G["ContainerFrame"..i]:IsShown() and _G["ContainerFrame"..i]:GetID() ~= 0 ) then
+					frame = _G["ContainerFrame"..i];
+					break;
+				end
+			end
+		end
+		if (frame) then
+			BagHelpBox:ClearAllPoints();
+			BagHelpBox:SetPoint("RIGHT", frame.Portrait, "LEFT", -8, 0);
+			BagHelpBox.Text:SetText(BAG_SETTINGS_TUTORIAL);
+			BagHelpBox:Show();
+			BagHelpBox.owner = frame;
+			SetCVarBitfield("closedInfoFrames", LE_FRAME_TUTORIAL_BAG_SETTINGS, true);
+		end
+	end
+end
+
+function SearchBagsForItem(itemID)
+	local slot = -1;
+	for i = 0, NUM_BAG_SLOTS do
+		local found = false;
+		local num = GetContainerNumSlots(i);
+		for j = 1, num do
+			local id = GetContainerItemID(i, j);
+			if (id == itemID and C_NewItems.IsNewItem(i, j)) then
+				slot = i;
+				found = true;
+				break;
+			end
+		end
+		if (found) then
+			break;
+		end
+	end
+	return slot;
+end
+
 function ContainerFrame_GetOpenFrame()
 	for i=1, NUM_CONTAINER_FRAMES, 1 do
 		local frame = _G["ContainerFrame"..i];
@@ -289,27 +364,32 @@ function ContainerFrame_Update(frame)
 	local id = frame:GetID();
 	local name = frame:GetName();
 	local itemButton;
-	local texture, itemCount, locked, quality, readable, _, isFiltered;
+	local texture, itemCount, locked, quality, readable, _, isFiltered, noValue;
 	local isQuestItem, questId, isActive, questTexture;
-	local isNewItem, isBattlePayItem, newItemTexture;
+	local isNewItem, isBattlePayItem, newItemTexture, flash, newItemAnim;
 	local tooltipOwner = GameTooltip:GetOwner();
 	
-	--Update Searchbox
+	--Update Searchbox and sort button
 	if ( id == 0 ) then
 		BagItemSearchBox:SetParent(frame);
-		BagItemSearchBox:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -10, -26);
+		BagItemSearchBox:SetPoint("TOPLEFT", frame, "TOPLEFT", 54, -35);
 		BagItemSearchBox.anchorBag = frame;
 		BagItemSearchBox:Show();
+		BagItemAutoSortButton:SetParent(frame);
+		BagItemAutoSortButton:SetPoint("TOPRIGHT", frame, "TOPRIGHT", -9, -32);
+		BagItemAutoSortButton:Show();
 	elseif ( BagItemSearchBox.anchorBag == frame ) then
 		BagItemSearchBox:ClearAllPoints();
 		BagItemSearchBox:Hide();
 		BagItemSearchBox.anchorBag = nil;
+		BagItemAutoSortButton:ClearAllPoints();
+		BagItemAutoSortButton:Hide();
 	end
-	
+
 	for i=1, frame.size, 1 do
 		itemButton = _G[name.."Item"..i];
 		
-		texture, itemCount, locked, quality, readable, _, _, isFiltered = GetContainerItemInfo(id, itemButton:GetID());
+		texture, itemCount, locked, quality, readable, _, _, isFiltered, noValue = GetContainerItemInfo(id, itemButton:GetID());
 		isQuestItem, questId, isActive = GetContainerItemQuestInfo(id, itemButton:GetID());
 		
 		SetItemButtonTexture(itemButton, texture);
@@ -329,11 +409,51 @@ function ContainerFrame_Update(frame)
 		
 		isNewItem = C_NewItems.IsNewItem(id, itemButton:GetID());
 		isBattlePayItem = IsBattlePayItem(id, itemButton:GetID());
-		newItemTexture = _G[name.."Item"..i.."NewItemTexture"];
-		if ( isNewItem and isBattlePayItem ) then
-			newItemTexture:Show();
+		battlepayItemTexture = _G[name.."Item"..i].BattlepayItemTexture;
+		newItemTexture = _G[name.."Item"..i].NewItemTexture;
+		flash = _G[name.."Item"..i].flashAnim;
+		newItemAnim = _G[name.."Item"..i].newitemglowAnim;
+
+		if ( isNewItem ) then
+			if (isBattlePayItem) then
+				newItemTexture:Hide();
+				battlepayItemTexture:Show();
+			else
+				if (quality and NEW_ITEM_ATLAS_BY_QUALITY[quality]) then
+					newItemTexture:SetAtlas(NEW_ITEM_ATLAS_BY_QUALITY[quality]);
+				else
+					newItemTexture:SetAtlas("bags-glow-white");
+				end
+				battlepayItemTexture:Hide();
+				newItemTexture:Show();
+			end
+			if (not flash:IsPlaying() and not newItemAnim:IsPlaying()) then
+				flash:Play();
+				newItemAnim:Play();
+			end
 		else
+			battlepayItemTexture:Hide();
 			newItemTexture:Hide();
+			if (flash:IsPlaying() or newItemAnim:IsPlaying()) then
+				flash:Stop();
+				newItemAnim:Stop();
+			end
+		end
+		
+		itemButton.JunkIcon:Hide();
+		if (quality) then
+			if (quality >= LE_ITEM_QUALITY_COMMON and BAG_ITEM_QUALITY_COLORS[quality]) then
+				itemButton.IconBorder:Show();
+				itemButton.IconBorder:SetVertexColor(BAG_ITEM_QUALITY_COLORS[quality].r, BAG_ITEM_QUALITY_COLORS[quality].g, BAG_ITEM_QUALITY_COLORS[quality].b);
+			else
+				itemButton.IconBorder:Hide();
+			end
+
+			if (quality == LE_ITEM_QUALITY_POOR and not noValue and MerchantFrame:IsShown()) then
+				itemButton.JunkIcon:Show();
+			end
+		else
+			itemButton.IconBorder:Hide();
 		end
 				
 		if ( texture ) then
@@ -346,7 +466,11 @@ function ContainerFrame_Update(frame)
 		itemButton.readable = readable;
 		
 		if ( itemButton == tooltipOwner ) then
-			itemButton.UpdateTooltip(itemButton);
+			if (GetContainerItemInfo(frame:GetID(), itemButton:GetID())) then
+				itemButton.UpdateTooltip(itemButton);
+			else
+				GameTooltip:Hide();
+			end
 		end
 		
 		
@@ -358,6 +482,15 @@ function ContainerFrame_Update(frame)
 	end
 end
 
+function ContainerFrame_UpdateAll()
+	for i = 1, NUM_CONTAINER_FRAMES, 1 do
+		local frame = _G["ContainerFrame"..i];
+		if (frame:IsShown()) then
+			ContainerFrame_Update(frame);
+		end
+	end
+end
+
 function ContainerFrame_UpdateSearchResults(frame)
 	local id = frame:GetID();
 	local name = frame:GetName().."Item";
@@ -365,7 +498,7 @@ function ContainerFrame_UpdateSearchResu
 	local _, isFiltered;
 	
 	for i=1, frame.size, 1 do
-		itemButton = _G[name..i];
+		itemButton = _G[name..i] or frame["Item"..i];
 		_, _, _, _, _, _, _, isFiltered = GetContainerItemInfo(id, itemButton:GetID());	
 		if ( isFiltered ) then
 			itemButton.searchOverlay:Show();
@@ -577,7 +710,7 @@ function ContainerFrame_GenerateFrame(fr
 			if ( i == 1 ) then
 				-- Anchor the first item differently if its the backpack frame
 				if ( id == 0 ) then
-					itemButton:SetPoint("BOTTOMRIGHT", name, "TOPRIGHT", -12, -208);
+					itemButton:SetPoint("BOTTOMRIGHT", name, "TOPRIGHT", -12, -221);
 				else
 					itemButton:SetPoint("BOTTOMRIGHT", name, "BOTTOMRIGHT", -12, 9);
 				end
@@ -795,7 +928,7 @@ function ContainerFrameItemButton_OnClic
 				return;
 			end
 		end
-		UseContainerItem(self:GetParent():GetID(), self:GetID());
+		UseContainerItem(self:GetParent():GetID(), self:GetID(), nil, BankFrame:IsShown() and (BankFrame.selectedTab == 2));
 		StackSplitFrame:Hide();
 	end
 end
@@ -836,9 +969,17 @@ function ContainerFrameItemButton_OnEnte
 
 	C_NewItems.RemoveNewItem(self:GetParent():GetID(), self:GetID());
 
-	newItemTexture = _G[self:GetName().."NewItemTexture"];
-	if newItemTexture then
-		newItemTexture:Hide();
+	local newItemTexture = self.NewItemTexture;
+	local battlepayItemTexture = self.BattlepayItemTexture;
+	local flash = self.flashAnim;
+	local newItemGlowAnim = self.newitemglowAnim;
+	
+	newItemTexture:Hide();
+	battlepayItemTexture:Hide();
+	
+	if (flash:IsPlaying() or newItemGlowAnim:IsPlaying()) then
+		flash:Stop();
+		newItemGlowAnim:Stop();
 	end
 	
 	local showSell = nil;
@@ -853,7 +994,7 @@ function ContainerFrameItemButton_OnEnte
 	end
 
 	if ( InRepairMode() and (repairCost and repairCost > 0) ) then
-		GameTooltip:AddLine(REPAIR_COST, "", 1, 1, 1);
+		GameTooltip:AddLine(REPAIR_COST, nil, nil, nil, true);
 		SetTooltipMoney(GameTooltip, repairCost);
 		GameTooltip:Show();
 	elseif ( MerchantFrame:IsShown() and MerchantFrame.selectedTab == 1 ) then
@@ -893,10 +1034,13 @@ function ToggleAllBags()
 		end
 	end
 	if (bagsOpen < totalBags) then
+		ContainerFrame1.allBags = true;
 		OpenBackpack();
 		for i=1, NUM_BAG_FRAMES, 1 do
 			OpenBag(i);
 		end
+		ContainerFrame1.allBags = false;
+		CheckBagSettingsTutorial();
 	elseif( BankFrame:IsShown() ) then
 		bagsOpen = 0;
 		totalBags = 0;
@@ -910,10 +1054,13 @@ function ToggleAllBags()
 			end
 		end
 		if (bagsOpen < totalBags) then
+			ContainerFrame1.allBags = true;
 			OpenBackpack();
 			for i=1, NUM_CONTAINER_FRAMES, 1 do
 				OpenBag(i);
 			end
+			ContainerFrame1.allBags = false;
+			CheckBagSettingsTutorial();
 		end
 	end
 end
@@ -933,14 +1080,17 @@ function OpenAllBags(frame)
 	if( frame and not FRAME_THAT_OPENED_BAGS ) then
 		FRAME_THAT_OPENED_BAGS = frame:GetName();
 	end
-	
+
+	ContainerFrame1.allBags = true;
 	OpenBackpack();
 	for i=1, NUM_BAG_FRAMES, 1 do
 		OpenBag(i);
 	end
+	ContainerFrame1.allBags = false;
+	CheckBagSettingsTutorial();
 end
 
-function CloseAllBags(frame)
+function CloseAllBags(frame)	
 	if( frame ) then
 		if ( frame:GetName() == FRAME_THAT_OPENED_BAGS) then
 			FRAME_THAT_OPENED_BAGS = nil;
@@ -966,74 +1116,87 @@ function CloseAllBags()
 	end
 end
 
-
---KeyRing functions
-
-function PutKeyInKeyRing()
-	local texture;
-	local emptyKeyRingSlot;
-	for i=1, GetKeyRingSize() do
-		texture = GetContainerItemInfo(KEYRING_CONTAINER, i);
-		if ( not texture ) then
-			emptyKeyRingSlot = i;
-			break;
-		end
-	end
-	if ( emptyKeyRingSlot ) then
-		PickupContainerItem(KEYRING_CONTAINER, emptyKeyRingSlot);
-	else
-		UIErrorsFrame:AddMessage(NO_EMPTY_KEYRING_SLOTS, 1.0, 0.1, 0.1, 1.0);
-	end
-end
-
-function ToggleKeyRing()
-	if ( IsOptionFrameOpen() ) then
-		return;
-	end
-	
-	local shownContainerID = IsBagOpen(KEYRING_CONTAINER);
-	if ( shownContainerID ) then
-		_G["ContainerFrame"..shownContainerID]:Hide();
+function GetBackpackFrame()
+	local index = IsBagOpen(0);
+	if ( index ) then
+		return _G["ContainerFrame"..index];
 	else
-		ContainerFrame_GenerateFrame(ContainerFrame_GetOpenFrame(), GetKeyRingSize(), KEYRING_CONTAINER);
+		return nil;
 	end
 end
 
-function GetKeyRingSize()
-	local numKeyringSlots = GetContainerNumSlots(KEYRING_CONTAINER);
-	local maxSlotNumberFilled = 0;
-	local numItems = 0;
-	for i=1, numKeyringSlots do
-		local texture = GetContainerItemInfo(KEYRING_CONTAINER, i);
-		-- Update max slot
-		if ( texture and i > maxSlotNumberFilled) then
-			maxSlotNumberFilled = i;
-		end
-		-- Count how many items you have
-		if ( texture ) then
-			numItems = numItems + 1;
+-- Filters
+BAG_FILTER_LABELS = {
+	[LE_BAG_FILTER_FLAG_EQUIPMENT] = BAG_FILTER_EQUIPMENT,
+	[LE_BAG_FILTER_FLAG_CONSUMABLES] = BAG_FILTER_CONSUMABLES,
+	[LE_BAG_FILTER_FLAG_TRADE_GOODS] = BAG_FILTER_TRADE_GOODS,
+	[LE_BAG_FILTER_FLAG_JUNK] = BAG_FILTER_JUNK,
+};
+
+function ContainerFrameFilterDropDown_OnLoad(self)
+	UIDropDownMenu_Initialize(self, ContainerFrameFilterDropDown_Initialize, "MENU");
+end
+
+function ContainerFrameFilterDropDown_Initialize(self, level)
+	local id = self:GetParent():GetID();
+
+	local info = UIDropDownMenu_CreateInfo();	
+
+	if (id > 0 and id <= NUM_BAG_SLOTS) then
+		info.text = BAG_FILTER_ASSIGN_TO;
+		info.isTitle = 1;
+		info.notCheckable = 1;
+		UIDropDownMenu_AddButton(info);
+
+		info.isTitle = nil;
+		info.notCheckable = nil;
+		info.tooltipWhileDisabled = 1;
+		info.tooltipOnButton = 1;
+
+		for i = LE_BAG_FILTER_FLAG_EQUIPMENT, NUM_LE_BAG_FILTER_FLAGS do
+			if ( i ~= LE_BAG_FILTER_FLAG_JUNK ) then
+				info.text = BAG_FILTER_LABELS[i];
+				info.func = function(_, _, _, value)
+					SetBagSlotFlag(id, i, not value);
+				end;
+				info.checked = GetBagSlotFlag(id, i);
+				info.disabled = nil;
+				info.tooltipTitle = nil;
+				UIDropDownMenu_AddButton(info);
+			end
 		end
 	end
 
-	-- Round to the nearest 4 rows that will hold the keys
-	local modulo = maxSlotNumberFilled % 4;
-	local size;
-	if ( (modulo == 0) and (numItems < maxSlotNumberFilled) ) then
-		size = maxSlotNumberFilled;
-	else
-		-- Only expand if the number of keys in the keyring exceed or equal the max slot filled
-		size = maxSlotNumberFilled + (4 - modulo);
-	end	
-	size = min(size, numKeyringSlots);
-
-	return size;
-end
-
-function GetBackpackFrame()
-	local index = IsBagOpen(0);
-	if ( index ) then
-		return _G["ContainerFrame"..index];
+	info.text = BAG_FILTER_CLEANUP;
+	info.isTitle = 1;
+	info.notCheckable = 1;
+	UIDropDownMenu_AddButton(info);
+
+	info.isTitle = nil;
+	info.notCheckable = nil;
+	info.isNotRadio = true;
+	info.disabled = nil;
+
+	info.text = BAG_FILTER_IGNORE;
+	info.func = function(_, _, _, value)
+		if (id == -1) then
+			SetBankAutosortDisabled(not value);
+		elseif (id == 0) then
+			SetBackpackAutosortDisabled(not value);
+		elseif (id > NUM_BAG_SLOTS) then
+			SetBankBagSlotAutosortDisabled(id, not value);
+		else
+			SetBagSlotFlag(id, LE_BAG_FILTER_FLAG_IGNORE_CLEANUP, not value);
+		end
+	end;
+	if (id == -1) then
+		info.checked = GetBankAutosortDisabled();
+	elseif (id == 0) then
+		info.checked = GetBackpackAutosortDisabled();
+	elseif (id > NUM_BAG_SLOTS) then
+		info.checked = GetBankBagSlotAutosortDisabled(id);
 	else
-		return nil;
+		info.checked = GetBagSlotFlag(id, LE_BAG_FILTER_FLAG_IGNORE_CLEANUP);
 	end
+	UIDropDownMenu_AddButton(info);
 end