diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
index afeac0a90542bb0fee81f01cef4adf91ac38ee51..53254c3b5661b6d3c99f6eb1f4deb5f6e39f90a1 100644
--- a/indra/llcommon/llinitparam.cpp
+++ b/indra/llcommon/llinitparam.cpp
@@ -188,12 +188,9 @@ namespace LLInitParam
 	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const LLInitParam::BaseBlock* diff_block) const
 	{
 		bool serialized = false;
-		if (!isProvided())
+		if (!predicate_rule.check(ll_make_predicate(PROVIDED, isProvided())))
 		{
-			if ((predicate_rule && !ll_predicate(PROVIDED)).isTriviallyFalse())
-			{
-				return false;
-			}
+			return false;
 		}
 		// named param is one like LLView::Params::follows
 		// unnamed param is like LLView::Params::rect - implicit
@@ -206,7 +203,7 @@ namespace LLInitParam
 			param_handle_t param_handle = (*it)->mParamHandle;
 			const Param* param = getParamFromHandle(param_handle);
 			ParamDescriptor::serialize_func_t serialize_func = (*it)->mSerializeFunc;
-			if (serialize_func && param->anyProvided())
+			if (serialize_func && predicate_rule.check(ll_make_predicate(PROVIDED, param->anyProvided())))
 			{
 				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
 				serialized |= serialize_func(*param, parser, name_stack, predicate_rule, diff_param);
@@ -220,7 +217,7 @@ namespace LLInitParam
 			param_handle_t param_handle = it->second->mParamHandle;
 			const Param* param = getParamFromHandle(param_handle);
 			ParamDescriptor::serialize_func_t serialize_func = it->second->mSerializeFunc;
-			if (serialize_func && param->anyProvided())
+			if (serialize_func && predicate_rule.check(ll_make_predicate(PROVIDED, param->anyProvided())))
 			{
 				// Ensure this param has not already been serialized
 				// Prevents <rect> from being serialized as its own tag.
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index b52ac809e0647fb32bdde14846b54ad0937c87d4..c82b1226ee4c5ab5fef560ad80b4d148f3edb2f4 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -545,7 +545,7 @@ namespace LLInitParam
 		}
 
 		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
-		bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t rule = predicate_rule_t(ll_predicate(PROVIDED) && ll_predicate(NON_DEFAULT)), const BaseBlock* diff_block = NULL) const;
+		bool serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const predicate_rule_t rule, 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(); }
diff --git a/indra/llcommon/llpredicate.h b/indra/llcommon/llpredicate.h
index a13172da68b079989a420361734ed1c95fbdc9a5..3f7abe67f17c00d610d545cec5d212e72645b2c2 100644
--- a/indra/llcommon/llpredicate.h
+++ b/indra/llcommon/llpredicate.h
@@ -42,8 +42,8 @@ namespace LLPredicate
 		typedef U32 predicate_flag_t;
 		static const S32 cMaxEnum = 5;
 
-		Value(ENUM e)
-		:	mPredicateFlags(cPredicateFlagsFromEnum[e])
+		Value(ENUM e, bool predicate_value = true)
+		:	mPredicateFlags(predicate_value ? cPredicateFlagsFromEnum[e] : ~cPredicateFlagsFromEnum[e])
 		{
 			llassert(0 <= e && e < cMaxEnum);
 		}
@@ -227,9 +227,9 @@ namespace LLPredicate
 }
 
 template<typename ENUM>
-LLPredicate::Value<ENUM> ll_predicate(ENUM e)
+LLPredicate::Value<ENUM> ll_make_predicate(ENUM e, bool predicate_value = true)
 {
-	 return LLPredicate::Value<ENUM>(e);
+	 return LLPredicate::Value<ENUM>(e, predicate_value);
 }
 
 
diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp
index 42ecc9897da54d52904cdeb127a4fa0f0f9982a9..c10e1b1e20e13cdcd988c0efc54dbb7f50839299 100644
--- a/indra/llcommon/llsdparam.cpp
+++ b/indra/llcommon/llsdparam.cpp
@@ -102,13 +102,13 @@ void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool
 	//readSDValues(sd, block);
 }
 
