diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 835cdbca04294a905ac0b76603e466322e018c70..e595cc1f8ba3fee9a2c16e57948e516aa8af8fbd 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -101,7 +101,7 @@ LLAssetDictionary::LLAssetDictionary()
 	addEntry(LLAssetType::AT_IMAGE_TGA, 		new AssetEntry("IMAGE_TGA",			"img_tga",	"targa image",		"Uncompressed Images", DAD_NONE,	FALSE,		TRUE));
 	addEntry(LLAssetType::AT_IMAGE_JPEG, 		new AssetEntry("IMAGE_JPEG",		"jpeg",		"jpeg image",		"Uncompressed Images", DAD_NONE,	FALSE,		TRUE));
 	addEntry(LLAssetType::AT_ANIMATION, 		new AssetEntry("ANIMATION",			"animatn",	"animation",		"Animations", 		DAD_ANIMATION,	FALSE,		TRUE));
-	addEntry(LLAssetType::AT_GESTURE, 			new AssetEntry("GESTURE",			"gesture",	"gesture",			"Gestures", 		DAD_GESTURE,	FALSE,		TRUE));
+	addEntry(LLAssetType::AT_GESTURE, 			new AssetEntry("GESTURE",			"gesture",	"gesture",			"Gestures", 		DAD_GESTURE,	TRUE,		TRUE));
 	addEntry(LLAssetType::AT_SIMSTATE, 			new AssetEntry("SIMSTATE",			"simstate",	"simstate",			"New Folder", 		DAD_NONE,		FALSE,		TRUE));
 	addEntry(LLAssetType::AT_FAVORITE, 			new AssetEntry("FAVORITE",			"favorite",	"favorite",			"favorite", 		DAD_NONE,		FALSE,		TRUE));
 
@@ -116,7 +116,7 @@ LLAssetDictionary::LLAssetDictionary()
 	}
 
 	addEntry(LLAssetType::AT_CURRENT_OUTFIT, 	new AssetEntry("CURRENT",			"current",	"current outfit",	"Current Outfit", 	DAD_CATEGORY,	FALSE,		TRUE));
-	addEntry(LLAssetType::AT_OUTFIT, 			new AssetEntry("OUTFIT",			"outfit",	"outfit",			"Outfit", 			DAD_CATEGORY,	TRUE,		FALSE));
+	addEntry(LLAssetType::AT_OUTFIT, 			new AssetEntry("OUTFIT",			"outfit",	"outfit",			"New Outfit", 		DAD_CATEGORY,	TRUE,		FALSE));
 	addEntry(LLAssetType::AT_MY_OUTFITS, 		new AssetEntry("MY_OUTFITS",		"my_otfts",	"my outfits",		"My Outfits", 		DAD_CATEGORY,	FALSE,		TRUE));
 		 
 	addEntry(LLAssetType::AT_NONE, 				new AssetEntry("NONE",				"-1",		NULL,		  		"New Folder", 		DAD_NONE,		FALSE,		FALSE));
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 4834b31bc74e92c53798625366e5eb44be1172ac..1b496d44cd6e739122a2d8db20aaef2a7c58b9f6 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -44,12 +44,42 @@
 #include "llvoavatarself.h"
 #include "llwearable.h"
 #include "llwearablelist.h"
+#include "llgesturemgr.h"
 
 #include <boost/scoped_ptr.hpp>
 
-// For viewer2.0 internal demo, don't use current outfit folder contents at all during initial startup.  Will reenable
-// this once we're sure this works completely.
-// #define USE_CURRENT_OUTFIT_FOLDER
+#define USE_CURRENT_OUTFIT_FOLDER
+
+//--------------------------------------------------------------------
+// Classes for fetching initial wearables data
+//--------------------------------------------------------------------
+// Outfit folder fetching callback structure.
+class LLInitialWearablesFetch : public LLInventoryFetchDescendentsObserver
+{
+public:
+	LLInitialWearablesFetch() {}
+	~LLInitialWearablesFetch() {}
+	virtual void done();
+
+	struct InitialWearableData
+	{
+		EWearableType mType;
+		U32 mIndex;
+		LLUUID mItemID;
+		LLUUID mAssetID;
+		InitialWearableData(EWearableType type, U32 index, LLUUID itemID, LLUUID assetID) :
+			mType(type), mIndex(index), mItemID(itemID), mAssetID(assetID) { }
+	};
+
+	typedef std::vector<InitialWearableData> initial_wearable_data_vec_t;
+	initial_wearable_data_vec_t mCOFInitialWearables; // Wearables from the Current Outfit Folder
+	initial_wearable_data_vec_t mAgentInitialWearables; // Wearables from the old agent wearables msg
+
+protected:
+	void processInitialWearables();
+};
+
+
 
 LLAgentWearables gAgentWearables;
 
