Index: include/IEventReceiver.h
===================================================================
--- include/IEventReceiver.h	(revision 6702)
+++ include/IEventReceiver.h	(working copy)
@@ -271,6 +271,20 @@
 			//! may be removed by Irrlicht 1.9
 			EGET_TREEVIEW_NODE_COLLAPS = EGET_TREEVIEW_NODE_COLLAPSE,
 
+			//! Dragging of a tree view node has started
+			EGET_TREEVIEW_NODE_DRAG,
+
+			//! This event is called before a tree node is dropped
+			//! Note: IGUITreeView::getLastEventNode() will return the target
+			EGET_TREEVIEW_NODE_WILL_DROP,
+
+			//! A tree view node is dropped
+			//! Note: IGUITreeView::getLastEventNode() will return the target
+			EGET_TREEVIEW_NODE_DROP,
+
+			//! Dragging was canceled
+			EGET_TREEVIEW_DRAG_CANCELED,
+
 			//! No real event. Just for convenience to get number of events
 			EGET_COUNT
 		};
Index: include/IGUITreeView.h
===================================================================
--- include/IGUITreeView.h	(revision 6702)
+++ include/IGUITreeView.h	(working copy)
@@ -17,7 +17,49 @@
 	class IGUITreeView;
 	class IGUIScrollBar;
 
+	enum EGUI_TREE_DROP_FLAGS {
+		//! Dropping the node is not allowed
+		EGTDF_CANNOT_DROP = 0,
 
+		//! No drag / drop activity is active at the moment (for convenience)
+		EGTDF_NONE = 0,
+
+		//! The dragged node can be inserted as a child
+		EGTDF_ADD_AS_CHILD = 1,
+
+		//! The dragged node can be inserted after the hovered node
+		EGTDF_ADD_AFTER = 2,
+
+		//! The dragged node can be inserted before the hovered node
+		EGTDF_ADD_BEFORE = 4,
+
+		//! Allow every drag / drop operation for the tree
+		EGTDF_ALLOW_DRAG_DROP = 7
+	};
+
+	enum EGUI_TRENODE_DROP_FLAGS {
+		//! Don't allow drag / drop for this node
+		EGNDF_NO_DRAGDROP = 0,
+
+		//! Allow dragging this node
+		EGNDF_DRAG_NODE = 1,
+
+		//! Allow dragged nodes added as children
+		EGNDF_DROP_ADD_CHILD = 2,
+
+		//! Allow dragged nodes to be added before this node
+		EGNDF_DROP_INSERT_BEFORE = 4,
+
+		//! Allow dragged nodes to be added after this node
+		EGNDF_DROP_INSERT_AFTER = 8,
+
+		//! Allow all types of insert for this node
+		EGNDF_DROP_ALL = 14,
+
+		//! Allow all drag / drop operation for this node (default)
+		EGNDF_ALLOW_ALL = 15
+	};
+
 	//! Node for gui tree view
 	/** \par This element can create the following events of type EGUI_EVENT_TYPE:
 	\li EGET_TREEVIEW_NODE_EXPAND
@@ -77,6 +119,14 @@
 		//! removes all children (recursive) from this node
 		virtual void clearChildren() = 0;
 
+		//! set the drag / drop flag for this node
+		/** \param flag the new value for the flags, a bitfield composed from the enum values of "EGUI_TRENODE_DROP_FLAGS"
+		*/
+		virtual void setDragDropFlag( irr::u32 flag ) = 0;
+
+		//! get the drag / drop flag for this node
+		virtual u32 getDragDropFlag() const = 0;
+
 		//! removes all children (recursive) from this node
 		/** \deprecated Deprecated in 1.8, use clearChildren() instead.
 		This method may be removed by Irrlicht 1.9 */
@@ -158,6 +208,16 @@
 				s32 imageIndex=-1, s32 selectedImageIndex=-1,
 				void* data=0, IReferenceCounted* data2=0) = 0;
 
