diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 583bde360a3181d15d9a1813a119b1841c7b5d5e..2518dbe3c73cea0ff101500a39627265cc47b7f5 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -60,7 +60,7 @@ class LLLineEditor
 
 	typedef boost::function<void (LLLineEditor* caller)> keystroke_callback_t;
 	
-	struct MaxLength : public LLInitParam::Choice<MaxLength>
+	struct MaxLength : public LLInitParam::ChoiceBlock<MaxLength>
 	{
 		Alternative<S32> bytes, chars;
 		
diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp
index c4eec1835cdce8178eea2c1acd5d8121be1f92ea..6ac38f5ad40ab0634a8241be158e5b1bf3e0cc7e 100644
--- a/indra/llui/llloadingindicator.cpp
+++ b/indra/llui/llloadingindicator.cpp
@@ -34,6 +34,7 @@
 // Project includes
 #include "lluictrlfactory.h"
 #include "lluiimage.h"
+#include "boost/foreach.hpp"
 
 // registered in llui.cpp to avoid being left out by MS linker
 //static LLDefaultChildRegistry::Register<LLLoadingIndicator> r("loading_indicator");
@@ -51,11 +52,9 @@ LLLoadingIndicator::LLLoadingIndicator(const Params& p)
 
 void LLLoadingIndicator::initFromParams(const Params& p)
 {
-	for (LLInitParam::ParamIterator<LLUIImage*>::const_iterator it = p.images().image.begin(), end_it = p.images().image.end();
-		it != end_it;
-		++it)
+	BOOST_FOREACH(LLUIImage* image, p.images.image)
 	{
-		mImages.push_back(it->getValue());
+		mImages.push_back(image);
 	}
 
 	// Start timer for switching images.
diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h
index 7c444788483bd898c6d4a0d7eb6c0cecd8d37b4f..c1f979c1113f6bb9916c905f178f9e55b09be187 100644
--- a/indra/llui/llloadingindicator.h
+++ b/indra/llui/llloadingindicator.h
@@ -51,7 +51,7 @@ class LLLoadingIndicator
 	LOG_CLASS(LLLoadingIndicator);
 public:
 
-	struct Images : public LLInitParam::Block<Images>
+	struct Images : public LLInitParam::BatchBlock<Images>
 	{
 		Multiple<LLUIImage*>	image;
 
@@ -63,7 +63,7 @@ class LLLoadingIndicator
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
 		Optional<F32>			images_per_sec;
-		Batch<Images>			images;
+		Optional<Images>		images;
 
 		Params()
 		:	images_per_sec("images_per_sec", 1.0f),
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 0c4d4fc897ab187fe36b944cdad4b9fdcff2d12f..462d69be2e1b3bea6eb5339d0eca4d6371682e56 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -201,7 +201,7 @@ class LLNotificationForm
 		FormInput();
 	};
 
-	struct FormElement : public LLInitParam::Choice<FormElement>
+	struct FormElement : public LLInitParam::ChoiceBlock<FormElement>
 	{
 		Alternative<FormButton> button;
 		Alternative<FormInput>	input;
@@ -312,7 +312,7 @@ friend class LLNotifications;
 		Optional<LLNotificationContext*>		context;
 		Optional<void*>							responder;
 
-		struct Functor : public LLInitParam::Choice<Functor>
+		struct Functor : public LLInitParam::ChoiceBlock<Functor>
 		{
 			Alternative<std::string>										name;
 			Alternative<LLNotificationFunctorRegistry::ResponseFunctor>	function;
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index ab777d37a5f4d28095e4ca9b4f0f6d99a47da029..fb50c9c1233b8de79e8d3e27c62b94dce617a35a 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -91,7 +91,7 @@ struct LLNotificationTemplate
 		// <notification> <unique/> </notification>
 		// as well as
 		// <notification> <unique> <context></context> </unique>...
-		Flag			dummy_val;
+		Optional<LLInitParam::Flag>	dummy_val;
 	public:
 		Multiple<UniquenessContext>	contexts;
 
@@ -147,7 +147,7 @@ struct LLNotificationTemplate
 		{}
 	};
 
-	struct FormRef : public LLInitParam::Choice<FormRef>
+	struct FormRef : public LLInitParam::ChoiceBlock<FormRef>
 	{
 		Alternative<LLNotificationForm::Params>		form;
 		Alternative<TemplateRef>					form_template;
diff --git a/indra/llui/llnotificationvisibilityrule.h b/indra/llui/llnotificationvisibilityrule.h
index 78bdec2a8f3ac80591a8acbb540164c2942a9e51..78788a275c7b00150b0e7623da0ed95a0a02550f 100644
--- a/indra/llui/llnotificationvisibilityrule.h
+++ b/indra/llui/llnotificationvisibilityrule.h
@@ -59,7 +59,7 @@ struct LLNotificationVisibilityRule
 		{}
 	};
 
-	struct Rule : public LLInitParam::Choice<Rule>
+	struct Rule : public LLInitParam::ChoiceBlock<Rule>
 	{
 		Alternative<Filter>		show;
 		Alternative<Filter>		hide;
diff --git a/indra/llui/llscrolllistcolumn.h b/indra/llui/llscrolllistcolumn.h
index 12baea8e0c4c7fc9d5787507fd87931023a10dea..b4d4a6d05e7b8168702dfc96356d01669816ebbb 100644
--- a/indra/llui/llscrolllistcolumn.h
+++ b/indra/llui/llscrolllistcolumn.h
@@ -95,7 +95,7 @@ class LLScrollListColumn
 		Optional<ESortDirection, SortNames>	sort_direction;
 		Optional<bool>						sort_ascending;
 
-		struct Width : public LLInitParam::Choice<Width>
+		struct Width : public LLInitParam::ChoiceBlock<Width>
 		{
 			Alternative<bool>	dynamic_width;
 			Alternative<S32>		pixel_width;
@@ -112,7 +112,7 @@ class LLScrollListColumn
 		Optional<Width>						width;
 
 		// either an image or label is used in column header
-		struct Header : public LLInitParam::Choice<Header>
+		struct Header : public LLInitParam::ChoiceBlock<Header>
 		{
 			Alternative<std::string>			label;
 			Alternative<LLUIImage*>			image;
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index 04919e69916046457a4a68cc1ee2233a2f12ff83..4b69360e3302e4d9af063912e33244ca0856a93f 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -45,7 +45,7 @@ LLParamSDParser::LLParamSDParser()
 
 	if (sReadFuncs.empty())
 	{
-		registerParserFuncs<LLInitParam::NoParamValue>(readNoValue, &LLParamSDParser::writeNoValue);
+		registerParserFuncs<LLInitParam::Flag>(readFlag, &LLParamSDParser::writeFlag);
 		registerParserFuncs<S32>(readS32, &LLParamSDParser::writeTypedValue<S32>);
 		registerParserFuncs<U32>(readU32, &LLParamSDParser::writeU32Param);
 		registerParserFuncs<F32>(readF32, &LLParamSDParser::writeTypedValue<F32>);
@@ -72,7 +72,7 @@ bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const voi
 	return true;
 }
 
-bool LLParamSDParser::writeNoValue(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, const parser_t::name_stack_t& name_stack)
 {
 	LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
 	if (!sdparser.mWriteRootSD) return false;
@@ -226,7 +226,7 @@ LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack)
 	return sd_to_write;
 }
 
-bool LLParamSDParser::readNoValue(Parser& parser, void* val_ptr)
+bool LLParamSDParser::readFlag(Parser& parser, void* val_ptr)
 {
 	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
 	return self.mCurReadSD == &NO_VALUE_MARKER;
diff --git a/indra/llui/llsdparam.h b/indra/llui/llsdparam.h
index f776c781b33c642b59537d07adcd6a02fd5076f8..a371c28f68e95deaf77c24c814f90ec87fa320cc 100644
--- a/indra/llui/llsdparam.h
+++ b/indra/llui/llsdparam.h
@@ -63,9 +63,9 @@ typedef LLInitParam::Parser parser_t;
 	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 writeNoValue(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 readNoValue(Parser& parser, void* val_ptr);
+	static bool readFlag(Parser& parser, void* val_ptr);
 	static bool readS32(Parser& parser, void* val_ptr);
 	static bool readU32(Parser& parser, void* val_ptr);
 	static bool readF32(Parser& parser, void* val_ptr);
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 7d545a1ba61970dd4a0e2ad0746a556119b75a33..384d9116fc0b7d6b11bdf788a1ca028911988be2 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -237,7 +237,7 @@ class LLTextBase
 	friend class LLNormalTextSegment;
 	friend class LLUICtrlFactory;
 
-	struct LineSpacingParams : public LLInitParam::Choice<LineSpacingParams>
+	struct LineSpacingParams : public LLInitParam::ChoiceBlock<LineSpacingParams>
 	{
 		Alternative<F32>	multiple;
 		Alternative<S32>	pixels;
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 75c7d91f8a770516a1dd612956cf7309ed1baed4..2592fd1229bf5edaaaf37f42887b69eea331ebd7 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 "lltoolbarview.h"
 
 // uncomment this and remove the one in llui.cpp when there is an external reference to this translation unit
 // thanks, MSVC!
@@ -201,16 +202,16 @@ void LLToolBar::initFromParams(const LLToolBar::Params& p)
 bool LLToolBar::addCommand(const LLCommandId& commandId)
 {
 	LLCommand * command = LLCommandManager::instance().getCommand(commandId);
+	if (!command) return false;
 
-	bool add_command = (command != NULL);
-
-	if (add_command)
-	{
 		mButtonCommands.push_back(commandId);
-		createButton(commandId);
-	}
+	LLToolBarButton* button = createButton(commandId);
+	mButtons.push_back(button);
+	mButtonPanel->addChild(button);
+	mButtonMap.insert(std::make_pair(commandId, button));
+	mNeedsLayout = true;
 
-	return add_command;
+	return true;
 }
 
 void LLToolBar::clearCommandsList()
@@ -223,21 +224,13 @@ void LLToolBar::clearCommandsList()
 
 bool LLToolBar::hasCommand(const LLCommandId& commandId) const
 {
-	bool has_command = false;
-
 	if (commandId != LLCommandId::null)
 	{
-		BOOST_FOREACH(LLCommandId cmd, mButtonCommands)
-		{
-			if (cmd == commandId)
-			{
-				has_command = true;
-				break;
-			}
-		}
+		command_id_map::const_iterator it = mButtonMap.find(commandId);
+		return (it != mButtonMap.end());
 	}
 
-	return has_command;
+	return false;
 }
 
 bool LLToolBar::enableCommand(const LLCommandId& commandId, bool enabled)
@@ -246,11 +239,10 @@ bool LLToolBar::enableCommand(const LLCommandId& commandId, bool enabled)
 	
 	if (commandId != LLCommandId::null)
 	{
-		command_button = mButtonPanel->findChild<LLButton>(commandId.name());
-
-		if (command_button)
+		command_id_map::iterator it = mButtonMap.find(commandId);
+		if (it != mButtonMap.end())
 		{
-			command_button->setEnabled(enabled);
+			it->second->setEnabled(enabled);
 		}
 	}
 
@@ -319,7 +311,7 @@ void LLToolBar::setButtonType(LLToolBarEnums::ButtonType button_type)
 	bool regenerate_buttons = (mButtonType != button_type);
 	
 	mButtonType = button_type;
-	
+
 	if (regenerate_buttons)
 	{
 		createButtons();
@@ -511,14 +503,19 @@ void LLToolBar::createButtons()
 	
 	BOOST_FOREACH(LLCommandId& command_id, mButtonCommands)
 	{
-		createButton(command_id);
+		LLToolBarButton* button = createButton(command_id);
+		mButtons.push_back(button);
+		mButtonPanel->addChild(button);
+		mButtonMap.insert(std::make_pair(command_id, button));
 	}
+	mNeedsLayout = true;
+
 }
 
-void LLToolBar::createButton(const LLCommandId& id)
+LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
 {
 	LLCommand* commandp = LLCommandManager::instance().getCommand(id);
-	if (!commandp) return;
+	if (!commandp) return NULL;
 
 	LLToolBarButton::Params button_p;
 	button_p.name = id.name();
@@ -536,8 +533,48 @@ void LLToolBar::createButton(const LLCommandId& id)
 		button->setCommitCallback(cbParam);
 	}
 
-	mButtons.push_back(button);
-	mButtonPanel->addChild(button);
+	button->setCommandId(id);
+	return button;
 
-	mNeedsLayout = true;
+}
+
+//
+// LLToolBarButton
+//
+
+LLToolBarButton::LLToolBarButton(const Params& p) 
+:	LLButton(p),
+	mMouseDownX(0),
+	mMouseDownY(0),
+	mId("")
+{}
+
+
+BOOL LLToolBarButton::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	mMouseDownX = x;
+	mMouseDownY = y;
+	return LLButton::handleMouseDown(x, y, mask);
+}
+
+BOOL LLToolBarButton::handleHover(S32 x, S32 y, MASK mask)
+{
+	if (hasMouseCapture())
+	{
+		S32 dist_squared = (x - mMouseDownX) * (x - mMouseDownX) + (y - mMouseDownY) * (y - mMouseDownY);
+		S32 threshold = LLUI::sSettingGroups["config"]->getS32("DragAndDropDistanceThreshold");
+		S32 threshold_squared = threshold * threshold;
+		if (dist_squared > threshold_squared)
+		{
+			// start drag and drop
+			LLToolBarView* view = getParentByType<LLToolBarView>();
+			LLToolBar* bar = getParentByType<LLToolBar>();
+			if (view)
+			{
+				//view->startDrag(bar->createButton(mId));
+				//setVisible(FALSE);
+			}
+		}
+	}
+	return LLButton::handleHover(x, y, mask);
 }
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 03b1756988def9c993f86afea017b77511a6a3cc..0bb95f4e9c788b2d33c2646dfc5a23c3bf62bad1 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -42,7 +42,15 @@ class LLToolBarButton : public LLButton
 	{
 	};
 
-	LLToolBarButton(const Params& p) : LLButton(p) {}
+	LLToolBarButton(const Params& p);
+
+	BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+	BOOL handleHover(S32 x, S32 y, MASK mask);
+	void setCommandId(const LLCommandId& id) { mId = id; }
+private:
+	LLCommandId		mId;
+	S32				mMouseDownX;
+	S32				mMouseDownY;
 };
 
 
@@ -124,6 +132,8 @@ class LLToolBar
 	bool hasCommand(const LLCommandId& commandId) const;
 	bool enableCommand(const LLCommandId& commandId, bool enabled);
 
+	LLToolBarButton* createButton(const LLCommandId& id);
+
 protected:
 	friend class LLUICtrlFactory;
 	LLToolBar(const Params&);
@@ -142,7 +152,6 @@ class LLToolBar
 	void createContextMenu();
 	void updateLayoutAsNeeded();
 	void createButtons();
-	void createButton(const LLCommandId& id);
 	void resizeButtonsInRow(std::vector<LLToolBarButton*>& buttons_in_row, S32 max_row_girth);
 	BOOL isSettingChecked(const LLSD& userdata);
 	void onSettingEnable(const LLSD& userdata);
@@ -151,6 +160,9 @@ class LLToolBar
 
 	std::list<LLToolBarButton*>		mButtons;
 	command_id_list_t				mButtonCommands;
+	typedef std::map<LLCommandId, LLToolBarButton*> command_id_map;
+	command_id_map					mButtonMap;
+
 	LLToolBarEnums::ButtonType		mButtonType;
 	LLLayoutStack*					mCenteringStack;
 	LLLayoutStack*					mWrapStack;
diff --git a/indra/llui/lltoolbarview.cpp b/indra/llui/lltoolbarview.cpp
index 12247519ad73a36823f65d3b9958f76e4ff841d7..099657711413ed8c799d77352f239ca5315645f3 100644
--- a/indra/llui/lltoolbarview.cpp
+++ b/indra/llui/lltoolbarview.cpp
@@ -114,7 +114,7 @@ bool LLToolBarView::addCommand(const LLCommandId& command, LLToolBar* toolbar)
 }
 
 bool LLToolBarView::loadToolbars(bool force_default)
-{
+{	
 	LLToolBarView::ToolbarSet toolbar_set;
 	
 	// Load the toolbars.xml file
@@ -221,19 +221,18 @@ void LLToolBarView::saveToolbars() const
 {
 	// Build the parameter tree from the toolbar data
 	LLToolBarView::ToolbarSet toolbar_set;
+	
+	// *TODO : factorize that code a bit...
 	if (mToolbarLeft)
 	{
-		toolbar_set.left_toolbar.button_display_mode = (int)(mToolbarLeft->getButtonType());
 		addToToolset(mToolbarLeft->getCommandsList(),toolbar_set.left_toolbar);
 	}
 	if (mToolbarRight)
 	{
-		toolbar_set.right_toolbar.button_display_mode = (int)(mToolbarRight->getButtonType());
 		addToToolset(mToolbarRight->getCommandsList(),toolbar_set.right_toolbar);
 	}
 	if (mToolbarBottom)
 	{
-		toolbar_set.bottom_toolbar.button_display_mode = (int)(mToolbarBottom->getButtonType());
 		addToToolset(mToolbarBottom->getCommandsList(),toolbar_set.bottom_toolbar);
 	}
 	
@@ -256,19 +255,6 @@ void LLToolBarView::saveToolbars() const
 	}
 }
 
-// Enumerate the commands in command_list and add them as Params to the toolbar
-void LLToolBarView::addToToolset(command_id_list_t& command_list, Toolbar& toolbar) const
-{
-	for (command_id_list_t::const_iterator it = command_list.begin();
-		 it != command_list.end();
-		 ++it)
-	{
-		LLCommandId::Params command;
-		command.name = it->name();		
-		toolbar.commands.add(command);
-	}
-}
-
 void LLToolBarView::draw()
 {
 	static bool debug_print = true;
diff --git a/indra/llui/lltoolbarview.h b/indra/llui/lltoolbarview.h
index 95c09ece7359f4debc91b9ae629c222c24bbc8d3..20525a22ac3110c46e97dcd3a203ad354f149a5c 100644
--- a/indra/llui/lltoolbarview.h
+++ b/indra/llui/lltoolbarview.h
@@ -51,7 +51,7 @@ class LLToolBarView : public LLUICtrl
 	struct Toolbar : public LLInitParam::Block<Toolbar>
 	{
 		Mandatory<U32>                button_display_mode;
-		Multiple<LLCommandId::Params> commands;
+		Multiple<LLCommandId::Params>	commands;
 		Toolbar();
 	};
 	struct ToolbarSet : public LLInitParam::Block<ToolbarSet>
@@ -66,7 +66,6 @@ class LLToolBarView : public LLUICtrl
 	virtual ~LLToolBarView();
 	virtual BOOL postBuild();
 	virtual void draw();
-
 	// Toolbar view interface with the rest of the world
 	// Checks if the commandId is being used somewhere in one of the toolbars
 	bool hasCommand(const LLCommandId& commandId) const;
@@ -90,6 +89,10 @@ class LLToolBarView : public LLUICtrl
 	LLToolBar*	mToolbarLeft;
 	LLToolBar*	mToolbarRight;
 	LLToolBar*	mToolbarBottom;
+	bool		mDragging;
+	LLToolBarButton* mDragButton;
+	S32			mMouseX;
+	S32			mMouseY;
 };
 
 extern LLToolBarView* gToolBarView;
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 4f129ccfba110ca6516bfcdbc56dbca5c6c808e4..76a12e649b4d7e5c44f4cef7a7de8bdc59042359 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -2107,7 +2107,7 @@ namespace LLInitParam
 
 	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
 	{
-		if (control.isProvided())
+		if (control.isProvided() && !control().empty())
 		{
 			updateValue(LLUIColorTable::instance().getColor(control));
 		}
@@ -2264,9 +2264,11 @@ namespace LLInitParam
 		// in this case, that is left+width and bottom+height
 		LLRect& value = getValue();
 
+		right.set(value.mRight, false);
 		left.set(value.mLeft, make_block_authoritative);
 		width.set(value.getWidth(), make_block_authoritative);
 
+		top.set(value.mTop, false);
 		bottom.set(value.mBottom, make_block_authoritative);
 		height.set(value.getHeight(), make_block_authoritative);
 	}
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 7801a01acebbc0a1d998e2939f701093a61e9145..3afb7c65a90b604f06ae3cbaf821119b135cd919 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -365,7 +365,7 @@ template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(
 template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass);
 
 // useful parameter blocks
-struct TimeIntervalParam : public LLInitParam::Choice<TimeIntervalParam>
+struct TimeIntervalParam : public LLInitParam::ChoiceBlock<TimeIntervalParam>
 {
 	Alternative<F32>		seconds;
 	Alternative<S32>		frames;
diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h
index 76518789ec0b7d9437dfcea0c527d6a58fe2f0db..6a7a681d57a005775764cda908c343023439ea82 100644
--- a/indra/llui/lluicolortable.h
+++ b/indra/llui/lluicolortable.h
@@ -44,7 +44,7 @@ LOG_CLASS(LLUIColorTable);
 	typedef std::map<std::string, LLUIColor>  string_color_map_t;
 
 public:
-	struct ColorParams : LLInitParam::Choice<ColorParams>
+	struct ColorParams : LLInitParam::ChoiceBlock<ColorParams>
 	{
 		Alternative<LLColor4>    value;
 		Alternative<std::string> reference;
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index fc56e5fc35f2aa2a3bb495b8e561b6559019ccad..a8a4e3191d043d83dfa913d2acb4dc3760db6c50 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -76,14 +76,14 @@ class LLUICtrl
 		Optional<enable_callback_t> function;
 	};
 		
-	struct EnableControls : public LLInitParam::Choice<EnableControls>
+	struct EnableControls : public LLInitParam::ChoiceBlock<EnableControls>
 	{
 		Alternative<std::string> enabled;
 		Alternative<std::string> disabled;
 		
 		EnableControls();
 	};	
-	struct ControlVisibility : public LLInitParam::Choice<ControlVisibility>
+	struct ControlVisibility : public LLInitParam::ChoiceBlock<ControlVisibility>
 	{
 		Alternative<std::string> visible;
 		Alternative<std::string> invisible;
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 71c38237c1938fd2275ce1316830aab4eeff31d7..d612ad5005d19afebbbdbbc15d92e008396e92ad 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -125,12 +125,12 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 
 	// base case for recursion, there are NO base classes of LLInitParam::BaseBlock
 	template<int DUMMY>
-	class ParamDefaults<LLInitParam::BaseBlockWithFlags, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlockWithFlags, DUMMY> >
+	class ParamDefaults<LLInitParam::BaseBlock, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlock, DUMMY> >
 	{
 	public:
-		const LLInitParam::BaseBlockWithFlags& get() { return mBaseBlock; }
+		const LLInitParam::BaseBlock& get() { return mBaseBlock; }
 	private:
-		LLInitParam::BaseBlockWithFlags mBaseBlock;
+		LLInitParam::BaseBlock mBaseBlock;
 	};
 
 public:
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 9039366e7e3ab5eb2414c33521666c73bf3e1416..a1c46f3bf3a629088d298c4aceed658fa5c612a1 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -98,7 +98,7 @@ class LLViewDrawContext
 class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElement
 {
 public:
-	struct Follows : public LLInitParam::Choice<Follows>
+	struct Follows : public LLInitParam::ChoiceBlock<Follows>
 	{
 		Alternative<std::string>	string;
 		Alternative<U32>			flags;
@@ -465,6 +465,20 @@ class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElem
 		return dynamic_cast<T*>(widgetp);
 	}
 
+	template <class T> T* getParentByType() const
+	{
+		LLView* parent = getParent();
+		while(parent)
+		{
+			if (dynamic_cast<T*>(parent))
+			{
+				return static_cast<T*>(parent);
+			}
+			parent = parent->getParent();
+		}
+		return NULL;
+	}
+
 	//////////////////////////////////////////////
 	// statics
 	//////////////////////////////////////////////
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index c024fd405e7c947dd5d9de13d66b226b84eafeb4..99016205c857cc7eacc00a5a3266cd08cf003669 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -365,7 +365,7 @@ namespace LLInitParam
 		// verify by calling readValue with NoParamValue type, an inherently unparseable type
 		if (!names_left)
 		{
-			NoParamValue no_value;
+			Flag no_value;
 			return p.readValue(no_value);
 		}
 
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 69dcd474f7dacf371bfd651462b08d90eb613609..9a6ded47ffe956127601117769f15166d45df371 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -38,6 +38,9 @@
 
 namespace LLInitParam
 {
+	// used to indicate no matching value to a given name when parsing
+	struct Flag{};
+
 	template<typename T> const T& defaultValue() { static T value; return value; }
 
 	template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
@@ -65,6 +68,12 @@ namespace LLInitParam
 		static bool equals(const LLSD &a, const LLSD &b) { return false; }
 	};
 
+	template<>
+	struct ParamCompare<Flag, false>
+	{
+		static bool equals(const Flag& a, const Flag& b) { return false; }
+	};
+
 	// helper functions and classes
 	typedef ptrdiff_t param_handle_t;
 
@@ -275,9 +284,6 @@ namespace LLInitParam
 		static S32					sNextParseGeneration;
 	};
 
-	// used to indicate no matching value to a given name when parsing
-	struct NoParamValue{};
-
 	class BaseBlock;
 
 	class Param
@@ -385,36 +391,36 @@ namespace LLInitParam
 		// "Multiple" constraint types, put here in root class to avoid ambiguity during use
 		struct AnyAmount
 		{
-			static U32 minCount() { return 0; }
-			static U32 maxCount() { return U32_MAX; }
+			enum { minCount = 0 };
+			enum { maxCount = U32_MAX };
 		};
 
 		template<U32 MIN_AMOUNT>
 		struct AtLeast
 		{
-			static U32 minCount() { return MIN_AMOUNT; }
-			static U32 maxCount() { return U32_MAX; }
+			enum { minCount = MIN_AMOUNT };
+			enum { maxCount = U32_MAX };
 		};
 
 		template<U32 MAX_AMOUNT>
 		struct AtMost
 		{
-			static U32 minCount() { return 0; }
-			static U32 maxCount() { return MAX_AMOUNT; }
+			enum { minCount = 0 };
+			enum { maxCount = MAX_AMOUNT };
 		};
 
 		template<U32 MIN_AMOUNT, U32 MAX_AMOUNT>
 		struct Between
 		{
-			static U32 minCount() { return MIN_AMOUNT; }
-			static U32 maxCount() { return MAX_AMOUNT; }
+			enum { minCount = MIN_AMOUNT };
+			enum { maxCount = MAX_AMOUNT };
 		};
 
 		template<U32 EXACT_COUNT>
 		struct Exactly
 		{
-			static U32 minCount() { return EXACT_COUNT; }
-			static U32 maxCount() { return EXACT_COUNT; }
+			enum { minCount = EXACT_COUNT };
+			enum { maxCount = EXACT_COUNT };
 		};
 
 		// this typedef identifies derived classes as being blocks
@@ -477,9 +483,9 @@ namespace LLInitParam
 		void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
 
 
-		bool mergeBlockParam(bool param_provided, BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
 		{
-			return mergeBlock(block_data, other, overwrite);
+			return mergeBlock(block_data, source, overwrite);
 		}
 		// take all provided params from other and apply to self
 		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
@@ -497,92 +503,6 @@ namespace LLInitParam
 		const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
 	};
 
-	class BaseBlockWithFlags : public BaseBlock
-	{
-	public:
-		class FlagBase : public Param
-		{
-		public:
-			typedef FlagBase self_t;
-
-			FlagBase(const char* name, BaseBlock* enclosing_block) : Param(enclosing_block) 
-			{
-				if (LL_UNLIKELY(enclosing_block->mostDerivedBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
-				{
-					ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
-						enclosing_block->getHandleFromParam(this),
-						&mergeWith,
-						&deserializeParam,
-						&serializeParam,
-						NULL,
-						&inspectParam,
-						0, 1));
-					BaseBlock::addParam(enclosing_block->mostDerivedBlockDescriptor(), param_descriptor, name);
-				}
-			}
-
-			bool isProvided() const { return anyProvided(); }
-
-		private:
-			static bool mergeWith(Param& dst, const Param& src, bool overwrite)
-			{
-				const self_t& src_typed_param = static_cast<const self_t&>(src);
-				self_t& dst_typed_param = static_cast<self_t&>(dst);
-
-				if (src_typed_param.isProvided()
-					&& (overwrite || !dst_typed_param.isProvided()))
-				{
-					dst.setProvided(true);
-					return true;
-				}
-				return false;
-			}
-
-			static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation)
-			{
-				self_t& typed_param = static_cast<self_t&>(param);
-
-				// no further names in stack, parse value now
-				if (name_stack.first == name_stack.second)
-				{
-					typed_param.setProvided(true);
-					typed_param.enclosingBlock().paramChanged(param, true);
-					return true;
-				}
-
-				return false;
-			}
-
-			static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
-			{
-				const self_t& typed_param = static_cast<const self_t&>(param);
-				const self_t* typed_diff_param = static_cast<const self_t*>(diff_param);
-
-				if (!typed_param.isProvided()) return;
-
-				if (!name_stack.empty())
-				{
-					name_stack.back().second = parser.newParseGeneration();
-				}
-
-				// then try to serialize value directly
-				if (!typed_diff_param || !typed_diff_param->isProvided())
-				{
-					if (!parser.writeValue(NoParamValue(), name_stack)) 
-					{
-						return;
-					}
-				}
-			}
-
-			static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
-			{
-				// tell parser about our actual type
-				parser.inspectValue<NoParamValue>(name_stack, min_count, max_count, NULL);
-			}
-		};
-	};
-
 	// these templates allow us to distinguish between template parameters
 	// that derive from BaseBlock and those that don't
 	template<typename T, typename Void = void>
@@ -604,7 +524,7 @@ namespace LLInitParam
 		typedef const T&							value_assignment_t;
 
 		ParamValue(): mValue() {}
-		ParamValue(const T& other) : mValue(other) {}
+		ParamValue(value_assignment_t other) : mValue(other) {}
 
 		void setValue(value_assignment_t val)
 		{
@@ -621,6 +541,17 @@ namespace LLInitParam
 			return mValue;
 		}
 
+		operator value_assignment_t() const
+		{
+			return mValue;
+		}
+
+		value_assignment_t operator()() const
+		{
+			return mValue;
+		}
+
+
 	private:
 		T mValue;
 	};
@@ -644,7 +575,7 @@ namespace LLInitParam
 			mValidated(false)
 		{}
 
-		ParamValue(const T& other)
+		ParamValue(value_assignment_t other)
 		:	T(other),
 			mKeyVersion(0),
 			mValidatedVersion(-1),
@@ -666,6 +597,16 @@ namespace LLInitParam
 		{
 			return *this;
 		}
+
+		operator value_assignment_t() const
+		{
+			return *this;
+		}
+		
+		value_assignment_t operator()() const
+		{
+			return *this;
+		}
 	};
 
 	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
@@ -801,11 +742,6 @@ namespace LLInitParam
 			Param::enclosingBlock().paramChanged(*this, flag_as_provided);
 		}
 
-		// implicit conversion
-		operator value_assignment_t() const { return param_value_t::getValue(); } 
-		// explicit conversion
-		value_assignment_t operator()() const { return param_value_t::getValue(); } 
-
 	protected:
 
 		static bool mergeWith(Param& dst, const Param& src, bool overwrite)
@@ -958,11 +894,6 @@ namespace LLInitParam
 			}
 		}
 
-		// implicit conversion
-		operator value_assignment_t() const { return param_value_t::getValue(); } 
-		// explicit conversion
-		value_assignment_t operator()() const { return param_value_t::getValue(); } 
-
 	protected:
 
 		static bool mergeWith(Param& dst, const Param& src, bool overwrite)
@@ -972,8 +903,7 @@ namespace LLInitParam
 
 			if (src_typed_param.anyProvided())
 			{
-				bool param_provided = src_typed_param.isProvided() && (overwrite || !dst_typed_param.isProvided());
-				if (dst_typed_param.mergeBlockParam(param_provided, param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
+				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
 				{
 					dst_typed_param.clearValueName();
 					dst_typed_param.setProvided(true);
@@ -992,8 +922,8 @@ 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 ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>					param_value_t;
+		typedef typename std::vector<param_value_t>					container_t;
 		typedef const container_t&											value_assignment_t;
 
 		typedef VALUE_TYPE													value_t;
@@ -1118,6 +1048,8 @@ namespace LLInitParam
 
 		// implicit conversion
 		operator value_assignment_t() const { return mValues; } 
+		// explicit conversion		
+		value_assignment_t operator()() const { return mValues; }
 
 		typedef typename container_t::iterator iterator;
 		typedef typename container_t::const_iterator const_iterator;
@@ -1169,7 +1101,7 @@ namespace LLInitParam
 	public:
 		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>	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;
 		typedef NAME_VALUE_LOOKUP										name_value_lookup_t;
@@ -1308,6 +1240,8 @@ namespace LLInitParam
 
 		// implicit conversion
 		operator value_assignment_t() const { return mValues; } 
+		// explicit conversion
+		value_assignment_t operator()() const { return mValues; }
 
 		typedef typename container_t::iterator iterator;
 		typedef typename container_t::const_iterator const_iterator;
@@ -1363,10 +1297,10 @@ namespace LLInitParam
 	};
 
 	template <typename DERIVED_BLOCK>
-	class Choice : public BaseBlock
+	class ChoiceBlock : public BaseBlock
 	{
-		typedef Choice<DERIVED_BLOCK>	self_t;
-		typedef Choice<DERIVED_BLOCK>	enclosing_block_t;
+		typedef ChoiceBlock<DERIVED_BLOCK>	self_t;
+		typedef ChoiceBlock<DERIVED_BLOCK>	enclosing_block_t;
 		
 		LOG_CLASS(self_t);
 	public:
@@ -1382,11 +1316,13 @@ namespace LLInitParam
 			return mergeBlock(selfBlockDescriptor(), other, false);
 		}
 
-		bool mergeBlockParam(bool param_provided, BlockDescriptor& block_data, const self_t& other, bool overwrite)
+		bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
 		{
-			if (param_provided)
+			bool source_override = source_provided && (overwrite || !dest_provided);
+
+			if (source_override || source.mCurChoice == mCurChoice)
 			{
-				return mergeBlock(block_data, other, overwrite);
+				return mergeBlock(block_data, source, overwrite);
 			}
 			return false;
 		}
@@ -1420,7 +1356,7 @@ namespace LLInitParam
 		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
 
 	protected:
-		Choice()
+		ChoiceBlock()
 		:	mCurChoice(0)
 		{
 			BaseBlock::init(selfBlockDescriptor(), BaseBlock::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
@@ -1433,13 +1369,13 @@ namespace LLInitParam
 		class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
 		public:
-			friend class Choice<DERIVED_BLOCK>;
+			friend class ChoiceBlock<DERIVED_BLOCK>;
 
 			typedef Alternative<T, NAME_VALUE_LOOKUP>									self_t;
 			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;
 			typedef typename super_t::value_assignment_t								value_assignment_t;
 
-			explicit Alternative(const char* name, value_assignment_t val = defaultValue<T>())
+			explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>())
 			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
 				mOriginalValue(val)
 			{
@@ -1454,10 +1390,19 @@ namespace LLInitParam
 				}
 			}
 
-			Alternative& operator=(value_assignment_t val)
+			void choose()
+			{
+				static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true);
+			}
+
+			void chooseAs(value_assignment_t val)
+			{
+				super_t::set(val);
+			}
+
+			void operator=(value_assignment_t val)
 			{
 				super_t::set(val);
-				return *this;
 			}
 
 			void operator()(typename super_t::value_assignment_t val) 
@@ -1466,12 +1411,8 @@ namespace LLInitParam
 			}
 
 			operator value_assignment_t() const 
-			{ 
-				if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
-				{
-					return super_t::getValue(); 
-				}
-				return mOriginalValue;
+			{
+				return (*this)();
 			} 
 
 			value_assignment_t operator()() const 
@@ -1508,7 +1449,7 @@ namespace LLInitParam
 		}
 	};
 
-	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlockWithFlags>
+	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
 	class Block 
 	:	public BASE_BLOCK
 	{
@@ -1604,13 +1545,6 @@ namespace LLInitParam
 
 		};
 
-		class Flag : public BaseBlockWithFlags::FlagBase
-		{
-		public:
-			Flag(const char* name) : FlagBase(name, DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
-			{}
-		};
-
 		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
 		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
 		{
@@ -1623,7 +1557,7 @@ namespace LLInitParam
 			typedef typename super_t::const_iterator								const_iterator;
 
 			explicit Multiple(const char* name = "")
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount(), RANGE::maxCount())
+			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
 			{}
 
 			Multiple& operator=(value_assignment_t val)
@@ -1641,100 +1575,10 @@ namespace LLInitParam
 			static bool validate(const Param* paramp) 
 			{
 				U32 num_valid = ((super_t*)paramp)->numValidElements();
-				return RANGE::minCount() <= num_valid && num_valid <= RANGE::maxCount();
+				return RANGE::minCount <= num_valid && num_valid <= RANGE::maxCount;
 			}
 		};
 
-		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
-		class Batch : private TypedParam<T, NAME_VALUE_LOOKUP, false>
-		{
-		public:
-			typedef ParamValue<T, NAME_VALUE_LOOKUP>										param_value_t;
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<param_value_t>::value>	super_t;
-			typedef Batch<T, RANGE, NAME_VALUE_LOOKUP>										self_t;
-			typedef typename super_t::value_assignment_t									value_assignment_t;
-			typedef typename super_t::value_t												value_t;
-
-			struct BatchDefaultValue : public ParamDescriptor::UserData
-			{
-				BatchDefaultValue(const T& value)
-				:	mValue(value)
-				{}
-
-				T mValue;
-			};
-
-			explicit Batch(const char* name, value_assignment_t val)
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
-				mLastParseGeneration(-1)
-			{
-				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
-				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
-				{
-					ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this);
-
-					if (param_descriptorp)
-					{
-						param_descriptorp->mDeserializeFunc = &deserializeParam;
-						param_descriptorp->mUserData = new BatchDefaultValue(new param_value_t(val));
-					}
-				}
-			}
-
-			explicit Batch(const char* name = "")
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, defaultValue<T>(), NULL, 0, 1),
-				mLastParseGeneration(-1)
-			{
-				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
-				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
-				{
-					ParamDescriptorPtr param_descriptorp = block_descriptor.mCurrentBlockPtr->findParamDescriptor(*this);
-
-					if (param_descriptorp)
-					{
-						param_descriptorp->mDeserializeFunc = &deserializeParam;
-					}
-				}
-			}
-
-			Batch& operator=(value_assignment_t val)
-			{
-				set(val);
-				return *this;
-			}
-
-			DERIVED_BLOCK& operator()(value_assignment_t val)
-			{
-				super_t::set(val);
-				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
-			}
-
-			using super_t::operator();
-
-		private:
-			static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack, S32 generation) 
-			{
-				self_t& typed_param = static_cast<self_t&>(param);
-
-				if (generation != typed_param.mLastParseGeneration)
-				{
-					ParamDescriptorPtr descriptor = typed_param.enclosingBlock().findParamDescriptor(param);
-					if (descriptor && static_cast<BatchDefaultValue*>(descriptor->mUserData))
-					{
-						static_cast<param_value_t&>(typed_param) = (static_cast<BatchDefaultValue*>(descriptor->mUserData))->mValue;
-					}
-					else
-					{
-						static_cast<param_value_t&>(typed_param) = param_value_t(value_t());
-					}
-					typed_param.mLastParseGeneration = generation;
-				}
-				return super_t::deserializeParam(param, parser, name_stack, generation);
-			}
-
-			S32 mLastParseGeneration;
-		};
-
 		class Deprecated : public Param
 		{
 		public:
@@ -1769,6 +1613,7 @@ namespace LLInitParam
 			}
 		};
 
