diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 5a076845da2ecd369190c4e1c82c285ed2bd5dda..3c3894d1f53f291d3eebdbe8da75583012f84575 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1305,16 +1305,8 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
 		return false;
 	}
 
-	// Check whether the outfit contains any non-worn wearables.
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ true);
-	gInventory.collectDescendentsIf(outfit_cat_id,
-		cats,
-		items,
-		LLInventoryModel::EXCLUDE_TRASH,
-		not_worn);
-	return items.size() > 0;
+	// Check whether the outfit contains the full set of body parts (shape+skin+hair+eyes).
+	return getCanMakeFolderIntoOutfit(outfit_cat_id);
 }
 
 void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)
@@ -2514,29 +2506,17 @@ void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
 
 	switch (item_to_remove->getType())
 	{
-	case LLAssetType::AT_CLOTHING:
-		if (get_is_item_worn(id_to_remove))
-		{
-			//*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
-			LLWearableBridge::removeItemFromAvatar(item_to_remove);
-		}
-		break;
-	case LLAssetType::AT_OBJECT:
-		gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
-		gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
-		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_to_remove->getLinkedUUID());
-		gMessageSystem->sendReliable( gAgent.getRegion()->getHost());
-
-		{
-			// this object might have been selected, so let the selection manager know it's gone now
-			LLViewerObject *found_obj = gObjectList.findObject(item_to_remove->getLinkedUUID());
-			if (found_obj)
+		case LLAssetType::AT_CLOTHING:
+			if (get_is_item_worn(id_to_remove))
 			{
-				LLSelectMgr::getInstance()->remove(found_obj);
-			};
-		}
-	default: break;
+				//*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
+				LLWearableBridge::removeItemFromAvatar(item_to_remove);
+			}
+			break;
+		case LLAssetType::AT_OBJECT:
+			LLVOAvatarSelf::detachAttachmentIntoInventory(item_to_remove->getLinkedUUID());
+		default:
+			break;
 	}
 
 	// *HACK: Force to remove garbage from COF.
@@ -2676,7 +2656,6 @@ void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
 	mAttachmentInvLinkEnabled = val;
 }
 
-// BAP TODO - mRegisteredAttachments is currently maintained but not used for anything.  Consider yanking.
 void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
 {
        llinfos << msg << llendl;
@@ -2696,7 +2675,6 @@ void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
 
 void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
 {
-       mRegisteredAttachments.insert(item_id);
 	   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
 
 	   if (mAttachmentInvLinkEnabled)
@@ -2714,7 +2692,6 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
 
 void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
 {
-       mRegisteredAttachments.erase(item_id);
 	   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
 
 	   if (mAttachmentInvLinkEnabled)
@@ -2727,18 +2704,6 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
 	   }
 }
 
-void LLAppearanceMgr::linkRegisteredAttachments()
-{
-	for (std::set<LLUUID>::iterator it = mRegisteredAttachments.begin();
-		 it != mRegisteredAttachments.end();
-		 ++it)
-	{
-		LLUUID item_id = *it;
-		addCOFItemLink(item_id, false);
-	}
-	mRegisteredAttachments.clear();
-}
-
 BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
 {
 	return gInventory.isObjectDescendentOf(obj_id, getCOF());
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 796ac5c572e493405a4701d39507a24ffe493aeb..67c74e03432623e2a6ab188bece6952450199200 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -123,7 +123,6 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	void unregisterAttachment(const LLUUID& item_id);
 	void registerAttachment(const LLUUID& item_id);
 	void setAttachmentInvLinkEnable(bool val);
-	void linkRegisteredAttachments();
 
 	// utility function for bulk linking.
 	void linkAll(const LLUUID& category,
@@ -210,7 +209,6 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 
 	void setOutfitLocked(bool locked);
 
-	std::set<LLUUID> mRegisteredAttachments;
 	bool mAttachmentInvLinkEnabled;
 	bool mOutfitIsDirty;
 	bool mIsInUpdateAppearanceFromCOF; // to detect recursive calls.
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index 0bd8215e5cdb2115d2ba2c64b0bff3b0cd4263ca..307c937f6e57031ad5ef0217a210ee06dfb5e64b 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -47,7 +47,6 @@
 #include "llbutton.h"
 #include "llgroupactions.h"
 #include "llscrolllistctrl.h"
-#include "llselectmgr.h"
 #include "lltextbox.h"
 #include "lluictrlfactory.h"
 #include "lltrans.h"
@@ -90,15 +89,13 @@ BOOL LLFloaterGroupPicker::postBuild()
 		list_ctrl->setContextMenu(LLScrollListCtrl::MENU_GROUP);
 	}
 	
-	LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterGroupPicker::onBtnCancel, this));
-
 	childSetAction("OK", onBtnOK, this);
 
 	childSetAction("Cancel", onBtnCancel, this);
 
 	setDefaultBtn("OK");
 
-	getChildView("OK")->setEnabled(TRUE);
+	childEnable("OK");
 
 	return TRUE;
 }
@@ -179,8 +176,8 @@ void LLPanelGroups::reset()
 	{
 		group_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
 	}
-	getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count()));
-	getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",MAX_AGENT_GROUPS));
+	childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count()));
+	childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS));
 
 	init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID());
 	enableButtons();
@@ -190,8 +187,8 @@ BOOL LLPanelGroups::postBuild()
 {
 	childSetCommitCallback("group list", onGroupList, this);
 
-	getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count()));
-	getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",MAX_AGENT_GROUPS));
+	childSetTextArg("groupcount", "[COUNT]", llformat("%d",gAgent.mGroups.count()));
+	childSetTextArg("groupcount", "[MAX]", llformat("%d",MAX_AGENT_GROUPS));
 
 	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("group list");
 	if (list)
@@ -231,25 +228,25 @@ void LLPanelGroups::enableButtons()
 
 	if(group_id != gAgent.getGroupID())
 	{
-		getChildView("Activate")->setEnabled(TRUE);
+		childEnable("Activate");
 	}
 	else
 	{
-		getChildView("Activate")->setEnabled(FALSE);
+		childDisable("Activate");
 	}
 	if (group_id.notNull())
 	{
-		getChildView("Info")->setEnabled(TRUE);
-		getChildView("IM")->setEnabled(TRUE);
-		getChildView("Leave")->setEnabled(TRUE);
+		childEnable("Info");
+		childEnable("IM");
+		childEnable("Leave");
 	}
 	else
 	{
-		getChildView("Info")->setEnabled(FALSE);
-		getChildView("IM")->setEnabled(FALSE);
-		getChildView("Leave")->setEnabled(FALSE);
+		childDisable("Info");
+		childDisable("IM");
+		childDisable("Leave");
 	}
-	getChildView("Create")->setEnabled(gAgent.canJoinGroups());
+	childSetEnabled("Create", gAgent.canJoinGroups());
 }
 
 
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index ab36a7615343cf6c65821f6e56654422f0fd3009..81f00af94863d662da34175e7be8f876f22da471 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -62,7 +62,6 @@
 #include "llviewerwindow.h"
 #include "llvoavatar.h"
 #include "llfloaterproperties.h"
-#include "llnotificationsutil.h"
 
 // Linden library includes
 #include "lldbstrings.h"
@@ -105,7 +104,6 @@ void copy_selected_item(void* user_data);
 void open_selected_items(void* user_data);
 void properties_selected_items(void* user_data);
 void paste_items(void* user_data);
-void renamer_focus_lost( LLFocusableElement* handler, void* user_data );
 
 
 //---------------------------------------------------------------------------
@@ -185,6 +183,7 @@ LLFolderView::LLFolderView(const Params& p)
 	mSourceID(p.task_id),
 	mRenameItem( NULL ),
 	mNeedsScroll( FALSE ),
+	mEnableScroll( true ),
 	mUseLabelSuffix(p.use_label_suffix),
 	mPinningSelectedItem(FALSE),
 	mNeedsAutoSelect( FALSE ),
@@ -250,7 +249,7 @@ LLFolderView::LLFolderView(const Params& p)
 	text_p.name(std::string(p.name));
 	text_p.font(font);
 	text_p.visible(false);
-	text_p.parse_urls(true);
+	text_p.allow_html(true);
 	text_p.wrap(true); // allow multiline text. See EXT-7564, EXT-7047
 	// set text padding the same as in People panel. EXT-7047, EXT-4837
 	text_p.h_pad(STATUS_TEXT_HPAD);
@@ -275,6 +274,8 @@ LLFolderView::LLFolderView(const Params& p)
 // Destroys the object
 LLFolderView::~LLFolderView( void )
 {
+	closeRenamer();
+
 	// The release focus call can potentially call the
 	// scrollcontainer, which can potentially be called with a partly
 	// destroyed scollcontainer. Just null it out here, and no worries
@@ -290,8 +291,6 @@ LLFolderView::~LLFolderView( void )
 
 	LLView::deleteViewByHandle(mPopupMenuHandle);
 
-	gViewerWindow->removePopup(mRenamer);
-
 	mAutoOpenItems.removeAllNodes();
 	clearSelection();
 	mItems.clear();
@@ -998,12 +997,7 @@ void LLFolderView::finishRenamingItem( void )
 		mRenameItem->rename( mRenamer->getText() );
 	}
 
