diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 22d8f88420036be96335cc8e8f83c7c7dc82d4df..e1715d567b73196e847c89b7d813417113f6c289 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -414,3 +414,16 @@ LLViewerObject* LLControlAvatar::lineSegmentIntersectRiggedAttachments(const LLV
 		
 	return hit;
 }
+
+// virtual
+std::string LLControlAvatar::getFullname() const
+{
+    if (mRootVolp)
+    {
+        return "AO_" + mRootVolp->getID().getString();
+    }
+    else
+    {
+        return "AO_no_root_vol";
+    }
+}
diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h
index a0f7912d240b34f67def04995c2650d3cc73c2e4..f45de25d81a711446f9c9aab9d041bd976cf3a0e 100644
--- a/indra/newview/llcontrolavatar.h
+++ b/indra/newview/llcontrolavatar.h
@@ -70,6 +70,8 @@ class LLControlAvatar:
 
 	virtual void	updateDebugText();
 
+    virtual std::string getFullname() const;
+
     bool mPlaying;
 
     F32 mGlobalScale;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 262bbd4d368b5c0b90d0890b461264015d665963..c2f90cfe1406654e1a4d0cd637e441f0672f69b7 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -1620,7 +1620,19 @@ class LLAdvancedEnableAppearanceToXML : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+        LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+        if (obj && obj->isAnimatedObject() && obj->getControlAvatar())
+        {
+            return gSavedSettings.getBOOL("DebugAnimatedObjects");
+        }
+        else if (obj && obj->isAttachment() && obj->getAvatar())
+        {
+            return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+        }
+		else
+		{
+			return false;
+		}
 	}
 };
 