+		// different semantics for documentation purposes, but functionally identical
 		typedef Deprecated Ignored;
 
 	protected:
@@ -1790,6 +1635,106 @@ namespace LLInitParam
 
 	};
 	
+	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
+	class BatchBlock
+	:	public Block<DERIVED_BLOCK, BASE_BLOCK>
+	{
+	public:
+		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
+		typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t;
+
+		BatchBlock()
+		:	mLastParseGeneration(-1)
+		{}
+
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, S32 generation)
+		{
+			if (generation != mLastParseGeneration)
+			{
+				// reset block
+				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
+				mLastParseGeneration = generation;
+			}
+			return super_t::deserializeBlock(p, name_stack, generation);
+		}
+
+		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+		{
+			if (overwrite)
+			{
+				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
+				mLastParseGeneration = -1;
+				// merge individual parameters into destination
+				return super_t::mergeBlock(super_t::selfBlockDescriptor(), src_typed_param, overwrite);
+			}
+			return false;
+		}
+	protected:
+		static const DERIVED_BLOCK& defaultBatchValue()
+		{
+			static DERIVED_BLOCK default_value;
+			return default_value;
+		}
+
+		S32 mLastParseGeneration;
+	};
+
+	
+
+	template<typename DERIVED_BLOCK,
+			typename BASE_BLOCK,
+			typename NAME_VALUE_LOOKUP>
+	class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>,
+					NAME_VALUE_LOOKUP,
+					true>
+	:	public Param,
+		protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK>
+	{
+		typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>&	value_assignment_t;
+
+		ParamValue()
+		:	T(),
+			mKeyVersion(0),
+			mValidatedVersion(-1),
+			mValidated(false)
+		{}
+
+		ParamValue(value_assignment_t other)
+		:	T(other),
+			mKeyVersion(0),
+			mValidatedVersion(-1),
+			mValidated(false)
+		{
+		}
+
+		void setValue(value_assignment_t val)
+		{
+			*this = val;
+			mLastParseGeneration = -1;
+		}
+
+		value_assignment_t getValue() const
+		{
+			return *this;
+		}
+
+		BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& getValue()
+		{
+			return *this;
+		}
+
+		operator value_assignment_t() const
+		{
+			return *this;
+		}
+
+		value_assignment_t operator()() const
+		{
+			return *this;
+		}
+
+	};
+
 	template<typename T>
 	class CustomParamValue
 	:	public Block<ParamValue<T, TypeValues<T> > >,