+    /** Add a node as child at the end of the list of children
+    \param node the node to add 
+    */
+    virtual void addNodeBack(IGUITreeViewNode *node) = 0;
+
+    /** Add a node as child at the beginning of the list of children
+    \param node the node to add 
+    */
+    virtual void addNodeFront(IGUITreeViewNode *node) = 0;
+
 		//! Return the first child node from this node.
 		/** \return The first child node or 0 if this node has no children. */
 		virtual IGUITreeViewNode* getFirstChild() const = 0;
@@ -235,6 +295,23 @@
 	};
 
 
+	//! A struct for information on drag / drop activity
+	struct SGUIDragDropInformation
+	{
+		//! The dragged node
+		IGUITreeViewNode *DraggedNode;
+
+		//! The currently hovered node
+		IGUITreeViewNode *DropNode;
+
+		//! The current dragdrop state
+		EGUI_TREE_DROP_FLAGS DragDropState;
+
+		SGUIDragDropInformation() : DraggedNode( 0 ), DropNode( 0 ), DragDropState( EGTDF_NONE )
+		{
+		}
+		};
+
 	//! Default tree view GUI element.
 	/** Displays a windows like tree buttons to expand/collapse the child
 	nodes of an node and optional tree lines. Each node consists of an
@@ -317,6 +394,18 @@
 
 		//! Access the horizontal scrollbar
 		virtual IGUIScrollBar* getHorizontalScrollBar() const = 0;
+
+		//! returns the child at a position
+		virtual IGUITreeViewNode *getNodeAt(const irr::core::position2di &pos) = 0;
+
+		//! Cancel the node drag which is currently in progress
+		virtual void cancelNodeDrag() = 0;
+
+		//! Change the drag / drop flags for the tree as a bitfield of "EGUI_TREE_DROP_FLAGS" values
+		virtual void setDragDropFlags(irr::u32 flags) = 0;
+
+		//! Information of the current dragdrop activity (0 is returned if drag / drop is not active at the moment)
+		virtual const SGUIDragDropInformation *getDragDropInformation() const = 0;
 	};
 
 
Index: source/Irrlicht/CGUITreeView.cpp
===================================================================
--- source/Irrlicht/CGUITreeView.cpp	(revision 6702)
+++ source/Irrlicht/CGUITreeView.cpp	(working copy)
@@ -21,7 +21,7 @@
 
 CGUITreeViewNode::CGUITreeViewNode( CGUITreeView* owner, CGUITreeViewNode* parent )
 	: Owner(owner), Parent(parent), ImageIndex(-1), SelectedImageIndex(-1),
-	Data(0), Data2(0), Expanded(false)
+	Data(0), Data2(0), Expanded(false), DragDropFlags ( EGNDF_ALLOW_ALL )
 {
 #ifdef _DEBUG
 	setDebugName( "CGUITreeViewNode" );
@@ -69,6 +69,77 @@
 	Children.clear();
 }
 
+void CGUITreeViewNode::setDragDropFlag( irr::u32 flag ) {
+	DragDropFlags = flag;
+}
+
+u32 CGUITreeViewNode::getDragDropFlag() const {
+	return DragDropFlags;
+}
+
+void CGUITreeViewNode::addChildBefore(IGUITreeViewNode *node, IGUITreeViewNode *newNode) {
+	newNode->grab();
+	if (newNode->getParent()->deleteChild(newNode)) {
+		core::list<CGUITreeViewNode *>::Iterator itNode = Children.begin();
+
+		((CGUITreeViewNode *)newNode)->Parent = this;
+		while (*itNode != node && itNode != Children.end())
+			itNode++;
+
+	  if (itNode != Children.end())
+		  Children.insert_before(itNode, (CGUITreeViewNode *)newNode);
+	  else
+		  Children.push_back((CGUITreeViewNode *)newNode);
+	}
+	else newNode->drop();
+}
+
+void CGUITreeViewNode::addChildAfter(IGUITreeViewNode *node, IGUITreeViewNode *newNode) {
+	newNode->grab();
+	if (newNode->getParent()->deleteChild(newNode)) {
+		core::list<CGUITreeViewNode *>::Iterator itNode = Children.begin();
+
+		((CGUITreeViewNode *)newNode)->Parent = this;
+		while (*itNode != node && itNode != Children.end())
+			itNode++;
+
+		if (itNode != Children.end())
+			Children.insert_after(itNode, (CGUITreeViewNode *)newNode);
+		else
+			Children.push_back((CGUITreeViewNode *)newNode);
+	}
+	else newNode->drop();
+}
+
+void CGUITreeViewNode::addNodeBack(IGUITreeViewNode *node) {
+  node->grab();
+  if (node->getParent()->deleteChild(node)) {
+    ((CGUITreeViewNode *)node)->Parent = this;
+    Children.push_back((CGUITreeViewNode *)node);
+  }
+  else node->drop();
+}
+
+void CGUITreeViewNode::addNodeFront(IGUITreeViewNode *node) {
+  node->grab();
+  if (node->getParent()->deleteChild(node)) {
+    ((CGUITreeViewNode *)node)->Parent = this;
+    Children.push_front((CGUITreeViewNode *)node);
+  }
+  else node->drop();
+}
+
+void CGUITreeViewNode::addChild(CGUITreeViewNode *child)
+{
+	child->grab();
+	if ( child->getParent()  )
+	{
+		child->getParent()->deleteChild(child);
+	}
+	child->Parent = this;
+	Children.push_back(child);
+}
+
 IGUITreeViewNode* CGUITreeViewNode::addChildBack(
 	const wchar_t*		text,
 	const wchar_t*		icon /*= 0*/,
