diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index ab209577609b8efb728efd8c8cb7f2df5d0ba592..6fffb73acdcf47b4f1558942ee003ffee24bddb9 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -377,8 +377,9 @@ namespace LLInitParam
 		class Lazy
 		{
 		public:
+			
 			Lazy()
-				: mPtr(NULL)
+			:	mPtr(NULL)
 			{}
 
 			~Lazy()
@@ -386,6 +387,11 @@ namespace LLInitParam
 				delete mPtr;
 			}
 
+			Lazy(const T& value)
+			{
+				mPtr = new T(value);
+			}
+
 			Lazy(const Lazy& other)
 			{
 				if (other.mPtr)
@@ -424,12 +430,17 @@ namespace LLInitParam
 
 			const T& get() const
 			{
-				return ensureInstance();
+				return *ensureInstance();
 			}
 
 			T& get()
 			{
-				return ensureInstance();
+				return *ensureInstance();
+			}
+
+			operator const T&() const
+			{ 
+				return get(); 
 			}
 
 		private:
@@ -520,8 +531,8 @@ namespace LLInitParam
 		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
 		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
 
-		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
-		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
 
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const BaseBlock& other)
@@ -539,6 +550,15 @@ namespace LLInitParam
 
 		ParamDescriptorPtr findParamDescriptor(const Param& param);
 
+		// take all provided params from other and apply to self
+		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
+
+		static BlockDescriptor& getBlockDescriptor()
+		{
+			static BlockDescriptor sBlockDescriptor;
+			return sBlockDescriptor;
+		}
+
 	protected:
 		void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
 
@@ -547,25 +567,11 @@ namespace LLInitParam
 		{
 			return mergeBlock(block_data, source, overwrite);
 		}
-		// take all provided params from other and apply to self
-		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
-
-		static BlockDescriptor& selfBlockDescriptor()
-		{
-			static BlockDescriptor sBlockDescriptor;
-			return sBlockDescriptor;
-		}
 
 	private:
 		const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
 	};
 
-	template<typename T>
-	struct ParamCompare<BaseBlock::Lazy<T>, false >
-	{
-		static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); }
-	};
-
 	class Param
 	{
 	public:
@@ -607,26 +613,16 @@ namespace LLInitParam
 
 	// these templates allow us to distinguish between template parameters
 	// that derive from BaseBlock and those that don't
-	template<typename T, typename Void = void>
+	template<typename T, typename BLOCK_IDENTIFIER = void>
 	struct IsBlock
 	{
 		static const bool value = false;
-		struct EmptyBase {};
-		typedef EmptyBase base_class_t;
 	};
 
 	template<typename T>
 	struct IsBlock<T, typename T::baseblock_base_class_t>
 	{
 		static const bool value = true;
-		typedef BaseBlock base_class_t;
-	};
-
-	template<typename T>
-	struct IsBlock<BaseBlock::Lazy<T>, typename T::baseblock_base_class_t >
-	{
-		static const bool value = true;
-		typedef BaseBlock base_class_t;
 	};
 
 	template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value>
@@ -817,13 +813,13 @@ namespace LLInitParam
 	public:
 		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>		self_t;
 		typedef ParamValue<T, NAME_VALUE_LOOKUP>											param_value_t;
-		typedef typename param_value_t::value_assignment_t				value_assignment_t;
-		typedef NAME_VALUE_LOOKUP															name_value_lookup_t;
+		typedef typename param_value_t::value_assignment_t									value_assignment_t;
 
 		using param_value_t::operator();
 
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
-		:	Param(block_descriptor.mCurrentBlockPtr)
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const T& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
+		:	Param(block_descriptor.mCurrentBlockPtr),
+			param_value_t(value)
 		{
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
@@ -837,8 +833,6 @@ namespace LLInitParam
 												min_count, max_count));
 				BaseBlock::addParam(block_descriptor, param_descriptor, name);
 			}
-
-			setValue(value);
 		} 
 
 		bool isProvided() const { return Param::anyProvided(); }
@@ -857,14 +851,14 @@ namespace LLInitParam
 				}
 				
 				// try to parse a known named value
-				if(name_value_lookup_t::valueNamesExist())
+				if(param_value_t::valueNamesExist())
 				{
 					// try to parse a known named value
 					std::string name;
 					if (parser.readValue(name))
 					{
 						// try to parse a per type named value
-						if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
+						if (param_value_t::getValueFromName(name, typed_param.getValue()))
 						{
 							typed_param.setValueName(name);
 							typed_param.setProvided();
@@ -917,9 +911,9 @@ namespace LLInitParam
 			// tell parser about our actual type
 			parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
 			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
-			if (name_value_lookup_t::getPossibleValues())
+			if (param_value_t::getPossibleValues())
 			{
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, param_value_t::getPossibleValues());
 			}
 		}
 
@@ -969,11 +963,10 @@ namespace LLInitParam
 		typedef ParamValue<T, NAME_VALUE_LOOKUP>				param_value_t;
 		typedef typename param_value_t::value_assignment_t		value_assignment_t;
 		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true>	self_t;
-		typedef NAME_VALUE_LOOKUP								name_value_lookup_t;
 
 		using param_value_t::operator();
 
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const T& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr),
 			param_value_t(value)
 		{
@@ -1002,14 +995,14 @@ namespace LLInitParam
 				return true;
 			}
 
-			if(name_value_lookup_t::valueNamesExist())
+			if(param_value_t::valueNamesExist())
 			{
 				// try to parse a known named value
 				std::string name;
 				if (parser.readValue(name))
 				{
 					// try to parse a per type named value
-					if (name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
+					if (param_value_t::getValueFromName(name, typed_param.getValue()))
 					{
 						typed_param.setValueName(name);
 						typed_param.setProvided();
@@ -1041,7 +1034,7 @@ namespace LLInitParam
 			}
 			else
 			{
-				typed_param.serializeBlock(parser, name_stack, static_cast<const self_t*>(diff_param));
+				typed_param.serializeBlock(parser, name_stack, &static_cast<const BaseBlock&>(*static_cast<const self_t*>(diff_param)));
 			}
 		}
 
@@ -1115,7 +1108,7 @@ namespace LLInitParam
 
 			if (src_typed_param.anyProvided())
 			{
-				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
+				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::getBlockDescriptor(), src_typed_param, overwrite))
 				{
 					dst_typed_param.clearValueName();
 					dst_typed_param.setProvided(true);
@@ -1138,9 +1131,8 @@ namespace LLInitParam
 		typedef const container_t&											value_assignment_t;
 
 		typedef typename param_value_t::value_t								value_t;
-		typedef NAME_VALUE_LOOKUP											name_value_lookup_t;
 		
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const container_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
 			std::copy(value.begin(), value.end(), std::back_inserter(mValues));
@@ -1176,14 +1168,14 @@ namespace LLInitParam
 				}
 				
 				// try to parse a known named value
-				if(name_value_lookup_t::valueNamesExist())
+				if(param_value_t::valueNamesExist())
 				{
 					// try to parse a known named value
 					std::string name;
 					if (parser.readValue(name))
 					{
 						// try to parse a per type named value
-						if (name_value_lookup_t::getValueFromName(name, value))
+						if (param_value_t::getValueFromName(name, value))
 						{
 							typed_param.add(value);
 							typed_param.mValues.back().setValueName(name);
@@ -1234,9 +1226,9 @@ namespace LLInitParam
 		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
 		{
 			parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
-			if (name_value_lookup_t::getPossibleValues())
+			if (param_value_t::getPossibleValues())
 			{
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, param_value_t::getPossibleValues());
 			}
 		}
 
@@ -1261,12 +1253,12 @@ namespace LLInitParam
 			setProvided();
 		}
 
-		void add(const typename name_value_lookup_t::name_t& name)
+		void add(const typename param_value_t::name_t& name)
 		{
 			value_t value;
 
 			// try to parse a per type named value
-			if (name_value_lookup_t::getValueFromName(name, value))
+			if (param_value_t::getValueFromName(name, value))
 			{
 				add(value);
 				mValues.back().setValueName(name);
@@ -1330,9 +1322,8 @@ namespace LLInitParam
 		typedef typename std::vector<param_value_t>						container_t;
 		typedef const container_t&										value_assignment_t;
 		typedef typename param_value_t::value_t							value_t;
-		typedef NAME_VALUE_LOOKUP										name_value_lookup_t;
 
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const container_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
 			std::copy(value.begin(), value.end(), back_inserter(mValues));
@@ -1372,14 +1363,14 @@ namespace LLInitParam
 				typed_param.setProvided();
 				return true;
 			}
-			else if(name_value_lookup_t::valueNamesExist())
+			else if(param_value_t::valueNamesExist())
 			{
 				// try to parse a known named value
 				std::string name;
 				if (parser.readValue(name))
 				{
 					// try to parse a per type named value
-					if (name_value_lookup_t::getValueFromName(name, value.getValue()))
+					if (param_value_t::getValueFromName(name, value.getValue()))
 					{
 						typed_param.mValues.back().setValueName(name);
 						typed_param.setProvided();
@@ -1447,12 +1438,12 @@ namespace LLInitParam
 			setProvided();
 		}
 
-		void add(const typename name_value_lookup_t::name_t& name)
+		void add(const typename param_value_t::name_t& name)
 		{
 			value_t value;
 
 			// try to parse a per type named value
-			if (name_value_lookup_t::getValueFromName(name, value))
+			if (param_value_t::getValueFromName(name, value))
 			{
 				add(value);
 				mValues.back().setValueName(name);
@@ -1526,13 +1517,13 @@ namespace LLInitParam
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
 		}
 
 		// take all provided params that are not already provided, and apply to self
 		bool fillFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
 		}
 
 		bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
@@ -1550,7 +1541,7 @@ namespace LLInitParam
 		bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)
 		{
 			mCurChoice = other.mCurChoice;
-			return base_block_t::mergeBlock(selfBlockDescriptor(), other, overwrite);
+			return base_block_t::mergeBlock(getBlockDescriptor(), other, overwrite);
 		}
 
 		// clear out old choice when param has changed
@@ -1571,14 +1562,14 @@ namespace LLInitParam
 			base_block_t::paramChanged(changed_param, user_provided);
 		}
 
-		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
-		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
 
 	protected:
 		ChoiceBlock()
 		:	mCurChoice(0)
 		{
-			BaseBlock::init(selfBlockDescriptor(), base_block_t::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+			BaseBlock::init(getBlockDescriptor(), base_block_t::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
 		}
 
 		// Alternatives are mutually exclusive wrt other Alternatives in the same block.  
@@ -1596,13 +1587,13 @@ namespace LLInitParam
 
 			using super_t::operator =;
 
-			explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>())
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
+			explicit Alternative(const char* name = "", const T& val = defaultValue<T>())
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1),
 				mOriginalValue(val)
 			{
 				// assign initial choice to first declared option
-				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr);
-				if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
+				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr);
+				if (LL_UNLIKELY(DERIVED_BLOCK::getBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
 				{
 					if(blockp->mCurChoice == 0)
 					{
@@ -1654,8 +1645,8 @@ namespace LLInitParam
 			T			mOriginalValue;
 		};
 
-	protected:
-		static BlockDescriptor& selfBlockDescriptor()
+	public:
+		static BlockDescriptor& getBlockDescriptor()
 		{
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
@@ -1683,23 +1674,23 @@ namespace LLInitParam
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
 		}
 
 		// take all provided params that are not already provided, and apply to self
 		bool fillFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
 		}
 
-		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
-		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
 
 	protected:
 		Block()
 		{
 			//#pragma message("Parsing LLInitParam::Block")
-			BaseBlock::init(selfBlockDescriptor(), BASE_BLOCK::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+			BaseBlock::init(getBlockDescriptor(), BASE_BLOCK::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
 		}
 
 		//
@@ -1715,8 +1706,8 @@ namespace LLInitParam
 			using super_t::operator();
 			using super_t::operator =;
 			
-			explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>())
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)
+			explicit Optional(const char* name = "", const T& val = defaultValue<T>())
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1)
 			{
 				//#pragma message("Parsing LLInitParam::Block::Optional")
 			}
@@ -1746,8 +1737,8 @@ namespace LLInitParam
 			using super_t::operator =;
 
 			// mandatory parameters require a name to be parseable
-			explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>())
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)
+			explicit Mandatory(const char* name = "", const T& val = defaultValue<T>())
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, &validate, 1, 1)
 			{}
 
 			Mandatory& operator =(value_assignment_t val)