-	gViewerWindow->removePopup(mRenamer);
-
-	if( mRenameItem )
-	{
-		setSelectionFromRoot( mRenameItem, TRUE );
-	}
+	closeRenamer();
 
 	// List is re-sorted alphabeticly, so scroll to make sure the selected item is visible.
 	scrollToShowSelection();
@@ -1011,31 +1005,15 @@ void LLFolderView::finishRenamingItem( void )
 
 void LLFolderView::closeRenamer( void )
 {
-	// will commit current name (which could be same as original name)
-	mRenamer->setFocus( FALSE );
-	mRenamer->setVisible( FALSE );
-	gViewerWindow->removePopup(mRenamer);
-
-	if( mRenameItem )
+	if (mRenamer && mRenamer->getVisible())
 	{
-		setSelectionFromRoot( mRenameItem, TRUE );
-		mRenameItem = NULL;
+		// Triggers onRenamerLost() that actually closes the renamer.
+		gViewerWindow->removePopup(mRenamer);
 	}
 }
 
 void LLFolderView::removeSelectedItems( void )
 {
-	if (mSelectedItems.empty()) return;
-	LLSD args;
-	args["QUESTION"] = LLTrans::getString(mSelectedItems.size() > 1 ? "DeleteItems" :  "DeleteItem");
-	LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLFolderView::onItemsRemovalConfirmation, this, _1, _2));
-}
-
-void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	if (option != 0) return; // canceled
-
 	if(getVisible() && getEnabled())
 	{
 		// just in case we're removing the renaming item.
@@ -1455,8 +1433,7 @@ void LLFolderView::startRenamingSelectedItem( void )
 		mRenamer->setVisible( TRUE );
 		// set focus will fail unless item is visible
 		mRenamer->setFocus( TRUE );
-		mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this, _1));
-		mRenamer->setFocusLostCallback(boost::bind(&LLFolderView::onRenamerLost, this, _1));
+		mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this));
 		gViewerWindow->addPopup(mRenamer);
 	}
 }
@@ -1977,10 +1954,7 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 
 void LLFolderView::deleteAllChildren()
 {
-	if(mRenamer == gFocusMgr.getTopCtrl())
-	{
-		gViewerWindow->removePopup(mRenamer);
-	}
+	closeRenamer();
 	LLView::deleteViewByHandle(mPopupMenuHandle);
 	mPopupMenuHandle = LLHandle<LLView>();
 	mRenamer = NULL;
@@ -1991,9 +1965,7 @@ void LLFolderView::deleteAllChildren()
 
 void LLFolderView::scrollToShowSelection()
 {
-	// If items are filtered while background fetch is in progress
-	// scrollbar resets to the first filtered item. See EXT-3981.
-	if (!LLInventoryModelBackgroundFetch::instance().backgroundFetchActive() && mSelectedItems.size())
+	if (mEnableScroll && mSelectedItems.size())
 	{
 		mNeedsScroll = TRUE;
 	}
@@ -2465,13 +2437,20 @@ S32	LLFolderView::notify(const LLSD& info)
 /// Local function definitions
 ///----------------------------------------------------------------------------
 
-void LLFolderView::onRenamerLost( LLFocusableElement* renamer)
+void LLFolderView::onRenamerLost()
 {
-	mRenameItem = NULL;
-	LLUICtrl* uictrl = dynamic_cast<LLUICtrl*>(renamer);
-	if (uictrl)
+	if (mRenamer && mRenamer->getVisible())
 	{
-		uictrl->setVisible(FALSE);
+		mRenamer->setVisible(FALSE);
+
+		// will commit current name (which could be same as original name)
+		mRenamer->setFocus(FALSE);
+	}
+
+	if( mRenameItem )
+	{
+		setSelectionFromRoot( mRenameItem, TRUE );
+		mRenameItem = NULL;
 	}
 }
 
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index f5f229a602957107791ce272ccf6412cd6193584..31352d04bfe03e5a7fbb87b30fe95a71b9c57421 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -274,6 +274,7 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	void dumpSelectionInformation();
 
 	virtual S32	notify(const LLSD& info) ;
+	void setEnableScroll(bool enable_scroll) { mEnableScroll = enable_scroll; }
 	
 	bool useLabelSuffix() { return mUseLabelSuffix; }
 private:
@@ -283,7 +284,7 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	LLScrollContainer* mScrollContainer;  // NULL if this is not a child of a scroll container.
 
 	void commitRename( const LLSD& data );
-	void onRenamerLost( LLFocusableElement* renamer);
+	void onRenamerLost();
 
 	void finishRenamingItem( void );
 	void closeRenamer( void );
@@ -293,8 +294,6 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	
 	BOOL addNoOptions(LLMenuGL* menu) const;
 
-	void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response);
-
 protected:
 	LLHandle<LLView>					mPopupMenuHandle;
 	
@@ -310,6 +309,7 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	LLLineEditor*					mRenamer;
 
 	BOOL							mNeedsScroll;
+	bool							mEnableScroll;
 	BOOL							mPinningSelectedItem;
 	LLRect							mScrollConstraintRect;
 	BOOL							mNeedsAutoSelect;
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 531d4c3ee9a3a68817fc2e537ca0f11e1ad2bd42..ed15f2bd76a50399a22fb066c17252f84d8811fb 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -3957,18 +3957,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
 		LLInventoryItem* item = gInventory.getItem(mUUID);
 		if(item)
 		{
-			gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
-			gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
-			gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			gMessageSystem->addUUIDFast(_PREHASH_ItemID, item->getLinkedUUID());
-			gMessageSystem->sendReliable( gAgent.getRegion()->getHost());
-
-			// this object might have been selected, so let the selection manager know it's gone now
-			LLViewerObject *found_obj = gObjectList.findObject(item->getLinkedUUID());
-			if (found_obj)
-			{
-				LLSelectMgr::getInstance()->remove(found_obj);
-			}
+			LLVOAvatarSelf::detachAttachmentIntoInventory(item->getLinkedUUID());
 		}
 	}
 	else LLItemBridge::performAction(model, action);
@@ -3985,6 +3974,11 @@ std::string LLObjectBridge::getLabelSuffix() const
 {
 	if (get_is_item_worn(mUUID))
 	{
+		if (!isAgentAvatarValid())
+		{
+			return LLItemBridge::getLabelSuffix() + LLTrans::getString("worn");
+		}
+
 		std::string attachment_point_name = gAgentAvatarp->getAttachedPointName(mUUID);
 
 		// e.g. "(worn on ...)" / "(attached to ...)"
@@ -4329,19 +4323,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
 				LLViewerInventoryItem *obj_item = obj_item_array.get(i);
 				if (get_is_item_worn(obj_item->getUUID()))
 				{
-					gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
-					gMessageSystem->nextBlockFast(_PREHASH_ObjectData );
-					gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-					gMessageSystem->addUUIDFast(_PREHASH_ItemID, obj_item->getLinkedUUID() );
-					
-					gMessageSystem->sendReliable( gAgent.getRegion()->getHost() );
-					
-					// this object might have been selected, so let the selection manager know it's gone now
-					LLViewerObject *found_obj = gObjectList.findObject( obj_item->getLinkedUUID());
-					if (found_obj)
-					{
-						LLSelectMgr::getInstance()->remove(found_obj);
-					}
+					LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID());
 				}
 			}
 		}
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 0464aa377ee6387d81272dc80af2a96da46fd4a9..d76a5c586ff31a41f57283482555872a47744c65 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -42,7 +42,6 @@
 #include "lloutfitobserver.h"
 #include "llcofwearables.h"
 #include "llfilteredwearablelist.h"
-#include "llfolderviewitem.h"
 #include "llinventory.h"
 #include "llinventoryitemslist.h"
 #include "llviewercontrol.h"
@@ -86,11 +85,6 @@ const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK;
 
 static const std::string REVERT_BTN("revert_btn");
 