@@ -668,6 +698,9 @@ BOOL LLAgentWearables::isWearingItem(const LLUUID& item_id, BOOL include_linked_
 
 // MULTI-WEARABLE: update for multiple
 // static
+// ! BACKWARDS COMPATIBILITY ! When we stop supporting viewer1.23, we can assume
+// that viewers have a Current Outfit Folder and won't need this message, and thus
+// we can remove/ignore this whole function.
 void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data)
 {
 	// We should only receive this message a single time.  Ignore subsequent AgentWearablesUpdates
@@ -696,7 +729,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
 		// Get the UUID of the current outfit folder (will be created if it doesn't exist)
 		LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
 		
-		LLOutfitFolderFetch* outfit = new LLOutfitFolderFetch();
+		LLInitialWearablesFetch* outfit = new LLInitialWearablesFetch();
 		
 		//lldebugs << "processAgentInitialWearablesUpdate()" << llendl;
 		// Add wearables
@@ -733,8 +766,8 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
 				// MULTI-WEARABLE: TODO: update once messages change.  Currently use results to populate the zeroth element.
 				
 				// Store initial wearables data until we know whether we have the current outfit folder or need to use the data.
-				InitialWearableData * temp_wearable_data = new InitialWearableData(type, 0, item_id, asset_id); // MULTI-WEARABLE: update
-				outfit->mAgentInitialWearables.push_back(temp_wearable_data);
+				LLInitialWearablesFetch::InitialWearableData wearable_data(type, 0, item_id, asset_id); // MULTI-WEARABLE: update
+				outfit->mAgentInitialWearables.push_back(wearable_data);
 				
 			}
 			
@@ -761,52 +794,11 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
 	}
 }
 
-// static 
-void LLAgentWearables::fetchInitialWearables(initial_wearable_data_vec_t & current_outfit_links, initial_wearable_data_vec_t & message_wearables)
-{
-#ifdef USE_CURRENT_OUTFIT_FOLDER
-	if (!current_outfit_links.empty())
-	{
-		for (U8 i = 0; i < current_outfit_links.size(); ++i)
-		{
-			// Fetch the wearables in the current outfit folder
-			LLWearableList::instance().getAsset(current_outfit_links[i]->mAssetID,
-												LLStringUtil::null,
-												LLWearableDictionary::getAssetType(current_outfit_links[i]->mType),
-												onInitialWearableAssetArrived, (void*)(current_outfit_links[i]));			
-		}
-	}
-	else 
-#endif
-	if (!message_wearables.empty()) // We have an empty current outfit folder, use the message data instead.
-	{
-		LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
-		for (U8 i = 0; i < message_wearables.size(); ++i)
-		{
-			// Populate the current outfit folder with links to the wearables passed in the message
-#ifdef USE_CURRENT_OUTFIT_FOLDER
-			std::string link_name = "WearableLink";
-			link_inventory_item(gAgent.getID(), message_wearables[i]->mItemID, current_outfit_id, link_name,
-								LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
-#endif
-			// Fetch the wearables
-			LLWearableList::instance().getAsset(message_wearables[i]->mAssetID,
-												LLStringUtil::null,
-												LLWearableDictionary::getAssetType(message_wearables[i]->mType),
-												onInitialWearableAssetArrived, (void*)(message_wearables[i]));
-		}
-	}
-	else
-	{
-		LL_WARNS("Wearables") << "No current outfit folder iterms found and no initial wearables fallback message received." << LL_ENDL;
-	}
-}
-
 // A single wearable that the avatar was wearing on start-up has arrived from the database.
 // static
 void LLAgentWearables::onInitialWearableAssetArrived(LLWearable* wearable, void* userdata)
 {
-	boost::scoped_ptr<InitialWearableData> wear_data((InitialWearableData*)userdata); 
+	boost::scoped_ptr<LLInitialWearablesFetch::InitialWearableData> wear_data((LLInitialWearablesFetch::InitialWearableData*)userdata); 
 	const EWearableType type = wear_data->mType;
 	const U32 index = wear_data->mIndex;
 
@@ -999,6 +991,18 @@ void LLAgentWearables::createStandardWearablesAllDone()
 	mAvatarObject->onFirstTEMessageReceived();
 }
 
+void LLAgentWearables::getAllWearablesArray(LLDynamicArray<S32>& wearables)
+{
+	for( S32 i = 0; i < WT_COUNT; ++i )
+	{
+		// MULTI-WEARABLE: Properly handle multiwearables later.
+		if (getWearable( (EWearableType) i, 0 ) != NULL)
+		{
+			wearables.push_back(i);
+		}
+	}
+}
+
 // Note:	wearables_to_include should be a list of EWearableType types
 //			attachments_to_include should be a list of attachment points
 void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name,
@@ -1134,16 +1138,31 @@ void LLAgentWearables::makeNewOutfit(const std::string& new_folder_name,
 	} 
 }
 
+LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name)
+{
+	if (mAvatarObject.isNull())
+	{
+		return LLUUID::null;
+	}
+
+	LLDynamicArray<S32> wearables_to_include;
+	getAllWearablesArray(wearables_to_include);
+	
+	LLDynamicArray<S32> attachments_to_include;
+	mAvatarObject->getAllAttachmentsArray(attachments_to_include);
+
+	return makeNewOutfitLinks(new_folder_name, wearables_to_include, attachments_to_include);
+}
+
 // Note:	wearables_to_include should be a list of EWearableType types
 //			attachments_to_include should be a list of attachment points