@@ -1782,7 +1773,7 @@ namespace LLInitParam
 			typedef typename super_t::const_iterator								const_iterator;
 
 			explicit Multiple(const char* name = "")
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
 			{}
 
 			Multiple& operator =(value_assignment_t val)
@@ -1808,9 +1799,9 @@ namespace LLInitParam
 		{
 		public:
 			explicit Deprecated(const char* name)
-			:	Param(DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
+			:	Param(DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr)
 			{
-				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
+				BlockDescriptor& block_descriptor = DERIVED_BLOCK::getBlockDescriptor();
 				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 				{
 					ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
@@ -1841,13 +1832,14 @@ namespace LLInitParam
 		// different semantics for documentation purposes, but functionally identical
 		typedef Deprecated Ignored;
 
-	protected:
-		static BlockDescriptor& selfBlockDescriptor()
+	public:
+		static BlockDescriptor& getBlockDescriptor()
 		{
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
 		}
 
+	protected:
 		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block>
 		void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param, 
 			typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value)
@@ -1887,7 +1879,7 @@ namespace LLInitParam
 			{
 				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
 				// merge individual parameters into destination
-				return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite);
+				return super_t::mergeBlock(super_t::getBlockDescriptor(), other, overwrite);
 			}
 			return false;
 		}
@@ -1955,14 +1947,36 @@ namespace LLInitParam
 		mutable bool 	mValidated; // lazy validation flag
 	};
 
-	template<typename T, bool IS_BLOCK>
+	template<typename T, typename BLOCK_IDENTIFIER>
+	struct IsBlock<ParamValue<BaseBlock::Lazy<T>, TypeValues<BaseBlock::Lazy<T> > > , BLOCK_IDENTIFIER>
+	{
+		static const bool value = true;//IsBlock<T>::value;
+	};
+
+	template<typename T>
+	struct ParamCompare<BaseBlock::Lazy<T>, false>
+	{
+		static bool equals(const T&a, const T &b)
+		{
+			return a == b;
+		}
+
+		static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b)
+		{
+			if (a.empty() || b.empty()) return false;
+			return a.get() == b.get();
+		}
+	};
+
+
+	template<typename T, bool VALUE_IS_BLOCK>
 	class ParamValue <BaseBlock::Lazy<T>,
-					TypeValues<T>,
-					IS_BLOCK>
-	:	public IsBlock<T>::base_class_t
+					TypeValues<BaseBlock::Lazy<T> >,
+					VALUE_IS_BLOCK>
+	:	public TypeValues<T>
 	{
 	public:
-		typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<T>, false> self_t;
+		typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<BaseBlock::Lazy<T> >, false> self_t;
 		typedef const T& value_assignment_t;
 		typedef T value_t;
 	
@@ -1971,11 +1985,16 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		ParamValue(value_assignment_t other)
+		ParamValue(const BaseBlock::Lazy<T>& other)
 		:	mValue(other),
 			mValidated(false)
 		{}
 
+		ParamValue(const T& value)
+		:	mValue(value),
+			mValidated(false)
+		{}
+
 		void setValue(value_assignment_t val)
 		{
 			mValue.set(val);
@@ -1991,6 +2010,11 @@ namespace LLInitParam
 			return mValue.get();
 		}
 
+		operator const BaseBlock&() const
+		{
+			return mValue.get();
+		}
+
 		operator value_assignment_t() const
 		{
 			return mValue.get();
@@ -2020,7 +2044,22 @@ namespace LLInitParam
 			return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
 		}
 
-	protected:
+		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+		{
+			return mValue.get().mergeBlock(block_data, source.getValue(),  overwrite);
+		}
+
+		bool validateBlock(bool emit_errors = true) const
+		{
+			return mValue.get().validateBlock(emit_errors);
+		}
+
+		static BlockDescriptor& getBlockDescriptor()
+		{
+			return T::getBlockDescriptor();
+		}
+
+
 		mutable bool 	mValidated; // lazy validation flag
 
 	private:
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index afc76024d1e0ef0f8688b8de638cbe52c29843e2..3c89fa3aaf44fae552981dd83b88eee2470b7eeb 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -42,6 +42,7 @@
 #include <boost/spirit/include/classic_core.hpp>
 
 #include "lluicolor.h"
+#include "v3math.h"
 
 using namespace BOOST_SPIRIT_CLASSIC_NS;
 
@@ -670,6 +671,7 @@ LLXUIParser::LLXUIParser()
 		registerParserFuncs<S32>(readS32Value, writeS32Value);
 		registerParserFuncs<F32>(readF32Value, writeF32Value);
 		registerParserFuncs<F64>(readF64Value, writeF64Value);
+		registerParserFuncs<LLVector3>(readVector3Value, writeVector3Value);
 		registerParserFuncs<LLColor4>(readColor4Value, writeColor4Value);
 		registerParserFuncs<LLUIColor>(readUIColorValue, writeUIColorValue);
 		registerParserFuncs<LLUUID>(readUUIDValue, writeUUIDValue);
@@ -1144,6 +1146,31 @@ bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, name_stack_
 	return false;
 }
 
+bool LLXUIParser::readVector3Value(Parser& parser, void* val_ptr)
+{
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	LLVector3* vecp = (LLVector3*)val_ptr;
+	if(self.mCurReadNode->getFloatValue(3, vecp->mV) >= 3)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+bool LLXUIParser::writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	LLXMLNodePtr node = self.getNode(stack);
+	if (node.notNull())
+	{
+		LLVector3 vector = *((LLVector3*)val_ptr);
+		node->setFloatValue(3, vector.mV);
+		return true;
+	}
+	return false;
+}
+
 bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h
index d7cd25696723dd11a104c4435dd9067a5d84bbab..e48663e5cc94fc3d4963f0637bca4b06a2f21519 100644
--- a/indra/llxuixml/llxuiparser.h
+++ b/indra/llxuixml/llxuiparser.h
@@ -127,6 +127,7 @@ LOG_CLASS(LLXUIParser);
 	static bool readS32Value(Parser& parser, void* val_ptr);
 	static bool readF32Value(Parser& parser, void* val_ptr);
 	static bool readF64Value(Parser& parser, void* val_ptr);
+	static bool readVector3Value(Parser& parser, void* val_ptr);
 	static bool readColor4Value(Parser& parser, void* val_ptr);
 	static bool readUIColorValue(Parser& parser, void* val_ptr);
 	static bool readUUIDValue(Parser& parser, void* val_ptr);