-
-///////////////////////////////////////////////////////////////////////////////
-// LLShopURLDispatcher
-///////////////////////////////////////////////////////////////////////////////
-
 class LLShopURLDispatcher
 {
 public:
@@ -150,10 +144,6 @@ std::string LLShopURLDispatcher::resolveURL(LLAssetType::EType asset_type, ESex
 	return gSavedSettings.getString(setting_name);
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// LLPanelOutfitEditGearMenu
-///////////////////////////////////////////////////////////////////////////////
-
 class LLPanelOutfitEditGearMenu
 {
 public:
@@ -169,6 +159,7 @@ class LLPanelOutfitEditGearMenu
 		if (menu)
 		{
 			populateCreateWearableSubmenus(menu);
+			menu->buildDrawLabels();
 		}
 
 		return menu;
@@ -217,147 +208,6 @@ class LLPanelOutfitEditGearMenu
 	}
 };
 
-///////////////////////////////////////////////////////////////////////////////
-// LLAddWearablesGearMenu
-///////////////////////////////////////////////////////////////////////////////
-
-class LLAddWearablesGearMenu : public LLInitClass<LLAddWearablesGearMenu>
-{
-public:
-	static LLMenuGL* create(LLWearableItemsList* flat_list, LLInventoryPanel* inventory_panel)
-	{
-		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-
-		llassert(flat_list);
-		llassert(inventory_panel);
-
-		LLHandle<LLView> flat_list_handle = flat_list->getHandle();
-		LLHandle<LLPanel> inventory_panel_handle = inventory_panel->getHandle();
-
-		registrar.add("AddWearable.Gear.Sort", boost::bind(onSort, flat_list_handle, inventory_panel_handle, _2));
-		enable_registrar.add("AddWearable.Gear.Check", boost::bind(onCheck, flat_list_handle, inventory_panel_handle, _2));
-		enable_registrar.add("AddWearable.Gear.Visible", boost::bind(onVisible, inventory_panel_handle, _2));
-
-		LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(
-			"menu_add_wearable_gear.xml",
-			LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
-
-		return menu;
-	}
-
-private:
-	static void onSort(LLHandle<LLView> flat_list_handle,
-					   LLHandle<LLPanel> inventory_panel_handle,
-					   LLSD::String sort_order_str)
-	{
-		if (flat_list_handle.isDead() || inventory_panel_handle.isDead()) return;
-
-		LLWearableItemsList* flat_list = dynamic_cast<LLWearableItemsList*>(flat_list_handle.get());
-		LLInventoryPanel* inventory_panel = dynamic_cast<LLInventoryPanel*>(inventory_panel_handle.get());
-
-		if (!flat_list || !inventory_panel) return;
-
-		LLWearableItemsList::ESortOrder	sort_order;
-
-		if ("by_most_recent" == sort_order_str)
-		{
-			sort_order = LLWearableItemsList::E_SORT_BY_MOST_RECENT;
-		}
-		else if ("by_name" == sort_order_str)
-		{
-			sort_order = LLWearableItemsList::E_SORT_BY_NAME;
-		}
-		else if ("by_type" == sort_order_str)
-		{
-			sort_order = LLWearableItemsList::E_SORT_BY_TYPE_NAME;
-		}
-		else
-		{
-			llwarns << "Unrecognized sort order action" << llendl;
-			return;
-		}
-
-		if (inventory_panel->getVisible())
-		{
-			inventory_panel->setSortOrder(sort_order);
-		}
-		else
-		{
-			flat_list->setSortOrder(sort_order);
-		}
-	}
-
-	static bool onCheck(LLHandle<LLView> flat_list_handle,
-						LLHandle<LLPanel> inventory_panel_handle,
-						LLSD::String sort_order_str)
-	{
-		if (flat_list_handle.isDead() || inventory_panel_handle.isDead()) return false;
-
-		LLWearableItemsList* flat_list = dynamic_cast<LLWearableItemsList*>(flat_list_handle.get());
-		LLInventoryPanel* inventory_panel = dynamic_cast<LLInventoryPanel*>(inventory_panel_handle.get());
-
-		if (!inventory_panel || !flat_list) return false;
-
-		// Inventory panel uses its own sort order independent from
-		// flat list view so this flag is used to distinguish between
-		// currently visible "tree" or "flat" representation of inventory.
-		bool inventory_tree_visible = inventory_panel->getVisible();
-
-		if (inventory_tree_visible)
-		{
-			U32 sort_order = inventory_panel->getSortOrder();
-
-			if ("by_most_recent" == sort_order_str)
-			{
-				return LLWearableItemsList::E_SORT_BY_MOST_RECENT & sort_order;
-			}
-			else if ("by_name" == sort_order_str)
-			{
-				// If inventory panel is not sorted by date then it is sorted by name.
-				return LLWearableItemsList::E_SORT_BY_MOST_RECENT & ~sort_order;
-			}
-			llwarns << "Unrecognized inventory panel sort order" << llendl;
-		}
-		else
-		{
-			LLWearableItemsList::ESortOrder	sort_order = flat_list->getSortOrder();
-
-			if ("by_most_recent" == sort_order_str)
-			{
-				return LLWearableItemsList::E_SORT_BY_MOST_RECENT == sort_order;
-			}
-			else if ("by_name" == sort_order_str)
-			{
-				return LLWearableItemsList::E_SORT_BY_NAME == sort_order;
-			}
-			else if ("by_type" == sort_order_str)
-			{
-				return LLWearableItemsList::E_SORT_BY_TYPE_NAME == sort_order;
-			}
-			llwarns << "Unrecognized wearable list sort order" << llendl;
-		}
-		return false;
-	}
-
-	static bool onVisible(LLHandle<LLPanel> inventory_panel_handle,
-						  LLSD::String sort_order_str)
-	{
-		if (inventory_panel_handle.isDead()) return false;
-
-		LLInventoryPanel* inventory_panel = dynamic_cast<LLInventoryPanel*>(inventory_panel_handle.get());
-
-		// Enable sorting by type only for the flat list of items
-		// because inventory panel doesn't support this kind of sorting.
-		return ( "by_type" == sort_order_str )
-				&&	( !inventory_panel || !inventory_panel->getVisible() );
-	}
-};
-
-///////////////////////////////////////////////////////////////////////////////
-// LLCOFDragAndDropObserver
-///////////////////////////////////////////////////////////////////////////////
-
 class LLCOFDragAndDropObserver : public LLInventoryAddItemByAssetObserver
 {
 public:
@@ -393,17 +243,12 @@ void LLCOFDragAndDropObserver::done()
 	LLAppearanceMgr::instance().updateAppearanceFromCOF();
 }
 
-///////////////////////////////////////////////////////////////////////////////
-// LLPanelOutfitEdit
-///////////////////////////////////////////////////////////////////////////////
-
 LLPanelOutfitEdit::LLPanelOutfitEdit()
 :	LLPanel(), 
 	mSearchFilter(NULL),
 	mCOFWearables(NULL),
 	mInventoryItemsPanel(NULL),
 	mGearMenu(NULL),
-	mAddWearablesGearMenu(NULL),
 	mCOFDragAndDropObserver(NULL),
 	mInitialized(false),
 	mAddWearablesPanel(NULL),
@@ -456,7 +301,7 @@ BOOL LLPanelOutfitEdit::postBuild()
 	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.All"), new LLFindNonLinksByMask(ALL_ITEMS_MASK)));
 	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.Clothing"), new LLIsTypeActual(LLAssetType::AT_CLOTHING)));
 	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.Bodyparts"), new LLIsTypeActual(LLAssetType::AT_BODYPART)));
-	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.Objects"), new LLFindNonLinksByMask(ATTACHMENT_MASK)));;
+	mListViewItemTypes.push_back(new LLFilterItem(getString("Filter.Objects"), new LLFindByMask(ATTACHMENT_MASK)));;
 	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("shape"), new LLFindActualWearablesOfType(LLWearableType::WT_SHAPE)));
 	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("skin"), new LLFindActualWearablesOfType(LLWearableType::WT_SKIN)));
 	mListViewItemTypes.push_back(new LLFilterItem(LLTrans::getString("hair"), new LLFindActualWearablesOfType(LLWearableType::WT_HAIR)));
@@ -481,9 +326,7 @@ BOOL LLPanelOutfitEdit::postBuild()
 
 	childSetCommitCallback("filter_button", boost::bind(&LLPanelOutfitEdit::showWearablesFilter, this), NULL);
 	childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesFolderView, this), NULL);
-	childSetCommitCallback("folder_view_btn", boost::bind(&LLPanelOutfitEdit::saveListSelection, this), NULL);
 	childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::showWearablesListView, this), NULL);
-	childSetCommitCallback("list_view_btn", boost::bind(&LLPanelOutfitEdit::saveListSelection, this), NULL);
 	childSetCommitCallback("wearables_gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);
 	childSetCommitCallback("gear_menu_btn", boost::bind(&LLPanelOutfitEdit::onGearButtonClick, this, _1), NULL);
 	childSetCommitCallback("shop_btn_1", boost::bind(&LLPanelOutfitEdit::onShopButtonClicked, this), NULL);
@@ -543,12 +386,26 @@ BOOL LLPanelOutfitEdit::postBuild()
 
 	childSetAction(REVERT_BTN, boost::bind(&LLAppearanceMgr::wearBaseOutfit, LLAppearanceMgr::getInstance()));
 
+	/*
+	 * By default AT_CLOTHING are sorted by (in in MY OUTFITS):
+	 *  - by type (types order determined in LLWearableType::EType)
+	 *  - each LLWearableType::EType by outer layer on top
+	 *
+	 * In Add More panel AT_CLOTHING should be sorted in a such way:
+	 *  - by type (types order determined in LLWearableType::EType)
+	 *  - each LLWearableType::EType by name (EXT-8205)
+	*/
+	mWearableListViewItemsComparator = new LLWearableItemTypeNameComparator();
+	mWearableListViewItemsComparator->setOrder(LLAssetType::AT_CLOTHING, LLWearableItemTypeNameComparator::ORDER_RANG_1, false, true);
+
 	mWearablesListViewPanel = getChild<LLPanel>("filtered_wearables_panel");
-	mWearableItemsList = getChild<LLWearableItemsList>("list_view");
+	mWearableItemsList = getChild<LLInventoryItemsList>("list_view");
 	mWearableItemsList->setCommitOnSelectionChange(true);
 	mWearableItemsList->setCommitCallback(boost::bind(&LLPanelOutfitEdit::updatePlusButton, this));
 	mWearableItemsList->setDoubleClickCallback(boost::bind(&LLPanelOutfitEdit::onPlusBtnClicked, this));
 
+	mWearableItemsList->setComparator(mWearableListViewItemsComparator);
+
 	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
 	return TRUE;
 }