@@ -1955,6 +1900,16 @@ namespace LLInitParam
 			return mValue;
 		}
 
+		operator value_assignment_t() const
+		{
+			return getValue();
+		}
+
+		value_assignment_t operator()() const
+		{
+			return getValue();
+		}
+
 		S32 				mKeyVersion;
 
 	protected:
@@ -1965,30 +1920,29 @@ namespace LLInitParam
 			mValue = value;
 		}
 
-		bool mergeBlockParam(bool param_provided, BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
 		{
-			if (param_provided)
-			{
-				return mergeBlock(block_data, other, overwrite);
-			}
-			return false;
-		}
+			bool source_override = source_provided && (overwrite || !dst_provided);
 
-		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
-		{
-			const derived_t& src_typed_param = static_cast<const derived_t&>(other);
+			const derived_t& src_typed_param = static_cast<const derived_t&>(source);
 
-			if (src_typed_param.mValueAge == VALUE_AUTHORITATIVE)
+			if (source_override && src_typed_param.mValueAge == VALUE_AUTHORITATIVE)
 			{
 				// copy value over
 				setValue(src_typed_param.getValue());
 				return true;
 			}
-			else
+			// merge individual parameters into destination
+			if (mValueAge == VALUE_AUTHORITATIVE)
 			{
-				// merge individual parameters into destination
-				return block_t::mergeBlock(block_t::selfBlockDescriptor(), src_typed_param, overwrite);
+				static_cast<derived_t*>(this)->updateBlockFromValue(dst_provided);
 			}
+			return mergeBlock(block_data, source, overwrite);
+		}
+
+		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& source, bool overwrite)
+		{
+			return block_t::mergeBlock(block_data, source, overwrite);
 		}
 
 		mutable S32			mValidatedVersion;
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index 4af077b22c09b52e5e7b58ec33cae342f80e1d3f..c60f656c2ca11801b4b4b5a3ce28439376e51bef 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -51,6 +51,136 @@ static 	LLInitParam::Parser::parser_read_func_map_t sXSDReadFuncs;
 static 	LLInitParam::Parser::parser_write_func_map_t sXSDWriteFuncs;
 static 	LLInitParam::Parser::parser_inspect_func_map_t sXSDInspectFuncs;
 
