diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 6b2033fc6f93409211e230c1dab3104fd4e77656..538dcb6f3dff2c2bbac908687fb40d3d88dc426e 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -653,11 +653,13 @@ LLWearable* LLAgentWearables::getWearable(const EWearableType type, U32 index)
 
 void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearable *wearable)
 {
-	if (!getWearable(type,index))
+	LLWearable *old_wearable = getWearable(type,index);
+	if (!old_wearable)
 	{
 		pushWearable(type,wearable);
 		return;
 	}
+	
 	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
 	if (wearable_iter == mWearableDatas.end())
 	{
@@ -672,6 +674,7 @@ void LLAgentWearables::setWearable(const EWearableType type, U32 index, LLWearab
 	else
 	{
 		wearable_vec[index] = wearable;
+		old_wearable->setLabelUpdated();
 		mAvatarObject->wearableUpdated(wearable->getType());
 	}
 }
@@ -688,6 +691,7 @@ U32 LLAgentWearables::pushWearable(const EWearableType type, LLWearable *wearabl
 	{
 		mWearableDatas[type].push_back(wearable);
 		mAvatarObject->wearableUpdated(wearable->getType());
+		wearable->setLabelUpdated();
 		return mWearableDatas[type].size()-1;
 	}
 	return MAX_WEARABLES_PER_TYPE;
@@ -717,6 +721,7 @@ void LLAgentWearables::popWearable(const EWearableType type, U32 index)
 	{
 		mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
 		mAvatarObject->wearableUpdated(wearable->getType());
+		wearable->setLabelUpdated();
 	}
 }
 
@@ -1412,14 +1417,10 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem
 		for (S32 i=max_entry; i>=0; i--)
 		{
 			LLWearable* old_wearable = getWearable(type,i);
-			const LLUUID &item_id = getWearableItemID(type,i);
-			popWearable(type,i);
-			gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
-			LLAppearanceManager::instance().removeItemLinks(item_id,false);
-
 			//queryWearableCache(); // moved below
 			if (old_wearable)
 			{
+				popWearable(old_wearable);
 				old_wearable->removeFromAvatar(TRUE);
 			}
 		}
@@ -1428,16 +1429,11 @@ void LLAgentWearables::removeWearableFinal(const EWearableType type, bool do_rem
 	else
 	{
 		LLWearable* old_wearable = getWearable(type, index);
-
-		const LLUUID &item_id = getWearableItemID(type,index);
-		popWearable(type, index);
-		gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
-		LLAppearanceManager::instance().removeItemLinks(item_id,false);
-
 		//queryWearableCache(); // moved below
 
 		if (old_wearable)
 		{
+			popWearable(old_wearable);
 			old_wearable->removeFromAvatar(TRUE);
 		}
 	}
@@ -1499,7 +1495,6 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
 				continue;
 			}
 
-			gInventory.addChangedMask(LLInventoryObserver::LABEL, old_item_id);
 			// Assumes existing wearables are not dirty.
 			if (old_wearable->isDirty())
 			{
@@ -1508,9 +1503,9 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
 			}
 		}
 
-		setWearable(type,0,new_wearable);
 		if (new_wearable)
 			new_wearable->setItemID(new_item->getUUID());
+		setWearable(type,0,new_wearable);
 	}
 
 	std::vector<LLWearable*> wearables_being_removed;
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 60c6061e966a7860f43c85b35962fcae353a1927..d6265a85f63c3a4dd5c49e0c5b5a8c86a6935a5d 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -579,7 +579,6 @@ void LLAppearanceManager::updateAgentWearables(LLWearableHoldingPattern* holder,
 	if(wearables.count() > 0)
 	{
 		gAgentWearables.setWearableOutfit(items, wearables, !append);
-		gInventory.notifyObservers();
 	}
 
 	delete holder;
@@ -819,15 +818,23 @@ bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventor
 			(a->getWearableType() == b->getWearableType()));
 }
 
-void LLAppearanceManager::addItemLink( LLInventoryItem* item, bool do_update )
+void LLAppearanceManager::addCOFItemLink(const LLUUID &item_id, bool do_update )
 {
-	LLViewerInventoryItem *vitem = dynamic_cast<LLViewerInventoryItem*>(item);
+	const LLInventoryItem *item = gInventory.getItem(item_id);
+	addCOFItemLink(item);
+}
+
+void LLAppearanceManager::addCOFItemLink(const LLInventoryItem *item, bool do_update )
+{		
+	const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item);
 	if (!vitem)
 	{
 		llwarns << "not an llviewerinventoryitem, failed" << llendl;
 		return;
 	}
