diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 145dddd5434c418a2304f10769a049eb8c2f7d96..5e566d6c7cf810e227ee0a1da6e378c4afb2f4a0 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -93,7 +93,8 @@ LLAssetDictionary::LLAssetDictionary()
 
 	addEntry(LLAssetType::AT_LINK, 				new AssetEntry("LINK",				"link",		"sym link",			false,		false,		true));
 	addEntry(LLAssetType::AT_LINK_FOLDER, 		new AssetEntry("FOLDER_LINK",		"link_f", 	"sym folder link",	false,		false,		true));
-	addEntry(LLAssetType::AT_MESH,              new AssetEntry("MESH",              "mesh",     "mesh",             false, false, false));
+	addEntry(LLAssetType::AT_MESH,              new AssetEntry("MESH",              "mesh",     "mesh",             false,      false,      false));
+	addEntry(LLAssetType::AT_WIDGET,            new AssetEntry("WIDGET",            "widget",   "widget",           false,      false,      false));
 	addEntry(LLAssetType::AT_NONE, 				new AssetEntry("NONE",				"-1",		NULL,		  		FALSE,		FALSE,		FALSE));
 
 };
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index 74ccd003244566be98a76ed0e78a309953314a1c..d538accbf7289472d26965147c5879351498194a 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -108,9 +108,13 @@ class LL_COMMON_API LLAssetType
 
 		AT_LINK_FOLDER = 25,
 			// Inventory folder link
+		
+		AT_WIDGET = 40,
+			// UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...)
+		
 		AT_MESH = 49,
-		    // Mesh data in our proprietary SLM format
-
+			// Mesh data in our proprietary SLM format
+		
 		AT_COUNT = 50,
 
 			// +*********************************************************+
diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h
index 556eff8370cae1196e9b116ff652b8a7c53a6c04..40b3364b36078961f92d9742e36765028ae284c9 100644
--- a/indra/llcommon/stdenums.h
+++ b/indra/llcommon/stdenums.h
@@ -49,8 +49,9 @@ enum EDragAndDropType
 	DAD_ANIMATION		= 12,
 	DAD_GESTURE			= 13,
 	DAD_LINK			= 14,
-	DAD_MESH           		= 15,
-	DAD_COUNT			= 16,   // number of types in this enum
+	DAD_MESH            = 15,
+	DAD_WIDGET          = 16,
+	DAD_COUNT           = 17,   // number of types in this enum
 };
 
 // Reasons for drags to be denied.
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index d2bba216483796d5533f294d77e71feac32b0495..8282d79b673736ffab072ba47aaae3bf92d4a256 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -84,6 +84,7 @@ LLInventoryDictionary::LLInventoryDictionary()
 	addEntry(LLInventoryType::IT_ANIMATION,           new InventoryEntry("animation", "animation",     1, LLAssetType::AT_ANIMATION));  
 	addEntry(LLInventoryType::IT_GESTURE,             new InventoryEntry("gesture",   "gesture",       1, LLAssetType::AT_GESTURE)); 
 	addEntry(LLInventoryType::IT_MESH,                new InventoryEntry("mesh",      "mesh",          1, LLAssetType::AT_MESH));
+	addEntry(LLInventoryType::IT_WIDGET,              new InventoryEntry("widget",    "widget",        1, LLAssetType::AT_WIDGET));
 }
 
 
@@ -134,7 +135,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
 	LLInventoryType::IT_NONE,			// 37	AT_NONE
 	LLInventoryType::IT_NONE,			// 38	AT_NONE
 	LLInventoryType::IT_NONE,			// 39	AT_NONE
-	LLInventoryType::IT_NONE,			// 40	AT_NONE
+	LLInventoryType::IT_WIDGET,			// 40	AT_WIDGET
 	LLInventoryType::IT_NONE,			// 41	AT_NONE
 	LLInventoryType::IT_NONE,			// 42	AT_NONE
 	LLInventoryType::IT_NONE,			// 43	AT_NONE
@@ -143,7 +144,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
 	LLInventoryType::IT_NONE,			// 46	AT_NONE
 	LLInventoryType::IT_NONE,			// 47	AT_NONE
 	LLInventoryType::IT_NONE,			// 48	AT_NONE
-	LLInventoryType::IT_MESH            // 49	AT_MESH
+	LLInventoryType::IT_MESH,			// 49	AT_MESH
 };
 
 // static
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index 1a24e351adc6e5c7c00abc5b89307f4cf418bf0c..4d1e0db04016126a4fc70df3b1f738bf78031c4e 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -62,7 +62,8 @@ class LLInventoryType
 		IT_ANIMATION = 19,
 		IT_GESTURE = 20,
 		IT_MESH = 22,
