diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp
index fad2b7bc990749279c2e32f12cb9991c451ece45..6fa99df82eec7f3f449f8eb5d27c95d3c642f01b 100644
--- a/indra/llui/llsearcheditor.cpp
+++ b/indra/llui/llsearcheditor.cpp
@@ -141,6 +141,15 @@ void LLSearchEditor::clear()
 	}
 }
 
+//virtual
+void LLSearchEditor::setFocus( BOOL b )
+{
+	if (mSearchEditor)
+	{
+		mSearchEditor->setFocus(b);
+	}
+}
+
 void LLSearchEditor::onClearButtonClick(const LLSD& data)
 {
 	setText(LLStringUtil::null);
diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h
index f395e7e8161c0b5198ab425628091a786f39cf33..bd2d595174811d87aaa0d6235240a91b6c7775e9 100644
--- a/indra/llui/llsearcheditor.h
+++ b/indra/llui/llsearcheditor.h
@@ -83,6 +83,7 @@ class LLSearchEditor : public LLUICtrl
 	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
 	virtual void	setLabel( const LLStringExplicit &new_label );
 	virtual void	clear();
+	virtual void	setFocus( BOOL b );
 
 	void			setKeystrokeCallback( commit_callback_t cb ) { mKeystrokeCallback = cb; }
 
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index af9a30cb257b3d93a4b332be11e75b468a6aaa1f..86bbb0bcf8b05750bee689be9464354702ecfd6e 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -1441,7 +1441,7 @@ static void fixOrigin(void)
 	::GetPortBounds(port, &portrect);
 	if((portrect.left != 0) || (portrect.top != 0))
 	{
-		// Mozilla sometimes changes our port origin.  Fuckers.
+		// Mozilla sometimes changes our port origin.
 		::SetOrigin(0,0);
 	}
 }
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index c7f05d99f7f403bc7bd7caccaa3abb29edd96e29..d91b9d7ea431e6b03948cba209a7b06145bbb682 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -512,6 +512,21 @@ void LLAppearanceManager::updateCOF(const LLUUID& category, bool append)
 {
 	const LLUUID cof = getCOF();
 
+	// Deactivate currently active gestures in the COF, if replacing outfit
+	if (!append)
+	{
+		LLInventoryModel::item_array_t gest_items;
+		getDescendentsOfAssetType(cof, gest_items, LLAssetType::AT_GESTURE, false);
+		for(S32 i = 0; i  < gest_items.count(); ++i)
+		{
+			LLViewerInventoryItem *gest_item = gest_items.get(i);
+			if ( LLGestureManager::instance().isGestureActive( gest_item->getLinkedUUID()) )
+			{
+				LLGestureManager::instance().deactivateGesture( gest_item->getLinkedUUID() );
+			}
+		}
+	}
+	
 	// Collect and filter descendents to determine new COF contents.
 
 	// - Body parts: always include COF contents as a fallback in case any
diff --git a/indra/newview/llfolderview.cpp b/indra/newview/llfolderview.cpp
index 6a3462f20105e65cbead05db8792551f84206020..4e77b421875855e1a9a390ef8bb915a60103d32a 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/newview/llfolderview.cpp
@@ -2208,9 +2208,9 @@ void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask )
 	mFilter->setFilterPermissions(filter_perm_mask);
 }
 
-U32 LLFolderView::getFilterTypes() const
+U32 LLFolderView::getFilterObjectTypes() const
 {
-	return mFilter->getFilterTypes();
+	return mFilter->getFilterObjectTypes();
 }
 
 PermissionMask LLFolderView::getFilterPermissions() const