@@ -506,7 +577,7 @@
 	s32 id, core::rect<s32> rectangle, bool clip,
 	bool drawBack,bool scrollBarVertical, bool scrollBarHorizontal)
 	: IGUITreeView( environment, parent, id, rectangle ),
-	Root(0), Selected(0), HoverSelected(0),
+	Root(0), Selected(0), HoverSelected(0), DragCandidate(0),
 	ItemHeight( 0 ),
 	IndentWidth( 0 ),
 	TotalItemHeight( 0 ),
@@ -523,7 +594,8 @@
 	Selecting( false ),
 	Clip( clip ),
 	DrawBack( drawBack ),
-	ImageLeftOfIcon( true )
+	ImageLeftOfIcon( true ),
+	DragStateFlags( 0 )
 {
 #ifdef _DEBUG
 	setDebugName( "CGUITreeView" );
@@ -793,6 +865,79 @@
 	}
 }
 
+const SGUIDragDropInformation *CGUITreeView::getDragDropInformation() const {
+	if (DragDropInformation.DraggedNode == 0)
+		return 0;
+	else
+		return &DragDropInformation;
+}
+
+void CGUITreeView::setDragDropFlags(u32 flags)
+{
+	DragStateFlags = flags;
+	DragCandidate = 0;
+	DragDropInformation.DraggedNode = 0;
+}
+
+void CGUITreeView::cancelNodeDrag() 
+{
+	DragDropInformation.DraggedNode = 0;
+	DragDropInformation.DropNode = 0;
+	DragCandidate = 0;
+}
+
+bool CGUITreeView::canDropDraggedNode(CGUITreeViewNode *dropTarget)
+{
+	if (!DragDropInformation.DraggedNode || !dropTarget) 
+		return false;
+
+	CGUITreeViewNode *parent = dropTarget;
+	while (parent != Root) 
+	{
+		if (parent == DragDropInformation.DraggedNode)
+			return false;
+
+		parent = (CGUITreeViewNode *)parent->getParent();
+	}
+
+	return (dropTarget->getDragDropFlag() & EGNDF_DROP_ALL) != 0;
+}
+
+IGUITreeViewNode *CGUITreeView::getNodeAt(const irr::core::position2di& pos)
+{
+	if (!AbsoluteClippingRect.isPointInside(pos))
+		return 0;
+
+	s32 xpos = pos.X;
+	s32 ypos = pos.Y;
+
+	xpos -= AbsoluteRect.UpperLeftCorner.X;
+	ypos -= AbsoluteRect.UpperLeftCorner.Y;
+
+	s32	selIdx=-1;
+	// find new selected item.
+	s32 scrollBarVPos = ScrollBarV ? ScrollBarV->getPos() : 0;
+	if( ItemHeight != 0 )
+	{
+		selIdx = ( ( ypos - 1 ) + scrollBarVPos ) / ItemHeight;
+	}
+	IGUITreeViewNode* hitNode = 0;
+	IGUITreeViewNode* node = Root->getFirstChild();
+	s32	n = 0;
+	while( node )
+	{
+		if( selIdx == n )
+		{
+			hitNode = node;
+			break;
+		}
+		node = node->getNextVisible();
+		++n;
+	}
+
+	return hitNode;
+}
+
 //! called if an event happened.
 bool CGUITreeView::OnEvent( const SEvent &event )
 {
@@ -843,6 +988,12 @@
 						return true;
 					}
 