-void LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name,
-										  const LLDynamicArray<S32>& wearables_to_include,
-										  const LLDynamicArray<S32>& attachments_to_include,
-										  BOOL rename_clothing)
+LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name,
+											 const LLDynamicArray<S32>& wearables_to_include,
+											 const LLDynamicArray<S32>& attachments_to_include)
 {
 	if (mAvatarObject.isNull())
 	{
-		return;
+		return LLUUID::null;
 	}
 
 	// First, make a folder in the Clothes directory.
@@ -1172,22 +1191,13 @@ void LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name,
 				LLWearable* old_wearable = getWearable((EWearableType)type,j);
 				if (old_wearable)
 				{
-					std::string new_name;
-					if (rename_clothing)
-					{
-						new_name = new_folder_name;
-						new_name.append(" ");
-						new_name.append(old_wearable->getTypeLabel());
-						LLStringUtil::truncate(new_name, DB_INV_ITEM_NAME_STR_LEN);
-					}
-
 					LLViewerInventoryItem* item = gInventory.getItem(getWearableItemID((EWearableType) type, j));
 					if (!item) continue;
 					LLPointer<LLInventoryCallback> cb = NULL;
 					link_inventory_item(gAgent.getID(),
 										item->getUUID(),
 										folder_id,
-										new_name,
+										item->getName(),
 										LLAssetType::AT_LINK,
 										cb);
 				}
@@ -1223,6 +1233,32 @@ void LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name,
 								cb);
 		}
 	} 
+
+	///////////////////
+	// Gestures
+
+	/* Disabling this for now, otherwise this adds all your default gestures and all previous
+	   active gestures.  Need to rethink the intended behavior.
+	for (LLGestureManager::item_map_t::iterator iter = LLGestureManager::instance().mActive.begin();
+		 iter != LLGestureManager::instance().mActive.end();
+		 ++iter)
+	{
+		const LLUUID &gesture_id = (*iter).first;
+		LLViewerInventoryItem* item = gInventory.getItem(gesture_id);
+		if (item)
+		{
+			LLPointer<LLInventoryCallback> cb = NULL;
+			link_inventory_item(gAgent.getID(),
+								item->getUUID(),
+								folder_id,
+								item->getName(),
+								LLAssetType::AT_LINK,
+								cb);
+		}
+	}
+	*/
+	
+	return folder_id;
 }
 
 void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
@@ -1774,11 +1810,10 @@ void LLAgentWearables::updateServer()
 	gAgent.sendAgentSetAppearance();
 }
 
-void LLAgentWearables::LLOutfitFolderFetch::done()
+void LLInitialWearablesFetch::done()
 {
-	// What we do here is get the complete information on the items in
-	// the library, and set up an observer that will wait for that to
-	// happen.
+	// Get the complete information on the items in the library, 
+	// and set up an observer that will wait for that to happen.
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t item_array;
 	gInventory.collectDescendents(mCompleteFolders.front(),
@@ -1786,43 +1821,70 @@ void LLAgentWearables::LLOutfitFolderFetch::done()
 								  item_array,
 								  LLInventoryModel::EXCLUDE_TRASH);
 	S32 count = item_array.count();
-	LLAgentWearables::initial_wearable_data_vec_t current_outfit_links;
-	current_outfit_links.reserve(count);
+	mCOFInitialWearables.reserve(count);
 	
-	for(S32 i = 0; i < count; ++i)
-	{
-		// A bit of a hack since wearables database doesn't contain asset types...
-		// Perform indirection in case this assetID is in fact a link.  This only works
-		// because of the assumption that all assetIDs and itemIDs are unique (i.e. 
-		// no assetID is also used as an itemID elsewhere); therefore if the assetID
-		// exists as an itemID in the user's inventory, then this must be a link.
-		const LLInventoryItem *linked_item = gInventory.getItem(item_array.get(i)->getUUID());
-		LLAssetType::EType asset_type = (LLAssetType::EType) 0;
-		if (linked_item)
+	for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
+		 iter != item_array.end();
+		 iter++)
+	{
+		const LLViewerInventoryItem *item = (*iter).get();
+		// We're only concerned with linked items in the COF.  Ignore
+		// any non-link items or links to folders.
+		if (item->getActualType() != LLAssetType::AT_LINK)
 		{
-			asset_type = linked_item->getType();
-			LLInventoryItem * base_item = gInventory.getItem(linked_item->getLinkedUUID());
-			if (base_item)
-			{
-				EWearableType type = (EWearableType) (base_item->getFlags() & LLInventoryItem::II_FLAGS_WEARABLES_MASK);
-				// MULTI-WEARABLE: update
-				InitialWearableData * temp_wearable_data = new InitialWearableData(type, 0, linked_item->getLinkedUUID(), base_item->getAssetUUID());
-				current_outfit_links.push_back(temp_wearable_data);
-			}
-			else
-			{
-				llwarns << "Null base_item in LLOutfitFolderFetch::done, linkedUUID is " << linked_item->getLinkedUUID().asString() << llendl;
-			}
-		}
-		else
-		{
-			llwarns << "Null linked_item in LLOutfitFolderFetch::done, UUID is " << item_array.get(i)->getUUID().asString() << llendl;
+			continue;
 		}
+		EWearableType type = (EWearableType) (item->getFlags() & LLInventoryItem::II_FLAGS_WEARABLES_MASK);
+		// MULTI-WEARABLE: update
+		InitialWearableData wearable_data(type, 0, item->getUUID(), item->getAssetUUID());
+		mCOFInitialWearables.push_back(wearable_data);
 	}
 	
 	gInventory.removeObserver(this);
-	LLAgentWearables::fetchInitialWearables(current_outfit_links, mAgentInitialWearables);
-	mAgentInitialWearables.clear();
+	processInitialWearables();
 	delete this;
 }
 
