diff --git a/.hgpatchinfo/Appearance-Misc.dep b/.hgpatchinfo/Appearance-Misc.dep
new file mode 100644
index 0000000000000000000000000000000000000000..12aca283138750dca4c422f3dc44815842fae46e
--- /dev/null
+++ b/.hgpatchinfo/Appearance-Misc.dep
@@ -0,0 +1 @@
+54e81f61aca5bf7c655fb4bf94553aaca0251e43
\ No newline at end of file
diff --git a/.hgpatchinfo/Appearance-Misc.desc b/.hgpatchinfo/Appearance-Misc.desc
new file mode 100644
index 0000000000000000000000000000000000000000..551bffc46ca2e6049c89f872b651c4d19391a9ec
--- /dev/null
+++ b/.hgpatchinfo/Appearance-Misc.desc
@@ -0,0 +1,23 @@
+[Appearance/Misc]
+- fixed   : LLAppearanceMgr::filterWearableItems() doesn't properly filter body parts
+- fixed   : LLWearableList::processGetAssetReply() creates multiple LLWearable instances for the same asset UUID
+    -> fix for http://jira.secondlife.com/browse/VWR-20608
+- fixed   : attachments sometimes detach only to instantly get reattached after logon
+- fixed   : Add to/Replace Outfit removes newly worn attachments on completion
+    -> fix for http://jira.secondlife.com/browse/VWR-18512
+- fixed   : "Replace Outfit" isn't available for non-outfit folders that don't contain a full set of body parts (eyes, hair base, skin and shape)
+    -> fix for http://jira.secondlife.com/browse/VWR-23972
+- fixed   : attachments that attach and then instantly detach don't have their COF link removed
+- fixed   : multiple LLWearableHoldingPattern instances lead to "COF corruption"
+- fixed   : get_is_item_worn() shouldn't make the assumption that items in COFs are always worn
+- fixed   : drag-and-drop wear behaviour of an attachment onto self isn't consistant with the drag-and-drop behaviour of wearables
+    -> normal-drop : replace wear
+    -> Ctrl-drop   : add wear
+- fixed   : LLAppearanceMgr::registerAttachment() fails to (re)add a link for worn attachments that aren't linked to in COF at log-on
+- fixed   : LLViewerObject::getAttachmentItemID() sometimes returns the NULL UUID for the avatar's own attachments
+- fixed   : LLAppearanceMgr::updateAppearanceFromCOF() doesn't properly filter items collected from folder links
+    -> create an outfit with a folder link + "Replace Outfit" == wearables that exist in both COF and the linked folder will end up worn multiple times
+- changed : enable "Replace Current Outfit" on the base outfit if it's marked dirty
+- changed : "RenderUnloadedAvatar" no longer affects the user's own avatar
+    -> side-effect of the fix above due to the change to LLVOAvatar::isFullyLoaded()
+- added   : InitialWearablesLoadedSignal signal which is emitted *once* when the initial wearables are loaded
diff --git a/indra/cmake/DirectX.cmake b/indra/cmake/DirectX.cmake
index 083a5a3b03369d9ec4162a7cab8135655a84652e..d141f0bcd7917bb19f1bc1398df918d114315140 100644
--- a/indra/cmake/DirectX.cmake
+++ b/indra/cmake/DirectX.cmake
@@ -1,4 +1,5 @@
 # -*- cmake -*-
+include(FindWindowsSDK)
 
 if (WINDOWS)
   include(FindWindowsSDK)
diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp
index 207e0c4011f2e9c9496ea6c34b487d991b92f8a8..f088404c7f5ca8fe5fda2ab09896a259200a4a2b 100644
--- a/indra/llappearance/llwearabletype.cpp
+++ b/indra/llappearance/llwearabletype.cpp
@@ -92,7 +92,10 @@ LLWearableDictionary::LLWearableDictionary()
 	addEntry(LLWearableType::WT_ALPHA,        new WearableEntry("alpha",       "New Alpha",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
 	addEntry(LLWearableType::WT_TATTOO,       new WearableEntry("tattoo",      "New Tattoo",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
 
-	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2011-05-29 (Catznip-2.6)
+	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, FALSE));
+// [/SL:KB]
+//	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
 
 	addEntry(LLWearableType::WT_INVALID,      new WearableEntry("invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
 	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry("none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index dd079722499970da159714d742e546a1a51e5812..cb2905b28efd6e4488607f9e19e0098028259fc8 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -159,6 +159,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>AISCommandFilterMask</key>
+    <map>
+      <key>Comment</key>
+      <string>AIS command filter (death by Kitty if you change this)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>65247</integer>
+    </map>
     <key>AlertedUnsupportedHardware</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index 170e4063a1524b22d1eb62d69490194db116526b..bbc630937a85957e5c392de81ed9de06bfbb6621 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -57,6 +57,9 @@
 LLAgentWearables gAgentWearables;
 
 BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;
+// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
+bool LLAgentWearables::mInitialWearablesLoaded = false;
+// [/SL:KB]
 
 using namespace LLAvatarAppearanceDefines;
 
@@ -1134,6 +1137,13 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
 	// Start rendering & update the server
 	mWearablesLoaded = TRUE; 
 
+// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-09-22 (Catznip-2.2)
+	if (!mInitialWearablesLoaded)
+	{
+		mInitialWearablesLoaded = true;
+		mInitialWearablesLoadedSignal();
+	}
+// [/SL:KB]
 	notifyLoadingFinished();
 
 	// Copy wearable params to avatar.
@@ -1635,6 +1645,13 @@ bool LLAgentWearables::changeInProgress() const
 	return mCOFChangeInProgress;
 }
 
+// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
+boost::signals2::connection LLAgentWearables::addInitialWearablesLoadedCallback(const loaded_callback_t& cb)
+{
+	return mInitialWearablesLoadedSignal.connect(cb);
+}
+// [/SL:KB]
+
 void LLAgentWearables::notifyLoadingStarted()
 {
 	mCOFChangeInProgress = true;
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 27102629104216d6e612d21cc484914c0b68fe83..15cec032175de48c628655bed1e5376028fde6c7 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -72,6 +72,9 @@ public:
 
 	BOOL			isWearableCopyable(LLWearableType::EType type, U32 index /*= 0*/) const;
 	BOOL			areWearablesLoaded() const;
+// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
+	bool			areInitalWearablesLoaded() const { return mInitialWearablesLoaded; }
+// [/SL:KB]
 	bool			isCOFChangeInProgress() const { return mCOFChangeInProgress; }
 	F32				getCOFChangeTime() const { return mCOFChangeTimer.getElapsedTimeF32(); }
 	void			updateWearablesLoaded();
@@ -199,6 +202,9 @@ public:
 	typedef boost::function<void()>			loaded_callback_t;
 	typedef boost::signals2::signal<void()>	loaded_signal_t;
 	boost::signals2::connection				addLoadedCallback(loaded_callback_t cb);
+// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
+	boost::signals2::connection				addInitialWearablesLoadedCallback(const loaded_callback_t& cb);
+// [/SL:KB]
 
 	bool									changeInProgress() const;
 	void									notifyLoadingStarted();
@@ -207,12 +213,18 @@ public:
 private:
 	loading_started_signal_t				mLoadingStartedSignal; // should be called before wearables are changed
 	loaded_signal_t							mLoadedSignal; // emitted when all agent wearables get loaded
+// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.1)
+	loaded_signal_t							mInitialWearablesLoadedSignal; // emitted once when the initial wearables are loaded
+// [/SL:KB]
 
 	//--------------------------------------------------------------------
 	// Member variables
 	//--------------------------------------------------------------------
 private:
 	static BOOL		mInitialWearablesUpdateReceived;
+// [SL:KB] - Patch: Appearance-InitialWearablesLoadedCallback | Checked: 2010-08-14 (Catznip-2.2)
+	static bool		mInitialWearablesLoaded;
+// [/SL:KB]
 	BOOL			mWearablesLoaded;
 
 	/**
diff --git a/indra/newview/llaisapi.cpp b/indra/newview/llaisapi.cpp
index ee49125711ab81e1483c32d8e15ab1bdce1df20a..d8588528c03a1816aaf2c50eb317da8779a07a1a 100644
--- a/indra/newview/llaisapi.cpp
+++ b/indra/newview/llaisapi.cpp
@@ -436,14 +436,39 @@ void AISAPI::InvokeAISCommandCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t ht
 
     if (callback && !callback.empty())
     {   
-        LLUUID id(LLUUID::null);
-
-        if (result.has("category_id") && (type == COPYLIBRARYCATEGORY))
-	    {
-		    id = result["category_id"];
-	    }
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
+		uuid_list_t ids;
+		switch (type)
+		{
+			case COPYLIBRARYCATEGORY:
+				if (result.has("category_id"))
+				{
+					ids.insert(result["category_id"]);
+				}
+				break;
+			case COPYINVENTORY:
+				{
+					AISUpdate::parseUUIDArray(result, "_created_items", ids);
+					AISUpdate::parseUUIDArray(result, "_created_categories", ids);
+				}
+				break;
+			default:
+				break;
+		}
 
-        callback(id);
+		// If we were feeling daring we'd call LLInventoryCallback::fire for every item but it would take additional work to investigate whether all LLInventoryCallback derived classes
+		// were designed to handle multiple fire calls (with legacy link creation only one would ever fire per link creation) so we'll be cautious and only call for the first one for now
+		// (note that the LL code as written below will always call fire once with the NULL UUID for anything but CopyLibraryCategoryCommand so even the above is an improvement)
+		callback( (!ids.empty()) ? *ids.begin() : LLUUID::null);
+// [/SL:KB]
+//        LLUUID id(LLUUID::null);
+//
+//        if (result.has("category_id") && (type == COPYLIBRARYCATEGORY))
+//	    {
+//		    id = result["category_id"];
+//	    }
+//
+//        callback(id);
     }
 
 }
diff --git a/indra/newview/llaisapi.h b/indra/newview/llaisapi.h
index e97059014bd11fedf3847eb78041544de3d78cf9..200af0c67ff32d09cd695c90cef8e2d263432e2f 100644
--- a/indra/newview/llaisapi.h
+++ b/indra/newview/llaisapi.h
@@ -89,7 +89,10 @@ public:
 	void parseUpdate(const LLSD& update);
 	void parseMeta(const LLSD& update);
 	void parseContent(const LLSD& update);
-	void parseUUIDArray(const LLSD& content, const std::string& name, uuid_list_t& ids);
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
+	static void parseUUIDArray(const LLSD& content, const std::string& name, uuid_list_t& ids);
+// [/SL:KB]
+//	void parseUUIDArray(const LLSD& content, const std::string& name, uuid_list_t& ids);
 	void parseLink(const LLSD& link_map);
 	void parseItem(const LLSD& link_map);
 	void parseCategory(const LLSD& link_map);
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 0fb811a3867b0bec0ca00481d24c959ed84d34c2..96784b2b38aaef4ceb8b70773b2135396ad7a2ee 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -634,16 +634,20 @@ public:
 	bool pollMissingWearables();
 	bool isMissingCompleted();
 	void recoverMissingWearable(LLWearableType::EType type);
-	void clearCOFLinksForMissingWearables();
+//	void clearCOFLinksForMissingWearables();
 	
 	void onWearableAssetFetch(LLViewerWearable *wearable);
 	void onAllComplete();
 
+// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0)
+	bool pollStopped();
+// [/SL:KB]
+
 	typedef std::list<LLFoundData> found_list_t;
 	found_list_t& getFoundList();
 	void eraseTypeToLink(LLWearableType::EType type);
 	void eraseTypeToRecover(LLWearableType::EType type);
-	void setObjItems(const LLInventoryModel::item_array_t& items);
+//	void setObjItems(const LLInventoryModel::item_array_t& items);
 	void setGestItems(const LLInventoryModel::item_array_t& items);
 	bool isMostRecent();
 	void handleLateArrivals();
@@ -653,7 +657,7 @@ public:
 	
 private:
 	found_list_t mFoundList;
-	LLInventoryModel::item_array_t mObjItems;
+//	LLInventoryModel::item_array_t mObjItems;
 	LLInventoryModel::item_array_t mGestItems;
 	typedef std::set<S32> type_set_t;
 	type_set_t mTypesToRecover;
@@ -730,10 +734,11 @@ void LLWearableHoldingPattern::eraseTypeToRecover(LLWearableType::EType type)
 	mTypesToRecover.erase(type);
 }
 
-void LLWearableHoldingPattern::setObjItems(const LLInventoryModel::item_array_t& items)
-{
-	mObjItems = items;
-}
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.1
+//void LLWearableHoldingPattern::setObjItems(const LLInventoryModel::item_array_t& items)
+//{
+//	mObjItems = items;
+//}
 
 void LLWearableHoldingPattern::setGestItems(const LLInventoryModel::item_array_t& items)
 {
@@ -840,52 +845,52 @@ void LLWearableHoldingPattern::onAllComplete()
 
 	if (isAgentAvatarValid())
 	{
-		LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.size() << " attachments" << LL_ENDL;
-		LLAgentWearables::llvo_vec_t objects_to_remove;
-		LLAgentWearables::llvo_vec_t objects_to_retain;
-		LLInventoryModel::item_array_t items_to_add;
-
-		LLAgentWearables::findAttachmentsAddRemoveInfo(mObjItems,
-													   objects_to_remove,
-													   objects_to_retain,
-													   items_to_add);
-
-		LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size()
-							<< " attachments" << LL_ENDL;
-
-		// Here we remove the attachment pos overrides for *all*
-		// attachments, even those that are not being removed. This is
-		// needed to get joint positions all slammed down to their
-		// pre-attachment states.
-		gAgentAvatarp->clearAttachmentOverrides();
-
-		if (objects_to_remove.size() || items_to_add.size())
-		{
-			LL_DEBUGS("Avatar") << "ATT will remove " << objects_to_remove.size()
-								<< " and add " << items_to_add.size() << " items" << LL_ENDL;
-		}
-
-		// Take off the attachments that will no longer be in the outfit.
-		LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove);
-		
+//		LL_DEBUGS("Avatar") << self_av_string() << "Updating " << mObjItems.size() << " attachments" << LL_ENDL;
+//		LLAgentWearables::llvo_vec_t objects_to_remove;
+//		LLAgentWearables::llvo_vec_t objects_to_retain;
+//		LLInventoryModel::item_array_t items_to_add;
+//
+//		LLAgentWearables::findAttachmentsAddRemoveInfo(mObjItems,
+//													   objects_to_remove,
+//													   objects_to_retain,
+//													   items_to_add);
+//
+//		LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size()
+//							<< " attachments" << LL_ENDL;
+//
+//		// Here we remove the attachment pos overrides for *all*
+//		// attachments, even those that are not being removed. This is
+//		// needed to get joint positions all slammed down to their
+//		// pre-attachment states.
+//		gAgentAvatarp->clearAttachmentOverrides();
+//
+//		if (objects_to_remove.size() || items_to_add.size())
+//		{
+//			LL_DEBUGS("Avatar") << "ATT will remove " << objects_to_remove.size()
+//								<< " and add " << items_to_add.size() << " items" << LL_ENDL;
+//		}
+//
+//		// Take off the attachments that will no longer be in the outfit.
+//		LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove);
+ 		
 		// Update wearables.
 		LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " updating agent wearables with "
 						   << mResolved << " wearable items " << LL_ENDL;
 		LLAppearanceMgr::instance().updateAgentWearables(this);
 		
-		// Restore attachment pos overrides for the attachments that
-		// are remaining in the outfit.
-		for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin();
-			 it != objects_to_retain.end();
-			 ++it)
-		{
-			LLViewerObject *objectp = *it;
-			gAgentAvatarp->addAttachmentOverridesForObject(objectp);
-		}
-		
-		// Add new attachments to match those requested.
-		LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;
-		LLAgentWearables::userAttachMultipleAttachments(items_to_add);
+//		// Restore attachment pos overrides for the attachments that
+//		// are remaining in the outfit.
+//		for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin();
+//			 it != objects_to_retain.end();
+//			 ++it)
+//		{
+//			LLViewerObject *objectp = *it;
+//			gAgentAvatarp->addAttachmentOverridesForObject(objectp);
+//		}
+//		
+//		// Add new attachments to match those requested.
+//		LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;
+//		LLAgentWearables::userAttachMultipleAttachments(items_to_add);
 	}
 
 	if (isFetchCompleted() && isMissingCompleted())
@@ -923,6 +928,12 @@ bool LLWearableHoldingPattern::pollFetchCompletion()
 	{
 		// runway skip here?
 		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+
+// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0)
+		// If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves
+		doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollStopped, this));
+		return true;
+// [/SL:KB]
 	}
 
 	bool completed = isFetchCompleted();
@@ -993,6 +1004,11 @@ void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLView
 	{
 		// runway skip here?
 		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+
+// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0)
+		// If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves
+		return;
+// [/SL:KB]
 	}
 
 	LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL;
@@ -1044,19 +1060,32 @@ bool LLWearableHoldingPattern::isMissingCompleted()
 	return mTypesToLink.size()==0 && mTypesToRecover.size()==0;
 }
 
-void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
+//void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
+//{
+//	for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it)
+//	{
+//		LLFoundData &data = *it;
+//		if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable))
+//		{
+//			// Wearable link that was never resolved; remove links to it from COF
+//			LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " removing link for unresolved item " << data.mItemID.asString() << LL_ENDL;
+//			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
+//		}
+//	}
+//}
+
+// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0)
+bool LLWearableHoldingPattern::pollStopped()
 {
-	for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it)
+	// We have to keep on polling until we're sure that all callbacks have completed or they'll cause a crash
+	if ( (isFetchCompleted()) && (isMissingCompleted()) )
 	{
-		LLFoundData &data = *it;
-		if ((data.mWearableType < LLWearableType::WT_COUNT) && (!data.mWearable))
-		{
-			// Wearable link that was never resolved; remove links to it from COF
-			LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " removing link for unresolved item " << data.mItemID.asString() << LL_ENDL;
-			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
-		}
+		delete this;
+		return true;
 	}
+	return false;
 }
+// [/SL:KB]
 
 bool LLWearableHoldingPattern::pollMissingWearables()
 {
@@ -1064,6 +1093,12 @@ bool LLWearableHoldingPattern::pollMissingWearables()
 	{
 		// runway skip here?
 		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+
+// [SL:KB] - Patch: Appearance-COFCorruption | Checked: 2010-04-14 (Catznip-2.0)
+		// If we were signalled to stop then we shouldn't do anything else except poll for when it's safe to delete ourselves
+		doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollStopped, this));
+		return true;
+// [/SL:KB]
 	}
 	
 	bool timed_out = isTimedOut();
@@ -1496,7 +1531,10 @@ void LLAppearanceMgr::wearItemsOnAvatar(const uuid_vec_t& item_ids_to_wear,
                     {
                         LLUUID item_id = gAgentWearables.getWearableItemID(item_to_wear->getWearableType(),
                                                                            wearable_count-1);
-                        removeCOFItemLinks(item_id, cb);
+// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-05-02 (Catznip-3.7)
+			removeCOFItemLinks(item_id, NULL, true);
+// [/SL:KB]
+//			removeCOFItemLinks(item_id, cb);
                     }
                     
                     items_to_link.push_back(item_to_wear);
@@ -1919,7 +1957,10 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
 	}
 
 	// Check whether it's the base outfit.
-	if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID())
+//	if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID())
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-09-21 (Catznip-2.1)
+	if ( (outfit_cat_id.isNull()) || ((outfit_cat_id == getBaseOutfitUUID()) && (!isOutfitDirty())) )
+// [/SL:KB]
 	{
 		return false;
 	}
@@ -2032,7 +2073,10 @@ void LLAppearanceMgr::filterWearableItems(
             S32 size = items_by_type[i].size();
             if (size <= 0)
                 continue;
-            S32 start_index = llmax(0,size-max_per_type);
+//            S32 start_index = llmax(0,size-max_per_type);
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-05-11 (Catznip-2.0)
+			S32 start_index = llmax(0, size - ((LLWearableType::getAllowMultiwear((LLWearableType::EType)i)) ? max_per_type : 1));
+// [/SL:KB[
             for (S32 j = start_index; j<size; j++)
             {
                 items.push_back(items_by_type[i][j]);
@@ -2357,14 +2401,18 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
 	{
 		//checking integrity of the COF in terms of ordering of wearables, 
 		//checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state)
+// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-03-01 (Catznip-3.7)
+		// Ordering information is pre-applied locally so no reason to reason to wait on the inventory backend
+		updateClothingOrderingInfo(LLUUID::null);
+// [/SL:KB]
 
-		// As with enforce_item_restrictions handling above, we want
-		// to wait for the update callbacks, then (finally!) call
-		// updateAppearanceFromCOF() with no additional COF munging needed.
-		LLPointer<LLInventoryCallback> cb(
-			new LLUpdateAppearanceOnDestroy(false, false, post_update_func));
-		updateClothingOrderingInfo(LLUUID::null, cb);
-		return;
+//		// As with enforce_item_restrictions handling above, we want
+//		// to wait for the update callbacks, then (finally!) call
+//		// updateAppearanceFromCOF() with no additional COF munging needed.
+//		LLPointer<LLInventoryCallback> cb(
+//			new LLUpdateAppearanceOnDestroy(false, false, post_update_func));
+//		updateClothingOrderingInfo(LLUUID::null, cb);
+//		return;
 	}
 
 	if (!validateClothingOrderingInfo())
@@ -2397,6 +2445,13 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
 	remove_non_link_items(wear_items);
 	remove_non_link_items(obj_items);
 	remove_non_link_items(gest_items);
+// [SL:KB] - Patch: Apperance-Misc | Checked: 2010-11-24 (Catznip-2.4)
+	// Since we're following folder links we might have picked up new duplicates, or exceeded MAX_CLOTHING_LAYERS
+	removeDuplicateItems(wear_items);
+	removeDuplicateItems(obj_items);
+	removeDuplicateItems(gest_items);
+	filterWearableItems(wear_items, LLAgentWearables::MAX_CLOTHING_LAYERS, LLAgentWearables::MAX_CLOTHING_LAYERS);
+// [/SL:KB]
 
 	dumpItemArray(wear_items,"asset_dump: wear_item");
 	dumpItemArray(obj_items,"asset_dump: obj_item");
@@ -2408,6 +2463,69 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
 				<< " descendent_count " << cof->getDescendentCount()
 				<< " viewer desc count " << cof->getViewerDescendentCount() << LL_ENDL;
 	}
+	
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.2
+	// Update attachments to match those requested.
+	if (isAgentAvatarValid())
+	{
+		// Include attachments which should be in COF but don't have their link created yet
+		std::set<LLUUID> pendingAttachments;
+		if (LLAttachmentsMgr::instance().getPendingAttachments(pendingAttachments))
+		{
+			for (const LLUUID& idAttachItem : pendingAttachments)
+			{
+				if ( (!gAgentAvatarp->isWearingAttachment(idAttachItem)) || (isLinkedInCOF(idAttachItem)) )
+				{
+					LLAttachmentsMgr::instance().clearPendingAttachmentLink(idAttachItem);
+					continue;
+				}
+
+				LLViewerInventoryItem* pAttachItem = gInventory.getItem(idAttachItem);
+				if (pAttachItem)
+				{
+					obj_items.push_back(pAttachItem);
+				}
+			}
+		}
+
+		// (Start of LL code from LLWearableHoldingPattern::onAllComplete())
+		LL_DEBUGS("Avatar") << self_av_string() << "Updating " << obj_items.size() << " attachments" << LL_ENDL;
+
+		LLAgentWearables::llvo_vec_t objects_to_remove;
+		LLAgentWearables::llvo_vec_t objects_to_retain;
+		LLInventoryModel::item_array_t items_to_add;
+		LLAgentWearables::findAttachmentsAddRemoveInfo(obj_items, objects_to_remove, objects_to_retain, items_to_add);
+
+		// Here we remove the attachment pos overrides for *all*
+		// attachments, even those that are not being removed. This is
+		// needed to get joint positions all slammed down to their
+		// pre-attachment states.
+		gAgentAvatarp->clearAttachmentOverrides();
+		// (End of LL code)
+
+		// Take off the attachments that will no longer be in the outfit.
+		// (but don't remove attachments until avatar is fully loaded - should reduce random attaching/detaching/reattaching at log-on)
+		if (gAgentAvatarp->isFullyLoaded())
+		{
+			LL_DEBUGS("Avatar") << self_av_string() << "Removing " << objects_to_remove.size() << " attachments" << LL_ENDL;
+			LLAgentWearables::userRemoveMultipleAttachments(objects_to_remove);
+		}
+
+		// (Start of LL code from LLWearableHoldingPattern::onAllComplete())
+		// Restore attachment pos overrides for the attachments that are remaining in the outfit.
+		for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_retain.begin(); it != objects_to_retain.end(); ++it)
+		{
+			LLViewerObject *objectp = *it;
+			gAgentAvatarp->addAttachmentOverridesForObject(objectp);
+		}
+
+		// Add new attachments to match those requested.
+		LL_DEBUGS("Avatar") << self_av_string() << "Adding " << items_to_add.size() << " attachments" << LL_ENDL;
+		LLAgentWearables::userAttachMultipleAttachments(items_to_add);
+		// (End of LL code)
+	}
+// [/SL:KB]
+
 	if(!wear_items.size())
 	{
 		LLNotificationsUtil::add("CouldNotPutOnOutfit");
@@ -2422,7 +2540,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
 	LLTimer hp_block_timer;
 	LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
 
-	holder->setObjItems(obj_items);
+//	holder->setObjItems(obj_items);
 	holder->setGestItems(gest_items);
 		
 	// Note: can't do normal iteration, because if all the
@@ -2950,7 +3068,10 @@ private:
 	LLPointer<LLInventoryCallback> mCB;
 };
 
-void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb)
+//void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb)
+// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-05-02 (Catznip-3.7)
+void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb, bool immediate_delete)
+// [/SL:KB]
 {	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t item_array;
 	gInventory.collectDescendents(LLAppearanceMgr::getCOF(),
@@ -2962,7 +3083,17 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInve
 		const LLInventoryItem* item = item_array.at(i).get();
 		if (item->getIsLinkType() && item->getLinkedUUID() == item_id)
 		{
-			if (item->getType() == LLAssetType::AT_OBJECT)
+// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8)
+			if (rlv_handler_t::isEnabled())
+			{
+				RLV_ASSERT(rlvPredCanRemoveItem(item));
+			}
+// [/RLVa:KB]
+
+//			if (item->getType() == LLAssetType::AT_OBJECT)
+// [RLVa:KB] - Checked: 2013-02-12 (RLVa-1.4.8)
+			if (immediate_delete)
+// [/RLVa:KB]
 			{
 				// Immediate delete
 				remove_inventory_item(item->getUUID(), cb, true);
@@ -3870,14 +4001,23 @@ void LLAppearanceMgr::wearBaseOutfit()
 	updateCOF(base_outfit_id);
 }
 
-void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
+//void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
+void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, LLPointer<LLInventoryCallback> cb /*= NULL*/, bool immediate_delete /*= false*/)
+// [/SL:KB]
 {
 	if (ids_to_remove.empty())
 	{
 		LL_WARNS() << "called with empty list, nothing to do" << LL_ENDL;
 		return;
 	}
-	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
+//	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
+	if (!cb)
+	{
+		cb = new LLUpdateAppearanceOnDestroy;
+	}
+// [/SL:KB]
 	for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
 	{
 		const LLUUID& id_to_remove = *it;
@@ -3891,16 +4031,28 @@ void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
 		{
 		    continue;
 		}
-		removeCOFItemLinks(linked_item_id, cb);
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
+		removeCOFItemLinks(linked_item_id, cb, immediate_delete);
+// [/SL:KB]
+//		removeCOFItemLinks(linked_item_id, cb);
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
+		LLAttachmentsMgr::instance().clearPendingAttachmentLink(linked_item_id);
+// [/SL:KB]
 		addDoomedTempAttachment(linked_item_id);
 	}
 }
 
-void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
+//void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
+void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove, LLPointer<LLInventoryCallback> cb /*= NULL*/, bool immediate_delete /*= false*/)
+// [/SL:KB]
 {
 	uuid_vec_t ids_to_remove;
 	ids_to_remove.push_back(id_to_remove);
-	removeItemsFromAvatar(ids_to_remove);
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
+	removeItemsFromAvatar(ids_to_remove, cb, immediate_delete);
+// [/SL:KB]
+//	removeItemsFromAvatar(ids_to_remove);
 }
 
 
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index c274a8b04903e11cfdd7ec2a1801c5a66e4a43ce..7757b260797a09db6d469feca50c138be2509fef 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -147,6 +147,9 @@ public:
 	// Attachment link management
 	void unregisterAttachment(const LLUUID& item_id);
 	void registerAttachment(const LLUUID& item_id);
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
+	bool getAttachmentInvLinkEnable() { return mAttachmentInvLinkEnabled; }
+// [/SL:KB]
 	void setAttachmentInvLinkEnable(bool val);
 
 	// Add COF link to individual item.
@@ -158,7 +161,10 @@ public:
 	bool isLinkedInCOF(const LLUUID& item_id);
 
 	// Remove COF entries
-	void removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb = NULL);
+//	void removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb = NULL);
+// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-05-02 (Catznip-3.7)
+	void removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb = NULL, bool immediate_delete = false);
+// [/SL:KB]
 	void removeCOFLinksOfType(LLWearableType::EType type, LLPointer<LLInventoryCallback> cb = NULL);
 	void removeAllClothesFromAvatar();
 	void removeAllAttachmentsFromAvatar();
@@ -194,8 +200,15 @@ public:
 	bool updateBaseOutfit();
 
 	//Remove clothing or detach an object from the agent (a bodypart cannot be removed)
-	void removeItemsFromAvatar(const uuid_vec_t& item_ids);
-	void removeItemFromAvatar(const LLUUID& item_id);
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-05-05 (Catznip-3.7)
+	void removeItemFromAvatar(const LLUUID& id_to_remove) { removeItemFromAvatar(id_to_remove, NULL, false); }
+	void removeItemFromAvatar(const LLUUID& id_to_remove, LLPointer<LLInventoryCallback> cb /*= NULL*/, bool immediate_delete /*= false*/);
+
+	void removeItemsFromAvatar(const uuid_vec_t& ids_to_remove) { removeItemsFromAvatar(ids_to_remove, NULL, false); }
+	void removeItemsFromAvatar(const uuid_vec_t& ids_to_remove, LLPointer<LLInventoryCallback> cb /*= NULL*/, bool immediate_delete /*= false*/);
+// [/SL:KB]
+//	void removeItemsFromAvatar(const uuid_vec_t& item_ids);
+//	void removeItemFromAvatar(const LLUUID& item_id);
 
 
 	void onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel);