+					if (DragStateFlags != 0) {
+						DragCandidate = (CGUITreeViewNode *)getNodeAt(irr::core::position2di(event.MouseInput.X, event.MouseInput.Y));
+					if (DragCandidate && (DragCandidate->getDragDropFlag() & EGNDF_DRAG_NODE) == 0)
+						DragCandidate = 0;
+					}
+
 					Selecting = true;
 					return true;
 					break;
@@ -857,12 +1008,133 @@
 
 					Selecting = false;
 					mouseAction( event.MouseInput.X, event.MouseInput.Y );
+
+					if (DragStateFlags != 0) 
+					{
+						CGUITreeViewNode *dropCandidate = (CGUITreeViewNode *)getNodeAt(irr::core::position2di(event.MouseInput.X, event.MouseInput.Y));
+
+						if (DragDropInformation.DraggedNode != 0) 
+						{
+							if (DragDropInformation.DraggedNode == dropCandidate) 
+							{
+								DragDropInformation.DraggedNode = 0;
+							}
+							else if (!canDropDraggedNode(dropCandidate)) 
+							{
+								SEvent newEvent;
+								newEvent.EventType = irr::EET_GUI_EVENT;
+								newEvent.GUIEvent.Caller = this;
+								newEvent.GUIEvent.Element = 0;
+								newEvent.GUIEvent.EventType = irr::gui::EGET_TREEVIEW_DRAG_CANCELED;
+								Parent->OnEvent(newEvent);
+								DragDropInformation.DraggedNode = 0;
+							}
+						}
+
+						if (DragDropInformation.DraggedNode != 0) 
+						{
+							DragDropInformation.DropNode = dropCandidate;
+
+							SEvent newEvent;
+							newEvent.EventType = irr::EET_GUI_EVENT;
+							newEvent.GUIEvent.Caller = this;
+							newEvent.GUIEvent.Element = 0;
+							newEvent.GUIEvent.EventType = irr::gui::EGET_TREEVIEW_NODE_WILL_DROP;
+							Parent->OnEvent(newEvent);
+
+							if (DragDropInformation.DraggedNode != 0) 
+							{
+								bool nodeDropped = false;
+
+								if ((DragDropInformation.DragDropState & EGTDF_ADD_AS_CHILD) != 0) 
+								{
+									dropCandidate->addChild((CGUITreeViewNode *)DragDropInformation.DraggedNode);
+									dropCandidate->setExpanded(true);
+									nodeDropped = true;
+								}
+								else if ((DragDropInformation.DragDropState & EGTDF_ADD_BEFORE) != 0) 
+								{
+									((CGUITreeViewNode *)dropCandidate->getParent())->addChildBefore(dropCandidate, (CGUITreeViewNode *)DragDropInformation.DraggedNode);
+									nodeDropped = true;
+								}
+								else if ((DragDropInformation.DragDropState & EGTDF_ADD_AFTER) != 0) 
+								{
+									((CGUITreeViewNode *)dropCandidate->getParent())->addChildAfter(dropCandidate,(CGUITreeViewNode *)DragDropInformation.DraggedNode);
+									nodeDropped = true;
+								}
+
+								if (nodeDropped) 
+								{
+									Selected = (CGUITreeViewNode *)DragDropInformation.DraggedNode;
+									scrollTo(Selected, irr::gui::EGUIA_SCALE);
+									newEvent.GUIEvent.EventType = irr::gui::EGET_TREEVIEW_NODE_DROP;
+									Parent->OnEvent(newEvent);
+								}
+
+								DragDropInformation.DropNode = 0;
+								DragDropInformation.DraggedNode = 0;
+								DragDropInformation.DragDropState = EGTDF_NONE;
+							}
+						}
+					}
+
+					DragCandidate = 0;
+
 					return true;
 					break;
 
 				case EMIE_MOUSE_MOVED:
-					if( Selecting )
+					if (DragStateFlags != 0) 
 					{
+						if (DragCandidate != 0 && DragCandidate != getNodeAt(irr::core::position2di(event.MouseInput.X, event.MouseInput.Y))) 
+						{
+							DragDropInformation.DraggedNode = DragCandidate;
+							DragCandidate = 0;
+
+							SEvent newEvent;
+							newEvent.EventType = irr::EET_GUI_EVENT;
+							newEvent.GUIEvent.EventType = irr::gui::EGET_TREEVIEW_NODE_DRAG;
+							newEvent.GUIEvent.Caller = this;
+							Parent->OnEvent(newEvent);
+						}
+
+						if (DragDropInformation.DraggedNode != 0)
+							DragPosition = irr::core::position2di(event.MouseInput.X, event.MouseInput.Y);
+					}
+
+					if (DragDropInformation.DraggedNode != 0)
+					{
+						s32 rowY = AbsoluteClippingRect.UpperLeftCorner.Y + 1;
+						if ( ScrollBarV )
+						{
+							rowY -= ScrollBarV->getPos();
+						}
+
+						s32 dragOffset = (event.MouseInput.Y - rowY) % ItemHeight;
+
+						IGUITreeViewNode *hover = getNodeAt(irr::core::vector2di(event.MouseInput.X, event.MouseInput.Y));
+
+						DragDropInformation.DragDropState = EGTDF_NONE;
+
+						if (hover) {
+							if ((hover->getDragDropFlag() & (irr::u32)EGNDF_DROP_ADD_CHILD) != 0)
+								DragDropInformation.DragDropState = EGTDF_ADD_AS_CHILD;
+
+							if (dragOffset < 10 * ItemHeight / 100) 
+							{
+								if (DragStateFlags & EGTDF_ADD_BEFORE && hover->getDragDropFlag() & EGNDF_DROP_INSERT_BEFORE)
+								DragDropInformation.DragDropState = EGTDF_ADD_BEFORE;
+							}
+							else if (dragOffset > 90 * ItemHeight / 100) 
+							{
+								if (DragStateFlags & EGTDF_ADD_AFTER && hover->getDragDropFlag() & EGNDF_DROP_INSERT_AFTER)
+								DragDropInformation.DragDropState = EGTDF_ADD_AFTER;
+							}
+						}
+					}
+
+					if (DragDropInformation.DraggedNode != 0 && Selecting)
+					{
 						if( getAbsolutePosition().isPointInside( p ) )
 						{
 							mouseAction( event.MouseInput.X, event.MouseInput.Y, true );
@@ -1173,7 +1445,7 @@
 
 	if( DrawBack )
 	{
-		driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ), frameRect, clipRect );
+		driver->draw2DRectangle( skin->getColor( EGDC_3D_HIGH_LIGHT ) , frameRect, clipRect );
 	}
 
 	// draw the border
