diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index 2ead5a4a57b074c1d354c28e8d80d9eb9a3852d8..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);
@@ -417,8 +417,8 @@ namespace LLInitParam
 	{ 
 		if (user_provided)
 		{
-		mChangeVersion++;
-	}
+			mChangeVersion++;
+		}
 	}
 
 	const std::string& BaseBlock::getParamName(const BlockDescriptor& block_data, const Param* paramp) const
@@ -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;
@@ -460,7 +460,7 @@ namespace LLInitParam
 	// NOTE: this requires that "other" is of the same derived type as this
 	bool BaseBlock::merge(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
 	{
-		bool param_changed = false;
+		bool some_param_changed = false;
 		BlockDescriptor::all_params_list_t::const_iterator end_it = block_data.mAllParams.end();
 		for (BlockDescriptor::all_params_list_t::const_iterator it = block_data.mAllParams.begin();
 			it != end_it;
@@ -471,10 +471,10 @@ namespace LLInitParam
 			if (merge_func)
 			{
 				Param* paramp = getParamFromHandle(it->mParamHandle);
-				param_changed |= merge_func(*paramp, *other_paramp, overwrite);
+				some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
 			}
 		}
-		return param_changed;
+		return some_param_changed;
 	}
 
 	bool ParamCompare<LLSD, false>::equals(const LLSD &a, const LLSD &b)
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index c9c1d4af90c6d8af9e1e54cad7b382921b500506..3bddd50659218094eca90c94bce195b54f6224ab 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -477,10 +477,10 @@ namespace LLInitParam
 
 		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack);
 		bool serializeBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const;
-		virtual bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t()) 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,
@@ -584,6 +584,7 @@ namespace LLInitParam
 			{
 				if (parser.readValue<T>(typed_param.mData.mValue))
 				{
+					typed_param.mData.clearKey();
 					typed_param.setProvided(true);
 					typed_param.enclosingBlock().setLastChangedParam(param, true);
 					return true;
@@ -690,7 +691,7 @@ namespace LLInitParam
 				&& (overwrite || !dst_typed_param.isProvided()))
 			{
 				dst_typed_param.mData.clearKey();
-				dst_typed_param = src_typed_param;
+				dst_typed_param.set(src_typed_param.get());
 				return true;
 			}
 			return false;
@@ -722,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,
@@ -741,6 +742,7 @@ namespace LLInitParam
 			// attempt to parse block...
 			if(typed_param.deserializeBlock(parser, name_stack))
 			{
+				typed_param.mData.clearKey();
 				typed_param.enclosingBlock().setLastChangedParam(param, true);
 				return true;
 			}
@@ -856,21 +858,10 @@ 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 (overwrite)
-			{
-				if (dst_typed_param.T::overwriteFrom(src_typed_param))
-				{
-					dst_typed_param.mData.clearKey();
-					return true;
-				}
-			}
-			else
+			if (dst_typed_param.T::merge(selfBlockDescriptor(), src_typed_param, overwrite || !dst_typed_param.isProvided()))
 			{
-				if (dst_typed_param.T::fillFrom(src_typed_param))
-				{			
-					dst_typed_param.mData.clearKey();
-					return true;
-				}
+				dst_typed_param.mData.clearKey();
+				return true;
 			}
 			return false;
 		}
@@ -911,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,
@@ -1060,9 +1051,9 @@ namespace LLInitParam
 			self_t& dst_typed_param = static_cast<self_t&>(dst);
 
 			if (src_typed_param.isProvided()
-				&& (overwrite || !isProvided()))
+				&& (overwrite || !dst_typed_param.isProvided()))
 			{
-				dst_typed_param = src_typed_param;
+				dst_typed_param.set(src_typed_param.get());
 				return true;
 			}
 			return false;
@@ -1094,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,
@@ -1252,7 +1243,7 @@ namespace LLInitParam
 			if (src_typed_param.isProvided()
 				&& (overwrite || !dst_typed_param.isProvided()))
 			{
-				dst_typed_param = src_typed_param;
+				dst_typed_param.set(src_typed_param.get());
 				return true;
 			}
 			return false;
@@ -1282,13 +1273,24 @@ namespace LLInitParam
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const self_t& other)
 		{
-			mCurChoice = other.mCurChoice;
-			return BaseBlock::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(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
+			if (overwrite)
+			{
+				mCurChoice = other.mCurChoice;
+				return BaseBlock::merge(selfBlockDescriptor(), other, overwrite);
+			}
 			return false;
 		}
 
@@ -1314,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.  
@@ -1331,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);
 				}
@@ -1382,7 +1385,7 @@ namespace LLInitParam
 		};
 
 	protected:
-		static BlockDescriptor& blockDescriptor()
+		static BlockDescriptor& selfBlockDescriptor()
 		{
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
@@ -1410,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));
 		}
 
 		//
@@ -1436,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")
 			}
@@ -1465,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)
@@ -1501,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();
@@ -1529,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,
@@ -1561,7 +1564,7 @@ namespace LLInitParam
 		typedef Deprecated Ignored;
 
 	protected:
-		static BlockDescriptor& blockDescriptor()
+		static BlockDescriptor& selfBlockDescriptor()
 		{
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
@@ -1574,6 +1577,13 @@ namespace LLInitParam
 		public Param
 	{
 	public:
+		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
+		} EValueAge;
+
 		typedef BlockValue<T>										self_t;
 		typedef Block<TypedParam<T, TypeValues<T>, false> >			block_t;
 		typedef const T&											value_const_ref_t;
@@ -1582,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,
@@ -1604,7 +1614,7 @@ namespace LLInitParam
 
 		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
 		{
-			self_t& typed_param = static_cast<self_t&>(param);
+			DERIVED& typed_param = static_cast<DERIVED&>(param);
 			// type to apply parse direct value T
 			if (name_stack.first == name_stack.second)
 			{
@@ -1612,7 +1622,10 @@ namespace LLInitParam
 				{
 					typed_param.enclosingBlock().setLastChangedParam(param, true);
 					typed_param.setProvided(true);
-					typed_param.mData.mLastParamVersion = typed_param.BaseBlock::getLastChangeVersion();
+					typed_param.mData.clearKey();
+					typed_param.mData.mValueAge = NEWER_THAN_BLOCK;
+					typed_param.setBlockFromValue();
+
 					return true;
 				}
 
@@ -1628,7 +1641,9 @@ namespace LLInitParam
 							typed_param.mData.setKey(name);
 							typed_param.enclosingBlock().setLastChangedParam(param, true);
 							typed_param.setProvided(true);
-							typed_param.mData.mLastParamVersion = typed_param.BaseBlock::getLastChangeVersion();
+							typed_param.mData.mValueAge = NEWER_THAN_BLOCK;
+							typed_param.setBlockFromValue();
+
 							return true;
 						}
 					}
@@ -1703,16 +1718,18 @@ namespace LLInitParam
 
 		bool isProvided() const 
 		{
-			// either param value provided directly or block is sufficiently filled in
+			if (!Param::getProvided()) return false;
+
+			// block has an updated parameter
 			// if cached value is stale, regenerate from params
-			if (Param::getProvided() && mData.mLastParamVersion < BaseBlock::getLastChangeVersion())
+			if (mData.mValueAge == OLDER_THAN_BLOCK)
 			{
 				if (block_t::validateBlock(false))
 				{
 					static_cast<const DERIVED*>(this)->setValueFromBlock();
 					// clear stale keyword associated with old value
 					mData.clearKey();
-					mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
+					mData.mValueAge = SAME_AS_BLOCK;
 					return true;
 				}
 				else
@@ -1722,8 +1739,11 @@ namespace LLInitParam
 					return false;  
 				}
 			}
-			// either no data provided, or we have a valid value in hand
-			return Param::getProvided();
+			else
+			{
+				// we have a valid value in hand
+				return true;
+			}
 		}
 
 		void set(value_assignment_t val, bool flag_as_provided = true)
@@ -1731,7 +1751,7 @@ namespace LLInitParam
 			Param::enclosingBlock().setLastChangedParam(*this, flag_as_provided);
 			
 			// set param version number to be up to date, so we ignore block contents
-			mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
+			mData.mValueAge = NEWER_THAN_BLOCK;
 
 			mData.mValue = val;
 			mData.clearKey();
@@ -1756,6 +1776,8 @@ namespace LLInitParam
 			if (user_provided)
 			{
 				setProvided(true);  // some component provided
+				// a parameter changed, so our value is out of date
+				mData.mValueAge = OLDER_THAN_BLOCK;
 			}
 		}
 
@@ -1763,54 +1785,54 @@ namespace LLInitParam
 		value_assignment_t get() const
 		{
 			// if some parameters were provided, issue warnings on invalid blocks
-			if (Param::getProvided() && (mData.mLastParamVersion < BaseBlock::getLastChangeVersion()))
+			if (Param::getProvided() && (mData.mValueAge == OLDER_THAN_BLOCK))
 			{
 				// go ahead and issue warnings at this point if any param is invalid
 				if(block_t::validateBlock(true))
 				{
 					static_cast<const DERIVED*>(this)->setValueFromBlock();
 					mData.clearKey();
-					mData.mLastParamVersion = BaseBlock::getLastChangeVersion();
+					mData.mValueAge = SAME_AS_BLOCK;
 				}
 			}
 
 			return mData.mValue;
 		}
 
-		// mutable to allow lazy updates on get
+
 		struct Data : public key_cache_t
 		{
-			Data(const T& value) 
+			Data(const T& value, EValueAge age) 
 			:	mValue(value),
-				mLastParamVersion(0)
+				mValueAge(age)
 			{}
 
-			T		mValue;
-			S32		mLastParamVersion;
+			T			mValue;
+			EValueAge	mValueAge;
 		};
 
+		// mutable to allow lazy updates on get
 		mutable Data		mData;
 
 	private:
 		static bool mergeWith(Param& dst, const Param& src, bool overwrite)
 		{
-			const self_t& src_typed_param = static_cast<const self_t&>(src);
-			self_t& dst_typed_param = static_cast<self_t&>(dst);
+			const DERIVED& src_typed_param = static_cast<const DERIVED&>(src);
+			DERIVED& dst_typed_param = static_cast<DERIVED&>(dst);
 
 			if (src_typed_param.isProvided()
 				&& (overwrite || !dst_typed_param.isProvided()))
 			{
-				// assign individual parameters
-				dst_typed_param.BaseBlock::merge(block_t::blockDescriptor(), src_typed_param, overwrite);
-
-				// then copy actual value
-				dst_typed_param.mData.mValue = src_typed_param.get();
-				dst_typed_param.mData.clearKey();
-				dst_typed_param.setProvided(true);
-
-				// Propagate value back to block params since the value was updated during this merge.
-				// This will result in mData.mValue and the block params being in sync.
-				static_cast<DERIVED&>(dst_typed_param).setBlockFromValue();
+				if (src_typed_param.mData.mValueAge == NEWER_THAN_BLOCK)
+				{
+					// copy value over
+					dst_typed_param.set(src_typed_param.get());
+				}
+				else
+				{
+					// merge individual parameters into destination
+					dst_typed_param.merge(block_t::selfBlockDescriptor(), src_typed_param, overwrite);
+				}
 				return true;
 			}
 			return false;