@@ -144,6 +145,7 @@ LOG_CLASS(LLXUIParser);
 	static bool writeS32Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeF32Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeF64Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t&);
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 482294c8a614bf2aec9ba73251aefadd607cc684..cf55954d7d87aebad2b596e592cf9d2eac58eaec 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -187,45 +187,42 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
 			+ (y_pixel_vec * screen_offset.mV[VY]);
 
 
-	//if (mUseBubble)
-	{
-		LLVector3 bg_pos = render_position
-			+ (F32)mOffsetY * y_pixel_vec
-			- (width_vec / 2.f)
-			- (height_vec);
-		//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+	LLVector3 bg_pos = render_position
+		+ (F32)mOffsetY * y_pixel_vec
+		- (width_vec / 2.f)
+		- (height_vec);
+	//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
 
-		LLVector3 v[] = 
-		{
-			bg_pos,
-			bg_pos + width_vec,
-			bg_pos + width_vec + height_vec,
-			bg_pos + height_vec,
-		};
+	LLVector3 v[] = 
+	{
+		bg_pos,
+		bg_pos + width_vec,
+		bg_pos + width_vec + height_vec,
+		bg_pos + height_vec,
+	};
 
-		if (debug_render)
-		{
-			gGL.begin(LLRender::LINE_STRIP);
-			gGL.vertex3fv(v[0].mV);
-			gGL.vertex3fv(v[1].mV);
-			gGL.vertex3fv(v[2].mV);
-			gGL.vertex3fv(v[3].mV);
-			gGL.vertex3fv(v[0].mV);
-			gGL.vertex3fv(v[2].mV);
-			gGL.end();
-		}
+	if (debug_render)
+	{
+		gGL.begin(LLRender::LINE_STRIP);
+		gGL.vertex3fv(v[0].mV);
+		gGL.vertex3fv(v[1].mV);
+		gGL.vertex3fv(v[2].mV);
+		gGL.vertex3fv(v[3].mV);
+		gGL.vertex3fv(v[0].mV);
+		gGL.vertex3fv(v[2].mV);
+		gGL.end();
+	}
 
-		LLVector3 dir = end-start;
-		F32 a, b, t;
+	LLVector3 dir = end-start;
+	F32 a, b, t;
 
-		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
-			LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
+	if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
+		LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
+	{
+		if (t <= 1.f)
 		{
-			if (t <= 1.f)
-			{
-				intersection = start + dir*t;
-				return TRUE;
-			}
+			intersection = start + dir*t;
+			return TRUE;
 		}
 	}
 
@@ -241,12 +238,6 @@ void LLHUDNameTag::render()
 	}
 }
 
-void LLHUDNameTag::renderForSelect()
-{
-	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-	renderText(TRUE);
-}
-
 void LLHUDNameTag::renderText(BOOL for_select)
 {
 	if (!mVisible || mHidden)
@@ -336,142 +327,53 @@ void LLHUDNameTag::renderText(BOOL for_select)
 	LLCoordGL screen_pos;
 	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);
 
-	LLVector2 screen_offset;
-//	if (!mUseBubble)
-//	{
-//		screen_offset = mPositionOffset;
-//	}
-//	else
-//	{
-		screen_offset = updateScreenPos(mPositionOffset);
-//	}
+	LLVector2 screen_offset = updateScreenPos(mPositionOffset);
 
 	LLVector3 render_position = mPositionAgent  
 			+ (x_pixel_vec * screen_offset.mV[VX])
 			+ (y_pixel_vec * screen_offset.mV[VY]);
 
-//	if (mUseBubble)
+	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+	LLUI::pushMatrix();
 	{
-		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-		LLUI::pushMatrix();
-		{
-			LLVector3 bg_pos = render_position
-				+ (F32)mOffsetY * y_pixel_vec
-				- (width_vec / 2.f)
-				- (height_vec);
-			LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+		LLVector3 bg_pos = render_position
+			+ (F32)mOffsetY * y_pixel_vec
+			- (width_vec / 2.f)
+			- (height_vec);
+		LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
 
-			if (for_select)
-			{
-				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-				S32 name = mSourceObject->mGLName;
-				LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
-				gGL.color4ubv(coloru.mV);
-				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
-				LLUI::popMatrix();
-				return;
-			}
-			else
-			{
-				gGL.getTexUnit(0)->bind(imagep->getImage());
+		if (for_select)
+		{
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+			S32 name = mSourceObject->mGLName;
+			LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
+			gGL.color4ubv(coloru.mV);
+			gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
+			LLUI::popMatrix();
+			return;
+		}
+		else
+		{
+			gGL.getTexUnit(0)->bind(imagep->getImage());
 				
-				gGL.color4fv(bg_color.mV);
-				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
+			gGL.color4fv(bg_color.mV);
+			gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
 		
-				if ( mLabelSegments.size())
-				{
-					LLUI::pushMatrix();
-					{
-						gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
-						LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
-						LLVector3 label_offset = height_vec - label_height;
-						LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
-						gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
-					}
-					LLUI::popMatrix();
-				}
-			}
-
-			BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f;
-			BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f);
-
-			// draw line segments pointing to parent object
-			if (!mOffscreen && (outside_width || outside_height))
+			if ( mLabelSegments.size())
 			{
 				LLUI::pushMatrix();
 				{
-					gGL.color4fv(bg_color.mV);
-					LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec);
-					target_pos += (width_vec / 2.f);
-					target_pos += mVertAlignment == ALIGN_VERT_CENTER ? (height_vec * 0.5f) : LLVector3::zero;
-					target_pos -= 3.f * x_pixel_vec;
-					target_pos -= 6.f * y_pixel_vec;
-					LLUI::translate(target_pos.mV[VX], target_pos.mV[VY], target_pos.mV[VZ]);
-					gl_segmented_rect_3d_tex(border_scale_vec, 3.f * x_pixel_vec, 3.f * y_pixel_vec, 6.f * x_pixel_vec, 6.f * y_pixel_vec);	
+					gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
+					LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
+					LLVector3 label_offset = height_vec - label_height;
+					LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
+					gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
 				}
 				LLUI::popMatrix();
-
-				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-				LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE);
-				
-				LLVector3 box_center_offset;
-				box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f);
-				LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]);
-				gGL.color4fv(bg_color.mV);
-				LLUI::setLineWidth(2.0);
-				gGL.begin(LLRender::LINES);
-				{
-					if (outside_width)
-					{
-						LLVector3 vert;
-						// draw line in x then y
-						if (mPositionOffset.mV[VX] < 0.f)
-						{
-							// start at right edge
-							vert = width_vec * 0.5f;
-							gGL.vertex3fv(vert.mV);
-						}
-						else
-						{
-							// start at left edge
-							vert = width_vec * -0.5f;
-							gGL.vertex3fv(vert.mV);
-						}
-						vert = -mPositionOffset.mV[VX] * x_pixel_vec;
-						gGL.vertex3fv(vert.mV);
-						gGL.vertex3fv(vert.mV);
-						vert -= mPositionOffset.mV[VY] * y_pixel_vec;
-						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
-						gGL.vertex3fv(vert.mV);
-					}
-					else
-					{
-						LLVector3 vert;
-						// draw line in y then x
-						if (mPositionOffset.mV[VY] < 0.f)
-						{
-							// start at top edge
-							vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
-							gGL.vertex3fv(vert.mV);
-						}
-						else
-						{
-							// start at bottom edge
-							vert = (height_vec * -0.5f)  - (mPositionOffset.mV[VX] * x_pixel_vec);
-							gGL.vertex3fv(vert.mV);
-						}
-						vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec;
-						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
-						gGL.vertex3fv(vert.mV);
-					}
-				}
-				gGL.end();
-				LLUI::setLineWidth(1.0);
-
 			}
 		}
-		LLUI::popMatrix();
 	}
+	LLUI::popMatrix();
 
 	F32 y_offset = (F32)mOffsetY;
 		
@@ -874,29 +776,26 @@ void LLHUDNameTag::updateAll()
 	for (r_it = sVisibleTextObjects.rbegin(); r_it != sVisibleTextObjects.rend(); ++r_it)
 	{
 		LLHUDNameTag* textp = (*r_it);
-//		if (textp->mUseBubble)
-//		{
-			if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
-			{
-				textp->setLOD(3);
-			}
-			else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
-			{
-				textp->setLOD(2);
-			}
-			else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
-			{
-				textp->setLOD(1);
-			}
-			else
-			{
-				textp->setLOD(0);
-			}
-			textp->updateSize();
-			// find on-screen position and initialize collision rectangle
-			textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
-			current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
-//		}
+		if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
+		{
+			textp->setLOD(3);
+		}
+		else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
+		{
+			textp->setLOD(2);
+		}
+		else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
+		{
+			textp->setLOD(1);
+		}
+		else
+		{
+			textp->setLOD(0);
+		}
+		textp->updateSize();
+		// find on-screen position and initialize collision rectangle
+		textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
+		current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
 	}
 
 	LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat();