@@ -1242,10 +1514,43 @@
 		{
 			if( isSelected )
 			{
+				// Add "insert between" rendering here!
 				// selection box beginning from far left
 				core::rect<s32> copyFrameRect( frameRect ); // local copy to keep original untouched
 				copyFrameRect.UpperLeftCorner.X = AbsoluteRect.UpperLeftCorner.X + 1;
-				driver->draw2DRectangle( skin->getColor( EGDC_HIGH_LIGHT ), copyFrameRect, &clientClip );
+
+				if ( DragDropInformation.DraggedNode ) {
+					// First we draw a backgroud of the whole node hovered. 
+					// We need a color for this. The color is "EGFC_HIGH_LIGHT" by default
+					EGUI_DEFAULT_COLOR color = EGDC_HIGH_LIGHT;
+
+					// If the node needs to be inserted before or after we pick a color, ..
+					if ((DragDropInformation.DragDropState & (irr::u32)EGTDF_ADD_AFTER) != 0 || (DragDropInformation.DragDropState & (irr::u32)EGTDF_ADD_BEFORE) != 0)
+						color = EGDC_3D_SHADOW;
+					// .. if not and adding the node is child is not allowed we use another color
+					else if ((DragDropInformation.DragDropState & (irr::u32)EGTDF_ADD_AS_CHILD) == 0)
+						color = EGDC_INACTIVE_BORDER;
+
+					driver->draw2DRectangle( skin->getColor( color ), copyFrameRect, &clientClip );
+
+					// If a node is being dragged we check if it shall be inserted and not be added as a child
+					// and draw a small rectangle to indicate this to the user
+					if (DragDropInformation.DragDropState & EGTDF_ADD_AFTER) {
+						copyFrameRect.UpperLeftCorner.Y += 95 * copyFrameRect.getHeight() / 100;
+						if (copyFrameRect.UpperLeftCorner.Y >= copyFrameRect.LowerRightCorner.Y)
+							copyFrameRect.UpperLeftCorner.Y = copyFrameRect.LowerRightCorner.Y - 1;
+
+						driver->draw2DRectangle( skin->getColor(EGDC_ACTIVE_BORDER), copyFrameRect, &clientClip );
+					}
+					else if (DragDropInformation.DragDropState & EGTDF_ADD_BEFORE) {
+						copyFrameRect.LowerRightCorner.Y -= 95 * copyFrameRect.getHeight() / 100;
+						if (copyFrameRect.LowerRightCorner.Y <= copyFrameRect.UpperLeftCorner.Y)
+							copyFrameRect.LowerRightCorner.Y = copyFrameRect.UpperLeftCorner.Y + 1;
+
+						driver->draw2DRectangle( skin->getColor(EGDC_ACTIVE_BORDER), copyFrameRect, &clientClip );
+					}
+				}
+				else  driver->draw2DRectangle( skin->getColor(EGDC_HIGH_LIGHT), copyFrameRect, &clientClip );
 			}
 
 			irr::video::SColor textCol = isEnabled() ?
@@ -1406,6 +1711,14 @@
 		CGUITreeViewNode::getNextIterator(NodeIteratorStack, true);
 	}
 
+	// Draw dragged node
+	if ( DragDropInformation.DraggedNode && Font )
+	{
+		core::dimension2du textSize = Font->getDimension(DragDropInformation.DraggedNode->getText());
+		driver->draw2DRectangle(skin->getColor(EGDC_WINDOW), core::recti(DragPosition, textSize));
+		Font->draw(DragDropInformation.DraggedNode->getText(), core::recti(DragPosition, textSize), skin->getColor(EGDC_BUTTON_TEXT), true, true);
+	}
+
 	IGUIElement::draw();
 }
 
Index: source/Irrlicht/CGUITreeView.h
===================================================================
--- source/Irrlicht/CGUITreeView.h	(revision 6702)
+++ source/Irrlicht/CGUITreeView.h	(working copy)
@@ -98,9 +98,25 @@
 		virtual u32 getChildCount() const IRR_OVERRIDE
 		{ return Children.getSize(); }
 