@@ -228,6 +241,9 @@ public:
 	static void onIdle(void *);
 	void requestServerAppearanceUpdate();
 
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-06-27 (Catznip-3.7)
+	void syncCofVersionAndRefresh();
+// [/SL:KB]
 	void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
 	std::string getAppearanceServiceURL() const;
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 9a78b5d52a4ebb31fa732633df703faf43c83e06..efac4681d2608aceba4fca653f7242eb3a6dfd53 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -92,6 +92,9 @@
 #include "llprogressview.h"
 #include "llvocache.h"
 #include "llvopartgroup.h"
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2013-02-12 (Catznip-3.4)
+#include "llappearancemgr.h"
+// [/SL:KB]
 #include "llweb.h"
 #include "llfloatertexturefetchdebugger.h"
 #include "llspellcheck.h"
@@ -5406,6 +5409,11 @@ void LLAppViewer::disconnectViewer()
 	// close inventory interface, close all windows
 	LLSidepanelInventory::cleanup();
 
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2013-02-12 (Catznip-3.4)
+	// Destroying all objects below will trigger attachment detaching code and attempt to remove the COF links for them
+	LLAppearanceMgr::instance().setAttachmentInvLinkEnable(false);
+// [/SL:KB]
+
 	gAgentWearables.cleanup();
 	gAgentCamera.cleanup();
 	// Also writes cached agent settings to gSavedSettings
diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp
index d3e66289d1a4f2b1efff1b5a01be693d53358ab3..61ce7cd6aac51d26aa9ad3f3ebc6881e0767363d 100644
--- a/indra/newview/llattachmentsmgr.cpp
+++ b/indra/newview/llattachmentsmgr.cpp
@@ -41,10 +41,31 @@ const F32 MAX_ATTACHMENT_REQUEST_LIFETIME = 30.0F;
 const F32 MIN_RETRY_REQUEST_TIME = 5.0F;
 const F32 MAX_BAD_COF_TIME = 30.0F;
 
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
+class LLRegisterAttachmentCallback : public LLRequestServerAppearanceUpdateOnDestroy
+{
+public:
+	LLRegisterAttachmentCallback()
+		: LLRequestServerAppearanceUpdateOnDestroy()
+	{
+	}
+
+	~LLRegisterAttachmentCallback() override
+	{
+	}
+
+	void fire(const LLUUID& idItem) override
+	{
+		LLAttachmentsMgr::instance().onRegisterAttachmentComplete(idItem);
+		LLRequestServerAppearanceUpdateOnDestroy::fire(idItem);
+	}
+};
+// [/SL:KB]
+
 LLAttachmentsMgr::LLAttachmentsMgr():
     mAttachmentRequests("attach",MIN_RETRY_REQUEST_TIME),
-    mDetachRequests("detach",MIN_RETRY_REQUEST_TIME),
-    mQuestionableCOFLinks("badcof",MAX_BAD_COF_TIME)
+    mDetachRequests("detach",MIN_RETRY_REQUEST_TIME)
+//  ,  mQuestionableCOFLinks("badcof",MAX_BAD_COF_TIME)
 {
 }
 
