diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 45567d58599aac5847296b870e49c6e32f269371..caad896a0692747d4ca0dfe2cf40152b4bae9bd4 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,35 +202,27 @@ 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;
 }
 
 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)
@@ -238,11 +231,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);
 		}
 	}
 
@@ -498,14 +490,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();
@@ -523,8 +520,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 8e484c7e13b4862f453308fae449ba8e48cba58e..77bac87dbcda55d88724ed89145d682d644e43fc 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;
 };
 
 
@@ -125,6 +133,8 @@ class LLToolBar
 	bool enableCommand(const LLCommandId& commandId, bool enabled);
 	command_id_list_t& getCommandsList() { return mButtonCommands; }
 
+	LLToolBarButton* createButton(const LLCommandId& id);
+
 protected:
 	friend class LLUICtrlFactory;
 	LLToolBar(const Params&);
@@ -136,7 +146,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);
@@ -145,6 +154,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 f60598edcb12c64f2063d7c7760546cbf8fbd578..bb4ea815c96bc6d5ce2f6c88299304a515deb2fe 100644
--- a/indra/llui/lltoolbarview.cpp
+++ b/indra/llui/lltoolbarview.cpp
@@ -117,12 +117,8 @@ bool LLToolBarView::loadToolbars()
 	LLToolBarView::ToolbarSet toolbar_set;
 	
 	// Load the default toolbars.xml file
-	std::string toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "toolbars.xml");
-	if (!gDirUtilp->fileExists(toolbar_file)) 
-	{
-		llwarns << "User toolbars def not found -> use default" << llendl;
-		toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "toolbars.xml");
-	}
+	// *TODO : pick up the user's toolbar setting if existing
+	std::string toolbar_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "toolbars.xml");
 	
 	LLXMLNodePtr root;
 	if(!LLXMLNode::parseFile(toolbar_file, root, NULL))
@@ -174,17 +170,43 @@ void LLToolBarView::saveToolbars() const
 {
 	// Build the parameter tree from the toolbar data
 	LLToolBarView::ToolbarSet toolbar_set;
+	
+	// *TODO : factorize that code a bit...
 	if (mToolbarLeft)
 	{
-		addToToolset(mToolbarLeft->getCommandsList(),toolbar_set.left_toolbar);
+		command_id_list_t& command_list = mToolbarLeft->getCommandsList();
+		for (command_id_list_t::const_iterator it = command_list.begin();
+			 it != command_list.end();
+			 ++it)
+		{
+			LLCommandId::Params command;
+			command.name = it->name();		
+			toolbar_set.left_toolbar.commands.add(command);
+		}
 	}
 	if (mToolbarRight)
 	{
-		addToToolset(mToolbarRight->getCommandsList(),toolbar_set.right_toolbar);
+		command_id_list_t& command_list = mToolbarRight->getCommandsList();
+		for (command_id_list_t::const_iterator it = command_list.begin();
+			 it != command_list.end();
+			 ++it)
+		{
+			LLCommandId::Params command;
+			command.name = it->name();		
+			toolbar_set.right_toolbar.commands.add(command);
+		}
 	}
 	if (mToolbarBottom)
 	{
-		addToToolset(mToolbarBottom->getCommandsList(),toolbar_set.bottom_toolbar);
+		command_id_list_t& command_list = mToolbarBottom->getCommandsList();
+		for (command_id_list_t::const_iterator it = command_list.begin();
+			 it != command_list.end();
+			 ++it)
+		{
+			LLCommandId::Params command;
+			command.name = it->name();		
+			toolbar_set.bottom_toolbar.commands.add(command);
+		}
 	}
 	
 	// Serialize the parameter tree
@@ -206,19 +228,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 b19841997b4b03c2f393dbcc9b31864881775a12..ea3422f04e22c3011befd6e27d2adb721ab8f105 100644
--- a/indra/llui/lltoolbarview.h
+++ b/indra/llui/lltoolbarview.h
@@ -65,7 +65,10 @@ class LLToolBarView : public LLUICtrl
 	virtual ~LLToolBarView();
 	virtual BOOL postBuild();
 	virtual void draw();
-
+	virtual BOOL handleHover(S32 x, S32 y, MASK mask);
+	virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+	virtual void onMouseCaptureLost();
+	void startDrag(LLToolBarButton*);
 	// 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;
@@ -87,6 +90,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/llview.h b/indra/llui/llview.h
index 9039366e7e3ab5eb2414c33521666c73bf3e1416..f4e31b109a31b04fbf8a6f980c7d7fd2cc7f2a65 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -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
 	//////////////////////////////////////////////