diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 4bb45a3065fc7c745f3579e737219514e59d7612..7d37127584901977c4271661c3304f7612fb501e 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -43,33 +43,16 @@ LLParamSDParser::LLParamSDParser()
 {
 	using boost::bind;
 
-	registerParserFuncs<S32>(bind(&LLParamSDParser::readTypedValue<S32>, this, _1, &LLSD::asInteger),
-							bind(&LLParamSDParser::writeTypedValue<S32>, this, _1, _2));
-	registerParserFuncs<U32>(bind(&LLParamSDParser::readTypedValue<U32>, this, _1, &LLSD::asInteger),
-							bind(&LLParamSDParser::writeU32Param, this, _1, _2));
-	registerParserFuncs<F32>(bind(&LLParamSDParser::readTypedValue<F32>, this, _1, &LLSD::asReal),
-							bind(&LLParamSDParser::writeTypedValue<F32>, this, _1, _2));
-	registerParserFuncs<F64>(bind(&LLParamSDParser::readTypedValue<F64>, this, _1, &LLSD::asReal),
-							bind(&LLParamSDParser::writeTypedValue<F64>, this, _1, _2));
-	registerParserFuncs<bool>(bind(&LLParamSDParser::readTypedValue<F32>, this, _1, &LLSD::asBoolean),
-							bind(&LLParamSDParser::writeTypedValue<F32>, this, _1, _2));
-	registerParserFuncs<std::string>(bind(&LLParamSDParser::readTypedValue<std::string>, this, _1, &LLSD::asString),
-							bind(&LLParamSDParser::writeTypedValue<std::string>, this, _1, _2));
-	registerParserFuncs<LLUUID>(bind(&LLParamSDParser::readTypedValue<LLUUID>, this, _1, &LLSD::asUUID),
-							bind(&LLParamSDParser::writeTypedValue<LLUUID>, this, _1, _2));
-	registerParserFuncs<LLDate>(bind(&LLParamSDParser::readTypedValue<LLDate>, this, _1, &LLSD::asDate),
-							bind(&LLParamSDParser::writeTypedValue<LLDate>, this, _1, _2));
-	registerParserFuncs<LLURI>(bind(&LLParamSDParser::readTypedValue<LLURI>, this, _1, &LLSD::asURI),
-							bind(&LLParamSDParser::writeTypedValue<LLURI>, this, _1, _2));
-	registerParserFuncs<LLSD>(bind(&LLParamSDParser::readSDParam, this, _1),
-							bind(&LLParamSDParser::writeTypedValue<LLSD>, this, _1, _2));
-}
-
-bool LLParamSDParser::readSDParam(void* value_ptr)
-{
-	if (!mCurReadSD) return false;
-	*((LLSD*)value_ptr) = *mCurReadSD;
-	return true;
+	registerParserFuncs<S32>(readS32, bind(&LLParamSDParser::writeTypedValue<S32>, this, _1, _2));
+	registerParserFuncs<U32>(readU32, bind(&LLParamSDParser::writeU32Param, this, _1, _2));
+	registerParserFuncs<F32>(readF32, bind(&LLParamSDParser::writeTypedValue<F32>, this, _1, _2));
+	registerParserFuncs<F64>(readF64, bind(&LLParamSDParser::writeTypedValue<F64>, this, _1, _2));
+	registerParserFuncs<bool>(readBool, bind(&LLParamSDParser::writeTypedValue<F32>, this, _1, _2));
+	registerParserFuncs<std::string>(readString, bind(&LLParamSDParser::writeTypedValue<std::string>, this, _1, _2));
+	registerParserFuncs<LLUUID>(readUUID, bind(&LLParamSDParser::writeTypedValue<LLUUID>, this, _1, _2));
+	registerParserFuncs<LLDate>(readDate, bind(&LLParamSDParser::writeTypedValue<LLDate>, this, _1, _2));
+	registerParserFuncs<LLURI>(readURI, bind(&LLParamSDParser::writeTypedValue<LLURI>, this, _1, _2));
+	registerParserFuncs<LLSD>(readSD, bind(&LLParamSDParser::writeTypedValue<LLSD>, this, _1, _2));
 }
 
 // special case handling of U32 due to ambiguous LLSD::assign overload
@@ -148,3 +131,82 @@ LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack)
 	return mWriteSD;
 }
 
