diff --git a/indra/llui/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp
index 9ce7533e1bb633376af70fbccbd09c584ee68fd0..d8e035a320370fd1ca45d79e3a3dbefcc6c618c8 100644
--- a/indra/llui/llcommandmanager.cpp
+++ b/indra/llui/llcommandmanager.cpp
@@ -41,7 +41,7 @@
 // LLCommandId class
 //
 
-const LLCommandId LLCommandId::null("null command");
+const LLCommandId LLCommandId::null = LLCommandId();
 
 //
 // LLCommand class
@@ -152,7 +152,7 @@ bool LLCommandManager::load()
 
 	if (!commandsParams.validateBlock())
 	{
-		llerrs << "Unable to validate commands param block from file: " << commands_file << llendl;
+		llerrs << "Invalid commands file: " << commands_file << llendl;
 		return false;
 	}
 
diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h
index 8f9f956ec7eabda5a1847aa13f445194d28c63d7..fdad7cd1b5a7acef14c26e689b6fce9e78b1d3f5 100644
--- a/indra/llui/llcommandmanager.h
+++ b/indra/llui/llcommandmanager.h
@@ -50,6 +50,12 @@ class LLCommandId
 		{}
 	};
 
+	LLCommandId()
+		: mName("null command")
+	{
+		mUUID = LLUUID::generateNewID(mName);
+	}
+	
 	LLCommandId(const std::string& name)
 		: mName(name)
 	{
@@ -62,10 +68,9 @@ class LLCommandId
 		mUUID = LLUUID::generateNewID(p.name);
 	}
 
-	LLCommandId(const LLUUID& uuid)
-	:	mName(""),
+	LLCommandId(const std::string& name, const LLUUID& uuid)
+	:	mName(name),
 		mUUID(uuid)
-	
 	{
 	}
 	
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index f85e46e28d83f485408060ad68016c195481fb39..90c41e99dc121db3097620adb2da687d892b2cb1 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -849,9 +849,9 @@ void LLFloater::applyRectControl()
 	if (mRectControl.size() > 1)
 	{
 		const LLRect& rect = getControlGroup()->getRect(mRectControl);
-		if (rect.getWidth() > 0 && rect.getHeight() > 0)
+		if (rect.notEmpty())
 		{
-			translate( rect.mLeft - getRect().mLeft, rect.mBottom - getRect().mBottom);
+			setOrigin(rect.mLeft, rect.mBottom);
 			if (mResizable)
 			{
 				reshape(llmax(mMinWidth, rect.getWidth()), llmax(mMinHeight, rect.getHeight()));
@@ -2558,7 +2558,7 @@ void LLFloaterView::adjustToFitScreen(LLFloater* floater, BOOL allow_partial_out
 	}
 
 	// move window fully onscreen
-	if (floater->translateIntoRect( getLocalRect(), allow_partial_outside ))
+	if (floater->translateIntoRect( getSnapRect(), allow_partial_outside ))
 	{
 		floater->clearSnapTarget();
 	}
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index ffe5908a9d7ed490ad1fbe3b7b2b95347d72e156..8f7025a9a66b72a1a26e2ba6b7e7475725140fdd 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -46,6 +46,7 @@
 
 #include <algorithm>
 #include <boost/regex.hpp>
+#include <boost/foreach.hpp>
 
 
 const std::string NOTIFICATION_PERSIST_VERSION = "0.93";
@@ -416,23 +417,17 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
 		mSoundEffect = LLUUID(LLUI::sSettingGroups["config"]->getString(p.sound));
 	}
 
-	for(LLInitParam::ParamIterator<LLNotificationTemplate::UniquenessContext>::const_iterator it = p.unique.contexts.begin(),
-			end_it = p.unique.contexts.end();
-		it != end_it;
-		++it)
+	BOOST_FOREACH(const LLNotificationTemplate::UniquenessContext& context, p.unique.contexts)
 	{
-		mUniqueContext.push_back(it->value);
+		mUniqueContext.push_back(context.value);
 	}
 	
 	lldebugs << "notification \"" << mName << "\": tag count is " << p.tags.size() << llendl;
 	
-	for(LLInitParam::ParamIterator<LLNotificationTemplate::Tag>::const_iterator it = p.tags.begin(),
-			end_it = p.tags.end();
-		it != end_it;
-		++it)
+	BOOST_FOREACH(const LLNotificationTemplate::Tag& tag, p.tags)
 	{
-		lldebugs << "    tag \"" << std::string(it->value) << "\"" << llendl;
-		mTags.push_back(it->value);
+		lldebugs << "    tag \"" << std::string(tag.value) << "\"" << llendl;
+		mTags.push_back(tag.value);
 	}
 
 	mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form));
@@ -1397,14 +1392,12 @@ void replaceFormText(LLNotificationForm::Params& form, const std::string& patter
 	{
 		form.ignore.text = replace;
 	}
-	for (LLInitParam::ParamIterator<LLNotificationForm::FormElement>::iterator it = form.form_elements.elements.begin(),
-			end_it = form.form_elements.elements.end();
-		it != end_it;
-		++it)
+
+	BOOST_FOREACH(LLNotificationForm::FormElement& element, form.form_elements.elements)
 	{
-		if (it->button.isChosen() && it->button.text() == pattern)
+		if (element.button.isChosen() && element.button.text() == pattern)
 		{
-			it->button.text = replace;
+			element.button.text = replace;
 		}
 	}
 }
@@ -1453,48 +1446,42 @@ bool LLNotifications::loadTemplates()
 
 	mTemplates.clear();
 
-	for(LLInitParam::ParamIterator<LLNotificationTemplate::GlobalString>::const_iterator it = params.strings.begin(), end_it = params.strings.end();
-		it != end_it;
-		++it)
+	BOOST_FOREACH(LLNotificationTemplate::GlobalString& string, params.strings)
 	{
-		mGlobalStrings[it->name] = it->value;
+		mGlobalStrings[string.name] = string.value;
 	}
 
 	std::map<std::string, LLNotificationForm::Params> form_templates;
 
-	for(LLInitParam::ParamIterator<LLNotificationTemplate::Template>::const_iterator it = params.templates.begin(), end_it = params.templates.end();
-		it != end_it;
-		++it)
+	BOOST_FOREACH(LLNotificationTemplate::Template& notification_template, params.templates)
 	{
-		form_templates[it->name] = it->form;
+		form_templates[notification_template.name] = notification_template.form;
 	}
 
-	for(LLInitParam::ParamIterator<LLNotificationTemplate::Params>::iterator it = params.notifications.begin(), end_it = params.notifications.end();
-		it != end_it;
-		++it)
+	BOOST_FOREACH(LLNotificationTemplate::Params& notification, params.notifications)
 	{
-		if (it->form_ref.form_template.isChosen())
+		if (notification.form_ref.form_template.isChosen())
 		{
 			// replace form contents from template
-			it->form_ref.form = form_templates[it->form_ref.form_template.name];
-			if(it->form_ref.form_template.yes_text.isProvided())
+			notification.form_ref.form = form_templates[notification.form_ref.form_template.name];
+			if(notification.form_ref.form_template.yes_text.isProvided())
 			{
-				replaceFormText(it->form_ref.form, "$yestext", it->form_ref.form_template.yes_text);
+				replaceFormText(notification.form_ref.form, "$yestext", notification.form_ref.form_template.yes_text);
 			}
-			if(it->form_ref.form_template.no_text.isProvided())
+			if(notification.form_ref.form_template.no_text.isProvided())
 			{
-				replaceFormText(it->form_ref.form, "$notext", it->form_ref.form_template.no_text);
+				replaceFormText(notification.form_ref.form, "$notext", notification.form_ref.form_template.no_text);
 			}
-			if(it->form_ref.form_template.cancel_text.isProvided())
+			if(notification.form_ref.form_template.cancel_text.isProvided())
 			{
-				replaceFormText(it->form_ref.form, "$canceltext", it->form_ref.form_template.cancel_text);
+				replaceFormText(notification.form_ref.form, "$canceltext", notification.form_ref.form_template.cancel_text);
 			}
-			if(it->form_ref.form_template.ignore_text.isProvided())
+			if(notification.form_ref.form_template.ignore_text.isProvided())
 			{
-				replaceFormText(it->form_ref.form, "$ignoretext", it->form_ref.form_template.ignore_text);
+				replaceFormText(notification.form_ref.form, "$ignoretext", notification.form_ref.form_template.ignore_text);
 			}
 		}
-		mTemplates[it->name] = LLNotificationTemplatePtr(new LLNotificationTemplate(*it));
+		mTemplates[notification.name] = LLNotificationTemplatePtr(new LLNotificationTemplate(notification));
 	}
 
 	return true;
@@ -1517,12 +1504,9 @@ bool LLNotifications::loadVisibilityRules()
 
 	mVisibilityRules.clear();
 
-	for(LLInitParam::ParamIterator<LLNotificationVisibilityRule::Rule>::iterator it = params.rules.begin(), 
-			end_it = params.rules.end();
-		it != end_it;
-		++it)
+	BOOST_FOREACH(LLNotificationVisibilityRule::Rule& rule, params.rules)
 	{
-		mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(*it)));
+		mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(rule)));
 	}
 
 	return true;
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 4b69360e3302e4d9af063912e33244ca0856a93f..da50c0ff399fd97ad216e1c359acf1731488aeb2 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -34,6 +34,7 @@
 static 	LLInitParam::Parser::parser_read_func_map_t sReadFuncs;
 static 	LLInitParam::Parser::parser_write_func_map_t sWriteFuncs;
 static 	LLInitParam::Parser::parser_inspect_func_map_t sInspectFuncs;
+static const LLSD NO_VALUE_MARKER;
 
 //
 // LLParamSDParser
@@ -60,29 +61,34 @@ LLParamSDParser::LLParamSDParser()
 }
 
 // special case handling of U32 due to ambiguous LLSD::assign overload
-bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack)
+bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const void* val_ptr, parser_t::name_stack_t& name_stack)
 {
 	LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
 	if (!sdparser.mWriteRootSD) return false;
 	
-	LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack);
-	if (!sd_to_write) return false;
+	parser_t::name_stack_range_t range(name_stack.begin(), name_stack.end());
+	LLSD& sd_to_write = LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range);
+	sd_to_write.assign((S32)*((const U32*)val_ptr));
 
-	sd_to_write->assign((S32)*((const U32*)val_ptr));
 	return true;
 }
 
-bool LLParamSDParser::writeFlag(LLParamSDParser::parser_t& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack)
+bool LLParamSDParser::writeFlag(LLParamSDParser::parser_t& parser, const void* val_ptr, parser_t::name_stack_t& name_stack)
 {
 	LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
 	if (!sdparser.mWriteRootSD) return false;
 
-	LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack);
-	if (!sd_to_write) return false;
+	parser_t::name_stack_range_t range(name_stack.begin(), name_stack.end());
+	LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range);
 
 	return true;
 }
 
+void LLParamSDParser::submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack)
+{
+	mCurReadSD = &sd;
+	block.submitValue(name_stack, *this);
+}
 
 void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent)
 {
@@ -90,7 +96,8 @@ void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool
 	mNameStack.clear();
 	setParseSilently(silent);
 
-	readSDValues(sd, block);
+	LLParamSDParserUtilities::readSDValues(boost::bind(&LLParamSDParser::submit, this, boost::ref(block), _1, _2), sd, mNameStack);
+	//readSDValues(sd, block);
 }
 
 void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
@@ -100,43 +107,6 @@ void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
 	block.serializeBlock(*this);
 }
 
-const LLSD NO_VALUE_MARKER;
-
-void LLParamSDParser::readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block)
-{
-	if (sd.isMap())
-	{
-		for (LLSD::map_const_iterator it = sd.beginMap();
-			it != sd.endMap();
-			++it)
-		{
-			mNameStack.push_back(make_pair(it->first, newParseGeneration()));
-			readSDValues(it->second, block);
-			mNameStack.pop_back();
-		}
-	}
-	else if (sd.isArray())
-	{
-		for (LLSD::array_const_iterator it = sd.beginArray();
-			it != sd.endArray();
-			++it)
-		{
-			mNameStack.back().second = newParseGeneration();
-			readSDValues(*it, block);
-		}
-	}
-	else if (sd.isUndefined())
-	{
-		mCurReadSD = &NO_VALUE_MARKER;
-		block.submitValue(mNameStack, *this);
-	}
-	else
-	{
-		mCurReadSD = &sd;
-		block.submitValue(mNameStack, *this);
-	}
-}
-
 /*virtual*/ std::string LLParamSDParser::getCurrentElementName()
 {
 	std::string full_name = "sd";
@@ -150,81 +120,6 @@ void LLParamSDParser::readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block
 	return full_name;
 }
 
-LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack)
-{
-	//TODO: implement nested LLSD writing
-	LLSD* sd_to_write = mWriteRootSD;
-	bool new_traversal = false;
-	for (name_stack_t::const_iterator it = name_stack.begin(), prev_it = mNameStack.begin();
-		it != name_stack.end();
-		++it)
-	{
-		bool new_array_entry = false;
-		if (prev_it == mNameStack.end())
-		{
-			new_traversal = true;
-		}
-		else
-		{
-			if (!new_traversal						// have not diverged yet from previous trace
-				&& prev_it->first == it->first		// names match
-				&& prev_it->second != it->second)	// versions differ
-			{
-				// name stacks match, but version numbers differ in last place.
-				// create a different entry at this point using an LLSD array
-				new_array_entry = true;
-			}
-			if (prev_it->first != it->first			// names differ
-				|| prev_it->second != it->second)	// versions differ
-			{
-				// at this point we have diverged from our last trace
-				// so any elements referenced here are new
-				new_traversal = true;
-			}
-		}
-
-		LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first];
-
-		if (child_sd->isArray())
-		{
-			if (new_traversal)
-			{
-				// write to new element at end
-				sd_to_write = &(*child_sd)[child_sd->size()];
-			}
-			else
-			{
-				// write to last of existing elements, or first element if empty
-				sd_to_write = &(*child_sd)[llmax(0, child_sd->size() - 1)];
-			}
-		}
-		else
-		{
-			if (new_array_entry && !child_sd->isArray())
-			{
-				// copy child contents into first element of an array
-				LLSD new_array = LLSD::emptyArray();
-				new_array.append(*child_sd);
-				// assign array to slot that previously held the single value
-				*child_sd = new_array;
-				// return next element in that array
-				sd_to_write = &((*child_sd)[1]);
-			}
-			else
-			{
-				sd_to_write = child_sd;
-			}
-		}
-		if (prev_it != mNameStack.end())
-		{
-			++prev_it;
-		}
-	}
-	mNameStack = name_stack;
-	
-	//llinfos << ll_pretty_print_sd(*mWriteRootSD) << llendl;
-	return sd_to_write;
-}
 
 bool LLParamSDParser::readFlag(Parser& parser, void* val_ptr)
 {
@@ -312,3 +207,126 @@ bool LLParamSDParser::readSD(Parser& parser, void* val_ptr)
 	*((LLSD*)val_ptr) = *self.mCurReadSD;
     return true;
 }
+
+// static
+LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser::name_stack_range_t& name_stack_range)
+{
+	LLSD* sd_to_write = &input;
+	
+	for (LLInitParam::Parser::name_stack_t::iterator it = name_stack_range.first;
+		it != name_stack_range.second;
+		++it)
+	{
+		bool new_traversal = it->second;
+
+		LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first];
+
+		if (child_sd->isArray())
+		{
+			if (new_traversal)
+			{
+				// write to new element at end
+				sd_to_write = &(*child_sd)[child_sd->size()];
+			}
+			else
+			{
+				// write to last of existing elements, or first element if empty
+				sd_to_write = &(*child_sd)[llmax(0, child_sd->size() - 1)];
+			}
+		}
+		else
+		{
+			if (new_traversal 
+				&& child_sd->isDefined() 
+				&& !child_sd->isArray())
+			{
+				// copy child contents into first element of an array
+				LLSD new_array = LLSD::emptyArray();
+				new_array.append(*child_sd);
+				// assign array to slot that previously held the single value
+				*child_sd = new_array;
+				// return next element in that array
+				sd_to_write = &((*child_sd)[1]);
+			}
+			else
+			{
+				sd_to_write = child_sd;
+			}
+		}
+		it->second = false;
+	}
+	
+	return *sd_to_write;
+}
+
+//static
+void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLInitParam::Parser::name_stack_t& stack)
+{
+	if (sd.isMap())
+	{
+		for (LLSD::map_const_iterator it = sd.beginMap();
+			it != sd.endMap();
+			++it)
+		{
+			stack.push_back(make_pair(it->first, true));
+			readSDValues(cb, it->second, stack);
+			stack.pop_back();
+		}
+	}
+	else if (sd.isArray())
+	{
+		for (LLSD::array_const_iterator it = sd.beginArray();
+			it != sd.endArray();
+			++it)
+		{
+			stack.back().second = true;
+			readSDValues(cb, *it, stack);
+		}
+	}
+	else if (sd.isUndefined())
+	{
+		if (!cb.empty())
+		{
+			cb(NO_VALUE_MARKER, stack);
+		}
+	}
+	else
+	{
+		if (!cb.empty())
+		{
+			cb(sd, stack);
+		}
+	}
+}
+
+namespace LLInitParam
+{
+	// LLSD specialization
+	// block param interface
+	bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
+	{
+		LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);
+
+		LLSD::String string;
+
+		if (p.readValue<LLSD::String>(string))
+		{
+			sd = string;
+			return true;
+		}
+		return false;
+	}
+
+	//static
+	void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
+	{
+		p.writeValue<LLSD::String>(sd.asString(), name_stack);
+	}
+
+	void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t name_stack, const BaseBlock* diff_block) const
+	{
+		// read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
+		Parser::name_stack_t stack;
+		LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, stack);
+	}
+}
diff --git a/indra/llui/llsdparam.h b/indra/llui/llsdparam.h
index a371c28f68e95deaf77c24c814f90ec87fa320cc..784358d0389262b476caae720c17703f502e7690 100644
--- a/indra/llui/llsdparam.h
+++ b/indra/llui/llsdparam.h
@@ -29,6 +29,15 @@
 #define LL_LLSDPARAM_H
 
 #include "llinitparam.h"
+#include "boost/function.hpp"
+
+struct LLParamSDParserUtilities
+{
+	static LLSD& getSDWriteNode(LLSD& input, LLInitParam::Parser::name_stack_range_t& name_stack_range);
+
+	typedef boost::function<void (const LLSD&, LLInitParam::Parser::name_stack_t&)> read_sd_cb_t;
+	static void readSDValues(read_sd_cb_t cb, const LLSD& sd, LLInitParam::Parser::name_stack_t& stack = LLInitParam::Parser::name_stack_t());
+};
 
 class LLParamSDParser 
 :	public LLInitParam::Parser
@@ -45,25 +54,23 @@ typedef LLInitParam::Parser parser_t;
 	/*virtual*/ std::string getCurrentElementName();
 
 private:
-	void readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block);
+	void submit(LLInitParam::BaseBlock& block, const LLSD& sd, LLInitParam::Parser::name_stack_t& name_stack);
 
 	template<typename T>
-	static bool writeTypedValue(Parser& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack)
+	static bool writeTypedValue(Parser& parser, const void* val_ptr, parser_t::name_stack_t& name_stack)
 	{
 		LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
 		if (!sdparser.mWriteRootSD) return false;
 		
-		LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack);
-		if (!sd_to_write) return false;
+		LLInitParam::Parser::name_stack_range_t range(name_stack.begin(), name_stack.end());
+		LLSD& sd_to_write = LLParamSDParserUtilities::getSDWriteNode(*sdparser.mWriteRootSD, range);
 
-		sd_to_write->assign(*((const T*)val_ptr));
+		sd_to_write.assign(*((const T*)val_ptr));
 		return true;
 	}
 
-	LLSD* getSDWriteNode(const parser_t::name_stack_t& name_stack);
-
-	static bool writeU32Param(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack);
-	static bool writeFlag(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack);
+	static bool writeU32Param(Parser& parser, const void* value_ptr, parser_t::name_stack_t& name_stack);
+	static bool writeFlag(Parser& parser, const void* value_ptr, parser_t::name_stack_t& name_stack);
 
 	static bool readFlag(Parser& parser, void* val_ptr);
 	static bool readS32(Parser& parser, void* val_ptr);
@@ -85,29 +92,29 @@ typedef LLInitParam::Parser parser_t;
 
 template<typename T>
 class LLSDParamAdapter : public T
+{
+public:
+	LLSDParamAdapter() {}
+	LLSDParamAdapter(const LLSD& sd)
 	{
-	public:
-		LLSDParamAdapter() {}
-		LLSDParamAdapter(const LLSD& sd)
-		{
-			LLParamSDParser parser;
-			parser.readSD(sd, *this);
-		}
-
-		operator LLSD() const
-		{
-			LLParamSDParser parser;
-			LLSD sd;
-			parser.writeSD(sd, *this);
-			return sd;
-		}
+		LLParamSDParser parser;
+		parser.readSD(sd, *this);
+	}
+
+	operator LLSD() const
+	{
+		LLParamSDParser parser;
+		LLSD sd;
+		parser.writeSD(sd, *this);
+		return sd;
+	}
 		
-		LLSDParamAdapter(const T& val)
-		: T(val)
-		{
-			T::operator=(val);
-		}
-	};
+	LLSDParamAdapter(const T& val)
+	: T(val)
+	{
+		T::operator=(val);
+	}
+};
 
 #endif // LL_LLSDPARAM_H
 
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index c34fbcd4f51415d8d02150c0a6caf48438c579d3..6332b2674ad31b099368e6d7ab5adf05b16425e7 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -33,6 +33,7 @@
 #include "llcommandmanager.h"
 #include "llmenugl.h"
 #include "lltrans.h"
+#include "llinventory.h"
 
 // uncomment this and remove the one in llui.cpp when there is an external reference to this translation unit
 // thanks, MSVC!
@@ -86,6 +87,7 @@ LLToolBar::Params::Params()
 	pad_right("pad_right"),
 	pad_bottom("pad_bottom"),
 	pad_between("pad_between"),
+	min_girth("min_girth"),
 	button_panel("button_panel")
 {}
 
@@ -103,6 +105,7 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
 	mPadTop(p.pad_top),
 	mPadBottom(p.pad_bottom),
 	mPadBetween(p.pad_between),
+	mMinGirth(p.min_girth),
 	mPopupMenuHandle(),
 	mStartDragItemCallback(NULL),
 	mHandleDragItemCallback(NULL),
@@ -111,6 +114,8 @@ LLToolBar::LLToolBar(const LLToolBar::Params& p)
 {
 	mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_WITH_TEXT] = p.button_icon_and_text;
 	mButtonParams[LLToolBarEnums::BTNTYPE_ICONS_ONLY] = p.button_icon;
+	mDraggedCommand = LLCommandId::null;
+	mRank = 0;
 }
 
 LLToolBar::~LLToolBar()
@@ -201,17 +206,24 @@ bool LLToolBar::addCommand(const LLCommandId& commandId, int rank)
 {
 	LLCommand * command = LLCommandManager::instance().getCommand(commandId);
 	if (!command) return false;
-
+	llinfos << "Merov debug : addCommand, " << commandId.name() << ", " << commandId.uuid() << llendl;
+	
 	// Create the button and do the things that don't need ordering
 	LLToolBarButton* button = createButton(commandId);
 	mButtonPanel->addChild(button);
-	mButtonMap.insert(std::make_pair(commandId, button));
+	LLCommandId temp_command = commandId;
+	if (commandId.name() == "Drag Tool")
+	{
+		temp_command = LLCommandId("Drag Tool");
+	}
+	mButtonMap.insert(std::make_pair(temp_command.uuid(), button));
+
 
 	// Insert the command and button in the right place in their respective lists
 	if ((rank >= mButtonCommands.size()) || (rank < 0))
 	{
 		// In that case, back load
-		mButtonCommands.push_back(commandId);
+		mButtonCommands.push_back(temp_command);
 		mButtons.push_back(button);
 	}
 	else 
@@ -226,7 +238,7 @@ bool LLToolBar::addCommand(const LLCommandId& commandId, int rank)
 			rank--;
 		}
 		// ...then insert
-		mButtonCommands.insert(it_command,commandId);
+		mButtonCommands.insert(it_command,temp_command);
 		mButtons.insert(it_button,button);
 	}
 