-void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
+void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block, LLInitParam::predicate_rule_t rules)
 {
 	mNameStack.clear();
 	mWriteRootSD = &sd;
 
 	name_stack_t name_stack;
-	block.serializeBlock(*this, name_stack);
+	block.serializeBlock(*this, name_stack, rules);
 }
 
 /*virtual*/ std::string LLParamSDParser::getCurrentElementName()
diff --git a/indra/llcommon/llsdparam.h b/indra/llcommon/llsdparam.h
index 6ef5debd7b74eddf82a4d961e5491faab62f7758..032e506fd8433cc73e82f50ef9a785bf8b4c1015 100644
--- a/indra/llcommon/llsdparam.h
+++ b/indra/llcommon/llsdparam.h
@@ -50,7 +50,7 @@ typedef LLInitParam::Parser parser_t;
 public:
 	LLParamSDParser();
 	void readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent = false);
-	void writeSD(LLSD& sd, const LLInitParam::BaseBlock& block);
+	void writeSD(LLSD& sd, const LLInitParam::BaseBlock& block, LLInitParam::predicate_rule_t rules = LLInitParam::predicate_rule_t(LLInitParam::PROVIDED) && LLInitParam::NON_DEFAULT);
 
 	/*virtual*/ std::string getCurrentElementName();
 
diff --git a/indra/llcommon/lltracerecording.cpp b/indra/llcommon/lltracerecording.cpp
index a2733fd0e7eab14f35c6976708ee2f62f9f7742e..a8e1a5eec964321f6baa27ea2f8def9e1b486737 100644
--- a/indra/llcommon/lltracerecording.cpp
+++ b/indra/llcommon/lltracerecording.cpp
@@ -347,7 +347,7 @@ PeriodicRecording& get_frame_recording()
 
 }
 