+// This will either grab the contents of the Current Outfit Folder if they exist,
+// or use the old-style initial agent wearables message.  
+void LLInitialWearablesFetch::processInitialWearables()
+{
+#ifdef USE_CURRENT_OUTFIT_FOLDER
+	if (!mCOFInitialWearables.empty())
+	{
+		for (U8 i = 0; i < mCOFInitialWearables.size(); ++i)
+		{
+			// Fetch the wearables in the current outfit folder
+			InitialWearableData *wearable_data = new InitialWearableData(mCOFInitialWearables[i]); // This will be deleted in the callback.
+			LLWearableList::instance().getAsset(wearable_data->mAssetID,
+												LLStringUtil::null,
+												LLWearableDictionary::getAssetType(wearable_data->mType),
+												LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data));			
+		}
+	}
+	else 
+#endif
+	if (!mAgentInitialWearables.empty()) // We have an empty current outfit folder, use the message data instead.
+	{
+		LLUUID current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
+		for (U8 i = 0; i < mAgentInitialWearables.size(); ++i)
+		{
+			// Populate the current outfit folder with links to the wearables passed in the message
+			InitialWearableData *wearable_data = new InitialWearableData(mAgentInitialWearables[i]); // This will be deleted in the callback.
+#ifdef USE_CURRENT_OUTFIT_FOLDER
+			const std::string link_name = "WearableLink"; // Unimportant what this is named, it isn't exposed.
+			link_inventory_item(gAgent.getID(), wearable_data->mItemID, current_outfit_id, link_name,
+								LLAssetType::AT_LINK, LLPointer<LLInventoryCallback>(NULL));
+#endif
+			// Fetch the wearables
+			LLWearableList::instance().getAsset(wearable_data->mAssetID,
+												LLStringUtil::null,
+												LLWearableDictionary::getAssetType(wearable_data->mType),
+												LLAgentWearables::onInitialWearableAssetArrived, (void*)(wearable_data));
+		}
+	}
+	else
+	{
+		LL_WARNS("Wearables") << "No current outfit folder items found and no initial wearables fallback message received." << LL_ENDL;
+	}
+}
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 971fd9ee37d8a320f7147d01480113065773fafe..b415ef9eb3556b84cb8a91ca4cc1f7ce8ce66f8c 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -43,30 +43,16 @@
 class LLInventoryItem;
 class LLVOAvatarSelf;
 class LLWearable;
-
-// Forward Declaration
-class LLInventoryFetchDescendentsObserver;
+class LLInitialWearablesFetch;
 
 class LLAgentWearables
 {
-	//--------------------------------------------------------------------
-	// Data Types
-	//--------------------------------------------------------------------
-	typedef struct _InitialWearableData
-	{
-		EWearableType mType;
-		U32 mIndex;
-		LLUUID mItemID;
-		LLUUID mAssetID;
-		_InitialWearableData(EWearableType type, U32 index, LLUUID itemID, LLUUID assetID) :
-		mType(type), mIndex(index), mItemID(itemID), mAssetID(assetID) { }
-	} InitialWearableData;
-	typedef std::vector<InitialWearableData *> initial_wearable_data_vec_t;
-	
 	//--------------------------------------------------------------------
 	// Constructors / destructors / Initializers
 	//--------------------------------------------------------------------
 public:
+	friend class LLInitialWearablesFetch;
+
 	LLAgentWearables();
 	virtual ~LLAgentWearables();
 	void 			setAvatarObject(LLVOAvatarSelf *avatar);
@@ -149,7 +135,6 @@ class LLAgentWearables
 public:
 	// Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)
 	static void		processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
-	static void		fetchInitialWearables(initial_wearable_data_vec_t & current_outfit_links, initial_wearable_data_vec_t & message_wearables);
 protected:
 	void			sendAgentWearablesUpdate();
 	void			sendAgentWearablesRequest();
@@ -161,6 +146,8 @@ class LLAgentWearables
 	// Outfits
 	//--------------------------------------------------------------------
 public:
+	void 			getAllWearablesArray(LLDynamicArray<S32>& wearables);
+	
 	// Note:	wearables_to_include should be a list of EWearableType types
 	//			attachments_to_include should be a list of attachment points
 	void			makeNewOutfit(const std::string& new_folder_name,
@@ -170,10 +157,10 @@ class LLAgentWearables
 	
 	// Note:	wearables_to_include should be a list of EWearableType types
 	//			attachments_to_include should be a list of attachment points
-	void			makeNewOutfitLinks(const std::string& new_folder_name,
+	LLUUID			makeNewOutfitLinks(const std::string& new_folder_name);
+	LLUUID			makeNewOutfitLinks(const std::string& new_folder_name,
 									   const LLDynamicArray<S32>& wearables_to_include,
-									   const LLDynamicArray<S32>& attachments_to_include,
-									   BOOL rename_clothing);
+									   const LLDynamicArray<S32>& attachments_to_include);
 private:
 	void			makeNewOutfitDone(S32 type, U32 index); 
 
@@ -254,17 +241,6 @@ class LLAgentWearables
 		U32 mTodo;
 		LLPointer<LLRefCount> mCB;
 	};
-	
-	// Outfit folder fetching callback structure.
-	class LLOutfitFolderFetch : public LLInventoryFetchDescendentsObserver
-	{
-	public:
-		LLOutfitFolderFetch() {}
-		~LLOutfitFolderFetch() {}
-		virtual void done();
-		
-		LLAgentWearables::initial_wearable_data_vec_t mAgentInitialWearables;
-	};
 
 }; // LLAgentWearables
 
diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp
index 718719fe5752466554758e8d61affc965f17766e..3c66a2add14409453d0b8efcb3ee0999ad582899 100644
--- a/indra/newview/llfloaterinventory.cpp
+++ b/indra/newview/llfloaterinventory.cpp
@@ -1138,10 +1138,10 @@ const std::string& get_item_icon_name(LLAssetType::EType asset_type,
 		idx = LANDMARK_ICON_NAME;
 		break;
 	case LLAssetType::AT_LINK:
-		idx = BODYPART_ICON_NAME; // Seraph replace this with broken item link icon
+		idx = LINKITEM_ICON_NAME;
 		break;
 	case LLAssetType::AT_LINK_FOLDER:
-		idx = BODYPART_ICON_NAME; // Seraph replace this with broken folder link icon
+		idx = LINKFOLDER_ICON_NAME;
 		break;
 	default:
 		break;
@@ -1684,6 +1684,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
 			fv->startRenamingSelectedItem();
 		}
 	}
+	// Seraph - Put determineFolderType in here for ensemble typing?
 }
 
 //----------------------------------------------------------------------------
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 69ce2f0e0e822344e362578d1e96c2b7fc0df973..de6a1a097d81da0b6f0c9b66f7a3e997764212a8 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -2115,6 +2115,14 @@ BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
 
 BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
 {
+	const LLUUID &cat_uuid = getListener()->getUUID();
+	const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
+	if (cat && cat->getPreferredType() == LLAssetType::AT_OUTFIT)
+	{
+		getListener()->performAction(NULL, NULL,"replaceoutfit");
+		return TRUE;
+	}
+
 	BOOL handled = FALSE;
 	if( mIsOpen )
 	{
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 59041792a256cf23206dbb7c4e612194bec50387..45003fe56c98129ec8712c7104c365c7bf517e17 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -155,6 +155,9 @@ std::string ICON_NAME[ICON_NAME_COUNT] =
 
 	"inv_item_animation.tga",
 	"inv_item_gesture.tga",
+
+	"inv_item_linkitem.tga",
+	"inv_item_linkfolder.tga"
 };
 
 BOOL gAddToOutfit = FALSE;
@@ -2309,8 +2312,6 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	else if(isAgentInventory()) // do not allow creating in library
 	{
 		mItems.push_back(std::string("New Folder"));
-		mItems.push_back(std::string("New Outfit"));
-		mItems.push_back(std::string("New My Outfits"));
 		mItems.push_back(std::string("New Script"));
 		mItems.push_back(std::string("New Note"));
 		mItems.push_back(std::string("New Gesture"));
@@ -4157,6 +4158,58 @@ void wear_inventory_category_on_avatar( LLInventoryCategory* category, BOOL appe
 	}
 }
 
+void removeDuplicateItems(LLInventoryModel::item_array_t& dst, const LLInventoryModel::item_array_t& src)
+{
+	LLInventoryModel::item_array_t new_dst;
+	std::set<LLUUID> mark_inventory;
+	std::set<LLUUID> mark_asset;
+
+	S32 inventory_dups = 0;
+	S32 asset_dups = 0;
+	
+	for (LLInventoryModel::item_array_t::const_iterator src_pos = src.begin();
+		  src_pos != src.end();
+		  ++src_pos)
+	{
+		LLUUID src_item_id = (*src_pos)->getLinkedUUID();
+		mark_inventory.insert(src_item_id);
+		LLUUID src_asset_id = (*src_pos)->getAssetUUID();
+		mark_asset.insert(src_asset_id);
+	}
+
+	for (LLInventoryModel::item_array_t::const_iterator dst_pos = dst.begin();
+		  dst_pos != dst.end();
+		  ++dst_pos)
+	{
+		LLUUID dst_item_id = (*dst_pos)->getLinkedUUID();
+
+		if (mark_inventory.find(dst_item_id) == mark_inventory.end())
+		{
+		}
+		else
+		{
+			inventory_dups++;
+		}
+
+		LLUUID dst_asset_id = (*dst_pos)->getAssetUUID();
+
+		if (mark_asset.find(dst_asset_id) == mark_asset.end())
+		{
+			// Item is not already present in COF.
+			new_dst.put(*dst_pos);
+			mark_asset.insert(dst_item_id);
+		}
+		else
+		{
+			asset_dups++;
+		}
+	}
+	llinfos << "removeDups, original " << dst.count() << " final " << new_dst.count()
+			<< " inventory dups " << inventory_dups << " asset_dups " << asset_dups << llendl;
+	
+	dst = new_dst;
+}
+
 void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOOL append, BOOL follow_folder_links )
 {
 	// Find all the wearables that are in the category's subtree.	
@@ -4205,22 +4258,35 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOO
 		}
 		
 		const LLUUID &current_outfit_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CURRENT_OUTFIT);
+		// Processes that take time should show the busy cursor
+		inc_busy_count();
+		
+		LLInventoryModel::cat_array_t co_cat_array;
+		LLInventoryModel::item_array_t co_item_array;
+		gInventory.collectDescendents(current_outfit_id, co_cat_array, co_item_array,
+									  LLInventoryModel::EXCLUDE_TRASH);
+		if (append)
+		{
+			// Remove duplicates and update counts.
+			removeDuplicateItems(item_array,co_item_array);
+			wearable_count = item_array.count();
+
+			removeDuplicateItems(obj_item_array,co_item_array);
+			obj_count = obj_item_array.count();
+
+			removeDuplicateItems(gest_item_array,co_item_array);
+			gest_count = gest_item_array.count();
+		}
+			
 
 		if (wearable_count > 0 || obj_count > 0)
 		{
-			// Processes that take time should show the busy cursor
-			inc_busy_count();
-			
-			// Remove all current outfit folder links if we're now replacing the contents.
-			if (!append)
+			if (!append) 
 			{
-				LLInventoryModel::cat_array_t cat_array;
-				LLInventoryModel::item_array_t item_array;
-				gInventory.collectDescendents(current_outfit_id, cat_array, item_array,
-											  LLInventoryModel::EXCLUDE_TRASH);
-				for (i = 0; i < item_array.count(); ++i)
+				// Remove all current outfit folder links if we're now replacing the contents.
+				for (i = 0; i < co_item_array.count(); ++i)
 				{
-					gInventory.purgeObject(item_array.get(i)->getUUID());
+					gInventory.purgeObject(co_item_array.get(i)->getUUID());
 				}
 			}
 		}