@@ -239,14 +251,20 @@ bool LLToolBar::removeCommand(const LLCommandId& commandId)
 {
 	if (!hasCommand(commandId)) return false;
 	
+	llinfos << "Merov debug : removeCommand, " << commandId.name() << ", " << commandId.uuid() << llendl;
 	// First erase the map record
-	command_id_map::iterator it = mButtonMap.find(commandId);
+	LLCommandId temp_command = commandId;
+	if (commandId.name() == "Drag Tool")
+	{
+		temp_command = LLCommandId("Drag Tool");
+	}
+	command_id_map::iterator it = mButtonMap.find(temp_command.uuid());
 	mButtonMap.erase(it);
 	
 	// Now iterate on the commands and buttons to identify the relevant records
 	std::list<LLToolBarButton*>::iterator it_button = mButtons.begin();
 	command_id_list_t::iterator it_command = mButtonCommands.begin();
-	while (*it_command != commandId)
+	while (*it_command != temp_command)
 	{
 		++it_button;
 		++it_command;
@@ -274,7 +292,12 @@ bool LLToolBar::hasCommand(const LLCommandId& commandId) const
 {
 	if (commandId != LLCommandId::null)
 	{
-		command_id_map::const_iterator it = mButtonMap.find(commandId);
+		LLCommandId temp_command = commandId;
+		if (commandId.name() == "Drag Tool")
+		{
+			temp_command = LLCommandId("Drag Tool");
+		}
+		command_id_map::const_iterator it = mButtonMap.find(temp_command.uuid());
 		return (it != mButtonMap.end());
 	}
 
@@ -287,7 +310,12 @@ bool LLToolBar::enableCommand(const LLCommandId& commandId, bool enabled)
 	
 	if (commandId != LLCommandId::null)
 	{
-		command_id_map::iterator it = mButtonMap.find(commandId);
+		LLCommandId temp_command = commandId;
+		if (commandId.name() == "Drag Tool")
+		{
+			temp_command = LLCommandId("Drag Tool");
+		}
+		command_id_map::iterator it = mButtonMap.find(temp_command.uuid());
 		if (it != mButtonMap.end())
 		{
 			it->second->setEnabled(enabled);
@@ -505,7 +533,7 @@ void LLToolBar::updateLayoutAsNeeded()
 			button_rect.setLeftTopAndSize(cur_row, panel_rect.mTop - cur_start, button_clamped_width, button->getRect().getHeight());
 		}
 		button->setShape(button_rect);
-
+		
 		buttons_in_row.push_back(button);
 
 		row_running_length += button_length + mPadBetween;
@@ -517,6 +545,8 @@ void LLToolBar::updateLayoutAsNeeded()
 	S32 total_girth =	cur_row				// current row position...
 						+ max_row_girth		// ...incremented by size of final row...
 						+ girth_pad_end;	// ...plus padding reserved on end
+	total_girth = llmax(total_girth,mMinGirth);
+	
 	max_row_length = llmax(max_row_length, row_running_length - mPadBetween + row_pad_end);
 
 	resizeButtonsInRow(buttons_in_row, max_row_girth);
@@ -588,6 +618,12 @@ void LLToolBar::draw()
 			}
 		}
 	}
+	// HACK!!!
+	if (!mDragAndDropTarget)
+	{
+		removeCommand(mDraggedCommand);
+		mDraggedCommand = LLCommandId::null;
+	}
 
 	updateLayoutAsNeeded();
 	// rect may have shifted during layout
@@ -618,7 +654,12 @@ void LLToolBar::createButtons()
 		LLToolBarButton* button = createButton(command_id);
 		mButtons.push_back(button);
 		mButtonPanel->addChild(button);
-		mButtonMap.insert(std::make_pair(command_id, button));
+		LLCommandId temp_command = command_id;
+		if (command_id.name() == "Drag Tool")
+		{
+			temp_command = LLCommandId("Drag Tool");
+		}
+		mButtonMap.insert(std::make_pair(temp_command.uuid(), button));
 	}
 	mNeedsLayout = true;
 }
@@ -709,7 +750,31 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	*accept = (handled ? ACCEPT_YES_SINGLE : ACCEPT_NO);
 	
 	// We'll use that flag to change the visual aspect of the toolbar target on draw()
-	mDragAndDropTarget = handled;
+	mDragAndDropTarget = false;
+	
+	// HACK!!!
+	if (!isReadOnly() && handled)
+	{
+		if (!drop)
+		{
+			LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
+			LLAssetType::EType type = inv_item->getType();
+			if (type == LLAssetType::AT_WIDGET)
+			{
+				mRank = getRankFromPosition(x, y);
+				mDraggedCommand = LLCommandId("Drag Tool",inv_item->getUUID());
+				removeCommand(mDraggedCommand);
+				addCommand(mDraggedCommand,mRank);
+				mDragAndDropTarget = true;
+			}
+		}
+		else 
+		{
+			removeCommand(mDraggedCommand);
+			mDraggedCommand = LLCommandId::null;
+		}
+
+	}
 	
 	return handled;
 }
@@ -723,7 +788,10 @@ LLToolBarButton::LLToolBarButton(const Params& p)
 	mId(""),
 	mIsEnabledSignal(NULL),
 	mIsRunningSignal(NULL),
-	mIsStartingSignal(NULL)
+	mIsStartingSignal(NULL),
+	mIsDragged(false),
+	mStartDragItemCallback(NULL),
+	mHandleDragItemCallback(NULL)
 {
 	mButtonFlashRate = 0.0;
 	mButtonFlashCount = 0;
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 4fac08113046b16375176c8ed7c850c5c2aa6e32..84fa7ec0df5b595ac075026d47f3dfc86c45e39e 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -47,8 +47,8 @@ class LLToolBarButton : public LLButton
 public:
 	struct Params : public LLInitParam::Block<Params, LLButton::Params>
 	{
-		Optional<LLUI::RangeS32>	button_width;
-		Optional<S32>				desired_height;
+		Optional<LLUI::RangeS32::Params>	button_width;
+		Optional<S32>						desired_height;
 
 		Params()
 		:	button_width("button_width"),
@@ -141,7 +141,8 @@ class LLToolBar
 												pad_top,
 												pad_right,
 												pad_bottom,
-												pad_between;
+												pad_between,
+												min_girth;
 		// get rid of this
 		Multiple<LLCommandId::Params>			commands;
 
@@ -183,6 +184,8 @@ class LLToolBar
 	tool_handledrag_callback_t		mHandleDragItemCallback;
 	tool_handledrop_callback_t		mHandleDropCallback;
 	bool							mDragAndDropTarget;
+	int								mRank;
+	LLCommandId						mDraggedCommand;
 
 public:
 	// Methods used in loading and saving toolbar settings
@@ -204,7 +207,7 @@ class LLToolBar
 	typedef std::list<LLToolBarButton*> toolbar_button_list;
 	toolbar_button_list				mButtons;
 	command_id_list_t				mButtonCommands;
-	typedef std::map<LLCommandId, LLToolBarButton*> command_id_map;
+	typedef std::map<LLUUID, LLToolBarButton*> command_id_map;
 	command_id_map					mButtonMap;
 
 	LLToolBarEnums::ButtonType		mButtonType;
@@ -219,7 +222,8 @@ class LLToolBar
 									mPadRight,
 									mPadTop,
 									mPadBottom,
-									mPadBetween;
+									mPadBetween,
+									mMinGirth;
 
 	LLToolBarButton::Params			mButtonParams[LLToolBarEnums::BTNTYPE_COUNT];
 
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index d522123260152e37e903795d64dd7b9244db5e34..c8303bfc894017098ecb36cf0d5bea5029e14254 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -124,7 +124,7 @@ namespace LLInitParam
 	{
 		descriptor.mCurrentBlockPtr = this;
 	}
-	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; }
+	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name){ return true; }
 	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {}
 	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_value, S32 max_value) const { return true; }
 	bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 2f814f4200cad8bcc9b5a53b017656579a77668f..c1fb050206aadf943a43cedcc7b5f9c46a7b6985 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -72,7 +72,6 @@ S32 LLUIImage::getHeight() const
 
 namespace LLInitParam
 {
-	S32 Parser::sNextParseGeneration = 0;
 	BlockDescriptor::BlockDescriptor() {}
 	ParamDescriptor::ParamDescriptor(param_handle_t p, 
 						merge_func_t merge_func, 
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index fb6a2eabf10e5b11f13d0900226adfc23894ed0a..9dbccf125a34665c7d3be823ea2aa3e511268f32 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -66,8 +66,6 @@ namespace LLInitParam
 	BaseBlock::BaseBlock() {}
 	BaseBlock::~BaseBlock() {}
 
-	S32 Parser::sNextParseGeneration = 0;
-
 	BlockDescriptor::BlockDescriptor() {}
 	ParamDescriptor::ParamDescriptor(param_handle_t p, 
 						merge_func_t merge_func, 
@@ -98,7 +96,7 @@ namespace LLInitParam
 		mEnclosingBlockOffset = 0x7FFFffff & ((U32)(my_addr - block_addr));
 	}
 
-	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation){ return true; }
+	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name){ return true; }
 	void BaseBlock::serializeBlock(Parser& parser, Parser::name_stack_t name_stack, const LLInitParam::BaseBlock* diff_block) const {}
 	bool BaseBlock::inspectBlock(Parser& parser, Parser::name_stack_t name_stack, S32 min_count, S32 max_count) const { return true; }
 	bool BaseBlock::mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite) { return true; }
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index 99016205c857cc7eacc00a5a3266cd08cf003669..2520502cf1fe412e5dbd4aa0168e277850a19fb9 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -62,7 +62,6 @@ namespace LLInitParam
 		mInspectFunc(inspect_func),
 		mMinCount(min_count),
 		mMaxCount(max_count),
-		mGeneration(0),
 		mUserData(NULL)
 	{}
 
@@ -75,7 +74,6 @@ namespace LLInitParam
 		mInspectFunc(NULL),
 		mMinCount(0),
 		mMaxCount(0),
-		mGeneration(0),
 		mUserData(NULL)
 	{}
 
@@ -87,8 +85,6 @@ namespace LLInitParam
 	//
 	// Parser
 	//
-	S32 Parser::sNextParseGeneration = 0;
-
 	Parser::~Parser()
 	{}
 
@@ -162,9 +158,9 @@ namespace LLInitParam
 		return (param_address - baseblock_address);
 	}
 
-	bool BaseBlock::submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent)
+	bool BaseBlock::submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent)
 	{
-		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), -1))
+		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), true))
 		{
 			if (!silent)
 			{
@@ -213,8 +209,7 @@ namespace LLInitParam
 				// each param descriptor remembers its serial number
 				// so we can inspect the same param under different names
 				// and see that it has the same number
-				(*it)->mGeneration = parser.newParseGeneration();
-				name_stack.push_back(std::make_pair("", (*it)->mGeneration));
+				name_stack.push_back(std::make_pair("", true));
 				serialize_func(*param, parser, name_stack, diff_param);
 				name_stack.pop_back();
 			}
@@ -250,12 +245,7 @@ namespace LLInitParam
 					continue;
 				}
 
-				if (!duplicate)
-				{
-					it->second->mGeneration = parser.newParseGeneration();
-				}
-
-				name_stack.push_back(std::make_pair(it->first, it->second->mGeneration));
+				name_stack.push_back(std::make_pair(it->first, !duplicate));
 				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
 				serialize_func(*param, parser, name_stack, diff_param);
 				name_stack.pop_back();
@@ -278,8 +268,7 @@ namespace LLInitParam
 			ParamDescriptor::inspect_func_t inspect_func = (*it)->mInspectFunc;
 			if (inspect_func)
 			{
-				(*it)->mGeneration = parser.newParseGeneration();
-				name_stack.push_back(std::make_pair("", (*it)->mGeneration));
+				name_stack.push_back(std::make_pair("", true));
 				inspect_func(*param, parser, name_stack, (*it)->mMinCount, (*it)->mMaxCount);
 				name_stack.pop_back();
 			}
@@ -307,11 +296,7 @@ namespace LLInitParam
 					}
 				}
 
-				if (!duplicate)
-				{
-					it->second->mGeneration = parser.newParseGeneration();
-				}
-				name_stack.push_back(std::make_pair(it->first, it->second->mGeneration));
+				name_stack.push_back(std::make_pair(it->first, !duplicate));
 				inspect_func(*param, parser, name_stack, it->second->mMinCount, it->second->mMaxCount);
 				name_stack.pop_back();
 			}
@@ -320,16 +305,18 @@ namespace LLInitParam
 		return true;
 	}
 
-	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 parent_generation)
+	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool ignored)
 	{
 		BlockDescriptor& block_data = mostDerivedBlockDescriptor();
-		bool names_left = name_stack.first != name_stack.second;
+		bool names_left = name_stack_range.first != name_stack_range.second;
 
-		S32 parse_generation = name_stack.first == name_stack.second ? -1 : name_stack.first->second;
+		bool new_name = names_left
+						? name_stack_range.first->second
+						: true;
 
 		if (names_left)
 		{
-			const std::string& top_name = name_stack.first->first;
+			const std::string& top_name = name_stack_range.first->first;
 
 			ParamDescriptor::deserialize_func_t deserialize_func = NULL;
 			Param* paramp = NULL;
@@ -341,9 +328,18 @@ namespace LLInitParam
 				paramp = getParamFromHandle(found_it->second->mParamHandle);
 				deserialize_func = found_it->second->mDeserializeFunc;
 					
-				Parser::name_stack_range_t new_name_stack(name_stack.first, name_stack.second);
+				Parser::name_stack_range_t new_name_stack(name_stack_range.first, name_stack_range.second);
 				++new_name_stack.first;
-				return deserialize_func(*paramp, p, new_name_stack, parse_generation);
+				if (deserialize_func(*paramp, p, new_name_stack, new_name))
+				{
+					// value is no longer new, we know about it now
+					name_stack_range.first->second = false;
+					return true;
+				}
+				else
+				{
+					return false;
+				}
 			}
 		}
 