diff --git a/indra/newview/llfolderview.h b/indra/newview/llfolderview.h
index eaaba8c13d01b9c7c682404a6cfe2fbe60f37b01..4adf6c2fbf90ef38335d46eebc1f445a7d9dc0b0 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/newview/llfolderview.h
@@ -71,9 +71,6 @@ class LLUICtrl;
 // that only work folders or only work on items, but I'll worry about
 // that later when it's determined to be too slow.
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-
-
 class LLFolderViewFunctor
 {
 public:
@@ -119,7 +116,7 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	// filter is never null
 	LLInventoryFilter* getFilter();
 	const std::string getFilterSubString(BOOL trim = FALSE);
-	U32 getFilterTypes() const;
+	U32 getFilterObjectTypes() const;
 	PermissionMask getFilterPermissions() const;
 	// JAMESDEBUG use getFilter()->getShowFolderState();
 	//LLInventoryFilter::EFolderShow getShowFolderState();
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 18ff53c127d5cc13e2b3727d0d5c7dabfc3c1951..4f487ddf04ccb65b8be2b57ecd5c01702886594a 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -57,6 +57,7 @@
 #include "llvoavatarself.h"
 #include "llviewerstats.h"
 #include "llnearbychatbar.h"
+#include "llappearancemgr.h"
 
 // Longest time, in seconds, to wait for all animations to stop playing
 const F32 MAX_WAIT_ANIM_SECS = 30.f;
@@ -303,6 +304,8 @@ void LLGestureManager::deactivateGesture(const LLUUID& item_id)
 
 	gAgent.sendReliableMessage();
 
+	LLAppearanceManager::instance().removeCOFItemLinks(base_item_id, false);
+
 	notifyObservers();
 }
 
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 5bfad0695c1c0ca7552c3d7f23d7f920c2683e6f..4c28d5e2df906b5692e9e5f63d3ce8aac2d20243 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -512,37 +512,44 @@ void LLInvFVBridge::getClipboardEntries(bool show_asset_id,
 										std::vector<std::string> &disabled_items, U32 flags)
 {
 	const LLInventoryObject *obj = getInventoryObject();
-	if (obj && obj->getIsLinkType())
-	{
-		items.push_back(std::string("Find Original"));
-		if (isLinkedObjectMissing())
-		{
-			disabled_items.push_back(std::string("Find Original"));
-		}
-	}
-	else
+	if (obj)
 	{
-		items.push_back(std::string("Rename"));
-		if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
-		{
-			disabled_items.push_back(std::string("Rename"));
-		}
-		
-		if (show_asset_id)
+		if (obj->getIsLinkType())
 		{
-			items.push_back(std::string("Copy Asset UUID"));
-			if ( (! ( isItemPermissive() || gAgent.isGodlike() ) )
-				 || (flags & FIRST_SELECTED_ITEM) == 0)
+			items.push_back(std::string("Find Original"));
+			if (isLinkedObjectMissing())
 			{
-				disabled_items.push_back(std::string("Copy Asset UUID"));
+				disabled_items.push_back(std::string("Find Original"));
 			}
 		}
-		items.push_back(std::string("Copy Separator"));
-		
-		items.push_back(std::string("Copy"));
-		if (!isItemCopyable())
+		else
 		{
-			disabled_items.push_back(std::string("Copy"));
+			if (LLAssetType::lookupCanLink(obj->getType()))
+			{
+				items.push_back(std::string("Find Links"));
+			}
+			items.push_back(std::string("Rename"));
+			if (!isItemRenameable() || (flags & FIRST_SELECTED_ITEM) == 0)
+			{
+				disabled_items.push_back(std::string("Rename"));
+			}
+			
+			if (show_asset_id)
+			{
+				items.push_back(std::string("Copy Asset UUID"));
+				if ( (! ( isItemPermissive() || gAgent.isGodlike() ) )
+					 || (flags & FIRST_SELECTED_ITEM) == 0)
+				{
+					disabled_items.push_back(std::string("Copy Asset UUID"));
+				}
+			}
+			items.push_back(std::string("Copy Separator"));
+			
+			items.push_back(std::string("Copy"));
+			if (!isItemCopyable())
+			{
+				disabled_items.push_back(std::string("Copy"));
+			}
 		}
 	}
 
@@ -931,6 +938,7 @@ void LLItemBridge::performAction(LLFolderView* folder, LLInventoryModel* model,
 	{
 		gotoItem(folder);
 	}
+
 	if ("open" == action)
 	{
 		openItem();
@@ -3768,8 +3776,14 @@ void LLGestureBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 		getClipboardEntries(true, items, disabled_items, flags);
 
 		items.push_back(std::string("Gesture Separator"));
-		items.push_back(std::string("Activate"));
-		items.push_back(std::string("Deactivate"));
+		if (LLGestureManager::instance().isGestureActive(getUUID()))
+		{
+			items.push_back(std::string("Deactivate"));
+		}
+		else
+		{
+			items.push_back(std::string("Activate"));
+		}
 	}
 	hide_context_entries(menu, items, disabled_items);
 }
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 67dfc5b6f9a629577c651229bd4b97a270f9b2aa..63be9dcdb82de1cc0d4e553404092cc2742e741d 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -154,7 +154,6 @@ class LLInvFVBridge : public LLFolderViewEventListener
 	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
 	virtual void openItem() {}
 	virtual void closeItem() {}
-	virtual void gotoItem(LLFolderView *folder) {} // for links
 	virtual void previewItem() {openItem();}
 	virtual void showProperties();
 	virtual BOOL isItemRenameable() const { return TRUE; }
@@ -241,7 +240,6 @@ class LLItemBridge : public LLInvFVBridge
 	virtual void restoreItem();
 	virtual void restoreToWorld();
 	virtual void gotoItem(LLFolderView *folder);
-
 	virtual LLUIImagePtr getIcon() const;
 	virtual const std::string& getDisplayName() const;
 	virtual std::string getLabelSuffix() const;
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 085c96c93ddf9119a52d69803510147b99c8cf60..4c5e4d560732d2e179e2cc5a0af8731feae42638 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -44,6 +44,19 @@
 // linden library includes
 #include "lltrans.h"
 
+LLInventoryFilter::FilterOps::FilterOps() :
+	mFilterObjectTypes(0xffffffffffffffffULL),
+	mFilterCategoryTypes(0xffffffffffffffffULL),
+	mMinDate(time_min()),
+	mMaxDate(time_max()),
+	mHoursAgo(0),
+	mShowFolderState(SHOW_NON_EMPTY_FOLDERS),
+	mPermissions(PERM_NONE),
+	mFilterTypes(FILTERTYPE_OBJECT),
+	mFilterUUID(LLUUID::null)
+{
+}
+
 ///----------------------------------------------------------------------------
 /// Class LLInventoryFilter
 ///----------------------------------------------------------------------------
@@ -52,14 +65,6 @@ LLInventoryFilter::LLInventoryFilter(const std::string& name)
 	mModified(FALSE),
 	mNeedTextRebuild(TRUE)
 {
-	mFilterOps.mFilterTypes = 0xffffffffffffffffULL;
-	mFilterOps.mMinDate = time_min();
-	mFilterOps.mMaxDate = time_max();
-	mFilterOps.mHoursAgo = 0;
-	mFilterOps.mShowFolderState = SHOW_NON_EMPTY_FOLDERS;
-	mFilterOps.mPermissions = PERM_NONE;
-	mFilterOps.mFilterForCategories = FALSE;
-
 	mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately
 
 	mSubStringMatchOffset = 0;
@@ -81,11 +86,17 @@ LLInventoryFilter::~LLInventoryFilter()
 {
 }
 
-BOOL LLInventoryFilter::check(LLFolderViewItem* item) 
+BOOL LLInventoryFilter::check(const LLFolderViewItem* item) 
 {
-	time_t earliest;
+	// If it's a folder and we're showing all folders, return TRUE automatically.
+	const BOOL is_folder = (dynamic_cast<const LLFolderViewFolder*>(item) != NULL);
+	if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
+	{
+		return TRUE;
+	}
 
-	earliest = time_corrected() - mFilterOps.mHoursAgo * 3600;
+	const U16 HOURS_TO_SECONDS = 3600;
+	time_t earliest = time_corrected() - mFilterOps.mHoursAgo * HOURS_TO_SECONDS;
 	if (mFilterOps.mMinDate > time_min() && mFilterOps.mMinDate < earliest)
 	{
 		earliest = mFilterOps.mMinDate;
@@ -94,59 +105,73 @@ BOOL LLInventoryFilter::check(LLFolderViewItem* item)
 	{
 		earliest = 0;
 	}
-	LLFolderViewEventListener* listener = item->getListener();
+
+	const LLFolderViewEventListener* listener = item->getListener();
 	mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
 
-	bool passed_type = false;
-	if (mFilterOps.mFilterForCategories)
+	const BOOL passed_filtertype = checkAgainstFilterType(item);
+	const BOOL passed = passed_filtertype &&
+		(mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos) &&
+		((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions) &&
+		(listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate);
+	
+	return passed;
+}
+
+BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item)
+{
+	const LLFolderViewEventListener* listener = item->getListener();
+	if (!listener) return FALSE;
+
+	const LLInventoryType::EType object_type = listener->getInventoryType();
+	const LLUUID object_id = listener->getUUID();
+	const LLInventoryObject *object = gInventory.getObject(object_id);
+
+	if (!object) return FALSE;
+
+	const U32 filterTypes = mFilterOps.mFilterTypes;
+
+	// Pass if this item's type is of the correct filter type
+	if (filterTypes & FILTERTYPE_OBJECT)
 	{
-		// Pass if this item is a category of the filter type, or
-		// if its parent is a category of the filter type.
-		LLUUID uuid = listener->getUUID();
-		if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
+		// If it has no type, pass it, unless it's a link.
+		if (object_type == LLInventoryType::IT_NONE)
 		{
-			const LLInventoryObject *obj = gInventory.getObject(uuid);
-			uuid = obj->getParentUUID();
-		}
-		LLViewerInventoryCategory *cat = gInventory.getCategory(uuid);
-		if (cat)
-		{
-			passed_type |= ((1LL << cat->getPreferredType() & mFilterOps.mFilterTypes) != U64(0));
+			if (object->getIsLinkType())
+				return FALSE;
 		}
+		if ((1LL << object_type & mFilterOps.mFilterObjectTypes) == U64(0))
+			return FALSE;
 	}
-	else
+	
+	// Pass if this item is a category of the filter type, or
+	// if its parent is a category of the filter type.
+	if (filterTypes & FILTERTYPE_CATEGORY)
 	{
-		LLInventoryType::EType type = listener->getInventoryType();
-		passed_type |= ((1LL << type & mFilterOps.mFilterTypes) != U64(0));
-		if (type == LLInventoryType::IT_NONE)
+		LLUUID cat_id = object_id;
+		if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
 		{
-			const LLInventoryObject *obj = gInventory.getObject(listener->getUUID());
-			if (obj && obj->getIsLinkType())
-			{
-				passed_type = FALSE;
-			}
-			else
-			{
-				passed_type = TRUE;
-			}
+			cat_id = object->getParentUUID();
 		}
+		const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
+		if (!cat) 
+			return FALSE;
+		if ((1LL << cat->getPreferredType() & mFilterOps.mFilterCategoryTypes) == U64(0))
+			return FALSE;
 	}
 
-	BOOL passed = passed_type
-		&& (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos)
-		&& ((listener->getPermissionMask() & mFilterOps.mPermissions) == mFilterOps.mPermissions)
-		&& (listener->getCreationDate() >= earliest && listener->getCreationDate() <= mFilterOps.mMaxDate);
-
-	BOOL is_folder = (dynamic_cast<LLFolderViewFolder*>(item) != NULL);
-	if (is_folder && mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
+	// Pass if this item is the target UUID or if it links to the target UUID
+	if (filterTypes & FILTERTYPE_UUID)
 	{
-		passed = TRUE;
+		if (object->getLinkedUUID() != mFilterOps.mFilterUUID)
+			return FALSE;
 	}
 
-	return passed;
+	return TRUE;
 }
 
-const std::string LLInventoryFilter::getFilterSubString(BOOL trim)
+
+const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
 {
 	return mFilterSubString;
 }
@@ -157,9 +182,9 @@ std::string::size_type LLInventoryFilter::getStringMatchOffset() const
 }
 
 // has user modified default filter params?
-BOOL LLInventoryFilter::isNotDefault()
+BOOL LLInventoryFilter::isNotDefault() const
 {
-	return mFilterOps.mFilterTypes != mDefaultFilterOps.mFilterTypes 
+	return mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes 
 		|| mFilterSubString.size() 
 		|| mFilterOps.mPermissions != mDefaultFilterOps.mPermissions
 		|| mFilterOps.mMinDate != mDefaultFilterOps.mMinDate 
@@ -167,9 +192,9 @@ BOOL LLInventoryFilter::isNotDefault()
 		|| mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo;
 }
 
-BOOL LLInventoryFilter::isActive()
+BOOL LLInventoryFilter::isActive() const
 {
-	return mFilterOps.mFilterTypes != 0xffffffffffffffffULL 
+	return mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL 
 		|| mFilterSubString.size() 
 		|| mFilterOps.mPermissions != PERM_NONE 
 		|| mFilterOps.mMinDate != time_min()
@@ -177,7 +202,7 @@ BOOL LLInventoryFilter::isActive()
 		|| mFilterOps.mHoursAgo != 0;
 }
 
-BOOL LLInventoryFilter::isModified()
+BOOL LLInventoryFilter::isModified() const
 {
 	return mModified;
 }
@@ -189,15 +214,43 @@ BOOL LLInventoryFilter::isModifiedAndClear()
 	return ret;
 }
 
-void LLInventoryFilter::setFilterTypes(U64 types, BOOL filter_for_categories)
+void LLInventoryFilter::setFilterObjectTypes(U64 types)
+{
+	if (mFilterOps.mFilterObjectTypes != types)
+	{
+		// keep current items only if no type bits getting turned off
+		BOOL fewer_bits_set = (mFilterOps.mFilterObjectTypes & ~types);
+		BOOL more_bits_set = (~mFilterOps.mFilterObjectTypes & types);
+
+		mFilterOps.mFilterObjectTypes = types;
+		if (more_bits_set && fewer_bits_set)
+		{
+			// neither less or more restrive, both simultaneously
+			// so we need to filter from scratch
+			setModified(FILTER_RESTART);
+		}
+		else if (more_bits_set)
+		{
+			// target is only one of all requested types so more type bits == less restrictive
+			setModified(FILTER_LESS_RESTRICTIVE);
+		}
+		else if (fewer_bits_set)
+		{
+			setModified(FILTER_MORE_RESTRICTIVE);
+		}
+	}
+	mFilterOps.mFilterTypes |= FILTERTYPE_OBJECT;
+}
+
+void LLInventoryFilter::setFilterCategoryTypes(U64 types)
 {
-	if (mFilterOps.mFilterTypes != types)
+	if (mFilterOps.mFilterCategoryTypes != types)
 	{
 		// keep current items only if no type bits getting turned off
-		BOOL fewer_bits_set = (mFilterOps.mFilterTypes & ~types);
-		BOOL more_bits_set = (~mFilterOps.mFilterTypes & types);
+		BOOL fewer_bits_set = (mFilterOps.mFilterCategoryTypes & ~types);
+		BOOL more_bits_set = (~mFilterOps.mFilterCategoryTypes & types);
 
-		mFilterOps.mFilterTypes = types;
+		mFilterOps.mFilterCategoryTypes = types;
 		if (more_bits_set && fewer_bits_set)
 		{
 			// neither less or more restrive, both simultaneously
@@ -214,7 +267,21 @@ void LLInventoryFilter::setFilterTypes(U64 types, BOOL filter_for_categories)
 			setModified(FILTER_MORE_RESTRICTIVE);
 		}
 	}
-	mFilterOps.mFilterForCategories = filter_for_categories;
+	mFilterOps.mFilterTypes |= FILTERTYPE_CATEGORY;
+}
+
+void LLInventoryFilter::setFilterUUID(const LLUUID& object_id)
+{
+	if (mFilterOps.mFilterUUID == LLUUID::null)
+	{
+		setModified(FILTER_MORE_RESTRICTIVE);
+	}
+	else
+	{
+		setModified(FILTER_RESTART);
+	}
+	mFilterOps.mFilterUUID = object_id;
+	mFilterOps.mFilterTypes = FILTERTYPE_UUID;
 }
 
 void LLInventoryFilter::setFilterSubString(const std::string& string)
@@ -222,9 +289,11 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
 	if (mFilterSubString != string)
 	{
 		// hitting BACKSPACE, for example
-		BOOL less_restrictive = mFilterSubString.size() >= string.size() && !mFilterSubString.substr(0, string.size()).compare(string);
+		const BOOL less_restrictive = mFilterSubString.size() >= string.size() && !mFilterSubString.substr(0, string.size()).compare(string);
+
 		// appending new characters
-		BOOL more_restrictive = mFilterSubString.size() < string.size() && !string.substr(0, mFilterSubString.size()).compare(mFilterSubString);
+		const BOOL more_restrictive = mFilterSubString.size() < string.size() && !string.substr(0, mFilterSubString.size()).compare(mFilterSubString);
+
 		mFilterSubString = string;
 		LLStringUtil::toUpper(mFilterSubString);
 		LLStringUtil::trimHead(mFilterSubString);
@@ -241,6 +310,14 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
 		{
 			setModified(FILTER_RESTART);
 		}
+
+		// Cancel out UUID once the search string is modified
+		if (mFilterOps.mFilterTypes == FILTERTYPE_UUID)
+		{
+			mFilterOps.mFilterTypes &= ~FILTERTYPE_UUID;
+			mFilterOps.mFilterUUID == LLUUID::null;
+			setModified(FILTER_RESTART);
+		}
 	}
 }
 
@@ -298,12 +375,18 @@ void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
 	}
 }
 