-		
+
+	gInventory.addChangedMask(LLInventoryObserver::LABEL, vitem->getLinkedUUID());
+
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t item_array;
 	gInventory.collectDescendents(LLAppearanceManager::getCOF(),
@@ -839,7 +846,7 @@ void LLAppearanceManager::addItemLink( LLInventoryItem* item, bool do_update )
 	{
 		// Are these links to the same object?
 		const LLViewerInventoryItem* inv_item = item_array.get(i).get();
-		if (inv_item->getLinkedUUID() == item->getLinkedUUID())
+		if (inv_item->getLinkedUUID() == vitem->getLinkedUUID())
 		{
 			linked_already = true;
 		}
@@ -850,7 +857,6 @@ void LLAppearanceManager::addItemLink( LLInventoryItem* item, bool do_update )
 		{
 			gAgentWearables.removeWearable(inv_item->getWearableType(),true,0);
 			gInventory.purgeObject(inv_item->getUUID());
-			gInventory.notifyObservers();
 		}
 	}
 	if (linked_already)
@@ -886,8 +892,10 @@ void LLAppearanceManager::addEnsembleLink( LLInventoryCategory* cat, bool do_upd
 #endif
 }
 
-void LLAppearanceManager::removeItemLinks(const LLUUID& item_id, bool do_update)
+void LLAppearanceManager::removeCOFItemLinks(const LLUUID& item_id, bool do_update)
 {
+	gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
+
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t item_array;
 	gInventory.collectDescendents(LLAppearanceManager::getCOF(),
@@ -899,7 +907,8 @@ void LLAppearanceManager::removeItemLinks(const LLUUID& item_id, bool do_update)
 		const LLInventoryItem* item = item_array.get(i).get();
 		if (item->getLinkedUUID() == item_id)
 		{
-			gInventory.purgeObject(item_array.get(i)->getUUID());
+			const LLUUID& item_id = item_array.get(i)->getUUID();
+			gInventory.purgeObject(item_id);
 		}
 	}
 	if (do_update)
@@ -978,18 +987,13 @@ void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
 void LLAppearanceManager::registerAttachment(const LLUUID& item_id)
 {
        mRegisteredAttachments.insert(item_id);
+	   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
        //dumpAttachmentSet(mRegisteredAttachments,"after register:");
 
 	   if (mAttachmentInvLinkEnabled)
 	   {
-		   LLViewerInventoryItem *item = gInventory.getItem(item_id);
-		   if (item)
-		   {
-			   //LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:");
-			   LLAppearanceManager::addItemLink(item,false);  // Add COF link for item.
-			   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
-			   gInventory.notifyObservers();
-		   }
+		   //LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Adding attachment link:");
+		   LLAppearanceManager::addCOFItemLink(item_id, false);  // Add COF link for item.
 	   }
 	   else
 	   {
@@ -1000,15 +1004,14 @@ void LLAppearanceManager::registerAttachment(const LLUUID& item_id)
 void LLAppearanceManager::unregisterAttachment(const LLUUID& item_id)
 {
        mRegisteredAttachments.erase(item_id);
+	   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
+
        //dumpAttachmentSet(mRegisteredAttachments,"after unregister:");
 
 	   if (mAttachmentInvLinkEnabled)
 	   {
 		   //LLAppearanceManager::dumpCat(LLAppearanceManager::getCOF(),"Removing attachment link:");
-		   LLAppearanceManager::removeItemLinks(item_id, false);
-		   // BAP - needs to change for label to track link.
-		   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
-		   gInventory.notifyObservers();
+		   LLAppearanceManager::removeCOFItemLinks(item_id, false);
 	   }
 	   else
 	   {
@@ -1023,13 +1026,7 @@ void LLAppearanceManager::linkRegisteredAttachments()
 		 ++it)
 	{
 		LLUUID item_id = *it;
-		LLViewerInventoryItem *item = gInventory.getItem(item_id);
-		if (item)
-		{
-			addItemLink(item, false);
-			gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
-			gInventory.notifyObservers();
-		}
+		addCOFItemLink(item_id, false);
 	}
 	mRegisteredAttachments.clear();
 }
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 12ffa336b45ecce82d4e38b3f09def64a708fb3c..5daa6d067b633012ae36d4e5bc1b6fd70831d661 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -54,12 +54,6 @@ class LLAppearanceManager: public LLSingleton<LLAppearanceManager>
 	void wearOutfitByName(const std::string& name);
 	void changeOutfit(bool proceed, const LLUUID& category, bool append);
 
-	// Add COF link to individual item.
-	void addItemLink(LLInventoryItem* item, bool do_update = true);
-
-	// Add COF link to ensemble folder.
-	void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
-
 	// Copy all items in a category.
 	void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
 							 LLPointer<LLInventoryCallback> cb);
@@ -67,9 +61,6 @@ class LLAppearanceManager: public LLSingleton<LLAppearanceManager>
 	// Find the Current Outfit folder.
 	LLUUID getCOF();
 
-	// Remove COF entries
-	void removeItemLinks(const LLUUID& item_id, bool do_update = true);
-
 	void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
 
 	// For debugging - could be moved elsewhere.
@@ -87,6 +78,16 @@ class LLAppearanceManager: public LLSingleton<LLAppearanceManager>
 				 LLInventoryModel::item_array_t& items,
 				 LLPointer<LLInventoryCallback> cb);
 
+	// Add COF link to individual item.
+	void addCOFItemLink(const LLUUID& item_id, bool do_update = true);
+	void addCOFItemLink(const LLInventoryItem *item, bool do_update = true);
+
+	// Remove COF entries
+	void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true);
+
+	// Add COF link to ensemble folder.
+	void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
+
 protected:
 	LLAppearanceManager();
 	~LLAppearanceManager();
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f82d17808954775dc00ce6752bf012491f3b8923..3d7b324458529d3d495dd7757bcff790874624a0 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -3534,6 +3534,7 @@ void LLAppViewer::idle()
 		gEventNotifier.update();
 		
 		gIdleCallbacks.callFunctions();
+		gInventory.notifyObservers();
 	}
 	
 	if (gDisconnected)
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index fbef237779c7f82320f92beca9ad1c8172725b0a..384d2ae671a3c395516ab3780c7c6038c46b1350 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -183,37 +183,6 @@ BOOL LLInvFVBridge::isItemRemovable()
 	return FALSE;
 }
 