-		IT_COUNT = 23,
+		IT_WIDGET = 23,
+		IT_COUNT = 24,
 
 		IT_NONE = -1
 	};
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 421281255898b9bda2e8b806c7e55092468bace1..dded8ab661e448034765201ae080e9a858bac353 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -5,6 +5,7 @@ project(llui)
 include(00-Common)
 include(LLCommon)
 include(LLImage)
+include(LLInventory)
 include(LLMath)
 include(LLMessage)
 include(LLRender)
@@ -16,6 +17,7 @@ include(LLXUIXML)
 include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
     ${LLIMAGE_INCLUDE_DIRS}
+    ${LLINVENTORY_INCLUDE_DIRS}
     ${LLMATH_INCLUDE_DIRS}
     ${LLMESSAGE_INCLUDE_DIRS}
     ${LLRENDER_INCLUDE_DIRS}
@@ -101,7 +103,6 @@ set(llui_SOURCE_FILES
     lltransutil.cpp
     lltoggleablemenu.cpp
     lltoolbar.cpp
-    lltoolbarview.cpp
     lltooltip.cpp
     llui.cpp
     lluicolortable.cpp
@@ -205,7 +206,6 @@ set(llui_HEADER_FILES
     lltimectrl.h
     lltoggleablemenu.h
     lltoolbar.h
-    lltoolbarview.h
     lltooltip.h
     lltransutil.h
     lluicolortable.h
@@ -251,6 +251,7 @@ target_link_libraries(llui
     ${LLRENDER_LIBRARIES}
     ${LLWINDOW_LIBRARIES}
     ${LLIMAGE_LIBRARIES}
+    ${LLINVENTORY_LIBRARIES}
     ${LLVFS_LIBRARIES}    # ugh, just for LLDir
     ${LLXUIXML_LIBRARIES}
     ${LLXML_LIBRARIES}
diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp
index 984c4ec5fb759df4d028514b02dc548260f4b446..6910b962a1932ce09c9e31bc5f120a3e460ece1b 100644
--- a/indra/llui/llclipboard.cpp
+++ b/indra/llui/llclipboard.cpp
@@ -40,6 +40,7 @@ LLClipboard gClipboard;
 
 LLClipboard::LLClipboard()
 {
+	mSourceItem = NULL;
 }
 
 
@@ -134,3 +135,8 @@ BOOL LLClipboard::canPastePrimaryString() const
 {
 	return LLView::getWindow()->isPrimaryTextAvailable();
 }
+
+void LLClipboard::setSourceObject(const LLUUID& source_id, LLAssetType::EType type) 
+{
+	mSourceItem = new LLInventoryObject (source_id, LLUUID::null, type, "");
+}
diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h
index 24cb46c3f49476b6061ed4e14a6da2856fd9c5b1..9371b9428447ae2c8deb3ba3238d726dca41a7cb 100644
--- a/indra/llui/llclipboard.h
+++ b/indra/llui/llclipboard.h
@@ -30,6 +30,8 @@
 
 #include "llstring.h"
 #include "lluuid.h"
+#include "stdenums.h"
+#include "llinventory.h"
 
 
 class LLClipboard
@@ -52,9 +54,14 @@ class LLClipboard
 	BOOL		canPastePrimaryString() const;
 	const LLWString&	getPastePrimaryWString(LLUUID* source_id = NULL);	
 
+	// Support clipboard for object known only by their uuid and asset type
+	void		  setSourceObject(const LLUUID& source_id, LLAssetType::EType type);
+	const LLInventoryObject* getSourceObject() { return mSourceItem; }
+	
 private:
-	LLUUID		mSourceID;
+	LLUUID      mSourceID;
 	LLWString	mString;
+	LLInventoryObject* mSourceItem;
 };
 
 
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index c0058d534df7391d925114f07c6e5c76e7bbf4db..efa077ffa10e756d61b67e656f9f4f4de57c6d24 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -33,7 +33,6 @@
 #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!
@@ -108,6 +107,7 @@ 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;
+	mUUID = LLUUID::generateNewID(p.name);
 }
 
 LLToolBar::~LLToolBar()
@@ -319,7 +319,7 @@ void LLToolBar::resizeButtonsInRow(std::vector<LLToolBarButton*>& buttons_in_row
 	{
 		if (getOrientation(mSideType) == LLLayoutStack::HORIZONTAL)
 		{
-			button->reshape(llclamp(button->getRect().getWidth(), button->mMinWidth, button->mMaxWidth), max_row_girth);
+			button->reshape(button->mWidthRange.clamp(button->getRect().getWidth()), max_row_girth);
 		}
 		else // VERTICAL
 		{
@@ -378,10 +378,10 @@ void LLToolBar::updateLayoutAsNeeded()
 
 	BOOST_FOREACH(LLToolBarButton* button, mButtons)
 	{
-		button->reshape(button->mMinWidth, button->mDesiredHeight);
+		button->reshape(button->mWidthRange.getMin(), button->mDesiredHeight);
 		button->autoResize();
 
-		S32 button_clamped_width = llclamp(button->getRect().getWidth(), button->mMinWidth, button->mMaxWidth);
+		S32 button_clamped_width = button->mWidthRange.clamp(button->getRect().getWidth());
 		S32 button_length = (orientation == LLLayoutStack::HORIZONTAL)
 							? button_clamped_width
 							: button->getRect().getHeight();
@@ -396,7 +396,7 @@ void LLToolBar::updateLayoutAsNeeded()
 		{
 			if (orientation == LLLayoutStack::VERTICAL)
 			{	// row girth (width in this case) is clamped to allowable button widths
-				max_row_girth = llclamp(max_row_girth, button->mMinWidth, button->mMaxWidth);
+				max_row_girth = button->mWidthRange.clamp(max_row_girth);
 			}
 
 			// make buttons in current row all same girth
@@ -528,6 +528,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
 		cbParam.function_name = commandp->functionName();
 		cbParam.parameter = commandp->parameter();
 		button->setCommitCallback(cbParam);
+		button->setStartDragCallback(mStartDragItemCallback);
+		button->setHandleDragCallback(mHandleDragItemCallback);
 	}
 
 	button->setCommandId(id);
@@ -535,20 +537,41 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
 
 }
 
-//
-// LLToolBarButton
-//
+BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+										EDragAndDropType cargo_type,
+										void* cargo_data,
+										EAcceptance* accept,
+										std::string& tooltip_msg)
+{
+	llinfos << "Merov debug : handleDragAndDrop. drop = " << drop << ", tooltip = " << tooltip_msg << llendl;
+	// If we have a drop callback, that means that we can handle the drop
+	BOOL handled = (mHandleDropCallback ? TRUE : FALSE);
+	
+	// if drop, time to call the drop callback to get the operation done
+	if (handled && drop)
+	{
+		handled = mHandleDropCallback(cargo_type,cargo_data,mUUID);
+	}
+	
+	// We accept multi drop by default
+	*accept = (handled ? ACCEPT_YES_MULTI : ACCEPT_NO);
+	
+	// We'll use that flag to change the visual aspect of the target on draw()
+	mDragAndDropTarget = handled;
+	
+	return handled;
+}
 
 LLToolBarButton::LLToolBarButton(const Params& p) 
 :	LLButton(p),
 	mMouseDownX(0),
 	mMouseDownY(0),
-	mMinWidth(p.min_button_width),
-	mMaxWidth(p.max_button_width),
+	mWidthRange(p.button_width),
 	mDesiredHeight(p.desired_height),
 	mId("")
-{}
-
+{
+	mUUID = LLUUID::generateNewID(p.name);
+}
 
 BOOL LLToolBarButton::handleMouseDown(S32 x, S32 y, MASK mask)
 {
@@ -559,22 +582,26 @@ BOOL LLToolBarButton::handleMouseDown(S32 x, S32 y, MASK mask)
 
 BOOL LLToolBarButton::handleHover(S32 x, S32 y, MASK mask)
 {
-	if (hasMouseCapture())
+//	llinfos << "Merov debug: handleHover, x = " << x << ", y = " << y << ", mouse = " << hasMouseCapture() << llendl;
+	BOOL handled = FALSE;
+		
+	if (hasMouseCapture() && mStartDragItemCallback && mHandleDragItemCallback)
 	{
-		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)
+		if (!mIsDragged)
 		{
-			// start drag and drop
-			LLToolBarView* view = getParentByType<LLToolBarView>();
-			LLToolBar* bar = getParentByType<LLToolBar>();
-			if (view)
+			mStartDragItemCallback(x,y,mUUID);
+			mIsDragged = true;
+			handled = TRUE;
+		}
+		else 
 			{
-				//view->startDrag(bar->createButton(mId));
-				//setVisible(FALSE);
+			handled = mHandleDragItemCallback(x,y,mUUID,LLAssetType::AT_WIDGET);
 			}
 		}
+	else
+	{
+		handled = LLButton::handleHover(x, y, mask);
 	}
-	return LLButton::handleHover(x, y, mask);
+	return handled;
 }
+
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index 5d64630fa61a46ef516c0fda33b911ca9cfdd363..407cbde7d27461ae209349070c07fdfaa67918d7 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -33,7 +33,11 @@
 #include "lllayoutstack.h"
 #include "lluictrl.h"
 #include "llcommandmanager.h"
+#include "llassettype.h"
 
+typedef boost::function<void (S32 x, S32 y, const LLUUID& uuid)> startdrag_callback_t;
+typedef boost::function<BOOL (S32 x, S32 y, const LLUUID& uuid, LLAssetType::EType type)> handledrag_callback_t;
+typedef boost::function<BOOL (EDragAndDropType type, void* data, const LLUUID& uuid)> handledrop_callback_t;
 
 class LLToolBarButton : public LLButton
 {
@@ -41,13 +45,11 @@ class LLToolBarButton : public LLButton
 public:
 	struct Params : public LLInitParam::Block<Params, LLButton::Params>
 	{
-		Optional<S32>	min_button_width,
-						max_button_width,
-						desired_height;
+		Optional<LLUI::Range<S32> >	button_width;
+		Optional<S32>				desired_height;
 
 		Params()
-		:	min_button_width("min_button_width", 0),
-			max_button_width("max_button_width", S32_MAX),
+		:	button_width("button_width"),
 			desired_height("desired_height", 20)
 		{}
 
@@ -58,13 +60,19 @@ class LLToolBarButton : public LLButton
 	BOOL handleMouseDown(S32 x, S32 y, MASK mask);
 	BOOL handleHover(S32 x, S32 y, MASK mask);
 	void setCommandId(const LLCommandId& id) { mId = id; }
+
+	void setStartDragCallback(startdrag_callback_t cb) { mStartDragItemCallback = cb; }
+	void setHandleDragCallback(handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
 private:
 	LLCommandId		mId;
 	S32				mMouseDownX;
 	S32				mMouseDownY;
-	S32				mMinWidth;
-	S32				mMaxWidth;
+	LLUI::Range<S32> mWidthRange;
 	S32				mDesiredHeight;
+	bool						mIsDragged;
+	startdrag_callback_t		mStartDragItemCallback;
+	handledrag_callback_t		mHandleDragItemCallback;
+	LLUUID						mUUID;
 };
 
 
@@ -108,7 +116,6 @@ class LLToolBar
 :	public LLUICtrl
 {
 public:
-
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
 		Mandatory<LLToolBarEnums::ButtonType>	button_display_mode;
@@ -137,10 +144,18 @@ class LLToolBar
 	void draw();
 	void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 	BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+								   EDragAndDropType cargo_type,
+								   void* cargo_data,
+								   EAcceptance* accept,
+								   std::string& tooltip_msg);
 
 	bool addCommand(const LLCommandId& commandId);
 	bool hasCommand(const LLCommandId& commandId) const;
 	bool enableCommand(const LLCommandId& commandId, bool enabled);
+	void setStartDragCallback(startdrag_callback_t cb) { mStartDragItemCallback = cb; }
+	void setHandleDragCallback(handledrag_callback_t cb) { mHandleDragItemCallback = cb; }
+	void setHandleDropCallback(handledrop_callback_t cb) { mHandleDropCallback = cb; }
 
 	LLToolBarButton* createButton(const LLCommandId& id);
 
@@ -150,6 +165,10 @@ class LLToolBar
 	~LLToolBar();
 
 	void initFromParams(const Params&);
+	startdrag_callback_t		mStartDragItemCallback;
+	handledrag_callback_t		mHandleDragItemCallback;
+	handledrop_callback_t		mHandleDropCallback;
+	bool						mDragAndDropTarget;
 
 public:
 	// Methods used in loading and saving toolbar settings
@@ -166,6 +185,7 @@ class LLToolBar
 	BOOL isSettingChecked(const LLSD& userdata);
 	void onSettingEnable(const LLSD& userdata);
 
+	LLUUID							mUUID;
 	const bool						mReadOnly;
 
 	std::list<LLToolBarButton*>		mButtons;
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 3afb7c65a90b604f06ae3cbaf821119b135cd919..8cec1a16f406170e4a176f06b474552e888fac5e 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -147,6 +147,132 @@ class LLUI
 {
 	LOG_CLASS(LLUI);
 public:
+	//
+	// Classes
+	//
+
+	template <typename T>
+	struct Range 
+	{
+		typedef Range<T> self_t;
+
+		struct Params : public LLInitParam::Block<Params>
+		{
+			typename Optional<T>	minimum,
+									maximum;
+
+			Params()
+			:	minimum("min", 0),
+				maximum("max", S32_MAX)
+			{
+
+			}
+		};
+
+		// correct for inverted params
+		Range(const Params& p = Params())
+			:	mMin(p.minimum),
+			mMax(p.maximum)
+		{
+			sanitizeRange();
+		}
+
+		Range(T minimum, T maximum)
+			:	mMin(minimum),
+			mMax(maximum)
+		{
+			sanitizeRange();
+		}
+
+		S32 clamp(T input)
+		{
+			if (input < mMin) return mMin;
+			if (input > mMax) return mMax;
+			return input;
+		}
+
+		void setRange(T minimum, T maximum)
+		{
+			mMin = minimum;
+			mMax = maximum;
+			sanitizeRange();
+		}
+
+		S32 getMin() { return mMin; }
+		S32 getMax() { return mMax; }
+
+		bool operator==(const self_t& other) const
+		{
+			return mMin == other.mMin 
+				&& mMax == other.mMax;
+		}
+	private:
+		void sanitizeRange()
+		{
+			if (mMin > mMax)
+			{
+				llwarns << "Bad interval range (" << mMin << ", " << mMax << ")" << llendl;
+				// since max is usually the most dangerous one to ignore (buffer overflow, etc), prefer it
+				// in the case of a malformed range
+				mMin = mMax;
+			}
+		}
+
+
+		T	mMin,
+			mMax;
+	};
+
+	template<typename T>
+	struct ClampedValue : public Range<T>
+	{
+		typedef Range<T> range_t;
+
+		struct Params : public LLInitParam::Block<Params, typename range_t::Params>
+		{
+			Mandatory<S32> value;
+
+			Params()
+			:	value("", 0)
+			{
+				addSynonym(value, "value");
+			}
+		};
+
+		ClampedValue(const Params& p)
+		:	range_t(p)
+		{}
+
+		ClampedValue(const range_t& range)
+		:	range_t(range)
+		{
+			// set value here, after range has been sanitized
+			mValue = clamp(0);
+		}
+
+		ClampedValue(T value, const range_t& range = range_t())
+		:	range_t(range)
+		{
+			mValue = clamp(value);
+		}
+
+		T get()
+		{
+			return mValue;
+		}
+
+		void set(T value)
+		{
+			mValue = clamp(value);
+		}
+
+
+	private:
+		T mValue;
+	};
+
+	typedef ClampedValue<S32> ClampedS32;
+
 	//
 	// Methods
 	//
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 9a6ded47ffe956127601117769f15166d45df371..1a131d15a3f4d6eaae8cb189f23a917cc65ae4ac 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -87,6 +87,7 @@ namespace LLInitParam
 
 		void setValueName(const std::string& key) {}
 		std::string getValueName() const { return ""; }
+		std::string calcValueName(const T& value) const { return ""; }
 		void clearValueName() const {}
 
 		static bool getValueFromName(const std::string& name, T& value)
@@ -124,6 +125,22 @@ namespace LLInitParam
 			return mValueName; 
 		}
 
+		std::string calcValueName(const T& value) const
+		{
+			value_name_map_t* map = getValueNames();
+			for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
+				it != end_it;
+				++it)
+			{
+				if (ParamCompare<T>::equals(it->second, value))
+				{
+					return it->first;
+				}
+			}
+
+			return "";
+		}
+
 		void clearValueName() const
 		{
 			mValueName.clear();
@@ -564,10 +581,6 @@ namespace LLInitParam
 	public:
 		typedef const T&							value_assignment_t;
 
-		S32 			mKeyVersion;
-		mutable S32 	mValidatedVersion;
-		mutable bool 	mValidated; // lazy validation flag
-
 		ParamValue() 
 		:	T(),
 			mKeyVersion(0),
@@ -607,6 +620,12 @@ namespace LLInitParam
 		{
 			return *this;
 		}
+
+		S32 			mKeyVersion;
+
+	protected:
+		mutable S32 	mValidatedVersion;
+		mutable bool 	mValidated; // lazy validation flag
 	};
 
 	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
@@ -707,10 +726,7 @@ namespace LLInitParam
 			{
 				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
 				{
-					if (!parser.writeValue(key, name_stack))
-					{
-						return;
-					}
+					parser.writeValue(key, name_stack);
 				}
 			}
 			// then try to serialize value directly
@@ -718,7 +734,11 @@ namespace LLInitParam
 			{
 				if (!parser.writeValue(typed_param.getValue(), name_stack)) 
 				{
-					return;
+					std::string calculated_key = typed_param.calcValueName(typed_param.getValue());
+					if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key))
+					{
+						parser.writeValue(calculated_key, name_stack);
+					}
 				}
 			}
 		}
@@ -1000,9 +1020,14 @@ namespace LLInitParam
 				if(key.empty())
 				// not parsed via name values, write out value directly
 				{
-					if (!parser.writeValue(*it, name_stack))
+					bool value_written = parser.writeValue(*it, name_stack);
+					if (!value_written)
 					{
-						break;
+						std::string calculated_key = typed_param.calcValueName(typed_param.getValue());
+						if (!parser.writeValue(calculated_key, name_stack))
+						{
+							break;
+						}
 					}
 				}
 				else 
@@ -1665,7 +1690,7 @@ namespace LLInitParam
 				*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 super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite);
 			}
 			return false;
 		}