-BOOL LLInventoryFilter::isSinceLogoff()
+BOOL LLInventoryFilter::isSinceLogoff() const
 {
 	return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
 		(mFilterOps.mMaxDate == time_max());
 }
 
+void LLInventoryFilter::clearModified()
+{
+	mModified = FALSE; 
+	mFilterBehavior = FILTER_NONE;
+}
+
 void LLInventoryFilter::setHoursAgo(U32 hours)
 {
 	if (mFilterOps.mHoursAgo != hours)
@@ -417,12 +500,12 @@ void LLInventoryFilter::setModified(EFilterBehavior behavior)
 	}
 }
 
-BOOL LLInventoryFilter::isFilterWith(LLInventoryType::EType t)
+BOOL LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
 {
-	return mFilterOps.mFilterTypes & (1LL << t);
+	return mFilterOps.mFilterObjectTypes & (1LL << t);
 }
 
-std::string LLInventoryFilter::getFilterText()
+const std::string& LLInventoryFilter::getFilterText()
 {
 	if (!mNeedTextRebuild)
 	{
@@ -437,7 +520,7 @@ std::string LLInventoryFilter::getFilterText()
 	S32 num_filter_types = 0;
 	mFilterText.clear();
 
-	if (isFilterWith(LLInventoryType::IT_ANIMATION))
+	if (isFilterObjectTypesWith(LLInventoryType::IT_ANIMATION))
 	{
 		//filtered_types += " Animations,";
 		filtered_types += LLTrans::getString("Animations");
@@ -452,7 +535,7 @@ std::string LLInventoryFilter::getFilterText()
 		filtered_by_all_types = FALSE;
 	}
 
-	if (isFilterWith(LLInventoryType::IT_CALLINGCARD))
+	if (isFilterObjectTypesWith(LLInventoryType::IT_CALLINGCARD))
 	{
 		//filtered_types += " Calling Cards,";
 		filtered_types += LLTrans::getString("Calling Cards");
@@ -466,7 +549,7 @@ std::string LLInventoryFilter::getFilterText()
 		filtered_by_all_types = FALSE;
 	}
 
-	if (isFilterWith(LLInventoryType::IT_WEARABLE))
+	if (isFilterObjectTypesWith(LLInventoryType::IT_WEARABLE))
 	{
 		//filtered_types += " Clothing,";
 		filtered_types +=  LLTrans::getString("Clothing");
@@ -480,7 +563,7 @@ std::string LLInventoryFilter::getFilterText()
 		filtered_by_all_types = FALSE;
 	}
 
-	if (isFilterWith(LLInventoryType::IT_GESTURE))
+	if (isFilterObjectTypesWith(LLInventoryType::IT_GESTURE))
 	{
 		//filtered_types += " Gestures,";
 		filtered_types +=  LLTrans::getString("Gestures");
@@ -494,7 +577,7 @@ std::string LLInventoryFilter::getFilterText()
 		filtered_by_all_types = FALSE;
 	}
 
-	if (isFilterWith(LLInventoryType::IT_LANDMARK))
+	if (isFilterObjectTypesWith(LLInventoryType::IT_LANDMARK))
 	{
 		//filtered_types += " Landmarks,";
 		filtered_types +=  LLTrans::getString("Landmarks");
@@ -508,7 +591,7 @@ std::string LLInventoryFilter::getFilterText()
 		filtered_by_all_types = FALSE;
 	}
 
-	if (isFilterWith(LLInventoryType::IT_NOTECARD))
+	if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
 	{
 		//filtered_types += " Notecards,";
 		filtered_types +=  LLTrans::getString("Notecards");
@@ -522,7 +605,7 @@ std::string LLInventoryFilter::getFilterText()
 		filtered_by_all_types = FALSE;
 	}
 
-	if (isFilterWith(LLInventoryType::IT_OBJECT) && isFilterWith(LLInventoryType::IT_ATTACHMENT))
+	if (isFilterObjectTypesWith(LLInventoryType::IT_OBJECT) && isFilterObjectTypesWith(LLInventoryType::IT_ATTACHMENT))
 	{
 		//filtered_types += " Objects,";
 		filtered_types +=  LLTrans::getString("Objects");
@@ -536,7 +619,7 @@ std::string LLInventoryFilter::getFilterText()
 		filtered_by_all_types = FALSE;
 	}
 
-	if (isFilterWith(LLInventoryType::IT_LSL))
+	if (isFilterObjectTypesWith(LLInventoryType::IT_LSL))
 	{
 		//filtered_types += " Scripts,";
 		filtered_types +=  LLTrans::getString("Scripts");
@@ -550,7 +633,7 @@ std::string LLInventoryFilter::getFilterText()
 		filtered_by_all_types = FALSE;
 	}
 
-	if (isFilterWith(LLInventoryType::IT_SOUND))
+	if (isFilterObjectTypesWith(LLInventoryType::IT_SOUND))
 	{
 		//filtered_types += " Sounds,";
 		filtered_types +=  LLTrans::getString("Sounds");
@@ -564,7 +647,7 @@ std::string LLInventoryFilter::getFilterText()
 		filtered_by_all_types = FALSE;
 	}
 
-	if (isFilterWith(LLInventoryType::IT_TEXTURE))
+	if (isFilterObjectTypesWith(LLInventoryType::IT_TEXTURE))
 	{
 		//filtered_types += " Textures,";
 		filtered_types +=  LLTrans::getString("Textures");
@@ -578,7 +661,7 @@ std::string LLInventoryFilter::getFilterText()
 		filtered_by_all_types = FALSE;
 	}
 
-	if (isFilterWith(LLInventoryType::IT_SNAPSHOT))
+	if (isFilterObjectTypesWith(LLInventoryType::IT_SNAPSHOT))
 	{
 		//filtered_types += " Snapshots,";
 		filtered_types +=  LLTrans::getString("Snapshots");
@@ -619,9 +702,9 @@ std::string LLInventoryFilter::getFilterText()
 	return mFilterText;
 }
 
-void LLInventoryFilter::toLLSD(LLSD& data)
+void LLInventoryFilter::toLLSD(LLSD& data) const
 {
-	data["filter_types"] = (LLSD::Integer)getFilterTypes();
+	data["filter_types"] = (LLSD::Integer)getFilterObjectTypes();
 	data["min_date"] = (LLSD::Integer)getMinDate();
 	data["max_date"] = (LLSD::Integer)getMaxDate();
 	data["hours_ago"] = (LLSD::Integer)getHoursAgo();
@@ -636,7 +719,7 @@ void LLInventoryFilter::fromLLSD(LLSD& data)
 {
 	if(data.has("filter_types"))
 	{
-		setFilterTypes((U32)data["filter_types"].asInteger());
+		setFilterObjectTypes((U32)data["filter_types"].asInteger());
 	}
 
 	if(data.has("min_date") && data.has("max_date"))
@@ -674,3 +757,71 @@ void LLInventoryFilter::fromLLSD(LLSD& data)
 		setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean());
 	}
 }
+
+U32 LLInventoryFilter::getFilterObjectTypes() const
+{
+	return mFilterOps.mFilterObjectTypes;
+}
+
+BOOL LLInventoryFilter::hasFilterString() const
+{
+	return mFilterSubString.size() > 0;
+}
+
+PermissionMask LLInventoryFilter::getFilterPermissions() const
+{
+	return mFilterOps.mPermissions;
+}
+
+time_t LLInventoryFilter::getMinDate() const
+{
+	return mFilterOps.mMinDate;
+}
+
+time_t LLInventoryFilter::getMaxDate() const 
+{ 
+	return mFilterOps.mMaxDate; 
+}
+U32 LLInventoryFilter::getHoursAgo() const 
+{ 
+	return mFilterOps.mHoursAgo; 
+}
+LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const
+{ 
+	return mFilterOps.mShowFolderState; 
+}
+U32 LLInventoryFilter::getSortOrder() const 
+{ 
+	return mOrder; 
+}
+const std::string& LLInventoryFilter::getName() const 
+{ 
+	return mName; 
+}
+
+void LLInventoryFilter::setFilterCount(S32 count) 
+{ 
+	mFilterCount = count; 
+}
+S32 LLInventoryFilter::getFilterCount() const
+{
+	return mFilterCount;
+}
+
+void LLInventoryFilter::decrementFilterCount() 
+{ 
+	mFilterCount--; 
+}
+
+S32 LLInventoryFilter::getCurrentGeneration() const 
+{ 
+	return mFilterGeneration; 
+}
+S32 LLInventoryFilter::getMinRequiredGeneration() const 
+{ 
+	return mMinRequiredGeneration; 
+}
+S32 LLInventoryFilter::getMustPassGeneration() const 
+{ 
+	return mMustPassGeneration; 
+}
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index b803df110b4b6a4064e79f71a57006c9226f56d9..d65fb8f27c24258327d487bfcf4bb61da5987cf5 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -33,30 +33,38 @@
 #ifndef LLINVENTORYFILTER_H
 #define LLINVENTORYFILTER_H
 
-// lots of includes here
 #include "llinventorytype.h"
-#include "llpermissionsflags.h"		// PermissionsMask
+#include "llpermissionsflags.h"
 
 class LLFolderViewItem;
 
 class LLInventoryFilter
 {
 public:
-	typedef enum e_folder_show
+	enum EFolderShow
 	{
 		SHOW_ALL_FOLDERS,
 		SHOW_NON_EMPTY_FOLDERS,
 		SHOW_NO_FOLDERS
-	} EFolderShow;
+	};
 
-	typedef enum e_filter_behavior
+	enum EFilterBehavior
 	{
 		FILTER_NONE,				// nothing to do, already filtered
 		FILTER_RESTART,				// restart filtering from scratch
 		FILTER_LESS_RESTRICTIVE,	// existing filtered items will certainly pass this filter
 		FILTER_MORE_RESTRICTIVE		// if you didn't pass the previous filter, you definitely won't pass this one
-	} EFilterBehavior;
+	};
+
+	enum EFilterType
+	{
+		FILTERTYPE_NONE = 0,
+		FILTERTYPE_OBJECT = 1,		// normal default search-by-object-type
+		FILTERTYPE_CATEGORY = 2,	// search by folder type
+		FILTERTYPE_UUID	= 4			// find the object with UUID and any links to it
+	};
 