@@ -586,46 +443,35 @@ void LLPanelOutfitEdit::showAddWearablesPanel(bool show_add_wearables)
 {
 	mAddWearablesPanel->setVisible(show_add_wearables);
 	
-	getChild<LLUICtrl>("show_add_wearables_btn")->setValue(show_add_wearables);
+	childSetValue("show_add_wearables_btn", show_add_wearables);
 
 	updateFiltersVisibility();
-	getChildView("filter_button")->setVisible( show_add_wearables);
+	childSetVisible("filter_button", show_add_wearables);
 
 	//search filter should be disabled
 	if (!show_add_wearables)
 	{
-		getChild<LLUICtrl>("filter_button")->setValue(false);
+		childSetValue("filter_button", false);
 
 		mFolderViewFilterCmbBox->setVisible(false);
 		mListViewFilterCmbBox->setVisible(false);
 
 		showWearablesFilter();
 
-		/*
-		 * By default AT_CLOTHING are sorted by (in in MY OUTFITS):
-		 *  - by type (types order determined in LLWearableType::EType)
-		 *  - each LLWearableType::EType by outer layer on top
-		 *
-		 * In Add More panel AT_CLOTHING should be sorted in a such way:
-		 *  - by type (types order determined in LLWearableType::EType)
-		 *  - each LLWearableType::EType by name (EXT-8205)
-		*/
-		mWearableItemsList->setSortOrder(LLWearableItemsList::E_SORT_BY_TYPE_NAME);
-
 		// Reset mWearableItemsList position to top. See EXT-8180.
 		mWearableItemsList->goToTop();
 	}
 
 	//switching button bars
-	getChildView("no_add_wearables_button_bar")->setVisible( !show_add_wearables);
-	getChildView("add_wearables_button_bar")->setVisible( show_add_wearables);
+	childSetVisible("no_add_wearables_button_bar", !show_add_wearables);
+	childSetVisible("add_wearables_button_bar", show_add_wearables);
 }
 
 void LLPanelOutfitEdit::showWearablesFilter()
 {
-	bool filter_visible = getChild<LLUICtrl>("filter_button")->getValue();
+	bool filter_visible = childGetValue("filter_button");
 
-	getChildView("filter_panel")->setVisible( filter_visible);
+	childSetVisible("filter_panel", filter_visible);
 
 	if(!filter_visible)
 	{
@@ -642,7 +488,9 @@ void LLPanelOutfitEdit::showWearablesListView()
 {
 	if(switchPanels(mInventoryItemsPanel, mWearablesListViewPanel))
 	{
-		updateWearablesPanelVerbButtons();
+		mFolderViewBtn->setToggleState(FALSE);
+		mFolderViewBtn->setImageOverlay(getString("folder_view_off"), mFolderViewBtn->getImageOverlayHAlign());
+		mListViewBtn->setImageOverlay(getString("list_view_on"), mListViewBtn->getImageOverlayHAlign());
 		updateFiltersVisibility();
 	}
 	mListViewBtn->setToggleState(TRUE);
@@ -652,7 +500,9 @@ void LLPanelOutfitEdit::showWearablesFolderView()
 {
 	if(switchPanels(mWearablesListViewPanel, mInventoryItemsPanel))
 	{
-		updateWearablesPanelVerbButtons();
+		mListViewBtn->setToggleState(FALSE);
+		mListViewBtn->setImageOverlay(getString("list_view_off"), mListViewBtn->getImageOverlayHAlign());
+		mFolderViewBtn->setImageOverlay(getString("folder_view_on"), mFolderViewBtn->getImageOverlayHAlign());
 		updateFiltersVisibility();
 	}
 	mFolderViewBtn->setToggleState(TRUE);
@@ -793,17 +643,8 @@ void LLPanelOutfitEdit::onShopButtonClicked()
 	if (isAgentAvatarValid())
 	{
 		// try to get wearable type from 'Add More' panel first (EXT-7639)
-		selection_info_t selection_info = getAddMorePanelSelectionType();
-
-		LLWearableType::EType type = selection_info.first;
+		LLWearableType::EType type = getAddMorePanelSelectionType();
 
-		if (selection_info.second > 1)
-		{
-			// the second argument is not important in this case: generic market place will be opened
-			url = url_resolver.resolveURL(LLWearableType::WT_NONE, SEX_FEMALE);
-		}
-		else
-		{
 		if (type == LLWearableType::WT_NONE)
 		{
 			type = getCOFWearablesSelectionType();
@@ -819,9 +660,7 @@ void LLPanelOutfitEdit::onShopButtonClicked()
 
 		if (url.empty())
 		{
-				url = url_resolver.resolveURL(
-						mCOFWearables->getExpandedAccordionAssetType(), sex);
-			}
+			url = url_resolver.resolveURL(mCOFWearables->getExpandedAccordionAssetType(), sex);
 		}
 	}
 	else
@@ -860,9 +699,9 @@ LLWearableType::EType LLPanelOutfitEdit::getCOFWearablesSelectionType() const
 	return type;
 }
 
-LLPanelOutfitEdit::selection_info_t LLPanelOutfitEdit::getAddMorePanelSelectionType() const
+LLWearableType::EType LLPanelOutfitEdit::getAddMorePanelSelectionType() const
 {
-	selection_info_t result = std::make_pair(LLWearableType::WT_NONE, 0);
+	LLWearableType::EType type = LLWearableType::WT_NONE;
 
 	if (mAddWearablesPanel != NULL && mAddWearablesPanel->getVisible())
 	{
@@ -870,11 +709,9 @@ LLPanelOutfitEdit::selection_info_t LLPanelOutfitEdit::getAddMorePanelSelectionT
 		{
 			std::set<LLUUID> selected_uuids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
 
-			result.second = selected_uuids.size();
-
-			if (result.second == 1)
+			if (selected_uuids.size() == 1)
 			{
-				result.first = getWearableTypeByItemUUID(*(selected_uuids.begin()));
+				type = getWearableTypeByItemUUID(*(selected_uuids.begin()));
 			}
 		}
 		else if (mWearableItemsList != NULL && mWearableItemsList->getVisible())
@@ -882,16 +719,14 @@ LLPanelOutfitEdit::selection_info_t LLPanelOutfitEdit::getAddMorePanelSelectionT
 			std::vector<LLUUID> selected_uuids;
 			mWearableItemsList->getSelectedUUIDs(selected_uuids);
 
-			result.second = selected_uuids.size();
-
-			if (result.second == 1)
+			if (selected_uuids.size() == 1)
 			{
-				result.first = getWearableTypeByItemUUID(selected_uuids.front());
+				type = getWearableTypeByItemUUID(selected_uuids.front());
 			}
 		}
 	}
 
-	return result;
+	return type;
 }
 
 LLWearableType::EType LLPanelOutfitEdit::getWearableTypeByItemUUID(const LLUUID& item_uuid) const
@@ -928,7 +763,7 @@ void LLPanelOutfitEdit::updatePlusButton()
 	}
 
 	// If any of the selected items are not wearable (due to already being worn OR being of the wrong type), disable the add button.
-	uuid_vec_t::iterator unwearable_item = std::find_if(selected_items.begin(), selected_items.end(), !boost::bind(&get_can_item_be_worn, _1));
+	uuid_vec_t::iterator unwearable_item = std::find_if(selected_items.begin(), selected_items.end(), !boost::bind(& get_can_item_be_worn, _1));
 	bool can_add = ( unwearable_item == selected_items.end() );
 
 	mPlusBtn->setEnabled(can_add);
@@ -1176,7 +1011,7 @@ void LLPanelOutfitEdit::updateVerbs()
 	bool has_baseoutfit = LLAppearanceMgr::getInstance()->getBaseOutfitUUID().notNull();
 
 	mSaveComboBtn->setSaveBtnEnabled(!outfit_locked && outfit_is_dirty);
-	getChildView(REVERT_BTN)->setEnabled(outfit_is_dirty && has_baseoutfit);
+	childSetEnabled(REVERT_BTN, outfit_is_dirty && has_baseoutfit);
 
 	mSaveComboBtn->setMenuItemEnabled("save_outfit", !outfit_locked && outfit_is_dirty);
 
@@ -1213,33 +1048,13 @@ void LLPanelOutfitEdit::resetAccordionState()
 
 void LLPanelOutfitEdit::onGearButtonClick(LLUICtrl* clicked_button)
 {
-	LLMenuGL* menu = NULL;
-
-	if (mAddWearablesPanel->getVisible())
+	if(!mGearMenu)
 	{
-		if (!mAddWearablesGearMenu)
-		{
-			mAddWearablesGearMenu = LLAddWearablesGearMenu::create(mWearableItemsList, mInventoryItemsPanel);
-		}
-
-		menu = mAddWearablesGearMenu;
-	}
-	else
-	{
-		if (!mGearMenu)
-		{
-			mGearMenu = LLPanelOutfitEditGearMenu::create();
-		}
-
-		menu = mGearMenu;
+		mGearMenu = LLPanelOutfitEditGearMenu::create();
 	}
 
-	if (!menu) return;
-
-	menu->arrangeAndClear(); // update menu height
-	S32 menu_y = menu->getRect().getHeight() + clicked_button->getRect().getHeight();
-	menu->buildDrawLabels();
-	LLMenuGL::showPopup(clicked_button, menu, 0, menu_y);
+	S32 menu_y = mGearMenu->getRect().getHeight() + clicked_button->getRect().getHeight();
+	LLMenuGL::showPopup(clicked_button, mGearMenu, 0, menu_y);
 }
 
 void LLPanelOutfitEdit::onAddMoreButtonClicked()
@@ -1331,62 +1146,5 @@ void LLPanelOutfitEdit::onCOFChanged()
 	update();
 }
 
-void LLPanelOutfitEdit::updateWearablesPanelVerbButtons()
-{
-	if(mWearablesListViewPanel->getVisible())
-	{
-		mFolderViewBtn->setToggleState(FALSE);
-		mFolderViewBtn->setImageOverlay(getString("folder_view_off"), mFolderViewBtn->getImageOverlayHAlign());
-		mListViewBtn->setImageOverlay(getString("list_view_on"), mListViewBtn->getImageOverlayHAlign());
-	}
-	else if(mInventoryItemsPanel->getVisible())
-	{
-		mListViewBtn->setToggleState(FALSE);
-		mListViewBtn->setImageOverlay(getString("list_view_off"), mListViewBtn->getImageOverlayHAlign());
-		mFolderViewBtn->setImageOverlay(getString("folder_view_on"), mFolderViewBtn->getImageOverlayHAlign());
-	}
-}
-
-void LLPanelOutfitEdit::saveListSelection()
-{
-	if(mWearablesListViewPanel->getVisible())
-	{
-		std::set<LLUUID> selected_ids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
-
-		if(!selected_ids.size()) return;
-
-		for (std::set<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
-		{
-			mWearableItemsList->selectItemByUUID(*item_id, true);
-		}
-		mWearableItemsList->scrollToShowFirstSelectedItem();
-	}
-	else if(mInventoryItemsPanel->getVisible())
-	{
-		std::vector<LLUUID> selected_ids;
-		mWearableItemsList->getSelectedUUIDs(selected_ids);
-
-		if(!selected_ids.size()) return;
-
-		mInventoryItemsPanel->clearSelection();
-		LLFolderView* root = mInventoryItemsPanel->getRootFolder();
-
-		if(!root) return;
-
-		for(std::vector<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
-		{
-			LLFolderViewItem* item = root->getItemByID(*item_id);
-			if (!item) continue;
-
-			LLFolderViewFolder* parent = item->getParentFolder();
-			if(parent)
-			{
-				parent->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
-			}
-			mInventoryItemsPanel->getRootFolder()->changeSelection(item, TRUE);
-		}
-		mInventoryItemsPanel->getRootFolder()->scrollToShowSelection();
-	}
-}
 
 // EOF
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 871ed8d7ec4c7e377f57cb44245b634c59ac2a35..784c2bcad1408af27b051006a5c9f3edca82c5ee 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -43,8 +43,8 @@
 #include "llremoteparcelrequest.h"
 #include "llinventory.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryitemslist.h"
 #include "llinventorymodel.h"
-#include "llwearableitemslist.h"
 
 class LLButton;
 class LLCOFWearables;
@@ -201,17 +201,8 @@ class LLPanelOutfitEdit : public LLPanel
 	void getCurrentItemUUID(LLUUID& selected_id);
 	void onCOFChanged();
 
-	/**
-	 * Method preserves selection while switching between folder/list view modes
-	*/
-	void saveListSelection();
-
-	void updateWearablesPanelVerbButtons();
-
-	typedef std::pair<LLWearableType::EType, size_t> selection_info_t;
-
 	LLWearableType::EType getCOFWearablesSelectionType() const;
-	selection_info_t getAddMorePanelSelectionType() const;
+	LLWearableType::EType getAddMorePanelSelectionType() const;
 	LLWearableType::EType getWearableTypeByItemUUID(const LLUUID& item_uuid) const;
 
 	LLTextBox*			mCurrentOutfitName;
@@ -230,8 +221,9 @@ class LLPanelOutfitEdit : public LLPanel
 	LLComboBox*			mListViewFilterCmbBox;
 
 	LLFilteredWearableListManager* 	mWearableListManager;
-	LLWearableItemsList* 			mWearableItemsList;
+	LLInventoryItemsList* 			mWearableItemsList;
 	LLPanel*						mWearablesListViewPanel;
+	LLWearableItemTypeNameComparator* mWearableListViewItemsComparator;
 
 	LLCOFDragAndDropObserver* mCOFDragAndDropObserver;
 
@@ -240,7 +232,6 @@ class LLPanelOutfitEdit : public LLPanel
 
 	LLCOFWearables*		mCOFWearables;
 	LLMenuGL*			mGearMenu;
-	LLMenuGL*			mAddWearablesGearMenu;
 	bool				mInitialized;
 	std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;
 
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 846cba4a3bd6da827f0b31d9733fa5daa898d478..f4899d0d5d671ce3492aa9f68214c3ab30d0ecaa 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -54,6 +54,7 @@
 #include "llviewertexturelist.h"
 #include "llviewertexture.h"
 #include "llviewerregion.h"
+#include "llviewerstats.h"
 #include "llworld.h"
 
 //////////////////////////////////////////////////////////////////////////////
@@ -150,7 +151,7 @@ class LLTextureFetchWorker : public LLWorkerClass
 	~LLTextureFetchWorker();
 	void relese() { --mActiveCount; }
 
-	void callbackHttpGet(const LLChannelDescriptors& channels,
+	S32 callbackHttpGet(const LLChannelDescriptors& channels,
 						 const LLIOPipe::buffer_ptr_t& buffer,
 						 bool partial, bool success);
 	void callbackCacheRead(bool success, LLImageFormatted* image,
@@ -335,8 +336,9 @@ class HTTPGetResponder : public LLCurl::Responder
 				worker->setGetStatus(status, reason);
 // 				llwarns << "CURL GET FAILED, status:" << status << " reason:" << reason << llendl;
 			}
-			mFetcher->removeFromHTTPQueue(mID);
-			worker->callbackHttpGet(channels, buffer, partial, success);
+			
+			S32 data_size = worker->callbackHttpGet(channels, buffer, partial, success);
+			mFetcher->removeFromHTTPQueue(mID, data_size);
 		}
 		else
 		{
@@ -850,19 +852,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
 	{
 		if(mCanUseHTTP)
 		{
-			// *TODO: Integrate this with llviewerthrottle
-			// Note: LLViewerThrottle uses dynamic throttling which makes sense for UDP,
-			// but probably not for Textures.
-			// Set the throttle to the entire bandwidth, assuming UDP packets will get priority
-			// when they are needed
-			//F32 max_bandwidth = mFetcher->mMaxBandwidth;
-			if (mFetcher->isHTTPThrottled(mDesiredSize))// ||
-				//mFetcher->getTextureBandwidth() > max_bandwidth)
-			{
-				// Make normal priority and return (i.e. wait until there is room in the queue)
-				setPriority(LLWorkerThread::PRIORITY_NORMAL | mWorkPriority);
-				return false;
-			}
+			//NOTE:
+			//it seems ok to let sim control the UDP traffic
+			//so there is no throttle for http here.
+			//
 			
 			mFetcher->removeFromNetworkQueue(this, false);
 			
@@ -979,6 +972,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					else
 					{
 						resetFormattedData();
+						mState = DONE;
 						return true; // failed
 					}
 				}
@@ -1271,8 +1265,7 @@ bool LLTextureFetchWorker::deleteOK()
 
 	if ((haveWork() &&
 		 // not ok to delete from these states
-		 ((mState == WAIT_HTTP_REQ) ||
-		  (mState >= WRITE_TO_CACHE && mState <= WAIT_ON_WRITE))))
+		 ((mState >= WRITE_TO_CACHE && mState <= WAIT_ON_WRITE))))
 	{
 		delete_ok = false;
 	}
@@ -1351,29 +1344,29 @@ bool LLTextureFetchWorker::processSimulatorPackets()
 
 //////////////////////////////////////////////////////////////////////////////
 
-void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
+S32 LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
 										   const LLIOPipe::buffer_ptr_t& buffer,
 										   bool partial, bool success)
 {
+	S32 data_size = 0 ;
+
 	LLMutexLock lock(&mWorkMutex);
 
 	if (mState != WAIT_HTTP_REQ)
 	{
 		llwarns << "callbackHttpGet for unrequested fetch worker: " << mID
 				<< " req=" << mSentRequest << " state= " << mState << llendl;
-		return;
+		return data_size;
 	}
 	if (mLoaded)
 	{
 		llwarns << "Duplicate callback for " << mID.asString() << llendl;
-		return; // ignore duplicate callback
+		return data_size ; // ignore duplicate callback
 	}
 	if (success)
 	{
 		// get length of stream:
-		S32 data_size = buffer->countAfter(channels.in(), NULL);
-
-		gTextureList.sTextureBits += data_size * 8; // Approximate - does not include header bits
+		data_size = buffer->countAfter(channels.in(), NULL);		
 	
 		LL_DEBUGS("Texture") << "HTTP RECEIVED: " << mID.asString() << " Bytes: " << data_size << LL_ENDL;
 		if (data_size > 0)
@@ -1410,6 +1403,8 @@ void LLTextureFetchWorker::callbackHttpGet(const LLChannelDescriptors& channels,
 	}
 	mLoaded = TRUE;
 	setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
+
+	return data_size ;
 }
 
 //////////////////////////////////////////////////////////////////////////////
@@ -1528,15 +1523,11 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
 	  mTextureCache(cache),
 	  mImageDecodeThread(imagedecodethread),
 	  mTextureBandwidth(0),
+	  mHTTPTextureBits(0),
 	  mCurlGetRequest(NULL)
 {
 	mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
 	mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold"));
-	
-	for(S32 i = 0 ; i < TOTAL_TEXTURE_TYPES; i++)
-	{
-		mHTTPThrottleFlag[i] = FALSE ;
-	}
 }
 
 LLTextureFetch::~LLTextureFetch()
@@ -1678,69 +1669,11 @@ void LLTextureFetch::addToHTTPQueue(const LLUUID& id)
 	mHTTPTextureQueue.insert(id);
 }
 
-void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id)
+void LLTextureFetch::removeFromHTTPQueue(const LLUUID& id, S32 received_size)
 {
 	LLMutexLock lock(&mNetworkQueueMutex);
 	mHTTPTextureQueue.erase(id);
-}
-
-void LLTextureFetch::clearHTTPThrottleFlag()
-{
-	static const F32 WAIT_TIME = 0.3f ; //seconds.
-	static LLFrameTimer timer ;
-
-	if(timer.getElapsedTimeF32() < WAIT_TIME) //wait for WAIT_TIME
-	{
-		return ;
-	}
-	timer.reset() ;
-
-	LLMutexLock lock(&mNetworkQueueMutex);
-	for(S32 i = 0 ; i < TOTAL_TEXTURE_TYPES; i++)//reset the http throttle flags.
-	{
-		mHTTPThrottleFlag[i] = FALSE ;
-	}
-}
-
-//check if need to throttle this fetching request.
-//rule: if a request can not be inserted into the http queue due to a full queue,
-//      block all future insertions of requests with larger fetching size requirement.
-//because:
-//      later insertions are usually at lower priorities; and
-//      small textures need chance to be fetched.
-bool LLTextureFetch::isHTTPThrottled(S32 requested_size)
-{
-	static const S32 SMALL_TEXTURE_MAX_SIZE = 64 * 64 * 4 ;
-	static const S32 MEDIUM_TEXTURE_MAX_SIZE = 256 * 256 * 4 ;
-	static const U32 MAX_HTTP_QUEUE_SIZE = 8 ;
-
-	//determine the class of the texture: SMALL, MEDIUM, or LARGE.
-	S32 type = LARGE_TEXTURE ;
-	if(requested_size <= SMALL_TEXTURE_MAX_SIZE)
-	{
-		type = SMALL_TEXTURE ;
-	}
-	else if(requested_size <= MEDIUM_TEXTURE_MAX_SIZE)
-	{
-		type = MEDIUM_TEXTURE ;
-	}
-
-	LLMutexLock lock(&mNetworkQueueMutex);
-
-	if(mHTTPTextureQueue.size() >= MAX_HTTP_QUEUE_SIZE)//if the http queue is full.
-	{
-		if(!mHTTPThrottleFlag[type + 1])
-		{
-			for(S32 i = type + 1 ; i < TOTAL_TEXTURE_TYPES; i++) //block all requests with fetching size larger than this request.		
-			{
-				mHTTPThrottleFlag[i] = TRUE ;			
-			}
-		}
-		
-		return true ;
-	}
-
-	return mHTTPThrottleFlag[type] ; //true if this request can not be inserted to the http queue.
+	mHTTPTextureBits += received_size * 8; // Approximate - does not include header bits	
 }
 
 void LLTextureFetch::deleteRequest(const LLUUID& id, bool cancel)
@@ -1888,12 +1821,19 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
 //virtual
 S32 LLTextureFetch::update(U32 max_time_ms)
 {
-	S32 res;
-	
 	static LLCachedControl<F32> band_width(gSavedSettings,"ThrottleBandwidthKBPS");
-	mMaxBandwidth = band_width ;
-	
-	res = LLWorkerThread::update(max_time_ms);
+
+	{
+		mNetworkQueueMutex.lock() ;
+		mMaxBandwidth = band_width ;
+
+		gTextureList.sTextureBits += mHTTPTextureBits ;
+		mHTTPTextureBits = 0 ;
+
+		mNetworkQueueMutex.unlock() ;
+	}
+
+	S32 res = LLWorkerThread::update(max_time_ms);
 	
 	if (!mDebugPause)
 	{
@@ -1909,7 +1849,6 @@ S32 LLTextureFetch::update(U32 max_time_ms)
 			lldebugs << "processed: " << processed << " messages." << llendl;
 		}
 	}
-	clearHTTPThrottleFlag();
 
 	return res;
 }
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index c31c38b04a5e7c78cacb1f2bb47a2ad3c55a984f..2024165e7e6a63607b49f64a6867b0a57b2260b9 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -94,9 +94,7 @@ class LLTextureFetch : public LLWorkerThread
 	void addToNetworkQueue(LLTextureFetchWorker* worker);
 	void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
 	void addToHTTPQueue(const LLUUID& id);