@@ -1679,8 +1704,6 @@ namespace LLInitParam
 		S32 mLastParseGeneration;
 	};
 
-	
-
 	template<typename DERIVED_BLOCK,
 			typename BASE_BLOCK,
 			typename NAME_VALUE_LOOKUP>
@@ -1690,17 +1713,18 @@ namespace LLInitParam
 	:	public Param,
 		protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK>
 	{
+		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t;
 		typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>&	value_assignment_t;
 
 		ParamValue()
-		:	T(),
+		:	block_t(),
 			mKeyVersion(0),
 			mValidatedVersion(-1),
 			mValidated(false)
 		{}
 
 		ParamValue(value_assignment_t other)
-		:	T(other),
+		:	block_t(other),
 			mKeyVersion(0),
 			mValidatedVersion(-1),
 			mValidated(false)
@@ -1710,7 +1734,7 @@ namespace LLInitParam
 		void setValue(value_assignment_t val)
 		{
 			*this = val;
-			mLastParseGeneration = -1;
+			block_t::mLastParseGeneration = -1;
 		}
 
 		value_assignment_t getValue() const
@@ -1733,6 +1757,11 @@ namespace LLInitParam
 			return *this;
 		}
 
+		S32 			mKeyVersion;
+
+	protected:
+		mutable S32 	mValidatedVersion;
+		mutable bool 	mValidated; // lazy validation flag
 	};
 
 	template<typename T>
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c488d51ba5e071446fd3a9b64ae4c4444262dfa1..ce47cca16f337ede98c70f6dd91441f32538e6de 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -481,6 +481,7 @@ set(viewer_SOURCE_FILES
     lltoastpanel.cpp
     lltoastscripttextbox.cpp
     lltool.cpp
+    lltoolbarview.cpp
     lltoolbrush.cpp
     lltoolcomp.cpp
     lltooldraganddrop.cpp
@@ -1039,6 +1040,7 @@ set(viewer_HEADER_FILES
     lltoastpanel.h
     lltoastscripttextbox.h
     lltool.h
+    lltoolbarview.h
     lltoolbrush.h
     lltoolcomp.h
     lltooldraganddrop.h
diff --git a/indra/newview/app_settings/toolbars.xml b/indra/newview/app_settings/toolbars.xml
index 21084d2c8da81bd5fcfb0f6ef142a5e954757dae..8eb438b857c83e3c8c8bb0161b9cc177e1d3d3b5 100644
--- a/indra/newview/app_settings/toolbars.xml
+++ b/indra/newview/app_settings/toolbars.xml
@@ -22,4 +22,4 @@
     <command name="voice"/>
     <command name="minimap"/>
   </left_toolbar>
-</toolbars>
+</toolbars>
\ No newline at end of file
diff --git a/indra/llui/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
similarity index 70%
rename from indra/llui/lltoolbarview.cpp
rename to indra/newview/lltoolbarview.cpp
index 12247519ad73a36823f65d3b9958f76e4ff841d7..65f63926b66cce21b2da58014ba00ad3eda00199 100644
--- a/indra/llui/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -25,7 +25,7 @@
  * $/LicenseInfo$
  */
 
-#include "linden_common.h"
+#include "llviewerprecompiledheaders.h"
 
 #include "lltoolbarview.h"
 
@@ -33,12 +33,15 @@
 #include "llxmlnode.h"
 #include "lltoolbar.h"
 #include "llbutton.h"
+#include "lltooldraganddrop.h"
+#include "llclipboard.h"
 
 #include <boost/foreach.hpp>
 
 LLToolBarView* gToolBarView = NULL;
 
 static LLDefaultChildRegistry::Register<LLToolBarView> r("toolbar_view");
+bool LLToolBarView::sDragStarted = false;
 
 LLToolBarView::Toolbar::Toolbar()
 :	button_display_mode("button_display_mode"),
@@ -77,6 +80,18 @@ 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));
+	
+	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));
+	
+	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));
+	
 	return TRUE;
 }
 