@@ -914,20 +813,12 @@ void LLHUDNameTag::updateAll()
 		{
 			LLHUDNameTag* src_textp = (*src_it);
 
-//			if (!src_textp->mUseBubble)
-//			{
-//				continue;
-//			}
 			VisibleTextObjectIterator dst_it = src_it;
 			++dst_it;
 			for (; dst_it != sVisibleTextObjects.end(); ++dst_it)
 			{
 				LLHUDNameTag* dst_textp = (*dst_it);
 
-//				if (!dst_textp->mUseBubble)
-//				{
-//					continue;
-//				}
 				if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect))
 				{
 					LLRectf intersect_rect = src_textp->mSoftScreenRect;
@@ -976,10 +867,6 @@ void LLHUDNameTag::updateAll()
 	VisibleTextObjectIterator this_object_it;
 	for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it)
 	{
-//		if (!(*this_object_it)->mUseBubble)
-//		{
-//			continue;
-//		}
 		(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC));
 	}
 }
@@ -1037,10 +924,6 @@ void LLHUDNameTag::addPickable(std::set<LLViewerObject*> &pick_list)
 	VisibleTextObjectIterator text_it;
 	for (text_it = sVisibleTextObjects.begin(); text_it != sVisibleTextObjects.end(); ++text_it)
 	{
-//		if (!(*text_it)->mUseBubble)
-//		{
-//			continue;
-//		}
 		pick_list.insert((*text_it)->mSourceObject);
 	}
 }
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 3325c22def35e12a0f7cf2efa6deff48036174ff..72647d5b262dbd7c952f74f63909932f23b7d644 100644
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -118,7 +118,6 @@ class LLHUDNameTag : public LLHUDObject
 	/*virtual*/ void markDead();
 	friend class LLHUDObject;
 	/*virtual*/ F32 getDistance() const { return mLastDistance; }
-	//void setUseBubble(BOOL use_bubble) { mUseBubble = use_bubble; }
 	S32  getLOD() { return mLOD; }
 	BOOL getVisible() { return mVisible; }
 	BOOL getHidden() const { return mHidden; }
@@ -136,7 +135,6 @@ class LLHUDNameTag : public LLHUDObject
 	LLHUDNameTag(const U8 type);
 
 	/*virtual*/ void render();
-	/*virtual*/ void renderForSelect();
 	void renderText(BOOL for_select);
 	static void updateAll();
 	void setLOD(S32 lod);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 5d196a465f6bc3a9f4f5c2284ce95aa9752305f0..1333862855f06ab59ad8cffe3f64cda7fd38b5d2 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -2774,7 +2774,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
 
 void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color)
 {
-	gGL.diffuseColor4fv(color.mV);
+	gGL.color4fv(color.mV);
 	gGL.begin(LLRender::LINES);
 	{
 		gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV);
@@ -3904,7 +3904,7 @@ void renderAgentTarget(LLVOAvatar* avatar)
 	if (avatar->isSelf())
 	{
 		renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
-		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
+		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f));
 		renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
 		renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));
 	}
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 99540ccce918dc8d0e6f24280ce25bc9880e08d3..ae32683c990c9c92aba3f6fd4058b83ef0eac32e 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3190,15 +3190,6 @@ bool enable_freeze_eject(const LLSD& avatar_id)
 	return new_value;
 }
 
-
-void login_done(S32 which, void *user)
-{
-	llinfos << "Login done " << which << llendl;
-
-	LLPanelLogin::closePanel();
-}
-
-
 bool callback_leave_group(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index bc7f5a9744a326d68fa051757296eedb1f4e1d32..f00363bfa68f08f843941fc711b738e6c9bd7b38 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -62,6 +62,7 @@
 #include "llhudmanager.h"
 #include "llhudnametag.h"
 #include "llhudtext.h"				// for mText/mDebugText
+#include "llinitparam.h"
 #include "llkeyframefallmotion.h"
 #include "llkeyframestandmotion.h"
 #include "llkeyframewalkmotion.h"
@@ -193,6 +194,9 @@ const S32 MAX_BUBBLE_CHAT_LENGTH = DB_CHAT_MSG_STR_LEN;
 const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12;
 const F32 CHAT_FADE_TIME = 8.0;
 const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f;
+const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f;
+const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f;
+const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.15f;
 
 const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
 
@@ -224,55 +228,62 @@ struct LLTextureMaskData
  **/
 
 //------------------------------------------------------------------------
-// LLVOBoneInfo
+// LLVOAvatarBoneInfo
 // Trans/Scale/Rot etc. info about each avatar bone.  Used by LLVOAvatarSkeleton.
 //------------------------------------------------------------------------
-class LLVOAvatarBoneInfo
+struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarCollisionVolumeInfo>
 {
-	friend class LLVOAvatar;
-	friend class LLVOAvatarSkeletonInfo;
-public:
-	LLVOAvatarBoneInfo() : mIsJoint(FALSE) {}
-	~LLVOAvatarBoneInfo()
-	{
-		std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
-	}
-	BOOL parseXml(LLXmlTreeNode* node);
+	LLVOAvatarCollisionVolumeInfo() 
+	:	name("name"),
+		pos("pos"),
+		rot("rot"),
+		scale("scale")
+	{}
+
+	Mandatory<std::string>	name;
+	Mandatory<LLVector3>	pos,
+							rot,
+							scale;
+};
+
+struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>
+{
+	Alternative<Lazy<struct LLVOAvatarBoneInfo> >	bone;
+	Alternative<LLVOAvatarCollisionVolumeInfo>		collision_volume;
+
+	LLVOAvatarChildJoint()
+	:	bone("bone"),
+		collision_volume("collision_volume")
+	{}
+};
+
+struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo>
+{
+	LLVOAvatarBoneInfo() 
+	:	pivot("pivot")
+	{}
 	
-private:
-	std::string mName;
-	BOOL mIsJoint;
-	LLVector3 mPos;
-	LLVector3 mRot;
-	LLVector3 mScale;
-	LLVector3 mPivot;
-	typedef std::vector<LLVOAvatarBoneInfo*> child_list_t;
-	child_list_t mChildList;
+	Mandatory<LLVector3>					pivot;
+	Multiple<LLVOAvatarChildJoint>			children;
 };
 
 //------------------------------------------------------------------------
 // LLVOAvatarSkeletonInfo
 // Overall avatar skeleton
 //------------------------------------------------------------------------
-class LLVOAvatarSkeletonInfo
+struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo>
 {
-	friend class LLVOAvatar;
-public:
-	LLVOAvatarSkeletonInfo() :
-		mNumBones(0), mNumCollisionVolumes(0) {}
-	~LLVOAvatarSkeletonInfo()
-	{
-		std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer());
-	}
-	BOOL parseXml(LLXmlTreeNode* node);
-	S32 getNumBones() const { return mNumBones; }
-	S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; }
+	LLVOAvatarSkeletonInfo()
+	:	skeleton_root(""),
+		num_bones("num_bones"),
+		num_collision_volumes("num_collision_volumes"),
+		version("version")
+	{}
 	
-private:
-	S32 mNumBones;
-	S32 mNumCollisionVolumes;
-	typedef std::vector<LLVOAvatarBoneInfo*> bone_info_list_t;
-	bone_info_list_t mBoneInfoList;
+	Mandatory<std::string>			version;
+	Mandatory<S32>					num_bones,
+									num_collision_volumes;
+	Mandatory<LLVOAvatarChildJoint>	skeleton_root;
 };
 
 //-----------------------------------------------------------------------------
@@ -597,7 +608,7 @@ class LLPelvisFixMotion :
 // Static Data
 //-----------------------------------------------------------------------------
 LLXmlTree LLVOAvatar::sXMLTree;
-LLXmlTree LLVOAvatar::sSkeletonXMLTree;
+LLXMLNodePtr LLVOAvatar::sSkeletonXMLTree;
 LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL;
 LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL;
 LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL;
@@ -1123,18 +1134,6 @@ void LLVOAvatar::initClass()
 		llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;
 	}
 
-	// Process XML data
-
-	// avatar_skeleton.xml
-	if (sAvatarSkeletonInfo)
-	{ //this can happen if a login attempt failed
-		delete sAvatarSkeletonInfo;
-	}
-	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo;
-	if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
-	{
-		llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl;
-	}
 	// parse avatar_lad.xml
 	if (sAvatarXmlInfo)
 	{ //this can happen if a login attempt failed
@@ -1183,7 +1182,7 @@ void LLVOAvatar::initClass()
 void LLVOAvatar::cleanupClass()
 {
 	deleteAndClear(sAvatarXmlInfo);
-	sSkeletonXMLTree.cleanup();
+	sSkeletonXMLTree = NULL;
 	sXMLTree.cleanup();
 }
 
@@ -1655,33 +1654,39 @@ BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)
 	//-------------------------------------------------------------------------
 	// parse the file
 	//-------------------------------------------------------------------------
-	BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
+	
+	LLXMLNodePtr skeleton_xml;
+	BOOL parsesuccess = LLXMLNode::parseFile(filename, skeleton_xml, NULL);
 
-	if (!parsesuccess)
+	if (!parsesuccess || skeleton_xml.isNull())
 	{
 		llerrs << "Can't parse skeleton file: " << filename << llendl;
 		return FALSE;
 	}
 
-	// now sanity check xml file
-	LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
-	if (!root) 
+	// Process XML data
+	if (sAvatarSkeletonInfo)
+	{ //this can happen if a login attempt failed
+		delete sAvatarSkeletonInfo;
+	}
+	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo;
+
+	LLXUIParser parser;
+	parser.readXUI(skeleton_xml, *sAvatarSkeletonInfo, filename);
+	if (!sAvatarSkeletonInfo->validateBlock())
 	{
-		llerrs << "No root node found in avatar skeleton file: " << filename << llendl;
-		return FALSE;
+		llerrs << "Error parsing skeleton XML file: " << filename << llendl;
 	}
 
