diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index e4102a622d8361ced6f72b91ff8fa2f9fbb4bbca..d431071c25c1d22daaf5f721ce1b543100d9e3e0 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -44,19 +44,29 @@ struct AssetEntry : public LLDictionaryEntry
 {
 	AssetEntry(const char *desc_name,
 			   const char *type_name, // 8 character limit!
-			   const char *human_name,
+			   const char *human_name, // for decoding to human readable form; put any and as many printable characters you want in each one
 			   const char *category_name, // used by llinventorymodel when creating new categories
 			   EDragAndDropType dad_type,
-			   bool can_link);
+			   bool can_link, // can you create a link to this type?
+			   bool is_protected) // can the viewer change categories of this type?
+		:
+		LLDictionaryEntry(desc_name),
+		mTypeName(type_name),
+		mHumanName(human_name),
+		mCategoryName(category_name),
+		mDadType(dad_type),
+		mCanLink(can_link),
+		mIsProtected(is_protected)
+	{
+		llassert(strlen(mTypeName) <= 8);
+	}
 
-	// limited to 8 characters
 	const char *mTypeName;
-	// human readable form.  Put as many printable characters you want in each one.
-	// (c.f. llinventory.cpp INVENTORY_TYPE_HUMAN_NAMES).
 	const char *mHumanName;
 	const char *mCategoryName;
 	EDragAndDropType mDadType;
 	bool mCanLink;
+	bool mIsProtected;
 };
 
 class LLAssetDictionary : public LLSingleton<LLAssetDictionary>,
@@ -68,52 +78,49 @@ class LLAssetDictionary : public LLSingleton<LLAssetDictionary>,
 
 LLAssetDictionary::LLAssetDictionary()
 {
-	addEntry(LLAssetType::AT_TEXTURE, 			new AssetEntry("TEXTURE",			"texture",	"texture",			"Textures", 		DAD_TEXTURE,	FALSE));
-	addEntry(LLAssetType::AT_SOUND, 			new AssetEntry("SOUND",				"sound",	"sound",			"Sounds", 			DAD_SOUND,		FALSE));
-	addEntry(LLAssetType::AT_CALLINGCARD, 		new AssetEntry("CALLINGCARD",		"callcard",	"calling card",		"Calling Cards", 	DAD_CALLINGCARD, FALSE));
-	addEntry(LLAssetType::AT_LANDMARK, 			new AssetEntry("LANDMARK",			"landmark",	"landmark",			"Landmarks", 		DAD_LANDMARK,	FALSE));
-	addEntry(LLAssetType::AT_SCRIPT, 			new AssetEntry("SCRIPT",			"script",	"legacy script",	"Scripts", 			DAD_NONE,		FALSE));
-	addEntry(LLAssetType::AT_CLOTHING, 			new AssetEntry("CLOTHING",			"clothing",	"clothing",			"Clothing", 		DAD_CLOTHING,	TRUE));
-	addEntry(LLAssetType::AT_OBJECT, 			new AssetEntry("OBJECT",			"object",	"object",			"Objects", 			DAD_OBJECT,		TRUE));
-	addEntry(LLAssetType::AT_NOTECARD, 			new AssetEntry("NOTECARD",			"notecard",	"note card",		"Notecards", 		DAD_NOTECARD,	FALSE));
-	addEntry(LLAssetType::AT_CATEGORY, 			new AssetEntry("CATEGORY",			"category",	"folder",			"New Folder", 		DAD_CATEGORY,	TRUE));
-	addEntry(LLAssetType::AT_ROOT_CATEGORY, 	new AssetEntry("ROOT_CATEGORY",		"root",		"root",				"Inventory", 		DAD_ROOT_CATEGORY, TRUE));
-	addEntry(LLAssetType::AT_LSL_TEXT, 			new AssetEntry("LSL_TEXT",			"lsltext",	"lsl2 script",		"Scripts", 			DAD_SCRIPT,		FALSE));
-	addEntry(LLAssetType::AT_LSL_BYTECODE, 		new AssetEntry("LSL_BYTECODE",		"lslbyte",	"lsl bytecode",		"Scripts", 			DAD_NONE,		FALSE));
-	addEntry(LLAssetType::AT_TEXTURE_TGA, 		new AssetEntry("TEXTURE_TGA",		"txtr_tga",	"tga texture",		"Uncompressed Images", DAD_NONE,	FALSE));
-	addEntry(LLAssetType::AT_BODYPART, 			new AssetEntry("BODYPART",			"bodypart",	"body part",		"Body Parts", 		DAD_BODYPART,	TRUE));
-	addEntry(LLAssetType::AT_TRASH, 			new AssetEntry("TRASH",				"trash",	"trash",			"Trash", 			DAD_NONE,		FALSE));
-	addEntry(LLAssetType::AT_SNAPSHOT_CATEGORY, new AssetEntry("SNAPSHOT_CATEGORY", "snapshot",	"snapshot",			"Photo Album", 		DAD_NONE,		FALSE));
-	addEntry(LLAssetType::AT_LOST_AND_FOUND, 	new AssetEntry("LOST_AND_FOUND", 	"lstndfnd",	"lost and found",	"Lost And Found", 	DAD_NONE,		FALSE));
-	addEntry(LLAssetType::AT_SOUND_WAV, 		new AssetEntry("SOUND_WAV",			"snd_wav",	"sound",			"Uncompressed SoundS", DAD_NONE,	FALSE));
-	addEntry(LLAssetType::AT_IMAGE_TGA, 		new AssetEntry("IMAGE_TGA",			"img_tga",	"targa image",		"Uncompressed Images", DAD_NONE,	FALSE));
-	addEntry(LLAssetType::AT_IMAGE_JPEG, 		new AssetEntry("IMAGE_JPEG",		"jpeg",		"jpeg image",		"Uncompressed Images", DAD_NONE,	FALSE));
-	addEntry(LLAssetType::AT_ANIMATION, 		new AssetEntry("ANIMATION",			"animatn",	"animation",		"Animations", 		DAD_ANIMATION,	FALSE));
-	addEntry(LLAssetType::AT_GESTURE, 			new AssetEntry("GESTURE",			"gesture",	"gesture",			"Gestures", 		DAD_GESTURE,	FALSE));
-	addEntry(LLAssetType::AT_SIMSTATE, 			new AssetEntry("SIMSTATE",			"simstate",	"simstate",			"New Folder", 		DAD_NONE,		FALSE));
-	addEntry(LLAssetType::AT_FAVORITE, 			new AssetEntry("FAVORITE",			"favorite",	"favorite",			"favorite", 		DAD_NONE,		FALSE));
+	//       												   DESCRIPTION			TYPE NAME	HUMAN NAME			CATEGORY NAME 		DRAG&DROP		CAN LINK?	PROTECTED?
+	//      												  |--------------------|-----------|-------------------|-------------------|---------------|-----------|-----------|
+	addEntry(LLAssetType::AT_TEXTURE, 			new AssetEntry("TEXTURE",			"texture",	"texture",			"Textures", 		DAD_TEXTURE,	FALSE,		TRUE));
+	addEntry(LLAssetType::AT_SOUND, 			new AssetEntry("SOUND",				"sound",	"sound",			"Sounds", 			DAD_SOUND,		FALSE,		TRUE));
+	addEntry(LLAssetType::AT_CALLINGCARD, 		new AssetEntry("CALLINGCARD",		"callcard",	"calling card",		"Calling Cards", 	DAD_CALLINGCARD, FALSE,		TRUE));
+	addEntry(LLAssetType::AT_LANDMARK, 			new AssetEntry("LANDMARK",			"landmark",	"landmark",			"Landmarks", 		DAD_LANDMARK,	FALSE,		TRUE));
+	addEntry(LLAssetType::AT_SCRIPT, 			new AssetEntry("SCRIPT",			"script",	"legacy script",	"Scripts", 			DAD_NONE,		FALSE,		TRUE));
+	addEntry(LLAssetType::AT_CLOTHING, 			new AssetEntry("CLOTHING",			"clothing",	"clothing",			"Clothing", 		DAD_CLOTHING,	TRUE,		TRUE));
+	addEntry(LLAssetType::AT_OBJECT, 			new AssetEntry("OBJECT",			"object",	"object",			"Objects", 			DAD_OBJECT,		TRUE,		TRUE));
+	addEntry(LLAssetType::AT_NOTECARD, 			new AssetEntry("NOTECARD",			"notecard",	"note card",		"Notecards", 		DAD_NOTECARD,	FALSE,		TRUE));
+	addEntry(LLAssetType::AT_CATEGORY, 			new AssetEntry("CATEGORY",			"category",	"folder",			"New Folder", 		DAD_CATEGORY,	TRUE,		TRUE));
+	addEntry(LLAssetType::AT_ROOT_CATEGORY, 	new AssetEntry("ROOT_CATEGORY",		"root",		"root",				"Inventory", 		DAD_ROOT_CATEGORY, TRUE,	TRUE));
+	addEntry(LLAssetType::AT_LSL_TEXT, 			new AssetEntry("LSL_TEXT",			"lsltext",	"lsl2 script",		"Scripts", 			DAD_SCRIPT,		FALSE,		TRUE));
+	addEntry(LLAssetType::AT_LSL_BYTECODE, 		new AssetEntry("LSL_BYTECODE",		"lslbyte",	"lsl bytecode",		"Scripts", 			DAD_NONE,		FALSE,		TRUE));
+	addEntry(LLAssetType::AT_TEXTURE_TGA, 		new AssetEntry("TEXTURE_TGA",		"txtr_tga",	"tga texture",		"Uncompressed Images", DAD_NONE,	FALSE,		TRUE));
+	addEntry(LLAssetType::AT_BODYPART, 			new AssetEntry("BODYPART",			"bodypart",	"body part",		"Body Parts", 		DAD_BODYPART,	TRUE,		TRUE));
+	addEntry(LLAssetType::AT_TRASH, 			new AssetEntry("TRASH",				"trash",	"trash",			"Trash", 			DAD_NONE,		FALSE,		TRUE));
+	addEntry(LLAssetType::AT_SNAPSHOT_CATEGORY, new AssetEntry("SNAPSHOT_CATEGORY", "snapshot",	"snapshot",			"Photo Album", 		DAD_NONE,		FALSE,		TRUE));
+	addEntry(LLAssetType::AT_LOST_AND_FOUND, 	new AssetEntry("LOST_AND_FOUND", 	"lstndfnd",	"lost and found",	"Lost And Found", 	DAD_NONE,		FALSE,		TRUE));
+	addEntry(LLAssetType::AT_SOUND_WAV, 		new AssetEntry("SOUND_WAV",			"snd_wav",	"sound",			"Uncompressed SoundS", DAD_NONE,	FALSE,		TRUE));
+	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_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));
 