+bool LLParamSDParser::readS32(Parser& parser, void* val_ptr)
+{
+	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+    *((S32*)val_ptr) = self.mCurReadSD->asInteger();
+    return true;
+}
+
+bool LLParamSDParser::readU32(Parser& parser, void* val_ptr)
+{
+	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+    *((U32*)val_ptr) = self.mCurReadSD->asInteger();
+    return true;
+}
+
+bool LLParamSDParser::readF32(Parser& parser, void* val_ptr)
+{
+	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+    *((F32*)val_ptr) = self.mCurReadSD->asReal();
+    return true;
+}
+
+bool LLParamSDParser::readF64(Parser& parser, void* val_ptr)
+{
+	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+    *((F64*)val_ptr) = self.mCurReadSD->asReal();
+    return true;
+}
+
+bool LLParamSDParser::readBool(Parser& parser, void* val_ptr)
+{
+	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+    *((bool*)val_ptr) = self.mCurReadSD->asBoolean();
+    return true;
+}
+
+bool LLParamSDParser::readString(Parser& parser, void* val_ptr)
+{
+	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+	*((std::string*)val_ptr) = self.mCurReadSD->asString();
+    return true;
+}
+
+bool LLParamSDParser::readUUID(Parser& parser, void* val_ptr)
+{
+	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+	*((LLUUID*)val_ptr) = self.mCurReadSD->asUUID();
+    return true;
+}
+
+bool LLParamSDParser::readDate(Parser& parser, void* val_ptr)
+{
+	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+	*((LLDate*)val_ptr) = self.mCurReadSD->asDate();
+    return true;
+}
+
+bool LLParamSDParser::readURI(Parser& parser, void* val_ptr)
+{
+	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+	*((LLURI*)val_ptr) = self.mCurReadSD->asURI();
+    return true;
+}
+
+bool LLParamSDParser::readSD(Parser& parser, void* val_ptr)
+{
+	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+
+	*((LLSD*)val_ptr) = *self.mCurReadSD;
+    return true;
+}
diff --git a/indra/llui/llsdparam.h b/indra/llui/llsdparam.h
index 12f28f876faa980bd12e9f475e72714130f6be1c..71b0a4563005dded1355fed1c91daa883e6288bf 100644
--- a/indra/llui/llsdparam.h
+++ b/indra/llui/llsdparam.h
@@ -79,9 +79,19 @@ typedef LLInitParam::Parser parser_t;
 
 	LLSD* getSDWriteNode(const parser_t::name_stack_t& name_stack);
 
-	bool readSDParam(void* value_ptr);
 	bool writeU32Param(const void* value_ptr, const parser_t::name_stack_t& name_stack);
 
+	static bool readS32(Parser& parser, void* val_ptr);
+	static bool readU32(Parser& parser, void* val_ptr);
+	static bool readF32(Parser& parser, void* val_ptr);
+	static bool readF64(Parser& parser, void* val_ptr);
+	static bool readBool(Parser& parser, void* val_ptr);
+	static bool readString(Parser& parser, void* val_ptr);
+	static bool readUUID(Parser& parser, void* val_ptr);
+	static bool readDate(Parser& parser, void* val_ptr);
+	static bool readURI(Parser& parser, void* val_ptr);
+	static bool readSD(Parser& parser, void* val_ptr);
+
 	Parser::name_stack_t	mNameStack;
 	const LLSD*				mCurReadSD;
 	LLSD*					mWriteSD;
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index a46d961709f9f98d41b2b6e18d07ee3ad7fe9501..6ad104c1f4287a9407fadc9bb9c395d2dfd44f0d 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -99,10 +99,11 @@ void LLUICtrlFactory::loadWidgetTemplate(const std::string& widget_tag, LLInitPa
 	std::string filename = std::string("widgets") + gDirUtilp->getDirDelimiter() + widget_tag + ".xml";
 	LLXMLNodePtr root_node;
 
-	if (LLUICtrlFactory::getLayeredXMLNode(filename, root_node))
+	std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), filename);
+	if (!full_filename.empty())
 	{
-		LLUICtrlFactory::instance().pushFileName(filename);
-		LLXUIParser::instance().readXUI(root_node, block, filename);
+		LLUICtrlFactory::instance().pushFileName(full_filename);
+		LLFastXUIParser::instance().readXUI(full_filename, block);
 		LLUICtrlFactory::instance().popFileName();
 	}
 }
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index b645c4be7c80636926848906bcec52c9cfa8698c..1cc7d06b73e32c0b2b46cbf4fd8e4bbdb794b706 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -40,6 +40,7 @@ f * @file llinitparam.h
 #include <boost/function.hpp>
 #include <boost/bind.hpp>
 #include <boost/type_traits/is_convertible.hpp>
+#include <boost/unordered_map.hpp>
 #include "llregistry.h"
 #include "llmemory.h"
 
@@ -202,13 +203,13 @@ namespace LLInitParam
 		typedef std::pair<name_stack_t::const_iterator, name_stack_t::const_iterator>	name_stack_range_t;
 		typedef std::vector<std::string>							possible_values_t;
 
-		typedef boost::function<bool (void*)>															parser_read_func_t;
+		typedef bool (*parser_read_func_t)(Parser& parser, void* output);
 		typedef boost::function<bool (const void*, const name_stack_t&)>								parser_write_func_t;
 		typedef boost::function<void (const name_stack_t&, S32, S32, const possible_values_t*)>	parser_inspect_func_t;
 
-		typedef std::map<const std::type_info*, parser_read_func_t, CompareTypeID>		parser_read_func_map_t;
-		typedef std::map<const std::type_info*, parser_write_func_t, CompareTypeID>		parser_write_func_map_t;
-		typedef std::map<const std::type_info*, parser_inspect_func_t, CompareTypeID>	parser_inspect_func_map_t;
+		typedef boost::unordered_map<const void*, parser_read_func_t>		parser_read_func_map_t;
+		typedef boost::unordered_map<const void*, parser_write_func_t>		parser_write_func_map_t;
+		typedef boost::unordered_map<const void*, parser_inspect_func_t>	parser_inspect_func_map_t;
 
 		Parser()
 		:	mParseSilently(false),