-// Sends an update to all link items that point to the base item.
-void LLInvFVBridge::renameLinkedItems(const LLUUID &item_id, const std::string& new_name)
-{
-	LLInventoryModel* model = getInventoryModel();
-	if(!model) return;
-
-	LLInventoryItem* itemp = model->getItem(mUUID);
-	if (!itemp) return;
-
-	if (itemp->getIsLinkType())
-	{
-		return;
-	}
-
-	LLInventoryModel::item_array_t item_array = model->collectLinkedItems(item_id);
-	for (LLInventoryModel::item_array_t::iterator iter = item_array.begin();
-		 iter != item_array.end();
-		 iter++)
-	{
-		LLViewerInventoryItem *linked_item = (*iter);
-		if (linked_item->getUUID() == item_id) continue;
-
-		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(linked_item);
-		new_item->rename(new_name);
-		new_item->updateServer(FALSE);
-		model->updateItem(new_item);
-		// model->addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
-	}
-	model->notifyObservers();
-}
-
 // Can be moved to another folder
 BOOL LLInvFVBridge::isItemMovable() const
 {
@@ -2924,7 +2893,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 				// BAP - should skip if dup.
 				if (move_is_into_current_outfit)
 				{
-					LLAppearanceManager::instance().addItemLink(inv_item);
+					LLAppearanceManager::instance().addCOFItemLink(inv_item);
 				}
 				else
 				{
@@ -4171,7 +4140,7 @@ void wear_inventory_item_on_avatar( LLInventoryItem* item )
 		lldebugs << "wear_inventory_item_on_avatar( " << item->getName()
 				 << " )" << llendl;
 
-		LLAppearanceManager::instance().addItemLink(item);
+		LLAppearanceManager::instance().addCOFItemLink(item);
 	}
 }
 
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 56cb0f93ed977810b618a6569b4aaa57af3d4cb2..49e64ebdded888521e3449f5d84bf5aad401da3f 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -204,8 +204,6 @@ class LLInvFVBridge : public LLFolderViewEventListener
 									 const LLUUID& new_parent,
 									 BOOL restamp);
 	void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch);
-	void renameLinkedItems(const LLUUID &item_id, const std::string& new_name);
-
 protected:
 	LLHandle<LLPanel> mInventoryPanel;
 	const LLUUID mUUID;	// item id
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 84588fbe8cae4021868719b4951530dffacc1630..fbaab385feddd0233469e4594f02247ad13caae0 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -509,7 +509,7 @@ void LLInventoryModel::collectDescendentsIf(const LLUUID& id,
 	}
 }
 