@@ -79,6 +100,11 @@ void LLAttachmentsMgr::addAttachmentRequest(const LLUUID& item_id,
 
 void LLAttachmentsMgr::onAttachmentRequested(const LLUUID& item_id)
 {
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
+	if (item_id.isNull())
+		return;
+// [/SL:KB]
+
 	LLViewerInventoryItem *item = gInventory.getItem(item_id);
 	LL_DEBUGS("Avatar") << "ATT attachment was requested "
 						<< (item ? item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
@@ -112,7 +138,7 @@ void LLAttachmentsMgr::onIdle()
 
     expireOldDetachRequests();
 
-    checkInvalidCOFLinks();
+//    checkInvalidCOFLinks();
     
     spamStatusInfo();
 }
@@ -221,6 +247,13 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
 {
     if (mRecentlyArrivedAttachments.size())
     {
+ // [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
+		if (!LLAppearanceMgr::instance().getAttachmentInvLinkEnable())
+		{
+			return;
+		}
+// [/SL:KB]
+
         // One or more attachments have arrived but have not yet been
         // processed for COF links
         if (mAttachmentRequests.empty())
@@ -259,17 +292,63 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
         }
         if (ids_to_link.size())
         {
-            LLPointer<LLInventoryCallback> cb = new LLRequestServerAppearanceUpdateOnDestroy();
-            for (uuid_vec_t::const_iterator uuid_it = ids_to_link.begin();
-                 uuid_it != ids_to_link.end(); ++uuid_it)
-            {
-                LLAppearanceMgr::instance().addCOFItemLink(*uuid_it, cb);
-            }
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-3.7
+			LLPointer<LLInventoryCallback> cb = new LLRegisterAttachmentCallback();
+			for (const LLUUID& idAttach : ids_to_link)
+			{
+				if (std::find(mPendingAttachLinks.begin(), mPendingAttachLinks.end(), idAttach) == mPendingAttachLinks.end())
+				{
+					LLAppearanceMgr::instance().addCOFItemLink(idAttach, cb);
+					mPendingAttachLinks.insert(idAttach);
+				}
+			}
+// [/SL:KB]
+//            LLPointer<LLInventoryCallback> cb = new LLRequestServerAppearanceUpdateOnDestroy();
+//            for (uuid_vec_t::const_iterator uuid_it = ids_to_link.begin();
+//                 uuid_it != ids_to_link.end(); ++uuid_it)
+//            {
+//                LLAppearanceMgr::instance().addCOFItemLink(*uuid_it, cb);
+//            }
         }
         mRecentlyArrivedAttachments.clear();
     }
 }
 
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.2
+bool LLAttachmentsMgr::getPendingAttachments(std::set<LLUUID>& ids) const
+{
+	ids.clear();
+
+	// Returns the union of the LL maintained list of attachments that are waiting for link creation and our maintained list of attachments that are pending link creation
+	set_union(mRecentlyArrivedAttachments.begin(), mRecentlyArrivedAttachments.end(), mPendingAttachLinks.begin(), mPendingAttachLinks.end(), std::inserter(ids, ids.begin()));
+
+	return !ids.empty();
+}
+
+void LLAttachmentsMgr::clearPendingAttachmentLink(const LLUUID& idItem)
+{
+	mPendingAttachLinks.erase(idItem);
+}
+
+void LLAttachmentsMgr::onRegisterAttachmentComplete(const LLUUID& idAttachLink)
+{
+	const LLViewerInventoryItem* pAttachLink = gInventory.getItem(idAttachLink);
+	if (!pAttachLink)
+		return;
+
+	const LLUUID& idAttachBase = pAttachLink->getLinkedUUID();
+
+	// Remove the attachment from the pending list
+	clearPendingAttachmentLink(idAttachBase);
+
+	// It may have been detached already in which case we should remove the COF link
+	if ( (isAgentAvatarValid()) && (!gAgentAvatarp->isWearingAttachment(idAttachBase)) )
+	{
+		LLAppearanceMgr::instance().removeCOFItemLinks(idAttachBase, NULL, true);
+	}
+}
+// [/SL:KB]
+
 LLAttachmentsMgr::LLItemRequestTimes::LLItemRequestTimes(const std::string& op_name, F32 timeout):
     mOpName(op_name),
     mTimeout(timeout)
@@ -398,6 +477,11 @@ void LLAttachmentsMgr::onDetachRequested(const LLUUID& inv_item_id)
 
 void LLAttachmentsMgr::onDetachCompleted(const LLUUID& inv_item_id)
 {
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.2
+	// (mRecentlyArrivedAttachments doesn't need pruning since it'll check the attachment is actually worn before linking)
+	clearPendingAttachmentLink(inv_item_id);
+// [/SL:KB]
+
     LLTimer timer;
     LLInventoryItem *item = gInventory.getItem(inv_item_id);
     if (mDetachRequests.getTime(inv_item_id, timer))
@@ -416,18 +500,25 @@ void LLAttachmentsMgr::onDetachCompleted(const LLUUID& inv_item_id)
                    << (item ? item->getName() : "UNKNOWN") << " id " << inv_item_id << LL_ENDL;
     }
 
-    LL_DEBUGS("Avatar") << "ATT detached item flagging as questionable for COF link checking "
-                        << (item ? item->getName() : "UNKNOWN") << " id " << inv_item_id << LL_ENDL;
-    mQuestionableCOFLinks.addTime(inv_item_id);
+//    LL_DEBUGS("Avatar") << "ATT detached item flagging as questionable for COF link checking "
+//                        << (item ? item->getName() : "UNKNOWN") << " id " << inv_item_id << LL_ENDL;
+//    mQuestionableCOFLinks.addTime(inv_item_id);
 }
 
 bool LLAttachmentsMgr::isAttachmentStateComplete() const
 {
-    return  mPendingAttachments.empty()
-        && mAttachmentRequests.empty()
-        && mDetachRequests.empty()
-        && mRecentlyArrivedAttachments.empty()
-        && mQuestionableCOFLinks.empty();
+// [SL:KB] - Patch: Appearance-Misc | Checked: Catznip-4.3
+	return  mPendingAttachments.empty()
+		&& mAttachmentRequests.empty()
+		&& mDetachRequests.empty()
+		&& mRecentlyArrivedAttachments.empty()
+		&& mPendingAttachLinks.empty();
+// [/SL:KB]
+//    return  mPendingAttachments.empty()
+//        && mAttachmentRequests.empty()
+//        && mDetachRequests.empty()
+//        && mRecentlyArrivedAttachments.empty()
+//        && mQuestionableCOFLinks.empty();
 }
 
 // Check for attachments that are (a) linked in COF and (b) not
@@ -450,54 +541,54 @@ bool LLAttachmentsMgr::isAttachmentStateComplete() const
 //
 // See related: MAINT-5070, MAINT-4409
 //
-void LLAttachmentsMgr::checkInvalidCOFLinks()
-{
-        LLInventoryModel::cat_array_t cat_array;
-        LLInventoryModel::item_array_t item_array;
-        gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
-                                      cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
-        for (S32 i=0; i<item_array.size(); i++)
-        {
-            const LLViewerInventoryItem* inv_item = item_array.at(i).get();
-            const LLUUID& item_id = inv_item->getLinkedUUID();
-            if (inv_item->getType() == LLAssetType::AT_OBJECT)
-            {
-                LLTimer timer;
-                bool is_flagged_questionable = mQuestionableCOFLinks.getTime(item_id,timer);
-                bool is_wearing_attachment = isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item_id);
-                if (is_wearing_attachment && is_flagged_questionable)
-                {
-                    LL_DEBUGS("Avatar") << "ATT was flagged questionable but is now " 
-                                        << (is_wearing_attachment ? "attached " : "") 
-                                        <<"removing flag after "
-                                        << timer.getElapsedTimeF32() << " item "
-                                        << inv_item->getName() << " id " << item_id << LL_ENDL;
-                    mQuestionableCOFLinks.removeTime(item_id);
-                }
-            }
-        }
-
-        for(LLItemRequestTimes::iterator it = mQuestionableCOFLinks.begin();
-            it != mQuestionableCOFLinks.end(); )
-        {
-            LLItemRequestTimes::iterator curr_it = it;
-            ++it;
-            const LLUUID& item_id = curr_it->first;
-            LLViewerInventoryItem *inv_item = gInventory.getItem(item_id);
-            if (curr_it->second.getElapsedTimeF32() > MAX_BAD_COF_TIME)
-            {
-                if (LLAppearanceMgr::instance().isLinkedInCOF(item_id))
-                {
-                    LL_DEBUGS("Avatar") << "ATT Linked in COF but not attached or requested, deleting link after "
-                                        << curr_it->second.getElapsedTimeF32() << " seconds for " 
-                                        << (inv_item ? inv_item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
-                    LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
-                }
-				mQuestionableCOFLinks.erase(curr_it);
-                continue;
-            }
-        }
-}
+//void LLAttachmentsMgr::checkInvalidCOFLinks()
+//{
+//        LLInventoryModel::cat_array_t cat_array;
+//        LLInventoryModel::item_array_t item_array;
+//        gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
+//                                      cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
+//        for (S32 i=0; i<item_array.size(); i++)
+//        {
+//            const LLViewerInventoryItem* inv_item = item_array.at(i).get();
+//            const LLUUID& item_id = inv_item->getLinkedUUID();
+//            if (inv_item->getType() == LLAssetType::AT_OBJECT)
+//            {
+//                LLTimer timer;
+//                bool is_flagged_questionable = mQuestionableCOFLinks.getTime(item_id,timer);
+//                bool is_wearing_attachment = isAgentAvatarValid() && gAgentAvatarp->isWearingAttachment(item_id);
+//                if (is_wearing_attachment && is_flagged_questionable)
+//                {
+//                    LL_DEBUGS("Avatar") << "ATT was flagged questionable but is now " 
+//                                        << (is_wearing_attachment ? "attached " : "") 
+//                                        <<"removing flag after "
+//                                        << timer.getElapsedTimeF32() << " item "
+//                                        << inv_item->getName() << " id " << item_id << LL_ENDL;
+//                    mQuestionableCOFLinks.removeTime(item_id);
+//                }
+//            }
+//        }
+//
+//        for(LLItemRequestTimes::iterator it = mQuestionableCOFLinks.begin();
+//            it != mQuestionableCOFLinks.end(); )
+//        {
+//            LLItemRequestTimes::iterator curr_it = it;
+//            ++it;
+//            const LLUUID& item_id = curr_it->first;
+//            LLViewerInventoryItem *inv_item = gInventory.getItem(item_id);
+//            if (curr_it->second.getElapsedTimeF32() > MAX_BAD_COF_TIME)
+//            {
+//                if (LLAppearanceMgr::instance().isLinkedInCOF(item_id))
+//                {
+//                    LL_DEBUGS("Avatar") << "ATT Linked in COF but not attached or requested, deleting link after "
+//                                        << curr_it->second.getElapsedTimeF32() << " seconds for " 
+//                                        << (inv_item ? inv_item->getName() : "UNKNOWN") << " id " << item_id << LL_ENDL;
+//                    LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
+//                }
+//				mQuestionableCOFLinks.erase(curr_it);
+//                continue;
+//            }
+//        }
+//}
 
 void LLAttachmentsMgr::spamStatusInfo()
 {
@@ -528,3 +619,28 @@ void LLAttachmentsMgr::spamStatusInfo()
     }
 #endif
 }