@@ -169,8 +184,8 @@ bool LLToolBarView::loadToolbars(bool force_default)
 	{
 		if (toolbar_set.left_toolbar.button_display_mode.isProvided())
 		{
-			U32 button_type = toolbar_set.left_toolbar.button_display_mode;
-			mToolbarLeft->setButtonType((LLToolBarEnums::ButtonType)(button_type));
+			LLToolBarEnums::ButtonType button_type = toolbar_set.left_toolbar.button_display_mode;
+			mToolbarLeft->setButtonType(button_type);
 		}
 		BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.left_toolbar.commands)
 		{
@@ -181,8 +196,8 @@ bool LLToolBarView::loadToolbars(bool force_default)
 	{
 		if (toolbar_set.right_toolbar.button_display_mode.isProvided())
 		{
-			U32 button_type = toolbar_set.right_toolbar.button_display_mode;
-			mToolbarRight->setButtonType((LLToolBarEnums::ButtonType)(button_type));
+			LLToolBarEnums::ButtonType button_type = toolbar_set.right_toolbar.button_display_mode;
+			mToolbarRight->setButtonType(button_type);
 		}
 		BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.right_toolbar.commands)
 		{
@@ -193,8 +208,8 @@ bool LLToolBarView::loadToolbars(bool force_default)
 	{
 		if (toolbar_set.bottom_toolbar.button_display_mode.isProvided())
 		{
-			U32 button_type = toolbar_set.bottom_toolbar.button_display_mode;
-			mToolbarBottom->setButtonType((LLToolBarEnums::ButtonType)(button_type));
+			LLToolBarEnums::ButtonType button_type = toolbar_set.bottom_toolbar.button_display_mode;
+			mToolbarBottom->setButtonType(button_type);
 		}
 		BOOST_FOREACH(LLCommandId::Params& command, toolbar_set.bottom_toolbar.commands)
 		{
@@ -223,17 +238,17 @@ void LLToolBarView::saveToolbars() const
 	LLToolBarView::ToolbarSet toolbar_set;
 	if (mToolbarLeft)
 	{
-		toolbar_set.left_toolbar.button_display_mode = (int)(mToolbarLeft->getButtonType());
+		toolbar_set.left_toolbar.button_display_mode = mToolbarLeft->getButtonType();
 		addToToolset(mToolbarLeft->getCommandsList(),toolbar_set.left_toolbar);
 	}
 	if (mToolbarRight)
 	{
-		toolbar_set.right_toolbar.button_display_mode = (int)(mToolbarRight->getButtonType());
+		toolbar_set.right_toolbar.button_display_mode = mToolbarRight->getButtonType();
 		addToToolset(mToolbarRight->getCommandsList(),toolbar_set.right_toolbar);
 	}
 	if (mToolbarBottom)
 	{
-		toolbar_set.bottom_toolbar.button_display_mode = (int)(mToolbarBottom->getButtonType());
+		toolbar_set.bottom_toolbar.button_display_mode = mToolbarBottom->getButtonType();
 		addToToolset(mToolbarBottom->getCommandsList(),toolbar_set.bottom_toolbar);
 	}
 	
@@ -322,3 +337,67 @@ void LLToolBarView::draw()
 	
 	LLUICtrl::draw();
 }
+
+
+// ----------------------------------------
+// Drag and Drop hacks (under construction)
+// ----------------------------------------
+
+
+void LLToolBarView::startDragItem( S32 x, S32 y, const LLUUID& uuid)
+{
+	llinfos << "Merov debug: startDragItem() : 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)
+{
+//	llinfos << "Merov debug: handleDragItem() : x = " << x << ", y = " << y << ", uuid = " << uuid << llendl;
+	if (LLToolDragAndDrop::getInstance()->isOverThreshold( x, y ))
+	{
+		if (!sDragStarted)
+		{
+			std::vector<EDragAndDropType> types;
+			uuid_vec_t cargo_ids;
+			types.push_back(DAD_WIDGET);
+			cargo_ids.push_back(uuid);
+			gClipboard.setSourceObject(uuid,LLAssetType::AT_WIDGET);
+			LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_VIEWER;
+			LLUUID srcID;
+			llinfos << "Merov debug: handleDragItem() :  beginMultiDrag()" << llendl;
+			LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src, srcID);
+			sDragStarted = true;
+			return TRUE;
+		}
+		else
+		{
+			MASK mask = 0;
+			return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
+		}
+	}
+	return FALSE;
+}
+
+BOOL LLToolBarView::handleDrop( EDragAndDropType cargo_type, void* cargo_data, const LLUUID& toolbar_id)
+{
+	LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
+	llinfos << "Merov debug : handleDrop. Drop " << inv_item->getUUID() << " named " << inv_item->getName() << " of type " << inv_item->getType() << " to toolbar " << toolbar_id << " under cargo type " << cargo_type << llendl;
+		
+	LLAssetType::EType type = inv_item->getType();
+	if (type == LLAssetType::AT_WIDGET)
+	{
+		llinfos << "Merov debug : handleDrop. Drop source is a widget -> that's where we'll get code in..." << llendl;
+		// Find out if he command is in one of the toolbar
+		// If it is, pull it out of the toolbar
+		// Now insert it in the toolbar in the correct spot...
+	}
+	else
+	{
+		llinfos << "Merov debug : handleDrop. Drop source is not a widget -> nothing to do" << llendl;
+	}
+	
+	return TRUE;
+}
+
+
diff --git a/indra/llui/lltoolbarview.h b/indra/newview/lltoolbarview.h
similarity index 89%
rename from indra/llui/lltoolbarview.h
rename to indra/newview/lltoolbarview.h
index 20525a22ac3110c46e97dcd3a203ad354f149a5c..dc27fc2ffac8d615ad79b2fa80675a9f9d30e667 100644
--- a/indra/llui/lltoolbarview.h
+++ b/indra/newview/lltoolbarview.h
@@ -50,7 +50,7 @@ class LLToolBarView : public LLUICtrl
 	// the user folder for the user specific (saved) settings
 	struct Toolbar : public LLInitParam::Block<Toolbar>
 	{
-		Mandatory<U32>                button_display_mode;
+		Mandatory<LLToolBarEnums::ButtonType>	button_display_mode;
 		Multiple<LLCommandId::Params>	commands;
 		Toolbar();
 	};
@@ -74,6 +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(	EDragAndDropType cargo_type, void* cargo_data, const LLUUID& folder_id);
+	
 protected:
 	friend class LLUICtrlFactory;
 	LLToolBarView(const Params&);
@@ -93,6 +97,8 @@ class LLToolBarView : public LLUICtrl
 	LLToolBarButton* mDragButton;
 	S32			mMouseX;
 	S32			mMouseY;
+	
+	static bool			sDragStarted;
 };
 
 extern LLToolBarView* gToolBarView;
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 3e5ce427a80dfbe2551c8a51593ace4ad7fe85a8..a8014b8cde0c3c380fd04fda9340380163d0ce9f 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -57,6 +57,7 @@
 #include "llviewerwindow.h"
 #include "llvoavatarself.h"
 #include "llworld.h"
+#include "llclipboard.h"
 
 // syntactic sugar
 #define callMemberFunction(object,ptrToMember)  ((object).*(ptrToMember))
@@ -2495,6 +2496,10 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
 			item = (LLViewerInventoryItem*)preview->getDragItem();
 		}
 	}
