diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index f151b15e294ab995544fd7d55afbc9d61f5267fd..ff0e2c42c105eae9c1f660dc5e490f7bdc540e6d 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -95,6 +95,8 @@
 #include "lscript_byteformat.h"
 #include "stringize.h"
 #include "boost/foreach.hpp"
+#include "llhttpsdhandler.h"
+#include "llcorehttputil.h"
 
 using namespace LLAvatarAppearanceDefines;
 
@@ -323,6 +325,7 @@ bool LLAgent::isMicrophoneOn(const LLSD& sdname)
 // For a toggled version, see viewer.h for the
 // TOGGLE_HACKED_GODLIKE_VIEWER define, instead.
 // ************************************************************
+bool LLAgent::mActive = true;
 
 // Constructors and Destructors
 
@@ -361,7 +364,12 @@ LLAgent::LLAgent() :
 	mMaturityPreferenceNumRetries(0U),
 	mLastKnownRequestMaturity(SIM_ACCESS_MIN),
 	mLastKnownResponseMaturity(SIM_ACCESS_MIN),
-	mTeleportState( TELEPORT_NONE ),
+	mHttpRequest(),
+	mHttpHeaders(),
+	mHttpOptions(),
+	mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+	mHttpPriority(0),
+	mTeleportState(TELEPORT_NONE),
 	mRegionp(NULL),
 
 	mAgentOriginGlobal(),
@@ -459,6 +467,15 @@ void LLAgent::init()
 		mTeleportFailedSlot = LLViewerParcelMgr::getInstance()->setTeleportFailedCallback(boost::bind(&LLAgent::handleTeleportFailed, this));
 	}
 
+	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
+
+	mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
+	mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false);
+	mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false);
+	mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_AVATAR);
+
+	doOnIdleRepeating(boost::bind(&LLAgent::onIdle, this));
+
 	mInitialized = TRUE;
 }
 
@@ -467,6 +484,7 @@ void LLAgent::init()
 //-----------------------------------------------------------------------------
 void LLAgent::cleanup()
 {
+	mActive = false;
 	mRegionp = NULL;
 	if (mTeleportFinishedSlot.connected())
 	{
@@ -498,6 +516,17 @@ LLAgent::~LLAgent()
 	mTeleportSourceSLURL = NULL;
 }
 
+//-----------------------------------------------------------------------------
+// Idle processing
+//-----------------------------------------------------------------------------
+bool LLAgent::onIdle()
+{
+	if (!LLAgent::mActive)
+		return true;
+	mHttpRequest->update(0L);
+	return false;
+}
+
 // Handle any actions that need to be performed when the main app gains focus
 // (such as through alt-tab).
 //-----------------------------------------------------------------------------
@@ -2515,66 +2544,61 @@ int LLAgent::convertTextToMaturity(char text)
 	return LLAgentAccess::convertTextToMaturity(text);
 }
 
-class LLMaturityPreferencesResponder : public LLHTTPClient::Responder
+//=========================================================================
+class LLMaturityHttpHandler : public LLHttpSDHandler
 {
-	LOG_CLASS(LLMaturityPreferencesResponder);
 public:
-	LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity);
-	virtual ~LLMaturityPreferencesResponder();
+	LLMaturityHttpHandler(const std::string& capabilityURL, LLAgent *agent, U8 preferred, U8 previous):
+		LLHttpSDHandler(capabilityURL),
+		mAgent(agent),
+		mPreferredMaturity(preferred),
+		mPreviousMaturity(previous)
+	{ }
 
-protected:
-	virtual void httpSuccess();
-	virtual void httpFailure();
+	virtual ~LLMaturityHttpHandler()
+	{ }
 
 protected:
+	virtual void onSuccess(LLCore::HttpResponse * response, LLSD &content);
+	virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
 
 private:
-	U8 parseMaturityFromServerResponse(const LLSD &pContent) const;
-
-	LLAgent                                  *mAgent;
-	U8                                       mPreferredMaturity;
-	U8                                       mPreviousMaturity;
-};
+	U8 LLMaturityHttpHandler::parseMaturityFromServerResponse(const LLSD &pContent) const;
 
-LLMaturityPreferencesResponder::LLMaturityPreferencesResponder(LLAgent *pAgent, U8 pPreferredMaturity, U8 pPreviousMaturity)
-	: LLHTTPClient::Responder(),
-	mAgent(pAgent),
-	mPreferredMaturity(pPreferredMaturity),
-	mPreviousMaturity(pPreviousMaturity)
-{
-}
+	LLAgent *	mAgent;
+	U8			mPreferredMaturity;
+	U8          mPreviousMaturity;
 
-LLMaturityPreferencesResponder::~LLMaturityPreferencesResponder()
-{
-}
+};
 
-void LLMaturityPreferencesResponder::httpSuccess()
+//-------------------------------------------------------------------------
+void LLMaturityHttpHandler::onSuccess(LLCore::HttpResponse * response, LLSD &content)
 {
-	U8 actualMaturity = parseMaturityFromServerResponse(getContent());
+	U8 actualMaturity = parseMaturityFromServerResponse(content);
 
 	if (actualMaturity != mPreferredMaturity)
 	{
 		LL_WARNS() << "while attempting to change maturity preference from '"
-				   << LLViewerRegion::accessToString(mPreviousMaturity)
-				   << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) 
-				   << "', the server responded with '"
-				   << LLViewerRegion::accessToString(actualMaturity) 
-				   << "' [value:" << static_cast<U32>(actualMaturity) 
-				   << "], " << dumpResponse() << LL_ENDL;
+			<< LLViewerRegion::accessToString(mPreviousMaturity)
+			<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity)
+			<< "', the server responded with '"
+			<< LLViewerRegion::accessToString(actualMaturity)
+			<< "' [value:" << static_cast<U32>(actualMaturity)
+			<< "], " << LL_ENDL;
 	}
 	mAgent->handlePreferredMaturityResult(actualMaturity);
 }
 
-void LLMaturityPreferencesResponder::httpFailure()
+void LLMaturityHttpHandler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
 {
-	LL_WARNS() << "while attempting to change maturity preference from '" 
-			   << LLViewerRegion::accessToString(mPreviousMaturity)
-			   << "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) 
-			<< "', " << dumpResponse() << LL_ENDL;
+	LL_WARNS() << "while attempting to change maturity preference from '"
+		<< LLViewerRegion::accessToString(mPreviousMaturity)
+		<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity)
+		<< "', " << LL_ENDL;
 	mAgent->handlePreferredMaturityError();
 }
 
-U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent) const
+U8 LLMaturityHttpHandler::parseMaturityFromServerResponse(const LLSD &pContent) const
 {
 	U8 maturity = SIM_ACCESS_MIN;
 
@@ -2595,6 +2619,7 @@ U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &p
 
 	return maturity;
 }
+//=========================================================================
 
 void LLAgent::handlePreferredMaturityResult(U8 pServerMaturity)
 {
@@ -2724,38 +2749,41 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
 		// Update the last know maturity request
 		mLastKnownRequestMaturity = pPreferredMaturity;
 
-		// Create a response handler
-		LLHTTPClient::ResponderPtr responderPtr = LLHTTPClient::ResponderPtr(new LLMaturityPreferencesResponder(this, pPreferredMaturity, mLastKnownResponseMaturity));
-
 		// If we don't have a region, report it as an error
 		if (getRegion() == NULL)
 		{
-			responderPtr->failureResult(0U, "region is not defined", LLSD());
+			LL_WARNS("Agent") << "Region is not defined, can not change Maturity setting." << LL_ENDL;
+			return;
 		}
-		else
+		std::string url = getRegion()->getCapability("UpdateAgentInformation");
+
+		// If the capability is not defined, report it as an error
+		if (url.empty())
 		{
-			// Find the capability to send maturity preference
-			std::string url = getRegion()->getCapability("UpdateAgentInformation");
+			LL_WARNS("Agent") << "'UpdateAgentInformation' is not defined for region" << LL_ENDL;
+			return;
+		}
 
-			// If the capability is not defined, report it as an error
-			if (url.empty())
-			{
-				responderPtr->failureResult(0U, 
-							"capability 'UpdateAgentInformation' is not defined for region", LLSD());
-			}
-			else
-			{
-				// Set new access preference
-				LLSD access_prefs = LLSD::emptyMap();
-				access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity);
-
-				LLSD body = LLSD::emptyMap();
-				body["access_prefs"] = access_prefs;
-				LL_INFOS() << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity)
-					<< "' via capability to: " << url << LL_ENDL;
-				LLSD headers;
-				LLHTTPClient::post(url, body, responderPtr, headers, 30.0f);
-			}
+		LLMaturityHttpHandler * handler = new LLMaturityHttpHandler(url, this, pPreferredMaturity, mLastKnownResponseMaturity);
+
+		LLSD access_prefs = LLSD::emptyMap();
+		access_prefs["max"] = LLViewerRegion::accessToShortString(pPreferredMaturity);
+
+		LLSD postData = LLSD::emptyMap();
+		postData["access_prefs"] = access_prefs;
+		LL_INFOS() << "Sending viewer preferred maturity to '" << LLViewerRegion::accessToString(pPreferredMaturity)
+			<< "' via capability to: " << url << LL_ENDL;
+
+		LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
+			mHttpPolicy, mHttpPriority, url,
+			postData, mHttpOptions, mHttpHeaders, handler);
+
+		if (handle == LLCORE_HTTP_HANDLE_INVALID)
+		{
+			delete handler;
+			LLCore::HttpStatus status = mHttpRequest->getStatus();
+			LL_WARNS("Avatar") << "Maturity request post failed Reason " << status.toTerseString()
+				<< " \"" << status.toString() << "\"" << LL_ENDL;
 		}
 	}
 }
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 56bd1428ce373a7972b26f77e1499d8a7eb20403..278e4c0fa15077d41f9d6c709c56079c85001aaf 100755
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -35,6 +35,9 @@
 #include "llavatarappearancedefines.h"
 #include "llpermissionsflags.h"
 #include "v3dmath.h"
+#include "httprequest.h"
+#include "httpheaders.h"
+#include "httpoptions.h"
 
 #include <boost/function.hpp>
 #include <boost/shared_ptr.hpp>
@@ -112,6 +115,10 @@ class LLAgent : public LLOldEvents::LLObservable
 	void			init();
 	void			cleanup();
 
+private:
+	bool			onIdle();
+
+	static bool		mActive;
 	//--------------------------------------------------------------------
 	// Login
 	//--------------------------------------------------------------------
@@ -754,11 +761,16 @@ class LLAgent : public LLOldEvents::LLObservable
 	unsigned int                    mMaturityPreferenceNumRetries;
 	U8                              mLastKnownRequestMaturity;
 	U8                              mLastKnownResponseMaturity;
+	LLCore::HttpRequest::ptr_t		mHttpRequest;
+	LLCore::HttpHeaders::ptr_t		mHttpHeaders;
+	LLCore::HttpOptions::ptr_t		mHttpOptions;
+	LLCore::HttpRequest::policy_t	mHttpPolicy;
+	LLCore::HttpRequest::priority_t	mHttpPriority;
 
 	bool            isMaturityPreferenceSyncedWithServer() const;
 	void 			sendMaturityPreferenceToServer(U8 pPreferredMaturity);
 