@@ -221,7 +222,7 @@ namespace LLInitParam
 		    parser_read_func_map_t::iterator found_it = mParserReadFuncs.find(&typeid(T));
 		    if (found_it != mParserReadFuncs.end())
 		    {
-			    return found_it->second((void*)&param);
+			    return found_it->second(*this, (void*)&param);
 		    }
 		    return false;
 	    }
@@ -386,7 +387,7 @@ namespace LLInitParam
 		void aggregateBlockData(BlockDescriptor& src_block_data);
 
 	public:
-		typedef std::map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams
+		typedef boost::unordered_map<const std::string, ParamDescriptor*> param_map_t; // references param descriptors stored in mAllParams
 		typedef std::vector<ParamDescriptor*> param_list_t; 
 
 		typedef std::list<ParamDescriptor> all_params_list_t;// references param descriptors stored in mAllParams
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index dbc20a5a1e2f79f0d487914776021ad8b9300cc1..00128c978a8357970ee5c5a0726f85bacf08bbde 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -35,11 +35,16 @@
 #include "llxuiparser.h"
 
 #include "llxmlnode.h"
+#include "expat/expat.h"
 #include <fstream>
 #include <boost/tokenizer.hpp>
+//#include <boost/spirit/include/qi.hpp>
+#include <boost/spirit/include/classic_core.hpp>
 
 #include "lluicolor.h"
 
+using namespace BOOST_SPIRIT_CLASSIC_NS;
+
 const S32 MAX_STRING_ATTRIBUTE_SIZE = 40;
 
 //
@@ -370,34 +375,20 @@ LLXUIParser::LLXUIParser()
 :	mLastWriteGeneration(-1),
 	mCurReadDepth(0)
 {
-	registerParserFuncs<bool>(boost::bind(&LLXUIParser::readBoolValue, this, _1),
-								boost::bind(&LLXUIParser::writeBoolValue, this, _1, _2));
-	registerParserFuncs<std::string>(boost::bind(&LLXUIParser::readStringValue, this, _1),
-								boost::bind(&LLXUIParser::writeStringValue, this, _1, _2));
-	registerParserFuncs<U8>(boost::bind(&LLXUIParser::readU8Value, this, _1),
-								boost::bind(&LLXUIParser::writeU8Value, this, _1, _2));
-	registerParserFuncs<S8>(boost::bind(&LLXUIParser::readS8Value, this, _1),
-								boost::bind(&LLXUIParser::writeS8Value, this, _1, _2));
-	registerParserFuncs<U16>(boost::bind(&LLXUIParser::readU16Value, this, _1),
-								boost::bind(&LLXUIParser::writeU16Value, this, _1, _2));
-	registerParserFuncs<S16>(boost::bind(&LLXUIParser::readS16Value, this, _1),
-								boost::bind(&LLXUIParser::writeS16Value, this, _1, _2));
-	registerParserFuncs<U32>(boost::bind(&LLXUIParser::readU32Value, this, _1),
-								boost::bind(&LLXUIParser::writeU32Value, this, _1, _2));
-	registerParserFuncs<S32>(boost::bind(&LLXUIParser::readS32Value, this, _1),
-								boost::bind(&LLXUIParser::writeS32Value, this, _1, _2));
-	registerParserFuncs<F32>(boost::bind(&LLXUIParser::readF32Value, this, _1),
-								boost::bind(&LLXUIParser::writeF32Value, this, _1, _2));
-	registerParserFuncs<F64>(boost::bind(&LLXUIParser::readF64Value, this, _1),
-								boost::bind(&LLXUIParser::writeF64Value, this, _1, _2));
-	registerParserFuncs<LLColor4>(boost::bind(&LLXUIParser::readColor4Value, this, _1),
-								boost::bind(&LLXUIParser::writeColor4Value, this, _1, _2));
-	registerParserFuncs<LLUIColor>(boost::bind(&LLXUIParser::readUIColorValue, this, _1),
-								boost::bind(&LLXUIParser::writeUIColorValue, this, _1, _2));
-	registerParserFuncs<LLUUID>(boost::bind(&LLXUIParser::readUUIDValue, this, _1),
-								boost::bind(&LLXUIParser::writeUUIDValue, this, _1, _2));
-	registerParserFuncs<LLSD>(boost::bind(&LLXUIParser::readSDValue, this, _1),
-								boost::bind(&LLXUIParser::writeSDValue, this, _1, _2));
+	registerParserFuncs<bool>(readBoolValue, boost::bind(&LLXUIParser::writeBoolValue, this, _1, _2));
+	registerParserFuncs<std::string>(readStringValue, boost::bind(&LLXUIParser::writeStringValue, this, _1, _2));
+	registerParserFuncs<U8>(readU8Value, boost::bind(&LLXUIParser::writeU8Value, this, _1, _2));
+	registerParserFuncs<S8>(readS8Value, boost::bind(&LLXUIParser::writeS8Value, this, _1, _2));
+	registerParserFuncs<U16>(readU16Value, boost::bind(&LLXUIParser::writeU16Value, this, _1, _2));
+	registerParserFuncs<S16>(readS16Value, boost::bind(&LLXUIParser::writeS16Value, this, _1, _2));
+	registerParserFuncs<U32>(readU32Value, boost::bind(&LLXUIParser::writeU32Value, this, _1, _2));
+	registerParserFuncs<S32>(readS32Value, boost::bind(&LLXUIParser::writeS32Value, this, _1, _2));
+	registerParserFuncs<F32>(readF32Value, boost::bind(&LLXUIParser::writeF32Value, this, _1, _2));
+	registerParserFuncs<F64>(readF64Value, boost::bind(&LLXUIParser::writeF64Value, this, _1, _2));
+	registerParserFuncs<LLColor4>(readColor4Value, boost::bind(&LLXUIParser::writeColor4Value, this, _1, _2));
+	registerParserFuncs<LLUIColor>(readUIColorValue, boost::bind(&LLXUIParser::writeUIColorValue, this, _1, _2));
+	registerParserFuncs<LLUUID>(readUUIDValue, boost::bind(&LLXUIParser::writeUUIDValue, this, _1, _2));
+	registerParserFuncs<LLSD>(readSDValue, boost::bind(&LLXUIParser::writeSDValue, this, _1, _2));
 }
 
 static LLFastTimer::DeclareTimer FTM_PARSE_XUI("XUI Parsing");