-	void removeFromHTTPQueue(const LLUUID& id);
-	bool isHTTPThrottled(S32 requested_size);
-	void clearHTTPThrottleFlag();
+	void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0);
 	void removeRequest(LLTextureFetchWorker* worker, bool cancel);
 	// Called from worker thread (during doWork)
 	void processCurlRequests();	
@@ -136,15 +134,7 @@ class LLTextureFetch : public LLWorkerThread
 	F32 mMaxBandwidth;
 	LLTextureInfo mTextureInfo;
 
-	enum
-	{
-		SMALL_TEXTURE = 0 , //size <= 64 * 64
-		MEDIUM_TEXTURE,     //size <= 256 * 256
-		LARGE_TEXTURE,      //size > 256 * 256
-		DUMMY,
-		TOTAL_TEXTURE_TYPES
-	};
-	BOOL mHTTPThrottleFlag[TOTAL_TEXTURE_TYPES];
+	U32 mHTTPTextureBits;
 };
 
 #endif // LL_LLTEXTUREFETCH_H
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 2b4b78d82d73582f4c6cfd24a657dd1fffb9db18..c9335366cddb61826f3803b401bad07d805ebec8 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -35,12 +35,11 @@
 #include "llviewerjointattachment.h"
 
 #include "llagentconstants.h"