+	// REFACTOR: Change this to an enum.
 	static const U32 SO_DATE = 1;
 	static const U32 SO_FOLDERS_BY_NAME = 2;
 	static const U32 SO_SYSTEM_FOLDERS_TO_TOP = 4;
@@ -64,89 +72,121 @@ class LLInventoryFilter
 	LLInventoryFilter(const std::string& name);
 	virtual ~LLInventoryFilter();
 
-	void setFilterTypes(U64 types, BOOL filter_for_categories = FALSE); // if filter_for_categories is true, operate on folder preferred asset type
-	U32 getFilterTypes() const { return mFilterOps.mFilterTypes; }
-
-	void setFilterSubString(const std::string& string);
-	const std::string getFilterSubString(BOOL trim = FALSE);
-
-	void setFilterPermissions(PermissionMask perms);
-	PermissionMask getFilterPermissions() const { return mFilterOps.mPermissions; }
-
-	void setDateRange(time_t min_date, time_t max_date);
-	void setDateRangeLastLogoff(BOOL sl);
-	time_t getMinDate() const { return mFilterOps.mMinDate; }
-	time_t getMaxDate() const { return mFilterOps.mMaxDate; }
-
-	void setHoursAgo(U32 hours);
-	U32 getHoursAgo() const { return mFilterOps.mHoursAgo; }
-
-	void setShowFolderState( EFolderShow state);
-	EFolderShow getShowFolderState() { return mFilterOps.mShowFolderState; }
-
-	void setSortOrder(U32 order);
-	U32 getSortOrder() { return mOrder; }
-
-	BOOL check(LLFolderViewItem* item);
+	// +-------------------------------------------------------------------+
+	// + Execution And Results
+	// +-------------------------------------------------------------------+
+	BOOL 				check(const LLFolderViewItem* item);
+	BOOL 				checkAgainstFilterType(const LLFolderViewItem* item);
 	std::string::size_type getStringMatchOffset() const;
-	BOOL isActive();
-	BOOL isNotDefault();
-	BOOL isModified();
-	BOOL isModifiedAndClear();
-	BOOL isSinceLogoff();
-	bool hasFilterString() { return mFilterSubString.size() > 0; }
-	void clearModified() { mModified = FALSE; mFilterBehavior = FILTER_NONE; }
-	const std::string getName() const { return mName; }
-	std::string getFilterText();
 
-	void setFilterCount(S32 count) { mFilterCount = count; }
-	S32 getFilterCount() { return mFilterCount; }
-	void decrementFilterCount() { mFilterCount--; }
+	// +-------------------------------------------------------------------+
+	// + Parameters
+	// +-------------------------------------------------------------------+
+	void 				setFilterObjectTypes(U64 types);
+	U32 				getFilterObjectTypes() const;
+	BOOL 				isFilterObjectTypesWith(LLInventoryType::EType t) const;
+	void 				setFilterCategoryTypes(U64 types);
+	void 				setFilterUUID(const LLUUID &object_id);
+
+	void 				setFilterSubString(const std::string& string);
+	const std::string& 	getFilterSubString(BOOL trim = FALSE) const;
+	BOOL 				hasFilterString() const;
+
+	void 				setFilterPermissions(PermissionMask perms);
+	PermissionMask 		getFilterPermissions() const;
+
+	void 				setDateRange(time_t min_date, time_t max_date);
+	void 				setDateRangeLastLogoff(BOOL sl);
+	time_t 				getMinDate() const;
+	time_t 				getMaxDate() const;
+
+	void 				setHoursAgo(U32 hours);
+	U32 				getHoursAgo() const;
+
+	void 				setShowFolderState( EFolderShow state);
+	EFolderShow 		getShowFolderState() const;
+
+	void 				setSortOrder(U32 order);
+	U32 				getSortOrder() const;
+
+	// +-------------------------------------------------------------------+
+	// + Status
+	// +-------------------------------------------------------------------+
+	BOOL 				isActive() const;
+	BOOL 				isModified() const;
+	BOOL 				isModifiedAndClear();
+	BOOL 				isSinceLogoff() const;
+	void 				clearModified();
+	const std::string& 	getName() const;
+	const std::string& 	getFilterText();
+	//RN: this is public to allow system to externally force a global refilter
+	void 				setModified(EFilterBehavior behavior = FILTER_RESTART);
+
+	// +-------------------------------------------------------------------+
+	// + Count
+	// +-------------------------------------------------------------------+
+	void 				setFilterCount(S32 count);
+	S32 				getFilterCount() const;
+	void 				decrementFilterCount();
+
+	// +-------------------------------------------------------------------+
+	// + Default
+	// +-------------------------------------------------------------------+
+	BOOL 				isNotDefault() const;
+	void 				markDefault();
+	void 				resetDefault();
+
+	// +-------------------------------------------------------------------+
+	// + Generation
+	// +-------------------------------------------------------------------+
+	S32 				getCurrentGeneration() const;
+	S32 				getMinRequiredGeneration() const;
+	S32 				getMustPassGeneration() const;
+
+	// +-------------------------------------------------------------------+
+	// + Conversion
+	// +-------------------------------------------------------------------+
+	void 				toLLSD(LLSD& data) const;
+	void 				fromLLSD(LLSD& data);
 
-	void markDefault();
-	void resetDefault();
+private:
+	struct FilterOps
+	{
+		FilterOps();
+		U32 			mFilterTypes;
 
-	BOOL isFilterWith(LLInventoryType::EType t);
+		U64				mFilterObjectTypes; // For _ITEM
+		U64				mFilterCategoryTypes; // For _ITEM
+		LLUUID      	mFilterUUID; // for UUID
 
-	S32 getCurrentGeneration() const { return mFilterGeneration; }
-	S32 getMinRequiredGeneration() const { return mMinRequiredGeneration; }
-	S32 getMustPassGeneration() const { return mMustPassGeneration; }
+		time_t			mMinDate;
+		time_t			mMaxDate;
+		U32				mHoursAgo;
+		EFolderShow		mShowFolderState;
+		PermissionMask	mPermissions;
+	};
 
-	//RN: this is public to allow system to externally force a global refilter
-	void setModified(EFilterBehavior behavior = FILTER_RESTART);
+	U32						mOrder;
+	U32 					mLastLogoff;
 
-	void toLLSD(LLSD& data);
-	void fromLLSD(LLSD& data);
+	FilterOps				mFilterOps;
+	FilterOps				mDefaultFilterOps;
 
-protected:
-	struct filter_ops
-	{
-		U64			mFilterTypes;
-		BOOL        mFilterForCategories;
-		time_t		mMinDate;
-		time_t		mMaxDate;
-		U32			mHoursAgo;
-		EFolderShow	mShowFolderState;
-		PermissionMask	mPermissions;
-	};
-	filter_ops		mFilterOps;
-	filter_ops		mDefaultFilterOps;
 	std::string::size_type	mSubStringMatchOffset;
-	std::string		mFilterSubString;
-	U32				mOrder;
-	const std::string	mName;
-	S32				mFilterGeneration;
-	S32				mMustPassGeneration;
-	S32				mMinRequiredGeneration;
-	S32				mFilterCount;
-	S32				mNextFilterGeneration;
-	EFilterBehavior mFilterBehavior;
+	std::string				mFilterSubString;
+	const std::string		mName;
 
-private:
-	U32 mLastLogoff;
-	BOOL mModified;
-	BOOL mNeedTextRebuild;
-	std::string mFilterText;
+	S32						mFilterGeneration;
+	S32						mMustPassGeneration;
+	S32						mMinRequiredGeneration;
+	S32						mNextFilterGeneration;
+
+	S32						mFilterCount;
+	EFilterBehavior 		mFilterBehavior;
+
+	BOOL 					mModified;
+	BOOL 					mNeedTextRebuild;
+	std::string 			mFilterText;
 };
 
 #endif
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 95cc68ddbe1712a1220459391ba3a61adb9d4972..9916a2351cfdebe6f63d501cea4ec2250de9b7bc 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -34,32 +34,9 @@
 #ifndef LL_LLINVENTORYFUNCTIONS_H
 #define LL_LLINVENTORYFUNCTIONS_H
 
-#include "llassetstorage.h"
-#include "lldarray.h"
-#include "llfloater.h"
-#include "llinventory.h"
-#include "llinventoryfilter.h"
+#include "llinventorytype.h"
 #include "llfolderview.h"
-#include "llinventorymodel.h"
-#include "lluictrlfactory.h"
-#include <set>
-
-
-class LLFolderViewItem;
-class LLInventoryFilter;
-class LLInventoryModel;
-class LLInventoryPanel;
-class LLInvFVBridge;
-class LLInventoryFVBridgeBuilder;
-class LLMenuBarGL;
-class LLCheckBoxCtrl;
-class LLSpinCtrl;
-class LLScrollContainer;
-class LLTextBox;
-class LLIconCtrl;
-class LLSaveFolderState;
-class LLFilterEditor;
-class LLTabContainer;
+#include "llfolderviewitem.h"
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 //
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 29096ff7188028db708eb9e56bde4a320d93f73f..fb9be1e04f470d035df64860f55ad1fee749d99e 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -211,6 +211,25 @@ BOOL LLInventoryModel::isObjectDescendentOf(const LLUUID& obj_id,
 	return FALSE;
 }
 