@@ -355,7 +351,7 @@ namespace LLInitParam
 			Param* paramp = getParamFromHandle((*it)->mParamHandle);
 			ParamDescriptor::deserialize_func_t deserialize_func = (*it)->mDeserializeFunc;
 
-			if (deserialize_func && deserialize_func(*paramp, p, name_stack, parse_generation))
+			if (deserialize_func && deserialize_func(*paramp, p, name_stack_range, new_name))
 			{
 				return true;
 			}
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 1a131d15a3f4d6eaae8cb189f23a917cc65ae4ac..06140d09319775e14c65285d1933f86ffbc379d6 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -214,13 +214,13 @@ namespace LLInitParam
 			}
 		};
 
-		typedef std::vector<std::pair<std::string, S32> >								name_stack_t;
-		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 std::vector<std::pair<std::string, bool> >					name_stack_t;
+		typedef std::pair<name_stack_t::iterator, name_stack_t::iterator>	name_stack_range_t;
+		typedef std::vector<std::string>									possible_values_t;
 
 		typedef bool (*parser_read_func_t)(Parser& parser, void* output);
-		typedef bool (*parser_write_func_t)(Parser& parser, const void*, const name_stack_t&);
-		typedef boost::function<void (const name_stack_t&, S32, S32, const possible_values_t*)>	parser_inspect_func_t;
+		typedef bool (*parser_write_func_t)(Parser& parser, const void*, name_stack_t&);
+		typedef boost::function<void (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;
@@ -228,7 +228,6 @@ namespace LLInitParam
 
 		Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
 		:	mParseSilently(false),
-			mParseGeneration(sNextParseGeneration),
 			mParserReadFuncs(&read_map),
 			mParserWriteFuncs(&write_map),
 			mParserInspectFuncs(&inspect_map)
@@ -245,7 +244,7 @@ namespace LLInitParam
 		    return false;
 	    }
 
-		template <typename T> bool writeValue(const T& param, const name_stack_t& name_stack)
+		template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
 		{
 		    parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
 		    if (found_it != mParserWriteFuncs->end())
@@ -256,7 +255,7 @@ namespace LLInitParam
 		}
 
 		// dispatch inspection to registered inspection functions, for each parameter in a param block
-		template <typename T> bool inspectValue(const name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
+		template <typename T> bool inspectValue(name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
 		{
 		    parser_inspect_func_map_t::iterator found_it = mParserInspectFuncs->find(&typeid(T));
 		    if (found_it != mParserInspectFuncs->end())
@@ -272,10 +271,6 @@ namespace LLInitParam
 		virtual void parserError(const std::string& message);
 		void setParseSilently(bool silent) { mParseSilently = silent; }
 
-		S32 getParseGeneration() { return mParseGeneration; }
-		S32 newParseGeneration() { return mParseGeneration = ++sNextParseGeneration; }
-
-
 	protected:
 		template <typename T>
 		void registerParserFuncs(parser_read_func_t read_func, parser_write_func_t write_func = NULL)
@@ -296,9 +291,6 @@ namespace LLInitParam
 		parser_read_func_map_t*		mParserReadFuncs;
 		parser_write_func_map_t*	mParserWriteFuncs;
 		parser_inspect_func_map_t*	mParserInspectFuncs;
-		S32	mParseGeneration;
-
-		static S32					sNextParseGeneration;
 	};
 
 	class BaseBlock;
@@ -341,7 +333,7 @@ namespace LLInitParam
 		};
 
 		typedef bool(*merge_func_t)(Param&, const Param&, bool);
-		typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, S32);
+		typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, bool);
 		typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
 		typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
 		typedef bool(*validation_func_t)(const Param*);
@@ -366,7 +358,6 @@ namespace LLInitParam
 		validation_func_t	mValidationFunc;
 		S32					mMinCount;
 		S32					mMaxCount;
-		S32					mGeneration;
 		S32					mNumRefs;
 		UserData*			mUserData;
 	};
@@ -447,7 +438,7 @@ namespace LLInitParam
 
 		BaseBlock();
 		virtual ~BaseBlock();
-		bool submitValue(const Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
+		bool submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent=false);
 
 		param_handle_t getHandleFromParam(const Param* param) const;
 		bool validateBlock(bool emit_errors = true) const;
@@ -473,7 +464,7 @@ namespace LLInitParam
 
 		S32 getLastChangeVersion() const { return mChangeVersion; }
 
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation);
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
 		void 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(), S32 min_count = 0, S32 max_count = S32_MAX) const;
 
@@ -593,8 +584,7 @@ namespace LLInitParam
 			mKeyVersion(0),
 			mValidatedVersion(-1),
 			mValidated(false)
-		{
-		}
+		{}
 
 		void setValue(value_assignment_t val)
 		{
@@ -672,11 +662,11 @@ namespace LLInitParam
 
 		bool isProvided() const { return Param::anyProvided(); }
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) 
+		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{ 
 			self_t& typed_param = static_cast<self_t&>(param);
 			// no further names in stack, attempt to parse value now
-			if (name_stack.first == name_stack.second)
+			if (name_stack_range.first == name_stack_range.second)
 			{
 				if (parser.readValue(typed_param.getValue()))
 				{
@@ -715,7 +705,7 @@ namespace LLInitParam
 
 			if (!name_stack.empty())
 			{
-				name_stack.back().second = parser.newParseGeneration();
+				name_stack.back().second = true;
 			}
 
 			std::string key = typed_param.getValueName();
@@ -811,11 +801,11 @@ namespace LLInitParam
 			}
 		}
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) 
+		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{ 
 			self_t& typed_param = static_cast<self_t&>(param);
 			// attempt to parse block...
-			if(typed_param.deserializeBlock(parser, name_stack, generation))
+			if(typed_param.deserializeBlock(parser, name_stack_range, new_name))
 			{
 				typed_param.clearValueName();
 				typed_param.enclosingBlock().paramChanged(param, true);
@@ -851,7 +841,7 @@ namespace LLInitParam
 
 			if (!name_stack.empty())
 			{
-				name_stack.back().second = parser.newParseGeneration();
+				name_stack.back().second = true;
 			}
 
 			std::string key = typed_param.getValueName();
@@ -943,7 +933,7 @@ namespace LLInitParam
 	public:
 		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>		self_t;
 		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>					param_value_t;
-		typedef typename std::vector<param_value_t>					container_t;
+		typedef typename std::vector<param_value_t>							container_t;
 		typedef const container_t&											value_assignment_t;
 
 		typedef VALUE_TYPE													value_t;
@@ -970,12 +960,12 @@ namespace LLInitParam
 
 		bool isProvided() const { return Param::anyProvided(); }
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) 
+		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{ 
 			self_t& typed_param = static_cast<self_t&>(param);
 			value_t value;
 			// no further names in stack, attempt to parse value now
-			if (name_stack.first == name_stack.second)
+			if (name_stack_range.first == name_stack_range.second)
 			{
 				// attempt to read value directly
 				if (parser.readValue(value))
@@ -1015,7 +1005,7 @@ namespace LLInitParam
 				++it)
 			{
 				std::string key = it->getValue();
-				name_stack.back().second = parser.newParseGeneration();
+				name_stack.back().second = true;
 
 				if(key.empty())
 				// not parsed via name values, write out value directly
@@ -1132,8 +1122,7 @@ namespace LLInitParam
 		typedef NAME_VALUE_LOOKUP										name_value_lookup_t;
 
 		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),
-			mLastParseGeneration(0)
+		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
 			std::copy(value.begin(), value.end(), back_inserter(mValues));
 
@@ -1153,13 +1142,12 @@ namespace LLInitParam
 
 		bool isProvided() const { return Param::anyProvided(); }
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) 
+		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name) 
 		{ 
 			self_t& typed_param = static_cast<self_t&>(param);
 			bool new_value = false;
 
-			if (generation != typed_param.mLastParseGeneration 
-				|| typed_param.mValues.empty())
+			if (new_name || typed_param.mValues.empty())
 			{
 				new_value = true;
 				typed_param.mValues.push_back(value_t());
@@ -1168,12 +1156,8 @@ namespace LLInitParam
 			param_value_t& value = typed_param.mValues.back();
 
 			// attempt to parse block...
-			if(value.deserializeBlock(parser, name_stack, generation))
+			if(value.deserializeBlock(parser, name_stack_range, new_name))
 			{
-				if (new_value)
-				{	// successfully parsed new value, let's keep it
-					typed_param.mLastParseGeneration = generation;
-				}
 				typed_param.enclosingBlock().paramChanged(param, true);
 				typed_param.setProvided(true);
 				return true;
@@ -1187,11 +1171,6 @@ namespace LLInitParam
 					// try to parse a per type named value
 					if (name_value_lookup_t::getValueFromName(name, value.getValue()))
 					{
-						if (new_value)
-						{	// successfully parsed new value, let's keep it
-							typed_param.mLastParseGeneration = generation;
-						}
-
 						typed_param.mValues.back().setValueName(name);
 						typed_param.mValues.back().mKeyVersion = value.getLastChangeVersion();
 						typed_param.enclosingBlock().paramChanged(param, true);
@@ -1219,7 +1198,7 @@ namespace LLInitParam
 				it != end_it;
 				++it)
 			{
-				name_stack.back().second = parser.newParseGeneration();
+				name_stack.back().second = true;
 
 				std::string key = it->getValueName();
 				if (!key.empty() && it->mKeyVersion == it->getLastChangeVersion())
@@ -1317,8 +1296,6 @@ namespace LLInitParam
 		}
 
 		container_t			mValues;
-
-		S32			mLastParseGeneration;
 	};
 
 	template <typename DERIVED_BLOCK>
@@ -1625,9 +1602,9 @@ namespace LLInitParam
 				}
 			}
 			
-			static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
+			static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
 			{
-				if (name_stack.first == name_stack.second)
+				if (name_stack_range.first == name_stack_range.second)
 				{
 					//std::string message = llformat("Deprecated value %s ignored", getName().c_str());
 					//parser.parserWarning(message);
@@ -1669,18 +1646,16 @@ namespace LLInitParam
 		typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t;
 
 		BatchBlock()
-		:	mLastParseGeneration(-1)
 		{}
 
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation)
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
 		{
-			if (generation != mLastParseGeneration)
+			if (new_name)
 			{
 				// reset block
 				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
-				mLastParseGeneration = generation;
 			}
-			return super_t::deserializeBlock(p, name_stack, generation);
+			return super_t::deserializeBlock(p, name_stack_range, new_name);
 		}
 
 		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
@@ -1688,7 +1663,6 @@ namespace LLInitParam
 			if (overwrite)
 			{
 				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
-				mLastParseGeneration = -1;
 				// merge individual parameters into destination
 				return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite);
 			}
@@ -1700,19 +1674,20 @@ namespace LLInitParam
 			static DERIVED_BLOCK default_value;
 			return default_value;
 		}
-
-		S32 mLastParseGeneration;
 	};
 
+	// FIXME: this specialization is not currently used, as it only matches against the BatchBlock base class
+	// and not the derived class with the actual params
 	template<typename DERIVED_BLOCK,
 			typename BASE_BLOCK,
 			typename NAME_VALUE_LOOKUP>
 	class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>,
 					NAME_VALUE_LOOKUP,
 					true>
-	:	public Param,
+	:	public NAME_VALUE_LOOKUP,
 		protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK>
 	{
+	public:
 		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t;
 		typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>&	value_assignment_t;
 
@@ -1734,7 +1709,6 @@ namespace LLInitParam
 		void setValue(value_assignment_t val)
 		{
 			*this = val;
-			block_t::mLastParseGeneration = -1;
 		}
 
 		value_assignment_t getValue() const
@@ -1764,6 +1738,59 @@ namespace LLInitParam
 		mutable bool 	mValidated; // lazy validation flag
 	};
 