-
 #include "llviewercontrol.h"
 #include "lldrawable.h"
 #include "llgl.h"
 #include "llrender.h"
-#include "llvoavatar.h"
+#include "llvoavatarself.h"
 #include "llvolume.h"
 #include "pipeline.h"
 #include "llspatialpartition.h"
@@ -164,6 +163,9 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
 //-----------------------------------------------------------------------------
 BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
 {
+	object->extractAttachmentItemID();
+
+	// Same object reattached
 	if (isObjectAttached(object))
 	{
 		llinfos << "(same object re-attached)" << llendl;
@@ -171,20 +173,19 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
 		// Pass through anyway to let setupDrawable()
 		// re-connect object to the joint correctly
 	}
-
-	// Find the inventory item ID of the attached object
-	LLNameValue* item_id_nv = object->getNVPair("AttachItemID");
-	if( item_id_nv )
+	
+	// Two instances of the same inventory item attached --
+	// Request detach, and kill the object in the meantime.
+	if (getAttachedObject(object->getAttachmentItemID()))
 	{
-		const char* s = item_id_nv->getString();
-		if( s )
-		{
-			LLUUID item_id;
-			item_id.set(s);
-			object->setItemID(item_id);
-			lldebugs << "getNVPair( AttachItemID ) = " << item_id << llendl;
-		}
+		llinfos << "(same object re-attached)" << llendl;
+		object->markDead();
+
+		// If this happens to be attached to self, then detach.
+		LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID());
+		return FALSE;
 	}
+
 	mAttachedObjects.push_back(object);
 	setupDrawable(object);
 	
@@ -207,7 +208,7 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
 	}
 	calcLOD();
 	mUpdateXform = TRUE;
-
+	
 	return TRUE;
 }
 
@@ -303,7 +304,7 @@ void LLViewerJointAttachment::removeObject(LLViewerObject *object)
 	{
 		mUpdateXform = FALSE;
 	}
-	object->setItemID(LLUUID::null);
+	object->setAttachmentItemID(LLUUID::null);
 }
 
 //-----------------------------------------------------------------------------