+	else if(mSource == SOURCE_VIEWER)
+	{
+		item = (LLViewerInventoryItem*)gClipboard.getSourceObject();
+	}
 	if(item) return item;
 	if(cat) return cat;
 	return NULL;
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 7b8cce3dc7f0c6e7fbbc2fd30f40e0bd77311724..92f007a2518e21258872f24ca7dc1188ecd016d1 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -66,7 +66,8 @@ class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop>
 		SOURCE_AGENT,
 		SOURCE_WORLD,
 		SOURCE_NOTECARD,
-		SOURCE_LIBRARY
+		SOURCE_LIBRARY,
+		SOURCE_VIEWER
 	};
 
 	void beginDrag(EDragAndDropType type,
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index b103f115976cd1943e4fa39323737d7f143d59bf..a4b1c2155ffe63359ecb49ad45cd15b910890860 100644
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -80,7 +80,9 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()
 	addEntry(LLViewerAssetType::AT_LINK_FOLDER, 		new ViewerAssetEntry(DAD_LINK));
 
 	addEntry(LLViewerAssetType::AT_MESH, 				new ViewerAssetEntry(DAD_MESH));
-
+	
+	addEntry(LLViewerAssetType::AT_WIDGET, 				new ViewerAssetEntry(DAD_WIDGET));
+	
 	addEntry(LLViewerAssetType::AT_NONE, 				new ViewerAssetEntry(DAD_NONE));
 };
 
