diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 6bd16c9ee6495676215d7e9299c18ba2d1caef0a..2433c14315f3a4f5405c913ba58a1e13c899916b 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -1285,7 +1285,7 @@ void LLFlatListViewEx::filterItems()
 		}
 	}
 
-	rearrangeItems();
+	sort();
 	notifyParentItemsRectChanged();
 }
 
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 8d4430a9ea718c1e31ab7f37024b4145e4a8ab6d..7c4ceb34583884e483b413c7a683e10dff2259e1 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -49,18 +49,6 @@ const LLSD REARRANGE = LLSD().with("rearrange", LLSD());
 static const LLWearableItemNameComparator WEARABLE_NAME_COMPARATOR;
 
 
-bool LLWearableItemNameComparator::doCompare(const LLPanelWearableListItem* wearable_item1, const LLPanelWearableListItem* wearable_item2) const
-{
-	std::string name1 = wearable_item1->getItemName();
-	std::string name2 = wearable_item2->getItemName();
-
-	LLStringUtil::toUpper(name1);
-	LLStringUtil::toUpper(name2);
-
-	return name1 < name2;
-}
-
-
 LLCOFWearables::LLCOFWearables() : LLPanel(),
 	mAttachments(NULL),
 	mClothing(NULL),
diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h
index 612bb103d210eb3b723adcb29fb9327223805f46..583ee962477896cae41cfac37219deb8e340ff4f 100644
--- a/indra/newview/llcofwearables.h
+++ b/indra/newview/llcofwearables.h
@@ -33,59 +33,16 @@
 #ifndef LL_LLCOFWEARABLES_H
 #define LL_LLCOFWEARABLES_H
 
+// llui
+#include "llflatlistview.h"
 #include "llpanel.h"
-#include "llinventorymodel.h"
-#include "llappearancemgr.h"
-#include "llwearableitemslist.h"
-
-class LLFlatListView;
-
-
-/** Abstract comparator of wearable list items */
-class LLWearableListItemComparator : public LLFlatListView::ItemComparator
-{
-	LOG_CLASS(LLWearableListItemComparator);
-
-public:
-	LLWearableListItemComparator() {};
-	virtual ~LLWearableListItemComparator() {};
-
-	virtual bool compare(const LLPanel* item1, const LLPanel* item2) const
-	{
-		const LLPanelWearableListItem* wearable_item1 = dynamic_cast<const LLPanelWearableListItem*>(item1);
-		const LLPanelWearableListItem* wearable_item2 = dynamic_cast<const LLPanelWearableListItem*>(item2);
-
-		if (!wearable_item1 || !wearable_item2)
-		{
-			llwarning("item1 and item2 cannot be null", 0);
-			return true;
-		}
-
-		return doCompare(wearable_item1, wearable_item2);
-	}
 
-protected:
-
-	/** 
-	 * Returns true if wearable_item1 < wearable_item2, false otherwise 
-	 * Implement this method in your particular comparator.
-	 */
-	virtual bool doCompare(const LLPanelWearableListItem* wearable_item1, const LLPanelWearableListItem* wearable_item2) const = 0;
-};
-
-
-class LLWearableItemNameComparator : public LLWearableListItemComparator
-{
-	LOG_CLASS(LLWearableItemNameComparator);
-
-public:
-	LLWearableItemNameComparator() {};
-	virtual ~LLWearableItemNameComparator() {};
-
-protected:
-	virtual bool doCompare(const LLPanelWearableListItem* wearable_item1, const LLPanelWearableListItem* wearable_item2) const;
-};
+#include "llappearancemgr.h"
+#include "llinventorymodel.h"
 