@@ -429,7 +430,7 @@ const LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &o
 		 ++iter)
 	{
 		const LLViewerObject* attached_object = (*iter);
-		if (attached_object->getItemID() == object_id)
+		if (attached_object->getAttachmentItemID() == object_id)
 		{
 			return attached_object;
 		}
@@ -444,7 +445,7 @@ LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &object_
 		 ++iter)
 	{
 		LLViewerObject* attached_object = (*iter);
-		if (attached_object->getItemID() == object_id)
+		if (attached_object->getAttachmentItemID() == object_id)
 		{
 			return attached_object;
 		}
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 9d4f6fdd0c51d72e4465f043d26697778894618e..9b3243a1bc5e768ce1b2433068e02636eb4abd7a 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -814,7 +814,7 @@ void LLViewerTexture::generateGLTexture()
 LLImageGL* LLViewerTexture::getGLTexture() const
 {
 	llassert(mGLTexturep.notNull()) ;
-	
+
 	return mGLTexturep ;
 }
 
@@ -1489,8 +1489,13 @@ void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
 //virtual
 void LLViewerFetchedTexture::processTextureStats()
 {
-	if(mFullyLoaded)
+	if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) //force to refetch the texture.
 	{
+		mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel) ;
+	}
+
+	if(mFullyLoaded)
+	{		
 		if(mDesiredDiscardLevel <= mMinDesiredDiscardLevel)//already loaded
 		{
 			return ;
@@ -2131,7 +2136,7 @@ void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::so
 void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
 {
 	if(!callback_list)
-{
+	{
 		mPauseLoadedCallBacks = FALSE ;
 		return ;
 	}
@@ -2160,7 +2165,7 @@ void LLViewerFetchedTexture::unpauseLoadedCallbacks(const LLLoadedCallbackEntry:
 void LLViewerFetchedTexture::pauseLoadedCallbacks(const LLLoadedCallbackEntry::source_callback_list_t* callback_list)
 {
 	if(!callback_list)
-{
+	{
 		return ;
 	}
 
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 7e6591a194f769a3c1006fdb7afc2d71e9df1e35..274dbe6332f45c7f11b02564d27258ffedbc5887 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1155,6 +1155,29 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
 	return FALSE;
 }
 
+// static
+BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
+{
+	LLInventoryItem* item = gInventory.getItem(item_id);
+	if (item)
+	{
+		gMessageSystem->newMessageFast(_PREHASH_DetachAttachmentIntoInv);
+		gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+		gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		gMessageSystem->addUUIDFast(_PREHASH_ItemID, item_id);
+		gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
+		
+		// this object might have been selected, so let the selection manager know it's gone now
+		LLViewerObject *found_obj = gObjectList.findObject(item_id);
+		if (found_obj)
+		{
+			LLSelectMgr::getInstance()->remove(found_obj);
+		}
+		return TRUE;
+	}
+	return FALSE;
+}
+
 U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const
 {
 	LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index b129ffd98669306e1bf5c522e4bc1d380b7177bf..21c815a70c7f832f958469dce70846df2d6b7644 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -298,6 +298,7 @@ class LLVOAvatarSelf :
 	const std::string   getAttachedPointName(const LLUUID& inv_item_id) const;
 	/*virtual*/ const LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object);
 	/*virtual*/ BOOL 	detachObject(LLViewerObject *viewer_object);
+	static BOOL			detachAttachmentIntoInventory(const LLUUID& item_id);
 
 private:
 	// Track attachments that have been requested but have not arrived yet.
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index e2a5489fcfcc973c3780cf51479e998a6405c422..5e23965f625cb100127aee5489ef3c995c8f9245 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -478,9 +478,9 @@ LLWearableItemTypeNameComparator::LLWearableItemTypeNameComparator()
 	// 1. CLOTHING - sorted by name
 	// 2. OBJECT   - sorted by type
 	// 3. BODYPART - sorted by name
-	mWearableOrder[LLAssetType::AT_CLOTHING] = LLWearableTypeOrder(ORDER_RANK_1, false, false);
-	mWearableOrder[LLAssetType::AT_OBJECT]   = LLWearableTypeOrder(ORDER_RANK_2, true, true);
-	mWearableOrder[LLAssetType::AT_BODYPART] = LLWearableTypeOrder(ORDER_RANK_3, false, true);
+	mWearableOrder[LLAssetType::AT_CLOTHING] = LLWearableTypeOrder(ORDER_RANG_1, false, false);
+	mWearableOrder[LLAssetType::AT_OBJECT]   = LLWearableTypeOrder(ORDER_RANG_2, true, true);
+	mWearableOrder[LLAssetType::AT_BODYPART] = LLWearableTypeOrder(ORDER_RANG_3, false, true);
 }
 
 void LLWearableItemTypeNameComparator::setOrder(LLAssetType::EType items_of_type,  LLWearableItemTypeNameComparator::ETypeListOrder order_priority, bool sort_asset_items_by_name, bool sort_wearable_items_by_name)
@@ -527,6 +527,8 @@ bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemB
 	const LLWearableType::EType item_wearable_type2 = wearable_item2->getWearableType();
 
 	if (item_wearable_type1 != item_wearable_type2)
+		// If items are of different LLWearableType::EType types they are compared
+		// by LLWearableType::EType. types order determined in LLWearableType::EType.
 	{
 		// If items are of different LLWearableType::EType types they are compared
 		// by LLWearableType::EType. types order determined in LLWearableType::EType.
@@ -549,10 +551,11 @@ LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparato
 {
 	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
 
+
 	if(const_it == mWearableOrder.end())
 	{
 		llwarns<<"Absent information about order rang of items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
-		return ORDER_RANK_UNKNOWN;
+		return ORDER_RANG_UNKNOWN;
 	}
 
 	return const_it->second.mOrderPriority;
@@ -562,49 +565,37 @@ bool LLWearableItemTypeNameComparator::sortAssetTypeByName(LLAssetType::EType it
 {
 	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
 
+
 	if(const_it == mWearableOrder.end())
 	{
 		llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
 		return true;
 	}
 
+
 	return const_it->second.mSortAssetTypeByName;
-	}
+}
+
 
 bool LLWearableItemTypeNameComparator::sortWearableTypeByName(LLAssetType::EType item_type) const
 {
 	wearable_type_order_map_t::const_iterator const_it = mWearableOrder.find(item_type);
 
+
 	if(const_it == mWearableOrder.end())
 	{
 		llwarns<<"Absent information about sorting items of "<<LLAssetType::getDesc(item_type)<<" type"<<llendl;
 		return true;
-}
-
-	return const_it->second.mSortWearableTypeByName;
-}
-
-/*virtual*/
-bool LLWearableItemCreationDateComparator::doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const
-{
-	time_t date1 = item1->getCreationDate();
-	time_t date2 = item2->getCreationDate();
-
-	if (date1 == date2)
-	{
-		return LLWearableItemNameComparator::doCompare(item1, item2);
 	}
 
-	return date1 > date2;
+
+	return const_it->second.mSortWearableTypeByName;
 }
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
-static LLWearableItemTypeNameComparator WEARABLE_TYPE_NAME_COMPARATOR;
-static const LLWearableItemTypeNameComparator WEARABLE_TYPE_LAYER_COMPARATOR;
-static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR;
-static const LLWearableItemCreationDateComparator WEARABLE_CREATION_DATE_COMPARATOR;
+static const LLWearableItemTypeNameComparator WEARABLE_TYPE_NAME_COMPARATOR;
 
 static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");
 
@@ -616,7 +607,7 @@ LLWearableItemsList::Params::Params()
 LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
 :	LLInventoryItemsList(p)
 {
-	setSortOrder(E_SORT_BY_TYPE_LAYER, false);
+	setComparator(&WEARABLE_TYPE_NAME_COMPARATOR);
 	mIsStandalone = p.standalone;
 	if (mIsStandalone)
 	{
@@ -716,38 +707,6 @@ void LLWearableItemsList::onRightClick(S32 x, S32 y)
 	ContextMenu::instance().show(this, selected_uuids, x, y);
 }
 
-void LLWearableItemsList::setSortOrder(ESortOrder sort_order, bool sort_now)
-{
-	switch (sort_order)
-	{
-	case E_SORT_BY_MOST_RECENT:
-		setComparator(&WEARABLE_CREATION_DATE_COMPARATOR);
-		break;
-	case E_SORT_BY_NAME:
-		setComparator(&WEARABLE_NAME_COMPARATOR);
-		break;
-	case E_SORT_BY_TYPE_LAYER:
-		setComparator(&WEARABLE_TYPE_LAYER_COMPARATOR);
-		break;
-	case E_SORT_BY_TYPE_NAME:
-	{
-		WEARABLE_TYPE_NAME_COMPARATOR.setOrder(LLAssetType::AT_CLOTHING, LLWearableItemTypeNameComparator::ORDER_RANK_1, false, true);
-		setComparator(&WEARABLE_TYPE_NAME_COMPARATOR);
-		break;
-	}
-
-	// No "default:" to raise compiler warning
-	// if we're not handling something
-	}
-
-	mSortOrder = sort_order;
-
-	if (sort_now)
-	{
-		sort();
-	}
-}
-
 //////////////////////////////////////////////////////////////////////////
 /// ContextMenu
 //////////////////////////////////////////////////////////////////////////
@@ -818,8 +777,6 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
 	U32 n_links = 0;				// number of links among the selected items
 	U32 n_editable = 0;				// number of editable items among the selected ones
 
-	bool can_be_worn = true;
-
 	for (uuid_vec_t::const_iterator it = ids.begin(); it != ids.end(); ++it)
 	{
 		LLUUID id = *it;
@@ -855,22 +812,16 @@ void LLWearableItemsList::ContextMenu::updateItemsVisibility(LLContextMenu* menu
 		{
 			++n_already_worn;
 		}
-
-		if (can_be_worn)
-		{
-			can_be_worn = get_can_item_be_worn(item->getLinkedUUID());
-		}
 	} // for
 
 	bool standalone = mParent ? mParent->isStandalone() : false;
-	bool wear_add_visible = mask & (MASK_CLOTHING|MASK_ATTACHMENT) && n_worn == 0 && can_be_worn && (n_already_worn != 0 || mask & MASK_ATTACHMENT);
 
 	// *TODO: eliminate multiple traversals over the menu items
-	setMenuItemVisible(menu, "wear_wear", 			n_already_worn == 0 && n_worn == 0 && can_be_worn);
+	setMenuItemVisible(menu, "wear_wear", 			n_already_worn == 0 && n_worn == 0);
 	setMenuItemEnabled(menu, "wear_wear", 			n_already_worn == 0 && n_worn == 0);
-	setMenuItemVisible(menu, "wear_add",			wear_add_visible);
-	setMenuItemEnabled(menu, "wear_add",			canAddWearables(ids));
-	setMenuItemVisible(menu, "wear_replace",		n_worn == 0 && n_already_worn != 0 && can_be_worn);
+	setMenuItemVisible(menu, "wear_add",			mask == MASK_CLOTHING && n_worn == 0 && n_already_worn != 0);
+	setMenuItemEnabled(menu, "wear_add",			n_items == 1 && canAddWearable(ids.front()) && n_already_worn != 0);
+	setMenuItemVisible(menu, "wear_replace",		n_worn == 0 && n_already_worn != 0);
 	//visible only when one item selected and this item is worn
 	setMenuItemVisible(menu, "edit",				!standalone && mask & (MASK_CLOTHING|MASK_BODYPART) && n_worn == n_items && n_worn == 1);
 	setMenuItemEnabled(menu, "edit",				n_editable == 1 && n_worn == 1 && n_items == 1);
@@ -978,61 +929,20 @@ void LLWearableItemsList::ContextMenu::createNewWearable(const LLUUID& item_id)
 	LLAgentWearables::createWearable(item->getWearableType(), true);
 }
 
-// Returns true if all the given objects and clothes can be added.
+// Can we wear another wearable of the given item's wearable type?
 // static
-bool LLWearableItemsList::ContextMenu::canAddWearables(const uuid_vec_t& item_ids)
+bool LLWearableItemsList::ContextMenu::canAddWearable(const LLUUID& item_id)
 {
 	// TODO: investigate wearables may not be loaded at this point EXT-8231
 
-	U32 n_objects = 0;
-	boost::unordered_map<LLWearableType::EType, U32> clothes_by_type;
-
-	// Count given clothes (by wearable type) and objects.
-	for (uuid_vec_t::const_iterator it = item_ids.begin(); it != item_ids.end(); ++it)
-	{
-		LLViewerInventoryItem* item = gInventory.getItem(*it);
-		if (!item)
-		{
-			return false;
-		}
-
-		if (item->getType() == LLAssetType::AT_OBJECT)
-		{
-			++n_objects;
-		}
-		else if (item->getType() == LLAssetType::AT_CLOTHING)
-		{
-			++clothes_by_type[item->getWearableType()];
-		}
-		else
-		{
-			llwarns << "Unexpected wearable type" << llendl;
-			return false;
-		}
-	}
-
-	// Check whether we can add all the objects.
-	if (!isAgentAvatarValid() || !gAgentAvatarp->canAttachMoreObjects(n_objects))
+	LLViewerInventoryItem* item = gInventory.getItem(item_id);
+	if (!item || item->getType() != LLAssetType::AT_CLOTHING)
 	{
 		return false;
 	}
 
-	// Check whether we can add all the clothes.
-	boost::unordered_map<LLWearableType::EType, U32>::const_iterator m_it;
-	for (m_it = clothes_by_type.begin(); m_it != clothes_by_type.end(); ++m_it)
-	{
-		LLWearableType::EType w_type	= m_it->first;
-		U32 n_clothes					= m_it->second;
-
-		U32 wearable_count = gAgentWearables.getWearableCount(w_type);
-		if ((wearable_count + n_clothes) > LLAgentWearables::MAX_CLOTHING_PER_TYPE)
-		{
-			return false;
-		}
-
-	}
-
-	return true;
+	U32 wearable_count = gAgentWearables.getWearableCount(item->getWearableType());
+	return wearable_count < LLAgentWearables::MAX_CLOTHING_PER_TYPE;
 }
 
 // EOF
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index d7970e08389d5b0fc49c16dff44c64e2fc88f0d8..237ba1af437fd45f43dff042a8acd916493621f9 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -313,10 +313,10 @@ class LLWearableItemTypeNameComparator : public LLWearableItemNameComparator
 
 	enum ETypeListOrder
 	{
-		ORDER_RANK_1 = 1,
-		ORDER_RANK_2,
-		ORDER_RANK_3,
-		ORDER_RANK_UNKNOWN
+		ORDER_RANG_1 = 1,
+		ORDER_RANG_2,
+		ORDER_RANG_3,
+		ORDER_RANG_UNKNOWN
 	};
 
 	void setOrder(LLAssetType::EType items_of_type, ETypeListOrder order_priority, bool sort_items_by_name, bool sort_wearable_items_by_name);
@@ -325,28 +325,28 @@ class LLWearableItemTypeNameComparator : public LLWearableItemNameComparator
 	/**
 	 * All information about sort order is stored in mWearableOrder map
 	 *
-	 * mWearableOrder :      KYES              VALUES
+	 * mWearableOrder :      KEYES              VALUES
 	 *                  [LLAssetType] [struct LLWearableTypeOrder]
 	 *
 	 *---------------------------------------------------------------------------------------------
-	 * I. Determines order (ORDER_RANK) in which items of LLAssetType should be displayed in list.
+	 * I. Determines order (ORDER_RANG) in which items of LLAssetType should be displayed in list.
 	 *     For example by spec in MY OUTFITS the order is:
-	 *     1. AT_CLOTHING (ORDER_RANK_1)
-	 *     2. AT_OBJECT   (ORDER_RANK_2)
-	 *     3. AT_BODYPART (ORDER_RANK_3)
+	 *     1. AT_CLOTHING (ORDER_RANG_1)
+	 *     2. AT_OBJECT   (ORDER_RANG_2)
+	 *     3. AT_BODYPART (ORDER_RANG_3)
 	 *
 	 * II.Items of each type(LLAssetType) are sorted by name or type(LLWearableType)
 	 *     For example by spec in MY OUTFITS the order within each items type(LLAssetType) is:
 	 *     1. AT_OBJECTS (abc order)
 	 *     2. AT_CLOTHINGS
-	 *         - by type (types order determined in LLWearableType::EType)
-	 *         - outer layer on top
+	 *       - by type (types order determined in LLWearableType::EType)
+	 *       - outer layer on top
 	 *     3. AT_BODYPARTS  (abc order)
 	 *---------------------------------------------------------------------------------------------
 	 *
 	 * For each LLAssetType (KEYS in mWearableOrder) the information about:
 	 *
-	 *                                             I.  ORDER_RANK (the flag is LLWearableTypeOrder::mOrderPriority)
+	 *                                             I.  ORDER_RANG (the flag is LLWearableTypeOrder::mOrderPriority)
 	 *
 	 *                                             II. whether items of this LLAssetType type should be ordered
 	 *                                                 by name or by LLWearableType::EType (the flag is LLWearableTypeOrder::mSortAssetTypeByName)
@@ -379,19 +379,6 @@ class LLWearableItemTypeNameComparator : public LLWearableItemNameComparator
 	wearable_type_order_map_t mWearableOrder;
 };
 
-/**
- * @class LLWearableItemCreationDateComparator
- *
- * Comparator for sorting wearable list items by creation date (newest go first).
- */
-class LLWearableItemCreationDateComparator : public LLWearableItemNameComparator
-{
-	LOG_CLASS(LLWearableItemCreationDateComparator);
-
-protected:
-	/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* item1, const LLPanelInventoryListItemBase* item2) const;
-};
-
 /**
  * @class LLWearableItemsList
  *
@@ -431,7 +418,7 @@ class LLWearableItemsList : public LLInventoryItemsList
 		static void setMenuItemEnabled(LLContextMenu* menu, const std::string& name, bool val);
 		static void updateMask(U32& mask, LLAssetType::EType at);
 		static void createNewWearable(const LLUUID& item_id);
-		static bool canAddWearables(const uuid_vec_t& item_ids);
+		static bool canAddWearable(const LLUUID& item_id);
 
 		LLWearableItemsList*	mParent;
 	};
@@ -444,14 +431,6 @@ class LLWearableItemsList : public LLInventoryItemsList
 		Params();
 	};
 
-	typedef enum e_sort_order {
-		// Values should be compatible with InventorySortOrder setting.
-		E_SORT_BY_NAME			= 0,
-		E_SORT_BY_MOST_RECENT	= 1,
-		E_SORT_BY_TYPE_LAYER	= 2,
-		E_SORT_BY_TYPE_NAME 	= 3,
-	} ESortOrder;
-
 	virtual ~LLWearableItemsList();
 
 	/*virtual*/ void addNewItem(LLViewerInventoryItem* item, bool rearrange = true);
@@ -466,10 +445,6 @@ class LLWearableItemsList : public LLInventoryItemsList
 
 	bool isStandalone() const { return mIsStandalone; }
 
-	ESortOrder getSortOrder() const { return mSortOrder; }
-
-	void setSortOrder(ESortOrder sort_order, bool sort_now = true);
-
 protected:
 	friend class LLUICtrlFactory;
 	LLWearableItemsList(const LLWearableItemsList::Params& p);
@@ -478,8 +453,6 @@ class LLWearableItemsList : public LLInventoryItemsList
 
 	bool mIsStandalone;
 	bool mWornIndicationEnabled;
-
-	ESortOrder		mSortOrder;
 };
 
 #endif //LL_LLWEARABLEITEMSLIST_H