diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index acbf02678c6674c270389d113603e89e55fb9c49..f2e6a3a5fb8d62ae2b8ad5470093126e52ae847d 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1410,7 +1410,7 @@ LLUUID LLAgentWearables::makeNewOutfitLinks(const std::string& new_folder_name)
 		new_folder_name);
 
 	LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id);
-	LLAppearanceManager::instance().shallowCopyCategory(LLAppearanceManager::instance().getCOF(),folder_id, cb);
+	LLAppearanceManager::instance().shallowCopyCategoryContents(LLAppearanceManager::instance().getCOF(),folder_id, cb);
 	LLAppearanceManager::instance().createBaseOutfitLink(folder_id, cb);
 
 	return folder_id;
@@ -2327,7 +2327,7 @@ void LLLibraryOutfitsFetch::libraryDone(void)
 			LLUUID folder_id = gInventory.createNewCategory(mImportedClothingID,
 															LLFolderType::FT_NONE,
 															iter->second);
-			LLAppearanceManager::getInstance()->shallowCopyCategory(iter->first, folder_id, copy_waiter);
+			LLAppearanceManager::getInstance()->shallowCopyCategoryContents(iter->first, folder_id, copy_waiter);
 		}
 	}
 	else
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 0fe236c0566f073f038bfe5e1a1d23571cc5aa9b..6c4c59c4e7c1df00891682e908388b9333da692d 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -519,8 +519,30 @@ void LLAppearanceManager::changeOutfit(bool proceed, const LLUUID& category, boo
 	LLAppearanceManager::instance().updateCOF(category,append);
 }
 
+// Create a copy of src_id + contents as a subfolder of dst_id.
 void LLAppearanceManager::shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
 											  LLPointer<LLInventoryCallback> cb)
+{
+	LLInventoryCategory *src_cat = gInventory.getCategory(src_id);
+	if (!src_cat)
+	{
+		llwarns << "folder not found for src " << src_id.asString() << llendl;
+		return;
+	}
+	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);
+}
+
+// Copy contents of src_id to dst_id.
+void LLAppearanceManager::shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
+													  LLPointer<LLInventoryCallback> cb)
 {
 	LLInventoryModel::cat_array_t cats;
 	LLInventoryModel::item_array_t items;
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 38d1e01d08521e0309b2432744bde7c909773b33..63ac4d5402e25d93f4de52f64e57e371077583e5 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -54,10 +54,14 @@ class LLAppearanceManager: public LLSingleton<LLAppearanceManager>
 	void wearOutfitByName(const std::string& name);
 	void changeOutfit(bool proceed, const LLUUID& category, bool append);
 
-	// Copy all items in a category.
+	// Copy all items and the src category itself.
 	void shallowCopyCategory(const LLUUID& src_id, const LLUUID& dst_id,
 							 LLPointer<LLInventoryCallback> cb);
 
+	// Copy all items in a category.
+	void shallowCopyCategoryContents(const LLUUID& src_id, const LLUUID& dst_id,
+									 LLPointer<LLInventoryCallback> cb);
+
 	// Find the Current Outfit folder.
 	const LLUUID getCOF() const;
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index a402dfc3d1796dca0ad9f506f7f0c2edfb8aedeb..7dd597a0df30ad2f8bcd73b515579614fa24de76 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2530,6 +2530,109 @@ bool callback_choose_gender(const LLSD& notification, const LLSD& response)
 	return false;
 }
 
+LLViewerInventoryCategory* findDescendentCategoryByName(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.count())
+		return NULL;
+	else
+		return cat_array.get(0);
+}
+
+class CopyAfterFetchStage2: public LLInventoryFetchObserver
+{
+public:
+	CopyAfterFetchStage2(LLViewerInventoryCategory *cat, const LLUUID& dst_id):
+		mCat(cat),
+		mDstID(dst_id)
+	{
+	}
+	~CopyAfterFetchStage2()
+	{
+	}
+	virtual void done()
+	{
+//		LLAppearanceManager::instance().shallowCopyCategory(cat,dst_id,NULL);
+		gInventory.removeObserver(this);
+		LLPointer<LLInventoryCallback> cb(NULL);
+		LLAppearanceManager *app_mgr = &(LLAppearanceManager::instance());
+		doOnIdle(boost::bind(&LLAppearanceManager::shallowCopyCategory,app_mgr,mCat->getUUID(),mDstID,cb));
+		delete this;
+	}
+protected:
+	LLViewerInventoryCategory *mCat;
+	LLUUID mDstID;
+};
+
+class CopyAfterFetchStage1: public LLInventoryFetchDescendentsObserver
+{
+public:
+	CopyAfterFetchStage1(LLViewerInventoryCategory *cat, const LLUUID& dst_id):
+		mCat(cat),
+		mDstID(dst_id)
+	{
+	}
+	~CopyAfterFetchStage1()
+	{
+	}
+	virtual void done()
+	{
+		// What we do here is get the complete information on the items in
+		// the library, 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(mCompleteFolders.front(),
+									  cat_array,
+									  item_array,
+									  LLInventoryModel::EXCLUDE_TRASH);
+		S32 count = item_array.count();
+		if(!count)
+		{
+			llwarns << "Nothing fetched in category " << mCompleteFolders.front()
+					<< llendl;
+			//dec_busy_count();
+			gInventory.removeObserver(this);
+			delete this;
+			return;
+		}
+
+		CopyAfterFetchStage2 *stage2 = new CopyAfterFetchStage2(mCat,mDstID);
+		LLInventoryFetchObserver::item_ref_t ids;
+		for(S32 i = 0; i < count; ++i)
+		{
+			ids.push_back(item_array.get(i)->getUUID());
+		}
+		
+		gInventory.removeObserver(this);
+		
+		// do the fetch
+		stage2->fetchItems(ids);
+		if(stage2->isEverythingComplete())
+		{
+			// 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:
+	LLViewerInventoryCategory *mCat;
+	LLUUID mDstID;
+};
+
 void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 								   const std::string& gender_name )
 {
@@ -2553,27 +2656,59 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 
 	// try to find the outfit - if not there, create some default
 	// wearables.
-	LLInventoryModel::cat_array_t cat_array;
-	LLInventoryModel::item_array_t item_array;
-	LLNameCategoryCollector has_name(outfit_folder_name);
-	gInventory.collectDescendentsIf(gInventory.getLibraryRootFolderID(),
-									cat_array,
-									item_array,
-									LLInventoryModel::EXCLUDE_TRASH,
-									has_name);
-	if (0 == cat_array.count())
+	LLViewerInventoryCategory *cat = findDescendentCategoryByName(
+		gInventory.getLibraryRootFolderID(),
+		outfit_folder_name);
+	if (!cat)
 	{
 		gAgentWearables.createStandardWearables(gender);
 	}
 	else
 	{
-		LLInventoryCategory* cat = cat_array.get(0);
 		bool do_copy = true;
 		bool do_append = false;
 		LLAppearanceManager::instance().wearInventoryCategory(cat, do_copy, do_append);
 	}
-	LLAppearanceManager::instance().wearOutfitByName(gestures);
-	LLAppearanceManager::instance().wearOutfitByName(COMMON_GESTURES_FOLDER);
+
+	// Copy gender-specific gestures.
+	LLViewerInventoryCategory *gestures_cat = findDescendentCategoryByName( 
+		gInventory.getLibraryRootFolderID(),
+		gestures);
+	if (gestures_cat)
+	{
+		CopyAfterFetchStage1 *stage1 = new CopyAfterFetchStage1(
+			gestures_cat, gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE));
+		LLInventoryFetchDescendentsObserver::folder_ref_t folders;
+		folders.push_back(gestures_cat->getUUID());
+		stage1->fetchDescendents(folders);
+		if (stage1->isEverythingComplete())
+		{
+			stage1->done();
+		}
+		else
+		{
+			gInventory.addObserver(stage1);
+		}
+
+//		LLAppearanceManager::instance().shallowCopyCategory(
+//			gestures_cat->getUUID(),
+//			gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE),
+//			NULL);
+	}
+
+	// Copy common gestures.
+#if 0
+	LLViewerInventoryCategory *common_gestures_cat = findDescendentCategoryByName( 
+		gInventory.getLibraryRootFolderID(),
+		COMMON_GESTURES_FOLDER);
+	if (common_gestures_cat)
+	{
+		LLAppearanceManager::instance().shallowCopyCategory(
+			common_gestures_cat->getUUID(),
+			gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE),
+			NULL);
+	}
+#endif
 
 	// This is really misnamed -- it means we have started loading
 	// an outfit/shape that will give the avatar a gender eventually. JC
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 4235f97eabb71d826e9f33039957874be40fe753..bafdd9474e94778881dbeb45203129095a3eed68 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1869,7 +1869,8 @@ void LLVOAvatar::releaseMeshData()
 // virtual
 void LLVOAvatar::restoreMeshData()
 {
-	llassert(!isSelf());
+	// BAP restore
+	//llassert(!isSelf());
 	LLMemType mt(LLMemType::MTYPE_AVATAR);
 	
 	//llinfos << "Restoring" << llendl;