-	friend class LLMaturityPreferencesResponder;
+	friend class	LLMaturityHttpHandler;
 	void            handlePreferredMaturityResult(U8 pServerMaturity);
 	void            handlePreferredMaturityError();
 	void            reportPreferredMaturitySuccess();
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index dbc858bdb0421c6dc64e7b88d70e1363ad32276f..bb4228dbb2f3786d3180fee5dcd2cc8add2fb7b9 100755
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1,3490 +1,3490 @@
-/** 
- * @file llappearancemgr.cpp
- * @brief Manager for initiating appearance changes on the viewer
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include <boost/lexical_cast.hpp>
-#include "llaccordionctrltab.h"
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llagentwearables.h"
-#include "llappearancemgr.h"
-#include "llattachmentsmgr.h"
-#include "llcommandhandler.h"
-#include "lleventtimer.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llgesturemgr.h"
-#include "llinventorybridge.h"
-#include "llinventoryfunctions.h"
-#include "llinventoryobserver.h"
-#include "llnotificationsutil.h"
-#include "lloutfitobserver.h"
-#include "lloutfitslist.h"
-#include "llselectmgr.h"
-#include "llsidepanelappearance.h"
-#include "llviewerobjectlist.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "llviewerregion.h"
-#include "llwearablelist.h"
-#include "llsdutil.h"
-#include "llsdserialize.h"
-#include "llhttpretrypolicy.h"
-#include "llaisapi.h"
-#include "llhttpsdhandler.h"
-#include "llcorehttputil.h"
-#include "llappviewer.h"
-
-#if LL_MSVC
-// disable boost::lexical_cast warning
-#pragma warning (disable:4702)
-#endif
-
-std::string self_av_string()
-{
-	// On logout gAgentAvatarp can already be invalid
-	return isAgentAvatarValid() ? gAgentAvatarp->avString() : "";
-}
-
-// RAII thingy to guarantee that a variable gets reset when the Setter
-// goes out of scope.  More general utility would be handy - TODO:
-// check boost.
-class BoolSetter
-{
-public:
-	BoolSetter(bool& var):
-		mVar(var)
-	{
-		mVar = true;
-	}
-	~BoolSetter()
-	{
-		mVar = false; 
-	}
-private:
-	bool& mVar;
-};
-
-char ORDER_NUMBER_SEPARATOR('@');
-
-class LLOutfitUnLockTimer: public LLEventTimer
-{
-public:
-	LLOutfitUnLockTimer(F32 period) : LLEventTimer(period)
-	{
-		// restart timer on BOF changed event
-		LLOutfitObserver::instance().addBOFChangedCallback(boost::bind(
-				&LLOutfitUnLockTimer::reset, this));
-		stop();
-	}
-
-	/*virtual*/
-	BOOL tick()
-	{
-		if(mEventTimer.hasExpired())
-		{
-			LLAppearanceMgr::instance().setOutfitLocked(false);
-		}
-		return FALSE;
-	}
-	void stop() { mEventTimer.stop(); }
-	void start() { mEventTimer.start(); }
-	void reset() { mEventTimer.reset(); }
-	BOOL getStarted() { return mEventTimer.getStarted(); }
-
-	LLTimer&  getEventTimer() { return mEventTimer;}
-};
-
-// support for secondlife:///app/appearance SLapps
-class LLAppearanceHandler : public LLCommandHandler
-{
-public:
-	// requests will be throttled from a non-trusted browser
-	LLAppearanceHandler() : LLCommandHandler("appearance", UNTRUSTED_THROTTLE) {}
-
-	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
-	{
-		// support secondlife:///app/appearance/show, but for now we just
-		// make all secondlife:///app/appearance SLapps behave this way
-		if (!LLUI::sSettingGroups["config"]->getBOOL("EnableAppearance"))
-		{
-			LLNotificationsUtil::add("NoAppearance", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
-			return true;
-		}
-
-		LLFloaterSidePanelContainer::showPanel("appearance", LLSD());
-		return true;
-	}
-};
-
-LLAppearanceHandler gAppearanceHandler;
-
-
-LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id, const std::string& name)
-{
-	LLInventoryModel::cat_array_t cat_array;
-	LLInventoryModel::item_array_t item_array;
-	LLNameCategoryCollector has_name(name);
-	gInventory.collectDescendentsIf(parent_id,
-									cat_array,
-									item_array,
-									LLInventoryModel::EXCLUDE_TRASH,
-									has_name);
-	if (0 == cat_array.size())
-		return LLUUID();
-	else
-	{
-		LLViewerInventoryCategory *cat = cat_array.at(0);
-		if (cat)
-			return cat->getUUID();
-		else
-		{
-			LL_WARNS() << "null cat" << LL_ENDL;
-			return LLUUID();
-		}
-	}
-}
-
-// We want this to be much lower (e.g. 15.0 is usually fine), bumping
-// up for now until we can diagnose some cases of very slow response
-// to requests.
-const F32 DEFAULT_RETRY_AFTER_INTERVAL = 300.0;
-
-// Given the current back-end problems, retrying is causing too many
-// duplicate items. Bump this back to 2 once they are resolved (or can
-// leave at 0 if the operations become actually reliable).
-const S32 DEFAULT_MAX_RETRIES = 0;
-
-class LLCallAfterInventoryBatchMgr: public LLEventTimer 
-{
-public:
-	LLCallAfterInventoryBatchMgr(const LLUUID& dst_cat_id,
-								 const std::string& phase_name,
-								 nullary_func_t on_completion_func,
-								 nullary_func_t on_failure_func = no_op,
-								 F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
-								 S32 max_retries = DEFAULT_MAX_RETRIES
-		):
-		mDstCatID(dst_cat_id),
-		mTrackingPhase(phase_name),
-		mOnCompletionFunc(on_completion_func),
-		mOnFailureFunc(on_failure_func),
-		mRetryAfter(retry_after),
-		mMaxRetries(max_retries),
-		mPendingRequests(0),
-		mFailCount(0),
-		mCompletionOrFailureCalled(false),
-		mRetryCount(0),
-		LLEventTimer(5.0)
-	{
-		if (!mTrackingPhase.empty())
-		{
-			selfStartPhase(mTrackingPhase);
-		}
-	}
-
-	void addItems(LLInventoryModel::item_array_t& src_items)
-	{
-		for (LLInventoryModel::item_array_t::const_iterator it = src_items.begin();
-			 it != src_items.end();
-			 ++it)
-		{
-			LLViewerInventoryItem* item = *it;
-			llassert(item);
-			addItem(item->getUUID());
-		}
-	}
-
-	// Request or re-request operation for specified item.
-	void addItem(const LLUUID& item_id)
-	{
-		LL_DEBUGS("Avatar") << "item_id " << item_id << LL_ENDL;
-		if (!requestOperation(item_id))
-		{
-			LL_DEBUGS("Avatar") << "item_id " << item_id << " requestOperation false, skipping" << LL_ENDL;
-			return;
-		}
-
-		mPendingRequests++;
-		// On a re-request, this will reset the timer.
-		mWaitTimes[item_id] = LLTimer();
-		if (mRetryCounts.find(item_id) == mRetryCounts.end())
-		{
-			mRetryCounts[item_id] = 0;
-		}
-		else
-		{
-			mRetryCounts[item_id]++;
-		}
-	}
-
-	virtual bool requestOperation(const LLUUID& item_id) = 0;
-
-	void onOp(const LLUUID& src_id, const LLUUID& dst_id, LLTimer timestamp)
-	{
-		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateLateOpRate"))
-		{
-			LL_WARNS() << "Simulating late operation by punting handling to later" << LL_ENDL;
-			doAfterInterval(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,src_id,dst_id,timestamp),
-							mRetryAfter);
-			return;
-		}
-		mPendingRequests--;
-		F32 elapsed = timestamp.getElapsedTimeF32();
-		LL_DEBUGS("Avatar") << "op done, src_id " << src_id << " dst_id " << dst_id << " after " << elapsed << " seconds" << LL_ENDL;
-		if (mWaitTimes.find(src_id) == mWaitTimes.end())
-		{
-			// No longer waiting for this item - either serviced
-			// already or gave up after too many retries.
-			LL_WARNS() << "duplicate or late operation, src_id " << src_id << "dst_id " << dst_id
-					<< " elapsed " << elapsed << " after end " << (S32) mCompletionOrFailureCalled << LL_ENDL;
-		}
-		mTimeStats.push(elapsed);
-		mWaitTimes.erase(src_id);
-		if (mWaitTimes.empty() && !mCompletionOrFailureCalled)
-		{
-			onCompletionOrFailure();
-		}
-	}
-
-	void onCompletionOrFailure()
-	{
-		assert (!mCompletionOrFailureCalled);
-		mCompletionOrFailureCalled = true;
-		
-		// Will never call onCompletion() if any item has been flagged as
-		// a failure - otherwise could wind up with corrupted
-		// outfit, involuntary nudity, etc.
-		reportStats();
-		if (!mTrackingPhase.empty())
-		{
-			selfStopPhase(mTrackingPhase);
-		}
-		if (!mFailCount)
-		{
-			onCompletion();
-		}
-		else
-		{
-			onFailure();
-		}
-	}
-
-	void onFailure()
-	{
-		LL_INFOS() << "failed" << LL_ENDL;
-		mOnFailureFunc();
-	}
-
-	void onCompletion()
-	{
-		LL_INFOS() << "done" << LL_ENDL;
-		mOnCompletionFunc();
-	}
-	
-	// virtual
-	// Will be deleted after returning true - only safe to do this if all callbacks have fired.
-	BOOL tick()
-	{
-		// mPendingRequests will be zero if all requests have been
-		// responded to.  mWaitTimes.empty() will be true if we have
-		// received at least one reply for each UUID.  If requests
-		// have been dropped and retried, these will not necessarily
-		// be the same.  Only safe to return true if all requests have
-		// been serviced, since it will result in this object being
-		// deleted.
-		bool all_done = (mPendingRequests==0);
-
-		if (!mWaitTimes.empty())
-		{
-			LL_WARNS() << "still waiting on " << mWaitTimes.size() << " items" << LL_ENDL;
-			for (std::map<LLUUID,LLTimer>::iterator it = mWaitTimes.begin();
-				 it != mWaitTimes.end();)
-			{
-				// Use a copy of iterator because it may be erased/invalidated.
-				std::map<LLUUID,LLTimer>::iterator curr_it = it;
-				++it;
-				
-				F32 time_waited = curr_it->second.getElapsedTimeF32();
-				S32 retries = mRetryCounts[curr_it->first];
-				if (time_waited > mRetryAfter)
-				{
-					if (retries < mMaxRetries)
-					{
-						LL_DEBUGS("Avatar") << "Waited " << time_waited <<
-							" for " << curr_it->first << ", retrying" << LL_ENDL;
-						mRetryCount++;
-						addItem(curr_it->first);
-					}
-					else
-					{
-						LL_WARNS() << "Giving up on " << curr_it->first << " after too many retries" << LL_ENDL;
-						mWaitTimes.erase(curr_it);
-						mFailCount++;
-					}
-				}
-				if (mWaitTimes.empty())
-				{
-					onCompletionOrFailure();
-				}
-
-			}
-		}
-		return all_done;
-	}
-
-	void reportStats()
-	{
-		LL_DEBUGS("Avatar") << "Phase: " << mTrackingPhase << LL_ENDL;
-		LL_DEBUGS("Avatar") << "mFailCount: " << mFailCount << LL_ENDL;
-		LL_DEBUGS("Avatar") << "mRetryCount: " << mRetryCount << LL_ENDL;
-		LL_DEBUGS("Avatar") << "Times: n " << mTimeStats.getCount() << " min " << mTimeStats.getMinValue() << " max " << mTimeStats.getMaxValue() << LL_ENDL;
-		LL_DEBUGS("Avatar") << "Mean " << mTimeStats.getMean() << " stddev " << mTimeStats.getStdDev() << LL_ENDL;
-	}
-	
-	virtual ~LLCallAfterInventoryBatchMgr()
-	{
-		LL_DEBUGS("Avatar") << "deleting" << LL_ENDL;
-	}
-
-protected:
-	std::string mTrackingPhase;
-	std::map<LLUUID,LLTimer> mWaitTimes;
-	std::map<LLUUID,S32> mRetryCounts;
-	LLUUID mDstCatID;
-	nullary_func_t mOnCompletionFunc;
-	nullary_func_t mOnFailureFunc;
-	F32 mRetryAfter;
-	S32 mMaxRetries;
-	S32 mPendingRequests;
-	S32 mFailCount;
-	S32 mRetryCount;
-	bool mCompletionOrFailureCalled;
-	LLViewerStats::StatsAccumulator mTimeStats;
-};
-
-class LLCallAfterInventoryCopyMgr: public LLCallAfterInventoryBatchMgr
-{
-public:
-	LLCallAfterInventoryCopyMgr(LLInventoryModel::item_array_t& src_items,
-								const LLUUID& dst_cat_id,
-								const std::string& phase_name,
-								nullary_func_t on_completion_func,
-								nullary_func_t on_failure_func = no_op,
-								 F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
-								 S32 max_retries = DEFAULT_MAX_RETRIES
-		):
-		LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries)
-	{
-		addItems(src_items);
-		sInstanceCount++;
-	}
-
-	~LLCallAfterInventoryCopyMgr()
-	{
-		sInstanceCount--;
-	}
-	
-	virtual bool requestOperation(const LLUUID& item_id)
-	{
-		LLViewerInventoryItem *item = gInventory.getItem(item_id);
-		llassert(item);
-		LL_DEBUGS("Avatar") << "copying item " << item_id << LL_ENDL;
-		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
-		{
-			LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << LL_ENDL;
-			return true;
-		}
-		copy_inventory_item(
-			gAgent.getID(),
-			item->getPermissions().getOwner(),
-			item->getUUID(),
-			mDstCatID,
-			std::string(),
-			new LLBoostFuncInventoryCallback(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer()))
-			);
-		return true;
-	}
-
-	static S32 getInstanceCount() { return sInstanceCount; }
-	
-private:
-	static S32 sInstanceCount;
-};
-
-S32 LLCallAfterInventoryCopyMgr::sInstanceCount = 0;
-
-class LLWearCategoryAfterCopy: public LLInventoryCallback
-{
-public:
-	LLWearCategoryAfterCopy(bool append):
-		mAppend(append)
-	{}
-
-	// virtual
-	void fire(const LLUUID& id)
-	{
-		// Wear the inventory category.
-		LLInventoryCategory* cat = gInventory.getCategory(id);
-		LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(cat, mAppend);
-	}
-
-private:
-	bool mAppend;
-};
-
-class LLTrackPhaseWrapper : public LLInventoryCallback
-{
-public:
-	LLTrackPhaseWrapper(const std::string& phase_name, LLPointer<LLInventoryCallback> cb = NULL):
-		mTrackingPhase(phase_name),
-		mCB(cb)
-	{
-		selfStartPhase(mTrackingPhase);
-	}
-
-	// virtual
-	void fire(const LLUUID& id)
-	{
-		if (mCB)
-		{
-			mCB->fire(id);
-		}
-	}
-
-	// virtual
-	~LLTrackPhaseWrapper()
-	{
-		selfStopPhase(mTrackingPhase);
-	}
-
-protected:
-	std::string mTrackingPhase;
-	LLPointer<LLInventoryCallback> mCB;
-};
-
-LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool enforce_item_restrictions,
-														 bool enforce_ordering,
-														 nullary_func_t post_update_func 
-	):
-	mFireCount(0),
-	mEnforceItemRestrictions(enforce_item_restrictions),
-	mEnforceOrdering(enforce_ordering),
-	mPostUpdateFunc(post_update_func)
-{
-	selfStartPhase("update_appearance_on_destroy");
-}
-
-void LLUpdateAppearanceOnDestroy::fire(const LLUUID& inv_item)
-{
-	LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(inv_item);
-	const std::string item_name = item ? item->getName() : "ITEM NOT FOUND";
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << LL_ENDL;
-#endif
-	mFireCount++;
-}
-
-LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()
-{
-	if (!LLApp::isExiting())
-	{
-		// speculative fix for MAINT-1150
-		LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL;
-
-		selfStopPhase("update_appearance_on_destroy");
-
-		LLAppearanceMgr::instance().updateAppearanceFromCOF(mEnforceItemRestrictions,
-															mEnforceOrdering,
-															mPostUpdateFunc);
-	}
-}
-
-LLUpdateAppearanceAndEditWearableOnDestroy::LLUpdateAppearanceAndEditWearableOnDestroy(const LLUUID& item_id):
-	mItemID(item_id)
-{
-}
-
-void edit_wearable_and_customize_avatar(LLUUID item_id)
-{
-	// Start editing the item if previously requested.
-	gAgentWearables.editWearableIfRequested(item_id);
-	
-	// TODO: camera mode may not be changed if a debug setting is tweaked
-	if( gAgentCamera.cameraCustomizeAvatar() )
-	{
-		// If we're in appearance editing mode, the current tab may need to be refreshed
-		LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(
-			LLFloaterSidePanelContainer::getPanel("appearance"));
-		if (panel)
-		{
-			panel->showDefaultSubpart();
-		}
-	}
-}
-
-LLUpdateAppearanceAndEditWearableOnDestroy::~LLUpdateAppearanceAndEditWearableOnDestroy()
-{
-	if (!LLApp::isExiting())
-	{
-		LLAppearanceMgr::instance().updateAppearanceFromCOF(
-			true,true,
-			boost::bind(edit_wearable_and_customize_avatar, mItemID));
-	}
-}
-
-
-struct LLFoundData
-{
-	LLFoundData() :
-		mAssetType(LLAssetType::AT_NONE),
-		mWearableType(LLWearableType::WT_INVALID),
-		mWearable(NULL) {}
-
-	LLFoundData(const LLUUID& item_id,
-				const LLUUID& asset_id,
-				const std::string& name,
-				const LLAssetType::EType& asset_type,
-				const LLWearableType::EType& wearable_type,
-				const bool is_replacement = false
-		) :
-		mItemID(item_id),
-		mAssetID(asset_id),
-		mName(name),
-		mAssetType(asset_type),
-		mWearableType(wearable_type),
-		mIsReplacement(is_replacement),
-		mWearable( NULL ) {}
-	
-	LLUUID mItemID;
-	LLUUID mAssetID;
-	std::string mName;
-	LLAssetType::EType mAssetType;
-	LLWearableType::EType mWearableType;
-	LLViewerWearable* mWearable;
-	bool mIsReplacement;
-};
-
-	
-class LLWearableHoldingPattern
-{
-	LOG_CLASS(LLWearableHoldingPattern);
-
-public:
-	LLWearableHoldingPattern();
-	~LLWearableHoldingPattern();
-
-	bool pollFetchCompletion();
-	void onFetchCompletion();
-	bool isFetchCompleted();
-	bool isTimedOut();
-
-	void checkMissingWearables();
-	bool pollMissingWearables();
-	bool isMissingCompleted();
-	void recoverMissingWearable(LLWearableType::EType type);
-	void clearCOFLinksForMissingWearables();
-	
-	void onWearableAssetFetch(LLViewerWearable *wearable);
-	void onAllComplete();
-
-	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 setGestItems(const LLInventoryModel::item_array_t& items);
-	bool isMostRecent();
-	void handleLateArrivals();
-	void resetTime(F32 timeout);
-	static S32 countActive() { return sActiveHoldingPatterns.size(); }
-	S32 index() { return mIndex; }
-	
-private:
-	found_list_t mFoundList;
-	LLInventoryModel::item_array_t mObjItems;
-	LLInventoryModel::item_array_t mGestItems;
-	typedef std::set<S32> type_set_t;
-	type_set_t mTypesToRecover;
-	type_set_t mTypesToLink;
-	S32 mResolved;
-	LLTimer mWaitTime;
-	bool mFired;
-	typedef std::set<LLWearableHoldingPattern*> type_set_hp;
-	static type_set_hp sActiveHoldingPatterns;
-	static S32 sNextIndex;
-	S32 mIndex;
-	bool mIsMostRecent;
-	std::set<LLViewerWearable*> mLateArrivals;
-	bool mIsAllComplete;
-};
-
-LLWearableHoldingPattern::type_set_hp LLWearableHoldingPattern::sActiveHoldingPatterns;
-S32 LLWearableHoldingPattern::sNextIndex = 0;
-
-LLWearableHoldingPattern::LLWearableHoldingPattern():
-	mResolved(0),
-	mFired(false),
-	mIsMostRecent(true),
-	mIsAllComplete(false)
-{
-	if (countActive()>0)
-	{
-		LL_INFOS() << "Creating LLWearableHoldingPattern when "
-				   << countActive()
-				   << " other attempts are active."
-				   << " Flagging others as invalid."
-				   << LL_ENDL;
-		for (type_set_hp::iterator it = sActiveHoldingPatterns.begin();
-			 it != sActiveHoldingPatterns.end();
-			 ++it)
-		{
-			(*it)->mIsMostRecent = false;
-		}
-			 
-	}
-	mIndex = sNextIndex++;
-	sActiveHoldingPatterns.insert(this);
-	LL_DEBUGS("Avatar") << "HP " << index() << " created" << LL_ENDL;
-	selfStartPhase("holding_pattern");
-}
-
-LLWearableHoldingPattern::~LLWearableHoldingPattern()
-{
-	sActiveHoldingPatterns.erase(this);
-	if (isMostRecent())
-	{
-		selfStopPhase("holding_pattern");
-	}
-	LL_DEBUGS("Avatar") << "HP " << index() << " deleted" << LL_ENDL;
-}
-
-bool LLWearableHoldingPattern::isMostRecent()
-{
-	return mIsMostRecent;
-}
-
-LLWearableHoldingPattern::found_list_t& LLWearableHoldingPattern::getFoundList()
-{
-	return mFoundList;
-}
-
-void LLWearableHoldingPattern::eraseTypeToLink(LLWearableType::EType type)
-{
-	mTypesToLink.erase(type);
-}
-
-void LLWearableHoldingPattern::eraseTypeToRecover(LLWearableType::EType type)
-{
-	mTypesToRecover.erase(type);
-}
-
-void LLWearableHoldingPattern::setObjItems(const LLInventoryModel::item_array_t& items)
-{
-	mObjItems = items;
-}
-
-void LLWearableHoldingPattern::setGestItems(const LLInventoryModel::item_array_t& items)
-{
-	mGestItems = items;
-}
-
-bool LLWearableHoldingPattern::isFetchCompleted()
-{
-	return (mResolved >= (S32)getFoundList().size()); // have everything we were waiting for?
-}
-
-bool LLWearableHoldingPattern::isTimedOut()
-{
-	return mWaitTime.hasExpired();
-}
-
-void LLWearableHoldingPattern::checkMissingWearables()
-{
-	if (!isMostRecent())
-	{
-		// runway why don't we actually skip here?
-		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
-	}
-
-	std::vector<S32> found_by_type(LLWearableType::WT_COUNT,0);
-	std::vector<S32> requested_by_type(LLWearableType::WT_COUNT,0);
-	for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it)
-	{
-		LLFoundData &data = *it;
-		if (data.mWearableType < LLWearableType::WT_COUNT)
-			requested_by_type[data.mWearableType]++;
-		if (data.mWearable)
-			found_by_type[data.mWearableType]++;
-	}
-
-	for (S32 type = 0; type < LLWearableType::WT_COUNT; ++type)
-	{
-		if (requested_by_type[type] > found_by_type[type])
-		{
-			LL_WARNS() << self_av_string() << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << LL_ENDL;
-		}
-		if (found_by_type[type] > 0)
-			continue;
-		if (
-			// If at least one wearable of certain types (pants/shirt/skirt)
-			// was requested but none was found, create a default asset as a replacement.
-			// In all other cases, don't do anything.
-			// For critical types (shape/hair/skin/eyes), this will keep the avatar as a cloud 
-			// due to logic in LLVOAvatarSelf::getIsCloud().
-			// For non-critical types (tatoo, socks, etc.) the wearable will just be missing.
-			(requested_by_type[type] > 0) &&  
-			((type == LLWearableType::WT_PANTS) || (type == LLWearableType::WT_SHIRT) || (type == LLWearableType::WT_SKIRT)))
-		{
-			mTypesToRecover.insert(type);
-			mTypesToLink.insert(type);
-			recoverMissingWearable((LLWearableType::EType)type);
-			LL_WARNS() << self_av_string() << "need to replace " << type << LL_ENDL; 
-		}
-	}
-
-	resetTime(60.0F);
-
-	if (isMostRecent())
-	{
-		selfStartPhase("get_missing_wearables_2");
-	}
-	if (!pollMissingWearables())
-	{
-		doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this));
-	}
-}
-
-void LLWearableHoldingPattern::onAllComplete()
-{
-	if (isAgentAvatarValid())
-	{
-		gAgentAvatarp->outputRezTiming("Agent wearables fetch complete");
-	}
-
-	if (!isMostRecent())
-	{
-		// runway need to skip here?
-		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
-	}
-
-	// Activate all gestures in this folder
-	if (mGestItems.size() > 0)
-	{
-		LL_DEBUGS("Avatar") << self_av_string() << "Activating " << mGestItems.size() << " gestures" << LL_ENDL;
-		
-		LLGestureMgr::instance().activateGestures(mGestItems);
-		
-		// Update the inventory item labels to reflect the fact
-		// they are active.
-		LLViewerInventoryCategory* catp =
-			gInventory.getCategory(LLAppearanceMgr::instance().getCOF());
-		
-		if (catp)
-		{
-			gInventory.updateCategory(catp);
-			gInventory.notifyObservers();
-		}
-	}
-
-	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->clearAttachmentPosOverrides();
-
-		// 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->addAttachmentPosOverridesForObject(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())
-	{
-		// Only safe to delete if all wearable callbacks and all missing wearables completed.
-		delete this;
-	}
-	else
-	{
-		mIsAllComplete = true;
-		handleLateArrivals();
-	}
-}
-
-void LLWearableHoldingPattern::onFetchCompletion()
-{
-	if (isMostRecent())
-	{
-		selfStopPhase("get_wearables_2");
-	}
-		
-	if (!isMostRecent())
-	{
-		// runway skip here?
-		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
-	}
-
-	checkMissingWearables();
-}
-
-// Runs as an idle callback until all wearables are fetched (or we time out).
-bool LLWearableHoldingPattern::pollFetchCompletion()
-{
-	if (!isMostRecent())
-	{
-		// runway skip here?
-		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
-	}
-
-	bool completed = isFetchCompleted();
-	bool timed_out = isTimedOut();
-	bool done = completed || timed_out;
-
-	if (done)
-	{
-		LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " polling, done status: " << completed << " timed out " << timed_out
-				<< " elapsed " << mWaitTime.getElapsedTimeF32() << LL_ENDL;
-
-		mFired = true;
-		
-		if (timed_out)
-		{
-			LL_WARNS() << self_av_string() << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << LL_ENDL;
-		}
-
-		onFetchCompletion();
-	}
-	return done;
-}
-
-void recovered_item_link_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
-{
-	if (!holder->isMostRecent())
-	{
-		LL_WARNS() << "HP " << holder->index() << " skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
-		// runway skip here?
-	}
-
-	LL_INFOS() << "HP " << holder->index() << " recovered item link for type " << type << LL_ENDL;
-	holder->eraseTypeToLink(type);
-	// Add wearable to FoundData for actual wearing
-	LLViewerInventoryItem *item = gInventory.getItem(item_id);
-	LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
-
-	if (linked_item)
-	{
-		gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
-			
-		if (item)
-		{
-			LLFoundData found(linked_item->getUUID(),
-							  linked_item->getAssetUUID(),
-							  linked_item->getName(),
-							  linked_item->getType(),
-							  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID,
-							  true // is replacement
-				);
-			found.mWearable = wearable;
-			holder->getFoundList().push_front(found);
-		}
-		else
-		{
-			LL_WARNS() << self_av_string() << "inventory link not found for recovered wearable" << LL_ENDL;
-		}
-	}
-	else
-	{
-		LL_WARNS() << self_av_string() << "HP " << holder->index() << " inventory link not found for recovered wearable" << LL_ENDL;
-	}
-}
-
-void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
-{
-	if (!holder->isMostRecent())
-	{
-		// runway skip here?
-		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
-	}
-
-	LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL;
-	LLConstPointer<LLInventoryObject> itemp = gInventory.getItem(item_id);
-	wearable->setItemID(item_id);
-	holder->eraseTypeToRecover(type);
-	llassert(itemp);
-	if (itemp)
-	{
-		LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder));
-
-		link_inventory_object(LLAppearanceMgr::instance().getCOF(), itemp, cb);
-	}
-}
-
-void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type)
-{
-	if (!isMostRecent())
-	{
-		// runway skip here?
-		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
-	}
-	
-		// Try to recover by replacing missing wearable with a new one.
-	LLNotificationsUtil::add("ReplacedMissingWearable");
-	LL_DEBUGS() << "Wearable " << LLWearableType::getTypeLabel(type)
-				<< " could not be downloaded.  Replaced inventory item with default wearable." << LL_ENDL;
-	LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
-
-	// Add a new one in the lost and found folder.
-	const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
-	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_cb,_1,type,wearable,this));
-
-	create_inventory_item(gAgent.getID(),
-						  gAgent.getSessionID(),
-						  lost_and_found_id,
-						  wearable->getTransactionID(),
-						  wearable->getName(),
-						  wearable->getDescription(),
-						  wearable->getAssetType(),
-						  LLInventoryType::IT_WEARABLE,
-						  wearable->getType(),
-						  wearable->getPermissions().getMaskNextOwner(),
-						  cb);
-}
-
-bool LLWearableHoldingPattern::isMissingCompleted()
-{
-	return mTypesToLink.size()==0 && mTypesToRecover.size()==0;
-}
-
-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);
-		}
-	}
-}
-
-bool LLWearableHoldingPattern::pollMissingWearables()
-{
-	if (!isMostRecent())
-	{
-		// runway skip here?
-		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
-	}
-	
-	bool timed_out = isTimedOut();
-	bool missing_completed = isMissingCompleted();
-	bool done = timed_out || missing_completed;
-
-	if (!done)
-	{
-		LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " polling missing wearables, waiting for items " << mTypesToRecover.size()
-				<< " links " << mTypesToLink.size()
-				<< " wearables, timed out " << timed_out
-				<< " elapsed " << mWaitTime.getElapsedTimeF32()
-				<< " done " << done << LL_ENDL;
-	}
-
-	if (done)
-	{
-		if (isMostRecent())
-		{
-			selfStopPhase("get_missing_wearables_2");
-		}
-
-		gAgentAvatarp->debugWearablesLoaded();
-
-		// BAP - if we don't call clearCOFLinksForMissingWearables()
-		// here, we won't have to add the link back in later if the
-		// wearable arrives late.  This is to avoid corruption of
-		// wearable ordering info.  Also has the effect of making
-		// unworn item links visible in the COF under some
-		// circumstances.
-
-		//clearCOFLinksForMissingWearables();
-		onAllComplete();
-	}
-	return done;
-}
-
-// Handle wearables that arrived after the timeout period expired.
-void LLWearableHoldingPattern::handleLateArrivals()
-{
-	// Only safe to run if we have previously finished the missing
-	// wearables and other processing - otherwise we could be in some
-	// intermediate state - but have not been superceded by a later
-	// outfit change request.
-	if (mLateArrivals.size() == 0)
-	{
-		// Nothing to process.
-		return;
-	}
-	if (!isMostRecent())
-	{
-		LL_WARNS() << self_av_string() << "Late arrivals not handled - outfit change no longer valid" << LL_ENDL;
-	}
-	if (!mIsAllComplete)
-	{
-		LL_WARNS() << self_av_string() << "Late arrivals not handled - in middle of missing wearables processing" << LL_ENDL;
-	}
-
-	LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " need to handle " << mLateArrivals.size() << " late arriving wearables" << LL_ENDL;
-
-	// Update mFoundList using late-arriving wearables.
-	std::set<LLWearableType::EType> replaced_types;
-	for (LLWearableHoldingPattern::found_list_t::iterator iter = getFoundList().begin();
-		 iter != getFoundList().end(); ++iter)
-	{
-		LLFoundData& data = *iter;
-		for (std::set<LLViewerWearable*>::iterator wear_it = mLateArrivals.begin();
-			 wear_it != mLateArrivals.end();
-			 ++wear_it)
-		{
-			LLViewerWearable *wearable = *wear_it;
-
-			if(wearable->getAssetID() == data.mAssetID)
-			{
-				data.mWearable = wearable;
-
-				replaced_types.insert(data.mWearableType);
-
-				// BAP - if we didn't call
-				// clearCOFLinksForMissingWearables() earlier, we
-				// don't need to restore the link here.  Fixes
-				// wearable ordering problems.
-
-				// LLAppearanceMgr::instance().addCOFItemLink(data.mItemID,false);
-
-				// BAP failing this means inventory or asset server
-				// are corrupted in a way we don't handle.
-				llassert((data.mWearableType < LLWearableType::WT_COUNT) && (wearable->getType() == data.mWearableType));
-				break;
-			}
-		}
-	}
-
-	// Remove COF links for any default wearables previously used to replace the late arrivals.
-	// All this pussyfooting around with a while loop and explicit
-	// iterator incrementing is to allow removing items from the list
-	// without clobbering the iterator we're using to navigate.
-	LLWearableHoldingPattern::found_list_t::iterator iter = getFoundList().begin();
-	while (iter != getFoundList().end())
-	{
-		LLFoundData& data = *iter;
-
-		// If an item of this type has recently shown up, removed the corresponding replacement wearable from COF.
-		if (data.mWearable && data.mIsReplacement &&
-			replaced_types.find(data.mWearableType) != replaced_types.end())
-		{
-			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
-			std::list<LLFoundData>::iterator clobber_ator = iter;
-			++iter;
-			getFoundList().erase(clobber_ator);
-		}
-		else
-		{
-			++iter;
-		}
-	}
-
-	// Clear contents of late arrivals.
-	mLateArrivals.clear();
-
-	// Update appearance based on mFoundList
-	LLAppearanceMgr::instance().updateAgentWearables(this);
-}
-
-void LLWearableHoldingPattern::resetTime(F32 timeout)
-{
-	mWaitTime.reset();
-	mWaitTime.setTimerExpirySec(timeout);
-}
-
-void LLWearableHoldingPattern::onWearableAssetFetch(LLViewerWearable *wearable)
-{
-	if (!isMostRecent())
-	{
-		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
-	}
-	
-	mResolved += 1;  // just counting callbacks, not successes.
-	LL_DEBUGS("Avatar") << self_av_string() << "HP " << index() << " resolved " << mResolved << "/" << getFoundList().size() << LL_ENDL;
-	if (!wearable)
-	{
-		LL_WARNS() << self_av_string() << "no wearable found" << LL_ENDL;
-	}
-
-	if (mFired)
-	{
-		LL_WARNS() << self_av_string() << "called after holder fired" << LL_ENDL;
-		if (wearable)
-		{
-			mLateArrivals.insert(wearable);
-			if (mIsAllComplete)
-			{
-				handleLateArrivals();
-			}
-		}
-		return;
-	}
-
-	if (!wearable)
-	{
-		return;
-	}
-
-	for (LLWearableHoldingPattern::found_list_t::iterator iter = getFoundList().begin();
-		 iter != getFoundList().end(); ++iter)
-	{
-		LLFoundData& data = *iter;
-		if(wearable->getAssetID() == data.mAssetID)
-		{
-			// Failing this means inventory or asset server are corrupted in a way we don't handle.
-			if ((data.mWearableType >= LLWearableType::WT_COUNT) || (wearable->getType() != data.mWearableType))
-			{
-				LL_WARNS() << self_av_string() << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << LL_ENDL;
-				break;
-			}
-
-			data.mWearable = wearable;
-		}
-	}
-}
-
-static void onWearableAssetFetch(LLViewerWearable* wearable, void* data)
-{
-	LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
-	holder->onWearableAssetFetch(wearable);
-}
-
-
-static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
-{
-	LLInventoryModel::item_array_t new_items;
-	std::set<LLUUID> items_seen;
-	std::deque<LLViewerInventoryItem*> tmp_list;
-	// Traverse from the front and keep the first of each item
-	// encountered, so we actually keep the *last* of each duplicate
-	// item.  This is needed to give the right priority when adding
-	// duplicate items to an existing outfit.
-	for (S32 i=items.size()-1; i>=0; i--)
-	{
-		LLViewerInventoryItem *item = items.at(i);
-		LLUUID item_id = item->getLinkedUUID();
-		if (items_seen.find(item_id)!=items_seen.end())
-			continue;
-		items_seen.insert(item_id);
-		tmp_list.push_front(item);
-	}
-	for (std::deque<LLViewerInventoryItem*>::iterator it = tmp_list.begin();
-		 it != tmp_list.end();
-		 ++it)
-	{
-		new_items.push_back(*it);
-	}
-	items = new_items;
-}
-
-//=========================================================================
-class LLAppearanceMgrHttpHandler : public LLHttpSDHandler
-{
-public:
-	LLAppearanceMgrHttpHandler(const std::string& capabilityURL, LLAppearanceMgr *mgr) :
-		LLHttpSDHandler(capabilityURL),
-		mManager(mgr)
-	{ }
-
-	virtual ~LLAppearanceMgrHttpHandler()
-	{ }
-
+/** 
+ * @file llappearancemgr.cpp
+ * @brief Manager for initiating appearance changes on the viewer
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+ 
+#include "llviewerprecompiledheaders.h"
+
+#include <boost/lexical_cast.hpp>
+#include "llaccordionctrltab.h"
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llagentwearables.h"
+#include "llappearancemgr.h"
+#include "llattachmentsmgr.h"
+#include "llcommandhandler.h"
+#include "lleventtimer.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llgesturemgr.h"
+#include "llinventorybridge.h"
+#include "llinventoryfunctions.h"
+#include "llinventoryobserver.h"
+#include "llnotificationsutil.h"
+#include "lloutfitobserver.h"
+#include "lloutfitslist.h"
+#include "llselectmgr.h"
+#include "llsidepanelappearance.h"
+#include "llviewerobjectlist.h"
+#include "llvoavatar.h"
+#include "llvoavatarself.h"
+#include "llviewerregion.h"
+#include "llwearablelist.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+#include "llhttpretrypolicy.h"
+#include "llaisapi.h"
+#include "llhttpsdhandler.h"
+#include "llcorehttputil.h"
+#include "llappviewer.h"
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+std::string self_av_string()
+{
+	// On logout gAgentAvatarp can already be invalid
+	return isAgentAvatarValid() ? gAgentAvatarp->avString() : "";
+}
+
+// RAII thingy to guarantee that a variable gets reset when the Setter
+// goes out of scope.  More general utility would be handy - TODO:
+// check boost.
+class BoolSetter
+{
+public:
+	BoolSetter(bool& var):
+		mVar(var)
+	{
+		mVar = true;
+	}
+	~BoolSetter()
+	{
+		mVar = false; 
+	}
+private:
+	bool& mVar;
+};
+
+char ORDER_NUMBER_SEPARATOR('@');
+
+class LLOutfitUnLockTimer: public LLEventTimer
+{
+public:
+	LLOutfitUnLockTimer(F32 period) : LLEventTimer(period)
+	{
+		// restart timer on BOF changed event
+		LLOutfitObserver::instance().addBOFChangedCallback(boost::bind(
+				&LLOutfitUnLockTimer::reset, this));
+		stop();
+	}
+
+	/*virtual*/
+	BOOL tick()
+	{
+		if(mEventTimer.hasExpired())
+		{
+			LLAppearanceMgr::instance().setOutfitLocked(false);
+		}
+		return FALSE;
+	}
+	void stop() { mEventTimer.stop(); }
+	void start() { mEventTimer.start(); }
+	void reset() { mEventTimer.reset(); }
+	BOOL getStarted() { return mEventTimer.getStarted(); }
+
+	LLTimer&  getEventTimer() { return mEventTimer;}
+};
+
+// support for secondlife:///app/appearance SLapps
+class LLAppearanceHandler : public LLCommandHandler
+{
+public:
+	// requests will be throttled from a non-trusted browser
+	LLAppearanceHandler() : LLCommandHandler("appearance", UNTRUSTED_THROTTLE) {}
+
+	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+	{
+		// support secondlife:///app/appearance/show, but for now we just
+		// make all secondlife:///app/appearance SLapps behave this way
+		if (!LLUI::sSettingGroups["config"]->getBOOL("EnableAppearance"))
+		{
+			LLNotificationsUtil::add("NoAppearance", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
+			return true;
+		}
+
+		LLFloaterSidePanelContainer::showPanel("appearance", LLSD());
+		return true;
+	}
+};
+
+LLAppearanceHandler gAppearanceHandler;
+
+
+LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id, const std::string& name)
+{
+	LLInventoryModel::cat_array_t cat_array;
+	LLInventoryModel::item_array_t item_array;
+	LLNameCategoryCollector has_name(name);
+	gInventory.collectDescendentsIf(parent_id,
+									cat_array,
+									item_array,
+									LLInventoryModel::EXCLUDE_TRASH,
+									has_name);
+	if (0 == cat_array.size())
+		return LLUUID();
+	else
+	{
+		LLViewerInventoryCategory *cat = cat_array.at(0);
+		if (cat)
+			return cat->getUUID();
+		else
+		{
+			LL_WARNS() << "null cat" << LL_ENDL;
+			return LLUUID();
+		}
+	}
+}
+
+// We want this to be much lower (e.g. 15.0 is usually fine), bumping
+// up for now until we can diagnose some cases of very slow response
+// to requests.
+const F32 DEFAULT_RETRY_AFTER_INTERVAL = 300.0;
+
+// Given the current back-end problems, retrying is causing too many
+// duplicate items. Bump this back to 2 once they are resolved (or can
+// leave at 0 if the operations become actually reliable).
+const S32 DEFAULT_MAX_RETRIES = 0;
+
+class LLCallAfterInventoryBatchMgr: public LLEventTimer 
+{
+public:
+	LLCallAfterInventoryBatchMgr(const LLUUID& dst_cat_id,
+								 const std::string& phase_name,
+								 nullary_func_t on_completion_func,
+								 nullary_func_t on_failure_func = no_op,
+								 F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
+								 S32 max_retries = DEFAULT_MAX_RETRIES
+		):
+		mDstCatID(dst_cat_id),
+		mTrackingPhase(phase_name),
+		mOnCompletionFunc(on_completion_func),
+		mOnFailureFunc(on_failure_func),
+		mRetryAfter(retry_after),
+		mMaxRetries(max_retries),
+		mPendingRequests(0),
+		mFailCount(0),
+		mCompletionOrFailureCalled(false),
+		mRetryCount(0),
+		LLEventTimer(5.0)
+	{
+		if (!mTrackingPhase.empty())
+		{
+			selfStartPhase(mTrackingPhase);
+		}
+	}
+
+	void addItems(LLInventoryModel::item_array_t& src_items)
+	{
+		for (LLInventoryModel::item_array_t::const_iterator it = src_items.begin();
+			 it != src_items.end();
+			 ++it)
+		{
+			LLViewerInventoryItem* item = *it;
+			llassert(item);
+			addItem(item->getUUID());
+		}
+	}
+
+	// Request or re-request operation for specified item.
+	void addItem(const LLUUID& item_id)
+	{
+		LL_DEBUGS("Avatar") << "item_id " << item_id << LL_ENDL;
+		if (!requestOperation(item_id))
+		{
+			LL_DEBUGS("Avatar") << "item_id " << item_id << " requestOperation false, skipping" << LL_ENDL;
+			return;
+		}
+
+		mPendingRequests++;
+		// On a re-request, this will reset the timer.
+		mWaitTimes[item_id] = LLTimer();
+		if (mRetryCounts.find(item_id) == mRetryCounts.end())
+		{
+			mRetryCounts[item_id] = 0;
+		}
+		else
+		{
+			mRetryCounts[item_id]++;
+		}
+	}
+
+	virtual bool requestOperation(const LLUUID& item_id) = 0;
+
+	void onOp(const LLUUID& src_id, const LLUUID& dst_id, LLTimer timestamp)
+	{
+		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateLateOpRate"))
+		{
+			LL_WARNS() << "Simulating late operation by punting handling to later" << LL_ENDL;
+			doAfterInterval(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,src_id,dst_id,timestamp),
+							mRetryAfter);
+			return;
+		}
+		mPendingRequests--;
+		F32 elapsed = timestamp.getElapsedTimeF32();
+		LL_DEBUGS("Avatar") << "op done, src_id " << src_id << " dst_id " << dst_id << " after " << elapsed << " seconds" << LL_ENDL;
+		if (mWaitTimes.find(src_id) == mWaitTimes.end())
+		{
+			// No longer waiting for this item - either serviced
+			// already or gave up after too many retries.
+			LL_WARNS() << "duplicate or late operation, src_id " << src_id << "dst_id " << dst_id
+					<< " elapsed " << elapsed << " after end " << (S32) mCompletionOrFailureCalled << LL_ENDL;
+		}
+		mTimeStats.push(elapsed);
+		mWaitTimes.erase(src_id);
+		if (mWaitTimes.empty() && !mCompletionOrFailureCalled)
+		{
+			onCompletionOrFailure();
+		}
+	}
+
+	void onCompletionOrFailure()
+	{
+		assert (!mCompletionOrFailureCalled);
+		mCompletionOrFailureCalled = true;
+		
+		// Will never call onCompletion() if any item has been flagged as
+		// a failure - otherwise could wind up with corrupted
+		// outfit, involuntary nudity, etc.
+		reportStats();
+		if (!mTrackingPhase.empty())
+		{
+			selfStopPhase(mTrackingPhase);
+		}
+		if (!mFailCount)
+		{
+			onCompletion();
+		}
+		else
+		{
+			onFailure();
+		}
+	}
+
+	void onFailure()
+	{
+		LL_INFOS() << "failed" << LL_ENDL;
+		mOnFailureFunc();
+	}
+
+	void onCompletion()
+	{
+		LL_INFOS() << "done" << LL_ENDL;
+		mOnCompletionFunc();
+	}
+	
+	// virtual
+	// Will be deleted after returning true - only safe to do this if all callbacks have fired.
+	BOOL tick()
+	{
+		// mPendingRequests will be zero if all requests have been
+		// responded to.  mWaitTimes.empty() will be true if we have
+		// received at least one reply for each UUID.  If requests
+		// have been dropped and retried, these will not necessarily
+		// be the same.  Only safe to return true if all requests have
+		// been serviced, since it will result in this object being
+		// deleted.
+		bool all_done = (mPendingRequests==0);
+
+		if (!mWaitTimes.empty())
+		{
+			LL_WARNS() << "still waiting on " << mWaitTimes.size() << " items" << LL_ENDL;
+			for (std::map<LLUUID,LLTimer>::iterator it = mWaitTimes.begin();
+				 it != mWaitTimes.end();)
+			{
+				// Use a copy of iterator because it may be erased/invalidated.
+				std::map<LLUUID,LLTimer>::iterator curr_it = it;
+				++it;
+				
+				F32 time_waited = curr_it->second.getElapsedTimeF32();
+				S32 retries = mRetryCounts[curr_it->first];
+				if (time_waited > mRetryAfter)
+				{
+					if (retries < mMaxRetries)
+					{
+						LL_DEBUGS("Avatar") << "Waited " << time_waited <<
+							" for " << curr_it->first << ", retrying" << LL_ENDL;
+						mRetryCount++;
+						addItem(curr_it->first);
+					}
+					else
+					{
+						LL_WARNS() << "Giving up on " << curr_it->first << " after too many retries" << LL_ENDL;
+						mWaitTimes.erase(curr_it);
+						mFailCount++;
+					}
+				}
+				if (mWaitTimes.empty())
+				{
+					onCompletionOrFailure();
+				}
+
+			}
+		}
+		return all_done;
+	}
+
+	void reportStats()
+	{
+		LL_DEBUGS("Avatar") << "Phase: " << mTrackingPhase << LL_ENDL;
+		LL_DEBUGS("Avatar") << "mFailCount: " << mFailCount << LL_ENDL;
+		LL_DEBUGS("Avatar") << "mRetryCount: " << mRetryCount << LL_ENDL;
+		LL_DEBUGS("Avatar") << "Times: n " << mTimeStats.getCount() << " min " << mTimeStats.getMinValue() << " max " << mTimeStats.getMaxValue() << LL_ENDL;
+		LL_DEBUGS("Avatar") << "Mean " << mTimeStats.getMean() << " stddev " << mTimeStats.getStdDev() << LL_ENDL;
+	}
+	
+	virtual ~LLCallAfterInventoryBatchMgr()
+	{
+		LL_DEBUGS("Avatar") << "deleting" << LL_ENDL;
+	}
+
+protected:
+	std::string mTrackingPhase;
+	std::map<LLUUID,LLTimer> mWaitTimes;
+	std::map<LLUUID,S32> mRetryCounts;
+	LLUUID mDstCatID;
+	nullary_func_t mOnCompletionFunc;
+	nullary_func_t mOnFailureFunc;
+	F32 mRetryAfter;
+	S32 mMaxRetries;
+	S32 mPendingRequests;
+	S32 mFailCount;
+	S32 mRetryCount;
+	bool mCompletionOrFailureCalled;
+	LLViewerStats::StatsAccumulator mTimeStats;
+};
+
+class LLCallAfterInventoryCopyMgr: public LLCallAfterInventoryBatchMgr
+{
+public:
+	LLCallAfterInventoryCopyMgr(LLInventoryModel::item_array_t& src_items,
+								const LLUUID& dst_cat_id,
+								const std::string& phase_name,
+								nullary_func_t on_completion_func,
+								nullary_func_t on_failure_func = no_op,
+								 F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
+								 S32 max_retries = DEFAULT_MAX_RETRIES
+		):
+		LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries)
+	{
+		addItems(src_items);
+		sInstanceCount++;
+	}
+
+	~LLCallAfterInventoryCopyMgr()
+	{
+		sInstanceCount--;
+	}
+	
+	virtual bool requestOperation(const LLUUID& item_id)
+	{
+		LLViewerInventoryItem *item = gInventory.getItem(item_id);
+		llassert(item);
+		LL_DEBUGS("Avatar") << "copying item " << item_id << LL_ENDL;
+		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
+		{
+			LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << LL_ENDL;
+			return true;
+		}
+		copy_inventory_item(
+			gAgent.getID(),
+			item->getPermissions().getOwner(),
+			item->getUUID(),
+			mDstCatID,
+			std::string(),
+			new LLBoostFuncInventoryCallback(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer()))
+			);
+		return true;
+	}
+
+	static S32 getInstanceCount() { return sInstanceCount; }
+	
+private:
+	static S32 sInstanceCount;
+};
+
+S32 LLCallAfterInventoryCopyMgr::sInstanceCount = 0;
+
+class LLWearCategoryAfterCopy: public LLInventoryCallback
+{
+public:
+	LLWearCategoryAfterCopy(bool append):
+		mAppend(append)
+	{}
+
+	// virtual
+	void fire(const LLUUID& id)
+	{
+		// Wear the inventory category.
+		LLInventoryCategory* cat = gInventory.getCategory(id);
+		LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(cat, mAppend);
+	}
+
+private:
+	bool mAppend;
+};
+
+class LLTrackPhaseWrapper : public LLInventoryCallback
+{
+public:
+	LLTrackPhaseWrapper(const std::string& phase_name, LLPointer<LLInventoryCallback> cb = NULL):
+		mTrackingPhase(phase_name),
+		mCB(cb)
+	{
+		selfStartPhase(mTrackingPhase);
+	}
+
+	// virtual
+	void fire(const LLUUID& id)
+	{
+		if (mCB)
+		{
+			mCB->fire(id);
+		}
+	}
+
+	// virtual
+	~LLTrackPhaseWrapper()
+	{
+		selfStopPhase(mTrackingPhase);
+	}
+
+protected:
+	std::string mTrackingPhase;
+	LLPointer<LLInventoryCallback> mCB;
+};
+
+LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool enforce_item_restrictions,
+														 bool enforce_ordering,
+														 nullary_func_t post_update_func 
+	):
+	mFireCount(0),
+	mEnforceItemRestrictions(enforce_item_restrictions),
+	mEnforceOrdering(enforce_ordering),
+	mPostUpdateFunc(post_update_func)
+{
+	selfStartPhase("update_appearance_on_destroy");
+}
+
+void LLUpdateAppearanceOnDestroy::fire(const LLUUID& inv_item)
+{
+	LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(inv_item);
+	const std::string item_name = item ? item->getName() : "ITEM NOT FOUND";
+#ifndef LL_RELEASE_FOR_DOWNLOAD
+	LL_DEBUGS("Avatar") << self_av_string() << "callback fired [ name:" << item_name << " UUID:" << inv_item << " count:" << mFireCount << " ] " << LL_ENDL;
+#endif
+	mFireCount++;
+}
+
+LLUpdateAppearanceOnDestroy::~LLUpdateAppearanceOnDestroy()
+{
+	if (!LLApp::isExiting())
+	{
+		// speculative fix for MAINT-1150
+		LL_INFOS("Avatar") << self_av_string() << "done update appearance on destroy" << LL_ENDL;
+
+		selfStopPhase("update_appearance_on_destroy");
+
+		LLAppearanceMgr::instance().updateAppearanceFromCOF(mEnforceItemRestrictions,
+															mEnforceOrdering,
+															mPostUpdateFunc);
+	}
+}
+
+LLUpdateAppearanceAndEditWearableOnDestroy::LLUpdateAppearanceAndEditWearableOnDestroy(const LLUUID& item_id):
+	mItemID(item_id)
+{
+}
+
+void edit_wearable_and_customize_avatar(LLUUID item_id)
+{
+	// Start editing the item if previously requested.
+	gAgentWearables.editWearableIfRequested(item_id);
+	
+	// TODO: camera mode may not be changed if a debug setting is tweaked
+	if( gAgentCamera.cameraCustomizeAvatar() )
+	{
+		// If we're in appearance editing mode, the current tab may need to be refreshed
+		LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(
+			LLFloaterSidePanelContainer::getPanel("appearance"));
+		if (panel)
+		{
+			panel->showDefaultSubpart();
+		}
+	}
+}
+
+LLUpdateAppearanceAndEditWearableOnDestroy::~LLUpdateAppearanceAndEditWearableOnDestroy()
+{
+	if (!LLApp::isExiting())
+	{
+		LLAppearanceMgr::instance().updateAppearanceFromCOF(
+			true,true,
+			boost::bind(edit_wearable_and_customize_avatar, mItemID));
+	}
+}
+
+
+struct LLFoundData
+{
+	LLFoundData() :
+		mAssetType(LLAssetType::AT_NONE),
+		mWearableType(LLWearableType::WT_INVALID),
+		mWearable(NULL) {}
+
+	LLFoundData(const LLUUID& item_id,
+				const LLUUID& asset_id,
+				const std::string& name,
+				const LLAssetType::EType& asset_type,
+				const LLWearableType::EType& wearable_type,
+				const bool is_replacement = false
+		) :
+		mItemID(item_id),
+		mAssetID(asset_id),
+		mName(name),
+		mAssetType(asset_type),
+		mWearableType(wearable_type),
+		mIsReplacement(is_replacement),
+		mWearable( NULL ) {}
+	
+	LLUUID mItemID;
+	LLUUID mAssetID;
+	std::string mName;
+	LLAssetType::EType mAssetType;
+	LLWearableType::EType mWearableType;
+	LLViewerWearable* mWearable;
+	bool mIsReplacement;
+};
+
+	
+class LLWearableHoldingPattern
+{
+	LOG_CLASS(LLWearableHoldingPattern);
+
+public:
+	LLWearableHoldingPattern();
+	~LLWearableHoldingPattern();
+
+	bool pollFetchCompletion();
+	void onFetchCompletion();
+	bool isFetchCompleted();
+	bool isTimedOut();
+
+	void checkMissingWearables();
+	bool pollMissingWearables();
+	bool isMissingCompleted();
+	void recoverMissingWearable(LLWearableType::EType type);
+	void clearCOFLinksForMissingWearables();
+	
+	void onWearableAssetFetch(LLViewerWearable *wearable);
+	void onAllComplete();
+
+	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 setGestItems(const LLInventoryModel::item_array_t& items);
+	bool isMostRecent();
+	void handleLateArrivals();
+	void resetTime(F32 timeout);
+	static S32 countActive() { return sActiveHoldingPatterns.size(); }
+	S32 index() { return mIndex; }
+	
+private:
+	found_list_t mFoundList;
+	LLInventoryModel::item_array_t mObjItems;
+	LLInventoryModel::item_array_t mGestItems;
+	typedef std::set<S32> type_set_t;
+	type_set_t mTypesToRecover;
+	type_set_t mTypesToLink;
+	S32 mResolved;
+	LLTimer mWaitTime;
+	bool mFired;
+	typedef std::set<LLWearableHoldingPattern*> type_set_hp;
+	static type_set_hp sActiveHoldingPatterns;
+	static S32 sNextIndex;
+	S32 mIndex;
+	bool mIsMostRecent;
+	std::set<LLViewerWearable*> mLateArrivals;
+	bool mIsAllComplete;
+};
+
+LLWearableHoldingPattern::type_set_hp LLWearableHoldingPattern::sActiveHoldingPatterns;
+S32 LLWearableHoldingPattern::sNextIndex = 0;
+
+LLWearableHoldingPattern::LLWearableHoldingPattern():
+	mResolved(0),
+	mFired(false),
+	mIsMostRecent(true),
+	mIsAllComplete(false)
+{
+	if (countActive()>0)
+	{
+		LL_INFOS() << "Creating LLWearableHoldingPattern when "
+				   << countActive()
+				   << " other attempts are active."
+				   << " Flagging others as invalid."
+				   << LL_ENDL;
+		for (type_set_hp::iterator it = sActiveHoldingPatterns.begin();
+			 it != sActiveHoldingPatterns.end();
+			 ++it)
+		{
+			(*it)->mIsMostRecent = false;
+		}
+			 
+	}
+	mIndex = sNextIndex++;
+	sActiveHoldingPatterns.insert(this);
+	LL_DEBUGS("Avatar") << "HP " << index() << " created" << LL_ENDL;
+	selfStartPhase("holding_pattern");
+}
+
+LLWearableHoldingPattern::~LLWearableHoldingPattern()
+{
+	sActiveHoldingPatterns.erase(this);
+	if (isMostRecent())
+	{
+		selfStopPhase("holding_pattern");
+	}
+	LL_DEBUGS("Avatar") << "HP " << index() << " deleted" << LL_ENDL;
+}
+
+bool LLWearableHoldingPattern::isMostRecent()
+{
+	return mIsMostRecent;
+}
+
+LLWearableHoldingPattern::found_list_t& LLWearableHoldingPattern::getFoundList()
+{
+	return mFoundList;
+}
+
+void LLWearableHoldingPattern::eraseTypeToLink(LLWearableType::EType type)
+{
+	mTypesToLink.erase(type);
+}
+
+void LLWearableHoldingPattern::eraseTypeToRecover(LLWearableType::EType type)
+{
+	mTypesToRecover.erase(type);
+}
+
+void LLWearableHoldingPattern::setObjItems(const LLInventoryModel::item_array_t& items)
+{
+	mObjItems = items;
+}
+
+void LLWearableHoldingPattern::setGestItems(const LLInventoryModel::item_array_t& items)
+{
+	mGestItems = items;
+}
+
+bool LLWearableHoldingPattern::isFetchCompleted()
+{
+	return (mResolved >= (S32)getFoundList().size()); // have everything we were waiting for?
+}
+
+bool LLWearableHoldingPattern::isTimedOut()
+{
+	return mWaitTime.hasExpired();
+}
+
+void LLWearableHoldingPattern::checkMissingWearables()
+{
+	if (!isMostRecent())
+	{
+		// runway why don't we actually skip here?
+		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+	}
+
+	std::vector<S32> found_by_type(LLWearableType::WT_COUNT,0);
+	std::vector<S32> requested_by_type(LLWearableType::WT_COUNT,0);
+	for (found_list_t::iterator it = getFoundList().begin(); it != getFoundList().end(); ++it)
+	{
+		LLFoundData &data = *it;
+		if (data.mWearableType < LLWearableType::WT_COUNT)
+			requested_by_type[data.mWearableType]++;
+		if (data.mWearable)
+			found_by_type[data.mWearableType]++;
+	}
+
+	for (S32 type = 0; type < LLWearableType::WT_COUNT; ++type)
+	{
+		if (requested_by_type[type] > found_by_type[type])
+		{
+			LL_WARNS() << self_av_string() << "got fewer wearables than requested, type " << type << ": requested " << requested_by_type[type] << ", found " << found_by_type[type] << LL_ENDL;
+		}
+		if (found_by_type[type] > 0)
+			continue;
+		if (
+			// If at least one wearable of certain types (pants/shirt/skirt)
+			// was requested but none was found, create a default asset as a replacement.
+			// In all other cases, don't do anything.
+			// For critical types (shape/hair/skin/eyes), this will keep the avatar as a cloud 
+			// due to logic in LLVOAvatarSelf::getIsCloud().
+			// For non-critical types (tatoo, socks, etc.) the wearable will just be missing.
+			(requested_by_type[type] > 0) &&  
+			((type == LLWearableType::WT_PANTS) || (type == LLWearableType::WT_SHIRT) || (type == LLWearableType::WT_SKIRT)))
+		{
+			mTypesToRecover.insert(type);
+			mTypesToLink.insert(type);
+			recoverMissingWearable((LLWearableType::EType)type);
+			LL_WARNS() << self_av_string() << "need to replace " << type << LL_ENDL; 
+		}
+	}
+
+	resetTime(60.0F);
+
+	if (isMostRecent())
+	{
+		selfStartPhase("get_missing_wearables_2");
+	}
+	if (!pollMissingWearables())
+	{
+		doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollMissingWearables,this));
+	}
+}
+
+void LLWearableHoldingPattern::onAllComplete()
+{
+	if (isAgentAvatarValid())
+	{
+		gAgentAvatarp->outputRezTiming("Agent wearables fetch complete");
+	}
+
+	if (!isMostRecent())
+	{
+		// runway need to skip here?
+		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+	}
+
+	// Activate all gestures in this folder
+	if (mGestItems.size() > 0)
+	{
+		LL_DEBUGS("Avatar") << self_av_string() << "Activating " << mGestItems.size() << " gestures" << LL_ENDL;
+		
+		LLGestureMgr::instance().activateGestures(mGestItems);
+		
+		// Update the inventory item labels to reflect the fact
+		// they are active.
+		LLViewerInventoryCategory* catp =
+			gInventory.getCategory(LLAppearanceMgr::instance().getCOF());
+		
+		if (catp)
+		{
+			gInventory.updateCategory(catp);
+			gInventory.notifyObservers();
+		}
+	}
+
+	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->clearAttachmentPosOverrides();
+
+		// 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->addAttachmentPosOverridesForObject(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())
+	{
+		// Only safe to delete if all wearable callbacks and all missing wearables completed.
+		delete this;
+	}
+	else
+	{
+		mIsAllComplete = true;
+		handleLateArrivals();
+	}
+}
+
+void LLWearableHoldingPattern::onFetchCompletion()
+{
+	if (isMostRecent())
+	{
+		selfStopPhase("get_wearables_2");
+	}
+		
+	if (!isMostRecent())
+	{
+		// runway skip here?
+		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+	}
+
+	checkMissingWearables();
+}
+
+// Runs as an idle callback until all wearables are fetched (or we time out).
+bool LLWearableHoldingPattern::pollFetchCompletion()
+{
+	if (!isMostRecent())
+	{
+		// runway skip here?
+		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+	}
+
+	bool completed = isFetchCompleted();
+	bool timed_out = isTimedOut();
+	bool done = completed || timed_out;
+
+	if (done)
+	{
+		LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " polling, done status: " << completed << " timed out " << timed_out
+				<< " elapsed " << mWaitTime.getElapsedTimeF32() << LL_ENDL;
+
+		mFired = true;
+		
+		if (timed_out)
+		{
+			LL_WARNS() << self_av_string() << "Exceeded max wait time for wearables, updating appearance based on what has arrived" << LL_ENDL;
+		}
+
+		onFetchCompletion();
+	}
+	return done;
+}
+
+void recovered_item_link_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
+{
+	if (!holder->isMostRecent())
+	{
+		LL_WARNS() << "HP " << holder->index() << " skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+		// runway skip here?
+	}
+
+	LL_INFOS() << "HP " << holder->index() << " recovered item link for type " << type << LL_ENDL;
+	holder->eraseTypeToLink(type);
+	// Add wearable to FoundData for actual wearing
+	LLViewerInventoryItem *item = gInventory.getItem(item_id);
+	LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
+
+	if (linked_item)
+	{
+		gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
+			
+		if (item)
+		{
+			LLFoundData found(linked_item->getUUID(),
+							  linked_item->getAssetUUID(),
+							  linked_item->getName(),
+							  linked_item->getType(),
+							  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID,
+							  true // is replacement
+				);
+			found.mWearable = wearable;
+			holder->getFoundList().push_front(found);
+		}
+		else
+		{
+			LL_WARNS() << self_av_string() << "inventory link not found for recovered wearable" << LL_ENDL;
+		}
+	}
+	else
+	{
+		LL_WARNS() << self_av_string() << "HP " << holder->index() << " inventory link not found for recovered wearable" << LL_ENDL;
+	}
+}
+
+void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
+{
+	if (!holder->isMostRecent())
+	{
+		// runway skip here?
+		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+	}
+
+	LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL;
+	LLConstPointer<LLInventoryObject> itemp = gInventory.getItem(item_id);
+	wearable->setItemID(item_id);
+	holder->eraseTypeToRecover(type);
+	llassert(itemp);
+	if (itemp)
+	{
+		LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder));
+
+		link_inventory_object(LLAppearanceMgr::instance().getCOF(), itemp, cb);
+	}
+}
+
+void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type)
+{
+	if (!isMostRecent())
+	{
+		// runway skip here?
+		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+	}
+	
+		// Try to recover by replacing missing wearable with a new one.
+	LLNotificationsUtil::add("ReplacedMissingWearable");
+	LL_DEBUGS() << "Wearable " << LLWearableType::getTypeLabel(type)
+				<< " could not be downloaded.  Replaced inventory item with default wearable." << LL_ENDL;
+	LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
+
+	// Add a new one in the lost and found folder.
+	const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
+	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_cb,_1,type,wearable,this));
+
+	create_inventory_item(gAgent.getID(),
+						  gAgent.getSessionID(),
+						  lost_and_found_id,
+						  wearable->getTransactionID(),
+						  wearable->getName(),
+						  wearable->getDescription(),
+						  wearable->getAssetType(),
+						  LLInventoryType::IT_WEARABLE,
+						  wearable->getType(),
+						  wearable->getPermissions().getMaskNextOwner(),
+						  cb);
+}
+
+bool LLWearableHoldingPattern::isMissingCompleted()
+{
+	return mTypesToLink.size()==0 && mTypesToRecover.size()==0;
+}
+
+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);
+		}
+	}
+}
+
+bool LLWearableHoldingPattern::pollMissingWearables()
+{
+	if (!isMostRecent())
+	{
+		// runway skip here?
+		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+	}
+	
+	bool timed_out = isTimedOut();
+	bool missing_completed = isMissingCompleted();
+	bool done = timed_out || missing_completed;
+
+	if (!done)
+	{
+		LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " polling missing wearables, waiting for items " << mTypesToRecover.size()
+				<< " links " << mTypesToLink.size()
+				<< " wearables, timed out " << timed_out
+				<< " elapsed " << mWaitTime.getElapsedTimeF32()
+				<< " done " << done << LL_ENDL;
+	}
+
+	if (done)
+	{
+		if (isMostRecent())
+		{
+			selfStopPhase("get_missing_wearables_2");
+		}
+
+		gAgentAvatarp->debugWearablesLoaded();
+
+		// BAP - if we don't call clearCOFLinksForMissingWearables()
+		// here, we won't have to add the link back in later if the
+		// wearable arrives late.  This is to avoid corruption of
+		// wearable ordering info.  Also has the effect of making
+		// unworn item links visible in the COF under some
+		// circumstances.
+
+		//clearCOFLinksForMissingWearables();
+		onAllComplete();
+	}
+	return done;
+}
+
+// Handle wearables that arrived after the timeout period expired.
+void LLWearableHoldingPattern::handleLateArrivals()
+{
+	// Only safe to run if we have previously finished the missing
+	// wearables and other processing - otherwise we could be in some
+	// intermediate state - but have not been superceded by a later
+	// outfit change request.
+	if (mLateArrivals.size() == 0)
+	{
+		// Nothing to process.
+		return;
+	}
+	if (!isMostRecent())
+	{
+		LL_WARNS() << self_av_string() << "Late arrivals not handled - outfit change no longer valid" << LL_ENDL;
+	}
+	if (!mIsAllComplete)
+	{
+		LL_WARNS() << self_av_string() << "Late arrivals not handled - in middle of missing wearables processing" << LL_ENDL;
+	}
+
+	LL_INFOS("Avatar") << self_av_string() << "HP " << index() << " need to handle " << mLateArrivals.size() << " late arriving wearables" << LL_ENDL;
+
+	// Update mFoundList using late-arriving wearables.
+	std::set<LLWearableType::EType> replaced_types;
+	for (LLWearableHoldingPattern::found_list_t::iterator iter = getFoundList().begin();
+		 iter != getFoundList().end(); ++iter)
+	{
+		LLFoundData& data = *iter;
+		for (std::set<LLViewerWearable*>::iterator wear_it = mLateArrivals.begin();
+			 wear_it != mLateArrivals.end();
+			 ++wear_it)
+		{
+			LLViewerWearable *wearable = *wear_it;
+
+			if(wearable->getAssetID() == data.mAssetID)
+			{
+				data.mWearable = wearable;
+
+				replaced_types.insert(data.mWearableType);
+
+				// BAP - if we didn't call
+				// clearCOFLinksForMissingWearables() earlier, we
+				// don't need to restore the link here.  Fixes
+				// wearable ordering problems.
+
+				// LLAppearanceMgr::instance().addCOFItemLink(data.mItemID,false);
+
+				// BAP failing this means inventory or asset server
+				// are corrupted in a way we don't handle.
+				llassert((data.mWearableType < LLWearableType::WT_COUNT) && (wearable->getType() == data.mWearableType));
+				break;
+			}
+		}
+	}
+
+	// Remove COF links for any default wearables previously used to replace the late arrivals.
+	// All this pussyfooting around with a while loop and explicit
+	// iterator incrementing is to allow removing items from the list
+	// without clobbering the iterator we're using to navigate.
+	LLWearableHoldingPattern::found_list_t::iterator iter = getFoundList().begin();
+	while (iter != getFoundList().end())
+	{
+		LLFoundData& data = *iter;
+
+		// If an item of this type has recently shown up, removed the corresponding replacement wearable from COF.
+		if (data.mWearable && data.mIsReplacement &&
+			replaced_types.find(data.mWearableType) != replaced_types.end())
+		{
+			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
+			std::list<LLFoundData>::iterator clobber_ator = iter;
+			++iter;
+			getFoundList().erase(clobber_ator);
+		}
+		else
+		{
+			++iter;
+		}
+	}
+
+	// Clear contents of late arrivals.
+	mLateArrivals.clear();
+
+	// Update appearance based on mFoundList
+	LLAppearanceMgr::instance().updateAgentWearables(this);
+}
+
+void LLWearableHoldingPattern::resetTime(F32 timeout)
+{
+	mWaitTime.reset();
+	mWaitTime.setTimerExpirySec(timeout);
+}
+
+void LLWearableHoldingPattern::onWearableAssetFetch(LLViewerWearable *wearable)
+{
+	if (!isMostRecent())
+	{
+		LL_WARNS() << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << LL_ENDL;
+	}
+	
+	mResolved += 1;  // just counting callbacks, not successes.
+	LL_DEBUGS("Avatar") << self_av_string() << "HP " << index() << " resolved " << mResolved << "/" << getFoundList().size() << LL_ENDL;
+	if (!wearable)
+	{
+		LL_WARNS() << self_av_string() << "no wearable found" << LL_ENDL;
+	}
+
+	if (mFired)
+	{
+		LL_WARNS() << self_av_string() << "called after holder fired" << LL_ENDL;
+		if (wearable)
+		{
+			mLateArrivals.insert(wearable);
+			if (mIsAllComplete)
+			{
+				handleLateArrivals();
+			}
+		}
+		return;
+	}
+
+	if (!wearable)
+	{
+		return;
+	}
+
+	for (LLWearableHoldingPattern::found_list_t::iterator iter = getFoundList().begin();
+		 iter != getFoundList().end(); ++iter)
+	{
+		LLFoundData& data = *iter;
+		if(wearable->getAssetID() == data.mAssetID)
+		{
+			// Failing this means inventory or asset server are corrupted in a way we don't handle.
+			if ((data.mWearableType >= LLWearableType::WT_COUNT) || (wearable->getType() != data.mWearableType))
+			{
+				LL_WARNS() << self_av_string() << "recovered wearable but type invalid. inventory wearable type: " << data.mWearableType << " asset wearable type: " << wearable->getType() << LL_ENDL;
+				break;
+			}
+
+			data.mWearable = wearable;
+		}
+	}
+}
+
+static void onWearableAssetFetch(LLViewerWearable* wearable, void* data)
+{
+	LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
+	holder->onWearableAssetFetch(wearable);
+}
+
+
+static void removeDuplicateItems(LLInventoryModel::item_array_t& items)
+{
+	LLInventoryModel::item_array_t new_items;
+	std::set<LLUUID> items_seen;
+	std::deque<LLViewerInventoryItem*> tmp_list;
+	// Traverse from the front and keep the first of each item
+	// encountered, so we actually keep the *last* of each duplicate
+	// item.  This is needed to give the right priority when adding
+	// duplicate items to an existing outfit.
+	for (S32 i=items.size()-1; i>=0; i--)
+	{
+		LLViewerInventoryItem *item = items.at(i);
+		LLUUID item_id = item->getLinkedUUID();
+		if (items_seen.find(item_id)!=items_seen.end())
+			continue;
+		items_seen.insert(item_id);
+		tmp_list.push_front(item);
+	}
+	for (std::deque<LLViewerInventoryItem*>::iterator it = tmp_list.begin();
+		 it != tmp_list.end();
+		 ++it)
+	{
+		new_items.push_back(*it);
+	}
+	items = new_items;
+}
+
+//=========================================================================
+class LLAppearanceMgrHttpHandler : public LLHttpSDHandler
+{
+public:
+	LLAppearanceMgrHttpHandler(const std::string& capabilityURL, LLAppearanceMgr *mgr) :
+		LLHttpSDHandler(capabilityURL),
+		mManager(mgr)
+	{ }
+
+	virtual ~LLAppearanceMgrHttpHandler()
+	{ }
+
 	virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
 
-protected:
-	virtual void onSuccess(LLCore::HttpResponse * response, LLSD &content);
-	virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
-
-private:
-	static void debugCOF(const LLSD& content);
-
-	LLAppearanceMgr *mManager;
-
-};
-
-//-------------------------------------------------------------------------
-void LLAppearanceMgrHttpHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+protected:
+	virtual void onSuccess(LLCore::HttpResponse * response, LLSD &content);
+	virtual void onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status);
+
+private:
+	static void debugCOF(const LLSD& content);
+
+	LLAppearanceMgr *mManager;
+
+};
+
+//-------------------------------------------------------------------------
+void LLAppearanceMgrHttpHandler::onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response)
+{
+	mManager->decrementInFlightCounter();
+
+	LLHttpSDHandler::onCompleted(handle, response);
+}
+
+void LLAppearanceMgrHttpHandler::onSuccess(LLCore::HttpResponse * response, LLSD &content)
+{
+	if (!content.isMap())
+	{
+		LLCore::HttpStatus status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents");
+		response->setStatus(status);
+		onFailure(response, status);
+		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+		{
+			debugCOF(content);
+		}
+		return;
+	}
+	if (content["success"].asBoolean())
+	{
+		LL_DEBUGS("Avatar") << "succeeded" << LL_ENDL;
+		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+		{
+			dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_ok", content);
+		}
+	}
+	else
+	{
+		LLCore::HttpStatus status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Non-success response");
+		response->setStatus(status);
+		onFailure(response, status);
+		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+		{
+			debugCOF(content);
+		}
+		return;
+	}
+}
+
+void LLAppearanceMgrHttpHandler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
+{
+	LL_WARNS("Avatar") << "Appearance Mgr request failed to " << getUri()
+		<< ". Reason code: (" << status.toTerseString() << ") "
+		<< status.toString() << LL_ENDL;
+}
+
+void LLAppearanceMgrHttpHandler::debugCOF(const LLSD& content)
+{
+	dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
+
+	LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger()
+		<< " ================================= " << LL_ENDL;
+	std::set<LLUUID> ais_items, local_items;
+	const LLSD& cof_raw = content["cof_raw"];
+	for (LLSD::array_const_iterator it = cof_raw.beginArray();
+		it != cof_raw.endArray(); ++it)
+	{
+		const LLSD& item = *it;
+		if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF())
+		{
+			ais_items.insert(item["item_id"].asUUID());
+			if (item["type"].asInteger() == 24) // link
+			{
+				LL_INFOS("Avatar") << "AIS Link: item_id: " << item["item_id"].asUUID()
+					<< " linked_item_id: " << item["asset_id"].asUUID()
+					<< " name: " << item["name"].asString()
+					<< LL_ENDL;
+			}
+			else if (item["type"].asInteger() == 25) // folder link
+			{
+				LL_INFOS("Avatar") << "AIS Folder link: item_id: " << item["item_id"].asUUID()
+					<< " linked_item_id: " << item["asset_id"].asUUID()
+					<< " name: " << item["name"].asString()
+					<< LL_ENDL;
+			}
+			else
+			{
+				LL_INFOS("Avatar") << "AIS Other: item_id: " << item["item_id"].asUUID()
+					<< " linked_item_id: " << item["asset_id"].asUUID()
+					<< " name: " << item["name"].asString()
+					<< " type: " << item["type"].asInteger()
+					<< LL_ENDL;
+			}
+		}
+	}
+	LL_INFOS("Avatar") << LL_ENDL;
+	LL_INFOS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger()
+		<< " ================================= " << LL_ENDL;
+	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();
+		local_items.insert(inv_item->getUUID());
+		LL_INFOS("Avatar") << "LOCAL: item_id: " << inv_item->getUUID()
+			<< " linked_item_id: " << inv_item->getLinkedUUID()
+			<< " name: " << inv_item->getName()
+			<< " parent: " << inv_item->getParentUUID()
+			<< LL_ENDL;
+	}
+	LL_INFOS("Avatar") << " ================================= " << LL_ENDL;
+	S32 local_only = 0, ais_only = 0;
+	for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it)
+	{
+		if (ais_items.find(*it) == ais_items.end())
+		{
+			LL_INFOS("Avatar") << "LOCAL ONLY: " << *it << LL_ENDL;
+			local_only++;
+		}
+	}
+	for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)
+	{
+		if (local_items.find(*it) == local_items.end())
+		{
+			LL_INFOS("Avatar") << "AIS ONLY: " << *it << LL_ENDL;
+			ais_only++;
+		}
+	}
+	if (local_only == 0 && ais_only == 0)
+	{
+		LL_INFOS("Avatar") << "COF contents identical, only version numbers differ (req "
+			<< content["observed"].asInteger()
+			<< " rcv " << content["expected"].asInteger()
+			<< ")" << LL_ENDL;
+	}
+}
+
+//=========================================================================
+
+const LLUUID LLAppearanceMgr::getCOF() const
+{
+	return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
+}
+
+S32 LLAppearanceMgr::getCOFVersion() const
+{
+	LLViewerInventoryCategory *cof = gInventory.getCategory(getCOF());
+	if (cof)
+	{
+		return cof->getVersion();
+	}
+	else
+	{
+		return LLViewerInventoryCategory::VERSION_UNKNOWN;
+	}
+}
+
+const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink()
+{
+	const LLUUID& current_outfit_cat = getCOF();
+	LLInventoryModel::cat_array_t cat_array;
+	LLInventoryModel::item_array_t item_array;
+	// Can't search on FT_OUTFIT since links to categories return FT_CATEGORY for type since they don't
+	// return preferred type.
+	LLIsType is_category( LLAssetType::AT_CATEGORY ); 
+	gInventory.collectDescendentsIf(current_outfit_cat,
+									cat_array,
+									item_array,
+									false,
+									is_category);
+	for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
+		 iter != item_array.end();
+		 iter++)
+	{
+		const LLViewerInventoryItem *item = (*iter);
+		const LLViewerInventoryCategory *cat = item->getLinkedCategory();
+		if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
+		{
+			const LLUUID parent_id = cat->getParentUUID();
+			LLViewerInventoryCategory*  parent_cat =  gInventory.getCategory(parent_id);
+			// if base outfit moved to trash it means that we don't have base outfit
+			if (parent_cat != NULL && parent_cat->getPreferredType() == LLFolderType::FT_TRASH)
+			{
+				return NULL;
+			}
+			return item;
+		}
+	}
+	return NULL;
+}
+
+bool LLAppearanceMgr::getBaseOutfitName(std::string& name)
+{
+	const LLViewerInventoryItem* outfit_link = getBaseOutfitLink();
+	if(outfit_link)
+	{
+		const LLViewerInventoryCategory *cat = outfit_link->getLinkedCategory();
+		if (cat)
+		{
+			name = cat->getName();
+			return true;
+		}
+	}
+	return false;
+}
+
+const LLUUID LLAppearanceMgr::getBaseOutfitUUID()
+{
+	const LLViewerInventoryItem* outfit_link = getBaseOutfitLink();
+	if (!outfit_link || !outfit_link->getIsLinkType()) return LLUUID::null;
+
+	const LLViewerInventoryCategory* outfit_cat = outfit_link->getLinkedCategory();
+	if (!outfit_cat) return LLUUID::null;
+
+	if (outfit_cat->getPreferredType() != LLFolderType::FT_OUTFIT)
+	{
+		LL_WARNS() << "Expected outfit type:" << LLFolderType::FT_OUTFIT << " but got type:" << outfit_cat->getType() << " for folder name:" << outfit_cat->getName() << LL_ENDL;
+		return LLUUID::null;
+	}
+
+	return outfit_cat->getUUID();
+}
+
+void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace = false)
+{
+	if (inv_item.isNull())
+		return;
+	
+	LLViewerInventoryItem *item = gInventory.getItem(inv_item);
+	if (item)
+	{
+		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, do_replace);
+	}
+}
+
+bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear,
+									   bool do_update,
+									   bool replace,
+									   LLPointer<LLInventoryCallback> cb)
+{
+
+	if (item_id_to_wear.isNull()) return false;
+
+	// *TODO: issue with multi-wearable should be fixed:
+	// in this case this method will be called N times - loading started for each item
+	// and than N times will be called - loading completed for each item.
+	// That means subscribers will be notified that loading is done after first item in a batch is worn.
+	// (loading indicator disappears for example before all selected items are worn)
+	// Have not fix this issue for 2.1 because of stability reason. EXT-7777.
+
+	// Disabled for now because it is *not* acceptable to call updateAppearanceFromCOF() multiple times
+//	gAgentWearables.notifyLoadingStarted();
+
+	LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear);
+	if (!item_to_wear) return false;
+
+	if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID()))
+	{
+		LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb,_1,replace));
+		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(), cb);
+		return false;
+	} 
+	else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID()))
+	{
+		return false; // not in library and not in agent's inventory
+	}
+	else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH)))
+	{
+		LLNotificationsUtil::add("CannotWearTrash");
+		return false;
+	}
+	else if (isLinkedInCOF(item_to_wear->getUUID())) // EXT-84911
+	{
+		return false;
+	}
+
+	switch (item_to_wear->getType())
+	{
+		case LLAssetType::AT_CLOTHING:
+		if (gAgentWearables.areWearablesLoaded())
+		{
+			if (!cb && do_update)
+			{
+				cb = new LLUpdateAppearanceAndEditWearableOnDestroy(item_id_to_wear);
+			}
+			S32 wearable_count = gAgentWearables.getWearableCount(item_to_wear->getWearableType());
+			if ((replace && wearable_count != 0) ||
+				(wearable_count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) )
+			{
+				LLUUID item_id = gAgentWearables.getWearableItemID(item_to_wear->getWearableType(),
+																   wearable_count-1);
+				removeCOFItemLinks(item_id, cb);
+			}
+
+			addCOFItemLink(item_to_wear, cb);
+		} 
+		break;
+
+		case LLAssetType::AT_BODYPART:
+		// TODO: investigate wearables may not be loaded at this point EXT-8231
+		
+		// Remove the existing wearables of the same type.
+		// Remove existing body parts anyway because we must not be able to wear e.g. two skins.
+		removeCOFLinksOfType(item_to_wear->getWearableType());
+		if (!cb && do_update)
+		{
+			cb = new LLUpdateAppearanceAndEditWearableOnDestroy(item_id_to_wear);
+		}
+		addCOFItemLink(item_to_wear, cb);
+		break;
+
+		case LLAssetType::AT_OBJECT:
+		rez_attachment(item_to_wear, NULL, replace);
+		break;
+
+		default: return false;;
+	}
+
+	return true;
+}
+
+// Update appearance from outfit folder.
+void LLAppearanceMgr::changeOutfit(bool proceed, const LLUUID& category, bool append)
+{
+	if (!proceed)
+		return;
+	LLAppearanceMgr::instance().updateCOF(category,append);
+}
+
+void LLAppearanceMgr::replaceCurrentOutfit(const LLUUID& new_outfit)
+{
+	LLViewerInventoryCategory* cat = gInventory.getCategory(new_outfit);
+	wearInventoryCategory(cat, false, false);
+}
+
+// Open outfit renaming dialog.
+void LLAppearanceMgr::renameOutfit(const LLUUID& outfit_id)
+{
+	LLViewerInventoryCategory* cat = gInventory.getCategory(outfit_id);
+	if (!cat)
+	{
+		return;
+	}
+
+	LLSD args;
+	args["NAME"] = cat->getName();
+
+	LLSD payload;
+	payload["cat_id"] = outfit_id;
+
+	LLNotificationsUtil::add("RenameOutfit", args, payload, boost::bind(onOutfitRename, _1, _2));
+}
+
+// User typed new outfit name.
+// static
+void LLAppearanceMgr::onOutfitRename(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if (option != 0) return; // canceled
+
+	std::string outfit_name = response["new_name"].asString();
+	LLStringUtil::trim(outfit_name);
+	if (!outfit_name.empty())
+	{
+		LLUUID cat_id = notification["payload"]["cat_id"].asUUID();
+		rename_category(&gInventory, cat_id, outfit_name);
+	}
+}
+
+void LLAppearanceMgr::setOutfitLocked(bool locked)
+{
+	if (mOutfitLocked == locked)
+	{
+		return;
+	}
+
+	mOutfitLocked = locked;
+	if (locked)
+	{
+		mUnlockOutfitTimer->reset();
+		mUnlockOutfitTimer->start();
+	}
+	else
+	{
+		mUnlockOutfitTimer->stop();
+	}
+
+	LLOutfitObserver::instance().notifyOutfitLockChanged();
+}
+
+void LLAppearanceMgr::addCategoryToCurrentOutfit(const LLUUID& cat_id)
+{
+	LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
+	wearInventoryCategory(cat, false, true);
+}
+
+void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id)
+{
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLFindWearablesEx collector(/*is_worn=*/ true, /*include_body_parts=*/ false);
+
+	gInventory.collectDescendentsIf(cat_id, cats, items, FALSE, collector);
+
+	LLInventoryModel::item_array_t::const_iterator it = items.begin();
+	const LLInventoryModel::item_array_t::const_iterator it_end = items.end();
+	uuid_vec_t uuids_to_remove;
+	for( ; it_end != it; ++it)
+	{
+		LLViewerInventoryItem* item = *it;
+		uuids_to_remove.push_back(item->getUUID());
+	}
+	removeItemsFromAvatar(uuids_to_remove);
+
+	// deactivate all gestures in the outfit folder
+	LLInventoryModel::item_array_t gest_items;
+	getDescendentsOfAssetType(cat_id, gest_items, LLAssetType::AT_GESTURE);
+	for(S32 i = 0; i  < gest_items.size(); ++i)
+	{
+		LLViewerInventoryItem *gest_item = gest_items[i];
+		if ( LLGestureMgr::instance().isGestureActive( gest_item->getLinkedUUID()) )
+		{
+			LLGestureMgr::instance().deactivateGesture( gest_item->getLinkedUUID() );
+		}
+	}
+}
+
+// Create a copy of src_id + contents as a subfolder of dst_id.
+void LLAppearanceMgr::shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
+											  LLPointer<LLInventoryCallback> cb)
+{
+	LLInventoryCategory *src_cat = gInventory.getCategory(src_id);
+	if (!src_cat)
+	{
+		LL_WARNS() << "folder not found for src " << src_id.asString() << LL_ENDL;
+		return;
+	}
+	LL_INFOS() << "starting, src_id " << src_id << " name " << src_cat->getName() << " dst_id " << dst_id << LL_ENDL;
+	LLUUID parent_id = dst_id;
+	if(parent_id.isNull())
+	{
+		parent_id = gInventory.getRootFolderID();
+	}
+	LLUUID subfolder_id = gInventory.createNewCategory( parent_id,
+														LLFolderType::FT_NONE,
+														src_cat->getName());
+	shallowCopyCategoryContents(src_id, subfolder_id, cb);
+
+	gInventory.notifyObservers();
+}
+
+void LLAppearanceMgr::slamCategoryLinks(const LLUUID& src_id, const LLUUID& dst_id,
+										bool include_folder_links, LLPointer<LLInventoryCallback> cb)
+{
+	LLInventoryModel::cat_array_t* cats;
+	LLInventoryModel::item_array_t* items;
+	LLSD contents = LLSD::emptyArray();
+	gInventory.getDirectDescendentsOf(src_id, cats, items);
+	LL_INFOS() << "copying " << items->size() << " items" << LL_ENDL;
+	for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
+		 iter != items->end();
+		 ++iter)
+	{
+		const LLViewerInventoryItem* item = (*iter);
+		switch (item->getActualType())
+		{
+			case LLAssetType::AT_LINK:
+			{
+				LL_DEBUGS("Avatar") << "linking inventory item " << item->getName() << LL_ENDL;
+				//getActualDescription() is used for a new description 
+				//to propagate ordering information saved in descriptions of links
+				LLSD item_contents;
+				item_contents["name"] = item->getName();
+				item_contents["desc"] = item->getActualDescription();
+				item_contents["linked_id"] = item->getLinkedUUID();
+				item_contents["type"] = LLAssetType::AT_LINK; 
+				contents.append(item_contents);
+				break;
+			}
+			case LLAssetType::AT_LINK_FOLDER:
+			{
+				LLViewerInventoryCategory *catp = item->getLinkedCategory();
+				if (catp && include_folder_links)
+				{
+					LL_DEBUGS("Avatar") << "linking inventory folder " << item->getName() << LL_ENDL;
+					LLSD base_contents;
+					base_contents["name"] = catp->getName();
+					base_contents["desc"] = ""; // categories don't have descriptions.
+					base_contents["linked_id"] = catp->getLinkedUUID();
+					base_contents["type"] = LLAssetType::AT_LINK_FOLDER; 
+					contents.append(base_contents);
+				}
+				break;
+			}
+			default:
+			{
+				// Linux refuses to compile unless all possible enums are handled. Really, Linux?
+				break;
+			}
+		}
+	}
+	slam_inventory_folder(dst_id, contents, cb);
+}
+// Copy contents of src_id to dst_id.
+void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
+													  LLPointer<LLInventoryCallback> cb)
+{
+	LLInventoryModel::cat_array_t* cats;
+	LLInventoryModel::item_array_t* items;
+	gInventory.getDirectDescendentsOf(src_id, cats, items);
+	LL_INFOS() << "copying " << items->size() << " items" << LL_ENDL;
+	LLInventoryObject::const_object_list_t link_array;
+	for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
+		 iter != items->end();
+		 ++iter)
+	{
+		const LLViewerInventoryItem* item = (*iter);
+		switch (item->getActualType())
+		{
+			case LLAssetType::AT_LINK:
+			{
+				LL_DEBUGS("Avatar") << "linking inventory item " << item->getName() << LL_ENDL;
+				link_array.push_back(LLConstPointer<LLInventoryObject>(item));
+				break;
+			}
+			case LLAssetType::AT_LINK_FOLDER:
+			{
+				LLViewerInventoryCategory *catp = item->getLinkedCategory();
+				// Skip copying outfit links.
+				if (catp && catp->getPreferredType() != LLFolderType::FT_OUTFIT)
+				{
+					LL_DEBUGS("Avatar") << "linking inventory folder " << item->getName() << LL_ENDL;
+					link_array.push_back(LLConstPointer<LLInventoryObject>(item));
+				}
+				break;
+			}
+			case LLAssetType::AT_CLOTHING:
+			case LLAssetType::AT_OBJECT:
+			case LLAssetType::AT_BODYPART:
+			case LLAssetType::AT_GESTURE:
+			{
+				LL_DEBUGS("Avatar") << "copying inventory item " << item->getName() << LL_ENDL;
+				copy_inventory_item(gAgent.getID(),
+									item->getPermissions().getOwner(),
+									item->getUUID(),
+									dst_id,
+									item->getName(),
+									cb);
+				break;
+			}
+			default:
+				// Ignore non-outfit asset types
+				break;
+		}
+	}
+	if (!link_array.empty())
+	{
+		link_inventory_array(dst_id, link_array, cb);
+	}
+}
+
+BOOL LLAppearanceMgr::getCanMakeFolderIntoOutfit(const LLUUID& folder_id)
+{
+	// These are the wearable items that are required for considering this
+	// folder as containing a complete outfit.
+	U32 required_wearables = 0;
+	required_wearables |= 1LL << LLWearableType::WT_SHAPE;
+	required_wearables |= 1LL << LLWearableType::WT_SKIN;
+	required_wearables |= 1LL << LLWearableType::WT_HAIR;
+	required_wearables |= 1LL << LLWearableType::WT_EYES;
+
+	// These are the wearables that the folder actually contains.
+	U32 folder_wearables = 0;
+	LLInventoryModel::cat_array_t* cats;
+	LLInventoryModel::item_array_t* items;
+	gInventory.getDirectDescendentsOf(folder_id, cats, items);
+	for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
+		 iter != items->end();
+		 ++iter)
+	{
+		const LLViewerInventoryItem* item = (*iter);
+		if (item->isWearableType())
+		{
+			const LLWearableType::EType wearable_type = item->getWearableType();
+			folder_wearables |= 1LL << wearable_type;
+		}
+	}
+
+	// If the folder contains the required wearables, return TRUE.
+	return ((required_wearables & folder_wearables) == required_wearables);
+}
+
+bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id)
+{
+	// Disallow removing the base outfit.
+	if (outfit_cat_id == getBaseOutfitUUID())
+	{
+		return false;
+	}
+
+	// Check if the outfit folder itself is removable.
+	if (!get_is_category_removable(&gInventory, outfit_cat_id))
+	{
+		return false;
+	}
+
+	// Check for the folder's non-removable descendants.
+	LLFindNonRemovableObjects filter_non_removable;
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLInventoryModel::item_array_t::const_iterator it;
+	gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_non_removable);
+	if (!cats.empty() || !items.empty())
+	{
+		return false;
+	}
+
+	return true;
+}
+
+// static
+bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id)
+{
+	if (gAgentWearables.isCOFChangeInProgress())
+	{
+		return false;
+	}
+
+	LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false);
+	return gInventory.hasMatchingDirectDescendent(outfit_cat_id, is_worn);
+}
+
+// static
+bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id)
+{
+	if (gAgentWearables.isCOFChangeInProgress())
+	{
+		return false;
+	}
+
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
+	gInventory.collectDescendentsIf(outfit_cat_id,
+		cats,
+		items,
+		LLInventoryModel::EXCLUDE_TRASH,
+		not_worn);
+
+	return items.size() > 0;
+}
+
+bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
+{
+	// Don't allow wearing anything while we're changing appearance.
+	if (gAgentWearables.isCOFChangeInProgress())
+	{
+		return false;
+	}
+
+	// Check whether it's the base outfit.
+	if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID())
+	{
+		return false;
+	}
+
+	// Check whether the outfit contains any wearables we aren't wearing already (STORM-702).
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true);
+	gInventory.collectDescendentsIf(outfit_cat_id,
+		cats,
+		items,
+		LLInventoryModel::EXCLUDE_TRASH,
+		is_worn);
+
+	return items.size() > 0;
+}
+
+void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> cb)
+{
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	gInventory.collectDescendents(category, cats, items,
+								  LLInventoryModel::EXCLUDE_TRASH);
+	for (S32 i = 0; i < items.size(); ++i)
+	{
+		LLViewerInventoryItem *item = items.at(i);
+		if (item->getActualType() != LLAssetType::AT_LINK_FOLDER)
+			continue;
+		LLViewerInventoryCategory* catp = item->getLinkedCategory();
+		if(catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
+		{
+			remove_inventory_item(item->getUUID(), cb);
+		}
+	}
+}
+
+// Keep the last N wearables of each type.  For viewer 2.0, N is 1 for
+// both body parts and clothing items.
+void LLAppearanceMgr::filterWearableItems(
+	LLInventoryModel::item_array_t& items, S32 max_per_type)
+{
+	// Divvy items into arrays by wearable type.
+	std::vector<LLInventoryModel::item_array_t> items_by_type(LLWearableType::WT_COUNT);
+	divvyWearablesByType(items, items_by_type);
+
+	// rebuild items list, retaining the last max_per_type of each array
+	items.clear();
+	for (S32 i=0; i<LLWearableType::WT_COUNT; i++)
+	{
+		S32 size = items_by_type[i].size();
+		if (size <= 0)
+			continue;
+		S32 start_index = llmax(0,size-max_per_type);
+		for (S32 j = start_index; j<size; j++)
+		{
+			items.push_back(items_by_type[i][j]);
+		}
+	}
+}
+
+void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
+{
+	LLViewerInventoryCategory *pcat = gInventory.getCategory(category);
+	if (!pcat)
+	{
+		LL_WARNS() << "no category found for id " << category << LL_ENDL;
+		return;
+	}
+	LL_INFOS("Avatar") << self_av_string() << "starting, cat '" << (pcat ? pcat->getName() : "[UNKNOWN]") << "'" << LL_ENDL;
+
+	const LLUUID cof = getCOF();
+
+	// Deactivate currently active gestures in the COF, if replacing outfit
+	if (!append)
+	{
+		LLInventoryModel::item_array_t gest_items;
+		getDescendentsOfAssetType(cof, gest_items, LLAssetType::AT_GESTURE);
+		for(S32 i = 0; i  < gest_items.size(); ++i)
+		{
+			LLViewerInventoryItem *gest_item = gest_items.at(i);
+			if ( LLGestureMgr::instance().isGestureActive( gest_item->getLinkedUUID()) )
+			{
+				LLGestureMgr::instance().deactivateGesture( gest_item->getLinkedUUID() );
+			}
+		}
+	}
+	
+	// Collect and filter descendents to determine new COF contents.
+
+	// - Body parts: always include COF contents as a fallback in case any
+	// required parts are missing.
+	// Preserve body parts from COF if appending.
+	LLInventoryModel::item_array_t body_items;
+	getDescendentsOfAssetType(cof, body_items, LLAssetType::AT_BODYPART);
+	getDescendentsOfAssetType(category, body_items, LLAssetType::AT_BODYPART);
+	if (append)
+		reverse(body_items.begin(), body_items.end());
+	// Reduce body items to max of one per type.
+	removeDuplicateItems(body_items);
+	filterWearableItems(body_items, 1);
+
+	// - Wearables: include COF contents only if appending.
+	LLInventoryModel::item_array_t wear_items;
+	if (append)
+		getDescendentsOfAssetType(cof, wear_items, LLAssetType::AT_CLOTHING);
+	getDescendentsOfAssetType(category, wear_items, LLAssetType::AT_CLOTHING);
+	// Reduce wearables to max of one per type.
+	removeDuplicateItems(wear_items);
+	filterWearableItems(wear_items, LLAgentWearables::MAX_CLOTHING_PER_TYPE);
+
+	// - Attachments: include COF contents only if appending.
+	LLInventoryModel::item_array_t obj_items;
+	if (append)
+		getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT);
+	getDescendentsOfAssetType(category, obj_items, LLAssetType::AT_OBJECT);
+	removeDuplicateItems(obj_items);
+
+	// - Gestures: include COF contents only if appending.
+	LLInventoryModel::item_array_t gest_items;
+	if (append)
+		getDescendentsOfAssetType(cof, gest_items, LLAssetType::AT_GESTURE);
+	getDescendentsOfAssetType(category, gest_items, LLAssetType::AT_GESTURE);
+	removeDuplicateItems(gest_items);
+	
+	// Create links to new COF contents.
+	LLInventoryModel::item_array_t all_items;
+	std::copy(body_items.begin(), body_items.end(), std::back_inserter(all_items));
+	std::copy(wear_items.begin(), wear_items.end(), std::back_inserter(all_items));
+	std::copy(obj_items.begin(), obj_items.end(), std::back_inserter(all_items));
+	std::copy(gest_items.begin(), gest_items.end(), std::back_inserter(all_items));
+
+	// Find any wearables that need description set to enforce ordering.
+	desc_map_t desc_map;
+	getWearableOrderingDescUpdates(wear_items, desc_map);
+
+	// Will link all the above items.
+	// link_waiter enforce flags are false because we've already fixed everything up in updateCOF().
+	LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy(false,false);
+	LLSD contents = LLSD::emptyArray();
+
+	for (LLInventoryModel::item_array_t::const_iterator it = all_items.begin();
+		 it != all_items.end(); ++it)
+	{
+		LLSD item_contents;
+		LLInventoryItem *item = *it;
+
+		std::string desc;
+		desc_map_t::const_iterator desc_iter = desc_map.find(item->getUUID());
+		if (desc_iter != desc_map.end())
+		{
+			desc = desc_iter->second;
+			LL_DEBUGS("Avatar") << item->getName() << " overriding desc to: " << desc
+								<< " (was: " << item->getActualDescription() << ")" << LL_ENDL;
+		}
+		else
+		{
+			desc = item->getActualDescription();
+		}
+
+		item_contents["name"] = item->getName();
+		item_contents["desc"] = desc;
+		item_contents["linked_id"] = item->getLinkedUUID();
+		item_contents["type"] = LLAssetType::AT_LINK; 
+		contents.append(item_contents);
+	}
+	const LLUUID& base_id = append ? getBaseOutfitUUID() : category;
+	LLViewerInventoryCategory *base_cat = gInventory.getCategory(base_id);
+	if (base_cat)
+	{
+		LLSD base_contents;
+		base_contents["name"] = base_cat->getName();
+		base_contents["desc"] = "";
+		base_contents["linked_id"] = base_cat->getLinkedUUID();
+		base_contents["type"] = LLAssetType::AT_LINK_FOLDER; 
+		contents.append(base_contents);
+	}
+	if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+	{
+		dump_sequential_xml(gAgentAvatarp->getFullname() + "_slam_request", contents);
+	}
+	slam_inventory_folder(getCOF(), contents, link_waiter);
+
+	LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;
+}
+
+void LLAppearanceMgr::updatePanelOutfitName(const std::string& name)
+{
+	LLSidepanelAppearance* panel_appearance =
+		dynamic_cast<LLSidepanelAppearance *>(LLFloaterSidePanelContainer::getPanel("appearance"));
+	if (panel_appearance)
+	{
+		panel_appearance->refreshCurrentOutfitName(name);
+	}
+}
+
+void LLAppearanceMgr::createBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> link_waiter)
+{
+	const LLUUID cof = getCOF();
+	LLViewerInventoryCategory* catp = gInventory.getCategory(category);
+	std::string new_outfit_name = "";
+
+	purgeBaseOutfitLink(cof, link_waiter);
+
+	if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
+	{
+		link_inventory_object(cof, catp, link_waiter);
+		new_outfit_name = catp->getName();
+	}
+	
+	updatePanelOutfitName(new_outfit_name);
+}
+
+void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder)
+{
+	LL_DEBUGS("Avatar") << "updateAgentWearables()" << LL_ENDL;
+	LLInventoryItem::item_array_t items;
+	std::vector< LLViewerWearable* > wearables;
+	wearables.reserve(32);
+
+	// For each wearable type, find the wearables of that type.
+	for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ )
+	{
+		for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->getFoundList().begin();
+			 iter != holder->getFoundList().end(); ++iter)
+		{
+			LLFoundData& data = *iter;
+			LLViewerWearable* wearable = data.mWearable;
+			if( wearable && ((S32)wearable->getType() == i) )
+			{
+				LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID);
+				if( item && (item->getAssetUUID() == wearable->getAssetID()) )
+				{
+					items.push_back(item);
+					wearables.push_back(wearable);
+				}
+			}
+		}
+	}
+
+	if(wearables.size() > 0)
+	{
+		gAgentWearables.setWearableOutfit(items, wearables);
+	}
+}
+
+S32 LLAppearanceMgr::countActiveHoldingPatterns()
+{
+	return LLWearableHoldingPattern::countActive();
+}
+
+static void remove_non_link_items(LLInventoryModel::item_array_t &items)
+{
+	LLInventoryModel::item_array_t pruned_items;
+	for (LLInventoryModel::item_array_t::const_iterator iter = items.begin();
+		 iter != items.end();
+		 ++iter)
+	{
+ 		const LLViewerInventoryItem *item = (*iter);
+		if (item && item->getIsLinkType())
+		{
+			pruned_items.push_back((*iter));
+		}
+	}
+	items = pruned_items;
+}
+
+//a predicate for sorting inventory items by actual descriptions
+bool sort_by_actual_description(const LLInventoryItem* item1, const LLInventoryItem* item2)
+{
+	if (!item1 || !item2) 
+	{
+		LL_WARNS() << "either item1 or item2 is NULL" << LL_ENDL;
+		return true;
+	}
+
+	return item1->getActualDescription() < item2->getActualDescription();
+}
+
+void item_array_diff(LLInventoryModel::item_array_t& full_list,
+					 LLInventoryModel::item_array_t& keep_list,
+					 LLInventoryModel::item_array_t& kill_list)
+	
+{
+	for (LLInventoryModel::item_array_t::iterator it = full_list.begin();
+		 it != full_list.end();
+		 ++it)
+	{
+		LLViewerInventoryItem *item = *it;
+		if (std::find(keep_list.begin(), keep_list.end(), item) == keep_list.end())
+		{
+			kill_list.push_back(item);
+		}
+	}
+}
+
+S32 LLAppearanceMgr::findExcessOrDuplicateItems(const LLUUID& cat_id,
+												 LLAssetType::EType type,
+												 S32 max_items,
+												 LLInventoryObject::object_list_t& items_to_kill)
+{
+	S32 to_kill_count = 0;
+
+	LLInventoryModel::item_array_t items;
+	getDescendentsOfAssetType(cat_id, items, type);
+	LLInventoryModel::item_array_t curr_items = items;
+	removeDuplicateItems(items);
+	if (max_items > 0)
+	{
+		filterWearableItems(items, max_items);
+	}
+	LLInventoryModel::item_array_t kill_items;
+	item_array_diff(curr_items,items,kill_items);
+	for (LLInventoryModel::item_array_t::iterator it = kill_items.begin();
+		 it != kill_items.end();
+		 ++it)
+	{
+		items_to_kill.push_back(LLPointer<LLInventoryObject>(*it));
+		to_kill_count++;
+	}
+	return to_kill_count;
+}
+	
+
+void LLAppearanceMgr::findAllExcessOrDuplicateItems(const LLUUID& cat_id,
+													LLInventoryObject::object_list_t& items_to_kill)
+{
+	findExcessOrDuplicateItems(cat_id,LLAssetType::AT_BODYPART,
+							   1, items_to_kill);
+	findExcessOrDuplicateItems(cat_id,LLAssetType::AT_CLOTHING,
+							   LLAgentWearables::MAX_CLOTHING_PER_TYPE, items_to_kill);
+	findExcessOrDuplicateItems(cat_id,LLAssetType::AT_OBJECT,
+							   -1, items_to_kill);
+}
+
+void LLAppearanceMgr::enforceCOFItemRestrictions(LLPointer<LLInventoryCallback> cb)
+{
+	LLInventoryObject::object_list_t items_to_kill;
+	findAllExcessOrDuplicateItems(getCOF(), items_to_kill);
+	if (items_to_kill.size()>0)
+	{
+		// Remove duplicate or excess wearables. Should normally be enforced at the UI level, but
+		// this should catch anything that gets through.
+		remove_inventory_items(items_to_kill, cb);
+	}
+}
+
+void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
+											  bool enforce_ordering,
+											  nullary_func_t post_update_func)
+{
+	if (mIsInUpdateAppearanceFromCOF)
+	{
+		LL_WARNS() << "Called updateAppearanceFromCOF inside updateAppearanceFromCOF, skipping" << LL_ENDL;
+		return;
+	}
+
+	LL_DEBUGS("Avatar") << self_av_string() << "starting" << LL_ENDL;
+
+	if (enforce_item_restrictions)
+	{
+		// The point here is just to call
+		// updateAppearanceFromCOF() again after excess items
+		// have been removed. That time we will set
+		// enforce_item_restrictions to false so we don't get
+		// caught in a perpetual loop.
+		LLPointer<LLInventoryCallback> cb(
+			new LLUpdateAppearanceOnDestroy(false, enforce_ordering, post_update_func));
+		enforceCOFItemRestrictions(cb);
+		return;
+	}
+
+	if (enforce_ordering)
+	{
+		//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)
+
+		// 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())
+	{
+		LL_WARNS() << "Clothing ordering error" << LL_ENDL;
+	}
+
+	BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF);
+	selfStartPhase("update_appearance_from_cof");
+
+	// update dirty flag to see if the state of the COF matches
+	// the saved outfit stored as a folder link
+	updateIsDirty();
+
+	// Send server request for appearance update
+	if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
+	{
+		requestServerAppearanceUpdate();
+	}
+
+	LLUUID current_outfit_id = getCOF();
+
+	// Find all the wearables that are in the COF's subtree.
+	LL_DEBUGS() << "LLAppearanceMgr::updateFromCOF()" << LL_ENDL;
+	LLInventoryModel::item_array_t wear_items;
+	LLInventoryModel::item_array_t obj_items;
+	LLInventoryModel::item_array_t gest_items;
+	getUserDescendents(current_outfit_id, wear_items, obj_items, gest_items);
+	// Get rid of non-links in case somehow the COF was corrupted.
+	remove_non_link_items(wear_items);
+	remove_non_link_items(obj_items);
+	remove_non_link_items(gest_items);
+
+	dumpItemArray(wear_items,"asset_dump: wear_item");
+	dumpItemArray(obj_items,"asset_dump: obj_item");
+
+	LLViewerInventoryCategory *cof = gInventory.getCategory(current_outfit_id);
+	if (!gInventory.isCategoryComplete(current_outfit_id))
+	{
+		LL_WARNS() << "COF info is not complete. Version " << cof->getVersion()
+				<< " descendent_count " << cof->getDescendentCount()
+				<< " viewer desc count " << cof->getViewerDescendentCount() << LL_ENDL;
+	}
+	if(!wear_items.size())
+	{
+		LLNotificationsUtil::add("CouldNotPutOnOutfit");
+		return;
+	}
+
+	//preparing the list of wearables in the correct order for LLAgentWearables
+	sortItemsByActualDescription(wear_items);
+
+
+	LL_DEBUGS("Avatar") << "HP block starts" << LL_ENDL;
+	LLTimer hp_block_timer;
+	LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
+
+	holder->setObjItems(obj_items);
+	holder->setGestItems(gest_items);
+		
+	// Note: can't do normal iteration, because if all the
+	// wearables can be resolved immediately, then the
+	// callback will be called (and this object deleted)
+	// before the final getNextData().
+
+	for(S32 i = 0; i  < wear_items.size(); ++i)
+	{
+		LLViewerInventoryItem *item = wear_items.at(i);
+		LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
+
+		// Fault injection: use debug setting to test asset 
+		// fetch failures (should be replaced by new defaults in
+		// lost&found).
+		U32 skip_type = gSavedSettings.getU32("ForceAssetFail");
+
+		if (item && item->getIsLinkType() && linked_item)
+		{
+			LLFoundData found(linked_item->getUUID(),
+							  linked_item->getAssetUUID(),
+							  linked_item->getName(),
+							  linked_item->getType(),
+							  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID
+				);
+
+			if (skip_type != LLWearableType::WT_INVALID && skip_type == found.mWearableType)
+			{
+				found.mAssetID.generate(); // Replace with new UUID, guaranteed not to exist in DB
+			}
+			//pushing back, not front, to preserve order of wearables for LLAgentWearables
+			holder->getFoundList().push_back(found);
+		}
+		else
+		{
+			if (!item)
+			{
+				LL_WARNS() << "Attempt to wear a null item " << LL_ENDL;
+			}
+			else if (!linked_item)
+			{
+				LL_WARNS() << "Attempt to wear a broken link [ name:" << item->getName() << " ] " << LL_ENDL;
+			}
+		}
+	}
+
+	selfStartPhase("get_wearables_2");
+
+	for (LLWearableHoldingPattern::found_list_t::iterator it = holder->getFoundList().begin();
+		 it != holder->getFoundList().end(); ++it)
+	{
+		LLFoundData& found = *it;
+
+		LL_DEBUGS() << self_av_string() << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << LL_ENDL;
+
+		// Fetch the wearables about to be worn.
+		LLWearableList::instance().getAsset(found.mAssetID,
+											found.mName,
+											gAgentAvatarp,
+											found.mAssetType,
+											onWearableAssetFetch,
+											(void*)holder);
+
+	}
+
+	holder->resetTime(gSavedSettings.getF32("MaxWearableWaitTime"));
+	if (!holder->pollFetchCompletion())
+	{
+		doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollFetchCompletion,holder));
+	}
+	post_update_func();
+
+	LL_DEBUGS("Avatar") << "HP block ends, elapsed " << hp_block_timer.getElapsedTimeF32() << LL_ENDL;
+}
+
+void LLAppearanceMgr::getDescendentsOfAssetType(const LLUUID& category,
+													LLInventoryModel::item_array_t& items,
+													LLAssetType::EType type)
+{
+	LLInventoryModel::cat_array_t cats;
+	LLIsType is_of_type(type);
+	gInventory.collectDescendentsIf(category,
+									cats,
+									items,
+									LLInventoryModel::EXCLUDE_TRASH,
+									is_of_type);
+}
+
+void LLAppearanceMgr::getUserDescendents(const LLUUID& category, 
+											 LLInventoryModel::item_array_t& wear_items,
+											 LLInventoryModel::item_array_t& obj_items,
+											 LLInventoryModel::item_array_t& gest_items)
+{
+	LLInventoryModel::cat_array_t wear_cats;
+	LLFindWearables is_wearable;
+	gInventory.collectDescendentsIf(category,
+									wear_cats,
+									wear_items,
+									LLInventoryModel::EXCLUDE_TRASH,
+									is_wearable);
+
+	LLInventoryModel::cat_array_t obj_cats;
+	LLIsType is_object( LLAssetType::AT_OBJECT );
+	gInventory.collectDescendentsIf(category,
+									obj_cats,
+									obj_items,
+									LLInventoryModel::EXCLUDE_TRASH,
+									is_object);
+
+	// Find all gestures in this folder
+	LLInventoryModel::cat_array_t gest_cats;
+	LLIsType is_gesture( LLAssetType::AT_GESTURE );
+	gInventory.collectDescendentsIf(category,
+									gest_cats,
+									gest_items,
+									LLInventoryModel::EXCLUDE_TRASH,
+									is_gesture);
+}
+
+void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append)
+{
+	if(!category) return;
+
+	selfClearPhases();
+	selfStartPhase("wear_inventory_category");
+
+	gAgentWearables.notifyLoadingStarted();
+
+	LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategory( " << category->getName()
+			 << " )" << LL_ENDL;
+
+	// If we are copying from library, attempt to use AIS to copy the category.
+	bool ais_ran=false;
+	if (copy && AISCommand::isAPIAvailable())
+	{
+		LLUUID parent_id;
+		parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
+		if (parent_id.isNull())
+		{
+			parent_id = gInventory.getRootFolderID();
+		}
+
+		LLPointer<LLInventoryCallback> copy_cb = new LLWearCategoryAfterCopy(append);
+		LLPointer<LLInventoryCallback> track_cb = new LLTrackPhaseWrapper(
+													std::string("wear_inventory_category_callback"), copy_cb);
+		LLPointer<AISCommand> cmd_ptr = new CopyLibraryCategoryCommand(category->getUUID(), parent_id, track_cb);
+		ais_ran=cmd_ptr->run_command();
+	}
+
+	if (!ais_ran)
+	{
+		selfStartPhase("wear_inventory_category_fetch");
+		callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal,
+															   &LLAppearanceMgr::instance(),
+															   category->getUUID(), copy, append));
+	}
+}
+
+S32 LLAppearanceMgr::getActiveCopyOperations() const
+{
+	return LLCallAfterInventoryCopyMgr::getInstanceCount(); 
+}
+
+void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append)
+{
+	LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
+
+	selfStopPhase("wear_inventory_category_fetch");
+	
+	// We now have an outfit ready to be copied to agent inventory. Do
+	// it, and wear that outfit normally.
+	LLInventoryCategory* cat = gInventory.getCategory(cat_id);
+	if(copy_items)
+	{
+		LLInventoryModel::cat_array_t* cats;
+		LLInventoryModel::item_array_t* items;
+		gInventory.getDirectDescendentsOf(cat_id, cats, items);
+		std::string name;
+		if(!cat)
+		{
+			// should never happen.
+			name = "New Outfit";
+		}
+		else
+		{
+			name = cat->getName();
+		}
+		LLViewerInventoryItem* item = NULL;
+		LLInventoryModel::item_array_t::const_iterator it = items->begin();
+		LLInventoryModel::item_array_t::const_iterator end = items->end();
+		LLUUID pid;
+		for(; it < end; ++it)
+		{
+			item = *it;
+			if(item)
+			{
+				if(LLInventoryType::IT_GESTURE == item->getInventoryType())
+				{
+					pid = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE);
+				}
+				else
+				{
+					pid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
+				}
+				break;
+			}
+		}
+		if(pid.isNull())
+		{
+			pid = gInventory.getRootFolderID();
+		}
+		
+		LLUUID new_cat_id = gInventory.createNewCategory(
+			pid,
+			LLFolderType::FT_NONE,
+			name);
+
+		// Create a CopyMgr that will copy items, manage its own destruction
+		new LLCallAfterInventoryCopyMgr(
+			*items, new_cat_id, std::string("wear_inventory_category_callback"),
+			boost::bind(&LLAppearanceMgr::wearInventoryCategoryOnAvatar,
+						LLAppearanceMgr::getInstance(),
+						gInventory.getCategory(new_cat_id),
+						append));
+
+		// BAP fixes a lag in display of created dir.
+		gInventory.notifyObservers();
+	}
+	else
+	{
+		// Wear the inventory category.
+		LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(cat, append);
+	}
+}
+
+// *NOTE: hack to get from avatar inventory to avatar
+void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* category, bool append )
+{
+	// Avoid unintentionally overwriting old wearables.  We have to do
+	// this up front to avoid having to deal with the case of multiple
+	// wearables being dirty.
+	if (!category) return;
+
+	if ( !LLInventoryCallbackManager::is_instantiated() )
+	{
+		// shutting down, ignore.
+		return;
+	}
+
+	LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName()
+			 << "'" << LL_ENDL;
+			 	
+	if (gAgentCamera.cameraCustomizeAvatar())
+	{
+		// switching to outfit editor should automagically save any currently edited wearable
+		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
+	}
+
+	LLAppearanceMgr::changeOutfit(TRUE, category->getUUID(), append);
+}
+
+// FIXME do we really want to search entire inventory for matching name?
+void LLAppearanceMgr::wearOutfitByName(const std::string& name)
+{
+	LL_INFOS("Avatar") << self_av_string() << "Wearing category " << name << LL_ENDL;
+
+	LLInventoryModel::cat_array_t cat_array;
+	LLInventoryModel::item_array_t item_array;
+	LLNameCategoryCollector has_name(name);
+	gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
+									cat_array,
+									item_array,
+									LLInventoryModel::EXCLUDE_TRASH,
+									has_name);
+	bool copy_items = false;
+	LLInventoryCategory* cat = NULL;
+	if (cat_array.size() > 0)
+	{
+		// Just wear the first one that matches
+		cat = cat_array.at(0);
+	}
+	else
+	{
+		gInventory.collectDescendentsIf(LLUUID::null,
+										cat_array,
+										item_array,
+										LLInventoryModel::EXCLUDE_TRASH,
+										has_name);
+		if(cat_array.size() > 0)
+		{
+			cat = cat_array.at(0);
+			copy_items = true;
+		}
+	}
+
+	if(cat)
+	{
+		LLAppearanceMgr::wearInventoryCategory(cat, copy_items, false);
+	}
+	else
+	{
+		LL_WARNS() << "Couldn't find outfit " <<name<< " in wearOutfitByName()"
+				<< LL_ENDL;
+	}
+}
+
+bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventoryItem *b)
+{
+	return (a->isWearableType() && b->isWearableType() &&
+			(a->getWearableType() == b->getWearableType()));
+}
+
+class LLDeferredCOFLinkObserver: public LLInventoryObserver
+{
+public:
+	LLDeferredCOFLinkObserver(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb, const std::string& description):
+		mItemID(item_id),
+		mCallback(cb),
+		mDescription(description)
+	{
+	}
+
+	~LLDeferredCOFLinkObserver()
+	{
+	}
+	
+	/* virtual */ void changed(U32 mask)
+	{
+		const LLInventoryItem *item = gInventory.getItem(mItemID);
+		if (item)
+		{
+			gInventory.removeObserver(this);
+			LLAppearanceMgr::instance().addCOFItemLink(item, mCallback, mDescription);
+			delete this;
+		}
+	}
+
+private:
+	const LLUUID mItemID;
+	std::string mDescription;
+	LLPointer<LLInventoryCallback> mCallback;
+};
+
+
+// BAP - note that this runs asynchronously if the item is not already loaded from inventory.
+// Dangerous if caller assumes link will exist after calling the function.
+void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id,
+									 LLPointer<LLInventoryCallback> cb,
+									 const std::string description)
+{
+	const LLInventoryItem *item = gInventory.getItem(item_id);
+	if (!item)
+	{
+		LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, cb, description);
+		gInventory.addObserver(observer);
+	}
+	else
+	{
+		addCOFItemLink(item, cb, description);
+	}
+}
+
+void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item,
+									 LLPointer<LLInventoryCallback> cb,
+									 const std::string description)
 {
-	mManager->decrementInFlightCounter();
-
-	LLHttpSDHandler::onCompleted(handle, response);
+	const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item);
+	if (!vitem)
+	{
+		LL_WARNS() << "not an llviewerinventoryitem, failed" << LL_ENDL;
+		return;
+	}
+
+	gInventory.addChangedMask(LLInventoryObserver::LABEL, vitem->getLinkedUUID());
+
+	LLInventoryModel::cat_array_t cat_array;
+	LLInventoryModel::item_array_t item_array;
+	gInventory.collectDescendents(LLAppearanceMgr::getCOF(),
+								  cat_array,
+								  item_array,
+								  LLInventoryModel::EXCLUDE_TRASH);
+	bool linked_already = false;
+	U32 count = 0;
+	for (S32 i=0; i<item_array.size(); i++)
+	{
+		// Are these links to the same object?
+		const LLViewerInventoryItem* inv_item = item_array.at(i).get();
+		const LLWearableType::EType wearable_type = inv_item->getWearableType();
+
+		const bool is_body_part =    (wearable_type == LLWearableType::WT_SHAPE) 
+								  || (wearable_type == LLWearableType::WT_HAIR) 
+								  || (wearable_type == LLWearableType::WT_EYES)
+								  || (wearable_type == LLWearableType::WT_SKIN);
+
+		if (inv_item->getLinkedUUID() == vitem->getLinkedUUID())
+		{
+			linked_already = true;
+		}
+		// Are these links to different items of the same body part
+		// type? If so, new item will replace old.
+		else if ((vitem->isWearableType()) && (vitem->getWearableType() == wearable_type))
+		{
+			++count;
+			if (is_body_part && inv_item->getIsLinkType()  && (vitem->getWearableType() == wearable_type))
+			{
+				remove_inventory_item(inv_item->getUUID(), cb);
+			}
+			else if (count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE)
+			{
+				// MULTI-WEARABLES: make sure we don't go over MAX_CLOTHING_PER_TYPE
+				remove_inventory_item(inv_item->getUUID(), cb);
+			}
+		}
+	}
+
+	if (!linked_already)
+	{
+		LLViewerInventoryItem *copy_item = new LLViewerInventoryItem;
+		copy_item->copyViewerItem(vitem);
+		copy_item->setDescription(description);
+		link_inventory_object(getCOF(), copy_item, cb);
+	}
+}
+
+LLInventoryModel::item_array_t LLAppearanceMgr::findCOFItemLinks(const LLUUID& item_id)
+{
+
+	LLInventoryModel::item_array_t result;
+	const LLViewerInventoryItem *vitem =
+		dynamic_cast<const LLViewerInventoryItem*>(gInventory.getItem(item_id));
+
+	if (vitem)
+	{
+		LLInventoryModel::cat_array_t cat_array;
+		LLInventoryModel::item_array_t item_array;
+		gInventory.collectDescendents(LLAppearanceMgr::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();
+			if (inv_item->getLinkedUUID() == vitem->getLinkedUUID())
+			{
+				result.push_back(item_array.at(i));
+			}
+		}
+	}
+	return result;
+}
+
+bool LLAppearanceMgr::isLinkedInCOF(const LLUUID& item_id)
+{
+	LLInventoryModel::item_array_t links = LLAppearanceMgr::instance().findCOFItemLinks(item_id);
+	return links.size() > 0;
+}
+
+void LLAppearanceMgr::removeAllClothesFromAvatar()
+{
+	// Fetch worn clothes (i.e. the ones in COF).
+	LLInventoryModel::item_array_t clothing_items;
+	LLInventoryModel::cat_array_t dummy;
+	LLIsType is_clothing(LLAssetType::AT_CLOTHING);
+	gInventory.collectDescendentsIf(getCOF(),
+									dummy,
+									clothing_items,
+									LLInventoryModel::EXCLUDE_TRASH,
+									is_clothing);
+	uuid_vec_t item_ids;
+	for (LLInventoryModel::item_array_t::iterator it = clothing_items.begin();
+		it != clothing_items.end(); ++it)
+	{
+		item_ids.push_back((*it).get()->getLinkedUUID());
+	}
+
+	// Take them off by removing from COF.
+	removeItemsFromAvatar(item_ids);
+}
+
+void LLAppearanceMgr::removeAllAttachmentsFromAvatar()
+{
+	if (!isAgentAvatarValid()) return;
+
+	LLAgentWearables::llvo_vec_t objects_to_remove;
+	
+	for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); 
+		 iter != gAgentAvatarp->mAttachmentPoints.end();)
+	{
+		LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+		LLViewerJointAttachment* attachment = curiter->second;
+		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+			 attachment_iter != attachment->mAttachedObjects.end();
+			 ++attachment_iter)
+		{
+			LLViewerObject *attached_object = (*attachment_iter);
+			if (attached_object)
+			{
+				objects_to_remove.push_back(attached_object);
+			}
+		}
+	}
+	uuid_vec_t ids_to_remove;
+	for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_remove.begin();
+		 it != objects_to_remove.end();
+		 ++it)
+	{
+		ids_to_remove.push_back((*it)->getAttachmentItemID());
+	}
+	removeItemsFromAvatar(ids_to_remove);
+}
+
+void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb)
+{
+	gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
+
+	LLInventoryModel::cat_array_t cat_array;
+	LLInventoryModel::item_array_t item_array;
+	gInventory.collectDescendents(LLAppearanceMgr::getCOF(),
+								  cat_array,
+								  item_array,
+								  LLInventoryModel::EXCLUDE_TRASH);
+	for (S32 i=0; i<item_array.size(); i++)
+	{
+		const LLInventoryItem* item = item_array.at(i).get();
+		if (item->getIsLinkType() && item->getLinkedUUID() == item_id)
+		{
+			bool immediate_delete = false;
+			if (item->getType() == LLAssetType::AT_OBJECT)
+			{
+				immediate_delete = true;
+			}
+			remove_inventory_item(item->getUUID(), cb, immediate_delete);
+		}
+	}
+}
+
+void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, LLPointer<LLInventoryCallback> cb)
+{
+	LLFindWearablesOfType filter_wearables_of_type(type);
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLInventoryModel::item_array_t::const_iterator it;
+
+	gInventory.collectDescendentsIf(getCOF(), cats, items, true, filter_wearables_of_type);
+	for (it = items.begin(); it != items.end(); ++it)
+	{
+		const LLViewerInventoryItem* item = *it;
+		if (item->getIsLinkType()) // we must operate on links only
+		{
+			remove_inventory_item(item->getUUID(), cb);
+		}
+	}
+}
+
+bool sort_by_linked_uuid(const LLViewerInventoryItem* item1, const LLViewerInventoryItem* item2)
+{
+	if (!item1 || !item2)
+	{
+		LL_WARNS() << "item1, item2 cannot be null, something is very wrong" << LL_ENDL;
+		return true;
+	}
+
+	return item1->getLinkedUUID() < item2->getLinkedUUID();
+}
+
+void LLAppearanceMgr::updateIsDirty()
+{
+	LLUUID cof = getCOF();
+	LLUUID base_outfit;
+
+	// find base outfit link 
+	const LLViewerInventoryItem* base_outfit_item = getBaseOutfitLink();
+	LLViewerInventoryCategory* catp = NULL;
+	if (base_outfit_item && base_outfit_item->getIsLinkType())
+	{
+		catp = base_outfit_item->getLinkedCategory();
+	}
+	if(catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
+	{
+		base_outfit = catp->getUUID();
+	}
+
+	// Set dirty to "false" if no base outfit found to disable "Save"
+	// and leave only "Save As" enabled in My Outfits.
+	mOutfitIsDirty = false;
+
+	if (base_outfit.notNull())
+	{
+		LLIsValidItemLink collector;
+
+		LLInventoryModel::cat_array_t cof_cats;
+		LLInventoryModel::item_array_t cof_items;
+		gInventory.collectDescendentsIf(cof, cof_cats, cof_items,
+									  LLInventoryModel::EXCLUDE_TRASH, collector);
+
+		LLInventoryModel::cat_array_t outfit_cats;
+		LLInventoryModel::item_array_t outfit_items;
+		gInventory.collectDescendentsIf(base_outfit, outfit_cats, outfit_items,
+									  LLInventoryModel::EXCLUDE_TRASH, collector);
+
+		if(outfit_items.size() != cof_items.size())
+		{
+			LL_DEBUGS("Avatar") << "item count different - base " << outfit_items.size() << " cof " << cof_items.size() << LL_ENDL;
+			// Current outfit folder should have one more item than the outfit folder.
+			// this one item is the link back to the outfit folder itself.
+			mOutfitIsDirty = true;
+			return;
+		}
+
+		//"dirty" - also means a difference in linked UUIDs and/or a difference in wearables order (links' descriptions)
+		std::sort(cof_items.begin(), cof_items.end(), sort_by_linked_uuid);
+		std::sort(outfit_items.begin(), outfit_items.end(), sort_by_linked_uuid);
+
+		for (U32 i = 0; i < cof_items.size(); ++i)
+		{
+			LLViewerInventoryItem *item1 = cof_items.at(i);
+			LLViewerInventoryItem *item2 = outfit_items.at(i);
+
+			if (item1->getLinkedUUID() != item2->getLinkedUUID() || 
+				item1->getName() != item2->getName() ||
+				item1->getActualDescription() != item2->getActualDescription())
+			{
+				if (item1->getLinkedUUID() != item2->getLinkedUUID())
+				{
+					LL_DEBUGS("Avatar") << "link id different " << LL_ENDL;
+				}
+				else
+				{
+					if (item1->getName() != item2->getName())
+					{
+						LL_DEBUGS("Avatar") << "name different " << item1->getName() << " " << item2->getName() << LL_ENDL;
+					}
+					if (item1->getActualDescription() != item2->getActualDescription())
+					{
+						LL_DEBUGS("Avatar") << "desc different " << item1->getActualDescription()
+											<< " " << item2->getActualDescription() 
+											<< " names " << item1->getName() << " " << item2->getName() << LL_ENDL;
+					}
+				}
+				mOutfitIsDirty = true;
+				return;
+			}
+		}
+	}
+	llassert(!mOutfitIsDirty);
+	LL_DEBUGS("Avatar") << "clean" << LL_ENDL;
+}
+
+// *HACK: Must match name in Library or agent inventory
+const std::string ROOT_GESTURES_FOLDER = "Gestures";
+const std::string COMMON_GESTURES_FOLDER = "Common Gestures";
+const std::string MALE_GESTURES_FOLDER = "Male Gestures";
+const std::string FEMALE_GESTURES_FOLDER = "Female Gestures";
+const std::string SPEECH_GESTURES_FOLDER = "Speech Gestures";
+const std::string OTHER_GESTURES_FOLDER = "Other Gestures";
+
+void LLAppearanceMgr::copyLibraryGestures()
+{
+	LL_INFOS("Avatar") << self_av_string() << "Copying library gestures" << LL_ENDL;
+
+	// Copy gestures
+	LLUUID lib_gesture_cat_id =
+		gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_GESTURE,false);
+	if (lib_gesture_cat_id.isNull())
+	{
+		LL_WARNS() << "Unable to copy gestures, source category not found" << LL_ENDL;
+	}
+	LLUUID dst_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE);
+
+	std::vector<std::string> gesture_folders_to_copy;
+	gesture_folders_to_copy.push_back(MALE_GESTURES_FOLDER);
+	gesture_folders_to_copy.push_back(FEMALE_GESTURES_FOLDER);
+	gesture_folders_to_copy.push_back(COMMON_GESTURES_FOLDER);
+	gesture_folders_to_copy.push_back(SPEECH_GESTURES_FOLDER);
+	gesture_folders_to_copy.push_back(OTHER_GESTURES_FOLDER);
+
+	for(std::vector<std::string>::iterator it = gesture_folders_to_copy.begin();
+		it != gesture_folders_to_copy.end();
+		++it)
+	{
+		std::string& folder_name = *it;
+
+		LLPointer<LLInventoryCallback> cb(NULL);
+
+		// After copying gestures, activate Common, Other, plus
+		// Male and/or Female, depending upon the initial outfit gender.
+		ESex gender = gAgentAvatarp->getSex();
+
+		std::string activate_male_gestures;
+		std::string activate_female_gestures;
+		switch (gender) {
+			case SEX_MALE:
+				activate_male_gestures = MALE_GESTURES_FOLDER;
+				break;
+			case SEX_FEMALE:
+				activate_female_gestures = FEMALE_GESTURES_FOLDER;
+				break;
+			case SEX_BOTH:
+				activate_male_gestures = MALE_GESTURES_FOLDER;
+				activate_female_gestures = FEMALE_GESTURES_FOLDER;
+				break;
+		}
+
+		if (folder_name == activate_male_gestures ||
+			folder_name == activate_female_gestures ||
+			folder_name == COMMON_GESTURES_FOLDER ||
+			folder_name == OTHER_GESTURES_FOLDER)
+		{
+			cb = new LLBoostFuncInventoryCallback(activate_gesture_cb);
+		}
+
+		LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name);
+		if (cat_id.isNull())
+		{
+			LL_WARNS() << self_av_string() << "failed to find gesture folder for " << folder_name << LL_ENDL;
+		}
+		else
+		{
+			LL_DEBUGS("Avatar") << self_av_string() << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << LL_ENDL;
+			callAfterCategoryFetch(cat_id,
+								   boost::bind(&LLAppearanceMgr::shallowCopyCategory,
+											   &LLAppearanceMgr::instance(),
+											   cat_id, dst_id, cb));
+		}
+	}
+}
+
+// Handler for anything that's deferred until avatar de-clouds.
+void LLAppearanceMgr::onFirstFullyVisible()
+{
+	gAgentAvatarp->outputRezTiming("Avatar fully loaded");
+	gAgentAvatarp->reportAvatarRezTime();
+	gAgentAvatarp->debugAvatarVisible();
+
+	// If this is the first time we've ever logged in,
+	// then copy default gestures from the library.
+	if (gAgent.isFirstLogin()) {
+		copyLibraryGestures();
+	}
 }