+const LLViewerInventoryCategory *LLInventoryModel::getFirstNondefaultParent(const LLUUID& obj_id) const
+{
+	const LLInventoryObject* obj = getObject(obj_id);
+	const LLUUID& parent_id = obj->getParentUUID();
+	while (!parent_id.isNull())
+	{
+		const LLViewerInventoryCategory *cat = getCategory(parent_id);
+		if (!cat) break;
+		const LLFolderType::EType folder_type = cat->getPreferredType();
+		if (folder_type != LLFolderType::FT_NONE &&
+			folder_type != LLFolderType::FT_ROOT_INVENTORY &&
+			!LLFolderType::lookupIsEnsembleType(folder_type))
+		{
+			return cat;
+		}
+	}
+	return NULL;
+}
+
 // Get the object by id. Returns NULL if not found.
 LLInventoryObject* LLInventoryModel::getObject(const LLUUID& id) const
 {
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index c3e04ab93ccf2a261ad418fa7a0a969c9c70f9de..b744d821c75cf068b4babe5b1719eb8b495b7233 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -108,10 +108,12 @@ class LLInventoryModel
 	// Accessors
 	//
 
-	// This is a convenience function to check if one object has a
-	// parent chain up to the category specified by UUID.
+	// Check if one object has a parent chain up to the category specified by UUID.
 	BOOL isObjectDescendentOf(const LLUUID& obj_id, const LLUUID& cat_id) const;
 
+	// Get whatever special folder this object is a child of, if any.
+	const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const;
+
 	// Get the object by id. Returns NULL if not found.
 	// * WARNING: use the pointer returned for read operations - do
 	// not modify the object values in place or you will break stuff.
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index baa659df7c265bb25a8159fbe99e89b7fd996f22..54f528de8dc6bb62f4041ec035d3f355dee5ee93 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -169,7 +169,7 @@ BOOL LLInventoryPanel::postBuild()
 	{
 		setSortOrder(gSavedSettings.getU32(DEFAULT_SORT_ORDER));
 	}
-	mFolders->setSortOrder(mFolders->getFilter()->getSortOrder());
+	mFolders->setSortOrder(getFilter()->getSortOrder());
 
 	return TRUE;
 }
@@ -207,25 +207,28 @@ LLInventoryFilter* LLInventoryPanel::getFilter()
 	return NULL;
 }
 
-void LLInventoryPanel::setFilterTypes(U64 filter_types, BOOL filter_for_categories)
+void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
 {
-	mFolders->getFilter()->setFilterTypes(filter_types, filter_for_categories);
-}	
+	if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT)
+		getFilter()->setFilterObjectTypes(types);
+	if (filter_type == LLInventoryFilter::FILTERTYPE_CATEGORY)
+		getFilter()->setFilterCategoryTypes(types);
+}
 
 void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)
 {
-	mFolders->getFilter()->setFilterPermissions(filter_perm_mask);
+	getFilter()->setFilterPermissions(filter_perm_mask);
 }
 
 void LLInventoryPanel::setFilterSubString(const std::string& string)
 {
-	mFolders->getFilter()->setFilterSubString(string);
+	getFilter()->setFilterSubString(string);
 }
 
 void LLInventoryPanel::setSortOrder(U32 order)
 {
-	mFolders->getFilter()->setSortOrder(order);
-	if (mFolders->getFilter()->isModified())
+	getFilter()->setSortOrder(order);
+	if (getFilter()->isModified())
 	{
 		mFolders->setSortOrder(order);
 		// try to keep selection onscreen, even if it wasn't to start with
@@ -235,22 +238,22 @@ void LLInventoryPanel::setSortOrder(U32 order)
 
 void LLInventoryPanel::setSinceLogoff(BOOL sl)
 {
-	mFolders->getFilter()->setDateRangeLastLogoff(sl);
+	getFilter()->setDateRangeLastLogoff(sl);
 }
 
 void LLInventoryPanel::setHoursAgo(U32 hours)
 {
-	mFolders->getFilter()->setHoursAgo(hours);
+	getFilter()->setHoursAgo(hours);
 }
 
 void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show)
 {
-	mFolders->getFilter()->setShowFolderState(show);
+	getFilter()->setShowFolderState(show);
 }
 
 LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState()
 {
-	return mFolders->getFilter()->getShowFolderState();
+	return getFilter()->getShowFolderState();
 }
 
 void LLInventoryPanel::modelChanged(U32 mask)
@@ -845,7 +848,7 @@ bool LLInventoryPanel::attachObject(const LLSD& userdata)
 
 BOOL LLInventoryPanel::getSinceLogoff()
 {
-	return mFolders->getFilter()->isSinceLogoff();
+	return getFilter()->isSinceLogoff();
 }
 
 // DEBUG ONLY
@@ -856,14 +859,31 @@ void LLInventoryPanel::dumpSelectionInformation(void* user_data)
 	iv->mFolders->dumpSelectionInformation();
 }
 
-// static
-LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel()
+BOOL is_inventorysp_active()
 {
-	LLInventoryPanel* res = NULL;
+	if (!LLSideTray::getInstance()->isPanelActive("sidepanel_inventory")) return FALSE;
+	LLSidepanelInventory *inventorySP = dynamic_cast<LLSidepanelInventory *>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
+	if (!inventorySP) return FALSE; 
+	return inventorySP->isMainInventoryPanelActive();
+}
 
-	// Iterate through the inventory floaters and return whichever is on top.
+// static
+LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel(BOOL auto_open)
+{
+	// A. If the inventory side panel is open, use that preferably.
+	if (is_inventorysp_active())
+	{
+		LLSidepanelInventory *inventorySP = dynamic_cast<LLSidepanelInventory *>(LLSideTray::getInstance()->getPanel("sidepanel_inventory"));
+		if (inventorySP)
+		{
+			return inventorySP->getActivePanel();
+		}
+	}
+	
+	// B. Iterate through the inventory floaters and return whichever is on top.
 	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("inventory");
 	S32 z_min = S32_MAX;
+	LLInventoryPanel* res = NULL;
 	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
 	{
 		LLFloaterInventory* iv = dynamic_cast<LLFloaterInventory*>(*iter);
@@ -877,22 +897,19 @@ LLInventoryPanel* LLInventoryPanel::getActiveInventoryPanel()
 			}
 		}
 	}
-
-	// Otherwise, open the inventorySP and use that.
-	if (!res)
+	if (res) return res;
+		
+	// C. If no panels are open and we don't want to force open a panel, then just abort out.
+	if (!auto_open) return NULL;
+	
+	// D. Open the inventory side panel and use that.
+	LLSD key;
+	LLSidepanelInventory *sidepanel_inventory =
+		dynamic_cast<LLSidepanelInventory *>(LLSideTray::getInstance()->showPanel("sidepanel_inventory", key));
+	if (sidepanel_inventory)
 	{
-		LLSD key;
-		LLSidepanelInventory *sidepanel_inventory =
-			dynamic_cast<LLSidepanelInventory *>(LLSideTray::getInstance()->showPanel("sidepanel_inventory", key));
-		if (sidepanel_inventory)
-		{
-			res = sidepanel_inventory->getActivePanel();
-			if (res)
-			{
-				return res;
-			}
-		}
+		return sidepanel_inventory->getActivePanel();
 	}
 
-	return res;
+	return NULL;
 }
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index d65fe53812635a271f9746eca9134fe6145278cd..cbbd433c1dbf4cc4623f9a112bb49182bf0eb865 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -126,8 +126,8 @@ class LLInventoryPanel : public LLPanel
 	void setSelectCallback(const LLFolderView::signal_t::slot_type& cb) { if (mFolders) mFolders->setSelectCallback(cb); }
 	void clearSelection();
 	LLInventoryFilter* getFilter();
-	void setFilterTypes(U64 filter, BOOL filter_for_categories = FALSE); // if filter_for_categories is true, operate on folder preferred asset type
-	U32 getFilterTypes() const { return mFolders->getFilterTypes(); }
+	void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
+	U32 getFilterObjectTypes() const { return mFolders->getFilterObjectTypes(); }
 	void setFilterPermMask(PermissionMask filter_perm_mask);
 	U32 getFilterPermMask() const { return mFolders->getFilterPermissions(); }
 	void setFilterSubString(const std::string& string);
@@ -163,7 +163,8 @@ class LLInventoryPanel : public LLPanel
 	static void onIdle(void* user_data);
 
 	// Find whichever inventory panel is active / on top.
-	static LLInventoryPanel *getActiveInventoryPanel();
+	// "Auto_open" determines if we open an inventory panel if none are open.
+	static LLInventoryPanel *getActiveInventoryPanel(BOOL auto_open = TRUE);
 
 protected:
 	void defaultOpenInventory(); // open the first level of inventory
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 74c1420cf37323dfca11d5659d2c6a1eecc3a92a..9fd92725dc2539779d259284b8dda4c070471f33 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -653,7 +653,7 @@ void LLFloaterInventoryFinder::updateElementsFromFilter()
 		return;
 
 	// Get data needed for filter display
-	U32 filter_types = mFilter->getFilterTypes();
+	U32 filter_types = mFilter->getFilterObjectTypes();
 	std::string filter_string = mFilter->getFilterSubString();
 	LLInventoryFilter::EFolderShow show_folders = mFilter->getShowFolderState();
 	U32 hours = mFilter->getHoursAgo();
@@ -966,6 +966,46 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 			preview_texture->openToSave();
 		}
 	}
+	// This doesn't currently work, since the viewer can't change an assetID an item.
+	if (command_name == "regenerate_link")
+	{
+		LLInventoryPanel *active_panel = getActivePanel();
+		LLFolderViewItem* current_item = active_panel->getRootFolder()->getCurSelectedItem();
+		if (!current_item)
+		{
+			return;
+		}
+		const LLUUID item_id = current_item->getListener()->getUUID();
+		LLViewerInventoryItem *item = gInventory.getItem(item_id);
+		item->regenerateLink();
+		active_panel->setSelection(item_id, TAKE_FOCUS_NO);
+	}
+	if (command_name == "find_original")
+	{
+		LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+		if (!current_item)
+		{
+			return;
+		}
+		current_item->getListener()->performAction(getActivePanel()->getRootFolder(), getActivePanel()->getModel(), "goto");
+	}
+
+	if (command_name == "find_links")
+	{
+		LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+		if (!current_item)
+		{
+			return;
+		}
+		const LLUUID& item_id = current_item->getListener()->getUUID();
+		const std::string &item_name = current_item->getListener()->getName();
+		LLInventoryFilter *filter = mActivePanel->getFilter();
+		filter->setFilterSubString(item_name);
+		mFilterEditor->setText(item_name);
+		mFilterEditor->setFocus(TRUE);
+		filter->setFilterUUID(item_id);
+		filter->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+	}
 }
 
 BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
