diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index 3d26cd2404754f80b1c2a58df413e4cd982e116c..8d6aa405e26bc2966426ce575db014f2a4d44d98 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -139,7 +139,7 @@ namespace LLInitParam
 
 	bool BaseBlock::validateBlock(bool emit_errors) const
 	{
-		const BlockDescriptor& block_data = getBlockDescriptor();
+		const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
 		for (BlockDescriptor::param_validation_list_t::const_iterator it = block_data.mValidationList.begin(); it != block_data.mValidationList.end(); ++it)
 		{
 			const Param* param = getParamFromHandle(it->first);
@@ -159,7 +159,7 @@ namespace LLInitParam
 	{
 		// named param is one like LLView::Params::follows
 		// unnamed param is like LLView::Params::rect - implicit
-		const BlockDescriptor& block_data = getBlockDescriptor();
+		const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
 
 		for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin(); 
 			it != block_data.mUnnamedParams.end(); 
@@ -230,7 +230,7 @@ namespace LLInitParam
 	{
 		// named param is one like LLView::Params::follows
 		// unnamed param is like LLView::Params::rect - implicit
-		const BlockDescriptor& block_data = getBlockDescriptor();
+		const BlockDescriptor& block_data = mostDerivedBlockDescriptor();
 
 		for (BlockDescriptor::param_list_t::const_iterator it = block_data.mUnnamedParams.begin(); 
 			it != block_data.mUnnamedParams.end(); 
@@ -301,7 +301,7 @@ namespace LLInitParam
 
 	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack)
 	{
-		BlockDescriptor& block_data = getBlockDescriptor();
+		BlockDescriptor& block_data = mostDerivedBlockDescriptor();
 		bool names_left = name_stack.first != name_stack.second;
 
 		if (names_left)
@@ -386,7 +386,7 @@ namespace LLInitParam
 
 	void BaseBlock::addSynonym(Param& param, const std::string& synonym)
 	{
-		BlockDescriptor& block_data = getBlockDescriptor();
+		BlockDescriptor& block_data = mostDerivedBlockDescriptor();
 		if (block_data.mInitializationState == BlockDescriptor::INITIALIZING)
 		{
 			param_handle_t handle = getHandleFromParam(&param);
@@ -445,7 +445,7 @@ namespace LLInitParam
 
 	ParamDescriptor* BaseBlock::findParamDescriptor(param_handle_t handle)
 	{
-		BlockDescriptor& descriptor = getBlockDescriptor();
+		BlockDescriptor& descriptor = mostDerivedBlockDescriptor();
 		BlockDescriptor::all_params_list_t::iterator end_it = descriptor.mAllParams.end();
 		for (BlockDescriptor::all_params_list_t::iterator it = descriptor.mAllParams.begin();
 			it != end_it;
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 0e9fd54bc121cc3cd9010f350a08fc911a35b86f..3bddd50659218094eca90c94bce195b54f6224ab 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -479,8 +479,8 @@ namespace LLInitParam
 		bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const;
 		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) const;
 
-		const BlockDescriptor& getBlockDescriptor() const { return *mBlockDescriptor; }
-		BlockDescriptor& getBlockDescriptor() { return *mBlockDescriptor; }
+		const BlockDescriptor& mostDerivedBlockDescriptor() const { return *mBlockDescriptor; }
+		BlockDescriptor& mostDerivedBlockDescriptor() { return *mBlockDescriptor; }
 
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const BaseBlock& other)
@@ -507,7 +507,7 @@ namespace LLInitParam
 
 		BlockDescriptor*		mBlockDescriptor;	// most derived block descriptor
 
-		static BlockDescriptor& blockDescriptor()
+		static BlockDescriptor& selfBlockDescriptor()
 		{
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
@@ -559,7 +559,7 @@ namespace LLInitParam
 		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)
 		{
-			if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
 				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
 												&mergeWith,
@@ -723,7 +723,7 @@ namespace LLInitParam
 		:	Param(block_descriptor.mCurrentBlockPtr),
 			T(value)
 		{
-			if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
 				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
 												&mergeWith,
@@ -858,7 +858,7 @@ namespace LLInitParam
 		{
 			const self_t& src_typed_param = static_cast<const self_t&>(src);
 			self_t& dst_typed_param = static_cast<self_t&>(dst);
-			if (dst_typed_param.T::merge(dst_typed_param.BaseBlock::getBlockDescriptor(), src_typed_param, overwrite))
+			if (dst_typed_param.T::merge(selfBlockDescriptor(), src_typed_param, overwrite || !dst_typed_param.isProvided()))
 			{
 				dst_typed_param.mData.clearKey();
 				return true;
@@ -902,7 +902,7 @@ namespace LLInitParam
 			mValues(value)
 		{
 			mCachedKeys.resize(mValues.size());
-			if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
 				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
 												&mergeWith,
@@ -1085,7 +1085,7 @@ namespace LLInitParam
 			mLastParamGeneration(0)
 		{
 			mCachedKeys.resize(mValues.size());
-			if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
 				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
 												&mergeWith,
@@ -1273,24 +1273,23 @@ namespace LLInitParam
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const self_t& other)
 		{
-			return merge(blockDescriptor(), other, true);
+			return merge(selfBlockDescriptor(), other, true);
 		}
 
 		// take all provided params that are not already provided, and apply to self
 		bool fillFrom(const self_t& other)
 		{
-			return merge(blockDescriptor(), other, false);
+			return merge(selfBlockDescriptor(), other, false);
 		}
 
 		// merge with other block
 		bool merge(BlockDescriptor& block_data, const self_t& other, bool overwrite)
 		{
 			// only merge a choice if we are overwriting with other's contents
-			// or we have never specified a choice locally, other than the default
-			if (overwrite || getLastChangeVersion() == 0)
+			if (overwrite)
 			{
 				mCurChoice = other.mCurChoice;
-				return BaseBlock::merge(blockDescriptor(), other, overwrite);
+				return BaseBlock::merge(selfBlockDescriptor(), other, overwrite);
 			}
 			return false;
 		}
@@ -1317,7 +1316,7 @@ namespace LLInitParam
 		Choice()
 		:	mCurChoice(0)
 		{
-			BaseBlock::init(blockDescriptor(), BaseBlock::blockDescriptor(), sizeof(DERIVED_BLOCK));
+			BaseBlock::init(selfBlockDescriptor(), BaseBlock::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
 		}
 
 		// Alternatives are mutually exclusive wrt other Alternatives in the same block.  
@@ -1334,13 +1333,14 @@ namespace LLInitParam
 			typedef typename super_t::value_assignment_t								value_assignment_t;
 
 			explicit Alternative(const char* name, value_assignment_t val = DefaultInitializer<T>::get())
-			:	super_t(DERIVED_BLOCK::blockDescriptor(), name, val, NULL, 0, 1),
+			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
 				mOriginalValue(val)
 			{
 				// assign initial choice to first declared option
-				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::blockDescriptor().mCurrentBlockPtr);
-				if (DERIVED_BLOCK::blockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING
-					&& blockp->mCurChoice == 0)
+				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr);
+				if (LL_UNLIKELY(
+						DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING
+							&& blockp->mCurChoice == 0))
 				{
 					blockp->mCurChoice = Param::enclosingBlock().getHandleFromParam(this);
 				}
@@ -1385,7 +1385,7 @@ namespace LLInitParam
 		};
 
 	protected:
-		static BlockDescriptor& blockDescriptor()
+		static BlockDescriptor& selfBlockDescriptor()
 		{
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
@@ -1413,19 +1413,19 @@ namespace LLInitParam
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const self_t& other)
 		{
-			return BaseBlock::merge(blockDescriptor(), other, true);
+			return BaseBlock::merge(selfBlockDescriptor(), other, true);
 		}
 
 		// take all provided params that are not already provided, and apply to self
 		bool fillFrom(const self_t& other)
 		{
-			return BaseBlock::merge(blockDescriptor(), other, false);
+			return BaseBlock::merge(selfBlockDescriptor(), other, false);
 		}
 	protected:
 		Block()
 		{
 			//#pragma message("Parsing LLInitParam::Block")
-			BaseBlock::init(blockDescriptor(), BASE_BLOCK::blockDescriptor(), sizeof(DERIVED_BLOCK));
+			BaseBlock::init(selfBlockDescriptor(), BASE_BLOCK::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
 		}
 
 		//
@@ -1439,7 +1439,7 @@ namespace LLInitParam
 			typedef typename super_t::value_assignment_t								value_assignment_t;
 
 			explicit Optional(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get())
-			:	super_t(DERIVED_BLOCK::blockDescriptor(), name, val, NULL, 0, 1)
+			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)
 			{
 				//#pragma message("Parsing LLInitParam::Block::Optional")
 			}
@@ -1468,7 +1468,7 @@ namespace LLInitParam
 
 			// mandatory parameters require a name to be parseable
 			explicit Mandatory(const char* name = "", value_assignment_t val = DefaultInitializer<T>::get())
-			:	super_t(DERIVED_BLOCK::blockDescriptor(), name, val, &validate, 1, 1)
+			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)
 			{}
 
 			Mandatory& operator=(value_assignment_t val)
@@ -1504,7 +1504,7 @@ namespace LLInitParam
 			typedef typename container_t::const_iterator							const_iterator;
 
 			explicit Multiple(const char* name = "", value_assignment_t val = DefaultInitializer<container_t>::get())
-			:	super_t(DERIVED_BLOCK::blockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount())
+			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, RANGE::minCount(), RANGE::maxCount())
 			{}
 
 			using super_t::operator();
@@ -1532,10 +1532,10 @@ namespace LLInitParam
 		{
 		public:
 			explicit Deprecated(const char* name)
-			:	Param(DERIVED_BLOCK::blockDescriptor().mCurrentBlockPtr)
+			:	Param(DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
 			{
-				BlockDescriptor& block_descriptor = DERIVED_BLOCK::blockDescriptor();
-				if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
+				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 				{
 					ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
 													NULL,
@@ -1564,7 +1564,7 @@ namespace LLInitParam
 		typedef Deprecated Ignored;
 
 	protected:
-		static BlockDescriptor& blockDescriptor()
+		static BlockDescriptor& selfBlockDescriptor()
 		{
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
@@ -1577,12 +1577,12 @@ namespace LLInitParam
 		public Param
 	{
 	public:
-		typedef enum e_value_valid
-		{
+		typedef enum e_value_age
+		{	
 			OLDER_THAN_BLOCK,	// mData.mValue needs to be refreshed from the block parameters
 			NEWER_THAN_BLOCK,	// mData.mValue holds the authoritative value (which has been replicated to the block parameters via setBlockFromValue)
 			SAME_AS_BLOCK		// mData.mValue is derived from the block parameters, which are authoritative
-		} EValueValid;
+		} EValueAge;
 
 		typedef BlockValue<T>										self_t;
 		typedef Block<TypedParam<T, TypeValues<T>, false> >			block_t;
@@ -1592,9 +1592,9 @@ namespace LLInitParam
 
 		BlockValue(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),
-			mData(value)
+			mData(value, NEWER_THAN_BLOCK)
 		{
-			if (block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING)
+			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
 				ParamDescriptor param_descriptor(block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
 												&mergeWith,
@@ -1802,13 +1802,13 @@ namespace LLInitParam
 
 		struct Data : public key_cache_t
 		{
-			Data(const T& value) 
+			Data(const T& value, EValueAge age) 
 			:	mValue(value),
-				mValueAge(SAME_AS_BLOCK)
+				mValueAge(age)
 			{}
 
-			T		mValue;
-			EValueValid		mValueAge;
+			T			mValue;
+			EValueAge	mValueAge;
 		};
 
 		// mutable to allow lazy updates on get
@@ -1831,7 +1831,7 @@ namespace LLInitParam
 				else
 				{
 					// merge individual parameters into destination
-					dst_typed_param.merge(block_t::blockDescriptor(), src_typed_param, overwrite);
+					dst_typed_param.merge(block_t::selfBlockDescriptor(), src_typed_param, overwrite);
 				}
 				return true;
 			}