diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 97cf583a3c150d6b88aa7a9da90feadc907fb6f0..226a218e47be9b75875ae6d77c57956b99a0d0f5 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -422,7 +422,7 @@ int LLToolBar::getRankFromPosition(S32 x, S32 y)
 	LLRect button_rect;
 	while (it_button != end_button)
 	{
-		button_rect  = (*it_button)->getRect();
+		button_rect = (*it_button)->getRect();
 		S32 point_x = button_rect.mRight + mPadRight;
 		S32 point_y = button_rect.mBottom - mPadBottom;
 
@@ -444,11 +444,11 @@ int LLToolBar::getRankFromPosition(S32 x, S32 y)
 			S32 mid_point = (button_rect.mRight + button_rect.mLeft) / 2;
 			if (button_panel_x < mid_point)
 			{
-				mDragx = button_rect.mLeft - mPadLeft;
-				mDragy = button_rect.mTop + mPadTop;
-			}
-			else
-			{
+		mDragx = button_rect.mLeft - mPadLeft;
+		mDragy = button_rect.mTop + mPadTop;
+	}
+	else
+	{
 				rank++;
 				mDragx = button_rect.mRight + mPadRight - 1;
 				mDragy = button_rect.mTop + mPadTop;
@@ -475,12 +475,12 @@ int LLToolBar::getRankFromPosition(S32 x, S32 y)
 	{
 		// We hit passed the end of the list so put the insertion point at the end
 		if (orientation == LLLayoutStack::HORIZONTAL)
-		{
+	{
 			mDragx = button_rect.mRight + mPadRight;
 			mDragy = button_rect.mTop + mPadTop;
-		}
-		else
-		{
+	}
+	else
+	{
 			mDragx = button_rect.mLeft - mPadLeft;
 			mDragy = button_rect.mBottom - mPadBottom;
 		}
@@ -691,6 +691,7 @@ void LLToolBar::draw()
 			if (command && btn->mIsEnabledSignal)
 			{
 				const bool button_command_enabled = (*btn->mIsEnabledSignal)(btn, command->isEnabledParameters());
+				// TODO: make button appear disabled but have it still respond to drag and drop
 				btn->setEnabled(button_command_enabled);
 			}
 
@@ -964,6 +965,16 @@ void LLToolBarButton::onMouseCaptureLost()
 	mIsDragged = false;
 }
 
+void LLToolBarButton::onCommit()
+{
+	LLCommand* command = LLCommandManager::instance().getCommand(mId);
+
+	if (!mIsEnabledSignal || (*mIsEnabledSignal)(this, command->isEnabledParameters()))
+	{
+		LLButton::onCommit();
+	}
+}
+
 void LLToolBarButton::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
 	LLButton::reshape(mWidthRange.clamp(width), height, called_from_parent);
@@ -990,6 +1001,3 @@ const std::string LLToolBarButton::getToolTip() const
 
 
 
-
-
-
diff --git a/indra/llui/lltoolbar.h b/indra/llui/lltoolbar.h
index e78c99cb375aaff1ee5fab38307f77dbe737e62a..f7ec3186525f04e6f1dc6e89057b9f4249bcba11 100644
--- a/indra/llui/lltoolbar.h
+++ b/indra/llui/lltoolbar.h
@@ -72,9 +72,9 @@ class LLToolBarButton : public LLButton
 	void onMouseEnter(S32 x, S32 y, MASK mask);
 	void onMouseCaptureLost();
 
-	virtual const std::string getToolTip() const;		
-
+	void onCommit();
 
+	virtual const std::string getToolTip() const;		
 
 private:
 	LLCommandId		mId;
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index ca635eaa8f71a5c01eb7f00a195526dd7a8570a0..987651fc80435dfc493761b8ead5925b67e72b24 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -74,6 +74,7 @@ LLScreenChannel* LLChannelManager::createNotificationChannel()
 	LLScreenChannelBase::Params p;
 	p.id = LLUUID(gSavedSettings.getString("NotificationChannelUUID"));
 	p.channel_align = CA_RIGHT;
+	p.toast_align = NA_TOP;
 
 	// Getting a Channel for our notifications
 	return dynamic_cast<LLScreenChannel*> (LLChannelManager::getInstance()->getChannel(p));
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 3faf190618d35a72780c30bfd617b23790f65231..1ba1d2f0f06ac554576a04f715ab668e7fa96778 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -89,8 +89,6 @@ class LLNearbyChatScreenChannel: public LLScreenChannelBase
 	void onToastDestroyed	(LLToast* toast, bool app_quitting);
 	void onToastFade		(LLToast* toast);
 
-	void reshape			(S32 width, S32 height, BOOL called_from_parent);
-
 	void redrawToasts()
 	{
 		arrangeToasts();
@@ -379,7 +377,7 @@ void LLNearbyChatScreenChannel::arrangeToasts()
 	}
 
 	LLRect	toast_rect;	
-	updateBottom();
+	updateRect();
 
 	LLRect channel_rect;
 	floater_snap_region->localRectToOtherView(floater_snap_region->getLocalRect(), &channel_rect, gFloaterView);
@@ -436,15 +434,10 @@ void LLNearbyChatScreenChannel::arrangeToasts()
 		}
 	}
 
-	}
-
-void LLNearbyChatScreenChannel::reshape			(S32 width, S32 height, BOOL called_from_parent)
-{
-	LLScreenChannelBase::reshape(width, height, called_from_parent);
-	arrangeToasts();
 }
 
 