@@ -1001,6 +1041,45 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 		}
 		return FALSE;
 	}
+	if (command_name == "find_original")
+	{
+		LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+		if (!current_item) return FALSE;
+		const LLUUID& item_id = current_item->getListener()->getUUID();
+		const LLViewerInventoryItem *item = gInventory.getItem(item_id);
+		if (item && item->getIsLinkType() && !item->getIsBrokenLink())
+		{
+			return TRUE;
+		}
+		return FALSE;
+	}
+
+	if (command_name == "find_links")
+	{
+		LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+		if (!current_item) return FALSE;
+		const LLUUID& item_id = current_item->getListener()->getUUID();
+		const LLInventoryObject *obj = gInventory.getObject(item_id);
+		if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType()))
+		{
+			return TRUE;
+		}
+		return FALSE;
+	}
+	// This doesn't currently work, since the viewer can't change an assetID an item.
+	if (command_name == "regenerate_link")
+	{
+		LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
+		if (!current_item) return FALSE;
+		const LLUUID& item_id = current_item->getListener()->getUUID();
+		const LLViewerInventoryItem *item = gInventory.getItem(item_id);
+		if (item && item->getIsBrokenLink())
+		{
+			return TRUE;
+		}
+		return FALSE;
+	}
+
 	return TRUE;
 }
 
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 0012f22cdd20873fca2b00c060ba98bf35dae0d6..4f8aff6f781d7baab9ad96b5d9d0aff5256f70f7 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -50,6 +50,7 @@
 #include "llfloaterbuycurrency.h"
 #include "llfloaterreg.h"
 #include "llinventorybridge.h"
+#include "llinventoryfilter.h"
 #include "llinventoryfunctions.h"
 #include "llpreviewanim.h"
 #include "llpreviewgesture.h"
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index 951e74abf9697b16c5f3bf4c49e737133ec37782..6aba8c0ebb66c6a5616acfdc7b262814a1564f70 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -353,7 +353,7 @@ void LLPanelOutfitsInventory::initAccordionPanels()
 	mAccordionPanels.resize(2);
 	
 	LLInventoryPanel *myoutfits_panel = getChild<LLInventoryPanel>("outfitslist_accordionpanel");
-	myoutfits_panel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, TRUE);
+	myoutfits_panel->setFilterTypes(1LL << LLFolderType::FT_OUTFIT, LLInventoryFilter::FILTERTYPE_CATEGORY);
 	myoutfits_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
 	mAccordionPanels[0] = myoutfits_panel;
 	mActivePanel = myoutfits_panel;
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 9ab459080eadc8268a6a3095391bba8b4ab96f95..ca7a3b663a7105b5fbe2e15b44c45d8638370b59 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -128,10 +128,6 @@ void LLSidepanelInventory::onOpen(const LLSD& key)
 			mTaskPanel->setObjectSelection(LLSelectMgr::getInstance()->getSelection());
 		showTaskInfoPanel();
 	}
-	if (key.has("select"))
-	{
-		mPanelMainInventory->getPanel()->setSelection(key["select"].asUUID(), TAKE_FOCUS_NO);
-	}
 }
 
 void LLSidepanelInventory::onInfoButtonClicked()
@@ -290,3 +286,8 @@ LLInventoryPanel *LLSidepanelInventory::getActivePanel()
 	}
 	return NULL;
 }
+
+BOOL LLSidepanelInventory::isMainInventoryPanelActive() const
+{
+	return mInventoryPanel->getVisible();
+}
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index c2ce3badb8cb99d837a7ac210e9f0f48febbf02b..231cdac9e1e923ad679b5980f8177f835d17aaa0 100644
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -51,6 +51,7 @@ class LLSidepanelInventory : public LLPanel
 	/*virtual*/ void onOpen(const LLSD& key);
 
 	LLInventoryPanel* getActivePanel(); // Returns an active inventory panel, if any.
+	BOOL isMainInventoryPanelActive() const;
 
 protected:
 	// Tracks highlighted (selected) item in inventory panel.
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 933346505252bd443520459b2422f02c7a439dad..a1af2e5411a2d807877d9ed230b6102175eada4b 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -128,6 +128,7 @@ class LLSideTrayTab: public LLPanel
 	
 	void			onOpen		(const LLSD& key);
 	
+	LLPanel *getPanel();
 private:
 	std::string mTabTitle;
 	std::string mImage;
@@ -199,11 +200,17 @@ void LLSideTrayTab::reshape		(S32 width, S32 height, BOOL called_from_parent )
 
 void	LLSideTrayTab::onOpen		(const LLSD& key)
 {
-	LLPanel* panel = dynamic_cast<LLPanel*>(mMainPanel);
+	LLPanel *panel = getPanel();
 	if(panel)
 		panel->onOpen(key);
 }
 
+LLPanel*	LLSideTrayTab::getPanel()
+{
+	LLPanel* panel = dynamic_cast<LLPanel*>(mMainPanel);
+	return panel;
+}
+
 LLSideTrayTab*  LLSideTrayTab::createInstance	()
 {
 	LLSideTrayTab::Params tab_params; 
@@ -653,6 +660,23 @@ LLPanel*	LLSideTray::getPanel		(const std::string& panel_name)
 	return NULL;
 }
 