@@ -4272,10 +4338,10 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOO
 
 				// Fetch the wearables about to be worn.
 				LLWearableList::instance().getAsset(found->mAssetID,
-										found->mName,
-									   found->mAssetType,
-									   wear_inventory_category_on_avatar_loop,
-									   (void*)holder);
+													found->mName,
+													found->mAssetType,
+													wear_inventory_category_on_avatar_loop,
+													(void*)holder);
 			}
 		}
 
@@ -4352,9 +4418,10 @@ void wear_inventory_category_on_avatar_step2( BOOL proceed, LLUUID category, BOO
 			}
 		}
 
-		// Create a link to the folder that we wore.
+		// In the particular case that we're switching to a different outfit,
+		// create a link to the folder that we wore.
 		LLViewerInventoryCategory* catp = gInventory.getCategory(category);
-		if (catp)
+		if (!append && catp && catp->getPreferredType() == LLAssetType::AT_OUTFIT)
 		{
 			link_inventory_item(gAgent.getID(), category, current_outfit_id, catp->getName(),
 								LLAssetType::AT_LINK_FOLDER, LLPointer<LLInventoryCallback>(NULL));
@@ -5240,6 +5307,10 @@ std::string LLLinkItemBridge::sPrefix("Link: ");
 
 LLUIImagePtr LLLinkItemBridge::getIcon() const
 {
+	if (LLViewerInventoryItem *item = getItem())
+	{
+		return get_item_icon(item->getActualType(), LLInventoryType::IT_NONE, 0, FALSE);
+	}
 	return get_item_icon(LLAssetType::AT_LINK, LLInventoryType::IT_NONE, 0, FALSE);
 }
 
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 5cfebe6c154a1e67ed9d4fb89c1fea3ebe01d501..3af54c52eab56383f63d6db4fb2238ef7678997d 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -76,6 +76,9 @@ enum EInventoryIcon
 	ANIMATION_ICON_NAME,
 	GESTURE_ICON_NAME,
 
+	LINKITEM_ICON_NAME,
+	LINKFOLDER_ICON_NAME,
+
 	ICON_NAME_COUNT
 };
 
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 596211f16c93262f72a55510950c114d96a2cb69..f5525ec1f29bbdc65d45a8be830ee4f46f2dafd5 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -111,7 +111,15 @@ BOOL LLInventoryFilter::check(LLFolderViewItem* item)
 	}
 	else
 	{
-		passed_type |= ((1LL << listener->getInventoryType() & mFilterOps.mFilterTypes) != U64(0)) || listener->getInventoryType() == LLInventoryType::IT_NONE;
+		passed_type |= ((1LL << listener->getInventoryType() & mFilterOps.mFilterTypes) != U64(0));
+		if (listener->getInventoryType() == LLInventoryType::IT_NONE)
+		{
+			const LLInventoryObject *obj = gInventory.getObject(listener->getUUID());
+			if (!obj->getIsLinkType())
+			{
+				passed_type = TRUE;
+			}
+		}
 	}
 
 	BOOL passed = passed_type
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index b27fbbff88667418e8a6baa3e6425d5807fbbee0..aadda3fbfdced220fc46be3bd67704496b9f511b 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1790,7 +1790,7 @@ void LLInventoryModel::addItem(LLViewerInventoryItem* item)
 		// The item will show up as a broken link.
 		if (item->getIsBrokenLink())
 		{
-			llwarns << "Add link item without baseobj present ( itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) " << llendl;
+			llwarns << "Add link item without baseobj present ( name: " << item->getName() << " itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " )  parent: " << item->getParentUUID() << llendl;
 		}
 		mItemMap[item->getUUID()] = item;
 		//mInventory[item->getUUID()] = item;