+
 //-----------------------------------------------------------------------------------------------
 //LLNearbyChatHandler
 //-----------------------------------------------------------------------------------------------
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 71b6c18d8f78e88a9187b6455f709728a19ebed1..45cf81751bebed046511bb4620d3c5e2db20981f 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -41,6 +41,7 @@
 #include "llsyswellwindow.h"
 #include "llimfloater.h"
 #include "llscriptfloater.h"
+#include "llrootview.h"
 
 #include <algorithm>
 
@@ -48,12 +49,19 @@ using namespace LLNotificationsUI;
 
 bool LLScreenChannel::mWasStartUpToastShown = false;
 
-
-LLRect get_channel_rect()
+LLFastTimer::DeclareTimer FTM_GET_CHANNEL_RECT("Calculate Notification Channel Region");
+LLRect LLScreenChannelBase::getChannelRect()
 {
+	LLFastTimer _(FTM_GET_CHANNEL_RECT);
 	LLRect channel_rect;
-	LLView* floater_snap_region = LLUI::getRootView()->getChildView("floater_snap_region");
+	LLRect chiclet_rect;
+	LLView* floater_snap_region = gViewerWindow->getRootView()->getChildView("floater_snap_region");
 	floater_snap_region->localRectToScreen(floater_snap_region->getLocalRect(), &channel_rect);
+
+	LLView* chiclet_region = gViewerWindow->getRootView()->getChildView("chiclet_container");
+	chiclet_region->localRectToScreen(chiclet_region->getLocalRect(), &chiclet_rect);
+
+	channel_rect.mTop = chiclet_rect.mBottom;
 	return channel_rect;
 }
 
@@ -81,6 +89,11 @@ LLScreenChannelBase::LLScreenChannelBase(const Params& p)
 	setVisible(FALSE);
 }
 
+void LLScreenChannelBase::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+	redrawToasts();
+}
+
 bool  LLScreenChannelBase::isHovering()
 {
 	if (!mHoveredToast)
@@ -116,16 +129,16 @@ void LLScreenChannelBase::updatePositionAndSize(LLRect rect)
 
 void LLScreenChannelBase::init(S32 channel_left, S32 channel_right)
 {
-	// top and bottom set by updateBottom()
+	// top and bottom set by updateRect()
 	setRect(LLRect(channel_left, 0, channel_right, 0));
-	updateBottom();
+	updateRect();
 	setVisible(TRUE);
 }
 
-void	LLScreenChannelBase::updateBottom()
+void	LLScreenChannelBase::updateRect()
 {
-	S32 channel_top = get_channel_rect().mTop;
-	S32 channel_bottom = get_channel_rect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
+	S32 channel_top = getChannelRect().mTop;
+	S32 channel_bottom = getChannelRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
 	S32 channel_left = getRect().mLeft;
 	S32 channel_right = getRect().mRight;
 	setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
@@ -146,7 +159,7 @@ LLScreenChannel::LLScreenChannel(const Params& p)
 void LLScreenChannel::init(S32 channel_left, S32 channel_right)
 {
 	LLScreenChannelBase::init(channel_left, channel_right);
-	LLRect channel_rect = get_channel_rect();
+	LLRect channel_rect = getChannelRect();
 	updatePositionAndSize(channel_rect);
 }
 
@@ -460,6 +473,15 @@ void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel)
 //--------------------------------------------------------------------------
 void LLScreenChannel::redrawToasts()
 {
+	LLView* floater_snap_region = gViewerWindow->getRootView()->getChildView("floater_snap_region");
+
+	if (!getParent())
+	{
+		// connect to floater snap region just to get resize events, we don't care about being a proper widget 
+		floater_snap_region->addChild(this);
+		setFollows(FOLLOWS_ALL);
+	}
+
 	if(mToastList.size() == 0)
 		return;
 
@@ -486,7 +508,7 @@ void LLScreenChannel::showToastsBottom()
 	S32		toast_margin = 0;
 	std::vector<ToastElem>::reverse_iterator it;
 
-	updateBottom();
+	updateRect();
 
 	LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get());
 
@@ -518,7 +540,7 @@ void LLScreenChannel::showToastsBottom()
 				(*it).toast->translate(0, shift);
 			}
 
-			LLRect channel_rect = get_channel_rect();
+			LLRect channel_rect = getChannelRect();
 			// don't show toasts if there is not enough space
 			if(toast_rect.mTop > channel_rect.mTop)
 			{
@@ -591,6 +613,96 @@ void LLScreenChannel::showToastsCentre()
 //--------------------------------------------------------------------------
 void LLScreenChannel::showToastsTop()
 {
+	LLRect channel_rect = getChannelRect();
+
+	LLRect	toast_rect;	
+	S32		top = channel_rect.mTop;
+	S32		toast_margin = 0;
+	std::vector<ToastElem>::reverse_iterator it;
+
+	updateRect();
+
+	LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get());
+
+	for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
+	{
+		if(it != mToastList.rbegin())
+		{
+			LLToast* toast = (*(it-1)).toast;
+			top = toast->getRect().mBottom - toast->getTopPad();
+			toast_margin = gSavedSettings.getS32("ToastGap");
+		}
+
+		toast_rect = (*it).toast->getRect();
+		toast_rect.setLeftTopAndSize(channel_rect.mRight - toast_rect.getWidth(),
+			top, toast_rect.getWidth(),
+			toast_rect.getHeight());
+		(*it).toast->setRect(toast_rect);
+
+		if(floater && floater->overlapsScreenChannel())
+		{
+			if(it == mToastList.rbegin())
+			{
+				// move first toast above docked floater
+				S32 shift = -floater->getRect().getHeight();
+				if(floater->getDockControl())
+				{
+					shift -= floater->getDockControl()->getTongueHeight();
+				}
+				(*it).toast->translate(0, shift);
+			}
+
+			LLRect channel_rect = getChannelRect();
+			// don't show toasts if there is not enough space
+			if(toast_rect.mBottom < channel_rect.mBottom)
+			{
+				break;
+			}
+		}
+
+		bool stop_showing_toasts = (*it).toast->getRect().mBottom < channel_rect.mBottom;
+
+		if(!stop_showing_toasts)
+		{
+			if( it != mToastList.rend()-1)
+			{
+				S32 toast_bottom = (*it).toast->getRect().mBottom - gSavedSettings.getS32("ToastGap");
+				stop_showing_toasts = toast_bottom < channel_rect.mBottom;
+			}
+		} 
+
+		// at least one toast should be visible
+		if(it == mToastList.rbegin())
+		{
+			stop_showing_toasts = false;
+		}
+
+		if(stop_showing_toasts)
+			break;
+
+		if( !(*it).toast->getVisible() )
+		{
+			// HACK
+			// EXT-2653: it is necessary to prevent overlapping for secondary showed toasts
+			(*it).toast->setVisible(TRUE);
+		}		
+		if(!(*it).toast->hasFocus())
+		{
+			// Fixing Z-order of toasts (EXT-4862)
+			// Next toast will be positioned under this one.
+			gFloaterView->sendChildToBack((*it).toast);
+		}
+	}
+
+	// Dismiss toasts we don't have space for (STORM-391).
+	if(it != mToastList.rend())
+	{
+		mHiddenToastsNum = 0;
+		for(; it != mToastList.rend(); it++)
+		{
+			(*it).toast->hide();
+		}
+	}
 }
 
 //--------------------------------------------------------------------------
@@ -820,7 +932,7 @@ void LLScreenChannel::updateShowToastsState()
 		return;
 	}
 
-	updateBottom();
+	updateRect();
 }
 
 //--------------------------------------------------------------------------
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index f4f52eea1977b498342d49154c54db4f3b64088b..2f23552828bf66335fa738a217f3835ea1f02f3d 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -70,6 +70,8 @@ class LLScreenChannelBase : public LLUICtrl
 
 	LLScreenChannelBase(const Params&);
 
+	void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
+
 	// Channel's outfit-functions
 	// update channel's size and position in the World View
 	virtual void		updatePositionAndSize(LLRect rect);
@@ -116,7 +118,8 @@ class LLScreenChannelBase : public LLUICtrl
 	LLHandle<LLScreenChannelBase> getHandle() { mRootHandle.bind(this); return mRootHandle; }
 
 protected:
-	void	updateBottom();
+	void	updateRect();
+	LLRect	getChannelRect();
 
 	// Channel's flags
 	bool		mControlHovering;