+LLPanel*	LLSideTray::getActivePanel()
+{
+	if (mActiveTab && !mCollapsed)
+	{
+		return mActiveTab->getPanel();
+	}
+	return NULL;
+}
+
+bool		LLSideTray::isPanelActive(const std::string& panel_name)
+{
+	LLPanel *panel = getActivePanel();
+	if (!panel) return false;
+	return (panel->getName() == panel_name);
+}
+
+
 // *TODO: Eliminate magic constants.
 static const S32	fake_offset = 132;
 static const S32	fake_top_offset = 18;
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index 73215746819f36b4468ab451bc960fdc8d045b5d..cf2f6992d50d92869b5fe6d611d81d3de015b08f 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -100,7 +100,8 @@ class LLSideTray : public LLPanel, private LLDestroyClass<LLSideTray>
 	 * get the panel (don't show it or do anything else with it)
 	 */
     LLPanel*	getPanel		(const std::string& panel_name);
-
+    LLPanel*	getActivePanel	();
+    bool		isPanelActive	(const std::string& panel_name);
 	/*
      * collapse SideBar, hiding visible tab and moving tab buttons
      * to the right corner of the screen
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index 6aabcb11b82d0c7a6d03d3cf2a02001979661bb6..db54a79610eadac5a2fbc2b3121a1e48b5f157ce 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -43,12 +43,14 @@ struct ViewerFolderEntry : public LLDictionaryEntry
 {
 	// Constructor for non-ensembles
 	ViewerFolderEntry(const std::string &new_category_name, // default name when creating a new category of this type
-					  const std::string &icon_name 			// name of the folder icon
+					  const std::string &icon_name,			// name of the folder icon
+					  BOOL is_quiet							// folder doesn't need a UI update when changed
 		) 
 		:
 		LLDictionaryEntry(empty_string), // no reverse lookup needed on non-ensembles, so just leave this blank
 		mIconName(icon_name),
-		mNewCategoryName(new_category_name)
+		mNewCategoryName(new_category_name),
+		mIsQuiet(is_quiet)
 	{
 		mAllowedNames.clear();
 	}
@@ -62,7 +64,8 @@ struct ViewerFolderEntry : public LLDictionaryEntry
 		:
 		LLDictionaryEntry(xui_name),
 		mIconName(icon_name),
-		mNewCategoryName(new_category_name)
+		mNewCategoryName(new_category_name),
+		mIsQuiet(FALSE)
 	{
 		const std::string delims (",");
 		LLStringUtilBase<char>::getTokens(allowed_names, mAllowedNames, delims);
@@ -85,6 +88,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry
 	const std::string mNewCategoryName;
 	typedef std::vector<std::string> name_vec_t;
 	name_vec_t mAllowedNames;
+	BOOL mIsQuiet;
 };
 
 class LLViewerFolderDictionary : public LLSingleton<LLViewerFolderDictionary>,
@@ -100,31 +104,31 @@ LLViewerFolderDictionary::LLViewerFolderDictionary()
 {
 	initEnsemblesFromFile();
 
-	//       													    	  NEW CATEGORY NAME         FOLDER ICON NAME
-	//      												  		     |-------------------------|---------------------------|
-	addEntry(LLFolderType::FT_TEXTURE, 				new ViewerFolderEntry("Textures",				"inv_folder_texture.tga"));
-	addEntry(LLFolderType::FT_SOUND, 				new ViewerFolderEntry("Sounds",					"inv_folder_sound.tga"));
-	addEntry(LLFolderType::FT_CALLINGCARD, 			new ViewerFolderEntry("Calling Cards",			"inv_folder_callingcard.tga"));
-	addEntry(LLFolderType::FT_LANDMARK, 			new ViewerFolderEntry("Landmarks",				"inv_folder_landmark.tga"));
-	addEntry(LLFolderType::FT_CLOTHING, 			new ViewerFolderEntry("Clothing",				"inv_folder_clothing.tga"));
-	addEntry(LLFolderType::FT_OBJECT, 				new ViewerFolderEntry("Objects",				"inv_folder_object.tga"));
-	addEntry(LLFolderType::FT_NOTECARD, 			new ViewerFolderEntry("Notecards",				"inv_folder_notecard.tga"));
-	addEntry(LLFolderType::FT_ROOT_INVENTORY, 		new ViewerFolderEntry("My Inventory",			""));
-	addEntry(LLFolderType::FT_LSL_TEXT, 			new ViewerFolderEntry("Scripts",				"inv_folder_script.tga"));
-	addEntry(LLFolderType::FT_BODYPART, 			new ViewerFolderEntry("Body Parts",				"inv_folder_bodypart.tga"));
-	addEntry(LLFolderType::FT_TRASH, 				new ViewerFolderEntry("Trash",					"inv_folder_trash.tga"));
-	addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, 	new ViewerFolderEntry("Photo Album",			"inv_folder_snapshot.tga"));
-	addEntry(LLFolderType::FT_LOST_AND_FOUND, 		new ViewerFolderEntry("Lost And Found",	   		"inv_folder_lostandfound.tga"));
-	addEntry(LLFolderType::FT_ANIMATION, 			new ViewerFolderEntry("Animations",				"inv_folder_animation.tga"));
-	addEntry(LLFolderType::FT_GESTURE, 				new ViewerFolderEntry("Gestures",				"inv_folder_gesture.tga"));
-	addEntry(LLFolderType::FT_FAVORITE, 			new ViewerFolderEntry("Favorite",				"inv_folder_plain_closed.tga"));
+	//       													    	  NEW CATEGORY NAME         FOLDER ICON NAME                QUIET?
+	//      												  		     |-------------------------|-------------------------------|-----------|
+	addEntry(LLFolderType::FT_TEXTURE, 				new ViewerFolderEntry("Textures",				"inv_folder_texture.tga",		FALSE));
+	addEntry(LLFolderType::FT_SOUND, 				new ViewerFolderEntry("Sounds",					"inv_folder_sound.tga",			FALSE));
+	addEntry(LLFolderType::FT_CALLINGCARD, 			new ViewerFolderEntry("Calling Cards",			"inv_folder_callingcard.tga",	FALSE));
+	addEntry(LLFolderType::FT_LANDMARK, 			new ViewerFolderEntry("Landmarks",				"inv_folder_landmark.tga",		FALSE));
+	addEntry(LLFolderType::FT_CLOTHING, 			new ViewerFolderEntry("Clothing",				"inv_folder_clothing.tga",		FALSE));
+	addEntry(LLFolderType::FT_OBJECT, 				new ViewerFolderEntry("Objects",				"inv_folder_object.tga",		FALSE));
+	addEntry(LLFolderType::FT_NOTECARD, 			new ViewerFolderEntry("Notecards",				"inv_folder_notecard.tga",		FALSE));
+	addEntry(LLFolderType::FT_ROOT_INVENTORY, 		new ViewerFolderEntry("My Inventory",			"",								FALSE));
+	addEntry(LLFolderType::FT_LSL_TEXT, 			new ViewerFolderEntry("Scripts",				"inv_folder_script.tga",		FALSE));
+	addEntry(LLFolderType::FT_BODYPART, 			new ViewerFolderEntry("Body Parts",				"inv_folder_bodypart.tga",		FALSE));
+	addEntry(LLFolderType::FT_TRASH, 				new ViewerFolderEntry("Trash",					"inv_folder_trash.tga",			TRUE));
+	addEntry(LLFolderType::FT_SNAPSHOT_CATEGORY, 	new ViewerFolderEntry("Photo Album",			"inv_folder_snapshot.tga",		FALSE));
+	addEntry(LLFolderType::FT_LOST_AND_FOUND, 		new ViewerFolderEntry("Lost And Found",	   		"inv_folder_lostandfound.tga",	TRUE));
+	addEntry(LLFolderType::FT_ANIMATION, 			new ViewerFolderEntry("Animations",				"inv_folder_animation.tga",		FALSE));
+	addEntry(LLFolderType::FT_GESTURE, 				new ViewerFolderEntry("Gestures",				"inv_folder_gesture.tga",		FALSE));
+	addEntry(LLFolderType::FT_FAVORITE, 			new ViewerFolderEntry("Favorite",				"inv_folder_plain_closed.tga",	FALSE));
 
-	addEntry(LLFolderType::FT_CURRENT_OUTFIT, 		new ViewerFolderEntry("Current Outfit",			"inv_folder_current_outfit.tga"));
-	addEntry(LLFolderType::FT_OUTFIT, 				new ViewerFolderEntry("New Outfit",				"inv_folder_outfit.tga"));
-	addEntry(LLFolderType::FT_MY_OUTFITS, 			new ViewerFolderEntry("My Outfits",				"inv_folder_my_outfits.tga"));
-	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"inv_folder_inbox.tga"));
+	addEntry(LLFolderType::FT_CURRENT_OUTFIT, 		new ViewerFolderEntry("Current Outfit",			"inv_folder_current_outfit.tga",TRUE));
+	addEntry(LLFolderType::FT_OUTFIT, 				new ViewerFolderEntry("New Outfit",				"inv_folder_outfit.tga",		TRUE));
+	addEntry(LLFolderType::FT_MY_OUTFITS, 			new ViewerFolderEntry("My Outfits",				"inv_folder_my_outfits.tga",	TRUE));
+	addEntry(LLFolderType::FT_INBOX, 				new ViewerFolderEntry("Inbox",					"inv_folder_inbox.tga",			FALSE));
 		 
-	addEntry(LLFolderType::FT_NONE, 				new ViewerFolderEntry("New Folder",				"inv_folder_plain_closed.tga"));
+	addEntry(LLFolderType::FT_NONE, 				new ViewerFolderEntry("New Folder",				"inv_folder_plain_closed.tga",	FALSE));
 }
 
 bool LLViewerFolderDictionary::initEnsemblesFromFile()
@@ -219,6 +223,17 @@ const std::string &LLViewerFolderType::lookupIconName(LLFolderType::EType folder
 	return badLookup();
 }
 
+BOOL LLViewerFolderType::lookupIsQuietType(LLFolderType::EType folder_type)
+{
+	const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type);
+	if (entry)
+	{
+		return entry->mIsQuiet;
+	}
+	return FALSE;
+}
+
+
 const std::string &LLViewerFolderType::lookupNewCategoryName(LLFolderType::EType folder_type)
 {
 	const ViewerFolderEntry *entry = LLViewerFolderDictionary::getInstance()->lookup(folder_type);
diff --git a/indra/newview/llviewerfoldertype.h b/indra/newview/llviewerfoldertype.h
index a6aea62b2a33096559a70b24e30cfe8f85b59ad1..dd9360da9027526a2b0645a7a32f9fbc8e2fe76e 100644
--- a/indra/newview/llviewerfoldertype.h
+++ b/indra/newview/llviewerfoldertype.h
@@ -44,11 +44,13 @@ class LLViewerFolderType : public LLFolderType
 	static const std::string&   lookupXUIName(EType folder_type); // name used by the UI
 	static LLFolderType::EType 	lookupTypeFromXUIName(const std::string& name);
 
-	static const std::string&   lookupIconName(EType asset_type); // folder icon name
+	static const std::string&   lookupIconName(EType folder_type); // folder icon name
+	static BOOL					lookupIsQuietType(EType folder_type); // folder doesn't require UI update when changes have occured
 	static const std::string&	lookupNewCategoryName(EType folder_type); // default name when creating new category
 	static LLFolderType::EType	lookupTypeFromNewCategoryName(const std::string& name); // default name when creating new category
 
 	static U64					lookupValidFolderTypes(const std::string& item_name); // which folders allow an item of this type?
+
 protected:
 	LLViewerFolderType() {}
 	~LLViewerFolderType() {}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 5bdcbc79bd40bc95f287815953c0351fb9e472b0..5da77ecdb9303b6e38dac503368df3883a6a4a3c 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -509,11 +509,13 @@ bool LLViewerInventoryCategory::fetchDescendents()
 		// This comes from LLInventoryFilter from llfolderview.h
 		U32 sort_order = gSavedSettings.getU32("InventorySortOrder") & 0x1;
 
-		// *NOTE
-		// Temporary workaround for bug EXT-2879, see ticket for details.
-		// Commented gAgent.getRegion()->getCapability in order to use the old system.
-		std::string url;//= gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");
-   
+		// *NOTE: For bug EXT-2879, originally commented out
+		// gAgent.getRegion()->getCapability in order to use the old
+		// message-based system.  This has been uncommented now that
+		// AIS folks are aware of the issue and have a fix in process.
+		// see ticket for details.
+
+		std::string url = gAgent.getRegion()->getCapability("WebFetchInventoryDescendents");
 		if (!url.empty()) //Capability found.  Build up LLSD and use it.
 		{
 			LLInventoryModel::startBackgroundFetch(mUUID);			
@@ -1435,3 +1437,74 @@ void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std:
 	gInventory.notifyObservers();
 }
 
+class LLRegenerateLinkCollector : public LLInventoryCollectFunctor
+{
+public:
+	LLRegenerateLinkCollector(const LLViewerInventoryItem *target_item) : mTargetItem(target_item) {}
+	virtual ~LLRegenerateLinkCollector() {}
+	virtual bool operator()(LLInventoryCategory* cat,
+							LLInventoryItem* item)
+	{
+		if (item)
+		{
+			if ((item->getName() == mTargetItem->getName()) &&
+				(item->getInventoryType() == mTargetItem->getInventoryType()) &&
+				(!item->getIsLinkType()))
+			{
+				return true;
+			}
+		}
+		return false;
+	}
+protected:
+	const LLViewerInventoryItem* mTargetItem;
+};
+
+LLUUID find_possible_item_for_regeneration(const LLViewerInventoryItem *target_item)
+{
+	LLViewerInventoryCategory::cat_array_t cats;
+	LLViewerInventoryItem::item_array_t items;
+
+	LLRegenerateLinkCollector candidate_matches(target_item);
+	gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
+									cats,
+									items,
+									LLInventoryModel::EXCLUDE_TRASH,
+									candidate_matches);
+	for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items.begin();
+		 item_iter != items.end();
+		 ++item_iter)
+	{
+	    const LLViewerInventoryItem *item = (*item_iter);
+		if (true) return item->getUUID();
+	}
+	return LLUUID::null;
+}
+
+// This currently dosen't work, because the sim does not allow us 
+// to change an item's assetID.
+BOOL LLViewerInventoryItem::regenerateLink()
+{
+	const LLUUID target_item_id = find_possible_item_for_regeneration(this);
+	if (target_item_id.isNull())
+		return FALSE;
+	LLViewerInventoryCategory::cat_array_t cats;
+	LLViewerInventoryItem::item_array_t items;
+	LLAssetIDMatches asset_id_matches(getAssetUUID());
+	gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
+									cats,
+									items,
+									LLInventoryModel::EXCLUDE_TRASH,
+									asset_id_matches);
+	for (LLViewerInventoryItem::item_array_t::iterator item_iter = items.begin();
+		 item_iter != items.end();
+		 item_iter++)
+	{
+	    LLViewerInventoryItem *item = (*item_iter);
+		item->setAssetUUID(target_item_id);
+		item->updateServer(FALSE);
+		gInventory.addChangedMask(LLInventoryObserver::REBUILD, item->getUUID());
+	}
+	gInventory.notifyObservers();
+	return TRUE;
+}
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index d27faffdd9e7c4417683e4b512a5b1e1ac79c0e6..0156e7dab16c00f1d21e0950462263c7c8f85b2e 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -161,7 +161,10 @@ class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::tr
 
 	// callback
 	void onCallingCardNameLookup(const LLUUID& id, const std::string& first_name, const std::string& last_name);
-	
+
+	// If this is a broken link, try to fix it and any other identical link.
+	BOOL regenerateLink();
+
 public:
 	BOOL mIsComplete;
 	LLTransactionID mTransactionID;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 85b60515026536698bf102e4188ee063f2363882..507e34348b507c85c2bbb8e704e494427e2a2713 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -73,6 +73,7 @@
 #include "llstatusbar.h"
 #include "llimview.h"
 #include "lltrans.h"
+#include "llviewerfoldertype.h"
 #include "llviewergenericmessage.h"
 #include "llviewermenu.h"
 #include "llviewerobjectlist.h"
@@ -824,35 +825,49 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)
  
 void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& from_name)
 {
-	std::vector<LLUUID>::const_iterator it = items.begin();
-	std::vector<LLUUID>::const_iterator end = items.end();
-	const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
-	LLInventoryItem* item;
-	for(; it != end; ++it)
-	{
-		const LLUUID& id = *it;
-		item = gInventory.getItem(id);
+	for (std::vector<LLUUID>::const_iterator item_iter = items.begin();
+		 item_iter != items.end();
+		 ++item_iter)
+	{
+		const LLUUID& item_id = (*item_iter);
+		LLInventoryItem* item = gInventory.getItem(item_id);
 		if(!item)
 		{
-			LL_WARNS("Messaging") << "Unable to show inventory item: " << id << LL_ENDL;
+			LL_WARNS("Messaging") << "Unable to show inventory item: " << item_id << LL_ENDL;
 			continue;
 		}
-		if(gInventory.isObjectDescendentOf(id, trash_id))
+
+		////////////////////////////////////////////////////////////////////////////////
+		// Don't highlight if it's in certain "quiet" folders which don't need UI 
+		// notification (e.g. trash, cof, lost-and-found).
+		const BOOL user_is_away = gAwayTimer.getStarted();
+		if(!user_is_away)
 		{
-			continue;
+			const LLViewerInventoryCategory *parent = gInventory.getFirstNondefaultParent(item_id);
+			if (parent)
+			{
+				const LLFolderType::EType parent_type = parent->getPreferredType();
+				if (LLViewerFolderType::lookupIsQuietType(parent_type))
+				{
+					continue;
+				}
+			}
 		}
-		LLAssetType::EType asset_type = item->getType();
 
-		//if we are throttled, don't display them
-		if (check_offer_throttle(from_name, false))
+		////////////////////////////////////////////////////////////////////////////////
+		// Special handling for various types.
+		const LLAssetType::EType asset_type = item->getType();
+		if (check_offer_throttle(from_name, false)) // If we are throttled, don't display
 		{
 			// If we opened this ourselves, focus it
-			BOOL take_focus = from_name.empty() ? TAKE_FOCUS_YES : TAKE_FOCUS_NO;
+			const BOOL take_focus = from_name.empty() ? TAKE_FOCUS_YES : TAKE_FOCUS_NO;
 			switch(asset_type)
 			{
 			  case LLAssetType::AT_NOTECARD:
-				LLFloaterReg::showInstance("preview_notecard", LLSD(id), take_focus);
-				break;
+			  {
+				  LLFloaterReg::showInstance("preview_notecard", LLSD(item_id), take_focus);
+				  break;
+			  }
 			  case LLAssetType::AT_LANDMARK:
 			  	{
 					LLInventoryCategory* parent_folder = gInventory.getCategory(item->getParentUUID());
@@ -862,63 +877,35 @@ void open_inventory_offer(const std::vector<LLUUID>& items, const std::string& f
 					LLNotificationsUtil::add("LandmarkCreated", args);
 
 					// Created landmark is passed to Places panel to allow its editing.
-					LLPanelPlaces *panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->showPanel("panel_places", LLSD()));
-					if (panel)
+					LLPanelPlaces *places_panel = dynamic_cast<LLPanelPlaces*>(LLSideTray::getInstance()->showPanel("panel_places", LLSD()));
+					if (places_panel)
 					{
-						panel->setItem(item);
+						places_panel->setItem(item);
 					}
 			  	}
 				break;
 			  case LLAssetType::AT_TEXTURE:
-				LLFloaterReg::showInstance("preview_texture", LLSD(id), take_focus);
-				break;
+			  {
+				  LLFloaterReg::showInstance("preview_texture", LLSD(item_id), take_focus);
+				  break;
+			  }
 			  default:
 				break;
 			}
 		}
-		//highlight item, if it's not in the trash or lost+found
 		
-		// Don't auto-open the inventory floater
-		if(gSavedSettings.getBOOL("ShowInInventory") &&
-		   asset_type != LLAssetType::AT_CALLINGCARD &&
-		   item->getInventoryType() != LLInventoryType::IT_ATTACHMENT &&
-		   !from_name.empty())
-		{
-			//TODO:this should be moved to the end of method after all the checks,
-			//but first decide what to do with active inventory if any (EK)
-			LLSD key;
-			key["select"] = item->getUUID();
-			LLSideTray::getInstance()->showPanel("sidepanel_inventory", key);
-		}
-		LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
+		////////////////////////////////////////////////////////////////////////////////
+		// Highlight item if it's not in the trash, lost+found, or COF
+		const BOOL auto_open = gSavedSettings.getBOOL("ShowInInventory") &&
+			(asset_type != LLAssetType::AT_CALLINGCARD) &&
+			(item->getInventoryType() != LLInventoryType::IT_ATTACHMENT) &&
+			!from_name.empty();
+		LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel(auto_open);
 		if(active_panel)
 		{
-			//Trash Check
-			const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
-			if(gInventory.isObjectDescendentOf(item->getUUID(), trash_id))
-			{
-				return;
-			}
-			const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
-			//BOOL inventory_has_focus = gFocusMgr.childHasKeyboardFocus(view);
-			BOOL user_is_away = gAwayTimer.getStarted();
-
-			// don't select lost and found items if the user is active
-			if (gInventory.isObjectDescendentOf(item->getUUID(), lost_and_found_id)
-				&& !user_is_away)
-			{
-				return;
-			}
-
-			//Not sure about this check.  Could make it easy to miss incoming items.
-			//don't dick with highlight while the user is working
-			//if(inventory_has_focus && !user_is_away)
-			//	break;
-			LL_DEBUGS("Messaging") << "Highlighting" << item->getUUID()  << LL_ENDL;
-			//highlight item
-
+			LL_DEBUGS("Messaging") << "Highlighting" << item_id  << LL_ENDL;
 			LLFocusableElement* focus_ctrl = gFocusMgr.getKeyboardFocus();
-			active_panel->setSelection(item->getUUID(), TAKE_FOCUS_NO);
+			active_panel->setSelection(item_id, TAKE_FOCUS_NO);
 			gFocusMgr.setKeyboardFocus(focus_ctrl);
 		}
 	}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index a9194c0c3b4555d084cddbe9472d66e51813f968..93b0ad4a5b06b18f23f5b55f28495fc502d628e3 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3834,15 +3834,6 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
 			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
 		}
 		
-		bool should_alpha_mask = shouldAlphaMask();
-
-		LLGLState test(GL_ALPHA_TEST, should_alpha_mask);
-
-		if (should_alpha_mask)
-		{
-			gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
-		}
-
 		if (isTextureVisible(TEX_HEAD_BAKED))
 		{
 			num_indices += mMeshLOD[MESH_ID_EYELASH]->render(mAdjustedPixelArea, first_pass, mIsDummy);
@@ -6011,8 +6002,7 @@ void LLVOAvatar::updateMeshTextures()
 			}
 		}
 		else if (mBakedTextureDatas[i].mTexLayerSet 
-				 && !other_culled 
-				 && (i != BAKED_HAIR || mSupportsAlphaLayers)) // ! BACKWARDS COMPATIBILITY ! workaround for old viewers.
+				 && !other_culled) 
 		{
 			mBakedTextureDatas[i].mTexLayerSet->createComposite();
 			mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( TRUE );
@@ -6024,9 +6014,10 @@ void LLVOAvatar::updateMeshTextures()
 		}
 	}
 
-	// ! BACKWARDS COMPATIBILITY !
-	// Workaround for viewing avatars from old viewers that haven't baked hair textures.
-	if (!mSupportsAlphaLayers)
+	// set texture and color of hair manually if we are not using a baked image.
+	// This can happen while loading hair for yourself, or for clients that did not
+	// bake a hair texture. Still needed for yourself after 1.22 is depricated.
+	if (!is_layer_baked[BAKED_HAIR] || self_customizing)
 	{
 		const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1);
 		LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 );
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
index 435a3e6d3400a4bec8de94cf075a359c93233602..4e6a07d02056aaa15e992f6be3578bb7dae7a314 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
@@ -76,7 +76,9 @@
          function="Inventory.GearDefault.Custom.Action"
          parameter="empty_lostnfound" />
     </menu_item_call>
-        <menu_item_call
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call 
          label="Save Texture As"
          layout="topleft"
          name="Save Texture As">
@@ -87,4 +89,26 @@
 			 function="Inventory.GearDefault.Enable"
 			 parameter="save_texture" />
         </menu_item_call>
+    <menu_item_call 
+         label="Find Original"
+         layout="topleft"
+         name="Find Original">
+            <on_click
+             function="Inventory.GearDefault.Custom.Action"
+             parameter="find_original" />
+            <on_enable
+			 function="Inventory.GearDefault.Enable"
+			 parameter="find_original" />
+        </menu_item_call>
+    <menu_item_call 
+         label="Find All Links"
+         layout="topleft"
+         name="Find All Links">
+            <on_click
+             function="Inventory.GearDefault.Custom.Action"
+             parameter="find_links" />
+            <on_enable
+			 function="Inventory.GearDefault.Enable"
+			 parameter="find_links" />
+        </menu_item_call>
 </menu>