diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 6fc3d52fe7a5fee77a8657e34e293941f28623aa..bd99f66459eb2fc81096cda6f708911ab8b104d7 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -183,4 +183,10 @@ void LLControlAvatar::idleUpdate(LLAgent &agent, const F64 &time)
     }
 }
 
+//virtual
+void LLControlAvatar::updateDebugText()
+{
+    addDebugText("I'm a control avatar");
 
+    LLVOAvatar::updateDebugText();
+}
diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h
index 5cca0ab9dd79b327ee1301f2dd1d9b79fbdabf67..fc7b4aa06d9b4e8546ade2dd782915d10f350485 100644
--- a/indra/newview/llcontrolavatar.h
+++ b/indra/newview/llcontrolavatar.h
@@ -52,6 +52,8 @@ class LLControlAvatar:
 
     virtual void idleUpdate(LLAgent &agent, const F64 &time);
     
+	virtual void	updateDebugText();
+
     bool mPlaying;
 
     F32 mGlobalScale;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index f8cdb5bf928fc77e0025cdb236dc9095691aa6ef..227c6afcb0282acce9b4bfbd36aaeead6305ae88 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -5105,7 +5105,7 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data)
     }
     
 	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_AnimationList);
-	LL_WARNS() << "AXON handle object animation here, num_blocks " << num_blocks << LL_ENDL;
+	LL_DEBUGS("AXON") << "handle object animation here, num_blocks " << num_blocks << LL_ENDL;
 
     if (!avatarp->mPlaying)
     {
@@ -5119,13 +5119,13 @@ void process_object_animation(LLMessageSystem *mesgsys, void **user_data)
         mesgsys->getUUIDFast(_PREHASH_AnimationList, _PREHASH_AnimID, animation_id, i);
         mesgsys->getS32Fast(_PREHASH_AnimationList, _PREHASH_AnimSequenceID, anim_sequence_id, i);
         avatarp->mSignaledAnimations[animation_id] = anim_sequence_id;
-        LL_INFOS() << "AXON got object animation request for object " 
+        LL_DEBUGS("AXON") << "got object animation request for object " 
                    << uuid << " animation id " << animation_id << LL_ENDL;
     }
 
 	if (num_blocks >= 0)
 	{
-        LL_INFOS() << "AXON process animation state changes here" << LL_ENDL;
+        LL_DEBUGS("AXON") << "process animation state changes here" << LL_ENDL;
 		avatarp->processAnimationStateChanges();
 	}
 }
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 9a6153d3e642e87380452bf3c9fc4c6e8d4a313e..c6051650cf013715c84cad8d4af8826e28e7276e 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -371,17 +371,19 @@ void LLViewerObject::markDead()
 		//LL_INFOS() << "Marking self " << mLocalID << " as dead." << LL_ENDL;
 		
 		// Root object of this hierarchy unlinks itself.
-		LLVOAvatar *av = getAvatarAncestor();
 		if (getParent())
 		{
 			((LLViewerObject *)getParent())->removeChild(this);
 		}
 		LLUUID mesh_id;
-		if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id))
-		{
-			// This case is needed for indirectly attached mesh objects.
-			av->resetJointsOnDetach(mesh_id);
-		}
+        {
+            LLVOAvatar *av = getAvatar();
+            if (av && LLVOAvatar::getRiggedMeshID(this,mesh_id))
+            {
+                // This case is needed for indirectly attached mesh objects.
+                av->removeAttachmentOverridesForObject(mesh_id);
+            }
+        }
         if (getControlAvatar())
         {
             unlinkControlAvatar();
@@ -2950,7 +2952,7 @@ void LLViewerObject::unlinkControlAvatar()
 {
     if (getControlAvatar())
     {
-        getControlAvatar()->resetJointsOnDetach(this);
+        getControlAvatar()->removeAttachmentOverridesForObject(this);
     }
     if (isRootEdit())
     {
@@ -5187,6 +5189,7 @@ LLVOAvatar* LLViewerObject::asAvatar()
 // If this object is directly or indirectly parented by an avatar, return it.
 LLVOAvatar* LLViewerObject::getAvatarAncestor()
 {
+    LL_ERRS("AXON") << "this method has been targetted for termination. Use getAvatar()." << LL_ENDL;
 	LLViewerObject *pobj = (LLViewerObject*) getParent();
 	while (pobj)
 	{
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 4ed924f828dbadaf1849ec5480b7fdb6e5fdc40d..9a1629fbfbed1aa554dfa7ae256ab23578c5ce4d 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -1409,13 +1409,29 @@ void LLVOAvatar::renderCollisionVolumes()
         static F32 sphere_scale = 1.0f;
         static F32 center_dot_scale = 0.05f;
 
-        static LLVector3 CV_COLOR_OCCLUDED(0.0f, 0.0f, 1.0f);
-        static LLVector3 CV_COLOR_VISIBLE(0.5f, 0.5f, 1.0f);
-        static LLVector3 DOT_COLOR_OCCLUDED(1.0f, 1.0f, 1.0f);
-        static LLVector3 DOT_COLOR_VISIBLE(1.0f, 1.0f, 1.0f);
+        static LLVector3 BLUE(0.0f, 0.0f, 1.0f);
+        static LLVector3 PASTEL_BLUE(0.5f, 0.5f, 1.0f);
+        static LLVector3 RED(1.0f, 0.0f, 0.0f);
+        static LLVector3 PASTEL_RED(1.0f, 0.5f, 0.5f);
+        static LLVector3 WHITE(1.0f, 1.0f, 1.0f);
+        
 
-        render_sphere_and_line(begin_pos, end_pos, sphere_scale, CV_COLOR_OCCLUDED, CV_COLOR_VISIBLE);
-        render_sphere_and_line(begin_pos, end_pos, center_dot_scale, DOT_COLOR_OCCLUDED, DOT_COLOR_VISIBLE);
+        LLVector3 cv_color_occluded;
+        LLVector3 cv_color_visible;
+        LLVector3 dot_color_occluded(WHITE);
+        LLVector3 dot_color_visible(WHITE);
+        if (isControlAvatar())
+        {
+            cv_color_occluded = RED;
+            cv_color_visible = PASTEL_RED;
+        }
+        else
+        {
+            cv_color_occluded = BLUE;
+            cv_color_visible = PASTEL_BLUE;
+        }
+        render_sphere_and_line(begin_pos, end_pos, sphere_scale, cv_color_occluded, cv_color_visible);
+        render_sphere_and_line(begin_pos, end_pos, center_dot_scale, dot_color_occluded, dot_color_visible);
 
         gGL.popMatrix();
     }
@@ -1427,9 +1443,6 @@ void LLVOAvatar::renderCollisionVolumes()
 	
 		mNameText->lineSegmentIntersect(unused, unused, unused, TRUE);
 	}
-
-	mDebugText.clear();
-	addDebugText(ostr.str());
 }
 
 void LLVOAvatar::renderBones()
@@ -3357,8 +3370,7 @@ bool LLVOAvatar::isInMuteList()
 
 void LLVOAvatar::updateDebugText()
 {
-	// clear debug text
-	mDebugText.clear();
+    // Leave mDebugText uncleared here, in case a derived class has added some state first
 
 	if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
 	{
@@ -3482,8 +3494,7 @@ void LLVOAvatar::updateDebugText()
 	{
 		setDebugText(mDebugText);
 	}
-	mDebugText.clear();
-
+    mDebugText.clear();
 }
 
 //------------------------------------------------------------------------
@@ -5579,28 +5590,13 @@ void LLVOAvatar::rebuildAttachmentOverrides()
 //-----------------------------------------------------------------------------
 void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
 {
-    bool non_attached_case = false;
-    // FIXME AXON - will this work if vo has child objects?
-    if (vo->getControlAvatar())
-    {
-        non_attached_case = true;
-    }
-    LLVOAvatar *av;
-    if (non_attached_case)
-    {
-        av = vo->getControlAvatar();
-    }
-    else
+    if (vo->getAvatar() != this)
     {
-        av = vo->getAvatarAncestor();
-	if (!av || (av != this))
-	{
 		LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
         return;
-	}
     }
 
-    LLScopedContextString str("addAttachmentOverridesForObject " + av->getFullname());
+    LLScopedContextString str("addAttachmentOverridesForObject " + vo->getAvatar()->getFullname());
     
 	// Process all children
 	LLViewerObject::const_child_list_t& children = vo->getChildren();
@@ -5626,7 +5622,7 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo)
 	LLUUID currentId = vobj->getVolume()->getParams().getSculptID();						
 	const LLMeshSkinInfo*  pSkinData = gMeshRepo.getSkinInfo( currentId, vobj );
 
-	if ( vobj && (vobj->isAttachment()||non_attached_case) && vobj->isMesh() && pSkinData )
+	if ( vobj && vobj->isMesh() && pSkinData )
 	{
 		const int bindCnt = pSkinData->mAlternateBindMatrix.size();								
         const int jointCnt = pSkinData->mJointNames.size();
@@ -5808,15 +5804,15 @@ void LLVOAvatar::showAttachmentOverrides(bool verbose) const
 }
 
 //-----------------------------------------------------------------------------
-// resetJointsOnDetach
+// removeAttachmentOverridesForObject
 //-----------------------------------------------------------------------------
 // AXON handle NPC case
-void LLVOAvatar::resetJointsOnDetach(LLViewerObject *vo)
+void LLVOAvatar::removeAttachmentOverridesForObject(LLViewerObject *vo)
 {
-	LLVOAvatar *av = vo->getAvatarAncestor();
-	if (!av || (av != this))
+	if (vo->getAvatar() != this)
 	{
 		LL_WARNS("Avatar") << "called with invalid avatar" << LL_ENDL;
+        return;
 	}
 		
 	// Process all children
@@ -5825,22 +5821,22 @@ void LLVOAvatar::resetJointsOnDetach(LLViewerObject *vo)
 		 it != children.end(); ++it)
 	{
 		LLViewerObject *childp = *it;
-		resetJointsOnDetach(childp);
+		removeAttachmentOverridesForObject(childp);
 	}
 
 	// Process self.
 	LLUUID mesh_id;
 	if (getRiggedMeshID(vo,mesh_id))
 	{
-		resetJointsOnDetach(mesh_id);
+		removeAttachmentOverridesForObject(mesh_id);
 	}
 }
 
 //-----------------------------------------------------------------------------
-// resetJointsOnDetach
+// removeAttachmentOverridesForObject
 //-----------------------------------------------------------------------------
 // AXON handle NPC case
-void LLVOAvatar::resetJointsOnDetach(const LLUUID& mesh_id)
+void LLVOAvatar::removeAttachmentOverridesForObject(const LLUUID& mesh_id)
 {	
 	//Subsequent joints are relative to pelvis
 	avatar_joint_list_t::iterator iter = mSkeleton.begin();
@@ -6559,7 +6555,7 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
 	LLUUID mesh_id;
 	if (getRiggedMeshID(pVO, mesh_id))
 	{
-		resetJointsOnDetach(mesh_id);
+		removeAttachmentOverridesForObject(mesh_id);
 		if ( gAgentCamera.cameraCustomizeAvatar() )
 		{
 			gAgent.unpauseAnimation();
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 2b71cfbe61ecfd89bde52ca12d0b22182f31319f..406b9d8a22fb1c4eba05b75862db587f35817b02 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -202,8 +202,8 @@ class LLVOAvatar :
 	LLJoint*		        getJoint(S32 num);
 	
 	void 					addAttachmentOverridesForObject(LLViewerObject *vo);
-	void					resetJointsOnDetach(const LLUUID& mesh_id);
-	void					resetJointsOnDetach(LLViewerObject *vo);
+	void					removeAttachmentOverridesForObject(const LLUUID& mesh_id);
+	void					removeAttachmentOverridesForObject(LLViewerObject *vo);
     bool					jointIsRiggedTo(const std::string& joint_name);
     bool					jointIsRiggedTo(const std::string& joint_name, const LLViewerObject *vo);
 	void					clearAttachmentOverrides();
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 911575138b611abaea0dce27f2004201d2604d8a..94556a9f7079a78d44390ab23b9fe249d3fdaf49 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -3415,7 +3415,7 @@ void LLVOVolume::updateAnimatedObjectState(LLViewerObject *old_parent, LLViewerO
     if (old_volp && old_volp->isAnimatedObject())
     {
         // W have been removed from an animated object, need to do cleanup.
-        old_volp->getControlAvatar()->resetJointsOnDetach(this);
+        old_volp->getControlAvatar()->removeAttachmentOverridesForObject(this);
     }
     
     if (old_volp)