+
+// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
+void LLAttachmentsMgr::refreshAttachments()
+{
+	if (!isAgentAvatarValid())
+		return;
+
+	for (const auto& kvpAttachPt : gAgentAvatarp->mAttachmentPoints)
+	{
+		for (const LLViewerObject* pAttachObj : kvpAttachPt.second->mAttachedObjects)
+		{
+			const LLUUID& idItem = pAttachObj->getAttachmentItemID();
+			if ( (mAttachmentRequests.wasRequestedRecently(idItem)) || (pAttachObj->isTempAttachment()) )
+				continue;
+
+			AttachmentsInfo attachment;
+			attachment.mItemID = idItem;
+			attachment.mAttachmentPt = kvpAttachPt.first;
+			attachment.mAdd = true;
+			mPendingAttachments.push_back(attachment);
+			mAttachmentRequests.addTime(idItem);
+		}
+	}
+}
+// [/SL:KB]
diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h
index a4ef762e8b1b07a02efb185426c766b31739cfd1..d7ecc34aafe0eb626554271a3933c58ccb60e259 100644
--- a/indra/newview/llattachmentsmgr.h
+++ b/indra/newview/llattachmentsmgr.h
@@ -89,6 +89,16 @@ public:
 
     bool isAttachmentStateComplete() const;
 
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.1
+public:
+	void clearPendingAttachmentLink(const LLUUID& idItem);
+	bool getPendingAttachments(std::set<LLUUID>& ids) const;
+	void refreshAttachments();
+protected:
+	void onRegisterAttachmentComplete(const LLUUID& idAttachLink);
+	friend class LLRegisterAttachmentCallback;
+// [/SL:KB]
+
 private:
 
     class LLItemRequestTimes: public std::map<LLUUID,LLTimer>
@@ -111,7 +121,7 @@ private:
 	void linkRecentlyArrivedAttachments();
     void expireOldAttachmentRequests();
     void expireOldDetachRequests();
-    void checkInvalidCOFLinks();
+//    void checkInvalidCOFLinks();
     void spamStatusInfo();
 
     // Attachments that we are planning to rez but haven't requested from the server yet.
@@ -127,8 +137,13 @@ private:
     std::set<LLUUID> mRecentlyArrivedAttachments;
     LLTimer mCOFLinkBatchTimer;
 
-    // Attachments that are linked in the COF but may be invalid.
-	LLItemRequestTimes mQuestionableCOFLinks;
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.1
+	// Attachments that have pending link creation
+	std::set<LLUUID> mPendingAttachLinks;
+// [/SL:KB]
+
+//    // Attachments that are linked in the COF but may be invalid.
+//	LLItemRequestTimes mQuestionableCOFLinks;
 };
 
 #endif
diff --git a/indra/newview/llhttpretrypolicy.cpp b/indra/newview/llhttpretrypolicy.cpp
index 6a2daeeb90882b1e683668d0749022beb111d44f..30e5519ac5144d90ecb43cbe1f443554c333dbec 100644
--- a/indra/newview/llhttpretrypolicy.cpp
+++ b/indra/newview/llhttpretrypolicy.cpp
@@ -64,6 +64,15 @@ void LLAdaptiveRetryPolicy::reset()
 	init();
 }
 
+// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-06-27 (Catznip-3.7)
+// virtual
+void LLAdaptiveRetryPolicy::cancelRetry()
+{
+	// This relies on the current implementation where mShouldRetry is set to true only on initialization
+	mShouldRetry = false;
+}
+// [/SL:KB]
+
 bool LLAdaptiveRetryPolicy::getRetryAfter(const LLSD& headers, F32& retry_header_time)
 {
 	return (headers.has(HTTP_IN_HEADER_RETRY_AFTER)
diff --git a/indra/newview/llhttpretrypolicy.h b/indra/newview/llhttpretrypolicy.h
index af07b4afecbfc5065b8a3f9fabdd5788f29f5d1a..d71e114c5ddc90edfff66ffb3befa6f5317f82ec 100644
--- a/indra/newview/llhttpretrypolicy.h
+++ b/indra/newview/llhttpretrypolicy.h
@@ -55,6 +55,9 @@ public:
 	virtual bool shouldRetry(F32& seconds_to_wait) const = 0;
 
 	virtual void reset() = 0;
+// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-06-27 (Catznip-3.7)
+	virtual void cancelRetry() = 0;
+// [/SL:KB]
 };
 
 // Very general policy with geometric back-off after failures,
@@ -68,6 +71,9 @@ public:
 	void onSuccess();
 
 	void reset();
+// [SL:KB] - Patch: Appearance-AISFilter | Checked: 2015-06-27 (Catznip-3.7)
+	/*virtual*/ void cancelRetry();
+// [/SL:KB]
 	
 	// virtual
 	void onFailure(S32 status, const LLSD& headers);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 3acfaeb04973d8042a0bc6944a02c267871ec3c8..c8b7914ced9c06740c0bd9178bd1c5ceb828cc79 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -4165,6 +4165,9 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 	const bool is_system_folder = LLFolderType::lookupIsProtectedType(type);
 	// BAP change once we're no longer treating regular categories as ensembles.
 	const bool is_agent_inventory = isAgentInventory();
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-11-24 (Catznip-2.4)
+	const bool is_outfit = (type == LLFolderType::FT_OUTFIT);
+// [/SL:KB]
 
 	// Only enable calling-card related options for non-system folders.
 	if (!is_system_folder && is_agent_inventory)
@@ -4216,7 +4219,11 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 					disabled_items.push_back(std::string("Remove From Outfit"));
 			}
 		}
-		if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
+//		if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-11-24 (Catznip-2.4)
+		if ( ((is_outfit) && (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))) || 
+			 ((!is_outfit) && (gAgentWearables.isCOFChangeInProgress())) )
+// [/SL:KB]
 		{
 			disabled_items.push_back(std::string("Replace Outfit"));
 		}
@@ -6188,7 +6195,11 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
 		else if(item && item->isFinished())
 		{
 			// must be in library. copy it to our inventory and put it on.
-			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
+//			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
+// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2013-02-04 (Catznip-3.4)
+			// "Wear" from inventory replaces, so library items should too
+			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0, true));
+// [/SL;KB]
 			copy_inventory_item(
 				gAgent.getID(),
 				item->getPermissions().getOwner(),
@@ -6689,56 +6700,56 @@ void LLWearableBridge::wearAddOnAvatar()
 }
 
 // static
-void LLWearableBridge::onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
-{
-	LLUUID* item_id = (LLUUID*) userdata;
-	if(wearable)
-	{
-		LLViewerInventoryItem* item = NULL;
-		item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
-		if(item)
-		{
-			if(item->getAssetUUID() == wearable->getAssetID())
-			{
-				gAgentWearables.setWearableItem(item, wearable);
-				gInventory.notifyObservers();
-				//self->getFolderItem()->refreshFromRoot();
-			}
-			else
-			{
-				LL_INFOS() << "By the time wearable asset arrived, its inv item already pointed to a different asset." << LL_ENDL;
-			}
-		}
-	}
-	delete item_id;
-}
+//void LLWearableBridge::onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
+//{
+//	LLUUID* item_id = (LLUUID*) userdata;
+//	if(wearable)
+//	{
+//		LLViewerInventoryItem* item = NULL;
+//		item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
+//		if(item)
+//		{
+//			if(item->getAssetUUID() == wearable->getAssetID())
+//			{
+//				gAgentWearables.setWearableItem(item, wearable);
+//				gInventory.notifyObservers();
+//				//self->getFolderItem()->refreshFromRoot();
+//			}
+//			else
+//			{
+//				LL_INFOS() << "By the time wearable asset arrived, its inv item already pointed to a different asset." << LL_ENDL;
+//			}
+//		}
+//	}
+//	delete item_id;
+//}
 
 // static
 // BAP remove the "add" code path once everything is fully COF-ified.
-void LLWearableBridge::onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
-{
-	LLUUID* item_id = (LLUUID*) userdata;
-	if(wearable)
-	{
-		LLViewerInventoryItem* item = NULL;
-		item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
-		if(item)
-		{
-			if(item->getAssetUUID() == wearable->getAssetID())
-			{
-				bool do_append = true;
-				gAgentWearables.setWearableItem(item, wearable, do_append);
-				gInventory.notifyObservers();
-				//self->getFolderItem()->refreshFromRoot();
-			}
-			else
-			{
-				LL_INFOS() << "By the time wearable asset arrived, its inv item already pointed to a different asset." << LL_ENDL;
-			}
-		}
-	}
-	delete item_id;
-}
+//void LLWearableBridge::onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
+//{
+//	LLUUID* item_id = (LLUUID*) userdata;
+//	if(wearable)
+//	{
+//		LLViewerInventoryItem* item = NULL;
+//		item = (LLViewerInventoryItem*)gInventory.getItem(*item_id);
+//		if(item)
+//		{
+//			if(item->getAssetUUID() == wearable->getAssetID())
+//			{
+//				bool do_append = true;
+//				gAgentWearables.setWearableItem(item, wearable, do_append);
+//				gInventory.notifyObservers();
+//				//self->getFolderItem()->refreshFromRoot();
+//			}
+//			else
+//			{
+//				LL_INFOS() << "By the time wearable asset arrived, its inv item already pointed to a different asset." << LL_ENDL;
+//			}
+//		}
+//	}
+//	delete item_id;
+//}
 
 // static
 BOOL LLWearableBridge::canEditOnAvatar(void* user_data)
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index fd5c0433b1d3682d2d64abc92122fbeb10a76bcb..67bfad54fe46dad06aa5032c377050e8aa30c720 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -544,10 +544,10 @@ public:
 
 	static void		onWearOnAvatar( void* userdata );	// Access to wearOnAvatar() from menu
 	static BOOL		canWearOnAvatar( void* userdata );