@@ -1629,8 +1641,8 @@ class LLAdvancedAppearanceToXML : public view_listener_t
 	bool handleEvent(const LLSD& userdata)
 	{
 		std::string emptyname;
-		LLVOAvatar* avatar =
-			find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+        LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+        LLVOAvatar* avatar = obj->getAvatar();
 		if (!avatar)
 		{
 			avatar = gAgentAvatarp;
@@ -6054,7 +6066,12 @@ class LLAvatarResetSkeleton: public view_listener_t
 {
     bool handleEvent(const LLSD& userdata)
     {
-		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+		LLVOAvatar* avatar = NULL;
+        LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+        if (obj)
+        {
+            avatar = obj->getAvatar();
+        }
 		if(avatar)
         {
             avatar->resetSkeleton(false);
@@ -6063,6 +6080,20 @@ class LLAvatarResetSkeleton: public view_listener_t
     }
 };
 
+class LLAvatarEnableResetSkeleton: public view_listener_t
+{
+    bool handleEvent(const LLSD& userdata)
+    {
+        LLViewerObject *obj = LLSelectMgr::getInstance()->getSelection()->getPrimaryObject();
+        if (obj && obj->getAvatar())
+        {
+            return true;
+        }
+        return false;
+    }
+};
+
+
 class LLAvatarResetSkeletonAndAnimations : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -9080,6 +9111,7 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
 	view_listener_t::addMenu(new LLAvatarToggleMyProfile(), "Avatar.ToggleMyProfile");
 	view_listener_t::addMenu(new LLAvatarResetSkeleton(), "Avatar.ResetSkeleton");
+	view_listener_t::addMenu(new LLAvatarEnableResetSkeleton(), "Avatar.EnableResetSkeleton");
 	view_listener_t::addMenu(new LLAvatarResetSkeletonAndAnimations(), "Avatar.ResetSkeletonAndAnimations");
 	enable.add("Avatar.IsMyProfileOpen", boost::bind(&my_profile_visible));
 
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 5e88f9635feef5ae6430f591ba75ad818e845433..b0379bf9f7f9022b4495e018eeb61766bbe619a0 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -143,8 +143,8 @@ static LLTrace::BlockTimerStatHandle FTM_CREATE_OBJECT("Create Object");
 // static
 LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp, S32 flags)
 {
-    LL_DEBUGS("AnimatedObjects") << "creating " << id << LL_ENDL;
-    dumpStack("AnimatedObjectsStack");
+    LL_DEBUGS("ObjectUpdate") << "creating " << id << LL_ENDL;
+    dumpStack("ObjectUpdateStack");
     
 	LLViewerObject *res = NULL;
 	LL_RECORD_BLOCK_TIME(FTM_CREATE_OBJECT);
@@ -1111,8 +1111,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 {
 	LL_DEBUGS_ONCE("SceneLoadTiming") << "Received viewer object data" << LL_ENDL;
 
-    LL_DEBUGS("AnimatedObjects") << " mesgsys " << mesgsys << " dp " << dp << " id " << getID() << " update_type " << (S32) update_type << LL_ENDL;
-    dumpStack("AnimatedObjectsStack");
+    LL_DEBUGS("ObjectUpdate") << " mesgsys " << mesgsys << " dp " << dp << " id " << getID() << " update_type " << (S32) update_type << LL_ENDL;
+    dumpStack("ObjectUpdateStack");
 
 	U32 retval = 0x0;
 	
@@ -3002,6 +3002,9 @@ void LLViewerObject::linkControlAvatar()
             return;
         }
         mControlAvatar = LLControlAvatar::createControlAvatar(volp);
+        LL_DEBUGS("AnimatedObjects") << volp->getID() 
+                                     << " created control av for " 
+                                     << (S32) (1+volp->numChildren()) << " prims" << LL_ENDL;
     }
     if (getControlAvatar())
     {
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 6aac777007ed4f466ddaa1dc6d27e516beef9b77..c395259a8de0d5cfea50f5ea5f07c15399478e70 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -242,9 +242,9 @@ void LLViewerObjectList::processUpdateCore(LLViewerObject* objectp,
 	}
 
 	// ignore returned flags
-    LL_DEBUGS("AnimatedObjects") << "uuid " << objectp->mID << " calling processUpdateMessage " 
-                                 << objectp << " just_created " << just_created << " from_cache " << from_cache << " msg " << msg << LL_ENDL;
-    dumpStack("AnimatedObjectsStack");
+    LL_DEBUGS("ObjectUpdate") << "uuid " << objectp->mID << " calling processUpdateMessage " 
+                              << objectp << " just_created " << just_created << " from_cache " << from_cache << " msg " << msg << LL_ENDL;
+    dumpStack("ObjectUpdateStack");
 	 	
 	objectp->processUpdateMessage(msg, user_data, i, update_type, dpp);
 		
@@ -358,8 +358,8 @@ LLViewerObject* LLViewerObjectList::processObjectUpdateFromCache(LLVOCacheEntry*
 	{
 		objectp = createObjectFromCache(pcode, regionp, fullid, entry->getLocalID());
 
-        LL_DEBUGS("AnimatedObjects") << "uuid " << fullid << " created objectp " << objectp << LL_ENDL;
-        dumpStack("AnimatedObjectsStack");
+        LL_DEBUGS("ObjectUpdate") << "uuid " << fullid << " created objectp " << objectp << LL_ENDL;
+        dumpStack("ObjectUpdateStack");
 	 	
 		if (!objectp)
 		{
@@ -479,7 +479,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 			compressed_dp.reset();
 
 			uncompressed_length = mesgsys->getSizeFast(_PREHASH_ObjectData, i, _PREHASH_Data);
-            LL_DEBUGS("AnimatedObjects") << "got binary data from message to compressed_dpbuffer" << LL_ENDL;
+            LL_DEBUGS("ObjectUpdate") << "got binary data from message to compressed_dpbuffer" << LL_ENDL;
 			mesgsys->getBinaryDataFast(_PREHASH_ObjectData, _PREHASH_Data, compressed_dpbuffer, 0, i);
 			compressed_dp.assignBuffer(compressed_dpbuffer, uncompressed_length);
 
@@ -531,7 +531,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 			}
             else
             {
-                LL_DEBUGS("AnimatedObjects") << "Non-full, non-compressed update, obj " << local_id << ", global ID " << fullid << " from " << mesgsys->getSender() << LL_ENDL;
+                LL_DEBUGS("ObjectUpdate") << "Non-full, non-compressed update, obj " << local_id << ", global ID " << fullid << " from " << mesgsys->getSender() << LL_ENDL;
             }
 		}
 		else // OUT_FULL only?
@@ -541,18 +541,18 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 			mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_ID, local_id, i);
 			msg_size += sizeof(LLUUID);
 			msg_size += sizeof(U32);
-			LL_DEBUGS("AnimatedObjects") << "Full Update, obj " << local_id << ", global ID " << fullid << " from " << mesgsys->getSender() << LL_ENDL;
+			LL_DEBUGS("ObjectUpdate") << "Full Update, obj " << local_id << ", global ID " << fullid << " from " << mesgsys->getSender() << LL_ENDL;
 		}
 		objectp = findObject(fullid);
 
         if (compressed)
         {
-            LL_DEBUGS("AnimatedObjects") << "uuid " << fullid << " received compressed data from message (earlier in function)" << LL_ENDL;
+            LL_DEBUGS("ObjectUpdate") << "uuid " << fullid << " received compressed data from message (earlier in function)" << LL_ENDL;
         }
-        LL_DEBUGS("AnimatedObjects") << "uuid " << fullid << " objectp " << objectp 
+        LL_DEBUGS("ObjectUpdate") << "uuid " << fullid << " objectp " << objectp 
                                      << " update_cache " << (S32) update_cache << " compressed " << compressed
                                      << " update_type "  << update_type << LL_ENDL;
-        dumpStack("AnimatedObjectsStack");
+        dumpStack("ObjectUpdateStack");
         
 		if(update_cache)
 		{
@@ -629,8 +629,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 
 			objectp = createObject(pcode, regionp, fullid, local_id, gMessageSystem->getSender());
 
-            LL_DEBUGS("AnimatedObjects") << "creating object " << fullid << " result " << objectp << LL_ENDL;
-            dumpStack("AnimatedObjectsStack");
+            LL_DEBUGS("ObjectUpdate") << "creating object " << fullid << " result " << objectp << LL_ENDL;
+            dumpStack("ObjectUpdateStack");
 
 			if (!objectp)
 			{
@@ -727,15 +727,15 @@ void LLViewerObjectList::processCachedObjectUpdate(LLMessageSystem *mesgsys,
 		mesgsys->getU32Fast(_PREHASH_ObjectData, _PREHASH_UpdateFlags, flags, i);
 		msg_size += sizeof(U32) * 2;
 
-        LL_DEBUGS("AnimatedObjects") << "got probe for id " << id << " crc " << crc << LL_ENDL;
-        dumpStack("AnimatedObjectsStack");
+        LL_DEBUGS("ObjectUpdate") << "got probe for id " << id << " crc " << crc << LL_ENDL;
+        dumpStack("ObjectUpdateStack");
 
 		// Lookup data packer and add this id to cache miss lists if necessary.
 		U8 cache_miss_type = LLViewerRegion::CACHE_MISS_TYPE_NONE;
 		if(!regionp->probeCache(id, crc, flags, cache_miss_type))
 		{
 			// Cache Miss.
-            LL_DEBUGS("AnimatedObjects") << "cache miss for id " << id << " crc " << crc << " miss type " << (S32) cache_miss_type << LL_ENDL;
+            LL_DEBUGS("ObjectUpdate") << "cache miss for id " << id << " crc " << crc << " miss type " << (S32) cache_miss_type << LL_ENDL;
 
 			recorder.cacheMissEvent(id, update_type, cache_miss_type, msg_size);
 
@@ -1292,6 +1292,9 @@ void LLViewerObjectList::cleanupReferences(LLViewerObject *objectp)
 	// Cleanup any references we have to this object
 	// Remove from object map so noone can look it up.
 
+    LL_DEBUGS("ObjectUpdate") << " dereferencing id " << objectp->mID << LL_ENDL;
+    dumpStack("ObjectUpdateStack");
+    
 	mUUIDObjectMap.erase(objectp->mID);
 	
 	//if (objectp->getRegion())
@@ -2003,8 +2006,8 @@ LLViewerObject *LLViewerObjectList::createObjectFromCache(const LLPCode pcode, L
 {
 	llassert_always(uuid.notNull());
 
-    LL_DEBUGS("AnimatedObjects") << "creating " << uuid << " local_id " << local_id << LL_ENDL;
-    dumpStack("AnimatedObjectsStack");
+    LL_DEBUGS("ObjectUpdate") << "creating " << uuid << " local_id " << local_id << LL_ENDL;
+    dumpStack("ObjectUpdateStack");
     
 	LLViewerObject *objectp = LLViewerObject::createObject(uuid, pcode, regionp);
 	if (!objectp)
@@ -2040,8 +2043,8 @@ LLViewerObject *LLViewerObjectList::createObject(const LLPCode pcode, LLViewerRe
 		fullid = uuid;
 	}
 
-    LL_DEBUGS("AnimatedObjects") << "createObject creating " << fullid << LL_ENDL;
-    dumpStack("AnimatedObjectsStack");
+    LL_DEBUGS("ObjectUpdate") << "createObject creating " << fullid << LL_ENDL;
+    dumpStack("ObjectUpdateStack");
 
 	LLViewerObject *objectp = LLViewerObject::createObject(fullid, pcode, regionp);
 	if (!objectp)
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 54a53898fb0ab7fccec764d20e111a9c4c15c4c0..9d54767c13ea7c51fbcf432f28ee33b1e0d0d6fd 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1890,7 +1890,7 @@ void LLVOAvatar::resetVisualParams()
 void LLVOAvatar::resetSkeleton(bool reset_animations)
 {
     LL_DEBUGS("Avatar") << avString() << " reset starts" << LL_ENDL;
-    if (!mLastProcessedAppearance)
+    if (!isControlAvatar() && !mLastProcessedAppearance)
     {
         LL_WARNS() << "Can't reset avatar; no appearance message has been received yet." << LL_ENDL;
         return;
@@ -1944,8 +1944,11 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
     }
 
     // Reset tweakable params to preserved state
-    bool slam_params = true;
-    applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params);
+    if (mLastProcessedAppearance)
+    {
+        bool slam_params = true;
+        applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params);
+    }
     updateVisualParams();
 
     // Restore attachment pos overrides
@@ -5820,6 +5823,9 @@ void LLVOAvatar::rebuildAttachmentOverrides()
 {
     LLScopedContextString str("rebuildAttachmentOverrides " + getFullname());
 
+    LL_DEBUGS("AnimatedObjects") << "rebuilding" << LL_ENDL;
+    dumpStack("AnimatedObjectsStack");
+    
     clearAttachmentOverrides();
 
     // Handle the case that we're resetting the skeleton of an animated object.
@@ -5829,6 +5835,8 @@ void LLVOAvatar::rebuildAttachmentOverrides()
         LLVOVolume *volp = control_av->mRootVolp;
         if (volp)
         {
+            LL_DEBUGS("Avatar") << volp->getID() << " adding attachment overrides for root vol, prim count " 
+                                << (S32) (1+volp->numChildren()) << LL_ENDL;
             addAttachmentOverridesForObject(volp);
         }
     }
@@ -5869,6 +5877,9 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
 
     LLScopedContextString str("addAttachmentOverridesForObject " + vo->getAvatar()->getFullname());
     
+    LL_DEBUGS("AnimatedObjects") << "adding" << LL_ENDL;
+    dumpStack("AnimatedObjectsStack");
+    
 	// Process all children
 	LLViewerObject::const_child_list_t& children = vo->getChildren();
 	for (LLViewerObject::const_child_list_t::const_iterator it = children.begin();
@@ -5885,6 +5896,8 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
 	{
 		return;
 	}
+
+    LL_DEBUGS("AnimatedObjects") << "trying to add attachment overrides for root object " << root_object->getID() << " prim is " << vobj << LL_ENDL;
 	if (vobj->isMesh() &&
 		((vobj->getVolume() && !vobj->getVolume()->isMeshAssetLoaded()) || !gMeshRepo.meshRezEnabled()))
 	{
@@ -5904,6 +5917,8 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
 		{					
 			const F32 pelvisZOffset = pSkinData->mPelvisOffset;
 			const LLUUID& mesh_id = pSkinData->mMeshID;
+            LLViewerObject *root_object = (LLViewerObject*)vobj->getRoot();
+            LL_DEBUGS("AnimatedObjects") << "adding attachment overrides for " << mesh_id << " to root object " << root_object->getID() << LL_ENDL;
 			bool fullRig = (jointCnt>=JOINT_COUNT_REQUIRED_FOR_FULLRIG) ? true : false;								
 			if ( fullRig )
 			{								
@@ -9135,6 +9150,7 @@ void LLVOAvatar::updateRegion(LLViewerRegion *regionp)
 	LLViewerObject::updateRegion(regionp);
 }
 
+// virtual
 std::string LLVOAvatar::getFullname() const
 {
 	std::string name;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index e9eadb77e940c1de485479643b33a344f63946bc..d7b67de2ad32549e1ccda4671a95b453ff8460e3 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -926,7 +926,7 @@ class LLVOAvatar :
  **/
 
 public:
-	std::string		getFullname() const; // Returns "FirstName LastName"
+	virtual std::string	getFullname() const; // Returns "FirstName LastName"
 	std::string		avString() const; // Frequently used string in log messages "Avatar '<full name'"
 protected:
 	static void		getAnimLabels(std::vector<std::string>* labels);
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 3d1cfcfa6b216d7469f4640e087cd9fc8d158254..8fcb498fcaef940a8e552fbf6c533ff8edf9a50c 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -324,8 +324,8 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
 		sculpt_id = sculpt_params->getSculptTexture();
 		sculpt_type = sculpt_params->getSculptType();
 
-        LL_DEBUGS("AnimatedObjects") << "uuid " << mID << " set sculpt_id " << sculpt_id << LL_ENDL;
-        dumpStack("AnimatedObjectsStack");
+        LL_DEBUGS("ObjectUpdate") << "uuid " << mID << " set sculpt_id " << sculpt_id << LL_ENDL;
+        dumpStack("ObjectUpdateStack");
 	}
 
 	if (!dp)
@@ -3467,12 +3467,26 @@ void LLVOVolume::onReparent(LLViewerObject *old_parent, LLViewerObject *new_pare
 // virtual
 void LLVOVolume::afterReparent()
 {
-    // If this succeeds now, it's because the new parent is an animated object
+    {
+        LL_DEBUGS("AnimatedObjects") << "new child added for parent " 
+            << ((LLViewerObject*)getParent())->getID() << LL_ENDL;
+    }
+                                                                                             
     if (isAnimatedObject() && getControlAvatar())
     {
-        getControlAvatar()->addAttachmentOverridesForObject(this);
+        LL_DEBUGS("AnimatedObjects") << "adding attachment overrides, parent is animated object" 
+            << ((LLViewerObject*)getParent())->getID() << LL_ENDL;
+        //getControlAvatar()->addAttachmentOverridesForObject(this);
+        getControlAvatar()->rebuildAttachmentOverrides();
         getControlAvatar()->updateAnimations();
     }
+    else
+    {
+        LL_DEBUGS("AnimatedObjects") << "not adding overrides, parent: " 
+                                     << ((LLViewerObject*)getParent())->getID() 
+                                     << " isAnimated: "  << isAnimatedObject() << " cav "
+                                     << getControlAvatar() << LL_ENDL;
+    }
 }
 
 //----------------------------------------------------------------------------
diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml
index dc9622a27db73378b00e26e7c27adc72230b9648..91e7328979904ef1416c678e339e4af95b47705b 100644
--- a/indra/newview/skins/default/xui/en/menu_object.xml
+++ b/indra/newview/skins/default/xui/en/menu_object.xml
@@ -214,4 +214,20 @@
     <menu_item_call.on_enable
      function="EnableMuteParticle" />
   </menu_item_call>
+    <menu_item_call
+		 label="Dump XML"
+         name="Dump XML">
+            <menu_item_call.on_click
+             function="Advanced.AppearanceToXML" />
+            <menu_item_call.on_visible
+             function="Advanced.EnableAppearanceToXML"/>
+    </menu_item_call>
+    <menu_item_call
+		 label="Reset Skeleton"
+         name="Reset Skeleton">
+            <menu_item_call.on_click
+                function="Avatar.ResetSkeleton" />
+            <menu_item_call.on_visible
+             function="Advanced.EnableResetSkeleton"/>
+    </menu_item_call>
 </context_menu>