+struct MaxOccur : public LLInitParam::ChoiceBlock<MaxOccur>
+{
+	Alternative<int> count;
+	Alternative<std::string> unbounded;
+
+	MaxOccur()
+	:	unbounded("", "unbounded")
+	{}
+};
+
+struct Occurs : public LLInitParam::Block<Occurs>
+{
+	Optional<S32>	minOccurs;
+	Optional<MaxOccur>	maxOccurs;
+
+	Occurs()
+	:	minOccurs("minOccurs"),
+		maxOccurs("maxOccurs")
+	{
+		minOccurs = 0;
+		maxOccurs.unbounded.choose();
+	}
+};
+
+
+typedef enum
+{
+	USE_REQUIRED,
+	USE_OPTIONAL
+} EUse;
+
+namespace LLInitParam
+{
+	template<>
+	struct TypeValues<EUse> : public TypeValuesHelper<EUse>
+	{
+		static void declareValues()
+		{
+			declare("required", USE_REQUIRED);
+			declare("optional", USE_OPTIONAL);
+		}
+	};
+}
+
+struct Name : public LLInitParam::Block<Name>
+{
+	Mandatory<std::string> name;
+
+	Name()
+	:	name("name")
+	{}
+};
+
+struct Attribute : public LLInitParam::Block<Attribute>
+{
+	Mandatory<Name>			name;
+	Mandatory<std::string>	type;
+	Mandatory<EUse>			use;
+	
+	Attribute()
+	:	name("name"),
+		type("type"),
+		use("use")
+	{
+	}
+};
+
+struct ComplexType : public LLInitParam::Block<ComplexType>
+{
+	Multiple<Attribute>			attribute;
+	//Multiple<struct Element>	elements;
+	Optional<bool>				mixed;
+
+	ComplexType()
+	:	attribute("xs:attribute"),
+		//elements("xs:element"),
+		mixed("mixed")
+	{
+		mixed = true;
+	}
+};
+
+struct Element : public LLInitParam::Block<Element, Occurs>
+{
+	Mandatory<ComplexType>	complexType;
+	Mandatory<Name>			name;
+
+	Element()
+	:	complexType("xs:complexType")
+	{}
+};
+
+struct Elements : public LLInitParam::Block<Elements, Occurs>
+{
+	Multiple<Element> elements;
+
+	Elements()
+	:	elements("xs:element")
+	{}
+};
+
+struct Schema : public LLInitParam::Block<Schema>
+{
+private:
+	Mandatory<std::string>	targetNamespace,
+							xmlns;
+
+public:
+	Optional<std::string>	attributeFormDefault,
+							elementFormDefault,
+							xs;
+
+	Optional<Elements>		elements;
+	
+	void setNameSpace(const std::string& ns) {targetNamespace = ns; xmlns = ns;}
+
+	Schema()
+	:	attributeFormDefault("attributeFormDefault"),
+		elementFormDefault("elementFormDefault"),
+		xs("xmlns:xs"),
+		targetNamespace("targetNamespace"),
+		xmlns("xmlns"),
+		elements("xs:choice")
+	{
+		attributeFormDefault = "unqualified";
+		elementFormDefault = "qualified";
+		xs = "http://www.w3.org/2001/XMLSchema";
+	}
+
+};
 
 //
 // LLXSDWriter