-	static void		onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
+//	static void		onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
 	void			wearOnAvatar();
 
-	static void		onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
+//	static void		onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
 	void			wearAddOnAvatar();
 
 	static BOOL		canEditOnAvatar( void* userdata );	// Access to editOnAvatar() from menu
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index e056ccebee5b8753e4fb4bf97c923fb0832c4d8b..b0434af63d12c24ae0f108aa7b30d8c41941dd84 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -520,10 +520,11 @@ BOOL get_is_item_worn(const LLUUID& id)
 		return FALSE;
 
 	// Consider the item as worn if it has links in COF.
-	if (LLAppearanceMgr::instance().isLinkedInCOF(id))
-	{
-		return TRUE;
-	}
+// [SL:KB] - The code below causes problems across the board so it really just needs to go
+//	if (LLAppearanceMgr::instance().isLinkedInCOF(id))
+//	{
+//		return TRUE;
+//	}
 
 	switch(item->getType())
 	{
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index c44aca6fa500ad3c0b9031fd9cff1169a7f816c6..6b967cb9f05c43e372fdb0012e4c4418a81e1dd4 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -2491,7 +2491,7 @@ void LLSelectMgr::logNoOp(LLSelectNode* node, void *)
 // static
 void LLSelectMgr::logAttachmentRequest(LLSelectNode* node, void *)
 {
-    LLAttachmentsMgr::instance().onAttachmentRequested(node->mItemID);
+//    LLAttachmentsMgr::instance().onAttachmentRequested(node->mItemID);
 }
 
 // static
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index bd68d8c999ab0951e71601fb211e0efb128517d4..b4f2581e4205a2bae41c16b5b148d625a36761b1 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1737,7 +1737,11 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
 	{
 		if(mSource == SOURCE_LIBRARY)
 		{
-			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
+//			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
+// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-2.2)
+			// Make this behave consistent with dad3dWearItem
+			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0, !(mask & MASK_CONTROL)));
+// [/SL:KB]
 			copy_inventory_item(
 				gAgent.getID(),
 				item->getPermissions().getOwner(),
@@ -1748,7 +1752,11 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
 		}
 		else
 		{
-			rez_attachment(item, 0);
+// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-2.2)
+			// Make this behave consistent with dad3dWearItem
+			rez_attachment(item, 0, !(mask & MASK_CONTROL));
+// [/SL:KB]
+//			rez_attachment(item, 0);
 		}
 	}
 	return ACCEPT_YES_SINGLE;
diff --git a/indra/newview/llviewerattachmenu.cpp b/indra/newview/llviewerattachmenu.cpp
index 3975292ed3a6e7871384b9d21cebbfbf39876008..2d015fc8c1f4b681708ba1828a67e6ea1705ddb2 100644
--- a/indra/newview/llviewerattachmenu.cpp
+++ b/indra/newview/llviewerattachmenu.cpp
@@ -121,7 +121,10 @@ void LLViewerAttachMenu::attachObjects(const uuid_vec_t& items, const std::strin
 		else if(item && item->isFinished())
 		{
 			// must be in library. copy it to our inventory and put it on.
-			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp));
+//			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp));
+// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2013-02-04 (Catznip-3.4)
+			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp, false));
+// [/SL;KB]
 			copy_inventory_item(gAgent.getID(),
 								item->getPermissions().getOwner(),
 								item->getUUID(),
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 1ab7ec0156d56b42020e622c245f45ec96978453..360223b765e3359c6803d72418c5b889ed6fcf00 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -997,7 +997,10 @@ void LLInventoryCallbackManager::fire(U32 callback_id, const LLUUID& item_id)
 	}
 }
 
-void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp)
+//void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp)
+// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.4)
+void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp, bool replace)
+// [/SL:KB]
 {
 	if (inv_item.isNull())
 		return;
@@ -1005,7 +1008,10 @@ void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachme
 	LLViewerInventoryItem *item = gInventory.getItem(inv_item);
 	if (item)
 	{
-		rez_attachment(item, attachmentp);
+// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.4)
+		rez_attachment(item, attachmentp, replace);
+// [/SL:KB]
+//		rez_attachment(item, attachmentp);
 	}
 }
 
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index b3053e365bd2ce49a052338b9947b8636486bbe7..4ebb885cb918d3e01db8cafda5e4e425cc2469f6 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -253,7 +253,10 @@ public:
 
 class LLViewerJointAttachment;
 
-void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp);
+// [SL:KB] - Patch: Appearance-DnDWear | Checked: 2010-09-28 (Catznip-3.4)
+void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp, bool replace);
+// [/SL:KB]
+//void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp);
 
 void activate_gesture_cb(const LLUUID& inv_item);
 
diff --git a/indra/newview/llviewerjointattachment.cpp b/indra/newview/llviewerjointattachment.cpp
index 66e392ac424075f3ac3e3cb3d89705333073fef5..65fb661cd229ca5418e1bb7116b22af630300d4e 100644
--- a/indra/newview/llviewerjointattachment.cpp
+++ b/indra/newview/llviewerjointattachment.cpp
@@ -28,6 +28,9 @@
 
 #include "llviewerjointattachment.h"
 
+// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
+#include "llagent.h"
+// [/SL:KB]
 #include "llviewercontrol.h"
 #include "lldrawable.h"
 #include "llgl.h"
@@ -166,7 +169,7 @@ void LLViewerJointAttachment::setupDrawable(LLViewerObject *object)
 //-----------------------------------------------------------------------------
 BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
 {
-	object->extractAttachmentItemID();
+//	object->extractAttachmentItemID();
 
 	// Same object reattached
 	if (isObjectAttached(object))
@@ -177,17 +180,39 @@ BOOL LLViewerJointAttachment::addObject(LLViewerObject* object)
 		// re-connect object to the joint correctly
 	}
 	
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2011-01-13 (Catznip-2.4)
+	// LLViewerJointAttachment::removeObject() sets the object's item to the NULL UUID so we need to extract it *after* the block above
+	object->extractAttachmentItemID();
+// [/SL:KB]
+
 	// Two instances of the same inventory item attached --
 	// Request detach, and kill the object in the meantime.
-	if (getAttachedObject(object->getAttachmentItemID()))
+// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
+	if (LLViewerObject* pAttachObj = getAttachedObject(object->getAttachmentItemID()))
 	{
 		LL_INFOS() << "(same object re-attached)" << LL_ENDL;
-		object->markDead();
-
-		// If this happens to be attached to self, then detach.
-		LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID());
-		return FALSE;
-	}
+		pAttachObj->markDead();
+		if (pAttachObj->permYouOwner())
+		{
+			gMessageSystem->newMessage("ObjectDetach");
+			gMessageSystem->nextBlockFast(_PREHASH_AgentData);
+			gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+			gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
+			gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, pAttachObj->getLocalID());
+			gMessageSystem->sendReliable(gAgent.getRegionHost());
+		}
+ 	}
+// [/SL:KB]
+//	if (getAttachedObject(object->getAttachmentItemID()))
+//	{
+//		LL_INFOS() << "(same object re-attached)" << LL_ENDL;
+//		object->markDead();
+//
+//		// If this happens to be attached to self, then detach.
+//		LLVOAvatarSelf::detachAttachmentIntoInventory(object->getAttachmentItemID());
+//		return FALSE;
+//	}
 
 	mAttachedObjects.push_back(object);
 	setupDrawable(object);
@@ -442,7 +467,10 @@ const LLViewerObject *LLViewerJointAttachment::getAttachedObject(const LLUUID &o
 		 ++iter)
 	{
 		const LLViewerObject* attached_object = (*iter);
-		if (attached_object->getAttachmentItemID() == object_id)
+//		if (attached_object->getAttachmentItemID() == object_id)
+// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
+		if ( (attached_object->getAttachmentItemID() == object_id) && (!attached_object->isDead()) )
+// [/SL:KB]
 		{
 			return attached_object;
 		}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 5bbf5650ad20d6d27fb9983cd88013ce986671c3..baab574e38a8764e0e92747a802e9efc3b4022b3 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -49,6 +49,9 @@
 #include "llagentui.h"
 #include "llagentwearables.h"
 #include "llagentpilot.h"
+// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
+#include "llattachmentsmgr.h"
+// [/SL:KB]
 #include "llcompilequeue.h"
 #include "llconsole.h"
 #include "lldaycyclemanager.h"
@@ -1930,6 +1933,15 @@ class LLAdvancedRebakeTextures : public view_listener_t
 };
 	
 	
+// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
+void handle_refresh_attachments()
+{
+	if (isAgentAvatarValid())
+		gAgentAvatarp->rebuildAttachments();
+	LLAttachmentsMgr::instance().refreshAttachments();
+}
+// [/SL:KB]
+
 #if 1 //ndef LL_RELEASE_FOR_DOWNLOAD
 ///////////////////////////
 // DEBUG AVATAR TEXTURES //
@@ -4062,6 +4074,13 @@ void handle_reset_view()
 	gAgentCamera.switchCameraPreset(CAMERA_PRESET_REAR_VIEW);
 	reset_view_final( TRUE );
 	LLFloaterCamera::resetCameraMode();
+
+// [SL:KB] - Patch: Appearance-RefreshAttachments | Checked: Catznip-5.3
+	if (isAgentAvatarValid())
+	{
+		gAgentAvatarp->rebuildAttachments();
+	}
+// [/SL:KB]
 }
 
 class LLViewResetView : public view_listener_t
@@ -6054,6 +6073,9 @@ class LLAvatarResetSkeleton: public view_listener_t
 		if(avatar)
         {
             avatar->resetSkeleton(false);
+// [SL:KB] - Patch: Appearance-RefreshAttachments | Checked: Catznip-5.3
+			avatar->rebuildAttachments();
+// [/SL:KB]
         }
         return true;
     }
@@ -6067,6 +6089,9 @@ class LLAvatarResetSkeletonAndAnimations : public view_listener_t
 		if (avatar)
 		{
 			avatar->resetSkeleton(true);
+// [SL:KB] - Patch: Appearance-RefreshAttachments | Checked: Catznip-5.3
+			avatar->rebuildAttachments();
+// [/SL:KB]
 		}
 		return true;
 	}
@@ -8038,6 +8063,9 @@ void handle_rebake_textures(void*)
 	gAgentAvatarp->forceBakeAllTextures(slam_for_debug);
 	if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
 	{
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2015-06-27 (Catznip-3.7)
+//		LLAppearanceMgr::instance().syncCofVersionAndRefresh();
+// [/SL:KB]
 		LLAppearanceMgr::instance().requestServerAppearanceUpdate();
 	}
 }
@@ -8985,6 +9013,9 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLAdvancedCheckDebugCharacterVis(), "Advanced.CheckDebugCharacterVis");
 	view_listener_t::addMenu(new LLAdvancedDumpAttachments(), "Advanced.DumpAttachments");
 	view_listener_t::addMenu(new LLAdvancedRebakeTextures(), "Advanced.RebakeTextures");
+// [SL:KB] - Patch: Appearance-PhantomAttach | Checked: Catznip-5.0
+	commit.add("Advanced.RefreshAttachments", boost::bind(&handle_refresh_attachments));
+// [/SL:KB]
 	view_listener_t::addMenu(new LLAdvancedDebugAvatarTextures(), "Advanced.DebugAvatarTextures");
 	view_listener_t::addMenu(new LLAdvancedDumpAvatarLocalTextures(), "Advanced.DumpAvatarLocalTextures");
 	// Advanced > Network
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index eae8f2cc563562d219a6bbd6e9ace6f7410be22e..ea97c3afb4b1130de92ac585e2a9d479a929a613 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -6824,6 +6824,27 @@ LLViewerObject *	LLVOAvatar::findAttachmentByID( const LLUUID & target_id ) cons
 	return NULL;
 }
 
+// [SL:KB] - Patch: Appearance-RefreshAttachments | Checked: Catznip-5.3
+void LLVOAvatar::rebuildAttachments()
+{
+	for (const auto& kvpAttachPt : mAttachmentPoints)
+	{
+		for (LLViewerObject* pAttachObj : kvpAttachPt.second->mAttachedObjects)
+		{
+			if (LLVOVolume* pAttachVol = (pAttachObj->isMesh()) ? dynamic_cast<LLVOVolume*>(pAttachObj) : nullptr)
+			{
+				pAttachVol->forceLOD(3);
+				for (LLViewerObject* pChildObj : pAttachObj->getChildren())
+				{
+					if (LLVOVolume* pChildVol = (pChildObj->isMesh()) ? dynamic_cast<LLVOVolume*>(pChildObj) : nullptr)
+						pAttachVol->forceLOD(3);
+				}
+			}
+		}
+	}
+}
+// [/SL:KB]
+
 // virtual
 void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset)
 {
@@ -7140,7 +7161,11 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
 
 BOOL LLVOAvatar::isFullyLoaded() const
 {
-	return (mRenderUnloadedAvatar || mFullyLoaded);
+// [SL:KB] - Patch: Appearance-SyncAttach | Checked: Catznip-2.2
+	// Changes to LLAppearanceMgr::updateAppearanceFromCOF() expect this function to actually return mFullyLoaded for gAgentAvatarp
+	return (mRenderUnloadedAvatar && !isSelf()) ||(mFullyLoaded);
+// [/SL:KB]
+//	return (mRenderUnloadedAvatar || mFullyLoaded);
 }
 
 bool LLVOAvatar::isTooComplex() const
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index bd89d4ef23ab7b8bd2cad23d0a5546418deb6dc8..080eb1c380d17701655436f3aceaa1dd904557b6 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -739,6 +739,9 @@ public:
 	static LLVOAvatar*  findAvatarFromAttachment(LLViewerObject* obj);
 	/*virtual*/ BOOL	isWearingWearableType(LLWearableType::EType type ) const;
 	LLViewerObject *	findAttachmentByID( const LLUUID & target_id ) const;
+// [SL:KB] - Patch: Appearance-RefreshAttachments | Checked: Catznip-5.3
+	void				rebuildAttachments();
+// [/SL:KB]
 
 protected:
 	LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 7b4d8ef3299318bc0e2b043f7b7d340aa8a58fb9..63b1ae5b2f6587e6b33a182cb8ab4d32a0593bae 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3696,6 +3696,20 @@ U32 LLVOVolume::getHighLODTriangleCount()
 	return ret;
 }
 
+// [FS:Beq] - Patch: Appearance-RebuildAttachments | Checked: Catznip-5.3
+void LLVOVolume::forceLOD(S32 lod)
+{
+// [SL:KB] - Patch: Appearance-RebuildAttachments | Checked: Catznip-5.3
+	if (mDrawable.isNull())
+		return;
+// [/SL:KB]
+
+	mLOD = lod;
+	gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_VOLUME, FALSE);
+	mLODChanged = true;
+}
+// [/FS]
+
 //static
 void LLVOVolume::preUpdateGeom()
 {
diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h
index a3319083200be4300e5abebf5201bdeaa2d30dac..dcef1af51a0c8397b17c0d4ea42d2be5f99bdb89 100644
--- a/indra/newview/llvovolume.h
+++ b/indra/newview/llvovolume.h
@@ -154,6 +154,9 @@ public:
 				LLVector3 volumeDirectionToAgent(const LLVector3& dir) const;
 
 				
+// [FS:Beq] - Patch: Appearance-RebuildAttachments | Checked: Catznip-5.3
+				void    forceLOD(S32 lod);
+// [/FS]
 				BOOL	getVolumeChanged() const				{ return mVolumeChanged; }
 				
 	/*virtual*/ F32  	getRadius() const						{ return mVObjRadius; };
diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp
index b61fbbd07304cad9739741cb24d7698389f5b0ef..10e25bb86b3600c447ff9a3709b5f2e120f1f256 100644
--- a/indra/newview/llwearablelist.cpp
+++ b/indra/newview/llwearablelist.cpp
@@ -99,7 +99,23 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 {
 	BOOL isNewWearable = FALSE;
 	LLWearableArrivedData* data = (LLWearableArrivedData*) userdata;
-	LLViewerWearable* wearable = NULL; // NULL indicates failure
+//	LLViewerWearable* wearable = NULL; // NULL indicates failure
+// [SL:KB] - Patch: Appearance-Misc | Checked: 2010-08-13 (Catznip-2.1)
+	LLViewerWearable* wearable = get_if_there(LLWearableList::instance().mList, uuid, (LLViewerWearable*)NULL);
+	if (wearable)
+	{
+		LL_DEBUGS("Wearable") << "processGetAssetReply()" << LL_ENDL;
+		LL_DEBUGS("Wearable") << wearable << LL_ENDL;
+
+		if(data->mCallback)
+		{
+			data->mCallback(wearable, data->mUserdata);
+		}
+		delete data;
+
+		return;
+	}
+// [/SL:KB]
 	LLAvatarAppearance *avatarp = data->mAvatarp;
 	
 	if( !filename )
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 92511167c070c79a7dc4f403b7c9d7ea0a57b0de..84c722a204b038aab2d2f5e9fc00f39921d281f7 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1485,6 +1485,12 @@
             <menu_item_call.on_click
              function="Advanced.RebakeTextures" />
         </menu_item_call>
+        <menu_item_call
+         label="Refresh Attachments"
+         name="Refresh Attachments">
+            <menu_item_call.on_click
+             function="Advanced.RefreshAttachments" />
+        </menu_item_call>
         <menu_item_call
            label="Set UI Size to Default"
            name="Set UI Size to Default">