diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
index b4dcf3493ca01a83f65109504a79d4c8006294ac..69f97e87c4b7d48d903c777f6ccd2c3d4a0cd9de 100644
--- a/indra/llcommon/llinitparam.cpp
+++ b/indra/llcommon/llinitparam.cpp
@@ -185,7 +185,7 @@ namespace LLInitParam
 		return mValidated;
 	}
 
-	bool BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t& name_stack, const LLInitParam::BaseBlock* diff_block) const
+	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())
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index d3a0438d93c1082bc3a9f705b40c7e36f7c563f2..a3a5b3dc372f6c376a85d7cc82b6b0933df26b73 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -914,14 +914,15 @@ namespace LLInitParam
 			LLPredicate::Value<ESerializePredicates> predicate;
 			if (!diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()))
 			{
-				predicate.set(NON_DEFAULT);
+				predicate.add(NON_DEFAULT);
 			}
+			predicate.unknown(REQUIRED);
 			if (typed_param.isValid())
 			{
-				predicate.set(VALID);
+				predicate.add(VALID);
 				if (typed_param.anyProvided())
 				{
-					predicate.set(PROVIDED);
+					predicate.add(PROVIDED);
 				}
 			}
 
@@ -1071,19 +1072,17 @@ namespace LLInitParam
 		static bool serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const predicate_rule_t predicate_rule, const Param* diff_param)
 		{
 			const self_t& typed_param = static_cast<const self_t&>(param);
-			const self_t* diff_typed_param = static_cast<const self_t*>(diff_param);
 
 			LLPredicate::Value<ESerializePredicates> predicate;
-			if (!diff_typed_param || ParamCompare<T>::equals(typed_param.getValue(), diff_typed_param->getValue()))
-			{
-				predicate.set(NON_DEFAULT);
-			}
+			predicate.unknown(NON_DEFAULT);
+			predicate.unknown(REQUIRED);
+
 			if (typed_param.isValid())
 			{
-				predicate.set(VALID);
+				predicate.add(VALID);
 				if (typed_param.anyProvided())
 				{
-					predicate.set(PROVIDED);
+					predicate.add(PROVIDED);
 				}
 			}
 
@@ -1271,7 +1270,29 @@ namespace LLInitParam
 		{
 			bool serialized = false;
 			const self_t& typed_param = static_cast<const self_t&>(param);
-			if (!typed_param.isProvided()) return false;
+			
+			LLPredicate::Value<ESerializePredicates> predicate;
+			predicate.unknown(NON_DEFAULT);
+
+			if (typed_param.mMinCount > 0)
+			{
+				predicate.add(REQUIRED);
+			}
+			else
+			{
+				predicate.unknown(REQUIRED);
+			}
+
+			if (typed_param.isValid())
+			{
+				predicate.add(VALID);
+				if (typed_param.anyProvided())
+				{
+					predicate.add(PROVIDED);
+				}
+			}
+
+			if (!predicate_rule.check(predicate)) return false;
 
 			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
 				it != end_it;
@@ -1516,10 +1537,28 @@ namespace LLInitParam
 			bool serialized = false;
 			const self_t& typed_param = static_cast<const self_t&>(param);
 
-			LLPredicate::Value<ESerializePredicates> predicate_value;
-			if (typed_param.isProvided()) predicate_value.set(PROVIDED);
-			
-			if (!typed_param.isProvided()) return false;
+			LLPredicate::Value<ESerializePredicates> predicate;
+			predicate.unknown(NON_DEFAULT);
+
+			if (typed_param.mMinCount > 0)
+			{
+				predicate.add(REQUIRED);
+			}
+			else
+			{
+				predicate.unknown(REQUIRED);
+			}
+
+			if (typed_param.isValid())
+			{
+				predicate.add(VALID);
+				if (typed_param.anyProvided())
+				{
+					predicate.add(PROVIDED);
+				}
+			}
+
+			if (!predicate_rule.check(predicate)) return false;
 
 			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
 				it != end_it;
diff --git a/indra/llcommon/llpredicate.h b/indra/llcommon/llpredicate.h
index ad5ab363fa93fa6d36b66c1d8efb478ee30c0364..35ef22138c9d2bf5c2b5b018de84c7f179cb287d 100644
--- a/indra/llcommon/llpredicate.h
+++ b/indra/llcommon/llpredicate.h
@@ -42,34 +42,28 @@ namespace LLPredicate
 		:	mPredicateFlags(0x1),
 			mPredicateCombinationFlags(0x1)
 		{
-			set(e);
+			add(e);
 		}
 
 		Value()
-			:	mPredicateFlags(0x1),
+		:	mPredicateFlags(0x1),
 			mPredicateCombinationFlags(0x1)
 		{}
 
-		void set(ENUM predicate)
+		void add(ENUM predicate)
 		{
-			llassert(predicate <= 5);
-			int predicate_flag = 0x1 << (0x1 << (int)predicate);
-			if (!(mPredicateFlags & predicate_flag))
+			llassert(predicate < 5);
+			if (!has(predicate))
 			{
+				int predicate_flag = 0x1 << (0x1 << (int)predicate);
 				mPredicateCombinationFlags *= predicate_flag;
 				mPredicateFlags |= predicate_flag;
 			}
 		}
 
-		bool get(ENUM predicate)
-		{
-			int predicate_flag = 0x1 << (0x1 << (int)predicate);
-			return (mPredicateFlags & predicate_flag) != 0;
-		}
-
-		void clear(ENUM predicate)
+		void remove(ENUM predicate)
 		{
-			llassert(predicate <= 5);
+			llassert(predicate < 5);
 			int predicate_flag = 0x1 << (0x1 << (int)predicate);
 			if (mPredicateFlags & predicate_flag)
 			{
@@ -78,6 +72,19 @@ namespace LLPredicate
 			}
 		}
 
+		void unknown(ENUM predicate)
+		{
+			add(predicate);
+			int predicate_shift = 0x1 << (int)predicate;
+			mPredicateCombinationFlags |= mPredicateCombinationFlags << predicate_shift;
+		}
+
+		bool has(ENUM predicate)
+		{
+			int predicate_flag = 0x1 << (0x1 << (int)predicate);
+			return (mPredicateFlags & predicate_flag) != 0;
+		}
+
 	private:
 		int mPredicateCombinationFlags;
 		int mPredicateFlags;
@@ -89,16 +96,12 @@ namespace LLPredicate
 	class Rule
 	{
 	public:
-		Rule(EmptyRule e)
-			:	mPredicateRequirements(0x1)
-		{}
-
 		Rule(ENUM value)
-			:	mPredicateRequirements(predicateFromValue(value))
+		:	mPredicateRequirements(predicateFromValue(value))
 		{}
 
 		Rule()
-			:	mPredicateRequirements(0x1)
+		:	mPredicateRequirements(0x1)
 		{}
 
 		Rule operator~()
@@ -129,25 +132,16 @@ namespace LLPredicate
 
 		static int predicateFromValue(ENUM value)
 		{
-			int countdown = value;
-			bool bit_val = false;
-
-			int predicate = 0x0;
-
-			for (int bit_index = 0; bit_index < 32; bit_index++)
+			llassert(value < 5);
+			static const int predicates[5] = 
 			{
-				if (bit_val)
-				{
-					predicate |= 0x1 << bit_index;
-				}
-
-				if (countdown-- == 0)
-				{
-					countdown = value;
-					bit_val = !bit_val;
-				}
-			}
-			return predicate;
+				0xAAAAaaaa, //  10101010101010101010101010101010
+				0xCCCCcccc, //  11001100110011001100110011001100
+				0xF0F0F0F0, //  11110000111100001111000011110000
+				0xFF00FF00, //  11111111000000001111111100000000
+				0xFFFF0000  //  11111111111111110000000000000000 
+			};
+			return predicates[value];
 		}
 
 		bool isTriviallyTrue() const
@@ -167,6 +161,7 @@ namespace LLPredicate
 	template<typename ENUM>
 	Rule<ENUM> make_rule(ENUM e) { return Rule<ENUM>(e);}
 
+	// return generic empty rule class to avoid requiring template argument to create an empty rule
 	EmptyRule make_rule();
 
 }
diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
index afc76024d1e0ef0f8688b8de638cbe52c29843e2..179a1184af0c1c53fe7b70641c603ee37c5bd9e9 100644
--- a/indra/llui/llxuiparser.cpp
+++ b/indra/llui/llxuiparser.cpp
@@ -865,7 +865,7 @@ void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &bloc
 {
 	mWriteRootNode = node;
 	name_stack_t name_stack = Parser::name_stack_t();
-	block.serializeBlock(*this, name_stack, diff_block);
+	block.serializeBlock(*this, name_stack, LLPredicate::Rule<LLInitParam::ESerializePredicates>(), diff_block);
 	mOutNodes.clear();
 }