+	template <>
+	class ParamValue <LLSD,
+					TypeValues<LLSD>,
+					false>
+	:	public TypeValues<LLSD>,
+		public BaseBlock
+	{
+	public:
+		typedef ParamValue<LLSD, TypeValues<LLSD>, false> self_t;
+		typedef const LLSD&	value_assignment_t;
+
+		ParamValue()
+		:	mKeyVersion(0),
+			mValidatedVersion(-1),
+			mValidated(false)
+		{}
+
+		ParamValue(value_assignment_t other)
+		:	mValue(other),
+			mKeyVersion(0),
+			mValidatedVersion(-1),
+			mValidated(false)
+		{}
+
+		void setValue(value_assignment_t val) { mValue = val; }
+
+		value_assignment_t getValue() const { return mValue; }
+		LLSD& getValue() { return mValue; }
+
+		operator value_assignment_t() const { return mValue; }
+		value_assignment_t operator()() const { return mValue; }
+		
+		S32 			mKeyVersion;
+
+		// block param interface
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
+		void 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(), S32 min_count = 0, S32 max_count = S32_MAX) const
+		{
+			//TODO: implement LLSD params as schema type Any
+			return true;
+		}
+
+	protected:
+		mutable S32 	mValidatedVersion;
+		mutable bool 	mValidated; // lazy validation flag
+
+	private:
+		static void serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack);
+
+		LLSD mValue;
+	};
+
 	template<typename T>
 	class CustomParamValue
 	:	public Block<ParamValue<T, TypeValues<T> > >,
@@ -1790,11 +1817,11 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack, S32 generation)
+		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack_range, bool new_name)
 		{
 			derived_t& typed_param = static_cast<derived_t&>(*this);
 			// try to parse direct value T
-			if (name_stack.first == name_stack.second)
+			if (name_stack_range.first == name_stack_range.second)
 			{
 				if(parser.readValue(typed_param.mValue))
 				{
@@ -1808,7 +1835,7 @@ namespace LLInitParam
 			}
 
 			// fall back on parsing block components for T
-			return typed_param.BaseBlock::deserializeBlock(parser, name_stack, generation);
+			return typed_param.BaseBlock::deserializeBlock(parser, name_stack_range, new_name);
 		}
 
 		void serializeBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), const BaseBlock* diff_block = NULL) const
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index c60f656c2ca11801b4b4b5a3ce28439376e51bef..aee8fa8d8f8e344ec619425f9601a37d8bb61e8c 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -513,7 +513,6 @@ static 	LLInitParam::Parser::parser_inspect_func_map_t sXUIInspectFuncs;
 //
 LLXUIParser::LLXUIParser()
 :	Parser(sXUIReadFuncs, sXUIWriteFuncs, sXUIInspectFuncs),
-	mLastWriteGeneration(-1),
 	mCurReadDepth(0)
 {
 	if (sXUIReadFuncs.empty())
@@ -583,7 +582,7 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
 	if (!text_contents.empty())
 	{
 		mCurReadNode = nodep;
-		mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration()));
+		mNameStack.push_back(std::make_pair(std::string("value"), true));
 		// child nodes are not necessarily valid parameters (could be a child widget)
 		// so don't complain once we've recursed
 		if (!block.submitValue(mNameStack, *this, true))
@@ -618,7 +617,7 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
 		// since there is no widget named "rect"
 		if (child_name.find(".") == std::string::npos) 
 		{
-			mNameStack.push_back(std::make_pair(child_name, newParseGeneration()));
+			mNameStack.push_back(std::make_pair(child_name, true));
 			num_tokens_pushed++;
 		}
 		else
@@ -654,7 +653,7 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
 			// 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()));
+				mNameStack.push_back(std::make_pair(*token_to_push, true));
 				num_tokens_pushed++;
 			}
 		}
@@ -704,7 +703,7 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo
 		// 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()));
+			mNameStack.push_back(std::make_pair(*token_to_push, true));
 			num_tokens_pushed++;
 		}
 
@@ -728,24 +727,13 @@ void LLXUIParser::writeXUI(LLXMLNodePtr node, const LLInitParam::BaseBlock &bloc
 }
 
 // go from a stack of names to a specific XML node
-LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack)
+LLXMLNodePtr LLXUIParser::getNode(name_stack_t& stack)
 {
-	name_stack_t name_stack;
-	for (name_stack_t::const_iterator it = stack.begin();
-		it != stack.end();
-		++it)
-	{
-		if (!it->first.empty())
-		{
-			name_stack.push_back(*it);
-		}
-	}
-
 	LLXMLNodePtr out_node = mWriteRootNode;
 
-	name_stack_t::const_iterator next_it = name_stack.begin();
-	for (name_stack_t::const_iterator it = name_stack.begin();
-		it != name_stack.end();
+	name_stack_t::iterator next_it = stack.begin();
+	for (name_stack_t::iterator it = stack.begin();
+		it != stack.end();
 		it = next_it)
 	{
 		++next_it;
@@ -754,17 +742,18 @@ LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack)
 			continue;
 		}
 
-		out_nodes_t::iterator found_it = mOutNodes.lower_bound(it->second);
+		out_nodes_t::iterator found_it = mOutNodes.find(it->first);
 
 		// node with this name not yet written
-		if (found_it == mOutNodes.end() || mOutNodes.key_comp()(found_it->first, it->second))
+		if (found_it == mOutNodes.end() || it->second)
 		{
 			// make an attribute if we are the last element on the name stack
-			bool is_attribute = next_it == name_stack.end();
+			bool is_attribute = next_it == stack.end();
 			LLXMLNodePtr new_node = new LLXMLNode(it->first.c_str(), is_attribute);
 			out_node->addChild(new_node);
-			mOutNodes.insert(found_it, std::make_pair(it->second, new_node));
+			mOutNodes[it->first] = new_node;
 			out_node = new_node;
+			it->second = false;
 		}
 		else
 		{
@@ -781,7 +770,7 @@ bool LLXUIParser::readFlag(Parser& parser, void* val_ptr)
 	return self.mCurReadNode == DUMMY_NODE;
 }
 
-bool LLXUIParser::writeFlag(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeFlag(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	// just create node
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
@@ -798,7 +787,7 @@ bool LLXUIParser::readBoolValue(Parser& parser, void* val_ptr)
 	return success;
 }
 
-bool LLXUIParser::writeBoolValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeBoolValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -817,7 +806,7 @@ bool LLXUIParser::readStringValue(Parser& parser, void* val_ptr)
 	return true;
 }
 
-bool LLXUIParser::writeStringValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeStringValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -855,7 +844,7 @@ bool LLXUIParser::readU8Value(Parser& parser, void* val_ptr)
 	return self.mCurReadNode->getByteValue(1, (U8*)val_ptr);
 }
 
-bool LLXUIParser::writeU8Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeU8Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -879,7 +868,7 @@ bool LLXUIParser::readS8Value(Parser& parser, void* val_ptr)
 	return false;
 }
 
-bool LLXUIParser::writeS8Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeS8Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -903,7 +892,7 @@ bool LLXUIParser::readU16Value(Parser& parser, void* val_ptr)
 	return false;
 }
 
-bool LLXUIParser::writeU16Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeU16Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -927,7 +916,7 @@ bool LLXUIParser::readS16Value(Parser& parser, void* val_ptr)
 	return false;
 }
 
-bool LLXUIParser::writeS16Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeS16Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -945,7 +934,7 @@ bool LLXUIParser::readU32Value(Parser& parser, void* val_ptr)
 	return self.mCurReadNode->getUnsignedValue(1, (U32*)val_ptr);
 }
 
-bool LLXUIParser::writeU32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeU32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -963,7 +952,7 @@ bool LLXUIParser::readS32Value(Parser& parser, void* val_ptr)
 	return self.mCurReadNode->getIntValue(1, (S32*)val_ptr);
 }
 
-bool LLXUIParser::writeS32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeS32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -981,7 +970,7 @@ bool LLXUIParser::readF32Value(Parser& parser, void* val_ptr)
 	return self.mCurReadNode->getFloatValue(1, (F32*)val_ptr);
 }
 
-bool LLXUIParser::writeF32Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeF32Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -999,7 +988,7 @@ bool LLXUIParser::readF64Value(Parser& parser, void* val_ptr)
 	return self.mCurReadNode->getDoubleValue(1, (F64*)val_ptr);
 }
 
-bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -1023,7 +1012,7 @@ bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr)
 	return false;
 }
 
-bool LLXUIParser::writeColor4Value(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -1050,7 +1039,7 @@ bool LLXUIParser::readUIColorValue(Parser& parser, void* val_ptr)
 	return false;
 }
 
-bool LLXUIParser::writeUIColorValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -1079,7 +1068,7 @@ bool LLXUIParser::readUUIDValue(Parser& parser, void* val_ptr)
 	return false;
 }
 
-bool LLXUIParser::writeUUIDValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	LLXMLNodePtr node = self.getNode(stack);
@@ -1098,7 +1087,7 @@ bool LLXUIParser::readSDValue(Parser& parser, void* val_ptr)
 	return true;
 }
 
-bool LLXUIParser::writeSDValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeSDValue(Parser& parser, const void* val_ptr, name_stack_t& stack)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 
@@ -1207,7 +1196,6 @@ const char* NO_VALUE_MARKER = "no_value";
 
 LLSimpleXUIParser::LLSimpleXUIParser(LLSimpleXUIParser::element_start_callback_t element_cb)
 :	Parser(sSimpleXUIReadFuncs, sSimpleXUIWriteFuncs, sSimpleXUIInspectFuncs),
-	mLastWriteGeneration(-1),
 	mCurReadDepth(0),
 	mElementCB(element_cb)
 {
@@ -1338,7 +1326,7 @@ void LLSimpleXUIParser::startElement(const char *name, const char **atts)
 	{	// compound attribute
 		if (child_name.find(".") == std::string::npos) 
 		{
-			mNameStack.push_back(std::make_pair(child_name, newParseGeneration()));
+			mNameStack.push_back(std::make_pair(child_name, true));
 			num_tokens_pushed++;
 			mScope.push_back(child_name);
 		}
@@ -1365,7 +1353,7 @@ void LLSimpleXUIParser::startElement(const char *name, const char **atts)
 			// 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()));
+				mNameStack.push_back(std::make_pair(*token_to_push, true));
 				num_tokens_pushed++;
 			}
 			mScope.push_back(mNameStack.back().first);
@@ -1398,7 +1386,7 @@ bool LLSimpleXUIParser::readAttributes(const char **atts)
 		// 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()));
+			mNameStack.push_back(std::make_pair(*token_to_push, true));
 			num_tokens_pushed++;
 		}
 
@@ -1420,7 +1408,7 @@ bool LLSimpleXUIParser::processText()
 		LLStringUtil::trim(mTextContents);
 		if (!mTextContents.empty())
 		{
-			mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration()));
+			mNameStack.push_back(std::make_pair(std::string("value"), true));
 			mCurAttributeValueBegin = mTextContents.c_str();
 			mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);
 			mNameStack.pop_back();
diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h
index 42a79b4100bd4d23cb975636c6c678a608696f1b..d7cd25696723dd11a104c4435dd9067a5d84bbab 100644
--- a/indra/llxuixml/llxuiparser.h
+++ b/indra/llxuixml/llxuiparser.h
@@ -133,23 +133,23 @@ LOG_CLASS(LLXUIParser);
 	static bool readSDValue(Parser& parser, void* val_ptr);
 
 	//writer helper functions