-	addEntry(LLAssetType::AT_LINK, 				new AssetEntry("LINK",				"link",		"symbolic link",	"New Folder", 		DAD_NONE,		FALSE));
-	addEntry(LLAssetType::AT_LINK_FOLDER, 		new AssetEntry("FOLDER_LINK",		"link_f", "symbolic folder link", "New Folder", DAD_NONE,		FALSE));
+	addEntry(LLAssetType::AT_LINK, 				new AssetEntry("LINK",				"link",		"symbolic link",	"Link", 			DAD_LINK,		FALSE,		TRUE));
+	addEntry(LLAssetType::AT_LINK_FOLDER, 		new AssetEntry("FOLDER_LINK",		"link_f", 	"symbolic folder link", "New Folder", 	DAD_LINK,		FALSE,		TRUE));
 
-	addEntry(LLAssetType::AT_NONE, 				new AssetEntry("NONE",				"-1",		NULL,		  		"New Folder", 		DAD_NONE,		FALSE));
-};
+	for (S32 ensemble_num = S32(LLAssetType::AT_FOLDER_ENSEMBLE_START); 
+		 ensemble_num <= S32(LLAssetType::AT_FOLDER_ENSEMBLE_END); 
+		 ensemble_num++)
+	{
+		addEntry(LLAssetType::EType(ensemble_num), new AssetEntry("ENSEMBLE",		"ensemble", "ensemble", 		"New Folder", 		DAD_CATEGORY,	TRUE,		FALSE)); 
+	}
 
-AssetEntry::AssetEntry(const char *desc_name,
-					   const char *type_name,
-					   const char *human_name,
-					   const char *category_name,
-					   EDragAndDropType dad_type,
-					   bool can_link) :
-	LLDictionaryEntry(desc_name),
-	mTypeName(type_name),
-	mHumanName(human_name),
-	mCategoryName(category_name),
-	mDadType(dad_type),
-	mCanLink(can_link)
-{
-	llassert(strlen(mTypeName) <= 8);
-}
+	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_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));
+};
 
 // static
 LLAssetType::EType LLAssetType::getType(const std::string& desc_name)
@@ -128,11 +135,11 @@ const std::string &LLAssetType::getDesc(LLAssetType::EType asset_type)
 {
 	const AssetEntry *entry = LLAssetDictionary::getInstance()->lookup(asset_type);
 	if (entry)
-{ 
+	{
 		return entry->mName;
 	}
 	else
-	{ 
+	{
 		static const std::string error_string = "BAD TYPE";
 		return error_string;
 	}
@@ -154,7 +161,7 @@ const char *LLAssetType::lookup(LLAssetType::EType asset_type)
 }
 
 // static
-LLAssetType::EType LLAssetType::lookup( const char* name )
+LLAssetType::EType LLAssetType::lookup(const char* name)
 {
 	return lookup(ll_safe_string(name));
 }
@@ -191,7 +198,7 @@ const char *LLAssetType::lookupHumanReadable(LLAssetType::EType asset_type)
 }
 
 // static
-LLAssetType::EType LLAssetType::lookupHumanReadable( const char* name )
+LLAssetType::EType LLAssetType::lookupHumanReadable(const char* name)
 {
 	return lookupHumanReadable(ll_safe_string(name));
 }
@@ -261,6 +268,21 @@ bool LLAssetType::lookupIsLinkType(EType asset_type)
 	return false;
 }
 
+// static
+// Only ensembles and plain folders aren't protected.  "Protected" means
+// you can't change certain properties such as their type.
+bool LLAssetType::lookupIsProtectedCategoryType(EType asset_type)
+{
+	const LLAssetDictionary *dict = LLAssetDictionary::getInstance();
+	const AssetEntry *entry = dict->lookup(asset_type);
+	if (entry)
+	{
+		return entry->mIsProtected;
+	}
+	return true;
+}
+
+
 // static. Generate a good default description
 void LLAssetType::generateDescriptionFor(LLAssetType::EType asset_type,
 										 std::string& description)
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index 353bd57bb9bc5dd937a75aada2e93eb72b2cc41f..8ab75104946b97ab67014b9156f350ec7d3008fd 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -125,7 +125,7 @@ class LLAssetType
 
 		AT_SIMSTATE = 22,
 			// Simstate file.
-	
+
 		AT_FAVORITE = 23,
 			// favorite items
 
@@ -135,21 +135,35 @@ class LLAssetType
 		AT_LINK_FOLDER = 25,
 			// Inventory folder link
 
-		AT_COUNT = 26,
+		AT_FOLDER_ENSEMBLE_START = 26,
+		AT_FOLDER_ENSEMBLE_END = 45,
+			// This range is reserved for special clothing folder types.
+
+		AT_CURRENT_OUTFIT = 46,
+			// Current outfit
 
-			// +************************************************+
-			// |  TO ADD AN ELEMENT TO THIS ENUM:               |
-			// +************************************************+
-			// | 1. INSERT BEFORE AT_COUNT                      |
-			// | 2. INCREMENT AT_COUNT BY 1                     |
-			// | 3. ADD TO LLAssetDictionary in llassettype.cpp |
-			// +************************************************+
+		AT_OUTFIT = 47,
+			// Predefined outfit ("look")
+
+		AT_MY_OUTFITS = 48,
+			// Folder that holds your outfits.
+
+		
+		AT_COUNT = 49,
+			// +*********************************************************+
+			// |  TO ADD AN ELEMENT TO THIS ENUM:                        |
+			// +*********************************************************+
+			// | 1. INSERT BEFORE AT_COUNT                               |
+			// | 2. INCREMENT AT_COUNT BY 1                              |
+			// | 3. ADD TO LLAssetDictionary in LLAssetType.cpp          |
+			// | 3. ADD TO DEFAULT_ASSET_FOR_INV in LLInventoryType.cpp  |
+			// +*********************************************************+
 
 		AT_NONE = -1
 	};
 
 	// machine transation between type and strings
-	static EType lookup(const char* name); // safe conversion to std::string, *TODO: deprecate
+	static EType 				lookup(const char* name); // safe conversion to std::string, *TODO: deprecate
 	static EType 				lookup(const std::string& type_name);
 	static const char*			lookup(EType asset_type);
 