-
-void LLAppearanceMgrHttpHandler::onSuccess(LLCore::HttpResponse * response, LLSD &content)
-{
-	if (!content.isMap())
-	{
-		LLCore::HttpStatus status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Malformed response contents");
-		response->setStatus(status);
-		onFailure(response, status);
-		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
-		{
-			debugCOF(content);
-		}
-		return;
-	}
-	if (content["success"].asBoolean())
-	{
-		LL_DEBUGS("Avatar") << "succeeded" << LL_ENDL;
-		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
-		{
-			dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_ok", content);
-		}
-	}
-	else
-	{
-		LLCore::HttpStatus status = LLCore::HttpStatus(HTTP_INTERNAL_ERROR, "Non-success response");
-		response->setStatus(status);
-		onFailure(response, status);
-		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
-		{
-			debugCOF(content);
-		}
-		return;
-	}
-}
-
-void LLAppearanceMgrHttpHandler::onFailure(LLCore::HttpResponse * response, LLCore::HttpStatus status)
-{
-	LL_WARNS("Avatar") << "Appearance Mgr request failed to " << getUri()
-		<< ". Reason code: (" << status.toTerseString() << ") "
-		<< status.toString() << LL_ENDL;
-}
-
-void LLAppearanceMgrHttpHandler::debugCOF(const LLSD& content)
-{
-	dump_sequential_xml(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
-
-	LL_INFOS("Avatar") << "AIS COF, version received: " << content["expected"].asInteger()
-		<< " ================================= " << LL_ENDL;
-	std::set<LLUUID> ais_items, local_items;
-	const LLSD& cof_raw = content["cof_raw"];
-	for (LLSD::array_const_iterator it = cof_raw.beginArray();
-		it != cof_raw.endArray(); ++it)
-	{
-		const LLSD& item = *it;
-		if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF())
-		{
-			ais_items.insert(item["item_id"].asUUID());
-			if (item["type"].asInteger() == 24) // link
-			{
-				LL_INFOS("Avatar") << "AIS Link: item_id: " << item["item_id"].asUUID()
-					<< " linked_item_id: " << item["asset_id"].asUUID()
-					<< " name: " << item["name"].asString()
-					<< LL_ENDL;
-			}
-			else if (item["type"].asInteger() == 25) // folder link
-			{
-				LL_INFOS("Avatar") << "AIS Folder link: item_id: " << item["item_id"].asUUID()
-					<< " linked_item_id: " << item["asset_id"].asUUID()
-					<< " name: " << item["name"].asString()
-					<< LL_ENDL;
-			}
-			else
-			{
-				LL_INFOS("Avatar") << "AIS Other: item_id: " << item["item_id"].asUUID()
-					<< " linked_item_id: " << item["asset_id"].asUUID()
-					<< " name: " << item["name"].asString()
-					<< " type: " << item["type"].asInteger()
-					<< LL_ENDL;
-			}
-		}
-	}
-	LL_INFOS("Avatar") << LL_ENDL;
-	LL_INFOS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger()
-		<< " ================================= " << LL_ENDL;
-	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();
-		local_items.insert(inv_item->getUUID());
-		LL_INFOS("Avatar") << "LOCAL: item_id: " << inv_item->getUUID()
-			<< " linked_item_id: " << inv_item->getLinkedUUID()
-			<< " name: " << inv_item->getName()
-			<< " parent: " << inv_item->getParentUUID()
-			<< LL_ENDL;
-	}
-	LL_INFOS("Avatar") << " ================================= " << LL_ENDL;
-	S32 local_only = 0, ais_only = 0;
-	for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it)
-	{
-		if (ais_items.find(*it) == ais_items.end())
-		{
-			LL_INFOS("Avatar") << "LOCAL ONLY: " << *it << LL_ENDL;
-			local_only++;
-		}
-	}
-	for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)
-	{
-		if (local_items.find(*it) == local_items.end())
-		{
-			LL_INFOS("Avatar") << "AIS ONLY: " << *it << LL_ENDL;
-			ais_only++;
-		}
-	}
-	if (local_only == 0 && ais_only == 0)
-	{
-		LL_INFOS("Avatar") << "COF contents identical, only version numbers differ (req "
-			<< content["observed"].asInteger()
-			<< " rcv " << content["expected"].asInteger()
-			<< ")" << LL_ENDL;
-	}
-}
-
-//=========================================================================
-
-const LLUUID LLAppearanceMgr::getCOF() const
-{
-	return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
-}
-
-S32 LLAppearanceMgr::getCOFVersion() const
-{
-	LLViewerInventoryCategory *cof = gInventory.getCategory(getCOF());
-	if (cof)
-	{
-		return cof->getVersion();
-	}
-	else
-	{
-		return LLViewerInventoryCategory::VERSION_UNKNOWN;
-	}
-}
-
-const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink()
-{
-	const LLUUID& current_outfit_cat = getCOF();
-	LLInventoryModel::cat_array_t cat_array;
-	LLInventoryModel::item_array_t item_array;
-	// Can't search on FT_OUTFIT since links to categories return FT_CATEGORY for type since they don't
-	// return preferred type.
-	LLIsType is_category( LLAssetType::AT_CATEGORY ); 
-	gInventory.collectDescendentsIf(current_outfit_cat,
-									cat_array,
-									item_array,
-									false,
-									is_category);
-	for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
-		 iter != item_array.end();
-		 iter++)
-	{
-		const LLViewerInventoryItem *item = (*iter);
-		const LLViewerInventoryCategory *cat = item->getLinkedCategory();
-		if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
-		{
-			const LLUUID parent_id = cat->getParentUUID();
-			LLViewerInventoryCategory*  parent_cat =  gInventory.getCategory(parent_id);
-			// if base outfit moved to trash it means that we don't have base outfit
-			if (parent_cat != NULL && parent_cat->getPreferredType() == LLFolderType::FT_TRASH)
-			{
-				return NULL;
-			}
-			return item;
-		}
-	}
-	return NULL;
-}
-
-bool LLAppearanceMgr::getBaseOutfitName(std::string& name)
-{
-	const LLViewerInventoryItem* outfit_link = getBaseOutfitLink();
-	if(outfit_link)
-	{
-		const LLViewerInventoryCategory *cat = outfit_link->getLinkedCategory();
-		if (cat)
-		{
-			name = cat->getName();
-			return true;
-		}
-	}
-	return false;
-}
-
-const LLUUID LLAppearanceMgr::getBaseOutfitUUID()
-{
-	const LLViewerInventoryItem* outfit_link = getBaseOutfitLink();
-	if (!outfit_link || !outfit_link->getIsLinkType()) return LLUUID::null;
-
-	const LLViewerInventoryCategory* outfit_cat = outfit_link->getLinkedCategory();
-	if (!outfit_cat) return LLUUID::null;
-
-	if (outfit_cat->getPreferredType() != LLFolderType::FT_OUTFIT)
-	{
-		LL_WARNS() << "Expected outfit type:" << LLFolderType::FT_OUTFIT << " but got type:" << outfit_cat->getType() << " for folder name:" << outfit_cat->getName() << LL_ENDL;
-		return LLUUID::null;
-	}
-
-	return outfit_cat->getUUID();
-}
-
-void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace = false)
-{
-	if (inv_item.isNull())
-		return;
-	
-	LLViewerInventoryItem *item = gInventory.getItem(inv_item);
-	if (item)
-	{
-		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, do_replace);
-	}
-}
-
-bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear,
-									   bool do_update,
-									   bool replace,
-									   LLPointer<LLInventoryCallback> cb)
-{
-
-	if (item_id_to_wear.isNull()) return false;
-
-	// *TODO: issue with multi-wearable should be fixed:
-	// in this case this method will be called N times - loading started for each item
-	// and than N times will be called - loading completed for each item.
-	// That means subscribers will be notified that loading is done after first item in a batch is worn.
-	// (loading indicator disappears for example before all selected items are worn)
-	// Have not fix this issue for 2.1 because of stability reason. EXT-7777.
-
-	// Disabled for now because it is *not* acceptable to call updateAppearanceFromCOF() multiple times
-//	gAgentWearables.notifyLoadingStarted();
-
-	LLViewerInventoryItem* item_to_wear = gInventory.getItem(item_id_to_wear);
-	if (!item_to_wear) return false;
-
-	if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID()))
-	{
-		LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb,_1,replace));
-		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(), cb);
-		return false;
-	} 
-	else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID()))
-	{
-		return false; // not in library and not in agent's inventory
-	}
-	else if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH)))
-	{
-		LLNotificationsUtil::add("CannotWearTrash");
-		return false;
-	}
-	else if (isLinkedInCOF(item_to_wear->getUUID())) // EXT-84911
-	{
-		return false;
-	}
-
-	switch (item_to_wear->getType())
-	{
-		case LLAssetType::AT_CLOTHING:
-		if (gAgentWearables.areWearablesLoaded())
-		{
-			if (!cb && do_update)
-			{
-				cb = new LLUpdateAppearanceAndEditWearableOnDestroy(item_id_to_wear);
-			}
-			S32 wearable_count = gAgentWearables.getWearableCount(item_to_wear->getWearableType());
-			if ((replace && wearable_count != 0) ||
-				(wearable_count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) )
-			{
-				LLUUID item_id = gAgentWearables.getWearableItemID(item_to_wear->getWearableType(),
-																   wearable_count-1);
-				removeCOFItemLinks(item_id, cb);
-			}
-
-			addCOFItemLink(item_to_wear, cb);
-		} 
-		break;
-
-		case LLAssetType::AT_BODYPART:
-		// TODO: investigate wearables may not be loaded at this point EXT-8231
-		
-		// Remove the existing wearables of the same type.
-		// Remove existing body parts anyway because we must not be able to wear e.g. two skins.
-		removeCOFLinksOfType(item_to_wear->getWearableType());
-		if (!cb && do_update)
-		{
-			cb = new LLUpdateAppearanceAndEditWearableOnDestroy(item_id_to_wear);
-		}
-		addCOFItemLink(item_to_wear, cb);
-		break;
-
-		case LLAssetType::AT_OBJECT:
-		rez_attachment(item_to_wear, NULL, replace);
-		break;
-
-		default: return false;;
-	}
-
-	return true;
-}
-
-// Update appearance from outfit folder.
-void LLAppearanceMgr::changeOutfit(bool proceed, const LLUUID& category, bool append)
-{
-	if (!proceed)
-		return;
-	LLAppearanceMgr::instance().updateCOF(category,append);
-}
-
-void LLAppearanceMgr::replaceCurrentOutfit(const LLUUID& new_outfit)
-{
-	LLViewerInventoryCategory* cat = gInventory.getCategory(new_outfit);
-	wearInventoryCategory(cat, false, false);
-}
-
-// Open outfit renaming dialog.
-void LLAppearanceMgr::renameOutfit(const LLUUID& outfit_id)
-{
-	LLViewerInventoryCategory* cat = gInventory.getCategory(outfit_id);
-	if (!cat)
-	{
-		return;
-	}
-
-	LLSD args;
-	args["NAME"] = cat->getName();
-
-	LLSD payload;
-	payload["cat_id"] = outfit_id;
-
-	LLNotificationsUtil::add("RenameOutfit", args, payload, boost::bind(onOutfitRename, _1, _2));
-}
-
-// User typed new outfit name.
-// static
-void LLAppearanceMgr::onOutfitRename(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	if (option != 0) return; // canceled
-
-	std::string outfit_name = response["new_name"].asString();
-	LLStringUtil::trim(outfit_name);
-	if (!outfit_name.empty())
-	{
-		LLUUID cat_id = notification["payload"]["cat_id"].asUUID();
-		rename_category(&gInventory, cat_id, outfit_name);
-	}
-}
-
-void LLAppearanceMgr::setOutfitLocked(bool locked)
-{
-	if (mOutfitLocked == locked)
-	{
-		return;
-	}
-
-	mOutfitLocked = locked;
-	if (locked)
-	{
-		mUnlockOutfitTimer->reset();
-		mUnlockOutfitTimer->start();
-	}
-	else
-	{
-		mUnlockOutfitTimer->stop();
-	}
-
-	LLOutfitObserver::instance().notifyOutfitLockChanged();
-}
-
-void LLAppearanceMgr::addCategoryToCurrentOutfit(const LLUUID& cat_id)
-{
-	LLViewerInventoryCategory* cat = gInventory.getCategory(cat_id);
-	wearInventoryCategory(cat, false, true);
-}
-
-void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id)
-{
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	LLFindWearablesEx collector(/*is_worn=*/ true, /*include_body_parts=*/ false);
-
-	gInventory.collectDescendentsIf(cat_id, cats, items, FALSE, collector);
-
-	LLInventoryModel::item_array_t::const_iterator it = items.begin();
-	const LLInventoryModel::item_array_t::const_iterator it_end = items.end();
-	uuid_vec_t uuids_to_remove;
-	for( ; it_end != it; ++it)
-	{
-		LLViewerInventoryItem* item = *it;
-		uuids_to_remove.push_back(item->getUUID());
-	}
-	removeItemsFromAvatar(uuids_to_remove);
-
-	// deactivate all gestures in the outfit folder
-	LLInventoryModel::item_array_t gest_items;
-	getDescendentsOfAssetType(cat_id, gest_items, LLAssetType::AT_GESTURE);
-	for(S32 i = 0; i  < gest_items.size(); ++i)
-	{
-		LLViewerInventoryItem *gest_item = gest_items[i];
-		if ( LLGestureMgr::instance().isGestureActive( gest_item->getLinkedUUID()) )
-		{
-			LLGestureMgr::instance().deactivateGesture( gest_item->getLinkedUUID() );
-		}
-	}
-}
-
-// Create a copy of src_id + contents as a subfolder of dst_id.
-void LLAppearanceMgr::shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
-											  LLPointer<LLInventoryCallback> cb)
-{
-	LLInventoryCategory *src_cat = gInventory.getCategory(src_id);
-	if (!src_cat)
-	{
-		LL_WARNS() << "folder not found for src " << src_id.asString() << LL_ENDL;
-		return;
-	}
-	LL_INFOS() << "starting, src_id " << src_id << " name " << src_cat->getName() << " dst_id " << dst_id << LL_ENDL;
-	LLUUID parent_id = dst_id;
-	if(parent_id.isNull())
-	{
-		parent_id = gInventory.getRootFolderID();
-	}
-	LLUUID subfolder_id = gInventory.createNewCategory( parent_id,
-														LLFolderType::FT_NONE,
-														src_cat->getName());
-	shallowCopyCategoryContents(src_id, subfolder_id, cb);
-
-	gInventory.notifyObservers();
-}
-
-void LLAppearanceMgr::slamCategoryLinks(const LLUUID& src_id, const LLUUID& dst_id,
-										bool include_folder_links, LLPointer<LLInventoryCallback> cb)
-{
-	LLInventoryModel::cat_array_t* cats;
-	LLInventoryModel::item_array_t* items;
-	LLSD contents = LLSD::emptyArray();
-	gInventory.getDirectDescendentsOf(src_id, cats, items);
-	LL_INFOS() << "copying " << items->size() << " items" << LL_ENDL;
-	for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
-		 iter != items->end();
-		 ++iter)
-	{
-		const LLViewerInventoryItem* item = (*iter);
-		switch (item->getActualType())
-		{
-			case LLAssetType::AT_LINK:
-			{
-				LL_DEBUGS("Avatar") << "linking inventory item " << item->getName() << LL_ENDL;
-				//getActualDescription() is used for a new description 
-				//to propagate ordering information saved in descriptions of links
-				LLSD item_contents;
-				item_contents["name"] = item->getName();
-				item_contents["desc"] = item->getActualDescription();
-				item_contents["linked_id"] = item->getLinkedUUID();
-				item_contents["type"] = LLAssetType::AT_LINK; 
-				contents.append(item_contents);
-				break;
-			}
-			case LLAssetType::AT_LINK_FOLDER:
-			{
-				LLViewerInventoryCategory *catp = item->getLinkedCategory();
-				if (catp && include_folder_links)
-				{
-					LL_DEBUGS("Avatar") << "linking inventory folder " << item->getName() << LL_ENDL;
-					LLSD base_contents;
-					base_contents["name"] = catp->getName();
-					base_contents["desc"] = ""; // categories don't have descriptions.
-					base_contents["linked_id"] = catp->getLinkedUUID();
-					base_contents["type"] = LLAssetType::AT_LINK_FOLDER; 
-					contents.append(base_contents);
-				}
-				break;
-			}
-			default:
-			{
-				// Linux refuses to compile unless all possible enums are handled. Really, Linux?
-				break;
-			}
-		}
-	}
-	slam_inventory_folder(dst_id, contents, cb);
-}
-// Copy contents of src_id to dst_id.
-void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
-													  LLPointer<LLInventoryCallback> cb)
-{
-	LLInventoryModel::cat_array_t* cats;
-	LLInventoryModel::item_array_t* items;
-	gInventory.getDirectDescendentsOf(src_id, cats, items);
-	LL_INFOS() << "copying " << items->size() << " items" << LL_ENDL;
-	LLInventoryObject::const_object_list_t link_array;
-	for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
-		 iter != items->end();
-		 ++iter)
-	{
-		const LLViewerInventoryItem* item = (*iter);
-		switch (item->getActualType())
-		{
-			case LLAssetType::AT_LINK:
-			{
-				LL_DEBUGS("Avatar") << "linking inventory item " << item->getName() << LL_ENDL;
-				link_array.push_back(LLConstPointer<LLInventoryObject>(item));
-				break;
-			}
-			case LLAssetType::AT_LINK_FOLDER:
-			{
-				LLViewerInventoryCategory *catp = item->getLinkedCategory();
-				// Skip copying outfit links.
-				if (catp && catp->getPreferredType() != LLFolderType::FT_OUTFIT)
-				{
-					LL_DEBUGS("Avatar") << "linking inventory folder " << item->getName() << LL_ENDL;
-					link_array.push_back(LLConstPointer<LLInventoryObject>(item));
-				}
-				break;
-			}
-			case LLAssetType::AT_CLOTHING:
-			case LLAssetType::AT_OBJECT:
-			case LLAssetType::AT_BODYPART:
-			case LLAssetType::AT_GESTURE:
-			{
-				LL_DEBUGS("Avatar") << "copying inventory item " << item->getName() << LL_ENDL;
-				copy_inventory_item(gAgent.getID(),
-									item->getPermissions().getOwner(),
-									item->getUUID(),
-									dst_id,
-									item->getName(),
-									cb);
-				break;
-			}
-			default:
-				// Ignore non-outfit asset types
-				break;
-		}
-	}
-	if (!link_array.empty())
-	{
-		link_inventory_array(dst_id, link_array, cb);
-	}
-}
-
-BOOL LLAppearanceMgr::getCanMakeFolderIntoOutfit(const LLUUID& folder_id)
-{
-	// These are the wearable items that are required for considering this
-	// folder as containing a complete outfit.
-	U32 required_wearables = 0;
-	required_wearables |= 1LL << LLWearableType::WT_SHAPE;
-	required_wearables |= 1LL << LLWearableType::WT_SKIN;
-	required_wearables |= 1LL << LLWearableType::WT_HAIR;
-	required_wearables |= 1LL << LLWearableType::WT_EYES;
-
-	// These are the wearables that the folder actually contains.
-	U32 folder_wearables = 0;
-	LLInventoryModel::cat_array_t* cats;
-	LLInventoryModel::item_array_t* items;
-	gInventory.getDirectDescendentsOf(folder_id, cats, items);
-	for (LLInventoryModel::item_array_t::const_iterator iter = items->begin();
-		 iter != items->end();
-		 ++iter)
-	{
-		const LLViewerInventoryItem* item = (*iter);
-		if (item->isWearableType())
-		{
-			const LLWearableType::EType wearable_type = item->getWearableType();
-			folder_wearables |= 1LL << wearable_type;
-		}
-	}
-
-	// If the folder contains the required wearables, return TRUE.
-	return ((required_wearables & folder_wearables) == required_wearables);
-}
-
-bool LLAppearanceMgr::getCanRemoveOutfit(const LLUUID& outfit_cat_id)
-{
-	// Disallow removing the base outfit.
-	if (outfit_cat_id == getBaseOutfitUUID())
-	{
-		return false;
-	}
-
-	// Check if the outfit folder itself is removable.
-	if (!get_is_category_removable(&gInventory, outfit_cat_id))
-	{
-		return false;
-	}
-
-	// Check for the folder's non-removable descendants.
-	LLFindNonRemovableObjects filter_non_removable;
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	LLInventoryModel::item_array_t::const_iterator it;
-	gInventory.collectDescendentsIf(outfit_cat_id, cats, items, false, filter_non_removable);
-	if (!cats.empty() || !items.empty())
-	{
-		return false;
-	}
-
-	return true;
-}
-
-// static
-bool LLAppearanceMgr::getCanRemoveFromCOF(const LLUUID& outfit_cat_id)
-{
-	if (gAgentWearables.isCOFChangeInProgress())
-	{
-		return false;
-	}
-
-	LLFindWearablesEx is_worn(/*is_worn=*/ true, /*include_body_parts=*/ false);
-	return gInventory.hasMatchingDirectDescendent(outfit_cat_id, is_worn);
-}
-
-// static
-bool LLAppearanceMgr::getCanAddToCOF(const LLUUID& outfit_cat_id)
-{
-	if (gAgentWearables.isCOFChangeInProgress())
-	{
-		return false;
-	}
-
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	LLFindWearablesEx not_worn(/*is_worn=*/ false, /*include_body_parts=*/ false);
-	gInventory.collectDescendentsIf(outfit_cat_id,
-		cats,
-		items,
-		LLInventoryModel::EXCLUDE_TRASH,
-		not_worn);
-
-	return items.size() > 0;
-}
-
-bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
-{
-	// Don't allow wearing anything while we're changing appearance.
-	if (gAgentWearables.isCOFChangeInProgress())
-	{
-		return false;
-	}
-
-	// Check whether it's the base outfit.
-	if (outfit_cat_id.isNull() || outfit_cat_id == getBaseOutfitUUID())
-	{
-		return false;
-	}
-
-	// Check whether the outfit contains any wearables we aren't wearing already (STORM-702).
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true);
-	gInventory.collectDescendentsIf(outfit_cat_id,
-		cats,
-		items,
-		LLInventoryModel::EXCLUDE_TRASH,
-		is_worn);
-
-	return items.size() > 0;
-}
-
-void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> cb)
-{
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	gInventory.collectDescendents(category, cats, items,
-								  LLInventoryModel::EXCLUDE_TRASH);
-	for (S32 i = 0; i < items.size(); ++i)
-	{
-		LLViewerInventoryItem *item = items.at(i);
-		if (item->getActualType() != LLAssetType::AT_LINK_FOLDER)
-			continue;
-		LLViewerInventoryCategory* catp = item->getLinkedCategory();
-		if(catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
-		{
-			remove_inventory_item(item->getUUID(), cb);
-		}
-	}
-}
-
-// Keep the last N wearables of each type.  For viewer 2.0, N is 1 for
-// both body parts and clothing items.
-void LLAppearanceMgr::filterWearableItems(
-	LLInventoryModel::item_array_t& items, S32 max_per_type)
-{
-	// Divvy items into arrays by wearable type.
-	std::vector<LLInventoryModel::item_array_t> items_by_type(LLWearableType::WT_COUNT);
-	divvyWearablesByType(items, items_by_type);
-
-	// rebuild items list, retaining the last max_per_type of each array
-	items.clear();
-	for (S32 i=0; i<LLWearableType::WT_COUNT; i++)
-	{
-		S32 size = items_by_type[i].size();
-		if (size <= 0)
-			continue;
-		S32 start_index = llmax(0,size-max_per_type);
-		for (S32 j = start_index; j<size; j++)
-		{
-			items.push_back(items_by_type[i][j]);
-		}
-	}
-}
-
-void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
-{
-	LLViewerInventoryCategory *pcat = gInventory.getCategory(category);
-	if (!pcat)
-	{
-		LL_WARNS() << "no category found for id " << category << LL_ENDL;
-		return;
-	}
-	LL_INFOS("Avatar") << self_av_string() << "starting, cat '" << (pcat ? pcat->getName() : "[UNKNOWN]") << "'" << LL_ENDL;
-
-	const LLUUID cof = getCOF();
-
-	// Deactivate currently active gestures in the COF, if replacing outfit
-	if (!append)
-	{
-		LLInventoryModel::item_array_t gest_items;
-		getDescendentsOfAssetType(cof, gest_items, LLAssetType::AT_GESTURE);
-		for(S32 i = 0; i  < gest_items.size(); ++i)
-		{
-			LLViewerInventoryItem *gest_item = gest_items.at(i);
-			if ( LLGestureMgr::instance().isGestureActive( gest_item->getLinkedUUID()) )
-			{
-				LLGestureMgr::instance().deactivateGesture( gest_item->getLinkedUUID() );
-			}
-		}
-	}
-	
-	// Collect and filter descendents to determine new COF contents.
-
-	// - Body parts: always include COF contents as a fallback in case any
-	// required parts are missing.
-	// Preserve body parts from COF if appending.
-	LLInventoryModel::item_array_t body_items;
-	getDescendentsOfAssetType(cof, body_items, LLAssetType::AT_BODYPART);
-	getDescendentsOfAssetType(category, body_items, LLAssetType::AT_BODYPART);
-	if (append)
-		reverse(body_items.begin(), body_items.end());
-	// Reduce body items to max of one per type.
-	removeDuplicateItems(body_items);
-	filterWearableItems(body_items, 1);
-
-	// - Wearables: include COF contents only if appending.
-	LLInventoryModel::item_array_t wear_items;
-	if (append)
-		getDescendentsOfAssetType(cof, wear_items, LLAssetType::AT_CLOTHING);
-	getDescendentsOfAssetType(category, wear_items, LLAssetType::AT_CLOTHING);
-	// Reduce wearables to max of one per type.
-	removeDuplicateItems(wear_items);
-	filterWearableItems(wear_items, LLAgentWearables::MAX_CLOTHING_PER_TYPE);
-
-	// - Attachments: include COF contents only if appending.
-	LLInventoryModel::item_array_t obj_items;
-	if (append)
-		getDescendentsOfAssetType(cof, obj_items, LLAssetType::AT_OBJECT);
-	getDescendentsOfAssetType(category, obj_items, LLAssetType::AT_OBJECT);
-	removeDuplicateItems(obj_items);
-
-	// - Gestures: include COF contents only if appending.
-	LLInventoryModel::item_array_t gest_items;
-	if (append)
-		getDescendentsOfAssetType(cof, gest_items, LLAssetType::AT_GESTURE);
-	getDescendentsOfAssetType(category, gest_items, LLAssetType::AT_GESTURE);
-	removeDuplicateItems(gest_items);
-	
-	// Create links to new COF contents.
-	LLInventoryModel::item_array_t all_items;
-	std::copy(body_items.begin(), body_items.end(), std::back_inserter(all_items));
-	std::copy(wear_items.begin(), wear_items.end(), std::back_inserter(all_items));
-	std::copy(obj_items.begin(), obj_items.end(), std::back_inserter(all_items));
-	std::copy(gest_items.begin(), gest_items.end(), std::back_inserter(all_items));
-
-	// Find any wearables that need description set to enforce ordering.
-	desc_map_t desc_map;
-	getWearableOrderingDescUpdates(wear_items, desc_map);
-
-	// Will link all the above items.
-	// link_waiter enforce flags are false because we've already fixed everything up in updateCOF().
-	LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy(false,false);
-	LLSD contents = LLSD::emptyArray();
-
-	for (LLInventoryModel::item_array_t::const_iterator it = all_items.begin();
-		 it != all_items.end(); ++it)
-	{
-		LLSD item_contents;
-		LLInventoryItem *item = *it;
-
-		std::string desc;
-		desc_map_t::const_iterator desc_iter = desc_map.find(item->getUUID());
-		if (desc_iter != desc_map.end())
-		{
-			desc = desc_iter->second;
-			LL_DEBUGS("Avatar") << item->getName() << " overriding desc to: " << desc
-								<< " (was: " << item->getActualDescription() << ")" << LL_ENDL;
-		}
-		else
-		{
-			desc = item->getActualDescription();
-		}
-
-		item_contents["name"] = item->getName();
-		item_contents["desc"] = desc;
-		item_contents["linked_id"] = item->getLinkedUUID();
-		item_contents["type"] = LLAssetType::AT_LINK; 
-		contents.append(item_contents);
-	}
-	const LLUUID& base_id = append ? getBaseOutfitUUID() : category;
-	LLViewerInventoryCategory *base_cat = gInventory.getCategory(base_id);
-	if (base_cat)
-	{
-		LLSD base_contents;
-		base_contents["name"] = base_cat->getName();
-		base_contents["desc"] = "";
-		base_contents["linked_id"] = base_cat->getLinkedUUID();
-		base_contents["type"] = LLAssetType::AT_LINK_FOLDER; 
-		contents.append(base_contents);
-	}
-	if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
-	{
-		dump_sequential_xml(gAgentAvatarp->getFullname() + "_slam_request", contents);
-	}
-	slam_inventory_folder(getCOF(), contents, link_waiter);
-
-	LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;
-}
-
-void LLAppearanceMgr::updatePanelOutfitName(const std::string& name)
-{
-	LLSidepanelAppearance* panel_appearance =
-		dynamic_cast<LLSidepanelAppearance *>(LLFloaterSidePanelContainer::getPanel("appearance"));
-	if (panel_appearance)
-	{
-		panel_appearance->refreshCurrentOutfitName(name);
-	}
-}
-
-void LLAppearanceMgr::createBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> link_waiter)
-{
-	const LLUUID cof = getCOF();
-	LLViewerInventoryCategory* catp = gInventory.getCategory(category);
-	std::string new_outfit_name = "";
-
-	purgeBaseOutfitLink(cof, link_waiter);
-
-	if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
-	{
-		link_inventory_object(cof, catp, link_waiter);
-		new_outfit_name = catp->getName();
-	}
-	
-	updatePanelOutfitName(new_outfit_name);
-}
-
-void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder)
-{
-	LL_DEBUGS("Avatar") << "updateAgentWearables()" << LL_ENDL;
-	LLInventoryItem::item_array_t items;
-	std::vector< LLViewerWearable* > wearables;
-	wearables.reserve(32);
-
-	// For each wearable type, find the wearables of that type.
-	for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ )
-	{
-		for (LLWearableHoldingPattern::found_list_t::iterator iter = holder->getFoundList().begin();
-			 iter != holder->getFoundList().end(); ++iter)
-		{
-			LLFoundData& data = *iter;
-			LLViewerWearable* wearable = data.mWearable;
-			if( wearable && ((S32)wearable->getType() == i) )
-			{
-				LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID);
-				if( item && (item->getAssetUUID() == wearable->getAssetID()) )
-				{
-					items.push_back(item);
-					wearables.push_back(wearable);
-				}
-			}
-		}
-	}
-
-	if(wearables.size() > 0)
-	{
-		gAgentWearables.setWearableOutfit(items, wearables);
-	}
-}
-
-S32 LLAppearanceMgr::countActiveHoldingPatterns()
-{
-	return LLWearableHoldingPattern::countActive();
-}
-
-static void remove_non_link_items(LLInventoryModel::item_array_t &items)
-{
-	LLInventoryModel::item_array_t pruned_items;
-	for (LLInventoryModel::item_array_t::const_iterator iter = items.begin();
-		 iter != items.end();
-		 ++iter)
-	{
- 		const LLViewerInventoryItem *item = (*iter);
-		if (item && item->getIsLinkType())
-		{
-			pruned_items.push_back((*iter));
-		}
-	}
-	items = pruned_items;
-}
-
-//a predicate for sorting inventory items by actual descriptions
-bool sort_by_actual_description(const LLInventoryItem* item1, const LLInventoryItem* item2)
-{
-	if (!item1 || !item2) 
-	{
-		LL_WARNS() << "either item1 or item2 is NULL" << LL_ENDL;
-		return true;
-	}
-
-	return item1->getActualDescription() < item2->getActualDescription();
-}
-
-void item_array_diff(LLInventoryModel::item_array_t& full_list,
-					 LLInventoryModel::item_array_t& keep_list,
-					 LLInventoryModel::item_array_t& kill_list)
-	
-{
-	for (LLInventoryModel::item_array_t::iterator it = full_list.begin();
-		 it != full_list.end();
-		 ++it)
-	{
-		LLViewerInventoryItem *item = *it;
-		if (std::find(keep_list.begin(), keep_list.end(), item) == keep_list.end())
-		{
-			kill_list.push_back(item);
-		}
-	}
-}
-
-S32 LLAppearanceMgr::findExcessOrDuplicateItems(const LLUUID& cat_id,
-												 LLAssetType::EType type,
-												 S32 max_items,
-												 LLInventoryObject::object_list_t& items_to_kill)
-{
-	S32 to_kill_count = 0;
-
-	LLInventoryModel::item_array_t items;
-	getDescendentsOfAssetType(cat_id, items, type);
-	LLInventoryModel::item_array_t curr_items = items;
-	removeDuplicateItems(items);
-	if (max_items > 0)
-	{
-		filterWearableItems(items, max_items);
-	}
-	LLInventoryModel::item_array_t kill_items;
-	item_array_diff(curr_items,items,kill_items);
-	for (LLInventoryModel::item_array_t::iterator it = kill_items.begin();
-		 it != kill_items.end();
-		 ++it)
-	{
-		items_to_kill.push_back(LLPointer<LLInventoryObject>(*it));
-		to_kill_count++;
-	}
-	return to_kill_count;
-}
-	
-
-void LLAppearanceMgr::findAllExcessOrDuplicateItems(const LLUUID& cat_id,
-													LLInventoryObject::object_list_t& items_to_kill)
-{
-	findExcessOrDuplicateItems(cat_id,LLAssetType::AT_BODYPART,
-							   1, items_to_kill);
-	findExcessOrDuplicateItems(cat_id,LLAssetType::AT_CLOTHING,
-							   LLAgentWearables::MAX_CLOTHING_PER_TYPE, items_to_kill);
-	findExcessOrDuplicateItems(cat_id,LLAssetType::AT_OBJECT,
-							   -1, items_to_kill);
-}
-
-void LLAppearanceMgr::enforceCOFItemRestrictions(LLPointer<LLInventoryCallback> cb)
-{
-	LLInventoryObject::object_list_t items_to_kill;
-	findAllExcessOrDuplicateItems(getCOF(), items_to_kill);
-	if (items_to_kill.size()>0)
-	{
-		// Remove duplicate or excess wearables. Should normally be enforced at the UI level, but
-		// this should catch anything that gets through.
-		remove_inventory_items(items_to_kill, cb);
-	}
-}
-
-void LLAppearanceMgr::updateAppearanceFromCOF(bool enforce_item_restrictions,
-											  bool enforce_ordering,
-											  nullary_func_t post_update_func)
-{
-	if (mIsInUpdateAppearanceFromCOF)
-	{
-		LL_WARNS() << "Called updateAppearanceFromCOF inside updateAppearanceFromCOF, skipping" << LL_ENDL;
-		return;
-	}
-
-	LL_DEBUGS("Avatar") << self_av_string() << "starting" << LL_ENDL;
-
-	if (enforce_item_restrictions)
-	{
-		// The point here is just to call
-		// updateAppearanceFromCOF() again after excess items
-		// have been removed. That time we will set
-		// enforce_item_restrictions to false so we don't get
-		// caught in a perpetual loop.
-		LLPointer<LLInventoryCallback> cb(
-			new LLUpdateAppearanceOnDestroy(false, enforce_ordering, post_update_func));
-		enforceCOFItemRestrictions(cb);
-		return;
-	}
-
-	if (enforce_ordering)
-	{
-		//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)
-
-		// 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())
-	{
-		LL_WARNS() << "Clothing ordering error" << LL_ENDL;
-	}
-
-	BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF);
-	selfStartPhase("update_appearance_from_cof");
-
-	// update dirty flag to see if the state of the COF matches
-	// the saved outfit stored as a folder link
-	updateIsDirty();
-
-	// Send server request for appearance update
-	if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
-	{
-		requestServerAppearanceUpdate();
-	}
-
-	LLUUID current_outfit_id = getCOF();
-
-	// Find all the wearables that are in the COF's subtree.
-	LL_DEBUGS() << "LLAppearanceMgr::updateFromCOF()" << LL_ENDL;
-	LLInventoryModel::item_array_t wear_items;
-	LLInventoryModel::item_array_t obj_items;
-	LLInventoryModel::item_array_t gest_items;
-	getUserDescendents(current_outfit_id, wear_items, obj_items, gest_items);
-	// Get rid of non-links in case somehow the COF was corrupted.
-	remove_non_link_items(wear_items);
-	remove_non_link_items(obj_items);
-	remove_non_link_items(gest_items);
-
-	dumpItemArray(wear_items,"asset_dump: wear_item");
-	dumpItemArray(obj_items,"asset_dump: obj_item");
-
-	LLViewerInventoryCategory *cof = gInventory.getCategory(current_outfit_id);
-	if (!gInventory.isCategoryComplete(current_outfit_id))
-	{
-		LL_WARNS() << "COF info is not complete. Version " << cof->getVersion()
-				<< " descendent_count " << cof->getDescendentCount()
-				<< " viewer desc count " << cof->getViewerDescendentCount() << LL_ENDL;
-	}
-	if(!wear_items.size())
-	{
-		LLNotificationsUtil::add("CouldNotPutOnOutfit");
-		return;
-	}
-
-	//preparing the list of wearables in the correct order for LLAgentWearables
-	sortItemsByActualDescription(wear_items);
-
-
-	LL_DEBUGS("Avatar") << "HP block starts" << LL_ENDL;
-	LLTimer hp_block_timer;
-	LLWearableHoldingPattern* holder = new LLWearableHoldingPattern;
-
-	holder->setObjItems(obj_items);
-	holder->setGestItems(gest_items);
-		
-	// Note: can't do normal iteration, because if all the
-	// wearables can be resolved immediately, then the
-	// callback will be called (and this object deleted)
-	// before the final getNextData().
-
-	for(S32 i = 0; i  < wear_items.size(); ++i)
-	{
-		LLViewerInventoryItem *item = wear_items.at(i);
-		LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
-
-		// Fault injection: use debug setting to test asset 
-		// fetch failures (should be replaced by new defaults in
-		// lost&found).
-		U32 skip_type = gSavedSettings.getU32("ForceAssetFail");
-
-		if (item && item->getIsLinkType() && linked_item)
-		{
-			LLFoundData found(linked_item->getUUID(),
-							  linked_item->getAssetUUID(),
-							  linked_item->getName(),
-							  linked_item->getType(),
-							  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID
-				);
-
-			if (skip_type != LLWearableType::WT_INVALID && skip_type == found.mWearableType)
-			{
-				found.mAssetID.generate(); // Replace with new UUID, guaranteed not to exist in DB
-			}
-			//pushing back, not front, to preserve order of wearables for LLAgentWearables
-			holder->getFoundList().push_back(found);
-		}
-		else
-		{
-			if (!item)
-			{
-				LL_WARNS() << "Attempt to wear a null item " << LL_ENDL;
-			}
-			else if (!linked_item)
-			{
-				LL_WARNS() << "Attempt to wear a broken link [ name:" << item->getName() << " ] " << LL_ENDL;
-			}
-		}
-	}
-
-	selfStartPhase("get_wearables_2");
-
-	for (LLWearableHoldingPattern::found_list_t::iterator it = holder->getFoundList().begin();
-		 it != holder->getFoundList().end(); ++it)
-	{
-		LLFoundData& found = *it;
-
-		LL_DEBUGS() << self_av_string() << "waiting for onWearableAssetFetch callback, asset " << found.mAssetID.asString() << LL_ENDL;
-
-		// Fetch the wearables about to be worn.
-		LLWearableList::instance().getAsset(found.mAssetID,
-											found.mName,
-											gAgentAvatarp,
-											found.mAssetType,
-											onWearableAssetFetch,
-											(void*)holder);
-
-	}
-
-	holder->resetTime(gSavedSettings.getF32("MaxWearableWaitTime"));
-	if (!holder->pollFetchCompletion())
-	{
-		doOnIdleRepeating(boost::bind(&LLWearableHoldingPattern::pollFetchCompletion,holder));
-	}
-	post_update_func();
-
-	LL_DEBUGS("Avatar") << "HP block ends, elapsed " << hp_block_timer.getElapsedTimeF32() << LL_ENDL;
-}
-
-void LLAppearanceMgr::getDescendentsOfAssetType(const LLUUID& category,
-													LLInventoryModel::item_array_t& items,
-													LLAssetType::EType type)
-{
-	LLInventoryModel::cat_array_t cats;
-	LLIsType is_of_type(type);
-	gInventory.collectDescendentsIf(category,
-									cats,
-									items,
-									LLInventoryModel::EXCLUDE_TRASH,
-									is_of_type);
-}
-
-void LLAppearanceMgr::getUserDescendents(const LLUUID& category, 
-											 LLInventoryModel::item_array_t& wear_items,
-											 LLInventoryModel::item_array_t& obj_items,
-											 LLInventoryModel::item_array_t& gest_items)
-{
-	LLInventoryModel::cat_array_t wear_cats;
-	LLFindWearables is_wearable;
-	gInventory.collectDescendentsIf(category,
-									wear_cats,
-									wear_items,
-									LLInventoryModel::EXCLUDE_TRASH,
-									is_wearable);
-
-	LLInventoryModel::cat_array_t obj_cats;
-	LLIsType is_object( LLAssetType::AT_OBJECT );
-	gInventory.collectDescendentsIf(category,
-									obj_cats,
-									obj_items,
-									LLInventoryModel::EXCLUDE_TRASH,
-									is_object);
-
-	// Find all gestures in this folder
-	LLInventoryModel::cat_array_t gest_cats;
-	LLIsType is_gesture( LLAssetType::AT_GESTURE );
-	gInventory.collectDescendentsIf(category,
-									gest_cats,
-									gest_items,
-									LLInventoryModel::EXCLUDE_TRASH,
-									is_gesture);
-}
-
-void LLAppearanceMgr::wearInventoryCategory(LLInventoryCategory* category, bool copy, bool append)
-{
-	if(!category) return;
-
-	selfClearPhases();
-	selfStartPhase("wear_inventory_category");
-
-	gAgentWearables.notifyLoadingStarted();
-
-	LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategory( " << category->getName()
-			 << " )" << LL_ENDL;
-
-	// If we are copying from library, attempt to use AIS to copy the category.
-	bool ais_ran=false;
-	if (copy && AISCommand::isAPIAvailable())
-	{
-		LLUUID parent_id;
-		parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
-		if (parent_id.isNull())
-		{
-			parent_id = gInventory.getRootFolderID();
-		}
-
-		LLPointer<LLInventoryCallback> copy_cb = new LLWearCategoryAfterCopy(append);
-		LLPointer<LLInventoryCallback> track_cb = new LLTrackPhaseWrapper(
-													std::string("wear_inventory_category_callback"), copy_cb);
-		LLPointer<AISCommand> cmd_ptr = new CopyLibraryCategoryCommand(category->getUUID(), parent_id, track_cb);
-		ais_ran=cmd_ptr->run_command();
-	}
-
-	if (!ais_ran)
-	{
-		selfStartPhase("wear_inventory_category_fetch");
-		callAfterCategoryFetch(category->getUUID(),boost::bind(&LLAppearanceMgr::wearCategoryFinal,
-															   &LLAppearanceMgr::instance(),
-															   category->getUUID(), copy, append));
-	}
-}
-
-S32 LLAppearanceMgr::getActiveCopyOperations() const
-{
-	return LLCallAfterInventoryCopyMgr::getInstanceCount(); 
-}
-
-void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool append)
-{
-	LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
-
-	selfStopPhase("wear_inventory_category_fetch");
-	
-	// We now have an outfit ready to be copied to agent inventory. Do
-	// it, and wear that outfit normally.
-	LLInventoryCategory* cat = gInventory.getCategory(cat_id);
-	if(copy_items)
-	{
-		LLInventoryModel::cat_array_t* cats;
-		LLInventoryModel::item_array_t* items;
-		gInventory.getDirectDescendentsOf(cat_id, cats, items);
-		std::string name;
-		if(!cat)
-		{
-			// should never happen.
-			name = "New Outfit";
-		}
-		else
-		{
-			name = cat->getName();
-		}
-		LLViewerInventoryItem* item = NULL;
-		LLInventoryModel::item_array_t::const_iterator it = items->begin();
-		LLInventoryModel::item_array_t::const_iterator end = items->end();
-		LLUUID pid;
-		for(; it < end; ++it)
-		{
-			item = *it;
-			if(item)
-			{
-				if(LLInventoryType::IT_GESTURE == item->getInventoryType())
-				{
-					pid = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE);
-				}
-				else
-				{
-					pid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
-				}
-				break;
-			}
-		}
-		if(pid.isNull())
-		{
-			pid = gInventory.getRootFolderID();
-		}
-		
-		LLUUID new_cat_id = gInventory.createNewCategory(
-			pid,
-			LLFolderType::FT_NONE,
-			name);
-
-		// Create a CopyMgr that will copy items, manage its own destruction
-		new LLCallAfterInventoryCopyMgr(
-			*items, new_cat_id, std::string("wear_inventory_category_callback"),
-			boost::bind(&LLAppearanceMgr::wearInventoryCategoryOnAvatar,
-						LLAppearanceMgr::getInstance(),
-						gInventory.getCategory(new_cat_id),
-						append));
-
-		// BAP fixes a lag in display of created dir.
-		gInventory.notifyObservers();
-	}
-	else
-	{
-		// Wear the inventory category.
-		LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(cat, append);
-	}
-}
-
-// *NOTE: hack to get from avatar inventory to avatar
-void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* category, bool append )
-{
-	// Avoid unintentionally overwriting old wearables.  We have to do
-	// this up front to avoid having to deal with the case of multiple
-	// wearables being dirty.
-	if (!category) return;
-
-	if ( !LLInventoryCallbackManager::is_instantiated() )
-	{
-		// shutting down, ignore.
-		return;
-	}
-
-	LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName()
-			 << "'" << LL_ENDL;
-			 	
-	if (gAgentCamera.cameraCustomizeAvatar())
-	{
-		// switching to outfit editor should automagically save any currently edited wearable
-		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
-	}
-
-	LLAppearanceMgr::changeOutfit(TRUE, category->getUUID(), append);
-}
-
-// FIXME do we really want to search entire inventory for matching name?
-void LLAppearanceMgr::wearOutfitByName(const std::string& name)
-{
-	LL_INFOS("Avatar") << self_av_string() << "Wearing category " << name << LL_ENDL;
-
-	LLInventoryModel::cat_array_t cat_array;
-	LLInventoryModel::item_array_t item_array;
-	LLNameCategoryCollector has_name(name);
-	gInventory.collectDescendentsIf(gInventory.getRootFolderID(),
-									cat_array,
-									item_array,
-									LLInventoryModel::EXCLUDE_TRASH,
-									has_name);
-	bool copy_items = false;
-	LLInventoryCategory* cat = NULL;
-	if (cat_array.size() > 0)
-	{
-		// Just wear the first one that matches
-		cat = cat_array.at(0);
-	}
-	else
-	{
-		gInventory.collectDescendentsIf(LLUUID::null,
-										cat_array,
-										item_array,
-										LLInventoryModel::EXCLUDE_TRASH,
-										has_name);
-		if(cat_array.size() > 0)
-		{
-			cat = cat_array.at(0);
-			copy_items = true;
-		}
-	}
-
-	if(cat)
-	{
-		LLAppearanceMgr::wearInventoryCategory(cat, copy_items, false);
-	}
-	else
-	{
-		LL_WARNS() << "Couldn't find outfit " <<name<< " in wearOutfitByName()"
-				<< LL_ENDL;
-	}
-}
-
-bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventoryItem *b)
-{
-	return (a->isWearableType() && b->isWearableType() &&
-			(a->getWearableType() == b->getWearableType()));
-}
-
-class LLDeferredCOFLinkObserver: public LLInventoryObserver
-{
-public:
-	LLDeferredCOFLinkObserver(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb, const std::string& description):
-		mItemID(item_id),
-		mCallback(cb),
-		mDescription(description)
-	{
-	}
-
-	~LLDeferredCOFLinkObserver()
-	{
-	}
-	
-	/* virtual */ void changed(U32 mask)
-	{
-		const LLInventoryItem *item = gInventory.getItem(mItemID);
-		if (item)
-		{
-			gInventory.removeObserver(this);
-			LLAppearanceMgr::instance().addCOFItemLink(item, mCallback, mDescription);
-			delete this;
-		}
-	}
-
-private:
-	const LLUUID mItemID;
-	std::string mDescription;
-	LLPointer<LLInventoryCallback> mCallback;
-};
-
-
-// BAP - note that this runs asynchronously if the item is not already loaded from inventory.
-// Dangerous if caller assumes link will exist after calling the function.
-void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id,
-									 LLPointer<LLInventoryCallback> cb,
-									 const std::string description)
-{
-	const LLInventoryItem *item = gInventory.getItem(item_id);
-	if (!item)
-	{
-		LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, cb, description);
-		gInventory.addObserver(observer);
-	}
-	else
-	{
-		addCOFItemLink(item, cb, description);
-	}
-}
-
-void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item,
-									 LLPointer<LLInventoryCallback> cb,
-									 const std::string description)
-{
-	const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item);
-	if (!vitem)
-	{
-		LL_WARNS() << "not an llviewerinventoryitem, failed" << LL_ENDL;
-		return;
-	}
-
-	gInventory.addChangedMask(LLInventoryObserver::LABEL, vitem->getLinkedUUID());
-
-	LLInventoryModel::cat_array_t cat_array;
-	LLInventoryModel::item_array_t item_array;
-	gInventory.collectDescendents(LLAppearanceMgr::getCOF(),
-								  cat_array,
-								  item_array,
-								  LLInventoryModel::EXCLUDE_TRASH);
-	bool linked_already = false;
-	U32 count = 0;
-	for (S32 i=0; i<item_array.size(); i++)
-	{
-		// Are these links to the same object?
-		const LLViewerInventoryItem* inv_item = item_array.at(i).get();
-		const LLWearableType::EType wearable_type = inv_item->getWearableType();
-
-		const bool is_body_part =    (wearable_type == LLWearableType::WT_SHAPE) 
-								  || (wearable_type == LLWearableType::WT_HAIR) 
-								  || (wearable_type == LLWearableType::WT_EYES)
-								  || (wearable_type == LLWearableType::WT_SKIN);
-
-		if (inv_item->getLinkedUUID() == vitem->getLinkedUUID())
-		{
-			linked_already = true;
-		}
-		// Are these links to different items of the same body part
-		// type? If so, new item will replace old.
-		else if ((vitem->isWearableType()) && (vitem->getWearableType() == wearable_type))
-		{
-			++count;
-			if (is_body_part && inv_item->getIsLinkType()  && (vitem->getWearableType() == wearable_type))
-			{
-				remove_inventory_item(inv_item->getUUID(), cb);
-			}
-			else if (count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE)
-			{
-				// MULTI-WEARABLES: make sure we don't go over MAX_CLOTHING_PER_TYPE
-				remove_inventory_item(inv_item->getUUID(), cb);
-			}
-		}
-	}
-
-	if (!linked_already)
-	{
-		LLViewerInventoryItem *copy_item = new LLViewerInventoryItem;
-		copy_item->copyViewerItem(vitem);
-		copy_item->setDescription(description);
-		link_inventory_object(getCOF(), copy_item, cb);
-	}
-}
-
-LLInventoryModel::item_array_t LLAppearanceMgr::findCOFItemLinks(const LLUUID& item_id)
-{
-
-	LLInventoryModel::item_array_t result;
-	const LLViewerInventoryItem *vitem =
-		dynamic_cast<const LLViewerInventoryItem*>(gInventory.getItem(item_id));
-
-	if (vitem)
-	{
-		LLInventoryModel::cat_array_t cat_array;
-		LLInventoryModel::item_array_t item_array;
-		gInventory.collectDescendents(LLAppearanceMgr::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();
-			if (inv_item->getLinkedUUID() == vitem->getLinkedUUID())
-			{
-				result.push_back(item_array.at(i));
-			}
-		}
-	}
-	return result;
-}
-
-bool LLAppearanceMgr::isLinkedInCOF(const LLUUID& item_id)
-{
-	LLInventoryModel::item_array_t links = LLAppearanceMgr::instance().findCOFItemLinks(item_id);
-	return links.size() > 0;
-}
-
-void LLAppearanceMgr::removeAllClothesFromAvatar()
-{
-	// Fetch worn clothes (i.e. the ones in COF).
-	LLInventoryModel::item_array_t clothing_items;
-	LLInventoryModel::cat_array_t dummy;
-	LLIsType is_clothing(LLAssetType::AT_CLOTHING);
-	gInventory.collectDescendentsIf(getCOF(),
-									dummy,
-									clothing_items,
-									LLInventoryModel::EXCLUDE_TRASH,
-									is_clothing);
-	uuid_vec_t item_ids;
-	for (LLInventoryModel::item_array_t::iterator it = clothing_items.begin();
-		it != clothing_items.end(); ++it)
-	{
-		item_ids.push_back((*it).get()->getLinkedUUID());
-	}
-
-	// Take them off by removing from COF.
-	removeItemsFromAvatar(item_ids);
-}
-
-void LLAppearanceMgr::removeAllAttachmentsFromAvatar()
-{
-	if (!isAgentAvatarValid()) return;
-
-	LLAgentWearables::llvo_vec_t objects_to_remove;
-	
-	for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); 
-		 iter != gAgentAvatarp->mAttachmentPoints.end();)
-	{
-		LLVOAvatar::attachment_map_t::iterator curiter = iter++;
-		LLViewerJointAttachment* attachment = curiter->second;
-		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
-			 attachment_iter != attachment->mAttachedObjects.end();
-			 ++attachment_iter)
-		{
-			LLViewerObject *attached_object = (*attachment_iter);
-			if (attached_object)
-			{
-				objects_to_remove.push_back(attached_object);
-			}
-		}
-	}
-	uuid_vec_t ids_to_remove;
-	for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_remove.begin();
-		 it != objects_to_remove.end();
-		 ++it)
-	{
-		ids_to_remove.push_back((*it)->getAttachmentItemID());
-	}
-	removeItemsFromAvatar(ids_to_remove);
-}
-
-void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, LLPointer<LLInventoryCallback> cb)
-{
-	gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
-
-	LLInventoryModel::cat_array_t cat_array;
-	LLInventoryModel::item_array_t item_array;
-	gInventory.collectDescendents(LLAppearanceMgr::getCOF(),
-								  cat_array,
-								  item_array,
-								  LLInventoryModel::EXCLUDE_TRASH);
-	for (S32 i=0; i<item_array.size(); i++)
-	{
-		const LLInventoryItem* item = item_array.at(i).get();
-		if (item->getIsLinkType() && item->getLinkedUUID() == item_id)
-		{
-			bool immediate_delete = false;
-			if (item->getType() == LLAssetType::AT_OBJECT)
-			{
-				immediate_delete = true;
-			}
-			remove_inventory_item(item->getUUID(), cb, immediate_delete);
-		}
-	}
-}
-
-void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, LLPointer<LLInventoryCallback> cb)
-{
-	LLFindWearablesOfType filter_wearables_of_type(type);
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	LLInventoryModel::item_array_t::const_iterator it;
-
-	gInventory.collectDescendentsIf(getCOF(), cats, items, true, filter_wearables_of_type);
-	for (it = items.begin(); it != items.end(); ++it)
-	{
-		const LLViewerInventoryItem* item = *it;
-		if (item->getIsLinkType()) // we must operate on links only
-		{
-			remove_inventory_item(item->getUUID(), cb);
-		}
-	}
-}
-
-bool sort_by_linked_uuid(const LLViewerInventoryItem* item1, const LLViewerInventoryItem* item2)
-{
-	if (!item1 || !item2)
-	{
-		LL_WARNS() << "item1, item2 cannot be null, something is very wrong" << LL_ENDL;
-		return true;
-	}
-
-	return item1->getLinkedUUID() < item2->getLinkedUUID();
-}
-
-void LLAppearanceMgr::updateIsDirty()
-{
-	LLUUID cof = getCOF();
-	LLUUID base_outfit;
-
-	// find base outfit link 
-	const LLViewerInventoryItem* base_outfit_item = getBaseOutfitLink();
-	LLViewerInventoryCategory* catp = NULL;
-	if (base_outfit_item && base_outfit_item->getIsLinkType())
-	{
-		catp = base_outfit_item->getLinkedCategory();
-	}
-	if(catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
-	{
-		base_outfit = catp->getUUID();
-	}
-
-	// Set dirty to "false" if no base outfit found to disable "Save"
-	// and leave only "Save As" enabled in My Outfits.
-	mOutfitIsDirty = false;
-
-	if (base_outfit.notNull())
-	{
-		LLIsValidItemLink collector;
-
-		LLInventoryModel::cat_array_t cof_cats;
-		LLInventoryModel::item_array_t cof_items;
-		gInventory.collectDescendentsIf(cof, cof_cats, cof_items,
-									  LLInventoryModel::EXCLUDE_TRASH, collector);
-
-		LLInventoryModel::cat_array_t outfit_cats;
-		LLInventoryModel::item_array_t outfit_items;
-		gInventory.collectDescendentsIf(base_outfit, outfit_cats, outfit_items,
-									  LLInventoryModel::EXCLUDE_TRASH, collector);
-
-		if(outfit_items.size() != cof_items.size())
-		{
-			LL_DEBUGS("Avatar") << "item count different - base " << outfit_items.size() << " cof " << cof_items.size() << LL_ENDL;
-			// Current outfit folder should have one more item than the outfit folder.
-			// this one item is the link back to the outfit folder itself.
-			mOutfitIsDirty = true;
-			return;
-		}
-
-		//"dirty" - also means a difference in linked UUIDs and/or a difference in wearables order (links' descriptions)
-		std::sort(cof_items.begin(), cof_items.end(), sort_by_linked_uuid);
-		std::sort(outfit_items.begin(), outfit_items.end(), sort_by_linked_uuid);
-
-		for (U32 i = 0; i < cof_items.size(); ++i)
-		{
-			LLViewerInventoryItem *item1 = cof_items.at(i);
-			LLViewerInventoryItem *item2 = outfit_items.at(i);
-
-			if (item1->getLinkedUUID() != item2->getLinkedUUID() || 
-				item1->getName() != item2->getName() ||
-				item1->getActualDescription() != item2->getActualDescription())
-			{
-				if (item1->getLinkedUUID() != item2->getLinkedUUID())
-				{
-					LL_DEBUGS("Avatar") << "link id different " << LL_ENDL;
-				}
-				else
-				{
-					if (item1->getName() != item2->getName())
-					{
-						LL_DEBUGS("Avatar") << "name different " << item1->getName() << " " << item2->getName() << LL_ENDL;
-					}
-					if (item1->getActualDescription() != item2->getActualDescription())
-					{
-						LL_DEBUGS("Avatar") << "desc different " << item1->getActualDescription()
-											<< " " << item2->getActualDescription() 
-											<< " names " << item1->getName() << " " << item2->getName() << LL_ENDL;
-					}
-				}
-				mOutfitIsDirty = true;
-				return;
-			}
-		}
-	}
-	llassert(!mOutfitIsDirty);
-	LL_DEBUGS("Avatar") << "clean" << LL_ENDL;
-}
-
-// *HACK: Must match name in Library or agent inventory
-const std::string ROOT_GESTURES_FOLDER = "Gestures";
-const std::string COMMON_GESTURES_FOLDER = "Common Gestures";
-const std::string MALE_GESTURES_FOLDER = "Male Gestures";
-const std::string FEMALE_GESTURES_FOLDER = "Female Gestures";
-const std::string SPEECH_GESTURES_FOLDER = "Speech Gestures";
-const std::string OTHER_GESTURES_FOLDER = "Other Gestures";
-
-void LLAppearanceMgr::copyLibraryGestures()
-{
-	LL_INFOS("Avatar") << self_av_string() << "Copying library gestures" << LL_ENDL;
-
-	// Copy gestures
-	LLUUID lib_gesture_cat_id =
-		gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_GESTURE,false);
-	if (lib_gesture_cat_id.isNull())
-	{
-		LL_WARNS() << "Unable to copy gestures, source category not found" << LL_ENDL;
-	}
-	LLUUID dst_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE);
-
-	std::vector<std::string> gesture_folders_to_copy;
-	gesture_folders_to_copy.push_back(MALE_GESTURES_FOLDER);
-	gesture_folders_to_copy.push_back(FEMALE_GESTURES_FOLDER);
-	gesture_folders_to_copy.push_back(COMMON_GESTURES_FOLDER);
-	gesture_folders_to_copy.push_back(SPEECH_GESTURES_FOLDER);
-	gesture_folders_to_copy.push_back(OTHER_GESTURES_FOLDER);
-
-	for(std::vector<std::string>::iterator it = gesture_folders_to_copy.begin();
-		it != gesture_folders_to_copy.end();
-		++it)
-	{
-		std::string& folder_name = *it;
-
-		LLPointer<LLInventoryCallback> cb(NULL);
-
-		// After copying gestures, activate Common, Other, plus
-		// Male and/or Female, depending upon the initial outfit gender.
-		ESex gender = gAgentAvatarp->getSex();
-
-		std::string activate_male_gestures;
-		std::string activate_female_gestures;
-		switch (gender) {
-			case SEX_MALE:
-				activate_male_gestures = MALE_GESTURES_FOLDER;
-				break;
-			case SEX_FEMALE:
-				activate_female_gestures = FEMALE_GESTURES_FOLDER;
-				break;
-			case SEX_BOTH:
-				activate_male_gestures = MALE_GESTURES_FOLDER;
-				activate_female_gestures = FEMALE_GESTURES_FOLDER;
-				break;
-		}
-
-		if (folder_name == activate_male_gestures ||
-			folder_name == activate_female_gestures ||
-			folder_name == COMMON_GESTURES_FOLDER ||
-			folder_name == OTHER_GESTURES_FOLDER)
-		{
-			cb = new LLBoostFuncInventoryCallback(activate_gesture_cb);
-		}
-
-		LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name);
-		if (cat_id.isNull())
-		{
-			LL_WARNS() << self_av_string() << "failed to find gesture folder for " << folder_name << LL_ENDL;
-		}
-		else
-		{
-			LL_DEBUGS("Avatar") << self_av_string() << "initiating fetch and copy for " << folder_name << " cat_id " << cat_id << LL_ENDL;
-			callAfterCategoryFetch(cat_id,
-								   boost::bind(&LLAppearanceMgr::shallowCopyCategory,
-											   &LLAppearanceMgr::instance(),
-											   cat_id, dst_id, cb));
-		}
-	}
-}
-
-// Handler for anything that's deferred until avatar de-clouds.
-void LLAppearanceMgr::onFirstFullyVisible()
-{
-	gAgentAvatarp->outputRezTiming("Avatar fully loaded");
-	gAgentAvatarp->reportAvatarRezTime();
-	gAgentAvatarp->debugAvatarVisible();
-
-	// If this is the first time we've ever logged in,
-	// then copy default gestures from the library.
-	if (gAgent.isFirstLogin()) {
-		copyLibraryGestures();
-	}
-}
-
-// update "dirty" state - defined outside class to allow for calling
-// after appearance mgr instance has been destroyed.
-void appearance_mgr_update_dirty_state()
-{
-	if (LLAppearanceMgr::instanceExists())
-	{
-		LLAppearanceMgr::getInstance()->updateIsDirty();
-		LLAppearanceMgr::getInstance()->setOutfitLocked(false);
-		gAgentWearables.notifyLoadingFinished();
-	}
-}
-
-void update_base_outfit_after_ordering()
-{
-	LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance();
-	
-	LLPointer<LLInventoryCallback> dirty_state_updater =
-		new LLBoostFuncInventoryCallback(no_op_inventory_func, appearance_mgr_update_dirty_state);
-
-	//COF contains only links so we copy to the Base Outfit only links
-	const LLUUID base_outfit_id = app_mgr.getBaseOutfitUUID();
-	bool copy_folder_links = false;
-	app_mgr.slamCategoryLinks(app_mgr.getCOF(), base_outfit_id, copy_folder_links, dirty_state_updater);
-
-}
-
-// Save COF changes - update the contents of the current base outfit
-// to match the current COF. Fails if no current base outfit is set.
-bool LLAppearanceMgr::updateBaseOutfit()
-{
-	if (isOutfitLocked())
-	{
-		// don't allow modify locked outfit
-		llassert(!isOutfitLocked());
-		return false;
-	}
-
-	setOutfitLocked(true);
-
-	gAgentWearables.notifyLoadingStarted();
-
-	const LLUUID base_outfit_id = getBaseOutfitUUID();
-	if (base_outfit_id.isNull()) return false;
-	LL_DEBUGS("Avatar") << "saving cof to base outfit " << base_outfit_id << LL_ENDL;
-
-	LLPointer<LLInventoryCallback> cb =
-		new LLBoostFuncInventoryCallback(no_op_inventory_func, update_base_outfit_after_ordering);
-	// Really shouldn't be needed unless there's a race condition -
-	// updateAppearanceFromCOF() already calls updateClothingOrderingInfo.
-	updateClothingOrderingInfo(LLUUID::null, cb);
-
-	return true;
-}
-
-void LLAppearanceMgr::divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type)
-{
-	items_by_type.resize(LLWearableType::WT_COUNT);
-	if (items.empty()) return;
-
-	for (S32 i=0; i<items.size(); i++)
-	{
-		LLViewerInventoryItem *item = items.at(i);
-		if (!item)
-		{
-			LL_WARNS("Appearance") << "NULL item found" << LL_ENDL;
-			continue;
-		}
-		// Ignore non-wearables.
-		if (!item->isWearableType())
-			continue;
-		LLWearableType::EType type = item->getWearableType();
-		if(type < 0 || type >= LLWearableType::WT_COUNT)
-		{
-			LL_WARNS("Appearance") << "Invalid wearable type. Inventory type does not match wearable flag bitfield." << LL_ENDL;
-			continue;
-		}
-		items_by_type[type].push_back(item);
-	}
-}
-
-std::string build_order_string(LLWearableType::EType type, U32 i)
-{
-		std::ostringstream order_num;
-		order_num << ORDER_NUMBER_SEPARATOR << type * 100 + i;
-		return order_num.str();
-}
-
-struct WearablesOrderComparator
-{
-	LOG_CLASS(WearablesOrderComparator);
-	WearablesOrderComparator(const LLWearableType::EType type)
-	{
-		mControlSize = build_order_string(type, 0).size();
-	};
-
-	bool operator()(const LLInventoryItem* item1, const LLInventoryItem* item2)
-	{
-		const std::string& desc1 = item1->getActualDescription();
-		const std::string& desc2 = item2->getActualDescription();
-		
-		bool item1_valid = (desc1.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc1[0]);
-		bool item2_valid = (desc2.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc2[0]);
-
-		if (item1_valid && item2_valid)
-			return desc1 < desc2;
-
-		//we need to sink down invalid items: items with empty descriptions, items with "Broken link" descriptions,
-		//items with ordering information but not for the associated wearables type
-		if (!item1_valid && item2_valid) 
-			return false;
-		else if (item1_valid && !item2_valid)
-			return true;
-
-		return item1->getName() < item2->getName();
-	}
-
-	U32 mControlSize;
-};
-
-void LLAppearanceMgr::getWearableOrderingDescUpdates(LLInventoryModel::item_array_t& wear_items,
-													 desc_map_t& desc_map)
-{
-	wearables_by_type_t items_by_type(LLWearableType::WT_COUNT);
-	divvyWearablesByType(wear_items, items_by_type);
-
-	for (U32 type = LLWearableType::WT_SHIRT; type < LLWearableType::WT_COUNT; type++)
-	{
-		U32 size = items_by_type[type].size();
-		if (!size) continue;
-		
-		//sinking down invalid items which need reordering
-		std::sort(items_by_type[type].begin(), items_by_type[type].end(), WearablesOrderComparator((LLWearableType::EType) type));
-		
-		//requesting updates only for those links which don't have "valid" descriptions
-		for (U32 i = 0; i < size; i++)
-		{
-			LLViewerInventoryItem* item = items_by_type[type][i];
-			if (!item) continue;
-			
-			std::string new_order_str = build_order_string((LLWearableType::EType)type, i);
-			if (new_order_str == item->getActualDescription()) continue;
-			
-			desc_map[item->getUUID()] = new_order_str;
-		}
-	}
-}
-
-bool LLAppearanceMgr::validateClothingOrderingInfo(LLUUID cat_id)
-{
-	// COF is processed if cat_id is not specified
-	if (cat_id.isNull())
-	{
-		cat_id = getCOF();
-	}
-
-	LLInventoryModel::item_array_t wear_items;
-	getDescendentsOfAssetType(cat_id, wear_items, LLAssetType::AT_CLOTHING);
-
-	// Identify items for which desc needs to change.
-	desc_map_t desc_map;
-	getWearableOrderingDescUpdates(wear_items, desc_map);
-
-	for (desc_map_t::const_iterator it = desc_map.begin();
-		 it != desc_map.end(); ++it)
-	{
-		const LLUUID& item_id = it->first;
-		const std::string& new_order_str = it->second;
-		LLViewerInventoryItem *item = gInventory.getItem(item_id);
-		LL_WARNS() << "Order validation fails: " << item->getName()
-				<< " needs to update desc to: " << new_order_str
-				<< " (from: " << item->getActualDescription() << ")" << LL_ENDL;
-	}
-	
-	return desc_map.size() == 0;
-}
-
-void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id,
-												 LLPointer<LLInventoryCallback> cb)
-{
-	// COF is processed if cat_id is not specified
-	if (cat_id.isNull())
-	{
-		cat_id = getCOF();
-	}
-
-	LLInventoryModel::item_array_t wear_items;
-	getDescendentsOfAssetType(cat_id, wear_items, LLAssetType::AT_CLOTHING);
-
-	// Identify items for which desc needs to change.
-	desc_map_t desc_map;
-	getWearableOrderingDescUpdates(wear_items, desc_map);
-
-	for (desc_map_t::const_iterator it = desc_map.begin();
-		 it != desc_map.end(); ++it)
-	{
-		LLSD updates;
-		const LLUUID& item_id = it->first;
-		const std::string& new_order_str = it->second;
-		LLViewerInventoryItem *item = gInventory.getItem(item_id);
-		LL_DEBUGS("Avatar") << item->getName() << " updating desc to: " << new_order_str
-			<< " (was: " << item->getActualDescription() << ")" << LL_ENDL;
-		updates["desc"] = new_order_str;
-		update_inventory_item(item_id,updates,cb);
-	}
-		
-}
-
-
-LLSD LLAppearanceMgr::dumpCOF() const
-{
-	LLSD links = LLSD::emptyArray();
-	LLMD5 md5;
-	
-	LLInventoryModel::cat_array_t cat_array;
-	LLInventoryModel::item_array_t item_array;
-	gInventory.collectDescendents(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();
-		LLSD item;
-		LLUUID item_id(inv_item->getUUID());
-		md5.update((unsigned char*)item_id.mData, 16);
-		item["description"] = inv_item->getActualDescription();
-		md5.update(inv_item->getActualDescription());
-		item["asset_type"] = inv_item->getActualType();
-		LLUUID linked_id(inv_item->getLinkedUUID());
-		item["linked_id"] = linked_id;
-		md5.update((unsigned char*)linked_id.mData, 16);
-
-		if (LLAssetType::AT_LINK == inv_item->getActualType())
-		{
-			const LLViewerInventoryItem* linked_item = inv_item->getLinkedItem();
-			if (NULL == linked_item)
-			{
-				LL_WARNS() << "Broken link for item '" << inv_item->getName()
-						<< "' (" << inv_item->getUUID()
-						<< ") during requestServerAppearanceUpdate" << LL_ENDL;
-				continue;
-			}
-			// Some assets may be 'hidden' and show up as null in the viewer.
-			//if (linked_item->getAssetUUID().isNull())
-			//{
-			//	LL_WARNS() << "Broken link (null asset) for item '" << inv_item->getName()
-			//			<< "' (" << inv_item->getUUID()
-			//			<< ") during requestServerAppearanceUpdate" << LL_ENDL;
-			//	continue;
-			//}
-			LLUUID linked_asset_id(linked_item->getAssetUUID());
-			md5.update((unsigned char*)linked_asset_id.mData, 16);
-			U32 flags = linked_item->getFlags();
-			md5.update(boost::lexical_cast<std::string>(flags));
-		}
-		else if (LLAssetType::AT_LINK_FOLDER != inv_item->getActualType())
-		{
-			LL_WARNS() << "Non-link item '" << inv_item->getName()
-					<< "' (" << inv_item->getUUID()
-					<< ") type " << (S32) inv_item->getActualType()
-					<< " during requestServerAppearanceUpdate" << LL_ENDL;
-			continue;
-		}
-		links.append(item);
-	}
-	LLSD result = LLSD::emptyMap();
-	result["cof_contents"] = links;
-	char cof_md5sum[MD5HEX_STR_SIZE];
-	md5.finalize();
-	md5.hex_digest(cof_md5sum);
-	result["cof_md5sum"] = std::string(cof_md5sum);
-	return result;
-}
-
-void LLAppearanceMgr::requestServerAppearanceUpdate()
-{
-
-	if (!testCOFRequestVersion())
-	{
-		// *TODO: LL_LOG message here
-		return;
-	}
-
-	if ((mInFlightCounter > 0) && (mInFlightTimer.hasExpired()))
-	{
-		LL_WARNS("Avatar") << "in flight timer expired, resetting " << LL_ENDL;
-		mInFlightCounter = 0;
-	}
-
-	if (gAgentAvatarp->isEditingAppearance())
-	{
-		LL_WARNS("Avatar") << "Avatar editing appeance, not sending request." << LL_ENDL;
-		// don't send out appearance updates if in appearance editing mode
-		return;
-	}
-
-	if (!gAgent.getRegion())
-	{
-		LL_WARNS("Avatar") << "Region not set, cannot request server appearance update" << LL_ENDL;
-		return;
-	}
-	if (gAgent.getRegion()->getCentralBakeVersion() == 0)
-	{
-		LL_WARNS("Avatar") << "Region does not support baking" << LL_ENDL;
-	}
-	std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance");
-	if (url.empty())
-	{
-		LL_WARNS("Avatar") << "No cap for UpdateAvatarAppearance." << LL_ENDL;
-		return;
-	}
-
-	LLSD postData;
-	S32 cof_version = LLAppearanceMgr::instance().getCOFVersion();
-	if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate"))
-	{
-		postData = LLAppearanceMgr::instance().dumpCOF();
-	}
-	else
-	{
-		postData["cof_version"] = cof_version;
-		if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
-		{
-			postData["cof_version"] = cof_version + 999;
-		}
-	}
-	LL_DEBUGS("Avatar") << "request url " << url << " my_cof_version " << cof_version << LL_ENDL;
-
-	LLAppearanceMgrHttpHandler * handler = new LLAppearanceMgrHttpHandler(url, this);
-
-	mInFlightCounter++;
-	mInFlightTimer.setTimerExpirySec(60.0);
-
-	llassert(cof_version >= gAgentAvatarp->mLastUpdateRequestCOFVersion);
-	gAgentAvatarp->mLastUpdateRequestCOFVersion = cof_version;
-
-	LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
-		mHttpPolicy, mHttpPriority, url,
-		postData, mHttpOptions, mHttpHeaders, handler);
-
-	if (handle == LLCORE_HTTP_HANDLE_INVALID)
-	{
+
+// update "dirty" state - defined outside class to allow for calling
+// after appearance mgr instance has been destroyed.
+void appearance_mgr_update_dirty_state()
+{
+	if (LLAppearanceMgr::instanceExists())
+	{
+		LLAppearanceMgr::getInstance()->updateIsDirty();
+		LLAppearanceMgr::getInstance()->setOutfitLocked(false);
+		gAgentWearables.notifyLoadingFinished();
+	}
+}
+
+void update_base_outfit_after_ordering()
+{
+	LLAppearanceMgr& app_mgr = LLAppearanceMgr::instance();
+	
+	LLPointer<LLInventoryCallback> dirty_state_updater =
+		new LLBoostFuncInventoryCallback(no_op_inventory_func, appearance_mgr_update_dirty_state);
+
+	//COF contains only links so we copy to the Base Outfit only links
+	const LLUUID base_outfit_id = app_mgr.getBaseOutfitUUID();
+	bool copy_folder_links = false;
+	app_mgr.slamCategoryLinks(app_mgr.getCOF(), base_outfit_id, copy_folder_links, dirty_state_updater);
+
+}
+
+// Save COF changes - update the contents of the current base outfit
+// to match the current COF. Fails if no current base outfit is set.
+bool LLAppearanceMgr::updateBaseOutfit()
+{
+	if (isOutfitLocked())
+	{
+		// don't allow modify locked outfit
+		llassert(!isOutfitLocked());
+		return false;
+	}
+
+	setOutfitLocked(true);
+
+	gAgentWearables.notifyLoadingStarted();
+
+	const LLUUID base_outfit_id = getBaseOutfitUUID();
+	if (base_outfit_id.isNull()) return false;
+	LL_DEBUGS("Avatar") << "saving cof to base outfit " << base_outfit_id << LL_ENDL;
+
+	LLPointer<LLInventoryCallback> cb =
+		new LLBoostFuncInventoryCallback(no_op_inventory_func, update_base_outfit_after_ordering);
+	// Really shouldn't be needed unless there's a race condition -
+	// updateAppearanceFromCOF() already calls updateClothingOrderingInfo.
+	updateClothingOrderingInfo(LLUUID::null, cb);
+
+	return true;
+}
+
+void LLAppearanceMgr::divvyWearablesByType(const LLInventoryModel::item_array_t& items, wearables_by_type_t& items_by_type)
+{
+	items_by_type.resize(LLWearableType::WT_COUNT);
+	if (items.empty()) return;
+
+	for (S32 i=0; i<items.size(); i++)
+	{
+		LLViewerInventoryItem *item = items.at(i);
+		if (!item)
+		{
+			LL_WARNS("Appearance") << "NULL item found" << LL_ENDL;
+			continue;
+		}
+		// Ignore non-wearables.
+		if (!item->isWearableType())
+			continue;
+		LLWearableType::EType type = item->getWearableType();
+		if(type < 0 || type >= LLWearableType::WT_COUNT)
+		{
+			LL_WARNS("Appearance") << "Invalid wearable type. Inventory type does not match wearable flag bitfield." << LL_ENDL;
+			continue;
+		}
+		items_by_type[type].push_back(item);
+	}
+}
+
+std::string build_order_string(LLWearableType::EType type, U32 i)
+{
+		std::ostringstream order_num;
+		order_num << ORDER_NUMBER_SEPARATOR << type * 100 + i;
+		return order_num.str();
+}
+
+struct WearablesOrderComparator
+{
+	LOG_CLASS(WearablesOrderComparator);
+	WearablesOrderComparator(const LLWearableType::EType type)
+	{
+		mControlSize = build_order_string(type, 0).size();
+	};
+
+	bool operator()(const LLInventoryItem* item1, const LLInventoryItem* item2)
+	{
+		const std::string& desc1 = item1->getActualDescription();
+		const std::string& desc2 = item2->getActualDescription();
+		
+		bool item1_valid = (desc1.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc1[0]);
+		bool item2_valid = (desc2.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc2[0]);
+
+		if (item1_valid && item2_valid)
+			return desc1 < desc2;
+
+		//we need to sink down invalid items: items with empty descriptions, items with "Broken link" descriptions,
+		//items with ordering information but not for the associated wearables type
+		if (!item1_valid && item2_valid) 
+			return false;
+		else if (item1_valid && !item2_valid)
+			return true;
+
+		return item1->getName() < item2->getName();
+	}
+
+	U32 mControlSize;
+};
+
+void LLAppearanceMgr::getWearableOrderingDescUpdates(LLInventoryModel::item_array_t& wear_items,
+													 desc_map_t& desc_map)
+{
+	wearables_by_type_t items_by_type(LLWearableType::WT_COUNT);
+	divvyWearablesByType(wear_items, items_by_type);
+
+	for (U32 type = LLWearableType::WT_SHIRT; type < LLWearableType::WT_COUNT; type++)
+	{
+		U32 size = items_by_type[type].size();
+		if (!size) continue;
+		
+		//sinking down invalid items which need reordering
+		std::sort(items_by_type[type].begin(), items_by_type[type].end(), WearablesOrderComparator((LLWearableType::EType) type));
+		
+		//requesting updates only for those links which don't have "valid" descriptions
+		for (U32 i = 0; i < size; i++)
+		{
+			LLViewerInventoryItem* item = items_by_type[type][i];
+			if (!item) continue;
+			
+			std::string new_order_str = build_order_string((LLWearableType::EType)type, i);
+			if (new_order_str == item->getActualDescription()) continue;
+			
+			desc_map[item->getUUID()] = new_order_str;
+		}
+	}
+}
+
+bool LLAppearanceMgr::validateClothingOrderingInfo(LLUUID cat_id)
+{
+	// COF is processed if cat_id is not specified
+	if (cat_id.isNull())
+	{
+		cat_id = getCOF();
+	}
+
+	LLInventoryModel::item_array_t wear_items;
+	getDescendentsOfAssetType(cat_id, wear_items, LLAssetType::AT_CLOTHING);
+
+	// Identify items for which desc needs to change.
+	desc_map_t desc_map;
+	getWearableOrderingDescUpdates(wear_items, desc_map);
+
+	for (desc_map_t::const_iterator it = desc_map.begin();
+		 it != desc_map.end(); ++it)
+	{
+		const LLUUID& item_id = it->first;
+		const std::string& new_order_str = it->second;
+		LLViewerInventoryItem *item = gInventory.getItem(item_id);
+		LL_WARNS() << "Order validation fails: " << item->getName()
+				<< " needs to update desc to: " << new_order_str
+				<< " (from: " << item->getActualDescription() << ")" << LL_ENDL;
+	}
+	
+	return desc_map.size() == 0;
+}
+
+void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id,
+												 LLPointer<LLInventoryCallback> cb)
+{
+	// COF is processed if cat_id is not specified
+	if (cat_id.isNull())
+	{
+		cat_id = getCOF();
+	}
+
+	LLInventoryModel::item_array_t wear_items;
+	getDescendentsOfAssetType(cat_id, wear_items, LLAssetType::AT_CLOTHING);
+
+	// Identify items for which desc needs to change.
+	desc_map_t desc_map;
+	getWearableOrderingDescUpdates(wear_items, desc_map);
+
+	for (desc_map_t::const_iterator it = desc_map.begin();
+		 it != desc_map.end(); ++it)
+	{
+		LLSD updates;
+		const LLUUID& item_id = it->first;
+		const std::string& new_order_str = it->second;
+		LLViewerInventoryItem *item = gInventory.getItem(item_id);
+		LL_DEBUGS("Avatar") << item->getName() << " updating desc to: " << new_order_str
+			<< " (was: " << item->getActualDescription() << ")" << LL_ENDL;
+		updates["desc"] = new_order_str;
+		update_inventory_item(item_id,updates,cb);
+	}
+		
+}
+
+
+LLSD LLAppearanceMgr::dumpCOF() const
+{
+	LLSD links = LLSD::emptyArray();
+	LLMD5 md5;
+	
+	LLInventoryModel::cat_array_t cat_array;
+	LLInventoryModel::item_array_t item_array;
+	gInventory.collectDescendents(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();
+		LLSD item;
+		LLUUID item_id(inv_item->getUUID());
+		md5.update((unsigned char*)item_id.mData, 16);
+		item["description"] = inv_item->getActualDescription();
+		md5.update(inv_item->getActualDescription());
+		item["asset_type"] = inv_item->getActualType();
+		LLUUID linked_id(inv_item->getLinkedUUID());
+		item["linked_id"] = linked_id;
+		md5.update((unsigned char*)linked_id.mData, 16);
+
+		if (LLAssetType::AT_LINK == inv_item->getActualType())
+		{
+			const LLViewerInventoryItem* linked_item = inv_item->getLinkedItem();
+			if (NULL == linked_item)
+			{
+				LL_WARNS() << "Broken link for item '" << inv_item->getName()
+						<< "' (" << inv_item->getUUID()
+						<< ") during requestServerAppearanceUpdate" << LL_ENDL;
+				continue;
+			}
+			// Some assets may be 'hidden' and show up as null in the viewer.
+			//if (linked_item->getAssetUUID().isNull())
+			//{
+			//	LL_WARNS() << "Broken link (null asset) for item '" << inv_item->getName()
+			//			<< "' (" << inv_item->getUUID()
+			//			<< ") during requestServerAppearanceUpdate" << LL_ENDL;
+			//	continue;
+			//}
+			LLUUID linked_asset_id(linked_item->getAssetUUID());
+			md5.update((unsigned char*)linked_asset_id.mData, 16);
+			U32 flags = linked_item->getFlags();
+			md5.update(boost::lexical_cast<std::string>(flags));
+		}
+		else if (LLAssetType::AT_LINK_FOLDER != inv_item->getActualType())
+		{
+			LL_WARNS() << "Non-link item '" << inv_item->getName()
+					<< "' (" << inv_item->getUUID()
+					<< ") type " << (S32) inv_item->getActualType()
+					<< " during requestServerAppearanceUpdate" << LL_ENDL;
+			continue;
+		}
+		links.append(item);
+	}
+	LLSD result = LLSD::emptyMap();
+	result["cof_contents"] = links;
+	char cof_md5sum[MD5HEX_STR_SIZE];
+	md5.finalize();
+	md5.hex_digest(cof_md5sum);
+	result["cof_md5sum"] = std::string(cof_md5sum);
+	return result;
+}
+
+void LLAppearanceMgr::requestServerAppearanceUpdate()
+{
+
+	if (!testCOFRequestVersion())
+	{
+		// *TODO: LL_LOG message here
+		return;
+	}
+
+	if ((mInFlightCounter > 0) && (mInFlightTimer.hasExpired()))
+	{
+		LL_WARNS("Avatar") << "in flight timer expired, resetting " << LL_ENDL;
+		mInFlightCounter = 0;
+	}
+
+	if (gAgentAvatarp->isEditingAppearance())
+	{
+		LL_WARNS("Avatar") << "Avatar editing appeance, not sending request." << LL_ENDL;
+		// don't send out appearance updates if in appearance editing mode
+		return;
+	}
+
+	if (!gAgent.getRegion())
+	{
+		LL_WARNS("Avatar") << "Region not set, cannot request server appearance update" << LL_ENDL;
+		return;
+	}
+	if (gAgent.getRegion()->getCentralBakeVersion() == 0)
+	{
+		LL_WARNS("Avatar") << "Region does not support baking" << LL_ENDL;
+	}
+	std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance");
+	if (url.empty())
+	{
+		LL_WARNS("Avatar") << "No cap for UpdateAvatarAppearance." << LL_ENDL;
+		return;
+	}
+
+	LLSD postData;
+	S32 cof_version = LLAppearanceMgr::instance().getCOFVersion();
+	if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate"))
+	{
+		postData = LLAppearanceMgr::instance().dumpCOF();
+	}
+	else
+	{
+		postData["cof_version"] = cof_version;
+		if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
+		{
+			postData["cof_version"] = cof_version + 999;
+		}
+	}
+	LL_DEBUGS("Avatar") << "request url " << url << " my_cof_version " << cof_version << LL_ENDL;
+
+	LLAppearanceMgrHttpHandler * handler = new LLAppearanceMgrHttpHandler(url, this);
+
+	mInFlightCounter++;
+	mInFlightTimer.setTimerExpirySec(60.0);
+
+	llassert(cof_version >= gAgentAvatarp->mLastUpdateRequestCOFVersion);
+	gAgentAvatarp->mLastUpdateRequestCOFVersion = cof_version;
+
+	LLCore::HttpHandle handle = LLCoreHttpUtil::requestPostWithLLSD(mHttpRequest,
+		mHttpPolicy, mHttpPriority, url,
+		postData, mHttpOptions, mHttpHeaders, handler);
+
+	if (handle == LLCORE_HTTP_HANDLE_INVALID)
+	{
 		delete handler;
 		LLCore::HttpStatus status = mHttpRequest->getStatus();
-		LL_WARNS("Avatar") << "Appearance request post failed Reason " << status.toTerseString()
-			<< " \"" << status.toString() << "\"" << LL_ENDL;
-	}
-}
-
-bool LLAppearanceMgr::testCOFRequestVersion() const
-{
-	// If we have already received an update for this or higher cof version, ignore.
-	S32 cof_version = getCOFVersion();
-	S32 last_rcv = gAgentAvatarp->mLastUpdateReceivedCOFVersion;
-	S32 last_req = gAgentAvatarp->mLastUpdateRequestCOFVersion;
-
-	LL_DEBUGS("Avatar") << "cof_version " << cof_version
-		<< " last_rcv " << last_rcv
-		<< " last_req " << last_req
-		<< " in flight " << mInFlightCounter 
-		<< LL_ENDL;
-	if (cof_version < last_rcv)
-	{
-		LL_DEBUGS("Avatar") << "Have already received update for cof version " << last_rcv
-			<< " will not request for " << cof_version << LL_ENDL;
-		return false;
-	}
-	if (/*mInFlightCounter > 0 &&*/ last_req >= cof_version)
-	{
-		LL_DEBUGS("Avatar") << "Request already in flight for cof version " << last_req
-			<< " will not request for " << cof_version << LL_ENDL;
-		return false;
-	}
-
-	// Actually send the request.
-	LL_DEBUGS("Avatar") << "Will send request for cof_version " << cof_version << LL_ENDL;
-	return true;
-}
-
+		LL_WARNS("Avatar") << "Appearance request post failed Reason " << status.toTerseString()
+			<< " \"" << status.toString() << "\"" << LL_ENDL;
+	}
+}
+
+bool LLAppearanceMgr::testCOFRequestVersion() const
+{
+	// If we have already received an update for this or higher cof version, ignore.
+	S32 cof_version = getCOFVersion();
+	S32 last_rcv = gAgentAvatarp->mLastUpdateReceivedCOFVersion;
+	S32 last_req = gAgentAvatarp->mLastUpdateRequestCOFVersion;
+
+	LL_DEBUGS("Avatar") << "cof_version " << cof_version
+		<< " last_rcv " << last_rcv
+		<< " last_req " << last_req
+		<< " in flight " << mInFlightCounter 
+		<< LL_ENDL;
+	if (cof_version < last_rcv)
+	{
+		LL_DEBUGS("Avatar") << "Have already received update for cof version " << last_rcv
+			<< " will not request for " << cof_version << LL_ENDL;
+		return false;
+	}
+	if (/*mInFlightCounter > 0 &&*/ last_req >= cof_version)
+	{
+		LL_DEBUGS("Avatar") << "Request already in flight for cof version " << last_req
+			<< " will not request for " << cof_version << LL_ENDL;
+		return false;
+	}
+
+	// Actually send the request.
+	LL_DEBUGS("Avatar") << "Will send request for cof_version " << cof_version << LL_ENDL;
+	return true;
+}
+
 bool LLAppearanceMgr::onIdle()
 {
 	if (!LLAppearanceMgr::mActive)
@@ -3492,566 +3492,566 @@ bool LLAppearanceMgr::onIdle()
 	mHttpRequest->update(0L);
 	return false;
 }