-	if( !root->hasName( "linden_skeleton" ) )
+	if( !skeleton_xml->hasName( "linden_skeleton" ) )
 	{
 		llerrs << "Invalid avatar skeleton file header: " << filename << llendl;
 		return FALSE;
 	}
 
-	std::string version;
-	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
-	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
+	if (sAvatarSkeletonInfo->version() != "1.0")
 	{
-		llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl;
+		llerrs << "Invalid avatar skeleton file version: " << sAvatarSkeletonInfo->version() << " in file: " << filename << llendl;
 		return FALSE;
 	}
 
@@ -1690,14 +1695,13 @@ BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)
 
 //-----------------------------------------------------------------------------
 // setupBone()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num)
+//-----------------------------------------------------------
+BOOL LLVOAvatar::setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num)
 {
 	LLMemType mt(LLMemType::MTYPE_AVATAR);
 	
 	LLViewerJoint* joint = NULL;
-
-	if (info->mIsJoint)
+	if (info.bone.isChosen())
 	{
 		joint = (LLViewerJoint*)getCharacterJoint(joint_num);
 		if (!joint)
@@ -1705,7 +1709,23 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
 			llwarns << "Too many bones" << llendl;
 			return FALSE;
 		}
-		joint->setName( info->mName );
+		joint->setName( info.bone().name );
+		joint->setPosition(info.bone().pos);
+		joint->setRotation(mayaQ(info.bone().rot().mV[VX], info.bone().rot().mV[VY], info.bone().rot().mV[VZ], LLQuaternion::XYZ));
+		joint->setScale(info.bone().scale);
+		joint->setSkinOffset( info.bone().pivot );
+		joint_num++;
+
+		for (LLInitParam::ParamIterator<LLVOAvatarChildJoint>::const_iterator child_it = info.bone().children.begin(),
+				end_it = info.bone().children.end();
+			child_it != end_it;
+			++child_it)
+		{
+			if (!setupBone(*child_it, joint, volume_num, joint_num))
+			{
+				return FALSE;
+			}
+		}
 	}
 	else // collision volume
 	{
@@ -1715,7 +1735,11 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
 			return FALSE;
 		}
 		joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]);
-		joint->setName( info->mName );
+		joint->setName( info.collision_volume.name);
+		joint->setPosition(info.collision_volume.pos);
+		joint->setRotation(mayaQ(info.collision_volume.rot().mV[VX], info.collision_volume.rot().mV[VY], info.collision_volume.rot().mV[VZ], LLQuaternion::XYZ));
+		joint->setScale(info.collision_volume.scale);
+		volume_num++;
 	}
 
 	// add to parent
@@ -1724,34 +1748,8 @@ BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent
 		parent->addChild( joint );
 	}
 
-	joint->setPosition(info->mPos);
-	joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
-							 info->mRot.mV[VZ], LLQuaternion::XYZ));
-	joint->setScale(info->mScale);
-
 	joint->setDefaultFromCurrentXform();
 	
-	if (info->mIsJoint)
-	{
-		joint->setSkinOffset( info->mPivot );
-		joint_num++;
-	}
-	else // collision volume
-	{
-		volume_num++;
-	}
-
-	// setup children
-	LLVOAvatarBoneInfo::child_list_t::const_iterator iter;
-	for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter)
-	{
-		LLVOAvatarBoneInfo *child_info = *iter;
-		if (!setupBone(child_info, joint, volume_num, joint_num))
-		{
-			return FALSE;
-		}
-	}
-
 	return TRUE;
 }
 
@@ -1765,35 +1763,31 @@ BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)
 	//-------------------------------------------------------------------------
 	// allocate joints
 	//-------------------------------------------------------------------------
-	if (!allocateCharacterJoints(info->mNumBones))
+	if (!allocateCharacterJoints(info->num_bones))
 	{
-		llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl;
+		llerrs << "Can't allocate " << info->num_bones() << " joints" << llendl;
 		return FALSE;
 	}
 	
 	//-------------------------------------------------------------------------
 	// allocate volumes
 	//-------------------------------------------------------------------------
-	if (info->mNumCollisionVolumes)
+	if (info->num_collision_volumes)
 	{
-		if (!allocateCollisionVolumes(info->mNumCollisionVolumes))
+		if (!allocateCollisionVolumes(info->num_collision_volumes))
 		{
-			llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl;
+			llerrs << "Can't allocate " << info->num_collision_volumes() << " collision volumes" << llendl;
 			return FALSE;
 		}
 	}
 
 	S32 current_joint_num = 0;
 	S32 current_volume_num = 0;
-	LLVOAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
-	for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter)
+
+	if (!setupBone(info->skeleton_root, NULL, current_volume_num, current_joint_num))
 	{
-		LLVOAvatarBoneInfo *info = *iter;
-		if (!setupBone(info, NULL, current_volume_num, current_joint_num))
-		{
-			llerrs << "Error parsing bone in skeleton file" << llendl;
-			return FALSE;
-		}
+		llerrs << "Error parsing bone in skeleton file" << llendl;
+		return FALSE;
 	}
 
 	return TRUE;
@@ -2922,43 +2916,43 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 		return;
 	}
 
-		BOOL new_name = FALSE;
-		if (visible_chat != mVisibleChat)
-		{
-			mVisibleChat = visible_chat;
-			new_name = TRUE;
-		}
+	BOOL new_name = FALSE;
+	if (visible_chat != mVisibleChat)
+	{
+		mVisibleChat = visible_chat;
+		new_name = TRUE;
+	}
 		
-		if (sRenderGroupTitles != mRenderGroupTitles)
-		{
-			mRenderGroupTitles = sRenderGroupTitles;
-			new_name = TRUE;
-		}
+	if (sRenderGroupTitles != mRenderGroupTitles)
+	{
+		mRenderGroupTitles = sRenderGroupTitles;
+		new_name = TRUE;
+	}
 
-		// First Calculate Alpha
-		// If alpha > 0, create mNameText if necessary, otherwise delete it
-			F32 alpha = 0.f;
-			if (mAppAngle > 5.f)
+	// First Calculate Alpha
+	// If alpha > 0, create mNameText if necessary, otherwise delete it
+		F32 alpha = 0.f;
+		if (mAppAngle > 5.f)
+		{
+			const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
+			if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
 			{
-				const F32 START_FADE_TIME = NAME_SHOW_TIME - FADE_DURATION;
-				if (!visible_chat && sRenderName == RENDER_NAME_FADE && time_visible > START_FADE_TIME)
-				{
-					alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
-				}
-				else
-				{
-					// ...not fading, full alpha
-					alpha = 1.f;
-				}
+				alpha = 1.f - (time_visible - START_FADE_TIME) / FADE_DURATION;
 			}
-			else if (mAppAngle > 2.f)
+			else
 			{
-				// far away is faded out also
-				alpha = (mAppAngle-2.f)/3.f;
+				// ...not fading, full alpha
+				alpha = 1.f;
 			}
+		}
+		else if (mAppAngle > 2.f)
+		{
+			// far away is faded out also
+			alpha = (mAppAngle-2.f)/3.f;
+		}
 
 	if (alpha <= 0.f)
-			{
+	{
 		if (mNameText)
 		{
 			mNameText->markDead();
@@ -2968,31 +2962,30 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 		return;
 	}
 
-				if (!mNameText)
-				{
+	if (!mNameText)
+	{
 		mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject(
 			LLHUDObject::LL_HUD_NAME_TAG) );
 		//mNameText->setMass(10.f);
-					mNameText->setSourceObject(this);
+		mNameText->setSourceObject(this);
 		mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP);
-					mNameText->setVisibleOffScreen(TRUE);
-					mNameText->setMaxLines(11);
-					mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
-					sNumVisibleChatBubbles++;
-					new_name = TRUE;
-				}
+		mNameText->setVisibleOffScreen(TRUE);
+		mNameText->setMaxLines(11);
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+		sNumVisibleChatBubbles++;
+		new_name = TRUE;
+	}
 				
-	LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last);
-	mNameText->setPositionAgent(name_position);				
+	idleUpdateNameTagPosition(root_pos_last);
 	idleUpdateNameTagText(new_name);			
 	idleUpdateNameTagAlpha(new_name, alpha);
 }
 
 void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