@@ -158,8 +172,6 @@ class LLAssetType
 	static EType 				lookupHumanReadable(const std::string& readable_name);
 	static const char*			lookupHumanReadable(EType asset_type);
 
-	static const char*  		lookupCategoryName(EType asset_type);
-
 	// Generate a good default description. You may want to add a verb
 	// or agent name after this depending on your application.
 	static void 				generateDescriptionFor(LLAssetType::EType asset_type,
@@ -168,9 +180,13 @@ class LLAssetType
 	static EType 				getType(const std::string& desc_name);
 	static const std::string&	getDesc(EType asset_type);
 	static EDragAndDropType   	lookupDragAndDropType(EType asset_type);
+
 	static bool 				lookupCanLink(EType asset_type);
 	static bool 				lookupIsLinkType(EType asset_type);
 
+	static const char*  		lookupCategoryName(EType asset_type);
+	static bool 				lookupIsProtectedCategoryType(EType asset_type);
+
 	/* TODO: Change return types from "const char *" to "const std::string &".
 	This is fairly straightforward, but requires changing some calls to use .c_str().
 	e.g.:
@@ -180,8 +196,8 @@ class LLAssetType
 	
 private:
 	// don't instantiate or derive one of these objects
-	LLAssetType() {}
-	~LLAssetType() {}
+	LLAssetType( void ) {}
+	~LLAssetType( void ) {}
 };
 
 #endif // LL_LLASSETTYPE_H
diff --git a/indra/llcommon/lldictionary.h b/indra/llcommon/lldictionary.h
index 856947def80ddfe89983aba2d6b375f81c7c1398..436b689ca69a52d927a2996a7944561c039bd08a 100644
--- a/indra/llcommon/lldictionary.h
+++ b/indra/llcommon/lldictionary.h
@@ -95,6 +95,10 @@ class LLDictionary : public std::map<Index, Entry *>
 protected:
 	void addEntry(Index index, Entry *entry)
 	{
+		if (lookup(index))
+		{
+			llerrs << "Dictionary entry already added (attempted to add duplicate entry)" << llendl;
+		}
 		(*this)[index] = entry;
 	}
 };
diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h
index 41da51fce3bb3fd10aa24befbe90ba451412a8f9..1a5678dde1340fc0c78d2d1d178418c7cf0214c1 100644
--- a/indra/llcommon/stdenums.h
+++ b/indra/llcommon/stdenums.h
@@ -54,7 +54,8 @@ enum EDragAndDropType
 	DAD_BODYPART		= 11,
 	DAD_ANIMATION		= 12,
 	DAD_GESTURE			= 13,
-	DAD_COUNT			= 14,   // number of types in this enum
+	DAD_LINK			= 14,
+	DAD_COUNT			= 15,   // number of types in this enum
 };
 
 // Reasons for drags to be denied.
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index 597e19e7eadfa6f148ff172e810b5df6736183c9..2d507bd560b88282ce14e518eb0b7b548fcc9fe4 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -1624,7 +1624,7 @@ LLSD ll_create_sd_from_inventory_category(LLPointer<LLInventoryCategory> cat)
 	rv[INV_PARENT_ID_LABEL] = cat->getParentUUID();
 	rv[INV_NAME_LABEL] = cat->getName();
 	rv[INV_ASSET_TYPE_LABEL] = LLAssetType::lookup(cat->getType());
-	if(LLAssetType::AT_NONE != cat->getPreferredType())
+	if(LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType()))
 	{
 		rv[INV_PREFERRED_TYPE_LABEL] =
 			LLAssetType::lookup(cat->getPreferredType());
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index 2dc229226f14776279b2aa20222e0237461614fd..a445466b26aea80e3ced71b4eb9fe221008ba4b0 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -44,9 +44,23 @@ static const std::string empty_string;
 ///----------------------------------------------------------------------------
 struct InventoryEntry : public LLDictionaryEntry
 {
-	InventoryEntry(const std::string &name,
-				   const std::string &human_name,
-				   int num_asset_types = 0, ...);
+	InventoryEntry(const std::string &name, // unlike asset type names, not limited to 8 characters; need not match asset type names
+				   const std::string &human_name, // for decoding to human readable form; put any and as many printable characters you want in each one.
+				   int num_asset_types = 0, ...)
+		:
+		LLDictionaryEntry(name),
+		mHumanName(human_name)
+	{
+		va_list argp;
+		va_start(argp, num_asset_types);
+		// Read in local textures
+		for (U8 i=0; i < num_asset_types; i++)
+		{
+			LLAssetType::EType t = (LLAssetType::EType)va_arg(argp,int);
+			mAssetTypes.push_back(t);
+		}
+	}
+		
 	const std::string mHumanName;
 	typedef std::vector<LLAssetType::EType> asset_vec_t;
 	asset_vec_t mAssetTypes;
@@ -115,25 +129,35 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
 	LLInventoryType::IT_GESTURE,		// AT_GESTURE
 	LLInventoryType::IT_NONE,			// AT_SIMSTATE
 	LLInventoryType::IT_FAVORITE,		// AT_FAVORITE
+
 	LLInventoryType::IT_NONE,			// AT_LINK
 	LLInventoryType::IT_NONE,			// AT_LINK_FOLDER
-};
 
-InventoryEntry::InventoryEntry(const std::string &name,
-							   const std::string &human_name,
-							   int num_asset_types, ...) :
-	LLDictionaryEntry(name),
-	mHumanName(human_name)
-{
-	va_list argp;
-	va_start(argp, num_asset_types);
-	// Read in local textures
-	for (U8 i=0; i < num_asset_types; i++)
-	{
-		LLAssetType::EType t = (LLAssetType::EType)va_arg(argp,int);
-		mAssetTypes.push_back(t);
-	}
-}
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+	LLInventoryType::IT_CATEGORY,		// AT_ENSEMBLE
+
+	LLInventoryType::IT_CATEGORY,		// AT_CURRENT_OUTFIT
+	LLInventoryType::IT_CATEGORY,		// AT_OUTFIT
+	LLInventoryType::IT_CATEGORY,		// AT_MY_OUTFITS
+};
 
 // static
 const std::string &LLInventoryType::lookup(EType type)
@@ -173,6 +197,21 @@ LLInventoryType::EType LLInventoryType::defaultForAssetType(LLAssetType::EType a
 	}
 }
 
+
+// add any types that we don't want the user to be able to change permissions on.
+// static
+bool LLInventoryType::cannotRestrictPermissions(LLInventoryType::EType type)
+{
+	switch(type)
+	{
+		case IT_CALLINGCARD:
+		case IT_LANDMARK:
+			return true;
+		default:
+			return false;
+	}
+}
+
 bool inventory_and_asset_types_match(LLInventoryType::EType inventory_type,
 									 LLAssetType::EType asset_type)
 {
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index 1aad90d51b15e9120c3e8ec73af07983b9ff0c83..14b28bfe4b8ea583bd70531821fc03440f366904 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -83,10 +83,13 @@ class LLInventoryType
 	// return the default inventory for the given asset type.
 	static EType defaultForAssetType(LLAssetType::EType asset_type);
 
+	// true if this type cannot have restricted permissions.
+	static bool cannotRestrictPermissions(EType type);
+
 private:
 	// don't instantiate or derive one of these objects
-	LLInventoryType() {}
-	~LLInventoryType() {}
+	LLInventoryType( void );
+	~LLInventoryType( void );
 };
 
 // helper function that returns true if inventory type and asset type
diff --git a/indra/llmessage/lltransfersourceasset.cpp b/indra/llmessage/lltransfersourceasset.cpp
index c715e16e34c829598f62d2dae5939862df51b144..5a1cd95ffcd54183a95618dbd321b145d6e96952 100644
--- a/indra/llmessage/lltransfersourceasset.cpp
+++ b/indra/llmessage/lltransfersourceasset.cpp
@@ -296,10 +296,10 @@ bool is_asset_id_knowable(LLAssetType::EType type)
 		case LLAssetType::AT_FAVORITE:
 		case LLAssetType::AT_LINK:
 		case LLAssetType::AT_LINK_FOLDER:
-		rv = true;
-		break;
-	default:
-		break;
+			rv = true;
+			break;
+		default:
+			break;
 	}
 	return rv;
 }
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 5dec4a8688f32cf275b02785fa668de4f146bf77..d06571fb7ab6144fc0df888a6dd39566fed13660 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -211,6 +211,7 @@ set(viewer_SOURCE_FILES
     llfloaterwater.cpp
     llfloaterwindlight.cpp
     llfloaterworldmap.cpp
+    llfoldertype.cpp
     llfolderview.cpp
     llfolderviewitem.cpp
     llfollowcam.cpp
@@ -646,6 +647,7 @@ set(viewer_HEADER_FILES
     llfloaterwater.h
     llfloaterwindlight.h
     llfloaterworldmap.h
+    llfoldertype.h
     llfolderview.h
     llfoldervieweventlistener.h
     llfolderviewitem.h
diff --git a/indra/newview/app_settings/foldertypes.xml b/indra/newview/app_settings/foldertypes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4d4d479bdd6950e11170a078059a62e7c282f1ee
--- /dev/null
+++ b/indra/newview/app_settings/foldertypes.xml
@@ -0,0 +1,58 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<ensemble_defs>
+  <ensemble
+    asset_num="-1"
+    xui_name="default"
+    icon_name="inv_plain_closed.tga"
+     />
+  <ensemble
+    asset_num="27"
+    xui_name="head"
+    icon_name="inv_folder_outfit_head.tga"
+     />
+  <ensemble
+    asset_num="28"
+    xui_name="gloves"
+    icon_name="inv_folder_outfit_gloves.tga"
+     />
+  <ensemble
+    asset_num="29"
+    xui_name="jacket"
+    icon_name="inv_folder_outfit_jacket.tga"
+     />
+  <ensemble
+    asset_num="30"
+    xui_name="pants"
+    icon_name="inv_folder_outfit_pants.tga"
+     />
+  <ensemble
+    asset_num="31"
+    xui_name="shape"
+    icon_name="inv_folder_outfit_shape.tga"
+     />
+  <ensemble
+    asset_num="32"
+    xui_name="shoes"
+    icon_name="inv_folder_outfit_shoes.tga"
+     />
+  <ensemble
+    asset_num="33"
+    xui_name="shirt"
+    icon_name="inv_folder_outfit_shirt.tga"
+     />
+  <ensemble
+    asset_num="34"
+    xui_name="skirt"
+    icon_name="inv_folder_outfit_skirt.tga"
+     />
+  <ensemble
+    asset_num="35"
+    xui_name="underpants"
+    icon_name="inv_folder_outfit_underpants.tga"
+     />
+  <ensemble
+    asset_num="36"
+    xui_name="undershirt"
+    icon_name="inv_folder_outfit_undershirt.tga"
+     />
+</ensemble_defs>
diff --git a/indra/newview/llfloaterinventory.cpp b/indra/newview/llfloaterinventory.cpp
index d326e0e970739b6a0aa3555df81f020762ef329a..d05a32dc88b9bb9158a6d3bab0de897698f72a79 100644
--- a/indra/newview/llfloaterinventory.cpp
+++ b/indra/newview/llfloaterinventory.cpp
@@ -1533,12 +1533,14 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
 				<< ((S32) objectp->getType())
 				<< " (shouldn't happen)" << llendl;
 		}
-		else if (objectp->getType() == LLAssetType::AT_CATEGORY) // build new view for category
+		else if (objectp->getType() == LLAssetType::AT_CATEGORY &&
+				 objectp->getActualType() != LLAssetType::AT_LINK_FOLDER) 
 		{
 			LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(objectp->getType(),
-													LLInventoryType::IT_CATEGORY,
-													this,
-													objectp->getUUID());
+																	  objectp->getType(),
+																	  LLInventoryType::IT_CATEGORY,
+																	  this,
+																	  objectp->getUUID());
 
 			if (new_listener)
 			{
@@ -1553,15 +1555,17 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
 				itemp = folderp;
 			}
 		}
-		else // build new view for item
+		else 
 		{
+			// Build new view for item
 			LLInventoryItem* item = (LLInventoryItem*)objectp;
-			LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(
-				item->getType(),
-				item->getInventoryType(),
-				this,
-				item->getUUID(),
-				item->getFlags());
+			LLInvFVBridge* new_listener = LLInvFVBridge::createBridge(item->getType(),
+																	  item->getActualType(),
+																	  item->getInventoryType(),
+																	  this,
+																	  item->getUUID(),
+																	  item->getFlags());
+
 			if (new_listener)
 			{
 				LLFolderViewItem::Params params;
@@ -1591,7 +1595,7 @@ void LLInventoryPanel::buildNewViews(const LLUUID& id)
 		}
 	}
 	if ((id.isNull() ||
-		(objectp && objectp->getType() == LLAssetType::AT_CATEGORY)))
+		 (objectp && objectp->getType() == LLAssetType::AT_CATEGORY)))
 	{
 		LLViewerInventoryCategory::cat_array_t* categories;
 		LLViewerInventoryItem::item_array_t* items;
diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp
index efc273c6e524985ea003c9121b2e3fb21e751704..ca7c929d74e8e7a821ebb96f948dfe1245378ac4 100644
--- a/indra/newview/llfloaterproperties.cpp
+++ b/indra/newview/llfloaterproperties.cpp
@@ -658,6 +658,7 @@ void LLFloaterProperties::onCommitName(LLUICtrl* ctrl, void* data)
 		{
 			new_item->updateServer(FALSE);
 			gInventory.updateItem(new_item);
+			gInventory.updateLinkedObjects(new_item->getUUID());
 			gInventory.notifyObservers();
 		}
 		else
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 6ef011f1de2804f4a39baadd68630526785cf45e..c54eafb67a7984a03b0cf2749045bd44727b5625 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -34,10 +34,12 @@
 
 #include "llfolderview.h"
 
+#include "llagent.h"
 #include "llcallbacklist.h"
 #include "llinventorybridge.h"
 #include "llinventoryclipboard.h" // *TODO: remove this once hack below gone.
 #include "llinventoryfilter.h"
+#include "llfoldertype.h"
 #include "llfloaterinventory.h"// hacked in for the bonus context menu items.
 #include "llkeyboard.h"
 #include "lllineeditor.h"
@@ -1094,6 +1096,35 @@ void LLFolderView::propertiesSelectedItems( void )
 	}
 }
 
+void LLFolderView::changeType(LLInventoryModel *model, LLAssetType::EType new_folder_type)
+{
+	LLFolderBridge *folder_bridge = LLFolderBridge::sSelf;
+
+	if (!folder_bridge) return;
+	LLViewerInventoryCategory *cat = folder_bridge->getCategory();
+	if (!cat) return;
+		
+	const LLUUID &folder_id = cat->getUUID();
+	const LLUUID &parent_id = cat->getParentUUID();
+	const std::string &name = cat->getName();
+		
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_UpdateInventoryFolder);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->nextBlockFast(_PREHASH_FolderData);
+	msg->addUUIDFast(_PREHASH_FolderID, folder_id);
+	msg->addUUIDFast(_PREHASH_ParentID, parent_id);
+	msg->addS8Fast(_PREHASH_Type, new_folder_type);
+	msg->addStringFast(_PREHASH_Name, name);
+	gAgent.sendReliableMessage();
+
+	cat->setPreferredType(new_folder_type);
+	gInventory.addChangedMask(LLInventoryObserver::LABEL, folder_id);
+	gInventory.updateLinkedObjects(folder_id);
+}
+
 void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
 {
 	if (mAutoOpenItems.check() == item || mAutoOpenItems.getDepth() >= (U32)AUTO_OPEN_STACK_DEPTH)
@@ -1904,6 +1935,16 @@ bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
 		LLInventoryClipboard::instance().reset();
 	}
 
+	static const std::string change_folder_string = "change_folder_type_";
+	if (action.length() > change_folder_string.length() && 
+		(action.compare(0,change_folder_string.length(),"change_folder_type_") == 0))
+	{
+		LLAssetType::EType new_folder_type = LLFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length()));
+		changeType(model, new_folder_type);
+		return true;
+	}
+
+
 	std::set<LLUUID> selected_items;
 	getSelectionList(selected_items);
 
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index d944a4fa18df9775cfed68afdcbc41ded245efc5..8d9d52cd172bbcb2c58485c4c38fe532fb301bd1 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -190,6 +190,9 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	void openSelectedItems( void );
 	void propertiesSelectedItems( void );
 
+	// change the folder type
+	void changeType(LLInventoryModel *model, LLAssetType::EType new_folder_type);
+
 	void autoOpenItem(LLFolderViewFolder* item);
 	void closeAutoOpenedFolders();
 	BOOL autoOpenTest(LLFolderViewFolder* item);
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
index 7032e8695890007437ebbc7437ae5bae18928458..43f3ea8d8f3b27bb43fc3db2f866824b798323fa 100644
--- a/indra/newview/llfolderviewitem.cpp
+++ b/indra/newview/llfolderviewitem.cpp
@@ -230,7 +230,7 @@ void LLFolderViewItem::refreshFromListener()
 
 		// *TODO: to be removed when database supports multi language. This is a
 		// temporary attempt to display the inventory folder in the user locale.
-		if (preferred_type != LLAssetType::AT_NONE)
+		if (LLAssetType::lookupIsProtectedCategoryType(preferred_type))
 		{
 			mLabel = LLTrans::getString("InvFolder " + mLabel);
 		};
diff --git a/indra/newview/llfolderviewitem.h b/indra/newview/llfolderviewitem.h
index 57807005c2a702a1d23814c21b6a073174d730e3..31866c83c8b10d0a29f4b6de294446cc39a3bfcd 100644
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/newview/llfolderviewitem.h
@@ -157,13 +157,6 @@ class LLFolderViewItem : public LLView
 	BOOL                            mIsLoading;
 	LLTimer                         mTimeSinceRequestStart;
 
-	// This function clears the currently selected item, and records
-	// the specified selected item appropriately for display and use
-	// in the UI. If open is TRUE, then folders are opened up along
-	// the way to the selection.
-	void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
-		BOOL take_keyboard_focus = TRUE);
-
 	// helper function to change the selection from the root.
 	void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
 
@@ -176,6 +169,13 @@ class LLFolderViewItem : public LLView
 	virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
 
 public:
+	// This function clears the currently selected item, and records
+	// the specified selected item appropriately for display and use
+	// in the UI. If open is TRUE, then folders are opened up along
+	// the way to the selection.
+	void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
+		BOOL take_keyboard_focus = TRUE);
+
 	// This function is called when the folder view is dirty. It's
 	// implemented here but called by derived classes when folding the
 	// views.
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index b705543e444ca782c198990b53b05432c8f55fa1..edbeed2aa4722d616eaadc22837d20ad974a09f7 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -51,6 +51,7 @@
 
 #include "llviewercontrol.h"
 #include "llfirstuse.h"
+#include "llfoldertype.h"
 #include "llfloaterchat.h"
 #include "llfloatercustomize.h"
 #include "llfloaterproperties.h"
@@ -604,7 +605,7 @@ BOOL LLInvFVBridge::startDrag(EDragAndDropType* type, LLUUID* id) const
 
 	if(obj)
 	{
-		*type = LLAssetType::lookupDragAndDropType(obj->getType());
+		*type = LLAssetType::lookupDragAndDropType(obj->getActualType());
 		if(*type == DAD_NONE)
 		{
 			return FALSE;
@@ -653,11 +654,11 @@ BOOL LLInvFVBridge::isLinkedObjectInTrash() const
 {
 	if (isInTrash()) return TRUE;
 
-	LLInventoryModel* model = getInventoryModel();
-	if(!model) return FALSE;
-	LLInventoryObject *obj = model->getObject(mUUID);
+	LLInventoryObject *obj = getInventoryObject();
 	if (obj && LLAssetType::lookupIsLinkType(obj->getActualType()))
 	{
+		LLInventoryModel* model = getInventoryModel();
+		if(!model) return FALSE;
 		const LLUUID& trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
 		return model->isObjectDescendentOf(obj->getLinkedUUID(), trash_id);
 	}
@@ -735,6 +736,7 @@ const std::string safe_inv_type_lookup(LLInventoryType::EType inv_type)
 }
 
 LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
+										   LLAssetType::EType actual_asset_type,
 										   LLInventoryType::EType inv_type,
 										   LLInventoryPanel* inventory,
 										   const LLUUID& uuid,
@@ -833,12 +835,22 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
 			break;
 		case LLAssetType::AT_CATEGORY:
 		case LLAssetType::AT_ROOT_CATEGORY:
+			if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
+			{
+				// Create a link folder handler instead.
+				new_listener = new LLLinkFolderBridge(inventory, uuid);
+				break;
+			}
 			new_listener = new LLFolderBridge(inventory, uuid);
 			break;
 		case LLAssetType::AT_LINK:
 			// Only should happen for broken links.
 			new_listener = new LLLinkItemBridge(inventory, uuid);
 			break;
+		case LLAssetType::AT_LINK_FOLDER:
+			// Only should happen for broken links.
+			new_listener = new LLLinkItemBridge(inventory, uuid);
+			break;
 		default:
 			llinfos << "Unhandled asset type (llassetstorage.h): "
 					<< (S32)asset_type << llendl;
@@ -875,6 +887,10 @@ void LLInvFVBridge::purgeItem(LLInventoryModel *model, const LLUUID &uuid)
 
 void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
 {
+	if ("goto" == action)
+	{
+		gotoItem(folder);
+	}
 	if ("open" == action)
 	{
 		openItem();
@@ -1005,6 +1021,19 @@ void LLItemBridge::restoreToWorld()
 	}
 }
 
+void LLItemBridge::gotoItem(LLFolderView *folder)
+{
+	LLInventoryObject *obj = getInventoryObject();
+	if (obj && LLAssetType::lookupIsLinkType(obj->getActualType()))
+	{
+		LLInventoryPanel* active_panel = LLFloaterInventory::getActiveInventory()->getPanel();
+		if (active_panel)
+		{
+			active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
+		}
+	}
+}
+
 LLUIImagePtr LLItemBridge::getIcon() const
 {
 	return LLUI::getUIImage(ICON_NAME[OBJECT_ICON_NAME]);
@@ -1075,7 +1104,8 @@ std::string LLItemBridge::getLabelSuffix() const
 	static std::string NO_COPY =LLTrans::getString("no_copy");
 	static std::string NO_MOD = LLTrans::getString("no_modify");
 	static std::string NO_XFER = LLTrans::getString("no_transfer");
-
+	static std::string LINK = LLTrans::getString("link");
+	static std::string BROKEN_LINK = LLTrans::getString("broken_link");
 	std::string suffix;
 	LLInventoryItem* item = getItem();
 	if(item) 
@@ -1084,8 +1114,10 @@ std::string LLItemBridge::getLabelSuffix() const
 		if(LLAssetType::AT_CALLINGCARD != item->getType()
 		   && item->getPermissions().getOwner() == gAgent.getID())
 		{
-			BOOL link = (item->getActualType() == LLAssetType::AT_LINK);
-			const char* LINK = " (link)"; // *TODO: Seraph translate
+			BOOL broken_link = LLAssetType::lookupIsLinkType(item->getType());
+			if (broken_link) return BROKEN_LINK;
+
+			BOOL link = LLAssetType::lookupIsLinkType(item->getActualType());
 			if (link) return LINK;
 
 			BOOL copy = item->getPermissions().allowCopyBy(gAgent.getID());
@@ -1146,7 +1178,7 @@ BOOL LLItemBridge::renameItem(const std::string& new_name)
 		buildDisplayName(new_item, mDisplayName);
 		new_item->updateServer(FALSE);
 		model->updateItem(new_item);
-		renameLinkedItems(item->getUUID(),new_name);
+		model->updateLinkedObjects(item->getUUID());
 
 		model->notifyObservers();
 	}
@@ -1204,7 +1236,7 @@ BOOL LLItemBridge::isItemCopyable() const
 		// All items can be copied, not all can be pasted.
 		// The only time an item can't be copied is if it's a link 
 		// return (item->getPermissions().allowCopyBy(gAgent.getID()));
-		if (item->getActualType() == LLAssetType::AT_LINK)
+		if (LLAssetType::lookupIsLinkType(item->getActualType()))
 		{
 			return FALSE;
 		}
@@ -1259,7 +1291,7 @@ BOOL LLFolderBridge::isItemMovable()
 	LLInventoryObject* obj = getInventoryObject();
 	if(obj)
 	{
-		return (LLAssetType::AT_NONE == ((LLInventoryCategory*)obj)->getPreferredType());
+		return (!LLAssetType::lookupIsProtectedCategoryType(((LLInventoryCategory*)obj)->getPreferredType()));
 	}
 	return FALSE;
 }
@@ -1295,7 +1327,7 @@ BOOL LLFolderBridge::isItemRemovable()
 		return FALSE;
 	}
 
-	if( LLAssetType::AT_NONE != category->getPreferredType() )
+	if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType()))
 	{
 		return FALSE;
 	}
@@ -1308,7 +1340,7 @@ BOOL LLFolderBridge::isItemRemovable()
 	for( i = 0; i < descendent_categories.count(); i++ )
 	{
 		LLInventoryCategory* category = descendent_categories[i];
-		if( LLAssetType::AT_NONE != category->getPreferredType() )
+		if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType()))
 		{
 			return FALSE;
 		}
@@ -1403,7 +1435,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 		trash_id = model->findCategoryUUIDForType(LLAssetType::AT_TRASH);
 		BOOL move_is_into_trash = (mUUID == trash_id)
 				|| model->isObjectDescendentOf(mUUID, trash_id);
-		BOOL is_movable = (LLAssetType::AT_NONE == inv_cat->getPreferredType());
+		BOOL is_movable = (!LLAssetType::lookupIsProtectedCategoryType(inv_cat->getPreferredType()));
 		if( is_movable )
 		{
 			gInventory.collectDescendents( cat_id, descendent_categories, descendent_items, FALSE );
@@ -1411,7 +1443,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 			for( i = 0; i < descendent_categories.count(); i++ )
 			{
 				LLInventoryCategory* category = descendent_categories[i];
-				if( LLAssetType::AT_NONE != category->getPreferredType() )
+				if(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType()))
 				{
 					// ...can't move "special folders" like Textures
 					is_movable = FALSE;
@@ -1868,7 +1900,7 @@ void LLFolderBridge::openItem()
 BOOL LLFolderBridge::isItemRenameable() const
 {
 	LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)getCategory();
-	if(cat && (cat->getPreferredType() == LLAssetType::AT_NONE)
+	if(cat && !LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType())
 	   && (cat->getOwnerID() == gAgent.getID()))
 	{
 		return TRUE;
@@ -1904,13 +1936,26 @@ LLAssetType::EType LLFolderBridge::getPreferredType() const
 // Icons for folders are based on the preferred type
 LLUIImagePtr LLFolderBridge::getIcon() const
 {
-	const char* control = NULL;
 	LLAssetType::EType preferred_type = LLAssetType::AT_NONE;
 	LLViewerInventoryCategory* cat = getCategory();
 	if(cat)
 	{
 		preferred_type = cat->getPreferredType();
 	}
+	return getIcon(preferred_type);
+}
+
+LLUIImagePtr LLFolderBridge::getIcon(LLAssetType::EType preferred_type)
+{
+	if (preferred_type >= LLAssetType::AT_FOLDER_ENSEMBLE_START &&
+		preferred_type <= LLAssetType::AT_FOLDER_ENSEMBLE_END)
+	{
+		LLUIImage* icon = LLUI::getUIImage(LLFolderType::lookupIconName(preferred_type));
+		if (icon)
+			return icon;
+	}
+	
+	const char* control = NULL;
 	switch(preferred_type)
 	{
 		case LLAssetType::AT_TEXTURE:
@@ -1984,7 +2029,7 @@ BOOL LLFolderBridge::renameItem(const std::string& new_name)
 		new_cat->rename(new_name);
 		new_cat->updateServer(FALSE);
 		model->updateCategory(new_cat);
-		renameLinkedItems(cat->getUUID(),new_name);
+		model->updateLinkedObjects(cat->getUUID());
 
 		model->notifyObservers();
 	}
@@ -2066,15 +2111,24 @@ void LLFolderBridge::pasteLinkFromClipboard()
 	LLInventoryModel* model = getInventoryModel();
 	if(model)
 	{
-		LLInventoryItem* item = NULL;
 		LLDynamicArray<LLUUID> objects;
 		LLInventoryClipboard::instance().retrieve(objects);
 		S32 count = objects.count();
 		LLUUID parent_id(mUUID);
 		for(S32 i = 0; i < count; i++)
 		{
-			item = model->getItem(objects.get(i));
-			if (item)
+			const LLUUID &object_id = objects.get(i);
+			if (LLInventoryCategory *cat = model->getCategory(object_id))
+			{
+				link_inventory_item(
+					gAgent.getID(),
+					cat->getUUID(),
+					parent_id,
+					cat->getName(),
+					LLAssetType::AT_LINK_FOLDER,
+					LLPointer<LLInventoryCallback>(NULL));
+			}
+			else if (LLInventoryItem *item = model->getItem(object_id))
 			{
 				link_inventory_item(
 					gAgent.getID(),
@@ -2103,7 +2157,7 @@ void LLFolderBridge::folderOptionsMenu()
 
 	const LLInventoryCategory* category = model->getCategory(mUUID);
 	bool is_default_folder = category &&
-		(LLAssetType::AT_NONE != category->getPreferredType());
+		(LLAssetType::lookupIsProtectedCategoryType(category->getPreferredType()));
 	
 	// calling card related functionality for folders.
 
@@ -2199,7 +2253,14 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 		mItems.push_back(std::string("New Gesture"));
 		mItems.push_back(std::string("New Clothes"));
 		mItems.push_back(std::string("New Body Parts"));
+		mItems.push_back(std::string("Change Type"));
 
+		LLViewerInventoryCategory *cat =  getCategory();
+		if (cat && LLAssetType::lookupIsProtectedCategoryType(cat->getPreferredType()))
+		{
+			mDisabledItems.push_back(std::string("Change Type"));
+		}
+		
 		getClipboardEntries(false, mItems, mDisabledItems, flags);
 
 		//Added by spatters to force inventory pull on right-click to display folder options correctly. 07-17-06
@@ -2268,26 +2329,27 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop,
 	BOOL accept = FALSE;
 	switch(cargo_type)
 	{
-	case DAD_TEXTURE:
-	case DAD_SOUND:
-	case DAD_CALLINGCARD:
-	case DAD_LANDMARK:
-	case DAD_SCRIPT:
-	case DAD_OBJECT:
-	case DAD_NOTECARD:
-	case DAD_CLOTHING:
-	case DAD_BODYPART:
-	case DAD_ANIMATION:
-	case DAD_GESTURE:
-		accept = dragItemIntoFolder((LLInventoryItem*)cargo_data,
-									drop);
-		break;
-	case DAD_CATEGORY:
-		accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data,
+		case DAD_TEXTURE:
+		case DAD_SOUND:
+		case DAD_CALLINGCARD:
+		case DAD_LANDMARK:
+		case DAD_SCRIPT:
+		case DAD_OBJECT:
+		case DAD_NOTECARD:
+		case DAD_CLOTHING:
+		case DAD_BODYPART:
+		case DAD_ANIMATION:
+		case DAD_GESTURE:
+		case DAD_LINK:
+			accept = dragItemIntoFolder((LLInventoryItem*)cargo_data,
 										drop);
-		break;
-	default:
-		break;
+			break;
+		case DAD_CATEGORY:
+			accept = dragCategoryIntoFolder((LLInventoryCategory*)cargo_data,
+											drop);
+			break;
+		default:
+			break;
 	}
 	return accept;
 }
@@ -2490,14 +2552,14 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 	{
 
 		BOOL is_movable = TRUE;
-		switch( inv_item->getType() )
+		switch( inv_item->getActualType() )
 		{
 		case LLAssetType::AT_ROOT_CATEGORY:
 			is_movable = FALSE;
 			break;
 
 		case LLAssetType::AT_CATEGORY:
-			is_movable = ( LLAssetType::AT_NONE == ((LLInventoryCategory*)inv_item)->getPreferredType() );
+			is_movable = !LLAssetType::lookupIsProtectedCategoryType(((LLInventoryCategory*)inv_item)->getPreferredType());
 			break;
 		default:
 			break;
@@ -2511,11 +2573,11 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			{
 			case LLAssetType::AT_CLOTHING:
 			case LLAssetType::AT_BODYPART:
-				is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID());
+				is_movable = !gAgentWearables.isWearingItem(inv_item->getUUID(), TRUE);
 				break;
 
 			case LLAssetType::AT_OBJECT:
-				is_movable = !avatar->isWearingAttachment(inv_item->getUUID());
+				is_movable = !avatar->isWearingAttachment(inv_item->getUUID(), TRUE);
 				break;
 			default:
 				break;
@@ -3435,7 +3497,7 @@ LLFontGL::StyleFlags LLObjectBridge::getLabelStyle() const
 	}
 
 	LLInventoryItem* item = getItem();
-	if (item->getActualType() == LLAssetType::AT_LINK)
+	if (LLAssetType::lookupIsLinkType(item->getActualType()))
 	{
 		font |= LLFontGL::ITALIC;
 	}
@@ -3533,13 +3595,18 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	}
 	else
 	{
+		LLInventoryItem* item = getItem();
+		if (item && LLAssetType::lookupIsLinkType(item->getActualType()))
+		{
+			items.push_back(std::string("Goto Link"));
+		}
+
 		items.push_back(std::string("Properties"));
 
 		getClipboardEntries(true, items, disabled_items, flags);
 
 		LLObjectBridge::sContextMenuItemID = mUUID;
 
-		LLInventoryItem* item = getItem();
 		if(item)
 		{
 			LLVOAvatarSelf* avatarp = gAgent.getAvatarObject();
@@ -3619,7 +3686,7 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name)
 		buildDisplayName(new_item, mDisplayName);
 		new_item->updateServer(FALSE);
 		model->updateItem(new_item);
-		renameLinkedItems(item->getUUID(),new_name);
+		model->updateLinkedObjects(item->getUUID());
 
 		model->notifyObservers();
 
@@ -4513,6 +4580,11 @@ void LLWearableBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 			items.push_back(std::string("Open"));
 		}
 
+		if (item && LLAssetType::lookupIsLinkType(item->getActualType()))
+		{
+			items.push_back(std::string("Goto Link"));
+		}
+
 		items.push_back(std::string("Properties"));
 
 		getClipboardEntries(true, items, disabled_items, flags);
@@ -5093,3 +5165,94 @@ void LLLinkItemBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	}
 	hideContextEntries(menu, items, disabled_items);
 }
+
+
+// +=================================================+
+// |        LLLinkBridge                             |
+// +=================================================+
+// For broken links.
+
+std::string LLLinkFolderBridge::sPrefix("Link: ");
+
+
+LLUIImagePtr LLLinkFolderBridge::getIcon() const
+{
+	LLAssetType::EType preferred_type = LLAssetType::AT_NONE;
+	if (LLViewerInventoryItem *item = getItem())
+	{
+		if (const LLViewerInventoryCategory* cat = item->getLinkedCategory())
+		{
+			preferred_type = cat->getPreferredType();
+		}
+	}
+	return LLFolderBridge::getIcon(preferred_type);
+}
+
+void LLLinkFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+	// *TODO: Translate
+	lldebugs << "LLLink::buildContextMenu()" << llendl;
+	std::vector<std::string> items;
+	std::vector<std::string> disabled_items;
+
+	if(isInTrash())
+	{
+		items.push_back(std::string("Purge Item"));
+		if (!isItemRemovable())
+		{
+			disabled_items.push_back(std::string("Purge Item"));
+		}
+
+		items.push_back(std::string("Restore Item"));
+	}
+	else
+	{	
+		items.push_back(std::string("Goto Link"));
+		items.push_back(std::string("Delete"));
+		if (!isItemRemovable())
+		{
+			disabled_items.push_back(std::string("Delete"));
+		}
+	}
+	hideContextEntries(menu, items, disabled_items);
+}
+
+void LLLinkFolderBridge::performAction(LLFolderView* folder, LLInventoryModel* model, std::string action)
+{
+	if ("goto" == action)
+	{
+		gotoItem(folder);
+		return;
+	}
+	LLItemBridge::performAction(folder,model,action);
+}
+
+void LLLinkFolderBridge::gotoItem(LLFolderView *folder)
+{
+	const LLUUID &cat_uuid = getFolderID();
+	if (!cat_uuid.isNull())
+	{
+		if (LLFolderViewItem *base_folder = folder->getItemByID(cat_uuid))
+		{
+			if (LLInventoryModel* model = getInventoryModel())
+			{
+				model->fetchDescendentsOf(cat_uuid);
+			}
+			base_folder->setOpen(TRUE);
+			folder->setSelectionFromRoot(base_folder,TRUE);
+		}
+	}
+}
+
+const LLUUID &LLLinkFolderBridge::getFolderID() const
+{
+	if (LLViewerInventoryItem *link_item = getItem())
+	{
+		if (const LLViewerInventoryCategory *cat = link_item->getLinkedCategory())
+		{
+			const LLUUID& cat_uuid = cat->getUUID();
+			return cat_uuid;
+		}
+	}
+	return LLUUID::null;
+}
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index a37b7969edfee7622a28956bab989efe6ba868ee..915dfec629c7c9b9c28d73e7f94c8100f39e59e0 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -133,6 +133,7 @@ class LLInvFVBridge : public LLFolderViewEventListener
 	// This method is a convenience function which creates the correct
 	// type of bridge based on some basic information
 	static LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
+									   LLAssetType::EType actual_asset_type,
 									   LLInventoryType::EType inv_type,
 									   LLInventoryPanel* inventory,
 									   const LLUUID& uuid,
@@ -156,6 +157,7 @@ class LLInvFVBridge : public LLFolderViewEventListener
 	}
 	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
 	virtual void openItem() {}
+	virtual void gotoItem(LLFolderView *folder) {} // for links
 	virtual void previewItem() {openItem();}
 	virtual void showProperties();
 	virtual BOOL isItemRenameable() const { return TRUE; }
@@ -231,6 +233,7 @@ class LLItemBridge : public LLInvFVBridge
 	virtual void selectItem();
 	virtual void restoreItem();
 	virtual void restoreToWorld();
+	virtual void gotoItem(LLFolderView *folder);
 
 	virtual LLUIImagePtr getIcon() const;
 	virtual const std::string& getDisplayName() const;
@@ -274,6 +277,8 @@ class LLFolderBridge : public LLInvFVBridge
 
 	virtual LLAssetType::EType getPreferredType() const;
 	virtual LLUIImagePtr getIcon() const;
+	static LLUIImagePtr getIcon(LLAssetType::EType asset_type);
+
 	virtual BOOL renameItem(const std::string& new_name);
 	virtual BOOL removeItem();
 	virtual void pasteFromClipboard();
@@ -591,6 +596,27 @@ class LLLinkItemBridge : public LLItemBridge
 	static std::string sPrefix;
 };
 
+
+class LLLinkFolderBridge : public LLItemBridge
+{
+	friend class LLInvFVBridge;
+public:
+	virtual const std::string& getPrefix() { return sPrefix; }
+
+	virtual LLUIImagePtr getIcon() const;
+	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+	virtual void performAction(LLFolderView* folder, LLInventoryModel* model, std::string action);
+	virtual void gotoItem(LLFolderView *folder);
+
+protected:
+	LLLinkFolderBridge(LLInventoryPanel* inventory, const LLUUID& uuid) :
+		LLItemBridge(inventory, uuid) {}
+	const LLUUID &getFolderID() const;
+
+protected:
+	static std::string sPrefix;
+};
+
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLInvFVBridgeAction (& its derived classes)
 //
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 2c281a46157db183038ba5a14688c6532ab4aba1..bba0c9a90d3ce1a09e115bccb82c4abfceb5cf77 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -475,6 +475,35 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,
 	}
 }
 
+void LLInventoryModel::updateLinkedObjects(const LLUUID& object_id)
+{
+	LLInventoryModel::cat_array_t cat_array;
+	LLInventoryModel::item_array_t item_array;
+	LLLinkedItemIDMatches is_linked_item_match(object_id);
+	collectDescendentsIf(gInventory.getRootFolderID(),
+						 cat_array,
+						 item_array,
+						 LLInventoryModel::INCLUDE_TRASH,
+						 is_linked_item_match);
+
+	for (LLInventoryModel::cat_array_t::iterator cat_iter = cat_array.begin();
+		 cat_iter != cat_array.end();
+		 cat_iter++)
+	{
+		LLViewerInventoryCategory *linked_cat = (*cat_iter);
+		addChangedMask(LLInventoryObserver::LABEL, linked_cat->getUUID());
+	};
+
+	for (LLInventoryModel::item_array_t::iterator iter = item_array.begin();
+		 iter != item_array.end();
+		 iter++)
+	{
+		LLViewerInventoryItem *linked_item = (*iter);
+		addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
+	};
+	notifyObservers();
+}
+
 void LLInventoryModel::collectLinkedItems(const LLUUID& id,
 										  item_array_t& items)
 {
@@ -825,10 +854,10 @@ void LLInventoryModel::purgeObject(const LLUUID &id)
 
 void LLInventoryModel::purgeLinkedObjects(const LLUUID &id)
 {
-	LLInventoryItem* itemp = getItem(id);
-	if (!itemp) return;
+	LLInventoryObject* objectp = getObject(id);
+	if (!objectp) return;
 
-	if (LLAssetType::lookupIsLinkType(itemp->getActualType()))
+	if (LLAssetType::lookupIsLinkType(objectp->getActualType()))
 	{
 		return;
 	}
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index c402fea8863e30c51d4af67d220af905d8c23ee2..f470a779853881f88051a678ee7ada30b963f357 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -181,7 +181,6 @@ class LLInventoryModel
 							cat_array_t& categories,
 							item_array_t& items,
 							BOOL include_trash);
-
 	void collectDescendentsIf(const LLUUID& id,
 							  cat_array_t& categories,
 							  item_array_t& items,
@@ -192,8 +191,9 @@ class LLInventoryModel
 	// Assumes item_id is itself not a linked item.
 	void collectLinkedItems(const LLUUID& item_id,
 							item_array_t& items);
-	
-	// This method will return false if this inventory model is in an usabel state.
+	// Updates all linked objects pointing to this id.
+	void updateLinkedObjects(const LLUUID& object_id);
+
 	// The inventory model usage is sensitive to the initial construction of the 
 	// model. 
 	bool isInventoryUsable();
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 3a7ef4dfc95fe53c18430785afc30d19210812a2..d2e07f0725f6191034504452240af80a11bc12c6 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -473,6 +473,14 @@ LLToolDragAndDrop::dragOrDrop3dImpl LLToolDragAndDrop::sDragAndDrop3d[DAD_COUNT]
 		&LLToolDragAndDrop::dad3dUpdateInventory, // Dest: DT_OBJECT
 		&LLToolDragAndDrop::dad3dNULL,//dad3dAssetOnLand, // Dest: DT_LAND
 	},
+	//	Source: DAD_LINK
+	{
+		&LLToolDragAndDrop::dad3dNULL, // Dest: DT_NONE
+		&LLToolDragAndDrop::dad3dNULL, // Dest: DT_SELF
+		&LLToolDragAndDrop::dad3dNULL, // Dest: DT_AVATAR
+		&LLToolDragAndDrop::dad3dNULL, // Dest: DT_OBJECT
+		&LLToolDragAndDrop::dad3dNULL,//dad3dAssetOnLand, // Dest: DT_LAND
+	},
 };
 
 LLToolDragAndDrop::LLToolDragAndDrop()
@@ -1894,7 +1902,7 @@ BOOL LLToolDragAndDrop::isInventoryGroupGiveAcceptable(LLInventoryItem* item)
 		acceptable = FALSE;
 		break;
 	case LLAssetType::AT_OBJECT:
-		if(my_avatar->isWearingAttachment(item->getUUID()))
+		if(my_avatar->isWearingAttachment(item->getUUID(), TRUE))
 		{
 			acceptable = FALSE;
 		}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 54b0a4f5683af170f8c56b2e3eb42ddc71e71e21..66da7d89fb3187e468763837e4b9c34703033df1 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -403,7 +403,8 @@ void LLViewerInventoryCategory::updateParentOnServer(BOOL restamp) const
 void LLViewerInventoryCategory::updateServer(BOOL is_new) const
 {
 	// communicate that change with the server.
-	if(LLAssetType::AT_NONE != mPreferredType)
+
+	if (LLAssetType::lookupIsProtectedCategoryType(mPreferredType))
 	{
 		LLNotifications::instance().add("CannotModifyProtectedCategories");
 		return;
@@ -427,7 +428,7 @@ void LLViewerInventoryCategory::removeFromServer( void )
 	llinfos << "Removing inventory category " << mUUID << " from server."
 			<< llendl;
 	// communicate that change with the server.
-	if(LLAssetType::AT_NONE != mPreferredType)
+	if(LLAssetType::lookupIsProtectedCategoryType(mPreferredType))
 	{
 		LLNotifications::instance().add("CannotRemoveProtectedCategories");
 		return;
@@ -977,7 +978,10 @@ LLAssetType::EType LLViewerInventoryItem::getType() const
 	{
 		return linked_item->getType();
 	}
-	
+	if (const LLViewerInventoryCategory *linked_category = getLinkedCategory())
+	{
+		return linked_category->getType();
+	}	
 	return LLInventoryItem::getType();
 }
 
@@ -997,6 +1001,10 @@ const std::string& LLViewerInventoryItem::getName() const
 	{
 		return linked_item->getName();
 	}
+	if (const LLViewerInventoryCategory *linked_category = getLinkedCategory())
+	{
+		return linked_category->getName();
+	}
 
 	return LLInventoryItem::getName();
 }
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 7084c9f37ae5cbf17437651ddeb3e5e065467c8b..5198f5efc7772dc5e0a62ede3b82880d0eba2f7f 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -141,7 +141,6 @@ class LLViewerInventoryItem : public LLInventoryItem
 	};
 	LLTransactionID getTransactionID() const { return mTransactionID; }
 	
-protected:
 	const LLViewerInventoryItem *getLinkedItem() const;
 	const LLViewerInventoryCategory *getLinkedCategory() const;
 
diff --git a/indra/newview/skins/default/xui/en/menu_inventory.xml b/indra/newview/skins/default/xui/en/menu_inventory.xml
index 6f2fd5e5e5ee29b7b6551b1fa6d6279ab852cb5b..c788f8f095e72e9a2bcc0b0deddc337f6cfe4148 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory.xml
@@ -76,6 +76,14 @@
          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 Script"
      layout="topleft"
@@ -230,6 +238,91 @@
              parameter="eyes" />
         </menu_item_call>
     </menu>
+    <menu
+     label="Change Type"
+     layout="topleft"
+     name="Change Type">
+        <menu_item_call
+         label="Default"
+         layout="topleft"
+         name="Default">
+            <menu_item_call.on_click
+             function="Inventory.DoToSelected"
+             parameter="change_folder_type_default" />
+        </menu_item_call>
+        <menu_item_call
+         label="Gloves"
+         layout="topleft"
+         name="Gloves">
+            <menu_item_call.on_click
+             function="Inventory.DoToSelected"
+             parameter="change_folder_type_gloves" />
+        </menu_item_call>
+        <menu_item_call
+         label="Jacket"
+         layout="topleft"
+         name="Jacket">
+            <menu_item_call.on_click
+             function="Inventory.DoToSelected"
+             parameter="change_folder_type_jacket" />
+        </menu_item_call>
+        <menu_item_call
+         label="Pants"
+         layout="topleft"
+         name="Pants">
+            <menu_item_call.on_click
+             function="Inventory.DoToSelected"
+             parameter="change_folder_type_pants" />
+        </menu_item_call>
+        <menu_item_call
+         label="Shape"
+         layout="topleft"
+         name="Shape">
+            <menu_item_call.on_click
+             function="Inventory.DoToSelected"
+             parameter="change_folder_type_shape" />
+        </menu_item_call>
+        <menu_item_call
+         label="Shoes"
+         layout="topleft"
+         name="Shoes">
+            <menu_item_call.on_click
+             function="Inventory.DoToSelected"
+             parameter="change_folder_type_shoes" />
+        </menu_item_call>
+        <menu_item_call
+         label="Shirt"
+         layout="topleft"
+         name="Shirt">
+            <menu_item_call.on_click
+             function="Inventory.DoToSelected"
+             parameter="change_folder_type_shirt" />
+        </menu_item_call>
+        <menu_item_call
+         label="Skirt"
+         layout="topleft"
+         name="Skirt">
+            <menu_item_call.on_click
+             function="Inventory.DoToSelected"
+             parameter="change_folder_type_skirt" />
+        </menu_item_call>
+        <menu_item_call
+         label="Underpants"
+         layout="topleft"
+         name="Underpants">
+            <menu_item_call.on_click
+             function="Inventory.DoToSelected"
+             parameter="change_folder_type_underpants" />
+        </menu_item_call>
+        <menu_item_call
+         label="Undershirt"
+         layout="topleft"
+         name="Undershirt">
+            <menu_item_call.on_click
+             function="Inventory.DoToSelected"
+             parameter="change_folder_type_undershirt" />
+        </menu_item_call>
+    </menu>
     <menu_item_call
      label="Teleport"
      layout="topleft"
@@ -270,6 +363,14 @@
          function="Inventory.DoToSelected"
          parameter="restore" />
     </menu_item_call>
+    <menu_item_call
+     label="Goto Link"
+     layout="topleft"
+     name="Goto Link">
+        <menu_item_call.on_click
+         function="Inventory.DoToSelected"
+         parameter="goto" />
+    </menu_item_call>
     <menu_item_call
      label="Open"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index e54ef88f3401d06d5f882938e5a5c82315bc49a8..626c084f0c1c7e3c2f263c71d05abdef37bd02fa 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -346,6 +346,8 @@ this texture in your inventory
 	<string name="no_modify"   value=" (no modify)" />
 	<string name="no_copy"     value=" (no copy)" />
 	<string name="worn"        value=" (worn)" />
+	<string name="link"        value=" (link)" />
+	<string name="broken_link" value=" (broken_link)" />
 	<string name="LoadingContents">Loading contents...</string>
 	<string name="NoContents">No contents</string>