@@ -621,10 +612,11 @@ LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack)
 }
 
 
-bool LLXUIParser::readBoolValue(void* val_ptr)
+bool LLXUIParser::readBoolValue(Parser& parser, void* val_ptr)
 {
 	S32 value;
-	bool success = mCurReadNode->getBoolValue(1, &value);
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	bool success = self.mCurReadNode->getBoolValue(1, &value);
 	*((bool*)val_ptr) = (value != FALSE);
 	return success;
 }
@@ -640,9 +632,10 @@ bool LLXUIParser::writeBoolValue(const void* val_ptr, const name_stack_t& stack)
 	return false;
 }
 
-bool LLXUIParser::readStringValue(void* val_ptr)
+bool LLXUIParser::readStringValue(Parser& parser, void* val_ptr)
 {
-	*((std::string*)val_ptr) = mCurReadNode->getSanitizedValue();
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	*((std::string*)val_ptr) = self.mCurReadNode->getSanitizedValue();
 	return true;
 }
 
@@ -677,9 +670,10 @@ bool LLXUIParser::writeStringValue(const void* val_ptr, const name_stack_t& stac
 	return false;
 }
 
-bool LLXUIParser::readU8Value(void* val_ptr)
+bool LLXUIParser::readU8Value(Parser& parser, void* val_ptr)
 {
-	return mCurReadNode->getByteValue(1, (U8*)val_ptr);
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	return self.mCurReadNode->getByteValue(1, (U8*)val_ptr);
 }
 
 bool LLXUIParser::writeU8Value(const void* val_ptr, const name_stack_t& stack)
@@ -693,10 +687,11 @@ bool LLXUIParser::writeU8Value(const void* val_ptr, const name_stack_t& stack)
 	return false;
 }
 
-bool LLXUIParser::readS8Value(void* val_ptr)
+bool LLXUIParser::readS8Value(Parser& parser, void* val_ptr)
 {
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	S32 value;
-	if(mCurReadNode->getIntValue(1, &value))
+	if(self.mCurReadNode->getIntValue(1, &value))
 	{
 		*((S8*)val_ptr) = value;
 		return true;
@@ -715,10 +710,11 @@ bool LLXUIParser::writeS8Value(const void* val_ptr, const name_stack_t& stack)
 	return false;
 }
 
-bool LLXUIParser::readU16Value(void* val_ptr)
+bool LLXUIParser::readU16Value(Parser& parser, void* val_ptr)
 {
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	U32 value;
-	if(mCurReadNode->getUnsignedValue(1, &value))
+	if(self.mCurReadNode->getUnsignedValue(1, &value))
 	{
 		*((U16*)val_ptr) = value;
 		return true;
@@ -737,10 +733,11 @@ bool LLXUIParser::writeU16Value(const void* val_ptr, const name_stack_t& stack)
 	return false;
 }
 
-bool LLXUIParser::readS16Value(void* val_ptr)
+bool LLXUIParser::readS16Value(Parser& parser, void* val_ptr)
 {
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	S32 value;
-	if(mCurReadNode->getIntValue(1, &value))
+	if(self.mCurReadNode->getIntValue(1, &value))
 	{
 		*((S16*)val_ptr) = value;
 		return true;
@@ -759,9 +756,10 @@ bool LLXUIParser::writeS16Value(const void* val_ptr, const name_stack_t& stack)
 	return false;
 }
 
-bool LLXUIParser::readU32Value(void* val_ptr)
+bool LLXUIParser::readU32Value(Parser& parser, void* val_ptr)
 {
-	return mCurReadNode->getUnsignedValue(1, (U32*)val_ptr);
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	return self.mCurReadNode->getUnsignedValue(1, (U32*)val_ptr);
 }
 
 bool LLXUIParser::writeU32Value(const void* val_ptr, const name_stack_t& stack)
@@ -775,9 +773,10 @@ bool LLXUIParser::writeU32Value(const void* val_ptr, const name_stack_t& stack)
 	return false;
 }
 
-bool LLXUIParser::readS32Value(void* val_ptr)
+bool LLXUIParser::readS32Value(Parser& parser, void* val_ptr)
 {
-	return mCurReadNode->getIntValue(1, (S32*)val_ptr);
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	return self.mCurReadNode->getIntValue(1, (S32*)val_ptr);
 }
 
 bool LLXUIParser::writeS32Value(const void* val_ptr, const name_stack_t& stack)
@@ -791,9 +790,10 @@ bool LLXUIParser::writeS32Value(const void* val_ptr, const name_stack_t& stack)
 	return false;
 }
 
-bool LLXUIParser::readF32Value(void* val_ptr)
+bool LLXUIParser::readF32Value(Parser& parser, void* val_ptr)
 {
-	return mCurReadNode->getFloatValue(1, (F32*)val_ptr);
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	return self.mCurReadNode->getFloatValue(1, (F32*)val_ptr);
 }
 
 bool LLXUIParser::writeF32Value(const void* val_ptr, const name_stack_t& stack)
@@ -807,9 +807,10 @@ bool LLXUIParser::writeF32Value(const void* val_ptr, const name_stack_t& stack)
 	return false;
 }
 