-void LLInventoryModel::updateLinkedItems(const LLUUID& object_id)
+void LLInventoryModel::addChangedMaskForLinks(const LLUUID& object_id, U32 mask)
 {
 	const LLInventoryObject *obj = getObject(object_id);
 	if (!obj || obj->getIsLinkType())
@@ -532,7 +532,7 @@ void LLInventoryModel::updateLinkedItems(const LLUUID& object_id)
 		 cat_iter++)
 	{
 		LLViewerInventoryCategory *linked_cat = (*cat_iter);
-		addChangedMask(LLInventoryObserver::LABEL, linked_cat->getUUID());
+		addChangedMask(mask, linked_cat->getUUID());
 	};
 
 	for (LLInventoryModel::item_array_t::iterator iter = item_array.begin();
@@ -540,9 +540,8 @@ void LLInventoryModel::updateLinkedItems(const LLUUID& object_id)
 		 iter++)
 	{
 		LLViewerInventoryItem *linked_item = (*iter);
-		addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
+		addChangedMask(mask, linked_item->getUUID());
 	};
-	notifyObservers();
 }
 
 const LLUUID& LLInventoryModel::getLinkedItemID(const LLUUID& object_id) const
@@ -1133,6 +1132,14 @@ void LLInventoryModel::notifyObservers(const std::string service_name)
 		llwarns << "Call was made to notifyObservers within notifyObservers!" << llendl;
 		return;
 	}
+
+	if ((mModifyMask == LLInventoryObserver::NONE) && (service_name == ""))
+	{
+		mModifyMask = LLInventoryObserver::NONE;
+		mChangedItemIDs.clear();
+		return;
+	}
+
 	mIsNotifyObservers = TRUE;
 	for (observer_list_t::iterator iter = mObservers.begin();
 		 iter != mObservers.end(); )
@@ -1180,7 +1187,7 @@ void LLInventoryModel::addChangedMask(U32 mask, const LLUUID& referent)
 	// not sure what else might need to be accounted for this.
 	if (mModifyMask & LLInventoryObserver::LABEL)
 	{
-		updateLinkedItems(referent);
+		addChangedMaskForLinks(referent, LLInventoryObserver::LABEL);
 	}
 }
 
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index aa4ffb392fd79e0ca768b26e264a3b702cb156de..da12dbdf7fd06fb671cbd022abe3f83c5dc4ae28 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -167,8 +167,6 @@ class LLInventoryModel
 	// Assumes item_id is itself not a linked item.
 	item_array_t collectLinkedItems(const LLUUID& item_id,
 									const LLUUID& start_folder_id = LLUUID::null);
-	// Updates all linked items pointing to this id.
-	void updateLinkedItems(const LLUUID& object_id);
 
 	// Get the inventoryID that this item points to, else just return item_id
 	const LLUUID& getLinkedItemID(const LLUUID& object_id) const;
@@ -440,6 +438,9 @@ class LLInventoryModel
 	
 	bool messageUpdateCore(LLMessageSystem* msg, bool do_accounting);
 
+	// Updates all linked items pointing to this id.
+	void addChangedMaskForLinks(const LLUUID& object_id, U32 mask);
+
 protected:
 	cat_array_t* getUnlockedCatArray(const LLUUID& id);
 	item_array_t* getUnlockedItemArray(const LLUUID& id);
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
index 2849cfa20ed4af6609d30e8977970512f8e6cd28..ced0b6489667db5ba608d0c4d73b96e42525a141 100644
--- a/indra/newview/llwearable.cpp
+++ b/indra/newview/llwearable.cpp
@@ -38,6 +38,7 @@
 #include "lllocaltextureobject.h"
 #include "llviewertexturelist.h"
 #include "llinventorymodel.h"
+#include "llinventoryobserver.h"
 #include "llviewerregion.h"
 #include "llvoavatar.h"
 #include "llvoavatarself.h"
@@ -1098,6 +1099,12 @@ void LLWearable::destroyTextures()
 	mSavedTEMap.clear();
 }
 
+
+void LLWearable::setLabelUpdated() const
+{ 
+	gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID());
+}
+
 struct LLWearableSaveData
 {
 	EWearableType mType;
diff --git a/indra/newview/llwearable.h b/indra/newview/llwearable.h
index fd19a864062565e46bd19a18a9906f9df571f8a8..0863adb7f56fa590fa411cb3ac6555b3ed191602 100644
--- a/indra/newview/llwearable.h
+++ b/indra/newview/llwearable.h
@@ -128,6 +128,8 @@ class LLWearable
 
 	BOOL				isOnTop() const;
 
+	// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
+	void				setLabelUpdated() const;
 
 private:
 	typedef std::map<S32, LLLocalTextureObject*> te_map_t;