-void LLVCRControlsMixinCommon::start()
+void LLStopWatchControlsMixinCommon::start()
 {
 	switch (mPlayState)
 	{
@@ -365,7 +365,7 @@ void LLVCRControlsMixinCommon::start()
 	mPlayState = STARTED;
 }
 
-void LLVCRControlsMixinCommon::stop()
+void LLStopWatchControlsMixinCommon::stop()
 {
 	switch (mPlayState)
 	{
@@ -381,7 +381,7 @@ void LLVCRControlsMixinCommon::stop()
 	mPlayState = STOPPED;
 }
 
-void LLVCRControlsMixinCommon::pause()
+void LLStopWatchControlsMixinCommon::pause()
 {
 	switch (mPlayState)
 	{
@@ -396,7 +396,7 @@ void LLVCRControlsMixinCommon::pause()
 	mPlayState = PAUSED;
 }
 
-void LLVCRControlsMixinCommon::resume()
+void LLStopWatchControlsMixinCommon::resume()
 {
 	switch (mPlayState)
 	{
@@ -412,7 +412,7 @@ void LLVCRControlsMixinCommon::resume()
 	mPlayState = STARTED;
 }
 
-void LLVCRControlsMixinCommon::restart()
+void LLStopWatchControlsMixinCommon::restart()
 {
 	switch (mPlayState)
 	{
@@ -431,7 +431,7 @@ void LLVCRControlsMixinCommon::restart()
 	mPlayState = STARTED;
 }
 
-void LLVCRControlsMixinCommon::reset()
+void LLStopWatchControlsMixinCommon::reset()
 {
 	handleReset();
 }
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index a11f04b14bfccf66544dd98047f0011095657624..3a786c135736339d154848b152711e3e01999d4a 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -34,10 +34,10 @@
 #include "lltimer.h"
 #include "lltrace.h"
 
-class LL_COMMON_API LLVCRControlsMixinCommon
+class LL_COMMON_API LLStopWatchControlsMixinCommon
 {
 public:
-	virtual ~LLVCRControlsMixinCommon() {}
+	virtual ~LLStopWatchControlsMixinCommon() {}
 
 	enum EPlayState
 	{
@@ -59,7 +59,7 @@ class LL_COMMON_API LLVCRControlsMixinCommon
 	EPlayState getPlayState() { return mPlayState; }
 
 protected:
-	LLVCRControlsMixinCommon()
+	LLStopWatchControlsMixinCommon()
 	:	mPlayState(STOPPED)
 	{}
 
@@ -75,8 +75,8 @@ class LL_COMMON_API LLVCRControlsMixinCommon
 };
 
 template<typename DERIVED>
-class LLVCRControlsMixin
-:	public LLVCRControlsMixinCommon
+class LLStopWatchControlsMixin
+:	public LLStopWatchControlsMixinCommon
 {
 public:
 	void splitTo(DERIVED& other)
@@ -97,7 +97,7 @@ class LLVCRControlsMixin
 
 namespace LLTrace
 {
-	class LL_COMMON_API Recording : public LLVCRControlsMixin<Recording>
+	class LL_COMMON_API Recording : public LLStopWatchControlsMixin<Recording>
 	{
 	public:
 		Recording();
@@ -190,7 +190,7 @@ namespace LLTrace
 
 		LLUnit::Seconds<F64> getDuration() const { return mElapsedSeconds; }
 
-		// implementation for LLVCRControlsMixin
+		// implementation for LLStopWatchControlsMixin
 		/*virtual*/ void handleStart();
 		/*virtual*/ void handleStop();
 		/*virtual*/ void handleReset();
@@ -212,7 +212,7 @@ namespace LLTrace
 	};
 
 	class LL_COMMON_API PeriodicRecording
-	:	public LLVCRControlsMixin<PeriodicRecording>
+	:	public LLStopWatchControlsMixin<PeriodicRecording>
 	{
 	public:
 		PeriodicRecording(S32 num_periods);
@@ -340,7 +340,7 @@ namespace LLTrace
 
 	private:
 
-		// implementation for LLVCRControlsMixin
+		// implementation for LLStopWatchControlsMixin
 		/*virtual*/ void handleStart();
 		/*virtual*/ void handleStop();
 		/*virtual*/ void handleReset();
@@ -357,12 +357,12 @@ namespace LLTrace
 	PeriodicRecording& get_frame_recording();
 
 	class ExtendableRecording
-	:	public LLVCRControlsMixin<ExtendableRecording>
+	:	public LLStopWatchControlsMixin<ExtendableRecording>
 	{
 		void extend();
 
 	private:
-		// implementation for LLVCRControlsMixin
+		// implementation for LLStopWatchControlsMixin
 		/*virtual*/ void handleStart();
 		/*virtual*/ void handleStop();
 		/*virtual*/ void handleReset();
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index d14fe441fbe52dea336b7057852c41332fcdecfa..c4a5d1f05ebebadb8653a51e415cf1609309d41b 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -3085,7 +3085,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
 			parser.readXUI(node, output_params, LLUICtrlFactory::getInstance()->getCurFileName());
 			setupParamsForExport(output_params, parent);
 			output_node->setName(node->getName()->mString);
-			parser.writeXUI(output_node, output_params, &default_params);
+			parser.writeXUI(output_node, output_params, LLInitParam::predicate_rule_t(LLInitParam::PROVIDED) && LLInitParam::NON_DEFAULT, &default_params);
 			return TRUE;
 		}
 
@@ -3117,7 +3117,7 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
 		setupParamsForExport(output_params, parent);
         Params default_params(LLUICtrlFactory::getDefaultParams<LLFloater>());
 		output_node->setName(node->getName()->mString);
-		parser.writeXUI(output_node, output_params, &default_params);
+		parser.writeXUI(output_node, output_params, LLInitParam::predicate_rule_t(LLInitParam::PROVIDED) && LLInitParam::NON_DEFAULT, &default_params);
 	}
 
 	// Default floater position to top-left corner of screen
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 00318cec6b0b3043863eae2754ad9565b0ae1c38..f3d6687e4085b980c779ae66f27301728f20c73d 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -520,7 +520,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
 				Params output_params(params);
 				setupParamsForExport(output_params, parent);
 				output_node->setName(node->getName()->mString);
-				parser.writeXUI(output_node, output_params, &default_params);
+				parser.writeXUI(output_node, output_params, LLInitParam::predicate_rule_t(LLInitParam::PROVIDED) && LLInitParam::NON_DEFAULT, &default_params);
 				return TRUE;
 			}
 		
@@ -551,7 +551,7 @@ BOOL LLPanel::initPanelXML(LLXMLNodePtr node, LLView *parent, LLXMLNodePtr outpu
 			Params output_params(params);
 			setupParamsForExport(output_params, parent);
 			output_node->setName(node->getName()->mString);
-			parser.writeXUI(output_node, output_params, &default_params);
+			parser.writeXUI(output_node, output_params, LLInitParam::predicate_rule_t(LLInitParam::PROVIDED) && LLInitParam::NON_DEFAULT, &default_params);
 		}
 		
 		params.from_xui = true;
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 4e54354731e57fe76ef1afa9981cadc4e3ab4bc5..6513f97ca01e00ed80ae084db62fa01fa47b09d4 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -273,7 +273,7 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 			// Export only the differences between this any default params
 			typename T::Params default_params(getDefaultParams<T>());
 			copyName(node, output_node);
-			parser.writeXUI(output_node, output_params, &default_params);
+			parser.writeXUI(output_node, output_params, LLInitParam::predicate_rule_t(LLInitParam::PROVIDED) && LLInitParam::NON_DEFAULT, &default_params);
 		}
 
 		// Apply layout transformations, usually munging rect
diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
index 95cda92632947b64319cdecb0882aaa29c411f0b..6fc32dbf9c409c6c165728dee5fe7122841cee45 100644
--- a/indra/llui/llxuiparser.cpp
+++ b/indra/llui/llxuiparser.cpp
@@ -861,11 +861,11 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo
 	return any_parsed;
 }
 
-void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, const LLInitParam::BaseBlock* diff_block)
+void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &block, LLInitParam::predicate_rule_t rules, const LLInitParam::BaseBlock* diff_block)
 {
 	mWriteRootNode = node;
 	name_stack_t name_stack = Parser::name_stack_t();
-	block.serializeBlock(*this, name_stack, LLPredicate::Rule<LLInitParam::ESerializePredicates>(), diff_block);
+	block.serializeBlock(*this, name_stack, rules, diff_block);
 	mOutNodes.clear();
 }
 
diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h
index d7cd25696723dd11a104c4435dd9067a5d84bbab..9b6b2a321b28bbd2886690ebbd303d52d6b1a6a0 100644
--- a/indra/llui/llxuiparser.h
+++ b/indra/llui/llxuiparser.h
@@ -109,7 +109,7 @@ LOG_CLASS(LLXUIParser);
 	/*virtual*/ void parserError(const std::string& message);
 
 	void readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename = LLStringUtil::null, bool silent=false);
-	void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL);
+	void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, LLInitParam::predicate_rule_t rules = LLInitParam::predicate_rule_t(LLInitParam::PROVIDED) && LLInitParam::NON_DEFAULT, const LLInitParam::BaseBlock* diff_block = NULL);
 
 private:
 	bool readXUIImpl(LLXMLNodePtr node, LLInitParam::BaseBlock& block);
diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp
index fc5cd781e64cbf5e775409bc76aaada50439b7ec..26a76eda2c551844d0f8a242df76094fe5195266 100755
--- a/indra/newview/tests/llviewerassetstats_test.cpp
+++ b/indra/newview/tests/llviewerassetstats_test.cpp
@@ -266,6 +266,7 @@ namespace tut
 		ensure("Global gViewerAssetStats should still be NULL", (NULL == gViewerAssetStats));
 
 		LLSD sd_full = it->asLLSD(false);
+		llinfos << ll_pretty_print_sd(sd_full) << llendl;
 
 		// Default (NULL) region ID doesn't produce LLSD results so should
 		// get an empty map back from output