-bool LLXUIParser::readF64Value(void* val_ptr)
+bool LLXUIParser::readF64Value(Parser& parser, void* val_ptr)
 {
-	return mCurReadNode->getDoubleValue(1, (F64*)val_ptr);
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	return self.mCurReadNode->getDoubleValue(1, (F64*)val_ptr);
 }
 
 bool LLXUIParser::writeF64Value(const void* val_ptr, const name_stack_t& stack)
@@ -823,10 +824,11 @@ bool LLXUIParser::writeF64Value(const void* val_ptr, const name_stack_t& stack)
 	return false;
 }
 
-bool LLXUIParser::readColor4Value(void* val_ptr)
+bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr)
 {
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLColor4* colorp = (LLColor4*)val_ptr;
-	if(mCurReadNode->getFloatValue(4, colorp->mV) >= 3)
+	if(self.mCurReadNode->getFloatValue(4, colorp->mV) >= 3)
 	{
 		return true;
 	}
@@ -846,11 +848,12 @@ bool LLXUIParser::writeColor4Value(const void* val_ptr, const name_stack_t& stac
 	return false;
 }
 
-bool LLXUIParser::readUIColorValue(void* val_ptr)
+bool LLXUIParser::readUIColorValue(Parser& parser, void* val_ptr)
 {
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLUIColor* param = (LLUIColor*)val_ptr;
 	LLColor4 color;
-	bool success =  mCurReadNode->getFloatValue(4, color.mV) >= 3;
+	bool success =  self.mCurReadNode->getFloatValue(4, color.mV) >= 3;
 	if (success)
 	{
 		param->set(color);
@@ -874,11 +877,12 @@ bool LLXUIParser::writeUIColorValue(const void* val_ptr, const name_stack_t& sta
 	return false;
 }
 
-bool LLXUIParser::readUUIDValue(void* val_ptr)
+bool LLXUIParser::readUUIDValue(Parser& parser, void* val_ptr)
 {
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLUUID temp_id;
 	// LLUUID::set is destructive, so use temporary value
-	if (temp_id.set(mCurReadNode->getSanitizedValue()))
+	if (temp_id.set(self.mCurReadNode->getSanitizedValue()))
 	{
 		*(LLUUID*)(val_ptr) = temp_id;
 		return true;
@@ -897,9 +901,10 @@ bool LLXUIParser::writeUUIDValue(const void* val_ptr, const name_stack_t& stack)
 	return false;
 }
 
-bool LLXUIParser::readSDValue(void* val_ptr)
+bool LLXUIParser::readSDValue(Parser& parser, void* val_ptr)
 {
-	*((LLSD*)val_ptr) = LLSD(mCurReadNode->getSanitizedValue());
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	*((LLSD*)val_ptr) = LLSD(self.mCurReadNode->getSanitizedValue());
 	return true;
 }
 
@@ -968,3 +973,397 @@ void LLXUIParser::parserError(const std::string& message)
 	Parser::parserError(message);
 #endif
 }
+
+
+//
+// LLFastXUIParser
+//
+
+struct ScopedFile
+{
+	ScopedFile( const std::string& filename, const char* accessmode )
+	{
+		mFile = LLFile::fopen(filename, accessmode);
+	}
+
+	~ScopedFile()
+	{
+		fclose(mFile);
+		mFile = NULL;
+	}
+
+	S32 getRemainingBytes()
+	{
+		if (!isOpen()) return 0;
+
+		S32 cur_pos = ftell(mFile);
+		fseek(mFile, 0L, SEEK_END);
+		S32 file_size = ftell(mFile);
+		fseek(mFile, cur_pos, SEEK_SET);
+		return file_size - cur_pos;
+	}
+
+	bool isOpen() { return mFile != NULL; }
+
+	LLFILE* mFile;
+};
+
+LLFastXUIParser::LLFastXUIParser()
+:	mLastWriteGeneration(-1),
+	mCurReadDepth(0)
+{
+	registerParserFuncs<bool>(readBoolValue, NULL);
+	registerParserFuncs<std::string>(readStringValue, NULL);
+	registerParserFuncs<U8>(readU8Value, NULL);
+	registerParserFuncs<S8>(readS8Value, NULL);
+	registerParserFuncs<U16>(readU16Value, NULL);
+	registerParserFuncs<S16>(readS16Value, NULL);
+	registerParserFuncs<U32>(readU32Value, NULL);
+	registerParserFuncs<S32>(readS32Value, NULL);
+	registerParserFuncs<F32>(readF32Value, NULL);
+	registerParserFuncs<F64>(readF64Value, NULL);
+	registerParserFuncs<LLColor4>(readColor4Value, NULL);
+	registerParserFuncs<LLUIColor>(readUIColorValue, NULL);
+	registerParserFuncs<LLUUID>(readUUIDValue, NULL);
+	registerParserFuncs<LLSD>(readSDValue, NULL);
+}
+
+LLFastXUIParser::~LLFastXUIParser()
+{
+}
+
+
+bool LLFastXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent)
+{
+	LLFastTimer timer(FTM_PARSE_XUI);
+
+	mParser = XML_ParserCreate(NULL);
+	XML_SetUserData(mParser, this);
+	XML_SetElementHandler(					mParser,	startElementHandler, endElementHandler);
+	XML_SetCharacterDataHandler(			mParser,	characterDataHandler);
+
+	mBlock = &block;
+	mNameStack.clear();
+	mCurFileName = filename;
+	mCurReadDepth = 0;
+	setParseSilently(silent);
+
+	ScopedFile file(filename, "rb");
+	if( !file.isOpen() )
+	{
+		LL_WARNS("ReadXUI") << "Unable to open file " << filename << LL_ENDL;
+		return false;
+	}
+
+	S32 bytes_read = 0;
+	
+	S32 buffer_size = file.getRemainingBytes();
+	void* buffer = XML_GetBuffer(mParser, buffer_size);
+	if( !buffer ) 
+	{
+		LL_WARNS("ReadXUI") << "Unable to allocate XML buffer while reading file " << filename << LL_ENDL;
+		XML_ParserFree( mParser );
+		return false;
+	}
+
+	bytes_read = (S32)fread(buffer, 1, buffer_size, file.mFile);
+	if( bytes_read <= 0 )
+	{
+		LL_WARNS("ReadXUI") << "Error while reading file  " << filename << LL_ENDL;
+		XML_ParserFree( mParser );
+		return false;
+	}
+	
+	if( !XML_ParseBuffer(mParser, bytes_read, TRUE ) )
+	{
+		LL_WARNS("ReadXUI") << "Error while parsing file  " << filename << LL_ENDL;
+		XML_ParserFree( mParser );
+		return false;
+	}
+
+	XML_ParserFree( mParser );
+	return true;
+}
+
+void LLFastXUIParser::startElementHandler(void *userData, const char *name, const char **atts)
+{
+	LLFastXUIParser* self = reinterpret_cast<LLFastXUIParser*>(userData);
+	self->startElement(name, atts);
+}
+
+void LLFastXUIParser::endElementHandler(void *userData, const char *name)
+{
+	LLFastXUIParser* self = reinterpret_cast<LLFastXUIParser*>(userData);
+	self->endElement(name);
+}
+
+void LLFastXUIParser::characterDataHandler(void *userData, const char *s, int len)
+{
+	LLFastXUIParser* self = reinterpret_cast<LLFastXUIParser*>(userData);
+	self->characterData(s, len);
+}
+
+void LLFastXUIParser::startElement(const char *name, const char **atts)
+{
+	typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+	boost::char_separator<char> sep(".");
+
+	mCurReadDepth++;
+	S32 num_tokens_pushed = 0;
+	std::string child_name(name);
+
+	if (mCurReadDepth > 1)
+	{
+		// for non "dotted" child nodes	check to see if child node maps to another widget type
+		// and if not, treat as a child element of the current node
+		// e.g. <button><rect left="10"/></button> will interpret <rect> as "button.rect"
+		// since there is no widget named "rect"
+		if (child_name.find(".") == std::string::npos) 
+		{
+			mNameStack.push_back(std::make_pair(child_name, newParseGeneration()));
+			num_tokens_pushed++;
+		}
+		else
+		{
+			// parse out "dotted" name into individual tokens
+			tokenizer name_tokens(child_name, sep);
+
+			tokenizer::iterator name_token_it = name_tokens.begin();
+			if(name_token_it == name_tokens.end()) 
+			{
+				return;
+			}
+
+			// check for proper nesting
+			if(!mScope.empty() && *name_token_it != mScope.back())
+			{
+				return;
+			}
+
+			// now ignore first token
+			++name_token_it; 
+
+			// copy remaining tokens on to our running token list
+			for(tokenizer::iterator token_to_push = name_token_it; token_to_push != name_tokens.end(); ++token_to_push)
+			{
+				mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration()));
+				num_tokens_pushed++;
+			}
+			mScope.push_back(mNameStack.back().first);
+		}
+	}
+	else
+	{
+		mScope.push_back(name);
+	}
+
+	mTokenSizeStack.push_back(num_tokens_pushed);
+	readAttributes(atts);
+}
+
+bool LLFastXUIParser::readAttributes(const char **atts)
+{
+	typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
+	boost::char_separator<char> sep(".");
+
+	bool any_parsed = false;
+	for(S32 i = 0; atts[i] && atts[i+1]; i += 2 )
+	{
+		std::string attribute_name(atts[i]);
+		mCurAttributeValueBegin = atts[i+1];
+		
+		S32 num_tokens_pushed = 0;
+		tokenizer name_tokens(attribute_name, sep);
+		// copy remaining tokens on to our running token list
+		for(tokenizer::iterator token_to_push = name_tokens.begin(); token_to_push != name_tokens.end(); ++token_to_push)
+		{
+			mNameStack.push_back(std::make_pair(*token_to_push, newParseGeneration()));
+			num_tokens_pushed++;
+		}
+
+		// child nodes are not necessarily valid attributes, so don't complain once we've recursed
+		bool silent = mCurReadDepth > 1;
+		any_parsed |= mBlock->submitValue(mNameStack, *this, silent);
+		
+		while(num_tokens_pushed-- > 0)
+		{
+			mNameStack.pop_back();
+		}
+	}
+	return any_parsed;
+}
+
+
+void LLFastXUIParser::endElement(const char *name)
+{
+	mCurReadDepth--;
+	S32 num_tokens_to_pop = mTokenSizeStack.back();
+	mTokenSizeStack.pop_back();
+	while(num_tokens_to_pop-- > 0)
+	{
+		mNameStack.pop_back();
+	}
+	mScope.pop_back();
+}
+
+void LLFastXUIParser::characterData(const char *s, int len)
+{
+}
+
+
+/*virtual*/ std::string LLFastXUIParser::getCurrentElementName()
+{
+	std::string full_name;
+	for (name_stack_t::iterator it = mNameStack.begin();	
+		it != mNameStack.end();
+		++it)
+	{
+		full_name += it->first + "."; // build up dotted names: "button.param.nestedparam."
+	}
+
+	return full_name;
+}
+
+const S32 LINE_NUMBER_HERE = 0;
+
+void LLFastXUIParser::parserWarning(const std::string& message)
+{
+#ifdef LL_WINDOWS
+	// use Visual Studo friendly formatting of output message for easy access to originating xml
+	llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str());
+	utf16str += '\n';
+	OutputDebugString(utf16str.c_str());
+#else
+	Parser::parserWarning(message);
+#endif
+}
+
+void LLFastXUIParser::parserError(const std::string& message)
+{
+#ifdef LL_WINDOWS
+	llutf16string utf16str = utf8str_to_utf16str(llformat("%s(%d):\t%s", mCurFileName.c_str(), LINE_NUMBER_HERE, message.c_str()).c_str());
+	utf16str += '\n';
+	OutputDebugString(utf16str.c_str());
+#else
+	Parser::parserError(message);
+#endif
+}
+
+bool LLFastXUIParser::readBoolValue(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	if (!strcmp(self.mCurAttributeValueBegin, "true")) 
+	{
+		*((bool*)val_ptr) = true;
+		return true;
+	}
+	else if (!strcmp(self.mCurAttributeValueBegin, "false"))
+	{
+		*((bool*)val_ptr) = false;
+		return true;
+	}
+
+	return false;
+}
+
+bool LLFastXUIParser::readStringValue(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	*((std::string*)val_ptr) = self.mCurAttributeValueBegin;
+	return true;
+}
+
+bool LLFastXUIParser::readU8Value(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U8*)val_ptr)]).full;
+}
+
+bool LLFastXUIParser::readS8Value(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S8*)val_ptr)]).full;
+}
+
+bool LLFastXUIParser::readU16Value(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U16*)val_ptr)]).full;
+}
+
+bool LLFastXUIParser::readS16Value(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S16*)val_ptr)]).full;
+}
+
+bool LLFastXUIParser::readU32Value(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	return parse(self.mCurAttributeValueBegin, uint_p[assign_a(*(U32*)val_ptr)]).full;
+}
+
+bool LLFastXUIParser::readS32Value(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	return parse(self.mCurAttributeValueBegin, int_p[assign_a(*(S32*)val_ptr)]).full;
+}
+
+bool LLFastXUIParser::readF32Value(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F32*)val_ptr)]).full;
+}
+
+bool LLFastXUIParser::readF64Value(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	return parse(self.mCurAttributeValueBegin, real_p[assign_a(*(F64*)val_ptr)]).full;
+}
+	
+bool LLFastXUIParser::readColor4Value(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	LLColor4 value;
+
+	if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
+	{
+		*(LLColor4*)(val_ptr) = value;
+		return true;
+	}
+	return false;
+}
+
+bool LLFastXUIParser::readUIColorValue(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	LLColor4 value;
+	LLUIColor* colorp = (LLUIColor*)val_ptr;
+
+	if (parse(self.mCurAttributeValueBegin, real_p[assign_a(value.mV[0])] >> real_p[assign_a(value.mV[1])] >> real_p[assign_a(value.mV[2])] >> real_p[assign_a(value.mV[3])], space_p).full)
+	{
+		colorp->set(value);
+		return true;
+	}
+	return false;
+}
+
+bool LLFastXUIParser::readUUIDValue(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	LLUUID temp_id;
+	// LLUUID::set is destructive, so use temporary value
+	if (temp_id.set(self.mCurAttributeValueBegin))
+	{
+		*(LLUUID*)(val_ptr) = temp_id;
+		return true;
+	}
+	return false;
+}
+
+bool LLFastXUIParser::readSDValue(Parser& parser, void* val_ptr)
+{
+	LLFastXUIParser& self = static_cast<LLFastXUIParser&>(parser);
+	*((LLSD*)val_ptr) = LLSD(self.mCurAttributeValueBegin);
+	return true;
+}
\ No newline at end of file
diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h
index 884f4f75780c1b5a60155abbfc9fcd5813be25b7..4deb083e1ce9793c0acfb638827f1ce2d1df2ccd 100644
--- a/indra/llxuixml/llxuiparser.h
+++ b/indra/llxuixml/llxuiparser.h
@@ -120,26 +120,24 @@ LOG_CLASS(LLXUIParser);
 	void writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock& block, const LLInitParam::BaseBlock* diff_block = NULL);
 
 private:
-	typedef std::list<std::pair<std::string, bool> >	token_list_t;
-
 	bool readXUIImpl(LLXMLNodePtr node, const std::string& scope, LLInitParam::BaseBlock& block);
 	bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block);
 
 	//reader helper functions
-	bool readBoolValue(void* val_ptr);
-	bool readStringValue(void* val_ptr);
-	bool readU8Value(void* val_ptr);
-	bool readS8Value(void* val_ptr);
-	bool readU16Value(void* val_ptr);
-	bool readS16Value(void* val_ptr);
-	bool readU32Value(void* val_ptr);
-	bool readS32Value(void* val_ptr);
-	bool readF32Value(void* val_ptr);
-	bool readF64Value(void* val_ptr);
-	bool readColor4Value(void* val_ptr);
-	bool readUIColorValue(void* val_ptr);
-	bool readUUIDValue(void* val_ptr);
-	bool readSDValue(void* val_ptr);
+	static bool readBoolValue(Parser& parser, void* val_ptr);
+	static bool readStringValue(Parser& parser, void* val_ptr);
+	static bool readU8Value(Parser& parser, void* val_ptr);
+	static bool readS8Value(Parser& parser, void* val_ptr);
+	static bool readU16Value(Parser& parser, void* val_ptr);
+	static bool readS16Value(Parser& parser, void* val_ptr);
+	static bool readU32Value(Parser& parser, void* val_ptr);
+	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 readColor4Value(Parser& parser, void* val_ptr);
+	static bool readUIColorValue(Parser& parser, void* val_ptr);
+	static bool readUUIDValue(Parser& parser, void* val_ptr);
+	static bool readSDValue(Parser& parser, void* val_ptr);
 
 	//writer helper functions
 	bool writeBoolValue(const void* val_ptr, const name_stack_t&);