@@ -2041,6 +2041,7 @@ bool LLInventoryModel::loadSkeleton(
 	{
 		cat_array_t categories;
 		item_array_t items;
+		cat_set_t invalid_categories; // Used to mark categories that weren't successfully loaded.
 		std::string owner_id_str;
 		owner_id.toString(owner_id_str);
 		std::string path(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, owner_id_str));
@@ -2106,7 +2107,7 @@ bool LLInventoryModel::loadSkeleton(
 			}
 
 			// go ahead and add the cats returned during the download
-			std::set<LLUUID>::iterator not_cached_id = cached_ids.end();
+			std::set<LLUUID>::const_iterator not_cached_id = cached_ids.end();
 			cached_category_count = cached_ids.size();
 			for(cat_set_t::iterator it = temp_cats.begin(); it != temp_cats.end(); ++it)
 			{
@@ -2126,30 +2127,28 @@ bool LLInventoryModel::loadSkeleton(
 			// category with a correctly cached parent
 			count = items.count();
 			cat_map_t::iterator unparented = mCategoryMap.end();
-			for(int i = 0; i < count; ++i)
+			for(item_array_t::const_iterator item_iter = items.begin();
+				item_iter != items.end();
+				++item_iter)
 			{
-				LLViewerInventoryItem *item = items[i].get();
-				cat_map_t::iterator cit = mCategoryMap.find(item->getParentUUID());
+				LLViewerInventoryItem *item = (*item_iter).get();
+				const cat_map_t::iterator cit = mCategoryMap.find(item->getParentUUID());
 				
 				if(cit != unparented)
 				{
-					LLViewerInventoryCategory* cat = cit->second;
+					const LLViewerInventoryCategory* cat = cit->second.get();
 					if(cat->getVersion() != NO_VERSION)
 					{
+						// This can happen if the linked object's baseobj is removed from the cache but the linked object is still in the cache.
 						if (item->getIsBrokenLink())
 						{
 							llinfos << "Attempted to cached link item without baseobj present ( itemID: " << item->getUUID() << " assetID: " << item->getAssetUUID() << " ) " << llendl;
-							child_counts[cat->getUUID()].mValue = -1; // Invalidate this category's cache.
+							invalid_categories.insert(cit->second);
 							continue;
 						}
 						addItem(item);
 						cached_item_count += 1;
-
-						// If this category had any broken links, keep it invalidated.
-						if (child_counts[cat->getUUID()].mValue != -1)
-						{
-							++child_counts[cat->getUUID()];
-						}
+						++child_counts[cat->getUUID()];
 					}
 				}
 			}
@@ -2169,29 +2168,35 @@ bool LLInventoryModel::loadSkeleton(
 		// At this point, we need to set the known descendents for each
 		// category which successfully cached so that we do not
 		// needlessly fetch descendents for categories which we have.
-		update_map_t::iterator no_child_counts = child_counts.end();
-		update_map_t::iterator the_count;
+		update_map_t::const_iterator no_child_counts = child_counts.end();
 		for(cat_set_t::iterator it = temp_cats.begin(); it != temp_cats.end(); ++it)
 		{
-			LLViewerInventoryCategory* cat = (*it);
+			LLViewerInventoryCategory* cat = (*it).get();
 			if(cat->getVersion() != NO_VERSION)
 			{
-				the_count = child_counts.find(cat->getUUID());
+				update_map_t::const_iterator the_count = child_counts.find(cat->getUUID());
 				if(the_count != no_child_counts)
 				{
-					S32 num_descendents = (*the_count).second.mValue;
-
-					// -1 means that one of the children was a broken link, so we can't consider this folder successfully cached.
-					if (num_descendents != -1) 
-					{
-						cat->setDescendentCount(num_descendents);
-						continue;
-					}
+					cat->setDescendentCount((*the_count).second.mValue);
+				}
+				else
+				{
+					cat->setDescendentCount(0);
 				}
-				cat->setDescendentCount(0);
 			}
 		}
 
+		// Invalidate all categories that failed fetching descendents for whatever
+		// reason (e.g. one of the descendents was a broken link).
+		for (cat_set_t::iterator invalid_cat_it = invalid_categories.begin();
+			 invalid_cat_it != invalid_categories.end();
+			 invalid_cat_it++)
+		{
+			LLViewerInventoryCategory* cat = (*invalid_cat_it).get();
+			cat->setVersion(NO_VERSION);
+			llinfos << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl;
+		}
+
 		if(remove_inventory_file)
 		{
 			// clean up the gunzipped file.
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 9a090be76aa85bd001f8b5a7a7caddd25d71edbc..4645b9bf59ecfe9ed3563b2a5e1666b189f0df9a 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -612,10 +612,7 @@ void LLViewerInventoryCategory::determineFolderType()
 				return;
 			if (item->getInventoryType() == LLInventoryType::IT_WEARABLE)
 			{
-				U32 flags = item->getFlags();
-				if (flags > WT_COUNT)
-					return;
-				const EWearableType wearable_type = EWearableType(flags);
+				const EWearableType wearable_type = EWearableType(item->getFlags() & LLInventoryItem::II_FLAGS_WEARABLES_MASK);
 				const std::string& wearable_name = LLWearableDictionary::getTypeName(wearable_type);
 				U64 valid_folder_types = LLFolderType::lookupValidFolderTypes(wearable_name);
 				folder_valid |= valid_folder_types;
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 9df25bdb1108a9d7a8e4e371492a38e5f9fa6c8a..5b4a649ee131f592b72f12d6a50d4eb85002a3a1 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -990,6 +990,19 @@ LLViewerJointAttachment *LLVOAvatarSelf::attachObject(LLViewerObject *viewer_obj
 	return attachment;
 }
 
+void LLVOAvatarSelf::getAllAttachmentsArray(LLDynamicArray<S32>& attachments)
+{
+	for (LLVOAvatar::attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); 
+		 iter != mAttachmentPoints.end(); ++iter)
+	{
+		LLViewerJointAttachment* attachment = iter->second;
+		if ( attachment && (attachment->getNumObjects() > 0))
+		{
+			attachments.push_back(iter->first);
+		}
+	}
+}
+
 U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const
 {
 	EWearableType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index e34f09aca26e766e5adf132a5ac1a7993e9cefe5..17744cce1ba59ce36c48b2da82cdb364e3c79e67 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -261,6 +261,7 @@ class LLVOAvatarSelf :
 	LLViewerObject* 	getWornAttachment(const LLUUID& inv_item_id ) const;
 	const std::string   getAttachedPointName(const LLUUID& inv_item_id) const;
 	/*virtual*/ LLViewerJointAttachment *attachObject(LLViewerObject *viewer_object);
+	void				getAllAttachmentsArray(LLDynamicArray<S32>& attachments);
 
 	//--------------------------------------------------------------------
 	// HUDs
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 1515a34eeb6c218549a77aa843ecc0cd9850c577..ad208806b71da3f55a20c7b2143dbaad79de1057 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -414,6 +414,8 @@
   <texture name="inv_item_jacket.tga"/>
   <texture name="inv_item_landmark.tga"/>
   <texture name="inv_item_landmark_visited.tga"/>
+  <texture name="inv_item_linkitem.tga"/>
+  <texture name="inv_item_linkfolder.tga"/>
   <texture name="inv_item_notecard.tga"/>
   <texture name="inv_item_object.tga"/>
   <texture name="inv_item_object_multi.tga"/>
diff --git a/indra/newview/skins/default/xui/en/floater_customize.xml b/indra/newview/skins/default/xui/en/floater_customize.xml
index 41bd417c12d37ce08741683198f22260605796fb..824df082d8747c5bcdca2b41ff20e8b8aa6d5863 100644
--- a/indra/newview/skins/default/xui/en/floater_customize.xml
+++ b/indra/newview/skins/default/xui/en/floater_customize.xml
@@ -3561,14 +3561,4 @@ scratch and wear it.
      name="Ok"
      right="-116"
      width="100" />
-    <button
-     follows="left|bottom"
-     height="20"
-     label="Make Outfit..."
-     label_selected="Make Outfit..."
-     layout="topleft"
-     left_delta="-178"
-     name="Make Outfit"
-     top_delta="0"
-     width="100" />
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inventory.xml b/indra/newview/skins/default/xui/en/floater_inventory.xml
index 610c62a21aacfc4c7a3758d1b9e42f5120f4f9a5..37c6cbf3914c71ff3634fdd33ef1b78eb21db228 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory.xml
@@ -206,22 +206,6 @@
                  function="Inventory.DoCreate"
                  parameter="category" />
             </menu_item_call>
-            <menu_item_call
-             label="New Outfit"
-             layout="topleft"
-             name="New Outfit">
-                <menu_item_call.on_click
-                 function="Inventory.DoCreate"
-                 parameter="outfit" />
-            </menu_item_call>
-            <menu_item_call
-             label="New My Outfits"
-             layout="topleft"
-             name="New My Outfits">
-                <menu_item_call.on_click
-                 function="Inventory.DoCreate"
-                 parameter="my_otfts" />
-            </menu_item_call>
             <menu_item_call
              label="New Script"
              layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index dd8acea4ed73dbfd87666afd65fb158f1f466f9c..7762a7f667997d98388d3b403b0c49aa152cf6d4 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -76,30 +76,6 @@
          function="Inventory.DoCreate"
          parameter="category" />
     </menu_item_call>
-    <menu_item_call
-     label="New Current"
-     layout="topleft"
-     name="New Current">
-        <menu_item_call.on_click
-         function="Inventory.DoCreate"
-         parameter="current" />
-    </menu_item_call>
-    <menu_item_call
-       label="New Outfit"
-       layout="topleft"
-       name="New Outfit">
-      <menu_item_call.on_click
-         function="Inventory.DoCreate"
-         parameter="outfit" />
-    </menu_item_call>
-    <menu_item_call
-       label="New My Outfits"
-       layout="topleft"
-       name="New My Outfits">
-      <menu_item_call.on_click
-         function="Inventory.DoCreate"
-         parameter="my_otfts" />
-    </menu_item_call>
     <menu_item_call
      label="New Script"
      layout="topleft"
@@ -338,14 +314,6 @@
              function="Inventory.DoToSelected"
              parameter="change_folder_type_undershirt" />
         </menu_item_call>
-        <menu_item_call
-         label="Outfit"
-         layout="topleft"
-         name="Outfit">
-            <menu_item_call.on_click
-             function="Inventory.DoToSelected"
-             parameter="change_folder_type_outfit" />
-        </menu_item_call>
     </menu>
     <menu_item_call
      label="Teleport"
diff --git a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
index 7ea059ba6ace7770500089e11aab5e1bffa2eb8f..e87517e200ac8684173d13d213defea337960d16 100644
--- a/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
+++ b/indra/newview/skins/default/xui/en/panel_sidetray_home_tab.xml
@@ -149,11 +149,11 @@
          text_color="white"
          top="40"
          word_wrap="true">
-            Change your profile, your look and quick links to your outfits.
+            Change your profile.
         </text>
     </panel>
     <panel
-     background_visible="true" 
+     background_visible="true"
      bg_alpha_color="DkGray2"
      class="panel_sidetray_home_info"
      follows="left|top|right"
@@ -197,7 +197,7 @@
          text_color="white"
          top="40"
          word_wrap="true">
-            Change your appearance.
+            Change your apperance and looks.
         </text>
-    </panel> 
+    </panel>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index fb1aa25b25cf4413aacf22ee31c1d2bf6273d051..f89625c535fefaeab3f26050003065294d2cdf32 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -149,6 +149,7 @@
 	<string name="gesture">gesture</string>															
 	<string name="simstate">simstate</string>																
 	<string name="favorite">favorite</string>															
+	<string name="symbolic link">link</string>															
 	
 	<!-- llvoavatar. Displayed in the avatar chat bubble -->
 	<string name="AvatarEditingAppearance">(Editing Appearance)</string>