-
-std::string LLAppearanceMgr::getAppearanceServiceURL() const
-{
-	if (gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride").empty())
-	{
-		return mAppearanceServiceURL;
-	}
-	return gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride");
-}
-
-void show_created_outfit(LLUUID& folder_id, bool show_panel = true)
-{
-	if (!LLApp::isRunning())
-	{
-		LL_WARNS() << "called during shutdown, skipping" << LL_ENDL;
-		return;
-	}
-	
-	LL_DEBUGS("Avatar") << "called" << LL_ENDL;
-	LLSD key;
-	
-	//EXT-7727. For new accounts inventory callback is created during login process
-	// and may be processed after login process is finished
-	if (show_panel)
-	{
-		LL_DEBUGS("Avatar") << "showing panel" << LL_ENDL;
-		LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key);
-		
-	}
-	LLOutfitsList *outfits_list =
-		dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab"));
-	if (outfits_list)
-	{
-		outfits_list->setSelectedOutfitByUUID(folder_id);
-	}
-	
-	LLAppearanceMgr::getInstance()->updateIsDirty();
-	gAgentWearables.notifyLoadingFinished(); // New outfit is saved.
-	LLAppearanceMgr::getInstance()->updatePanelOutfitName("");
-
-	// For SSB, need to update appearance after we add a base outfit
-	// link, since, the COF version has changed. There is a race
-	// condition in initial outfit setup which can lead to rez
-	// failures - SH-3860.
-	LL_DEBUGS("Avatar") << "requesting appearance update after createBaseOutfitLink" << LL_ENDL;
-	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
-	LLAppearanceMgr::getInstance()->createBaseOutfitLink(folder_id, cb);
-}
-
-void LLAppearanceMgr::onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel)
-{
-	LLPointer<LLInventoryCallback> cb =
-		new LLBoostFuncInventoryCallback(no_op_inventory_func,
-										 boost::bind(&LLAppearanceMgr::onOutfitFolderCreatedAndClothingOrdered,this,folder_id,show_panel));
-	updateClothingOrderingInfo(LLUUID::null, cb);
-}
-
-void LLAppearanceMgr::onOutfitFolderCreatedAndClothingOrdered(const LLUUID& folder_id, bool show_panel)
-{
-	LLPointer<LLInventoryCallback> cb =
-		new LLBoostFuncInventoryCallback(no_op_inventory_func,
-										 boost::bind(show_created_outfit,folder_id,show_panel));
-	bool copy_folder_links = false;
-	slamCategoryLinks(getCOF(), folder_id, copy_folder_links, cb);
-}
-
-void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)
-{
-	if (!isAgentAvatarValid()) return;
-
-	LL_DEBUGS("Avatar") << "creating new outfit" << LL_ENDL;
-
-	gAgentWearables.notifyLoadingStarted();
-
-	// First, make a folder in the My Outfits directory.
-	const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
-	if (AISCommand::isAPIAvailable())
-	{
-		// cap-based category creation was buggy until recently. use
-		// existence of AIS as an indicator the fix is present. Does
-		// not actually use AIS to create the category.
-		inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel);
-		LLUUID folder_id = gInventory.createNewCategory(
-			parent_id,
-			LLFolderType::FT_OUTFIT,
-			new_folder_name,
-			func);
-	}
-	else
-	{		
-		LLUUID folder_id = gInventory.createNewCategory(
-			parent_id,
-			LLFolderType::FT_OUTFIT,
-			new_folder_name);
-		onOutfitFolderCreated(folder_id, show_panel);
-	}
-}
-
-void LLAppearanceMgr::wearBaseOutfit()
-{
-	const LLUUID& base_outfit_id = getBaseOutfitUUID();
-	if (base_outfit_id.isNull()) return;
-	
-	updateCOF(base_outfit_id);
-}
-
-void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
-{
-	if (ids_to_remove.empty())
-	{
-		LL_WARNS() << "called with empty list, nothing to do" << LL_ENDL;
-		return;
-	}
-	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
-	for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
-	{
-		const LLUUID& id_to_remove = *it;
-		const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);
-		removeCOFItemLinks(linked_item_id, cb);
-		addDoomedTempAttachment(linked_item_id);
-	}
-}
-
-void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
-{
-	LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove);
-	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
-	removeCOFItemLinks(linked_item_id, cb);
-	addDoomedTempAttachment(linked_item_id);
-}
-
-
-// Adds the given item ID to mDoomedTempAttachmentIDs iff it's a temp attachment
-void LLAppearanceMgr::addDoomedTempAttachment(const LLUUID& id_to_remove)
-{
-	LLViewerObject * attachmentp = gAgentAvatarp->findAttachmentByID(id_to_remove);
-	if (attachmentp &&
-		attachmentp->isTempAttachment())
-	{	// If this is a temp attachment and we want to remove it, record the ID 
-		// so it will be deleted when attachments are synced up with COF
-		mDoomedTempAttachmentIDs.insert(id_to_remove);
-		//LL_INFOS() << "Will remove temp attachment id " << id_to_remove << LL_ENDL;
-	}
-}
-
-// Find AND REMOVES the given UUID from mDoomedTempAttachmentIDs
-bool LLAppearanceMgr::shouldRemoveTempAttachment(const LLUUID& item_id)
-{
-	doomed_temp_attachments_t::iterator iter = mDoomedTempAttachmentIDs.find(item_id);
-	if (iter != mDoomedTempAttachmentIDs.end())
-	{
-		mDoomedTempAttachmentIDs.erase(iter);
-		return true;
-	}
-	return false;
-}
-
-
-bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body)
-{
-	if (!item || !item->isWearableType()) return false;
-	if (item->getType() != LLAssetType::AT_CLOTHING) return false;
-	if (!gInventory.isObjectDescendentOf(item->getUUID(), getCOF())) return false;
-
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	LLFindWearablesOfType filter_wearables_of_type(item->getWearableType());
-	gInventory.collectDescendentsIf(getCOF(), cats, items, true, filter_wearables_of_type);
-	if (items.empty()) return false;
-
-	// We assume that the items have valid descriptions.
-	std::sort(items.begin(), items.end(), WearablesOrderComparator(item->getWearableType()));
-
-	if (closer_to_body && items.front() == item) return false;
-	if (!closer_to_body && items.back() == item) return false;
-	
-	LLInventoryModel::item_array_t::iterator it = std::find(items.begin(), items.end(), item);
-	if (items.end() == it) return false;
-
-
-	//swapping descriptions
-	closer_to_body ? --it : ++it;
-	LLViewerInventoryItem* swap_item = *it;
-	if (!swap_item) return false;
-	std::string tmp = swap_item->getActualDescription();
-	swap_item->setDescription(item->getActualDescription());
-	item->setDescription(tmp);
-
-	// LL_DEBUGS("Inventory") << "swap, item "
-	// 					   << ll_pretty_print_sd(item->asLLSD())
-	// 					   << " swap_item "
-	// 					   << ll_pretty_print_sd(swap_item->asLLSD()) << LL_ENDL;
-
-	// FIXME switch to use AISv3 where supported.
-	//items need to be updated on a dataserver
-	item->setComplete(TRUE);
-	item->updateServer(FALSE);
-	gInventory.updateItem(item);
-
-	swap_item->setComplete(TRUE);
-	swap_item->updateServer(FALSE);
-	gInventory.updateItem(swap_item);
-
-	//to cause appearance of the agent to be updated
-	bool result = false;
-	if ((result = gAgentWearables.moveWearable(item, closer_to_body)))
-	{
-		gAgentAvatarp->wearableUpdated(item->getWearableType());
-	}
-
-	setOutfitDirty(true);
-
-	//*TODO do we need to notify observers here in such a way?
-	gInventory.notifyObservers();
-
-	return result;
-}
-
-//static
-void LLAppearanceMgr::sortItemsByActualDescription(LLInventoryModel::item_array_t& items)
-{
-	if (items.size() < 2) return;
-
-	std::sort(items.begin(), items.end(), sort_by_actual_description);
-}
-
-//#define DUMP_CAT_VERBOSE
-
-void LLAppearanceMgr::dumpCat(const LLUUID& cat_id, const std::string& msg)
-{
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	gInventory.collectDescendents(cat_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
-
-#ifdef DUMP_CAT_VERBOSE
-	LL_INFOS() << LL_ENDL;
-	LL_INFOS() << str << LL_ENDL;
-	S32 hitcount = 0;
-	for(S32 i=0; i<items.size(); i++)
-	{
-		LLViewerInventoryItem *item = items.get(i);
-		if (item)
-			hitcount++;
-		LL_INFOS() << i <<" "<< item->getName() <<LL_ENDL;
-	}
-#endif
-	LL_INFOS() << msg << " count " << items.size() << LL_ENDL;
-}
-
-void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items,
-									const std::string& msg)
-{
-	for (S32 i=0; i<items.size(); i++)
-	{
-		LLViewerInventoryItem *item = items.at(i);
-		LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
-		LLUUID asset_id;
-		if (linked_item)
-		{
-			asset_id = linked_item->getAssetUUID();
-		}
-		LL_DEBUGS("Avatar") << self_av_string() << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << LL_ENDL;
-	}
-}
-
-bool LLAppearanceMgr::mActive = true;
-
-LLAppearanceMgr::LLAppearanceMgr():
-	mAttachmentInvLinkEnabled(false),
-	mOutfitIsDirty(false),
-	mOutfitLocked(false),
-	mInFlightCounter(0),
-	mInFlightTimer(),
-	mIsInUpdateAppearanceFromCOF(false),
-	//mAppearanceResponder(new RequestAgentUpdateAppearanceResponder),
-	mHttpRequest(),
-	mHttpHeaders(),
-	mHttpOptions(),
-	mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
-	mHttpPriority(0)
-{
-	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
-
-	mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
-	mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false);
-	mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false);
-	mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_AVATAR);
-
-	LLOutfitObserver& outfit_observer = LLOutfitObserver::instance();
-	// unlock outfit on save operation completed
-	outfit_observer.addCOFSavedCallback(boost::bind(
-			&LLAppearanceMgr::setOutfitLocked, this, false));
-
-	mUnlockOutfitTimer.reset(new LLOutfitUnLockTimer(gSavedSettings.getS32(
-			"OutfitOperationsTimeout")));
-
-	gIdleCallbacks.addFunction(&LLAttachmentsMgr::onIdle, NULL);
-	doOnIdleRepeating(boost::bind(&LLAppearanceMgr::onIdle, this));
-}
-
-LLAppearanceMgr::~LLAppearanceMgr()
-{
-	mActive = false;
-}
-
-void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
-{
-	LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int) val << LL_ENDL;
-	mAttachmentInvLinkEnabled = val;
-}
-
-void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
-{
-       LL_INFOS() << msg << LL_ENDL;
-       for (std::set<LLUUID>::const_iterator it = atts.begin();
-               it != atts.end();
-               ++it)
-       {
-               LLUUID item_id = *it;
-               LLViewerInventoryItem *item = gInventory.getItem(item_id);
-               if (item)
-                       LL_INFOS() << "atts " << item->getName() << LL_ENDL;
-               else
-                       LL_INFOS() << "atts " << "UNKNOWN[" << item_id.asString() << "]" << LL_ENDL;
-       }
-       LL_INFOS() << LL_ENDL;
-}
-
-void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
-{
-	   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
-
-	   if (mAttachmentInvLinkEnabled)
-	   {
-		   // we have to pass do_update = true to call LLAppearanceMgr::updateAppearanceFromCOF.
-		   // it will trigger gAgentWariables.notifyLoadingFinished()
-		   // But it is not acceptable solution. See EXT-7777
-		   if (!isLinkedInCOF(item_id))
-		   {
-			   LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy();
-			   LLAppearanceMgr::addCOFItemLink(item_id, cb);  // Add COF link for item.
-		   }
-	   }
-	   else
-	   {
-		   //LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL;
-	   }
-}
-
-void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
-{
-	   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
-
-	   if (mAttachmentInvLinkEnabled)
-	   {
-		   LLAppearanceMgr::removeCOFItemLinks(item_id);
-	   }
-	   else
-	   {
-		   //LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL;
-	   }
-}
-
-BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
-{
-	const LLUUID& cof = getCOF();
-	if (obj_id == cof)
-		return TRUE;
-	const LLInventoryObject* obj = gInventory.getObject(obj_id);
-	if (obj && obj->getParentUUID() == cof)
-		return TRUE;
-	return FALSE;
-}
-
-// static
-bool LLAppearanceMgr::isLinkInCOF(const LLUUID& obj_id)
-{
-	const LLUUID& target_id = gInventory.getLinkedItemID(obj_id);
-	LLLinkedItemIDMatches find_links(target_id);
-	return gInventory.hasMatchingDirectDescendent(LLAppearanceMgr::instance().getCOF(), find_links);
-}
-
-BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
-{
-	if (!getIsInCOF(obj_id)) return FALSE;
-
-	// If a non-link somehow ended up in COF, allow deletion.
-	const LLInventoryObject *obj = gInventory.getObject(obj_id);
-	if (obj && !obj->getIsLinkType())
-	{
-		return FALSE;
-	}
-
-	// For now, don't allow direct deletion from the COF.  Instead, force users
-	// to choose "Detach" or "Take Off".
-	return TRUE;
-}
-
-class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver
-{
-public:
-	CallAfterCategoryFetchStage2(const uuid_vec_t& ids,
-								 nullary_func_t callable) :
-		LLInventoryFetchItemsObserver(ids),
-		mCallable(callable)
-	{
-	}
-	~CallAfterCategoryFetchStage2()
-	{
-	}
-	virtual void done()
-	{
-		LL_INFOS() << this << " done with incomplete " << mIncomplete.size()
-				<< " complete " << mComplete.size() <<  " calling callable" << LL_ENDL;
-
-		gInventory.removeObserver(this);
-		doOnIdleOneTime(mCallable);
-		delete this;
-	}
-protected:
-	nullary_func_t mCallable;
-};
-
-class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver
-{
-public:
-	CallAfterCategoryFetchStage1(const LLUUID& cat_id, nullary_func_t callable) :
-		LLInventoryFetchDescendentsObserver(cat_id),
-		mCallable(callable)
-	{
-	}
-	~CallAfterCategoryFetchStage1()
-	{
-	}
-	virtual void done()
-	{
-		// What we do here is get the complete information on the
-		// items in the requested category, and set up an observer
-		// that will wait for that to happen.
-		LLInventoryModel::cat_array_t cat_array;
-		LLInventoryModel::item_array_t item_array;
-		gInventory.collectDescendents(mComplete.front(),
-									  cat_array,
-									  item_array,
-									  LLInventoryModel::EXCLUDE_TRASH);
-		S32 count = item_array.size();
-		if(!count)
-		{
-			LL_WARNS() << "Nothing fetched in category " << mComplete.front()
-					<< LL_ENDL;
-			gInventory.removeObserver(this);
-			doOnIdleOneTime(mCallable);
-
-			delete this;
-			return;
-		}
-
-		LL_INFOS() << "stage1 got " << item_array.size() << " items, passing to stage2 " << LL_ENDL;
-		uuid_vec_t ids;
-		for(S32 i = 0; i < count; ++i)
-		{
-			ids.push_back(item_array.at(i)->getUUID());
-		}
-		
-		gInventory.removeObserver(this);
-		
-		// do the fetch
-		CallAfterCategoryFetchStage2 *stage2 = new CallAfterCategoryFetchStage2(ids, mCallable);
-		stage2->startFetch();
-		if(stage2->isFinished())
-		{
-			// everything is already here - call done.
-			stage2->done();
-		}
-		else
-		{
-			// it's all on it's way - add an observer, and the inventory
-			// will call done for us when everything is here.
-			gInventory.addObserver(stage2);
-		}
-		delete this;
-	}
-protected:
-	nullary_func_t mCallable;
-};
-
-void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb)
-{
-	CallAfterCategoryFetchStage1 *stage1 = new CallAfterCategoryFetchStage1(cat_id, cb);
-	stage1->startFetch();
-	if (stage1->isFinished())
-	{
-		stage1->done();
-	}
-	else
-	{
-		gInventory.addObserver(stage1);
-	}
-}
-
-void wear_multiple(const uuid_vec_t& ids, bool replace)
-{
-	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
-	
-	bool first = true;
-	uuid_vec_t::const_iterator it;
-	for (it = ids.begin(); it != ids.end(); ++it)
-	{
-		// if replace is requested, the first item worn will replace the current top
-		// item, and others will be added.
-		LLAppearanceMgr::instance().wearItemOnAvatar(*it,false,first && replace,cb);
-		first = false;
-	}
-}
-
-// SLapp for easy-wearing of a stock (library) avatar
-//
-class LLWearFolderHandler : public LLCommandHandler
-{
-public:
-	// not allowed from outside the app
-	LLWearFolderHandler() : LLCommandHandler("wear_folder", UNTRUSTED_BLOCK) { }
-
-	bool handle(const LLSD& tokens, const LLSD& query_map,
-				LLMediaCtrl* web)
-	{
-		LLSD::UUID folder_uuid;
-
-		if (folder_uuid.isNull() && query_map.has("folder_name"))
-		{
-			std::string outfit_folder_name = query_map["folder_name"];
-			folder_uuid = findDescendentCategoryIDByName(
-				gInventory.getLibraryRootFolderID(),
-				outfit_folder_name);	
-		}
-		if (folder_uuid.isNull() && query_map.has("folder_id"))
-		{
-			folder_uuid = query_map["folder_id"].asUUID();
-		}
-		
-		if (folder_uuid.notNull())
-		{
-			LLPointer<LLInventoryCategory> category = new LLInventoryCategory(folder_uuid,
-																			  LLUUID::null,
-																			  LLFolderType::FT_CLOTHING,
-																			  "Quick Appearance");
-			if ( gInventory.getCategory( folder_uuid ) != NULL )
-			{
-				LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
-				
-				// *TODOw: This may not be necessary if initial outfit is chosen already -- josh
-				gAgent.setOutfitChosen(TRUE);
-			}
-		}
-
-		// release avatar picker keyboard focus
-		gFocusMgr.setKeyboardFocus( NULL );
-
-		return true;
-	}
-};
-
-LLWearFolderHandler gWearFolderHandler;
+
+std::string LLAppearanceMgr::getAppearanceServiceURL() const
+{
+	if (gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride").empty())
+	{
+		return mAppearanceServiceURL;
+	}
+	return gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride");
+}
+
+void show_created_outfit(LLUUID& folder_id, bool show_panel = true)
+{
+	if (!LLApp::isRunning())
+	{
+		LL_WARNS() << "called during shutdown, skipping" << LL_ENDL;
+		return;
+	}
+	
+	LL_DEBUGS("Avatar") << "called" << LL_ENDL;
+	LLSD key;
+	
+	//EXT-7727. For new accounts inventory callback is created during login process
+	// and may be processed after login process is finished
+	if (show_panel)
+	{
+		LL_DEBUGS("Avatar") << "showing panel" << LL_ENDL;
+		LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key);
+		
+	}
+	LLOutfitsList *outfits_list =
+		dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab"));
+	if (outfits_list)
+	{
+		outfits_list->setSelectedOutfitByUUID(folder_id);
+	}
+	
+	LLAppearanceMgr::getInstance()->updateIsDirty();
+	gAgentWearables.notifyLoadingFinished(); // New outfit is saved.
+	LLAppearanceMgr::getInstance()->updatePanelOutfitName("");
+
+	// For SSB, need to update appearance after we add a base outfit
+	// link, since, the COF version has changed. There is a race
+	// condition in initial outfit setup which can lead to rez
+	// failures - SH-3860.
+	LL_DEBUGS("Avatar") << "requesting appearance update after createBaseOutfitLink" << LL_ENDL;
+	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
+	LLAppearanceMgr::getInstance()->createBaseOutfitLink(folder_id, cb);
+}
+
+void LLAppearanceMgr::onOutfitFolderCreated(const LLUUID& folder_id, bool show_panel)
+{
+	LLPointer<LLInventoryCallback> cb =
+		new LLBoostFuncInventoryCallback(no_op_inventory_func,
+										 boost::bind(&LLAppearanceMgr::onOutfitFolderCreatedAndClothingOrdered,this,folder_id,show_panel));
+	updateClothingOrderingInfo(LLUUID::null, cb);
+}
+
+void LLAppearanceMgr::onOutfitFolderCreatedAndClothingOrdered(const LLUUID& folder_id, bool show_panel)
+{
+	LLPointer<LLInventoryCallback> cb =
+		new LLBoostFuncInventoryCallback(no_op_inventory_func,
+										 boost::bind(show_created_outfit,folder_id,show_panel));
+	bool copy_folder_links = false;
+	slamCategoryLinks(getCOF(), folder_id, copy_folder_links, cb);
+}
+
+void LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)
+{
+	if (!isAgentAvatarValid()) return;
+
+	LL_DEBUGS("Avatar") << "creating new outfit" << LL_ENDL;
+
+	gAgentWearables.notifyLoadingStarted();
+
+	// First, make a folder in the My Outfits directory.
+	const LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+	if (AISCommand::isAPIAvailable())
+	{
+		// cap-based category creation was buggy until recently. use
+		// existence of AIS as an indicator the fix is present. Does
+		// not actually use AIS to create the category.
+		inventory_func_type func = boost::bind(&LLAppearanceMgr::onOutfitFolderCreated,this,_1,show_panel);
+		LLUUID folder_id = gInventory.createNewCategory(
+			parent_id,
+			LLFolderType::FT_OUTFIT,
+			new_folder_name,
+			func);
+	}
+	else
+	{		
+		LLUUID folder_id = gInventory.createNewCategory(
+			parent_id,
+			LLFolderType::FT_OUTFIT,
+			new_folder_name);
+		onOutfitFolderCreated(folder_id, show_panel);
+	}
+}
+
+void LLAppearanceMgr::wearBaseOutfit()
+{
+	const LLUUID& base_outfit_id = getBaseOutfitUUID();
+	if (base_outfit_id.isNull()) return;
+	
+	updateCOF(base_outfit_id);
+}
+
+void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
+{
+	if (ids_to_remove.empty())
+	{
+		LL_WARNS() << "called with empty list, nothing to do" << LL_ENDL;
+		return;
+	}
+	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
+	for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
+	{
+		const LLUUID& id_to_remove = *it;
+		const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);
+		removeCOFItemLinks(linked_item_id, cb);
+		addDoomedTempAttachment(linked_item_id);
+	}
+}
+
+void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
+{
+	LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove);
+	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
+	removeCOFItemLinks(linked_item_id, cb);
+	addDoomedTempAttachment(linked_item_id);
+}
+
+
+// Adds the given item ID to mDoomedTempAttachmentIDs iff it's a temp attachment
+void LLAppearanceMgr::addDoomedTempAttachment(const LLUUID& id_to_remove)
+{
+	LLViewerObject * attachmentp = gAgentAvatarp->findAttachmentByID(id_to_remove);
+	if (attachmentp &&
+		attachmentp->isTempAttachment())
+	{	// If this is a temp attachment and we want to remove it, record the ID 
+		// so it will be deleted when attachments are synced up with COF
+		mDoomedTempAttachmentIDs.insert(id_to_remove);
+		//LL_INFOS() << "Will remove temp attachment id " << id_to_remove << LL_ENDL;
+	}
+}
+
+// Find AND REMOVES the given UUID from mDoomedTempAttachmentIDs
+bool LLAppearanceMgr::shouldRemoveTempAttachment(const LLUUID& item_id)
+{
+	doomed_temp_attachments_t::iterator iter = mDoomedTempAttachmentIDs.find(item_id);
+	if (iter != mDoomedTempAttachmentIDs.end())
+	{
+		mDoomedTempAttachmentIDs.erase(iter);
+		return true;
+	}
+	return false;
+}
+
+
+bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body)
+{
+	if (!item || !item->isWearableType()) return false;
+	if (item->getType() != LLAssetType::AT_CLOTHING) return false;
+	if (!gInventory.isObjectDescendentOf(item->getUUID(), getCOF())) return false;
+
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLFindWearablesOfType filter_wearables_of_type(item->getWearableType());
+	gInventory.collectDescendentsIf(getCOF(), cats, items, true, filter_wearables_of_type);
+	if (items.empty()) return false;
+
+	// We assume that the items have valid descriptions.
+	std::sort(items.begin(), items.end(), WearablesOrderComparator(item->getWearableType()));
+
+	if (closer_to_body && items.front() == item) return false;
+	if (!closer_to_body && items.back() == item) return false;
+	
+	LLInventoryModel::item_array_t::iterator it = std::find(items.begin(), items.end(), item);
+	if (items.end() == it) return false;
+
+
+	//swapping descriptions
+	closer_to_body ? --it : ++it;
+	LLViewerInventoryItem* swap_item = *it;
+	if (!swap_item) return false;
+	std::string tmp = swap_item->getActualDescription();
+	swap_item->setDescription(item->getActualDescription());
+	item->setDescription(tmp);
+
+	// LL_DEBUGS("Inventory") << "swap, item "
+	// 					   << ll_pretty_print_sd(item->asLLSD())
+	// 					   << " swap_item "
+	// 					   << ll_pretty_print_sd(swap_item->asLLSD()) << LL_ENDL;
+
+	// FIXME switch to use AISv3 where supported.
+	//items need to be updated on a dataserver
+	item->setComplete(TRUE);
+	item->updateServer(FALSE);
+	gInventory.updateItem(item);
+
+	swap_item->setComplete(TRUE);
+	swap_item->updateServer(FALSE);
+	gInventory.updateItem(swap_item);
+
+	//to cause appearance of the agent to be updated
+	bool result = false;
+	if ((result = gAgentWearables.moveWearable(item, closer_to_body)))
+	{
+		gAgentAvatarp->wearableUpdated(item->getWearableType());
+	}
+
+	setOutfitDirty(true);
+
+	//*TODO do we need to notify observers here in such a way?
+	gInventory.notifyObservers();
+
+	return result;
+}
+
+//static
+void LLAppearanceMgr::sortItemsByActualDescription(LLInventoryModel::item_array_t& items)
+{
+	if (items.size() < 2) return;
+
+	std::sort(items.begin(), items.end(), sort_by_actual_description);
+}
+
+//#define DUMP_CAT_VERBOSE
+
+void LLAppearanceMgr::dumpCat(const LLUUID& cat_id, const std::string& msg)
+{
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	gInventory.collectDescendents(cat_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+#ifdef DUMP_CAT_VERBOSE
+	LL_INFOS() << LL_ENDL;
+	LL_INFOS() << str << LL_ENDL;
+	S32 hitcount = 0;
+	for(S32 i=0; i<items.size(); i++)
+	{
+		LLViewerInventoryItem *item = items.get(i);
+		if (item)
+			hitcount++;
+		LL_INFOS() << i <<" "<< item->getName() <<LL_ENDL;
+	}
+#endif
+	LL_INFOS() << msg << " count " << items.size() << LL_ENDL;
+}
+
+void LLAppearanceMgr::dumpItemArray(const LLInventoryModel::item_array_t& items,
+									const std::string& msg)
+{
+	for (S32 i=0; i<items.size(); i++)
+	{
+		LLViewerInventoryItem *item = items.at(i);
+		LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
+		LLUUID asset_id;
+		if (linked_item)
+		{
+			asset_id = linked_item->getAssetUUID();
+		}
+		LL_DEBUGS("Avatar") << self_av_string() << msg << " " << i <<" " << (item ? item->getName() : "(nullitem)") << " " << asset_id.asString() << LL_ENDL;
+	}
+}
+
+bool LLAppearanceMgr::mActive = true;
+
+LLAppearanceMgr::LLAppearanceMgr():
+	mAttachmentInvLinkEnabled(false),
+	mOutfitIsDirty(false),
+	mOutfitLocked(false),
+	mInFlightCounter(0),
+	mInFlightTimer(),
+	mIsInUpdateAppearanceFromCOF(false),
+	//mAppearanceResponder(new RequestAgentUpdateAppearanceResponder),
+	mHttpRequest(),
+	mHttpHeaders(),
+	mHttpOptions(),
+	mHttpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
+	mHttpPriority(0)
+{
+	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
+
+	mHttpRequest = LLCore::HttpRequest::ptr_t(new LLCore::HttpRequest());
+	mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders(), false);
+	mHttpOptions = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions(), false);
+	mHttpPolicy = app_core_http.getPolicy(LLAppCoreHttp::AP_AVATAR);
+
+	LLOutfitObserver& outfit_observer = LLOutfitObserver::instance();
+	// unlock outfit on save operation completed
+	outfit_observer.addCOFSavedCallback(boost::bind(
+			&LLAppearanceMgr::setOutfitLocked, this, false));
+
+	mUnlockOutfitTimer.reset(new LLOutfitUnLockTimer(gSavedSettings.getS32(
+			"OutfitOperationsTimeout")));
+
+	gIdleCallbacks.addFunction(&LLAttachmentsMgr::onIdle, NULL);
+	doOnIdleRepeating(boost::bind(&LLAppearanceMgr::onIdle, this));
+}
+
+LLAppearanceMgr::~LLAppearanceMgr()
+{
+	mActive = false;
+}
+
+void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
+{
+	LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int) val << LL_ENDL;
+	mAttachmentInvLinkEnabled = val;
+}
+
+void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
+{
+       LL_INFOS() << msg << LL_ENDL;
+       for (std::set<LLUUID>::const_iterator it = atts.begin();
+               it != atts.end();
+               ++it)
+       {
+               LLUUID item_id = *it;
+               LLViewerInventoryItem *item = gInventory.getItem(item_id);
+               if (item)
+                       LL_INFOS() << "atts " << item->getName() << LL_ENDL;
+               else
+                       LL_INFOS() << "atts " << "UNKNOWN[" << item_id.asString() << "]" << LL_ENDL;
+       }
+       LL_INFOS() << LL_ENDL;
+}
+
+void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
+{
+	   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
+
+	   if (mAttachmentInvLinkEnabled)
+	   {
+		   // we have to pass do_update = true to call LLAppearanceMgr::updateAppearanceFromCOF.
+		   // it will trigger gAgentWariables.notifyLoadingFinished()
+		   // But it is not acceptable solution. See EXT-7777
+		   if (!isLinkedInCOF(item_id))
+		   {
+			   LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy();
+			   LLAppearanceMgr::addCOFItemLink(item_id, cb);  // Add COF link for item.
+		   }
+	   }
+	   else
+	   {
+		   //LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL;
+	   }
+}
+
+void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
+{
+	   gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
+
+	   if (mAttachmentInvLinkEnabled)
+	   {
+		   LLAppearanceMgr::removeCOFItemLinks(item_id);
+	   }
+	   else
+	   {
+		   //LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL;
+	   }
+}
+
+BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
+{
+	const LLUUID& cof = getCOF();
+	if (obj_id == cof)
+		return TRUE;
+	const LLInventoryObject* obj = gInventory.getObject(obj_id);
+	if (obj && obj->getParentUUID() == cof)
+		return TRUE;
+	return FALSE;
+}
+
+// static
+bool LLAppearanceMgr::isLinkInCOF(const LLUUID& obj_id)
+{
+	const LLUUID& target_id = gInventory.getLinkedItemID(obj_id);
+	LLLinkedItemIDMatches find_links(target_id);
+	return gInventory.hasMatchingDirectDescendent(LLAppearanceMgr::instance().getCOF(), find_links);
+}
+
+BOOL LLAppearanceMgr::getIsProtectedCOFItem(const LLUUID& obj_id) const
+{
+	if (!getIsInCOF(obj_id)) return FALSE;
+
+	// If a non-link somehow ended up in COF, allow deletion.
+	const LLInventoryObject *obj = gInventory.getObject(obj_id);
+	if (obj && !obj->getIsLinkType())
+	{
+		return FALSE;
+	}
+
+	// For now, don't allow direct deletion from the COF.  Instead, force users
+	// to choose "Detach" or "Take Off".
+	return TRUE;
+}
+
+class CallAfterCategoryFetchStage2: public LLInventoryFetchItemsObserver
+{
+public:
+	CallAfterCategoryFetchStage2(const uuid_vec_t& ids,
+								 nullary_func_t callable) :
+		LLInventoryFetchItemsObserver(ids),
+		mCallable(callable)
+	{
+	}
+	~CallAfterCategoryFetchStage2()
+	{
+	}
+	virtual void done()
+	{
+		LL_INFOS() << this << " done with incomplete " << mIncomplete.size()
+				<< " complete " << mComplete.size() <<  " calling callable" << LL_ENDL;
+
+		gInventory.removeObserver(this);
+		doOnIdleOneTime(mCallable);
+		delete this;
+	}
+protected:
+	nullary_func_t mCallable;
+};
+
+class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver
+{
+public:
+	CallAfterCategoryFetchStage1(const LLUUID& cat_id, nullary_func_t callable) :
+		LLInventoryFetchDescendentsObserver(cat_id),
+		mCallable(callable)
+	{
+	}
+	~CallAfterCategoryFetchStage1()
+	{
+	}
+	virtual void done()
+	{
+		// What we do here is get the complete information on the
+		// items in the requested category, and set up an observer
+		// that will wait for that to happen.
+		LLInventoryModel::cat_array_t cat_array;
+		LLInventoryModel::item_array_t item_array;
+		gInventory.collectDescendents(mComplete.front(),
+									  cat_array,
+									  item_array,
+									  LLInventoryModel::EXCLUDE_TRASH);
+		S32 count = item_array.size();
+		if(!count)
+		{
+			LL_WARNS() << "Nothing fetched in category " << mComplete.front()
+					<< LL_ENDL;
+			gInventory.removeObserver(this);
+			doOnIdleOneTime(mCallable);
+
+			delete this;
+			return;
+		}
+
+		LL_INFOS() << "stage1 got " << item_array.size() << " items, passing to stage2 " << LL_ENDL;
+		uuid_vec_t ids;
+		for(S32 i = 0; i < count; ++i)
+		{
+			ids.push_back(item_array.at(i)->getUUID());
+		}
+		
+		gInventory.removeObserver(this);
+		
+		// do the fetch
+		CallAfterCategoryFetchStage2 *stage2 = new CallAfterCategoryFetchStage2(ids, mCallable);
+		stage2->startFetch();
+		if(stage2->isFinished())
+		{
+			// everything is already here - call done.
+			stage2->done();
+		}
+		else
+		{
+			// it's all on it's way - add an observer, and the inventory
+			// will call done for us when everything is here.
+			gInventory.addObserver(stage2);
+		}
+		delete this;
+	}
+protected:
+	nullary_func_t mCallable;
+};
+
+void callAfterCategoryFetch(const LLUUID& cat_id, nullary_func_t cb)
+{
+	CallAfterCategoryFetchStage1 *stage1 = new CallAfterCategoryFetchStage1(cat_id, cb);
+	stage1->startFetch();
+	if (stage1->isFinished())
+	{
+		stage1->done();
+	}
+	else
+	{
+		gInventory.addObserver(stage1);
+	}
+}
+
+void wear_multiple(const uuid_vec_t& ids, bool replace)
+{
+	LLPointer<LLInventoryCallback> cb = new LLUpdateAppearanceOnDestroy;
+	
+	bool first = true;
+	uuid_vec_t::const_iterator it;
+	for (it = ids.begin(); it != ids.end(); ++it)
+	{
+		// if replace is requested, the first item worn will replace the current top
+		// item, and others will be added.
+		LLAppearanceMgr::instance().wearItemOnAvatar(*it,false,first && replace,cb);
+		first = false;
+	}
+}
+
+// SLapp for easy-wearing of a stock (library) avatar
+//
+class LLWearFolderHandler : public LLCommandHandler
+{
+public:
+	// not allowed from outside the app
+	LLWearFolderHandler() : LLCommandHandler("wear_folder", UNTRUSTED_BLOCK) { }
+
+	bool handle(const LLSD& tokens, const LLSD& query_map,
+				LLMediaCtrl* web)
+	{
+		LLSD::UUID folder_uuid;
+
+		if (folder_uuid.isNull() && query_map.has("folder_name"))
+		{
+			std::string outfit_folder_name = query_map["folder_name"];
+			folder_uuid = findDescendentCategoryIDByName(
+				gInventory.getLibraryRootFolderID(),
+				outfit_folder_name);	
+		}
+		if (folder_uuid.isNull() && query_map.has("folder_id"))
+		{
+			folder_uuid = query_map["folder_id"].asUUID();
+		}
+		
+		if (folder_uuid.notNull())
+		{
+			LLPointer<LLInventoryCategory> category = new LLInventoryCategory(folder_uuid,
+																			  LLUUID::null,
+																			  LLFolderType::FT_CLOTHING,
+																			  "Quick Appearance");
+			if ( gInventory.getCategory( folder_uuid ) != NULL )
+			{
+				LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
+				
+				// *TODOw: This may not be necessary if initial outfit is chosen already -- josh
+				gAgent.setOutfitChosen(TRUE);
+			}
+		}
+
+		// release avatar picker keyboard focus
+		gFocusMgr.setKeyboardFocus( NULL );
+
+		return true;
+	}
+};
+
+LLWearFolderHandler gWearFolderHandler;
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 707b8d5a77aa490d4ea23d1a383458bd4284ea4d..b90ef65f95aa09ef0b2c6eac718a812971a1872d 100755
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -34,7 +34,6 @@
 #include "llinventorymodel.h"
 #include "llinventoryobserver.h"
 #include "llviewerinventory.h"
-#include "llhttpclient.h"
 
 class LLWearableHoldingPattern;
 class LLInventoryCallback;
@@ -218,10 +217,10 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 
 
 	bool testCOFRequestVersion() const;
-	void decrementInFlightCounter()
-	{
-		mInFlightCounter = llmax(mInFlightCounter - 1, 0);
-	}
+	void decrementInFlightCounter()
+	{
+		mInFlightCounter = llmax(mInFlightCounter - 1, 0);
+	}
 
 
 private:
@@ -263,9 +262,9 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	 * to avoid unsynchronized outfit state or performing duplicate operations.
 	 */
 	bool mOutfitLocked;
-	S32  mInFlightCounter;
-	LLTimer mInFlightTimer;
-	static bool mActive;
+	S32  mInFlightCounter;
+	LLTimer mInFlightTimer;
+	static bool mActive;
 
 	std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;