diff --git a/indra/newview/skins/default/xui/en/floater_toybox.xml b/indra/newview/skins/default/xui/en/floater_toybox.xml
index de39032cbf81ad1647fc50034fb4cd042da0b17f..972ae1487aefa0687ab5710734095c53539f3824 100644
--- a/indra/newview/skins/default/xui/en/floater_toybox.xml
+++ b/indra/newview/skins/default/xui/en/floater_toybox.xml
@@ -48,8 +48,8 @@
     button_display_mode="icons_with_text"
     follows="all"
     left="20"
-    button_icon_and_text.max_button_width="140"
-    button_icon_and_text.min_button_width="70"
+    button_icon_and_text.button_width.max="140"
+    button_icon_and_text.button_width.min="70"
     name="toybox_toolbar"
     pad_left="5"
     pad_right="5"
diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
index 8422e3943d5decc43fa421cdb97b0a80ec25f03a..0c7e7cff5641efb5641ed99ee517b27de442fffa 100644
--- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
@@ -12,8 +12,8 @@
                 bg_opaque_image_overlay="MouseGray"
                 background_opaque="true"/>
   <button_icon_and_text imgoverlay_label_space="7"
-                        min_button_width="70"
-                        max_button_width="140"
+                        button_width.min="70"
+                        button_width.max="140"
                         desired_height="24"
                         pad_left="10" 
                         pad_right="10"
@@ -25,8 +25,8 @@
   <button_icon pad_left="10"
                pad_right="10"
                desired_height="35"
-               min_button_width="35"
-               max_button_width="35"               
+               button_width.min="35"
+               button_width.max="35"               
                follows="left|top"
                label=""
                chrome="true"