-			{
-		LLNameValue *title = getNVPair("Title");
-		LLNameValue* firstname = getNVPair("FirstName");
-		LLNameValue* lastname = getNVPair("LastName");
+{
+	LLNameValue *title = getNVPair("Title");
+	LLNameValue* firstname = getNVPair("FirstName");
+	LLNameValue* lastname = getNVPair("LastName");
 
 	// Avatars must have a first and last name
 	if (!firstname || !lastname) return;
@@ -3006,34 +2999,29 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		is_muted = false;
 	}
 	else
-		{
+	{
 		is_muted = LLMuteList::getInstance()->isMuted(getID());
 	}
 	bool is_friend = LLAvatarTracker::instance().isBuddy(getID());
 	bool is_cloud = getIsCloud();
 
-			if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
-			{
-				if (is_appearance != mNameAppearance)
-				{
-					if (is_appearance)
-					{
-						LLSD args;
-						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
-						args["NAME"] = getFullname();
-						LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args);
-						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl;
-					}
-					else
-					{
-						LLSD args;
-						args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
-						args["NAME"] = getFullname();
-						LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args);
-						llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl;
-					}
-				}
-			}
+	if (gSavedSettings.getBOOL("DebugAvatarRezTime")
+		&& is_appearance != mNameAppearance)
+	{
+		LLSD args;
+		args["EXISTENCE"] = llformat("%d",(U32)mDebugExistenceTimer.getElapsedTimeF32());
+		args["NAME"] = getFullname();
+		if (is_appearance)
+		{
+			LLNotificationsUtil::add("AvatarRezEnteredAppearanceNotification",args);
+			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' entered appearance mode." << llendl;
+		}
+		else
+		{
+			LLNotificationsUtil::add("AvatarRezLeftAppearanceNotification",args);
+			llinfos << "REZTIME: [ " << (U32)mDebugExistenceTimer.getElapsedTimeF32() << "sec ] Avatar '" << getFullname() << "' left appearance mode." << llendl;
+		}
+	}
 
 	// Rebuild name tag if state change detected
 	if (mNameString.empty()
@@ -3043,39 +3031,39 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		|| is_away != mNameAway 
 		|| is_busy != mNameBusy 
 		|| is_muted != mNameMute
-				|| is_appearance != mNameAppearance 
+		|| is_appearance != mNameAppearance 
 		|| is_friend != mNameFriend
 		|| is_cloud != mNameCloud)
-				{
+	{
 		LLColor4 name_tag_color = getNameTagColor(is_friend);
 
 		clearNameTag();
 
 		if (is_away || is_muted || is_busy || is_appearance)
-				{
+		{
 			std::string line;
-					if (is_away)
-					{
-						line += LLTrans::getString("AvatarAway");
+			if (is_away)
+			{
+				line += LLTrans::getString("AvatarAway");
 				line += ", ";
-					}
-					if (is_busy)
-					{
+			}
+			if (is_busy)
+			{
 				line += LLTrans::getString("AvatarBusy");
 				line += ", ";
 			}
 			if (is_muted)
-						{
+			{
 				line += LLTrans::getString("AvatarMuted");
-							line += ", ";
-						}
+				line += ", ";
+			}
 			if (is_appearance)
 			{
 				line += LLTrans::getString("AvatarEditingAppearance");
 				line += ", ";
-					}
+			}
 			if (is_cloud)
-					{
+			{
 				line += LLTrans::getString("LoadingData");
 				line += ", ";
 			}
@@ -3087,12 +3075,12 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 
 		if (sRenderGroupTitles
 			&& title && title->getString() && title->getString()[0] != '\0')
-						{
+		{
 			std::string title_str = title->getString();
 			LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
 			addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
 				LLFontGL::getFontSansSerifSmall());
-						}
+		}
 
 		static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");
 		static LLUICachedControl<bool> show_usernames("NameTagShowUsernames");
@@ -3106,119 +3094,118 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 				// and force a rebuild
 				LLAvatarNameCache::get(getID(),
 					boost::bind(&LLVOAvatar::clearNameTag, this));
-					}
+			}
 
 			// Might be blank if name not available yet, that's OK
 			if (show_display_names)
 			{
 				addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL,
 					LLFontGL::getFontSansSerif());
-				}
+			}
 			// Suppress SLID display if display name matches exactly (ugh)
 			if (show_usernames && !av_name.mIsDisplayNameDefault)
-				{
+			{
 				// *HACK: Desaturate the color
 				LLColor4 username_color = name_tag_color * 0.83f;
 				addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL,
 					LLFontGL::getFontSansSerifSmall());
 			}
-				}
+		}
 		else
-				{
+		{
 			const LLFontGL* font = LLFontGL::getFontSansSerif();
-			std::string full_name =
-				LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
+			std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
 			addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font);
-				}
+		}
 
-				mNameAway = is_away;
-				mNameBusy = is_busy;
-				mNameMute = is_muted;
-				mNameAppearance = is_appearance;
-		mNameFriend = is_friend;
-				mNameCloud = is_cloud;
-				mTitle = title ? title->getString() : "";
-				LLStringFn::replace_ascii_controlchars(mTitle,LL_UNKNOWN_CHAR);
-				new_name = TRUE;
-			}
+		mNameAway 		= is_away;
+		mNameBusy 		= is_busy;
+		mNameMute 		= is_muted;
+		mNameAppearance = is_appearance;
+		mNameFriend 	= is_friend;
+		mNameCloud 		= is_cloud;
+		mTitle 			= title ? title->getString() : "";
+		LLStringFn::replace_ascii_controlchars(mTitle, LL_UNKNOWN_CHAR);
+		new_name = TRUE;
+	}
 
 	if (mVisibleChat)
-			{
-				mNameText->setFont(LLFontGL::getFontSansSerif());
+	{
+		mNameText->setFont(LLFontGL::getFontSansSerif());
 		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
-				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
-			
-				char line[MAX_STRING];		/* Flawfinder: ignore */
-				line[0] = '\0';
-				std::deque<LLChat>::iterator chat_iter = mChats.begin();
-				mNameText->clearString();
-
-				LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
-				LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
-				LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
-				if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) 
-				{
-					++chat_iter;
-				}
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
 
-				for(; chat_iter != mChats.end(); ++chat_iter)
-				{
-					F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
-					LLFontGL::StyleFlags style;
-					switch(chat_iter->mChatType)
-					{
-						case CHAT_TYPE_WHISPER:
-							style = LLFontGL::ITALIC;
-							break;
-						case CHAT_TYPE_SHOUT:
-							style = LLFontGL::BOLD;
-							break;
-						default:
-							style = LLFontGL::NORMAL;
-							break;
-					}
-					if (chat_fade_amt < 1.f)
-					{
-						F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
-						mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
-					}
-					else if (chat_fade_amt < 2.f)
-					{
-						F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
-						mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
-					}
-					else if (chat_fade_amt < 3.f)
-					{
-						// *NOTE: only remove lines down to minimum number
-						mNameText->addLine(chat_iter->mText, old_chat, style);
-					}
-				}
-				mNameText->setVisibleOffScreen(TRUE);
+		char line[MAX_STRING];		/* Flawfinder: ignore */
+		line[0] = '\0';
+		std::deque<LLChat>::iterator chat_iter = mChats.begin();
+		mNameText->clearString();
 
-				if (mTyping)
-				{
-					S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
-					switch(dot_count)
-					{
-						case 1:
-							mNameText->addLine(".", new_chat);
-							break;
-						case 2:
-							mNameText->addLine("..", new_chat);
-							break;
-						case 3:
-							mNameText->addLine("...", new_chat);
-							break;
-					}
+		LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
+		LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
+		LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
+		if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) 
+		{
+			++chat_iter;
+		}
 
-				}
+		for(; chat_iter != mChats.end(); ++chat_iter)
+		{
+			F32 chat_fade_amt = llclamp((F32)((LLFrameTimer::getElapsedSeconds() - chat_iter->mTime) / CHAT_FADE_TIME), 0.f, 4.f);
+			LLFontGL::StyleFlags style;
+			switch(chat_iter->mChatType)
+			{
+			case CHAT_TYPE_WHISPER:
+				style = LLFontGL::ITALIC;
+				break;
+			case CHAT_TYPE_SHOUT:
+				style = LLFontGL::BOLD;
+				break;
+			default:
+				style = LLFontGL::NORMAL;
+				break;
 			}
-			else
+			if (chat_fade_amt < 1.f)
 			{
+				F32 u = clamp_rescale(chat_fade_amt, 0.9f, 1.f, 0.f, 1.f);
+				mNameText->addLine(chat_iter->mText, lerp(new_chat, normal_chat, u), style);
+			}
+			else if (chat_fade_amt < 2.f)
+			{
+				F32 u = clamp_rescale(chat_fade_amt, 1.9f, 2.f, 0.f, 1.f);
+				mNameText->addLine(chat_iter->mText, lerp(normal_chat, old_chat, u), style);
+			}
+			else if (chat_fade_amt < 3.f)
+			{
+				// *NOTE: only remove lines down to minimum number
+				mNameText->addLine(chat_iter->mText, old_chat, style);
+			}
+		}
+		mNameText->setVisibleOffScreen(TRUE);
+
+		if (mTyping)
+		{
+			S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
+			switch(dot_count)
+			{
+			case 1:
+				mNameText->addLine(".", new_chat);
+				break;
+			case 2:
+				mNameText->addLine("..", new_chat);
+				break;
+			case 3:
+				mNameText->addLine("...", new_chat);
+				break;
+			}
+
+		}
+	}
+	else
+	{
 		// ...not using chat bubbles, just names
 		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_CENTER);
-				mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
-				mNameText->setVisibleOffScreen(FALSE);
+		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
+		mNameText->setVisibleOffScreen(FALSE);
 	}
 }
 
@@ -3241,8 +3228,8 @@ void LLVOAvatar::clearNameTag()
 {
 	mNameString.clear();
 	if (mNameText)
-				{
-					mNameText->setLabel("");
+	{
+		mNameText->setLabel("");
 		mNameText->setString( "" );
 	}
 }
@@ -3270,34 +3257,45 @@ void LLVOAvatar::invalidateNameTags()
 		if (avatar->isDead()) continue;
 
 		avatar->clearNameTag();
-
 	}
 }
 
 // Compute name tag position during idle update
-LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
+void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
 {
 	LLQuaternion root_rot = mRoot.getWorldRotation();
+	LLQuaternion inv_root_rot = ~root_rot;
 	LLVector3 pixel_right_vec;
 	LLVector3 pixel_up_vec;
 	LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);
 	LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin();
 	camera_to_av.normalize();
-	LLVector3 local_camera_at = camera_to_av * ~root_rot;
+	LLVector3 local_camera_at = camera_to_av * inv_root_rot;
 	LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis();
 	local_camera_up.normalize();
-	local_camera_up = local_camera_up * ~root_rot;
+	local_camera_up = local_camera_up * inv_root_rot;
+
+	LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f,
+								mBodySize.mV[VY] * 0.4f,
+								mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT);
 
-	local_camera_up.scaleVec(mBodySize * 0.5f);
-	local_camera_at.scaleVec(mBodySize * 0.5f);
+	local_camera_up.scaleVec(avatar_ellipsoid);
+	local_camera_at.scaleVec(avatar_ellipsoid);
 
-	LLVector3 name_position = mRoot.getWorldPosition();
-	name_position[VZ] -= mPelvisToFoot;
-	name_position[VZ] += (mBodySize[VZ]* 0.55f);
+	LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot.getLastWorldPosition()) * inv_root_rot;
+
+	if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD)
+	{
+		mTargetRootToHeadOffset = head_offset;
+	}
+	
+	mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f));
+
+	LLVector3 name_position = mRoot.getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);
 	name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));	
-	name_position += pixel_up_vec * 15.f;
+	name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET;
 
-	return name_position;
+	mNameText->setPositionAgent(name_position);				
 }
 
 void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
@@ -3333,7 +3331,7 @@ LLColor4 LLVOAvatar::getNameTagColor(bool is_friend)
 		else
 		{
 			color_name = "NameTagMismatch";
-	}
+		}
 	}
 	else
 	{
@@ -3370,9 +3368,9 @@ bool LLVOAvatar::isVisuallyMuted()
 	static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit");
 	static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit");
 	
-	return LLMuteList::getInstance()->isMuted(getID()) ||
-			(mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) ||
-			(mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
+	return LLMuteList::getInstance()->isMuted(getID()) 
+			|| (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) 
+			|| (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
 }
 
 //------------------------------------------------------------------------
@@ -3413,8 +3411,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		}
 	}
 
-	LLVector3d root_pos_global;
-
 	if (!mIsBuilt)
 	{
 		return FALSE;
@@ -3428,7 +3424,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 	{
 		mTimeVisible.reset();
 	}
-
 	
 	//--------------------------------------------------------------------
 	// the rest should only be done occasionally for far away avatars
@@ -3823,10 +3818,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 
 		if ( playSound )
 		{
-//			F32 gain = clamp_rescale( mSpeedAccum,
-//							AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
-//							AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
-
 			const F32 STEP_VOLUME = 0.1f;
 			const LLUUID& step_sound_id = getStepSound();
 
@@ -4043,13 +4034,6 @@ void LLVOAvatar::updateVisibility()
 		{
 			releaseMeshData();
 		}
-		// this breaks off-screen chat bubbles
-		//if (mNameText)
-		//{
-		//	mNameText->markDead();
-		//	mNameText = NULL;
-		//	sNumVisibleChatBubbles--;
-		//}
 	}
 
 	mVisible = visible;
@@ -4065,46 +4049,6 @@ bool LLVOAvatar::shouldAlphaMask()
 
 }
 
-U32 LLVOAvatar::renderSkinnedAttachments()
-{
-	/*U32 num_indices = 0;
-	
-	const U32 data_mask =	LLVertexBuffer::MAP_VERTEX | 
-							LLVertexBuffer::MAP_NORMAL | 
-							LLVertexBuffer::MAP_TEXCOORD0 |
-							LLVertexBuffer::MAP_COLOR |
-							LLVertexBuffer::MAP_WEIGHT4;
-
-	for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); 
-		 iter != mAttachmentPoints.end();
-		 ++iter)
-	{
-		LLViewerJointAttachment* attachment = iter->second;
-		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
-			 attachment_iter != attachment->mAttachedObjects.end();
-			 ++attachment_iter)
-		{
-			const LLViewerObject* attached_object = (*attachment_iter);
-			if (attached_object && !attached_object->isHUDAttachment())
-			{
-				const LLDrawable* drawable = attached_object->mDrawable;
-				if (drawable)
-				{
-					for (S32 i = 0; i < drawable->getNumFaces(); ++i)
-					{
-						LLFace* face = drawable->getFace(i);
-						if (face->isState(LLFace::RIGGED))
-						{
-							
-				}
-			}
-		}
-	}
-
-	return num_indices;*/
-	return 0;
-}
-
 //-----------------------------------------------------------------------------
 // renderSkinned()
 //-----------------------------------------------------------------------------
@@ -4125,11 +4069,11 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 	{	//LOD changed or new mesh created, allocate new vertex buffer if needed
 		if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
 		{
-		updateMeshData();
+			updateMeshData();
 			mDirtyMesh = 0;
-		mNeedsSkin = TRUE;
-		mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
-	}
+			mNeedsSkin = TRUE;
+			mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+		}
 	}
 
 	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
@@ -5790,36 +5734,34 @@ BOOL LLVOAvatar::updateJointLODs()
 	F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor);
 	F32 area_scale = 0.16f;
 
+	if (isSelf())
 	{
-		if (isSelf())
-		{
-			if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
-			{
-				mAdjustedPixelArea = MAX_PIXEL_AREA;
-			}
-			else
-			{
-				mAdjustedPixelArea = mPixelArea*area_scale;
-			}
-		}
-		else if (mIsDummy)
+		if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
 		{
 			mAdjustedPixelArea = MAX_PIXEL_AREA;
 		}
 		else
 		{
-			// reported avatar pixel area is dependent on avatar render load, based on number of visible avatars
-			mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor;
+			mAdjustedPixelArea = mPixelArea*area_scale;
 		}
+	}
+	else if (mIsDummy)
+	{
+		mAdjustedPixelArea = MAX_PIXEL_AREA;
+	}
+	else
+	{
+		// reported avatar pixel area is dependent on avatar render load, based on number of visible avatars
+		mAdjustedPixelArea = (F32)mPixelArea * area_scale * lod_factor * lod_factor * avatar_num_factor * avatar_num_factor;
+	}
 
-		// now select meshes to render based on adjusted pixel area
-		BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
- 		if (res)
-		{
-			sNumLODChangesThisFrame++;
-			dirtyMesh(2);
-			return TRUE;
-		}
+	// now select meshes to render based on adjusted pixel area
+	BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
+ 	if (res)
+	{
+		sNumLODChangesThisFrame++;
+		dirtyMesh(2);
+		return TRUE;
 	}
 
 	return FALSE;
@@ -6109,25 +6051,18 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
 		if ( pVObj )
 		{
 			const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj );
-			if ( pSkinData )
-			{
-				const int jointCnt = pSkinData->mJointNames.size();
-				bool fullRig = ( jointCnt>=20 ) ? true : false;
-				if ( fullRig )
+			if (pSkinData 
+				&& pSkinData->mJointNames.size() > 20				// full rig
+				&& pSkinData->mAlternateBindMatrix.size() > 0)
+			{
+				LLVOAvatar::resetJointPositionsToDefault();
+				//Need to handle the repositioning of the cam, updating rig data etc during outfit editing 
+				//This handles the case where we detach a replacement rig.
+				if ( gAgentCamera.cameraCustomizeAvatar() )
 				{
-					const int bindCnt = pSkinData->mAlternateBindMatrix.size();							
-					if ( bindCnt > 0 )
-					{
-						LLVOAvatar::resetJointPositionsToDefault();
-						//Need to handle the repositioning of the cam, updating rig data etc during outfit editing 
-						//This handles the case where we detach a replacement rig.
-						if ( gAgentCamera.cameraCustomizeAvatar() )
-						{
-							gAgent.unpauseAnimation();
-							//Still want to refocus on head bone
-							gAgentCamera.changeCameraToCustomizeAvatar();
-						}
-					}
+					gAgent.unpauseAnimation();
+					//Still want to refocus on head bone
+					gAgentCamera.changeCameraToCustomizeAvatar();
 				}
 			}				
 		}
@@ -6281,11 +6216,7 @@ void LLVOAvatar::getOffObject()
 		at_axis.mV[VZ] = 0.f;
 		at_axis.normalize();
 		gAgent.resetAxes(at_axis);
-
-		//reset orientation
-//		mRoot.setRotation(avWorldRot);
 		gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f));
-
 		gAgentCamera.setSitCamera(LLUUID::null);
 	}
 }
@@ -6335,7 +6266,6 @@ LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const
 	}
 	else
 	{
-//		return LLColor4( .5f, .5f, .5f, .5f );
 		return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
 	}
 }
@@ -7067,10 +6997,6 @@ LLBBox LLVOAvatar::getHUDBBox() const
 	return bbox;
 }
 
-void LLVOAvatar::rebuildHUD()
-{
-}
-
 //-----------------------------------------------------------------------------
 // onFirstTEMessageReceived()
 //-----------------------------------------------------------------------------
@@ -7192,7 +7118,10 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 			&& baked_index != BAKED_SKIRT)
 		{
 			setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, 
-				LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+						LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, 
+																TRUE, 
+																LLViewerTexture::BOOST_NONE, 
+																LLViewerTexture::LOD_TEXTURE));
 		}
 	}
 