+class LLPanelClothingListItem;
+class LLPanelBodyPartsListItem;
+class LLPanelDeletableWearableListItem;
 
 /**
  * Adaptor between LLAccordionCtrlTab and LLFlatListView to facilitate communication between them 
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index a3863b511cb3be38cac112fe561004ff6366d165..807952948b949293108a7ae351b0c88a954aacea 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -124,6 +124,15 @@ class LLPanelInventoryListItemBase : public LLPanel
 	/** Get the name of a corresponding inventory item */
 	const std::string& getItemName() const { return mItem->getName(); }
 
+	/** Get the asset type of a corresponding inventory item */
+	LLAssetType::EType getType() const { return mItem->getType(); }
+
+	/** Get the wearable type of a corresponding inventory item */
+	LLWearableType::EType getWearableType() const { return mItem->getWearableType(); }
+
+	/** Get the description of a corresponding inventory item */
+	const std::string& getDescription() const { return mItem->getDescription(); }
+
 	virtual ~LLPanelInventoryListItemBase(){}
 
 protected:
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index bac66d966a0ffde3b23a4dec41dbb6588617c9db..b209dfecce7b55a1d6a495756cd9a98fd15ff502 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -296,6 +296,84 @@ std::string LLPanelDummyClothingListItem::wearableTypeToString(LLWearableType::E
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
+/*virtual*/
+bool LLWearableItemNameComparator::doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const
+{
+	std::string name1 = wearable_item1->getItemName();
+	std::string name2 = wearable_item2->getItemName();
+
+	LLStringUtil::toUpper(name1);
+	LLStringUtil::toUpper(name2);
+
+	return name1 < name2;
+}
+
+/*virtual*/
+bool LLWearableItemTypeNameComparator::doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const
+{
+	const LLAssetType::EType item_type1 = wearable_item1->getType();
+	const LLAssetType::EType item_type2 = wearable_item2->getType();
+
+	LLWearableItemTypeNameComparator::ETypeListOrder item_type_order1 = getTypeListOrder(item_type1);
+	LLWearableItemTypeNameComparator::ETypeListOrder item_type_order2 = getTypeListOrder(item_type2);
+
+	if (item_type_order1 != item_type_order2)
+	{
+		// If items are of different asset types we can compare them
+		// by types order in the list.
+		return item_type_order1 < item_type_order2;
+	}
+
+	if (item_type_order1 & TLO_NOT_CLOTHING)
+	{
+		// If both items are of the same asset type except AT_CLOTHING
+		// we can compare them by name.
+		return LLWearableItemNameComparator::doCompare(wearable_item1, wearable_item2);
+	}
+
+	const LLWearableType::EType item_wearable_type1 = wearable_item1->getWearableType();
+	const LLWearableType::EType item_wearable_type2 = wearable_item2->getWearableType();
+
+	if (item_wearable_type1 != item_wearable_type2)
+	{
+		// If items are of different clothing types they are compared
+		// by clothing types order determined in LLWearableType::EType.
+		return item_wearable_type1 < item_wearable_type2;
+	}
+	else
+	{
+		// If both items are of the same clothing type they are compared
+		// by description and place in reverse order i.e. outer layer item
+		// on top.
+		return wearable_item1->getDescription() > wearable_item2->getDescription();
+	}
+}
+
+// static
+LLWearableItemTypeNameComparator::ETypeListOrder LLWearableItemTypeNameComparator::getTypeListOrder(LLAssetType::EType item_type)
+{
+	switch (item_type)
+	{
+	case LLAssetType::AT_OBJECT:
+		return TLO_ATTACHMENT;
+
+	case LLAssetType::AT_CLOTHING:
+		return TLO_CLOTHING;
+
+	case LLAssetType::AT_BODYPART:
+		return TLO_BODYPART;
+
+	default:
+		return TLO_UNKNOWN;
+	}
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+static const LLWearableItemTypeNameComparator WEARABLE_TYPE_NAME_COMPARATOR;
+
 static const LLDefaultChildRegistry::Register<LLWearableItemsList> r("wearable_items_list");
 
 LLWearableItemsList::Params::Params()
@@ -303,7 +381,9 @@ LLWearableItemsList::Params::Params()
 
 LLWearableItemsList::LLWearableItemsList(const LLWearableItemsList::Params& p)
 :	LLInventoryItemsList(p)
-{}
+{
+	setComparator(&WEARABLE_TYPE_NAME_COMPARATOR);
+}
 
 // virtual
 LLWearableItemsList::~LLWearableItemsList()
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index 5e3202c687688471eb5e25f070352a9e3837963e..2cab5a07a2b9380ed809861d1b9149e52b27bbb9 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -171,6 +171,98 @@ class LLPanelDummyClothingListItem : public LLPanelWearableListItem
 	LLWearableType::EType mWearableType;
 };
 
+/**
+ * @class LLWearableListItemComparator
+ *
+ * Abstract comparator of wearable list items.
+ */
+class LLWearableListItemComparator : public LLFlatListView::ItemComparator
+{
+	LOG_CLASS(LLWearableListItemComparator);
+
+public:
+	LLWearableListItemComparator() {};
+	virtual ~LLWearableListItemComparator() {};
+
+	virtual bool compare(const LLPanel* item1, const LLPanel* item2) const
+	{
+		const LLPanelInventoryListItemBase* wearable_item1 = dynamic_cast<const LLPanelInventoryListItemBase*>(item1);
+		const LLPanelInventoryListItemBase* wearable_item2 = dynamic_cast<const LLPanelInventoryListItemBase*>(item2);
+
+		if (!wearable_item1 || !wearable_item2)
+		{
+			llwarning("item1 and item2 cannot be null", 0);
+			return true;
+		}
+
+		return doCompare(wearable_item1, wearable_item2);
+	}
+
+protected:
+
+	/**
+	 * Returns true if wearable_item1 < wearable_item2, false otherwise
+	 * Implement this method in your particular comparator.
+	 */
+	virtual bool doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const = 0;
+};
+
+/**
+ * @class LLWearableItemNameComparator
+ *
+ * Comparator for sorting wearable list items by name.
+ */
+class LLWearableItemNameComparator : public LLWearableListItemComparator
+{
+	LOG_CLASS(LLWearableItemNameComparator);
+
+public:
+	LLWearableItemNameComparator() {};
+	virtual ~LLWearableItemNameComparator() {};
+
+protected:
+	/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const;
+};
+
+/**
+ * @class LLWearableItemTypeNameComparator
+ *
+ * Comparator for sorting wearable list items by type and name.
+ */
+class LLWearableItemTypeNameComparator : public LLWearableItemNameComparator
+{
+	LOG_CLASS(LLWearableItemTypeNameComparator);
+
+public:
+	LLWearableItemTypeNameComparator() {};
+	virtual ~LLWearableItemTypeNameComparator() {};
+
+protected:
+	/**
+	 * Returns "true" if wearable_item1 is placed before wearable_item2 sorted by the following:
+	 *   - Attachments (abc order)
+	 *   - Clothing
+	 *         - by type (types order determined in LLWearableType::EType)
+	 *         - outer layer on top
+	 *   - Body Parts (abc order),
+	 * "false" otherwise.
+	 */
+	/*virtual*/ bool doCompare(const LLPanelInventoryListItemBase* wearable_item1, const LLPanelInventoryListItemBase* wearable_item2) const;
+
+private:
+	enum ETypeListOrder
+	{
+		TLO_ATTACHMENT	= 0x01,
+		TLO_CLOTHING	= 0x02,
+		TLO_BODYPART	= 0x04,
+		TLO_UNKNOWN		= 0x08,
+
+		TLO_NOT_CLOTHING = TLO_ATTACHMENT | TLO_BODYPART | TLO_UNKNOWN
+	};
+
+	static LLWearableItemTypeNameComparator::ETypeListOrder getTypeListOrder(LLAssetType::EType item_type);
+};
+
 /**
  * @class LLWearableItemsList
  *