@@ -173,5 +171,61 @@ LOG_CLASS(LLXUIParser);
 	std::string						mCurFileName;
 };
 
+class LLFastXUIParser : public LLInitParam::Parser, public LLSingleton<LLFastXUIParser>
+{
+LOG_CLASS(LLFastXUIParser);
+
+protected:
+	LLFastXUIParser();
+	virtual ~LLFastXUIParser();
+	friend class LLSingleton<LLFastXUIParser>;
+public:
+	typedef LLInitParam::Parser::name_stack_t name_stack_t;
+
+	/*virtual*/ std::string getCurrentElementName();
+	/*virtual*/ void parserWarning(const std::string& message);
+	/*virtual*/ void parserError(const std::string& message);
+
+	bool readXUI(const std::string& filename, LLInitParam::BaseBlock& block, bool silent=false);
+
+private:
+	//reader helper functions
+	static bool readBoolValue(Parser&, void* val_ptr);
+	static bool readStringValue(Parser&, void* val_ptr);
+	static bool readU8Value(Parser&, void* val_ptr);
+	static bool readS8Value(Parser&, void* val_ptr);
+	static bool readU16Value(Parser&, void* val_ptr);
+	static bool readS16Value(Parser&, void* val_ptr);
+	static bool readU32Value(Parser&, void* val_ptr);
+	static bool readS32Value(Parser&, void* val_ptr);
+	static bool readF32Value(Parser&, void* val_ptr);
+	static bool readF64Value(Parser&, void* val_ptr);
+	static bool readColor4Value(Parser&, void* val_ptr);
+	static bool readUIColorValue(Parser&, void* val_ptr);
+	static bool readUUIDValue(Parser&, void* val_ptr);
+	static bool readSDValue(Parser&, void* val_ptr);
+
+private:
+	static void startElementHandler(void *userData, const char *name, const char **atts);
+	static void endElementHandler(void *userData, const char *name);
+	static void characterDataHandler(void *userData, const char *s, int len);
+
+	void startElement(const char *name, const char **atts);
+	void endElement(const char *name);
+	void characterData(const char *s, int len);
+	bool readAttributes(const char **atts);
+
+	LLInitParam::BaseBlock*			mBlock;
+	Parser::name_stack_t			mNameStack;
+	struct XML_ParserStruct*		mParser;
+	S32								mLastWriteGeneration;
+	LLXMLNodePtr					mLastWrittenChild;
+	S32								mCurReadDepth;
+	std::string						mCurFileName;
+	const char*						mCurAttributeValueBegin;
+	std::vector<S32>				mTokenSizeStack;
+	std::vector<std::string>		mScope;
+};
+
 
 #endif //LLXUIPARSER_H