@@ -7483,11 +7412,6 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_
 // Called when baked texture is loaded and also when we start up with a baked texture
 void LLVOAvatar::useBakedTexture( const LLUUID& id )
 {
-	/* if(id == head_baked->getID())
-		 mHeadBakedLoaded = TRUE;
-		 mLastHeadBakedID = id;
-		 mHeadMesh0.setTexture( head_baked );
-		 mHeadMesh1.setTexture( head_baked ); */
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
 		LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 );
@@ -7718,111 +7642,111 @@ LLVOAvatar::LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo()
 	std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
 }
 
-//-----------------------------------------------------------------------------
-// LLVOAvatarBoneInfo::parseXml()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
-{
-	if (node->hasName("bone"))
-	{
-		mIsJoint = TRUE;
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-		if (!node->getFastAttributeString(name_string, mName))
-		{
-			llwarns << "Bone without name" << llendl;
-			return FALSE;
-		}
-	}
-	else if (node->hasName("collision_volume"))
-	{
-		mIsJoint = FALSE;
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-		if (!node->getFastAttributeString(name_string, mName))
-		{
-			mName = "Collision Volume";
-		}
-	}
-	else
-	{
-		llwarns << "Invalid node " << node->getName() << llendl;
-		return FALSE;
-	}
-
-	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
-	if (!node->getFastAttributeVector3(pos_string, mPos))
-	{
-		llwarns << "Bone without position" << llendl;
-		return FALSE;
-	}
-
-	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
-	if (!node->getFastAttributeVector3(rot_string, mRot))
-	{
-		llwarns << "Bone without rotation" << llendl;
-		return FALSE;
-	}
-	
-	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
-	if (!node->getFastAttributeVector3(scale_string, mScale))
-	{
-		llwarns << "Bone without scale" << llendl;
-		return FALSE;
-	}
-
-	if (mIsJoint)
-	{
-		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
-		if (!node->getFastAttributeVector3(pivot_string, mPivot))
-		{
-			llwarns << "Bone without pivot" << llendl;
-			return FALSE;
-		}
-	}
-
-	// parse children
-	LLXmlTreeNode* child;
-	for( child = node->getFirstChild(); child; child = node->getNextChild() )
-	{
-		LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo;
-		if (!child_info->parseXml(child))
-		{
-			delete child_info;
-			return FALSE;
-		}
-		mChildList.push_back(child_info);
-	}
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLVOAvatarSkeletonInfo::parseXml()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
-{
-	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
-	if (!node->getFastAttributeS32(num_bones_string, mNumBones))
-	{
-		llwarns << "Couldn't find number of bones." << llendl;
-		return FALSE;
-	}
-
-	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
-	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
-
-	LLXmlTreeNode* child;
-	for( child = node->getFirstChild(); child; child = node->getNextChild() )
-	{
-		LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo;
-		if (!info->parseXml(child))
-		{
-			delete info;
-			llwarns << "Error parsing bone in skeleton file" << llendl;
-			return FALSE;
-		}
-		mBoneInfoList.push_back(info);
-	}
-	return TRUE;
-}
+////-----------------------------------------------------------------------------
+//// LLVOAvatarBoneInfo::parseXml()
+////-----------------------------------------------------------------------------
+//BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
+//{
+//	if (node->hasName("bone"))
+//	{
+//		mIsJoint = TRUE;
+//		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+//		if (!node->getFastAttributeString(name_string, mName))
+//		{
+//			llwarns << "Bone without name" << llendl;
+//			return FALSE;
+//		}
+//	}
+//	else if (node->hasName("collision_volume"))
+//	{
+//		mIsJoint = FALSE;
+//		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+//		if (!node->getFastAttributeString(name_string, mName))
+//		{
+//			mName = "Collision Volume";
+//		}
+//	}
+//	else
+//	{
+//		llwarns << "Invalid node " << node->getName() << llendl;
+//		return FALSE;
+//	}
+//
+//	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
+//	if (!node->getFastAttributeVector3(pos_string, mPos))
+//	{
+//		llwarns << "Bone without position" << llendl;
+//		return FALSE;
+//	}
+//
+//	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
+//	if (!node->getFastAttributeVector3(rot_string, mRot))
+//	{
+//		llwarns << "Bone without rotation" << llendl;
+//		return FALSE;
+//	}
+//	
+//	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+//	if (!node->getFastAttributeVector3(scale_string, mScale))
+//	{
+//		llwarns << "Bone without scale" << llendl;
+//		return FALSE;
+//	}
+//
+//	if (mIsJoint)
+//	{
+//		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
+//		if (!node->getFastAttributeVector3(pivot_string, mPivot))
+//		{
+//			llwarns << "Bone without pivot" << llendl;
+//			return FALSE;
+//		}
+//	}
+//
+//	// parse children
+//	LLXmlTreeNode* child;
+//	for( child = node->getFirstChild(); child; child = node->getNextChild() )
+//	{
+//		LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo;
+//		if (!child_info->parseXml(child))
+//		{
+//			delete child_info;
+//			return FALSE;
+//		}
+//		mChildList.push_back(child_info);
+//	}
+//	return TRUE;
+//}
+//
+////-----------------------------------------------------------------------------
+//// LLVOAvatarSkeletonInfo::parseXml()
+////-----------------------------------------------------------------------------
+//BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
+//{
+//	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
+//	if (!node->getFastAttributeS32(num_bones_string, mNumBones))
+//	{
+//		llwarns << "Couldn't find number of bones." << llendl;
+//		return FALSE;
+//	}
+//
+//	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
+//	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
+//
+//	LLXmlTreeNode* child;
+//	for( child = node->getFirstChild(); child; child = node->getNextChild() )
+//	{
+//		LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo;
+//		if (!info->parseXml(child))
+//		{
+//			delete info;
+//			llwarns << "Error parsing bone in skeleton file" << llendl;
+//			return FALSE;
+//		}
+//		mBoneInfoList.push_back(info);
+//	}
+//	return TRUE;
+//}
 
 //-----------------------------------------------------------------------------
 // parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index dd0317f555d4072093658aae464f2b4e933b4a9c..e84acd51ff003527f35df0e6c98552f972676497 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -66,8 +66,9 @@ class LLVoiceVisualizer;
 class LLHUDNameTag;
 class LLHUDEffectSpiral;
 class LLTexGlobalColor;
-class LLVOAvatarBoneInfo;
-class LLVOAvatarSkeletonInfo;
+struct LLVOAvatarBoneInfo;
+struct LLVOAvatarChildJoint;
+struct LLVOAvatarSkeletonInfo;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLVOAvatar
@@ -232,7 +233,7 @@ class LLVOAvatar :
 	void 			idleUpdateWindEffect();
 	void 			idleUpdateNameTag(const LLVector3& root_pos_last);
 	void			idleUpdateNameTagText(BOOL new_name);
-	LLVector3		idleUpdateNameTagPosition(const LLVector3& root_pos_last);
+	void			idleUpdateNameTagPosition(const LLVector3& root_pos_last);
 	void			idleUpdateNameTagAlpha(BOOL new_name, F32 alpha);
 	LLColor4		getNameTagColor(bool is_friend);
 	void			clearNameTag();
@@ -317,6 +318,8 @@ class LLVOAvatar :
 	F32					mLastPelvisToFoot;
 	F32					mPelvisFixup;
 	F32					mLastPelvisFixup;
+	LLVector3			mCurRootToHeadOffset;
+	LLVector3			mTargetRootToHeadOffset;
 
 	LLVector3			mHeadOffset; // current head position
 	LLViewerJoint		mRoot;
@@ -325,7 +328,7 @@ class LLVOAvatar :
 	void				buildCharacter();
 	virtual BOOL		loadAvatar();
 
-	BOOL				setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
+	BOOL				setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
 	BOOL				buildSkeleton(const LLVOAvatarSkeletonInfo *info);
 private:
 	BOOL				mIsBuilt; // state of deferred character building
@@ -369,7 +372,7 @@ class LLVOAvatar :
 	//--------------------------------------------------------------------
 private:
 	static LLXmlTree 	sXMLTree; // avatar config file
-	static LLXmlTree 	sSkeletonXMLTree; // avatar skeleton file
+	static LLXMLNodePtr	sSkeletonXMLTree; // avatar skeleton file
 
 /**                    Skeleton
  **                                                                            **
@@ -387,7 +390,6 @@ class LLVOAvatar :
 	U32 		renderRigid();
 	U32 		renderSkinned(EAvatarRenderPass pass);
 	F32			getLastSkinTime() { return mLastSkinTime; }
-	U32			renderSkinnedAttachments();
 	U32 		renderTransparent(BOOL first_pass);
 	void 		renderCollisionVolumes();
 	static void	deleteCachedImages(bool clearAll=true);
@@ -735,7 +737,6 @@ class LLVOAvatar :
 public:
 	BOOL 				hasHUDAttachment() const;
 	LLBBox 				getHUDBBox() const;
-	void 				rebuildHUD();
 	void 				resetHUDAttachments();
 	BOOL				canAttachMoreObjects() const;
 	BOOL				canAttachMoreObjects(U32 n) const;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c523a78b221e0fd88453ab05613c65092e4fc9cc..fc499bfe9ce92b9a1c6e9b1001eff77566faf188 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -4678,11 +4678,6 @@ void LLPipeline::rebuildPools()
 		}
 		max_count--;
 	}
-
-	if (isAgentAvatarValid())
-	{
-		gAgentAvatarp->rebuildHUD();
-	}
 }
 
 void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )