diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index b5e870228ad68f9ab140abf6b99773e725cc3d29..d0c73fbfbce62a6ca5742a3f4bceb6561fa49634 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -63,6 +63,8 @@ static LLDefaultChildRegistry::Register<LLAccordionCtrl>	t2("accordion");
 
 LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
  , mFitParent(params.fit_parent)
+ , mAutoScrolling( false )
+ , mAutoScrollRate( 0.f )
 {
   mSingleExpansion = params.single_expansion;
 	if(mFitParent && !mSingleExpansion)
@@ -72,6 +74,8 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
 }
 
 LLAccordionCtrl::LLAccordionCtrl() : LLPanel()
+ , mAutoScrolling( false )
+ , mAutoScrollRate( 0.f )
 {
 	mSingleExpansion = false;
 	mFitParent = false;
@@ -81,6 +85,19 @@ LLAccordionCtrl::LLAccordionCtrl() : LLPanel()
 //---------------------------------------------------------------------------------
 void LLAccordionCtrl::draw()
 {
+	if (mAutoScrolling)
+	{
+		// add acceleration to autoscroll
+		mAutoScrollRate = llmin(mAutoScrollRate + (LLFrameTimer::getFrameDeltaTimeF32() * AUTO_SCROLL_RATE_ACCEL), MAX_AUTO_SCROLL_RATE);
+	}
+	else
+	{
+		// reset to minimum for next time
+		mAutoScrollRate = MIN_AUTO_SCROLL_RATE;
+	}
+	// clear this flag to be set on next call to autoScroll
+	mAutoScrolling = false;
+
 	LLRect local_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
 	
 	LLLocalClipRect clip(local_rect);
@@ -420,6 +437,64 @@ BOOL LLAccordionCtrl::handleKeyHere			(KEY key, MASK mask)
 	return LLPanel::handleKeyHere(key,mask);
 }
 
+BOOL LLAccordionCtrl::handleDragAndDrop		(S32 x, S32 y, MASK mask,
+											 BOOL drop,
+											 EDragAndDropType cargo_type,
+											 void* cargo_data,
+											 EAcceptance* accept,
+											 std::string& tooltip_msg)
+{
+	// Scroll folder view if needed.  Never accepts a drag or drop.
+	*accept = ACCEPT_NO;
+	BOOL handled = autoScroll(x, y);
+
+	if( !handled )
+	{
+		handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type,
+											cargo_data, accept, tooltip_msg) != NULL;
+	}
+	return TRUE;
+}
+
+BOOL LLAccordionCtrl::autoScroll		(S32 x, S32 y)
+{
+	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+	bool scrolling = false;
+	if( mScrollbar->getVisible() )
+	{
+		LLRect rect_local( 0, getRect().getHeight(), getRect().getWidth() - scrollbar_size, 0 );
+		LLRect screen_local_extents;
+
+		// clip rect against root view
+		screenRectToLocal(getRootView()->getLocalRect(), &screen_local_extents);
+		rect_local.intersectWith(screen_local_extents);
+
+		// autoscroll region should take up no more than one third of visible scroller area
+		S32 auto_scroll_region_height = llmin(rect_local.getHeight() / 3, 10);
+		S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
+
+		LLRect bottom_scroll_rect = screen_local_extents;
+		bottom_scroll_rect.mTop = rect_local.mBottom + auto_scroll_region_height;
+		if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar->getDocPos() < mScrollbar->getDocPosMax()) )
+		{
+			mScrollbar->setDocPos( mScrollbar->getDocPos() + auto_scroll_speed );
+			mAutoScrolling = true;
+			scrolling = true;
+		}
+
+		LLRect top_scroll_rect = screen_local_extents;
+		top_scroll_rect.mBottom = rect_local.mTop - auto_scroll_region_height;
+		if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar->getDocPos() > 0) )
+		{
+			mScrollbar->setDocPos( mScrollbar->getDocPos() - auto_scroll_speed );
+			mAutoScrolling = true;
+			scrolling = true;
+		}
+	}
+	return scrolling;
+}
+
 void	LLAccordionCtrl::updateLayout	(S32 width, S32 height)
 {
 	S32 panel_top = height - BORDER_MARGIN ;
diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h
index 4cb0f382813ab9ef14fba7f462ab451751c91606..d57a42df32447aea03ab276b233875040d9366df 100644
--- a/indra/llui/llaccordionctrl.h
+++ b/indra/llui/llaccordionctrl.h
@@ -81,6 +81,11 @@ class LLAccordionCtrl: public LLPanel
 	virtual BOOL handleRightMouseDown	( S32 x, S32 y, MASK mask); 
 	virtual BOOL handleScrollWheel		( S32 x, S32 y, S32 clicks );
 	virtual BOOL handleKeyHere			(KEY key, 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);
 	//
 
 	// Call reshape after changing splitter's size
@@ -112,11 +117,15 @@ class LLAccordionCtrl: public LLPanel
 	void	showScrollbar			(S32 width, S32 height);
 	void	hideScrollbar			(S32 width, S32 height);
 
+	BOOL	autoScroll				(S32 x, S32 y);
+
 private:
 	LLRect			mInnerRect;
 	LLScrollbar*	mScrollbar;
 	bool			mSingleExpansion;
 	bool			mFitParent;
+	bool			mAutoScrolling;
+	F32				mAutoScrollRate;
 };
 
 
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 4bfe44135aad29ab85914d25a8bab73924b35413..daa9e08f14097462166cb59dee136137cd308773 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -45,6 +45,7 @@ static const std::string DD_HEADER_NAME = "dd_header";
 static const S32 HEADER_HEIGHT = 20;
 static const S32 HEADER_IMAGE_LEFT_OFFSET = 5;
 static const S32 HEADER_TEXT_LEFT_OFFSET = 30;
+static const F32 AUTO_OPEN_TIME = 1.f;
 
 static LLDefaultChildRegistry::Register<LLAccordionCtrlTab> t1("accordion_tab");
 
@@ -73,6 +74,11 @@ class LLAccordionCtrlTab::LLAccordionCtrlTabHeader : public LLUICtrl
 	virtual void onMouseEnter(S32 x, S32 y, MASK mask);
 	virtual void onMouseLeave(S32 x, S32 y, MASK mask);
 	virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
+	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+								   EDragAndDropType cargo_type,
+								   void* cargo_data,
+								   EAcceptance* accept,
+								   std::string& tooltip_msg);
 private:
 
 	LLTextBox* mHeaderTextbox;
@@ -92,6 +98,8 @@ class LLAccordionCtrlTab::LLAccordionCtrlTabHeader : public LLUICtrl
 	LLUIColor mHeaderBGColor;
 
 	bool mNeedsHighlight;
+
+	LLFrameTimer mAutoOpenTimer;
 };
 
 LLAccordionCtrlTab::LLAccordionCtrlTabHeader::Params::Params()
@@ -209,6 +217,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::onMouseLeave(S32 x, S32 y, MA
 {
 	LLUICtrl::onMouseLeave(x, y, mask);
 	mNeedsHighlight = false;
+	mAutoOpenTimer.stop();
 }
 BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleKey(KEY key, MASK mask, BOOL called_from_parent)
 {
@@ -218,8 +227,33 @@ BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleKey(KEY key, MASK mask,
 	}
 	return LLUICtrl::handleKey(key, mask, called_from_parent);
 }
+BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleDragAndDrop(S32 x, S32 y, MASK mask,
+																	 BOOL drop,
+																	 EDragAndDropType cargo_type,
+																	 void* cargo_data,
+																	 EAcceptance* accept,
+																	 std::string& tooltip_msg)
+{
+	LLAccordionCtrlTab* parent = dynamic_cast<LLAccordionCtrlTab*>(getParent());
 
+	if ( parent && !parent->getDisplayChildren() && parent->getCollapsible() && parent->canOpenClose() )
+	{
+		if (mAutoOpenTimer.getStarted())
+		{
+			if (mAutoOpenTimer.getElapsedTimeF32() > AUTO_OPEN_TIME)
+			{
+				parent->changeOpenClose(false);
+				mAutoOpenTimer.stop();
+				return TRUE;
+			}
+		}
+		else
+			mAutoOpenTimer.start();
+	}
 
+	return LLUICtrl::handleDragAndDrop(x, y, mask, drop, cargo_type,
+									   cargo_data, accept, tooltip_msg);
+}
 LLAccordionCtrlTab::Params::Params()
 	: title("title")
 	,display_children("expanded", true)
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index b200d43438b5e2f4920a51a95965075a9a90c312..2e0260ab16df31bb319772ba8af6dddfb56d0fe5 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -115,6 +115,7 @@ class LLAccordionCtrlTab : public LLUICtrl
 	void changeOpenClose(bool is_open);
 
 	void canOpenClose(bool can_open_close) { mCanOpenClose = can_open_close;};
+	bool canOpenClose() const { return mCanOpenClose; };
 
 	virtual BOOL postBuild();