-	static bool writeFlag(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeBoolValue(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeStringValue(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeU8Value(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeS8Value(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeU16Value(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeS16Value(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeU32Value(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeS32Value(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeF32Value(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeF64Value(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeColor4Value(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeUIColorValue(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeUUIDValue(Parser& parser, const void* val_ptr, const name_stack_t&);
-	static bool writeSDValue(Parser& parser, const void* val_ptr, const name_stack_t&);
-
-	LLXMLNodePtr getNode(const name_stack_t& stack);
+	static bool writeFlag(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeBoolValue(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeStringValue(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeU8Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeS8Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeU16Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeS16Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeU32Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeS32Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeF32Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeF64Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeSDValue(Parser& parser, const void* val_ptr, name_stack_t&);
+
+	LLXMLNodePtr getNode(name_stack_t& stack);
 
 private:
 	Parser::name_stack_t			mNameStack;
@@ -157,9 +157,8 @@ LOG_CLASS(LLXUIParser);
 	// Root of the widget XML sub-tree, for example, "line_editor"
 	LLXMLNodePtr					mWriteRootNode;
 	
-	typedef std::map<S32, LLXMLNodePtr>	out_nodes_t;
+	typedef std::map<std::string, LLXMLNodePtr>	out_nodes_t;
 	out_nodes_t						mOutNodes;
-	S32								mLastWriteGeneration;
 	LLXMLNodePtr					mLastWrittenChild;
 	S32								mCurReadDepth;
 	std::string						mCurFileName;
@@ -226,7 +225,6 @@ LOG_CLASS(LLSimpleXUIParser);
 
 	Parser::name_stack_t			mNameStack;
 	struct XML_ParserStruct*		mParser;
-	S32								mLastWriteGeneration;
 	LLXMLNodePtr					mLastWrittenChild;
 	S32								mCurReadDepth;
 	std::string						mCurFileName;
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index ae8471aa1523180ff43850ab8099cbc2d4d66468..f5581baa1938ea41895461c39973e5c45184738b 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -37,6 +37,8 @@
            tooltip_ref="Command_Build_Tooltip"
            execute_function="Floater.ToolbarToggle"
            execute_parameters="build"
+           is_enabled_function="Agent.IsActionAllowed"
+           is_enabled_parameters="build"
            is_running_function="Floater.IsOpen"
            is_running_parameters="build"
            />
@@ -150,6 +152,16 @@
            is_running_function="Floater.IsOpen"
            is_running_parameters="people"
            />
+  <command name="picks"
+           available_in_toybox="true"
+           icon="Command_Picks_Icon"
+           label_ref="Command_Picks_Label"
+           tooltip_ref="Command_Picks_Tooltip"
+           execute_function="Floater.ToolbarToggle"
+           execute_parameters="picks"
+           is_running_function="Floater.IsOpen"
+           is_running_parameters="picks"
+           />
   <command name="places"
            available_in_toybox="true"
            icon="Command_Places_Icon"
@@ -207,6 +219,8 @@
            tooltip_ref="Command_Speak_Tooltip"
            execute_function="Floater.ToolbarToggle"
            execute_parameters="speak"
+           is_enabled_function="Agent.IsActionAllowed"
+           is_enabled_parameters="speak"
            is_running_function="Floater.IsOpen"
            is_running_parameters="speak"
            />
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 092e69952cf86e4548248e985ba15bb6f956caff..aa2ff646a867116671bd1b1b6856124b00fd0be0 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4246,7 +4246,7 @@
         <key>Type</key>
         <string>Boolean</string>
         <key>Value</key>
-        <integer>0</integer>
+        <integer>1</integer>
     </map>
     <key>InventoryDisplayOutbox</key>
     <map>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index ba4212698563b34dfd5e46247bf010687dab698f..ed29ac796092f83c504cbb4c9312b8f4eadebc94 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -71,6 +71,7 @@
 #include "lltoolpie.h"
 #include "lltoolmgr.h"
 #include "lltrans.h"
+#include "lluictrl.h"
 #include "llurlentry.h"
 #include "llviewercontrol.h"
 #include "llviewerdisplay.h"
@@ -152,6 +153,34 @@ bool handleSlowMotionAnimation(const LLSD& newvalue)
 	return true;
 }
 
+// static
+void LLAgent::parcelChangedCallback()
+{
+	bool can_edit = LLToolMgr::getInstance()->canEdit();
+
+	gAgent.mCanEditParcel = can_edit;
+}
+
+// static
+bool LLAgent::isActionAllowed(const LLSD& sdname)
+{
+	bool retval = false;
+
+	const std::string& param = sdname.asString();
+
+	if (param == "build")
+	{
+		retval = gAgent.canEditParcel();
+	}
+	else if (param == "speak")
+	{
+		retval = true;
+	}
+
+	return retval;
+}
+
+
 // ************************************************************
 // Enabled this definition to compile a 'hacked' viewer that
 // locally believes the end user has godlike powers.
@@ -183,6 +212,7 @@ LLAgent::LLAgent() :
 	mbTeleportKeepsLookAt(false),
 
 	mAgentAccess(new LLAgentAccess(gSavedSettings)),
+	mCanEditParcel(false),
 	mTeleportSourceSLURL(new LLSLURL),
 	mTeleportState( TELEPORT_NONE ),
 	mRegionp(NULL),
@@ -246,6 +276,10 @@ LLAgent::LLAgent() :
 	mListener.reset(new LLAgentListener(*this));
 
 	mMoveTimer.stop();
+
+	LLViewerParcelMgr::getInstance()->addAgentParcelChangedCallback(boost::bind(&LLAgent::parcelChangedCallback));
+
+	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("Agent.IsActionAllowed", boost::bind(&LLAgent::isActionAllowed, _2));
 }
 
 // Requires gSavedSettings to be initialized.
@@ -3361,7 +3395,14 @@ bool LLAgent::teleportCore(bool is_local)
 	LLFloaterReg::hideInstance("region_info");
 
 	// minimize the Search floater (STORM-1474)
-	LLFloaterReg::getInstance("search")->setMinimized(TRUE);
+	{
+		LLFloater* instance = LLFloaterReg::getInstance("search");
+
+		if (instance && instance->getVisible())
+		{
+			instance->setMinimized(TRUE);
+		}
+	}
 
 	LLViewerParcelMgr::getInstance()->deselectLand();
 	LLViewerMediaFocus::getInstance()->clearFocus();
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 5e23ced4243c1b065617869dfa9509715583707a..1775a0235cc351fa38be5f7da659fd758fef3c57 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -575,6 +575,15 @@ class LLAgent : public LLOldEvents::LLObservable
  **                                                                            **
  *******************************************************************************/
 
+	// Build
+public:
+	bool			canEditParcel() const { return mCanEditParcel; }
+private:
+	bool			mCanEditParcel;
+
+	static bool isActionAllowed(const LLSD& sdname);
+	static void parcelChangedCallback();
+
 /********************************************************************************
  **                                                                            **
  **                    ACCESS
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index fa0b392f1b6e80952586a39a2e08dfd1db4cf1c7..5077a0a596bc450bdcf19b198fa54f64dad975d5 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -109,6 +109,7 @@
 
 // Third party library includes
 #include <boost/bind.hpp>
+#include <boost/foreach.hpp>
 
 
 #if LL_WINDOWS
@@ -2041,42 +2042,37 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
 		llerrs << "Invalid settings location list" << llendl;
 	}
 
-	for(LLInitParam::ParamIterator<SettingsGroup>::const_iterator it = mSettingsLocationList->groups.begin(), end_it = mSettingsLocationList->groups.end();
-		it != end_it;
-		++it)
+	BOOST_FOREACH(const SettingsGroup& group, mSettingsLocationList->groups)
 	{
 		// skip settings groups that aren't the one we requested
-		if (it->name() != location_key) continue;
+		if (group.name() != location_key) continue;
 
-		ELLPath path_index = (ELLPath)it->path_index();
+		ELLPath path_index = (ELLPath)group.path_index();
 		if(path_index <= LL_PATH_NONE || path_index >= LL_PATH_LAST)
 		{
 			llerrs << "Out of range path index in app_settings/settings_files.xml" << llendl;
 			return false;
 		}
 
-		LLInitParam::ParamIterator<SettingsFile>::const_iterator file_it, end_file_it;
-		for (file_it = it->files.begin(), end_file_it = it->files.end();
-			file_it != end_file_it;
-			++file_it)
+		BOOST_FOREACH(const SettingsFile& file, group.files)
 		{
-			llinfos << "Attempting to load settings for the group " << file_it->name()
+			llinfos << "Attempting to load settings for the group " << file.name()
 			    << " - from location " << location_key << llendl;
 
-			LLControlGroup* settings_group = LLControlGroup::getInstance(file_it->name);
+			LLControlGroup* settings_group = LLControlGroup::getInstance(file.name);
 			if(!settings_group)
 			{
-				llwarns << "No matching settings group for name " << file_it->name() << llendl;
+				llwarns << "No matching settings group for name " << file.name() << llendl;
 				continue;
 			}
 
 			std::string full_settings_path;
 
-			if (file_it->file_name_setting.isProvided() 
-				&& gSavedSettings.controlExists(file_it->file_name_setting))
+			if (file.file_name_setting.isProvided() 
+				&& gSavedSettings.controlExists(file.file_name_setting))
 			{
 				// try to find filename stored in file_name_setting control
-				full_settings_path = gSavedSettings.getString(file_it->file_name_setting);
+				full_settings_path = gSavedSettings.getString(file.file_name_setting);
 				if (full_settings_path.empty())
 				{
 					continue;
@@ -2090,16 +2086,16 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
 			else
 			{
 				// by default, use specified file name
-				full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, file_it->file_name());
+				full_settings_path = gDirUtilp->getExpandedFilename((ELLPath)path_index, file.file_name());
 			}
 
-			if(settings_group->loadFromFile(full_settings_path, set_defaults, file_it->persistent))
+			if(settings_group->loadFromFile(full_settings_path, set_defaults, file.persistent))
 			{	// success!
 				llinfos << "Loaded settings file " << full_settings_path << llendl;
 			}
 			else
 			{	// failed to load
-				if(file_it->required)
+				if(file.required)
 				{
 					llerrs << "Error: Cannot load required settings file from: " << full_settings_path << llendl;
 					return false;
@@ -2122,20 +2118,15 @@ bool LLAppViewer::loadSettingsFromDirectory(const std::string& location_key,
 std::string LLAppViewer::getSettingsFilename(const std::string& location_key,
 											 const std::string& file)
 {
-	for(LLInitParam::ParamIterator<SettingsGroup>::const_iterator it = mSettingsLocationList->groups.begin(), end_it = mSettingsLocationList->groups.end();
-		it != end_it;
-		++it)
+	BOOST_FOREACH(const SettingsGroup& group, mSettingsLocationList->groups)
 	{
-		if (it->name() == location_key)
+		if (group.name() == location_key)
 		{
-			LLInitParam::ParamIterator<SettingsFile>::const_iterator file_it, end_file_it;
-			for (file_it = it->files.begin(), end_file_it = it->files.end();
-				file_it != end_file_it;
-				++file_it)
+			BOOST_FOREACH(const SettingsFile& settings_file, group.files)
 			{
-				if (file_it->name() == file)
+				if (settings_file.name() == file)
 				{
-					return file_it->file_name;
+					return settings_file.file_name;
 				}
 			}
 		}
diff --git a/indra/newview/llfloatertoybox.cpp b/indra/newview/llfloatertoybox.cpp
index 58bb417b71f74bafd156f4f896217fb6bd749fde..fa60022911013081a486208278c6468140482e90 100644
--- a/indra/newview/llfloatertoybox.cpp
+++ b/indra/newview/llfloatertoybox.cpp
@@ -62,9 +62,9 @@ BOOL LLFloaterToybox::postBuild()
 
 	mBtnRestoreDefaults = getChild<LLButton>("btn_restore_defaults");
 	mToolBar = getChild<LLToolBar>("toybox_toolbar");
-	mToolBar->setStartDragCallback(boost::bind(LLToolBarView::startDragItem,_1,_2,_3));
-	mToolBar->setHandleDragCallback(boost::bind(LLToolBarView::handleDragItem,_1,_2,_3,_4));
-	mToolBar->setHandleDropCallback(boost::bind(LLToolBarView::handleDrop,_1,_2,_3,_4));
+	mToolBar->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
+	mToolBar->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
+	mToolBar->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
 	
 	LLCommandManager& cmdMgr = LLCommandManager::instance();
 
@@ -120,5 +120,16 @@ void LLFloaterToybox::onBtnRestoreDefaults()
 	LLToolBarView::loadDefaultToolbars();
 }
 
+BOOL LLFloaterToybox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+	EDragAndDropType cargo_type,
+	void* cargo_data,
+	EAcceptance* accept,
+	std::string& tooltip_msg)
+{
+	S32 local_x = x - mToolBar->getRect().mLeft;
+	S32 local_y = y - mToolBar->getRect().mBottom;
+	return mToolBar->handleDragAndDrop(local_x, local_y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+}
+
 
 // eof
diff --git a/indra/newview/llfloatertoybox.h b/indra/newview/llfloatertoybox.h
index f7245506c59f183b92638859338a7784deaed942..f0a6cf1a8be509c7f355dea29d3a23b86035cbb1 100644
--- a/indra/newview/llfloatertoybox.h
+++ b/indra/newview/llfloatertoybox.h
@@ -43,6 +43,11 @@ class LLFloaterToybox : public LLFloater
 	// virtuals
 	BOOL postBuild();
 	void draw();
+	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+		EDragAndDropType cargo_type,
+		void* cargo_data,
+		EAcceptance* accept,
+		std::string& tooltip_msg);
 
 protected:
 	void onBtnRestoreDefaults();
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index 95ed603bbfb1f74ca78cffaecb7624a6062eea32..44b244f16368c69f18729b8bf566fcca0a3e4d8f 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -43,6 +43,11 @@ LLToolBarView* gToolBarView = NULL;
 static LLDefaultChildRegistry::Register<LLToolBarView> r("toolbar_view");
 bool LLToolBarView::sDragStarted = false;
 
+bool isToolDragged()
+{
+	return (LLToolDragAndDrop::getInstance()->getSource() == LLToolDragAndDrop::SOURCE_VIEWER);
+}
+
 LLToolBarView::Toolbar::Toolbar()
 :	button_display_mode("button_display_mode"),
 	commands("command")
@@ -80,17 +85,17 @@ BOOL LLToolBarView::postBuild()
 	mToolbarRight  = getChild<LLToolBar>("toolbar_right");
 	mToolbarBottom = getChild<LLToolBar>("toolbar_bottom");
 
-	mToolbarLeft->setStartDragCallback(boost::bind(LLToolBarView::startDragItem,_1,_2,_3));
-	mToolbarLeft->setHandleDragCallback(boost::bind(LLToolBarView::handleDragItem,_1,_2,_3,_4));
-	mToolbarLeft->setHandleDropCallback(boost::bind(LLToolBarView::handleDrop,_1,_2,_3,_4));
+	mToolbarLeft->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
+	mToolbarLeft->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
+	mToolbarLeft->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
 	
-	mToolbarRight->setStartDragCallback(boost::bind(LLToolBarView::startDragItem,_1,_2,_3));
-	mToolbarRight->setHandleDragCallback(boost::bind(LLToolBarView::handleDragItem,_1,_2,_3,_4));
-	mToolbarRight->setHandleDropCallback(boost::bind(LLToolBarView::handleDrop,_1,_2,_3,_4));
+	mToolbarRight->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
+	mToolbarRight->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
+	mToolbarRight->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
 	
-	mToolbarBottom->setStartDragCallback(boost::bind(LLToolBarView::startDragItem,_1,_2,_3));
-	mToolbarBottom->setHandleDragCallback(boost::bind(LLToolBarView::handleDragItem,_1,_2,_3,_4));
-	mToolbarBottom->setHandleDropCallback(boost::bind(LLToolBarView::handleDrop,_1,_2,_3,_4));
+	mToolbarBottom->setStartDragCallback(boost::bind(LLToolBarView::startDragTool,_1,_2,_3));
+	mToolbarBottom->setHandleDragCallback(boost::bind(LLToolBarView::handleDragTool,_1,_2,_3,_4));
+	mToolbarBottom->setHandleDropCallback(boost::bind(LLToolBarView::handleDropTool,_1,_2,_3,_4));
 	
 	return TRUE;
 }
@@ -306,37 +311,34 @@ void LLToolBarView::draw()
 		mToolbarRight->localRectToOtherView(mToolbarRight->getLocalRect(), &right_rect, this);
 	}
 	
-	// Debug draw
-	LLColor4 back_color = LLColor4::blue;
-	LLColor4 back_color_vert = LLColor4::red;
-	LLColor4 back_color_hori = LLColor4::yellow;
-	back_color[VALPHA] = 0.5f;
-	back_color_hori[VALPHA] = 0.5f;
-	back_color_vert[VALPHA] = 0.5f;
-	//gl_rect_2d(getLocalRect(), back_color, TRUE);
-	//gl_rect_2d(bottom_rect, back_color_hori, TRUE);
-	//gl_rect_2d(left_rect, back_color_vert, TRUE);
-	//gl_rect_2d(right_rect, back_color_vert, TRUE);
+	// Draw drop zones if drop of a tool is active
+	if (isToolDragged())
+	{
+		LLColor4 drop_color = LLUIColorTable::instance().getColor( "ToolbarDropZoneColor" );
+		gl_rect_2d(bottom_rect, drop_color, TRUE);
+		gl_rect_2d(left_rect, drop_color, TRUE);
+		gl_rect_2d(right_rect, drop_color, TRUE);
+	}
 	
 	LLUICtrl::draw();
 }
 
 
 // ----------------------------------------
-// Drag and Drop hacks (under construction)
+// Drag and Drop Handling
 // ----------------------------------------
 
 
-void LLToolBarView::startDragItem( S32 x, S32 y, const LLUUID& uuid)
+void LLToolBarView::startDragTool( S32 x, S32 y, const LLUUID& uuid)
 {
-	//llinfos << "Merov debug: startDragItem() : x = " << x << ", y = " << y << llendl;
+	//llinfos << "Merov debug: startDragTool() : x = " << x << ", y = " << y << llendl;
 	LLToolDragAndDrop::getInstance()->setDragStart( x, y );
 	sDragStarted = false;
 }
 
-BOOL LLToolBarView::handleDragItem( S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type)
+BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type)
 {
-//	llinfos << "Merov debug: handleDragItem() : x = " << x << ", y = " << y << ", uuid = " << uuid << llendl;
+//	llinfos << "Merov debug: handleDragTool() : x = " << x << ", y = " << y << ", uuid = " << uuid << llendl;
 	if (LLToolDragAndDrop::getInstance()->isOverThreshold( x, y ))
 	{
 		if (!sDragStarted)
@@ -348,7 +350,7 @@ BOOL LLToolBarView::handleDragItem( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp
 			gClipboard.setSourceObject(uuid,LLAssetType::AT_WIDGET);
 			LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_VIEWER;
 			LLUUID srcID;
-			//llinfos << "Merov debug: handleDragItem() : beginMultiDrag()" << llendl;
+			//llinfos << "Merov debug: handleDragTool() : beginMultiDrag()" << llendl;
 			LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src, srcID);
 			sDragStarted = true;
 			return TRUE;
@@ -362,18 +364,18 @@ BOOL LLToolBarView::handleDragItem( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp
 	return FALSE;
 }
 
-BOOL LLToolBarView::handleDrop( void* cargo_data, S32 x, S32 y, LLToolBar* toolbar)
+BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* toolbar)
 {
 	LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
-	//llinfos << "Merov debug : handleDrop. Drop " << inv_item->getUUID() << " named " << inv_item->getName() << " of type " << inv_item->getType() << llendl;
-		
+	//llinfos << "Merov debug : handleDropTool. Drop " << inv_item->getUUID() << " named " << inv_item->getName() << " of type " << inv_item->getType() << llendl;
+	
 	LLAssetType::EType type = inv_item->getType();
 	if (type == LLAssetType::AT_WIDGET)
 	{
-		//llinfos << "Merov debug : handleDrop. Drop source is a widget -> drop it in place..." << llendl;
+		//llinfos << "Merov debug : handleDropTool. Drop source is a widget -> drop it in place..." << llendl;
 		// Get the command from its uuid
 		LLCommandManager& mgr = LLCommandManager::instance();
-		LLCommandId command_id(inv_item->getUUID());
+		LLCommandId command_id("",inv_item->getUUID());
 		LLCommand* command = mgr.getCommand(command_id);
 		if (command)
 		{
@@ -385,9 +387,10 @@ BOOL LLToolBarView::handleDrop( void* cargo_data, S32 x, S32 y, LLToolBar* toolb
 			}
 			// Suppress the command from the toolbars (including the one it's dropped in, 
 			// this will handle move position).
-			gToolBarView->mToolbarLeft->removeCommand(command->id());
-			gToolBarView->mToolbarRight->removeCommand(command->id());
-			gToolBarView->mToolbarBottom->removeCommand(command->id());
+			llinfos << "Merov debug : handleDropTool, " << command_id.name() << ", " << command_id.uuid() << llendl;
+			gToolBarView->mToolbarLeft->removeCommand(command_id);
+			gToolBarView->mToolbarRight->removeCommand(command_id);
+			gToolBarView->mToolbarBottom->removeCommand(command_id);
 			// Now insert it in the toolbar at the detected rank
 			if (!toolbar->isReadOnly())
 			{
@@ -399,8 +402,11 @@ BOOL LLToolBarView::handleDrop( void* cargo_data, S32 x, S32 y, LLToolBar* toolb
 			llwarns << "Command couldn't be found in command manager" << llendl;
 		}
 	}
-	
+	stopDragTool();
 	return TRUE;
 }
 
-
+void LLToolBarView::stopDragTool()
+{
+	sDragStarted = false;
+}
diff --git a/indra/newview/lltoolbarview.h b/indra/newview/lltoolbarview.h
index 414fcd87515080a74825c2e0c708c712ea63c062..a0c526ac541b694643a2440de775068faf3e468f 100644
--- a/indra/newview/lltoolbarview.h
+++ b/indra/newview/lltoolbarview.h
@@ -74,9 +74,10 @@ class LLToolBarView : public LLUICtrl
 	
 	static bool loadDefaultToolbars();
 	
-	static void startDragItem( S32 x, S32 y, const LLUUID& uuid);
-	static BOOL handleDragItem( S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type);
-	static BOOL handleDrop(	void* cargo_data, S32 x, S32 y, LLToolBar* toolbar);
+	static void startDragTool( S32 x, S32 y, const LLUUID& uuid);
+	static BOOL handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type);
+	static BOOL handleDropTool(	void* cargo_data, S32 x, S32 y, LLToolBar* toolbar);
+	static void stopDragTool();
 	
 protected:
 	friend class LLUICtrlFactory;
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 13dbc5e38637bd3962224a0c03470c02909b651e..41b4dc01e8dc0f252a35d6d00123d5b57baf769f 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1488,7 +1488,8 @@ void LLViewerMedia::setOpenIDCookie()
 			new LLViewerMediaWebProfileResponder(raw_profile_url.getAuthority()),
 			headers);
 
-		doOnetimeEarlyHTTPRequests();
+		// FUI: No longer perform the user_status query
+		//doOnetimeEarlyHTTPRequests();
 	}
 }
 
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index b5cc949ebfe03689f0f5c8c46b58a60dbfeee4a6..8baaa14595fdb8ea0dcb70a44fd5950b5d7e0c2d 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -795,6 +795,10 @@
     <color
      name="DirectChatColor"
      reference="LtOrange" />
+
+    <color
+      name="ToolbarDropZoneColor"
+      value=".48 .69 1 .5" />
   
     <!-- Generic color names (legacy) -->
   <color
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index a98ef58f501b38ef48c8293fb2024aafcb8bc6ea..e7fb836f451e285513e17283ba750d31a76712d9 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -125,29 +125,30 @@ with the same filename but different name
   <texture name="Checkbox_Press" file_name="widgets/Checkbox_Press.png" preload="true" />
   <texture name="Check_Mark" file_name="icons/check_mark" preload="true" />
 
-  <texture name="Command_AboutLand_Icon"    file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Appearance_Icon"   file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Avatar_Icon"       file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Build_Icon"        file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Chat_Icon"         file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Compass_Icon"      file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Destinations_Icon" file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Gestures_Icon"     file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_HowTo_Icon"        file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Inventory_Icon"    file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Map_Icon"          file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Marketplace_Icon"  file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_MiniMap_Icon"      file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Move_Icon"         file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_People_Icon"       file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Places_Icon"       file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Preferences_Icon"  file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Profile_Icon"      file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Search_Icon"       file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Snapshot_Icon"     file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Speak_Icon"        file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_View_Icon"         file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
-  <texture name="Command_Voice_Icon"        file_name="taskpanel/TabIcon_Home_Off.png" preload="true" />
+  <texture name="Command_AboutLand_Icon"    file_name="toolbar_icons/land.png"         preload="true" />
+  <texture name="Command_Appearance_Icon"   file_name="toolbar_icons/appearance.png"   preload="true" />
+  <texture name="Command_Avatar_Icon"       file_name="toolbar_icons/avatars.png"      preload="true" />
+  <texture name="Command_Build_Icon"        file_name="toolbar_icons/build.png"        preload="true" />
+  <texture name="Command_Chat_Icon"         file_name="toolbar_icons/chat.png"         preload="true" />
+  <texture name="Command_Compass_Icon"      file_name="toolbar_icons/land.png"         preload="true" />
+  <texture name="Command_Destinations_Icon" file_name="toolbar_icons/destinations.png" preload="true" />
+  <texture name="Command_Gestures_Icon"     file_name="toolbar_icons/gestures.png"     preload="true" />
+  <texture name="Command_HowTo_Icon"        file_name="toolbar_icons/howto.png"        preload="true" />
+  <texture name="Command_Inventory_Icon"    file_name="toolbar_icons/inventory.png"    preload="true" />
+  <texture name="Command_Map_Icon"          file_name="toolbar_icons/map.png"          preload="true" />
+  <texture name="Command_Marketplace_Icon"  file_name="toolbar_icons/marketplace.png"  preload="true" />
+  <texture name="Command_MiniMap_Icon"      file_name="toolbar_icons/mini_map.png"     preload="true" />
+  <texture name="Command_Move_Icon"         file_name="toolbar_icons/move.png"         preload="true" />
+  <texture name="Command_People_Icon"       file_name="toolbar_icons/people.png"       preload="true" />
+  <texture name="Command_Picks_Icon"        file_name="toolbar_icons/picks.png"        preload="true" />
+  <texture name="Command_Places_Icon"       file_name="toolbar_icons/places.png"       preload="true" />
+  <texture name="Command_Preferences_Icon"  file_name="toolbar_icons/preferences.png"  preload="true" />
+  <texture name="Command_Profile_Icon"      file_name="toolbar_icons/profile.png"      preload="true" />
+  <texture name="Command_Search_Icon"       file_name="toolbar_icons/search.png"       preload="true" />
+  <texture name="Command_Snapshot_Icon"     file_name="toolbar_icons/snapshot.png"     preload="true" />
+  <texture name="Command_Speak_Icon"        file_name="toolbar_icons/speak.png"        preload="true" />
+  <texture name="Command_View_Icon"         file_name="toolbar_icons/view.png"         preload="true" />
+  <texture name="Command_Voice_Icon"        file_name="toolbar_icons/nearbyvoice.png"  preload="true" />
 
   <texture name="ComboButton_Disabled" file_name="widgets/ComboButton_Disabled.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
   <texture name="ComboButton_Selected" file_name="widgets/ComboButton_Selected.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
diff --git a/indra/newview/skins/default/textures/toolbar_icons/appearance.png b/indra/newview/skins/default/textures/toolbar_icons/appearance.png
new file mode 100644
index 0000000000000000000000000000000000000000..e6b13653885bb803839f1ececacd8f10a9b57fbe
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/appearance.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/avatars.png b/indra/newview/skins/default/textures/toolbar_icons/avatars.png
new file mode 100644
index 0000000000000000000000000000000000000000..8fa0600cee51365850e9f4c7d282e37432d15d73
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/avatars.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/build.png b/indra/newview/skins/default/textures/toolbar_icons/build.png
new file mode 100644
index 0000000000000000000000000000000000000000..e21ab3f0e449443ef5ac93f9282098fe34a121fc
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/build.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/chat.png b/indra/newview/skins/default/textures/toolbar_icons/chat.png
new file mode 100644
index 0000000000000000000000000000000000000000..e0dbac495fcea3c9f804befcf18d44c1a306f184
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/chat.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/destinations.png b/indra/newview/skins/default/textures/toolbar_icons/destinations.png
new file mode 100644
index 0000000000000000000000000000000000000000..e2325f083ad37e13fe97eaa2b0aa7d31117b38ae
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/destinations.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/gestures.png b/indra/newview/skins/default/textures/toolbar_icons/gestures.png
new file mode 100644
index 0000000000000000000000000000000000000000..2404bb4e25328057fa3b9f22490bceb0e6af0520
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/gestures.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/howto.png b/indra/newview/skins/default/textures/toolbar_icons/howto.png
new file mode 100644
index 0000000000000000000000000000000000000000..8594d7111333ede852f8c3ea8dc533c205533b5d
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/howto.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/inventory.png b/indra/newview/skins/default/textures/toolbar_icons/inventory.png
new file mode 100644
index 0000000000000000000000000000000000000000..ab3191255e1f6f73176259ec9c6e55a9de190f44
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/inventory.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/land.png b/indra/newview/skins/default/textures/toolbar_icons/land.png
new file mode 100644
index 0000000000000000000000000000000000000000..89ea7604a4210ea76ca3fc680ff50da6eb984166
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/land.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/map.png b/indra/newview/skins/default/textures/toolbar_icons/map.png
new file mode 100644
index 0000000000000000000000000000000000000000..ed1049b7db7cf2a8d10f54aabcacfb58205f9b89
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/map.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/marketplace.png b/indra/newview/skins/default/textures/toolbar_icons/marketplace.png
new file mode 100644
index 0000000000000000000000000000000000000000..62bad20be69817302e64799a0d12d19ca5a70ad3
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/marketplace.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/mini_map.png b/indra/newview/skins/default/textures/toolbar_icons/mini_map.png
new file mode 100644
index 0000000000000000000000000000000000000000..b66af223bb27c0b1f6a6de76d4009a740436b8f7
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/mini_map.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/move.png b/indra/newview/skins/default/textures/toolbar_icons/move.png
new file mode 100644
index 0000000000000000000000000000000000000000..585411078233ed9a823ef9e5cee535e65a8e9bea
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/move.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/nearbyvoice.png b/indra/newview/skins/default/textures/toolbar_icons/nearbyvoice.png
new file mode 100644
index 0000000000000000000000000000000000000000..5bdcb22aa5e7698eada073b07bf7f15ab5452b9b
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/nearbyvoice.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/people.png b/indra/newview/skins/default/textures/toolbar_icons/people.png
new file mode 100644
index 0000000000000000000000000000000000000000..7228ae8e2f17985e31bc955d3725f168f103067e
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/people.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/picks.png b/indra/newview/skins/default/textures/toolbar_icons/picks.png
new file mode 100644
index 0000000000000000000000000000000000000000..4499bf562b5ce3fc093f253cad9e0ce09ff5cd11
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/picks.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/places.png b/indra/newview/skins/default/textures/toolbar_icons/places.png
new file mode 100644
index 0000000000000000000000000000000000000000..97d9fa066c430580aa5b92a9a45c2d75e2668752
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/places.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/preferences.png b/indra/newview/skins/default/textures/toolbar_icons/preferences.png
new file mode 100644
index 0000000000000000000000000000000000000000..df80d926b583a0fe3b25041f0ea024dc8ace6bb6
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/preferences.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/profile.png b/indra/newview/skins/default/textures/toolbar_icons/profile.png
new file mode 100644
index 0000000000000000000000000000000000000000..32fe2bf8ace6f41fef05446d9ea0a14aa4afc05b
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/profile.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/search.png b/indra/newview/skins/default/textures/toolbar_icons/search.png
new file mode 100644
index 0000000000000000000000000000000000000000..bcb11e950d100f3cb33229367754ed0a5f7e9ada
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/search.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/snapshot.png b/indra/newview/skins/default/textures/toolbar_icons/snapshot.png
new file mode 100644
index 0000000000000000000000000000000000000000..d26da9b1d2c78f56bd473c3fad6a891734cb0036
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/snapshot.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/speak.png b/indra/newview/skins/default/textures/toolbar_icons/speak.png
new file mode 100644
index 0000000000000000000000000000000000000000..10cd354c5c571d590bde78888ab06a7d753072a5
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/speak.png differ
diff --git a/indra/newview/skins/default/textures/toolbar_icons/view.png b/indra/newview/skins/default/textures/toolbar_icons/view.png
new file mode 100644
index 0000000000000000000000000000000000000000..5425af87e0e2624a0d4e35c16156a53318ae8364
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/view.png differ
diff --git a/indra/newview/skins/default/xui/en/floater_toybox.xml b/indra/newview/skins/default/xui/en/floater_toybox.xml
index 653788bd3c51b7fe23943ff4b42519bce44a24c0..90b7e906a5d761a279afe9a4080bd152395a212f 100644
--- a/indra/newview/skins/default/xui/en/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/en/floater_toybox.xml
@@ -74,6 +74,7 @@
                           image_color="ButtonImageColor"
                           image_color_disabled="ButtonImageColor"
                           flash_color="ButtonUnselectedFgColor"
+                          halign="left"
                           hover_glow_amount="0.15"
                           display_pressed_state="false" />
   </toolbar>
diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml
index cf566d7d232fc1bbce7b8870f4eb6dcaecfc28b2..96d070ae50942424a4003af9b651c3ebefc88252 100644
--- a/indra/newview/skins/default/xui/en/main_view.xml
+++ b/indra/newview/skins/default/xui/en/main_view.xml
@@ -74,13 +74,6 @@
                           user_resize="false" 
                           name="hud container"
                           width="500">
-              <view top="0"
-                    follows="all"
-                    height="500"
-                    left="0"
-                    mouse_opaque="false"
-                    name="floater_snap_region"
-                    width="500"/>
               <panel follows="left|top"
                      height="19"
                      left="0"
@@ -90,15 +83,6 @@
                      top="0"
                      visible="false"
                      width="1024"/>
-              <panel bottom="500"
-                     follows="left|right|bottom"
-                     height="25"
-                     left="0"
-                     mouse_opaque="false"
-                     tab_stop="false"
-                     name="stand_stop_flying_container"
-                     visible="false"
-                     width="500"/>
             </layout_panel>
             <!--<layout_panel auto_resize="false"
                    min_height="33"
diff --git a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
index 44da813f618b3b18ee997283131beeb83abe8801..bc96bfbab584b31dab65959640b2a8ac227314a9 100644
--- a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
@@ -41,10 +41,10 @@
         <toolbar follows="left|top|bottom"
                  button_panel.bg_opaque_image="Rounded_Rect_Right"
                  name="toolbar_left"
-                 height="500"
                  width="30"
                  left="0"
-                 top="0"
+                 top="10"
+                 bottom="-10"
                  side="left"
                  button_display_mode="icons_only">
         </toolbar>
@@ -52,7 +52,26 @@
       <layout_panel name="non_toolbar_panel"
                     auto_resize="true"
                     user_resize="false"
-                    mouse_opaque="false"/>
+                    mouse_opaque="false"
+                    height="100"
+                    width="100">
+        <view top="0"
+              follows="all"
+              height="100"
+              left="0"
+              mouse_opaque="false"
+              name="floater_snap_region"
+              width="100"/>
+        <panel bottom="100"
+               follows="left|right|bottom"
+               height="25"
+               left="0"
+               mouse_opaque="false"
+               tab_stop="false"
+               name="stand_stop_flying_container"
+               visible="false"
+               width="100"/>
+      </layout_panel>
       <layout_panel name="right_toolbar_panel"
                     auto_resize="false"
                     user_resize="false"
@@ -63,10 +82,10 @@
           button_panel.bg_opaque_image="Rounded_Rect_Left"
           follows="right|top|bottom"
           name="toolbar_right"
-          height="500"
           width="30"
           left="0"
-          top="0"
+          top="10"
+          bottom="-10"
           side="right"
           button_display_mode="icons_only">
         </toolbar>
@@ -83,8 +102,8 @@
              button_panel.bg_opaque_image="Rounded_Rect_Top"
              name="toolbar_bottom"
              height="30"
-             width="1024"
-             left="0"
+             left="40"
+             right="-40"
              top="0"
              side="bottom"
              follows="left|right|bottom"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f021fdd6a16da3be811cf8bc0fc70d5be4416653..d12dda88be405e00cfb248e974959f1bfc4ae2af 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -3668,6 +3668,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_MiniMap_Label">Mini-map</string>
   <string name="Command_Move_Label">Move</string>
   <string name="Command_People_Label">People</string>
+  <string name="Command_Picks_Label">Picks</string>
   <string name="Command_Places_Label">Places</string>
   <string name="Command_Preferences_Label">Preferences</string>
   <string name="Command_Profile_Label">Profile</string>
@@ -3692,6 +3693,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_MiniMap_Tooltip">Show nearby people</string>
   <string name="Command_Move_Tooltip">Moving your avatar</string>
   <string name="Command_People_Tooltip">Friends, groups, and nearby people</string>
+  <string name="Command_Picks_Tooltip">Favorite places</string>
   <string name="Command_Places_Tooltip">Places you've saved</string>
   <string name="Command_Preferences_Tooltip">Preferences</string>
   <string name="Command_Profile_Tooltip">Edit or view your profile</string>
diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
index 613dc6676223413e0297bc151d0a770b71f0d4bc..09967de7cc242ed17ee981311d484c60e8bba80a 100644
--- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
@@ -4,6 +4,7 @@
          pad_top="1"
          pad_bottom="1"
          pad_between="1"
+         min_girth="24"
          mouse_opaque="false"
          read_only="false">
   <button_panel name="button_panel"
@@ -13,6 +14,7 @@
                 background_opaque="true"/>
   <button_icon_and_text imgoverlay_label_space="7"
                         label_color_selected="White"
+                        halign="left"
                         image_pressed="PushButton_Press"
                         image_pressed_selected="PushButton_Selected_Press"
                         image_selected="PushButton_Selected_Press"
@@ -32,11 +34,12 @@
                image_pressed="PushButton_Press"
                image_pressed_selected="PushButton_Selected_Press"
                image_selected="PushButton_Selected_Press"
-               desired_height="35"
-               button_width.min="35"
-               button_width.max="35"               
+               desired_height="38"
+               button_width.min="38"
+               button_width.max="38"               
                follows="left|top"
                label=""
+               halign="left"
                chrome="true"
                use_ellipses="true"
                auto_resize="true"