@@ -388,7 +518,7 @@ LLXUIParser::LLXUIParser()
 {
 	if (sXUIReadFuncs.empty())
 	{
-		registerParserFuncs<LLInitParam::NoParamValue>(readNoValue, writeNoValue);
+		registerParserFuncs<LLInitParam::Flag>(readFlag, writeFlag);
 		registerParserFuncs<bool>(readBoolValue, writeBoolValue);
 		registerParserFuncs<std::string>(readStringValue, writeStringValue);
 		registerParserFuncs<U8>(readU8Value, writeU8Value);
@@ -645,13 +775,13 @@ LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack)
 	return (out_node == mWriteRootNode ? LLXMLNodePtr(NULL) : out_node);
 }
 
-bool LLXUIParser::readNoValue(Parser& parser, void* val_ptr)
+bool LLXUIParser::readFlag(Parser& parser, void* val_ptr)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
 	return self.mCurReadNode == DUMMY_NODE;
 }
 
-bool LLXUIParser::writeNoValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+bool LLXUIParser::writeFlag(Parser& parser, const void* val_ptr, const name_stack_t& stack)
 {
 	// just create node
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
@@ -1083,7 +1213,7 @@ LLSimpleXUIParser::LLSimpleXUIParser(LLSimpleXUIParser::element_start_callback_t
 {
 	if (sSimpleXUIReadFuncs.empty())
 	{
-		registerParserFuncs<LLInitParam::NoParamValue>(readNoValue);
+		registerParserFuncs<LLInitParam::Flag>(readFlag);
 		registerParserFuncs<bool>(readBoolValue);
 		registerParserFuncs<std::string>(readStringValue);
 		registerParserFuncs<U8>(readU8Value);
@@ -1376,7 +1506,7 @@ void LLSimpleXUIParser::parserError(const std::string& message)
 #endif
 }
 
-bool LLSimpleXUIParser::readNoValue(Parser& parser, void* val_ptr)
+bool LLSimpleXUIParser::readFlag(Parser& parser, void* val_ptr)
 {
 	LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
 	return self.mCurAttributeValueBegin == NO_VALUE_MARKER;
diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h
index 0c38c4da936b2feb28e4e58172f4db6c2c0f6b34..42a79b4100bd4d23cb975636c6c678a608696f1b 100644
--- a/indra/llxuixml/llxuiparser.h
+++ b/indra/llxuixml/llxuiparser.h
@@ -116,7 +116,7 @@ LOG_CLASS(LLXUIParser);
 	bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block);
 
 	//reader helper functions
-	static bool readNoValue(Parser& parser, void* val_ptr);
+	static bool readFlag(Parser& parser, void* val_ptr);
 	static bool readBoolValue(Parser& parser, void* val_ptr);
 	static bool readStringValue(Parser& parser, void* val_ptr);
 	static bool readU8Value(Parser& parser, void* val_ptr);
@@ -133,7 +133,7 @@ LOG_CLASS(LLXUIParser);
 	static bool readSDValue(Parser& parser, void* val_ptr);
 
 	//writer helper functions
-	static bool writeNoValue(Parser& parser, const void* val_ptr, const name_stack_t&);
+	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&);
@@ -197,7 +197,7 @@ LOG_CLASS(LLSimpleXUIParser);
 
 private:
 	//reader helper functions
-	static bool readNoValue(Parser&, void* val_ptr);
+	static bool readFlag(Parser&, void* val_ptr);
 	static bool readBoolValue(Parser&, void* val_ptr);
 	static bool readStringValue(Parser&, void* val_ptr);
 	static bool readU8Value(Parser&, void* val_ptr);
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index d64fdbe6a5aa2836193f6f119088f55296bf9f6a..ca9956dc5386332c586bd283888564bb58f1d42a 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -61,7 +61,7 @@ class LLNameListCtrl
 		{}
 	};
 
-	struct NameColumn : public LLInitParam::Choice<NameColumn>
+	struct NameColumn : public LLInitParam::ChoiceBlock<NameColumn>
 	{
 		Alternative<S32>				column_index;
 		Alternative<std::string>		column_name;
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 fa7632920bf6a41029d2a9b3a24a00c17d588b68..7bbacc015285e27eb1fb58c37d8f3b20fcb90b34 100644
--- a/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_toolbar_view.xml
@@ -33,7 +33,6 @@
                   follows="all"
                   mouse_opaque="false">
       <layout_panel name="left_toolbar_panel"
-                    fit_content="true"
                     auto_resize="false"
                     user_resize="false"
                     height="500"
@@ -54,7 +53,6 @@
                     user_resize="false"
                     mouse_opaque="false"/>
       <layout_panel name="right_toolbar_panel"
-                    fit_content="true"
                     auto_resize="false"
                     user_resize="false"
                     height="500"
@@ -74,7 +72,6 @@
     </layout_stack>
   </layout_panel>
   <layout_panel name="bottom_toolbar_panel"
-                fit_content="true"
                 auto_resize="false"
                 user_resize="false"
                 height="30"
diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
index 32bc88cc9a8b135de0d6122e1659261be0d29959..d16d70cb439881c69844447427e691442b7ee99b 100644
--- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
@@ -10,6 +10,7 @@
   <button_panel name="button_panel"
                 bg_opaque_image="Rounded_Rect"
                 background_visible="true"
+                bg_opaque_color="MouseGray"
                 background_opaque="true"/>
   <button_icon_and_text follows="left|top"
                         chrome="true"