+		//! set the drag / drop flag for this node
+		virtual void setDragDropFlag( irr::u32 flag ) IRR_OVERRIDE;
+
+		//! get the drag / drop flag for this node
+		virtual u32 getDragDropFlag() const IRR_OVERRIDE;
+
 		//! removes all children (recursive) from this node
 		virtual void clearChildren() IRR_OVERRIDE;
 
+		//! Add a node as child before another child. If the other child is not found the node is added at the end
+		void addChildBefore(IGUITreeViewNode *node, IGUITreeViewNode *newNode);
+
+		//! Add a node as child after another child. If the other child is not found the node is added at the end
+		void addChildAfter(IGUITreeViewNode *node, IGUITreeViewNode *newNode);
+
+    virtual void addNodeFront(IGUITreeViewNode *node) IRR_OVERRIDE;
+
+    virtual void addNodeBack(IGUITreeViewNode *node) IRR_OVERRIDE;
+
 		//! returns true if this node has child nodes
 		virtual bool hasChildren() const IRR_OVERRIDE
 		{ return !Children.empty(); }
@@ -207,6 +223,9 @@
 		//! Moves a child node one position down.
 		virtual bool moveChildDown( IGUITreeViewNode* child ) IRR_OVERRIDE;
 
+		//! move child from another node to this one
+		void addChild(CGUITreeViewNode *child);
+
 		//! Returns true if the node is expanded (children are visible).
 		virtual bool getExpanded() const IRR_OVERRIDE
 		{ return Expanded; }
@@ -248,6 +267,7 @@
 		IReferenceCounted*	Data2;
 		bool Expanded;
 		core::list<CGUITreeViewNode*> Children;
+		u32 DragDropFlags;
 	};
 
 
@@ -269,6 +289,9 @@
 		virtual IGUITreeViewNode* getRoot() const IRR_OVERRIDE
 		{ return Root; }
 
+		//! returns the child at a position
+		virtual IGUITreeViewNode *getNodeAt(const irr::core::position2di &pos) IRR_OVERRIDE;
+
 		//! returns the selected node of the tree or 0 if none is selected
 		virtual IGUITreeViewNode* getSelected() const IRR_OVERRIDE
 		{ 
@@ -346,6 +369,14 @@
 		//! Access the horizontal scrollbar
 		virtual IGUIScrollBar* getHorizontalScrollBar() const IRR_OVERRIDE;
 
+		virtual void cancelNodeDrag() IRR_OVERRIDE;
+
+		//! Set the drag / drop flags for this tree (a bitfield made up of "EGUI_TREE_DROP_FLAGS" values)
+		virtual void setDragDropFlags(irr::u32 flags) IRR_OVERRIDE;
+
+		//! Information of the current dragdrop activity (0 is returned if drag / drop is not active at the moment)
+		virtual const SGUIDragDropInformation *getDragDropInformation() const IRR_OVERRIDE;
+
 	private:
 		//! calculates the height of an node and of all visible nodes.
 		void recalculateItemHeight();
@@ -359,9 +390,16 @@
 		//! executes an mouse action (like selectNew of CGUIListBox)
 		void mouseAction( s32 xpos, s32 ypos, bool onlyHover = false );
 
+		bool canDropDraggedNode(CGUITreeViewNode *drop);
+
 		CGUITreeViewNode*	Root;
 		IGUITreeViewNode*	Selected;
 		IGUITreeViewNode*	HoverSelected;	// When we're in the middle of changing selection while mouse is pressed
+		// CGUITreeViewNode*	Dragged;
+		CGUITreeViewNode*	DragCandidate;
+
+		SGUIDragDropInformation DragDropInformation;
+
 		s32			ItemHeight;
 		s32			IndentWidth;
 		s32			TotalItemHeight;
@@ -381,6 +419,8 @@
 		bool			Clip;
 		bool			DrawBack;
 		bool			ImageLeftOfIcon;
+		core::position2di DragPosition;
+		u32 DragStateFlags;
 	};
 
 
