diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index ccc7aa8cec918b463fbf9745543ccfa4479af3f0..9c961d67d6f16f0558100a81f0b90d2095f92a56 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -71,7 +71,6 @@ set(llui_SOURCE_FILES
     llmultislider.cpp
     llmultisliderctrl.cpp
     llnotifications.cpp
-    llnotificationslistener.cpp
     llnotificationsutil.cpp
     llpanel.cpp
     llprogressbar.cpp
@@ -181,7 +180,6 @@ set(llui_HEADER_FILES
     llmultislider.h
     llnotificationptr.h
     llnotifications.h
-    llnotificationslistener.h
     llnotificationsutil.h
     llnotificationtemplate.h
     llnotificationvisibilityrule.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index f82cdc64a9c903ded0e45ded71006da3adc65d34..a8149a9a1dae6372f63f1d644ae28d8554e318f7 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -613,30 +613,6 @@ void LLButton::draw()
 	static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
 	F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
 
-	bool flash = false;
-	if (mFlashingTimer)
-	{
-		mFlashing = mFlashingTimer->isFlashingInProgress();
-		flash = mFlashing && (!sEnableButtonFlashing || mFlashingTimer->isCurrentlyHighlighted());
-	}
-	else 
-	{
-		if(mFlashing)
-		{
-			if ( sEnableButtonFlashing)
-			{
-				F32 elapsed = mFrameTimer.getElapsedTimeF32();
-				S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
-				// flash on or off?
-				flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
-			}
-			else
-			{ // otherwise just highlight button in flash color
-				flash = true;
-			}
-		}
-	}
-
 	bool pressed_by_keyboard = FALSE;
 	if (hasFocus())
 	{
@@ -660,9 +636,21 @@ void LLButton::draw()
 	bool selected = getToggleState();
 	
 	bool use_glow_effect = FALSE;
-	LLColor4 glow_color = LLColor4::white;
+	LLColor4 highlighting_color = LLColor4::white;
+	LLColor4 glow_color;
 	LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
 	LLUIImage* imagep = NULL;
+
+    //  Cancel sticking of color, if the button is pressed,
+	//  or when a flashing of the previously selected button is ended
+	if (mFlashingTimer
+		&& ((selected && !mFlashingTimer->isFlashingInProgress()) || pressed))
+	{
+		mFlashing = false;
+	}
+
+	bool flash = mFlashing && sEnableButtonFlashing;
+
 	if (pressed && mDisplayPressedState)
 	{
 		imagep = selected ? mImagePressedSelected : mImagePressed;
@@ -728,15 +716,20 @@ void LLButton::draw()
 			imagep = mImageFlash;
 		}
 		// else use usual flashing via flash_color
-		else
+		else if (mFlashingTimer)
 		{
 			LLColor4 flash_color = mFlashBgColor.get();
 			use_glow_effect = TRUE;
 			glow_type = LLRender::BT_ALPHA; // blend the glow
-			if (mNeedsHighlight) // highlighted AND flashing
-				glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
-			else
+
+			if (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress())
+			{
 				glow_color = flash_color;
+			}
+			else if (mNeedsHighlight)
+			{
+                glow_color = highlighting_color;
+			}
 		}
 	}
 
@@ -785,8 +778,7 @@ void LLButton::draw()
 	if (use_glow_effect)
 	{
 		mCurGlowStrength = lerp(mCurGlowStrength,
-					mFlashing ? (flash? 1.0 : 0.0)
-					: mHoverGlowStrength,
+					mFlashing ? (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress() || mNeedsHighlight? 1.0 : 0.0) : mHoverGlowStrength,
 					LLCriticalDamp::getInterpolant(0.05f));
 	}
 	else
@@ -973,23 +965,18 @@ void LLButton::setToggleState(BOOL b)
 	{
 		setControlValue(b); // will fire LLControlVariable callbacks (if any)
 		setValue(b);        // may or may not be redundant
+		setFlashing(false);	// stop flash state whenever the selected/unselected state if reset
 		// Unselected label assignments
 		autoResize();
 	}
 }
 
-void LLButton::setFlashing( bool b )	
+void LLButton::setFlashing(bool b)	
 { 
 	if (mFlashingTimer)
 	{
-		if (b)
-		{
-			mFlashingTimer->startFlashing();
-		}
-		else
-		{
-			mFlashingTimer->stopFlashing();
-		}
+		mFlashing = b; 
+		(b ? mFlashingTimer->startFlashing() : mFlashingTimer->stopFlashing());
 	}
 	else if (b != mFlashing)
 	{
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index a33ffc4240c31f918c37f5fc2ab5746da4b9e48c..7ae79d94fee7fbcb0014ebb27e59b3f508bb7edf 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1913,14 +1913,15 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu)
 
 	// Successively filter out invalid options
 
-	U32 flags = FIRST_SELECTED_ITEM;
+	U32 multi_select_flag = (mSelectedItems.size() > 1 ? ITEM_IN_MULTI_SELECTION : 0x0);
+	U32 flags = multi_select_flag | FIRST_SELECTED_ITEM;
 	for (selected_items_t::iterator item_itor = mSelectedItems.begin();
 			item_itor != mSelectedItems.end();
 			++item_itor)
 	{
 		LLFolderViewItem* selected_item = (*item_itor);
 		selected_item->buildContextMenu(*menu, flags);
-		flags = 0x0;
+		flags = multi_select_flag;
 	}
 
 	addNoOptions(menu);
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index d4a1434c73fa02203130057bbd039284e69d171e..2ee7417240d4fe5f49e2e9dc0ec6a53933abaffa 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -400,5 +400,6 @@ class LLOpenFoldersWithSelection : public LLFolderViewFunctor
 // Flags for buildContextMenu()
 const U32 SUPPRESS_OPEN_ITEM = 0x1;
 const U32 FIRST_SELECTED_ITEM = 0x2;
+const U32 ITEM_IN_MULTI_SELECTION = 0x4;
 
 #endif // LL_LLFOLDERVIEW_H
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 0a06ce66aae964a201df937ebe59e8b4e40dadef..1281d6bd66ea75a8dafc2345808d3bb88f79c38c 100755
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -50,6 +50,7 @@ std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
 bool LLFolderViewItem::sColorSetInitialized = false;
 LLUIColor LLFolderViewItem::sFgColor;
 LLUIColor LLFolderViewItem::sHighlightBgColor;
+LLUIColor LLFolderViewItem::sFlashBgColor;
 LLUIColor LLFolderViewItem::sFocusOutlineColor;
 LLUIColor LLFolderViewItem::sMouseOverColor;
 LLUIColor LLFolderViewItem::sFilterBGColor;
@@ -151,6 +152,7 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	{
 		sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
 		sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+		sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
 		sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
 		sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
 		sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
@@ -686,26 +688,31 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L
 	return mIsCurSelection;
 }
 
-void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, 
+void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor,  
                                                         const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor)
 {
-
-    //--------------------------------------------------------------------------------//
-    // Draw highlight for selected items
-    //
-
     const S32 focus_top = getRect().getHeight();
     const S32 focus_bottom = getRect().getHeight() - mItemHeight;
     const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
     const S32 FOCUS_LEFT = 1;
+	
+	// Determine which background color to use for highlighting
+	LLUIColor bgColor = (isFlashing() ? flashColor : selectColor);
 
-    if (isHighlightAllowed())	// always render "current" item (only render other selected items if
-    							// mShowSingleSelection is FALSE) or flashing item
+    //--------------------------------------------------------------------------------//
+    // Draw highlight for selected items
+	// Note: Always render "current" item or flashing item, only render other selected 
+	// items if mShowSingleSelection is FALSE.
+    //
+    if (isHighlightAllowed())	
+    							
     {
         gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-        LLColor4 bg_color = bgColor;
-        if (!isHighlightActive())
+		
+		// Highlight for selected but not current items
+        if (!isHighlightActive() && !isFlashing())
         {
+			LLColor4 bg_color = bgColor;
             // do time-based fade of extra objects
             F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
             if (getRoot() && getRoot()->getShowSingleSelection())
@@ -718,25 +725,30 @@ void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeybo
                 // fading in
                 bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
             }
+        	gl_rect_2d(FOCUS_LEFT,
+					   focus_top,
+					   getRect().getWidth() - 2,
+					   focus_bottom,
+					   bg_color, hasKeyboardFocus);
         }
 
-        if (isHighlightAllowed() || isHighlightActive())
+		// Highlight for currently selected or flashing item
+        if (isHighlightActive())
         {
+			// Background
         	gl_rect_2d(FOCUS_LEFT,
                 focus_top,
                 getRect().getWidth() - 2,
                 focus_bottom,
-                bg_color, hasKeyboardFocus);
-        }
-
-        if (isHighlightActive())
-        {
+                bgColor, hasKeyboardFocus);
+			// Outline
             gl_rect_2d(FOCUS_LEFT, 
                 focus_top, 
                 getRect().getWidth() - 2,
                 focus_bottom,
                 focusOutlineColor, FALSE);
         }
+
         if (folder_open)
         {
             gl_rect_2d(FOCUS_LEFT,
@@ -810,7 +822,7 @@ void LLFolderViewItem::draw()
 
     drawOpenFolderArrow(default_params, sFgColor);
 
-    drawHighlight(show_context, filled, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
+    drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
 
 	//--------------------------------------------------------------------------------//
 	// Draw open icon
@@ -1481,17 +1493,20 @@ void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
 
 void LLFolderViewFolder::destroyView()
 {
-	std::for_each(mItems.begin(), mItems.end(), DeletePointer());
-	mItems.clear();
+    while (!mItems.empty())
+    {
+    	LLFolderViewItem *itemp = mItems.back();
+    	itemp->destroyView(); // LLFolderViewItem::destroyView() removes entry from mItems
+    }
 
 	while (!mFolders.empty())
 	{
 		LLFolderViewFolder *folderp = mFolders.back();
-		folderp->destroyView(); // removes entry from mFolders
+		folderp->destroyView(); // LLFolderVievFolder::destroyView() removes entry from mFolders
 	}
 
 	LLFolderViewItem::destroyView();
-	}
+}
 
 // extractItem() removes the specified item from the folder, but
 // doesn't delete it.
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index d7f5e86aea94303c39b3aa900df77bab357cf356..ca31931e19443d94400473c4c1189fcc50217c71 100755
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -128,6 +128,7 @@ class LLFolderViewItem : public LLView
 	static LLUIColor			sFgColor;
 	static LLUIColor			sFgDisabledColor;
 	static LLUIColor			sHighlightBgColor;
+	static LLUIColor			sFlashBgColor;
 	static LLUIColor			sFocusOutlineColor;
 	static LLUIColor			sMouseOverColor;
 	static LLUIColor			sFilterBGColor;
@@ -141,6 +142,8 @@ class LLFolderViewItem : public LLView
 	virtual void addFolder(LLFolderViewFolder*) { }
 	virtual bool isHighlightAllowed();
 	virtual bool isHighlightActive();
+	virtual bool isFlashing() { return false; }
+	virtual void setFlashState(bool) { }
 
 	static LLFontGL* getLabelFontForStyle(U8 style);
 
@@ -269,7 +272,7 @@ class LLFolderViewItem : public LLView
 	//	virtual void handleDropped();
 	virtual void draw();
 	void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color);
-    void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &bgColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
+    void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
     void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
 	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 									EDragAndDropType cargo_type,
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 06742756128948df24d397f9cc0dd18e72fda384..e64288399133a970e51946e4475ec92691974ef0 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -32,7 +32,6 @@
 
 #include "lllocalcliprect.h"
 #include "llpanel.h"
-#include "llresizebar.h"
 #include "llcriticaldamp.h"
 #include "boost/foreach.hpp"
 
@@ -796,6 +795,11 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 				}
 				else
 				{
+					if (new_auto_resize_headroom < 1.f)
+					{
+						new_auto_resize_headroom = 1.f;
+					}
+
 					F32 new_fractional_size = llclamp(total_visible_fraction * (F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom) 
 														/ new_auto_resize_headroom,
 													MIN_FRACTIONAL_SIZE,
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index 883331c7925d3b0bf426acf11301638a071519ee..02c664f1a060bbcaa51d93143d31ef4f2b168c27 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -29,6 +29,7 @@
 #define LL_LLLAYOUTSTACK_H
 
 #include "llpanel.h"
+#include "llresizebar.h"
 
 
 class LLLayoutPanel;
@@ -178,6 +179,7 @@ friend class LLUICtrlFactory;
 	F32 getAutoResizeFactor() const;
 	F32 getVisibleAmount() const;
 	S32 getVisibleDim() const;
+	LLResizeBar* getResizeBar() { return mResizeBar; }
 
 	bool isCollapsed() const { return mCollapsed;}
 
diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index 02ff64dbc61bede62b7aa31cef1bb21fc21258fa..179b251cdbc5929b0788e9b427c5f16418bf459a 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -41,8 +41,8 @@ LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params)
 	  mTabContainer(NULL),
 	  mTabPos(LLTabContainer::TOP),
 	  mAutoResize(TRUE),
-	  mOrigMinWidth(0),
-	  mOrigMinHeight(0)
+	  mOrigMinWidth(params.min_width),
+	  mOrigMinHeight(params.min_height)
 {
 }
 
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 8fb7a9d864706e186ebbed8b4842cd158ad4111b..89fb5ed30c8aaa29c842225c58bcfb7c253b7964 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -39,7 +39,6 @@
 #include "lldir.h"
 #include "llsdserialize.h"
 #include "lltrans.h"
-#include "llnotificationslistener.h"
 #include "llstring.h"
 #include "llsdparam.h"
 #include "llsdutil.h"
@@ -993,10 +992,12 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 	bool abortProcessing = false;
 	if (passesFilter)
 	{
+		onFilterPass(pNotification);
 		abortProcessing = mPassedFilter(payload);
 	}
 	else
 	{
+		onFilterFail(pNotification);
 		abortProcessing = mFailedFilter(payload);
 	}
 	
@@ -1168,8 +1169,6 @@ LLNotifications::LLNotifications()
 	mIgnoreAllNotifications(false)
 {
 	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
-
-    mListener.reset(new LLNotificationsListener(*this));
 }
 
 
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 372b9ce46fe23ee0b923059ddfc51cee00477e73..42dee4c3e991c62d7969ce43b69da14dfcecb536 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -92,7 +92,6 @@
 #include "llevents.h"
 #include "llfunctorregistry.h"
 #include "llinitparam.h"
-#include "llnotificationslistener.h"
 #include "llnotificationptr.h"
 #include "llpointer.h"
 #include "llrefcount.h"
@@ -681,7 +680,6 @@ namespace LLNotificationComparators
 };
 
 typedef boost::function<bool (LLNotificationPtr)> LLNotificationFilter;
-typedef boost::function<bool (LLNotificationPtr, LLNotificationPtr)> LLNotificationComparator;
 typedef std::set<LLNotificationPtr, LLNotificationComparators::orderByUUID> LLNotificationSet;
 typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
 
@@ -776,6 +774,9 @@ class LLNotificationChannelBase :
 	virtual void onDelete(LLNotificationPtr p) {}
 	virtual void onChange(LLNotificationPtr p) {}
 
+	virtual void onFilterPass(LLNotificationPtr p) {}
+	virtual void onFilterFail(LLNotificationPtr p) {}
+
 	bool updateItem(const LLSD& payload, LLNotificationPtr pNotification);
 	LLNotificationFilter mFilter;
 };
@@ -831,7 +832,6 @@ class LLNotificationChannel :
 private:
 	std::string mName;
 	std::string mParent;
-	LLNotificationComparator mComparator;
 };
 
 // An interface class to provide a clean linker seam to the LLNotifications class.
@@ -951,7 +951,6 @@ class LLNotifications :
 
 	bool mIgnoreAllNotifications;
 
-    boost::scoped_ptr<LLNotificationsListener> mListener;
 	std::vector<LLNotificationChannelPtr> mDefaultChannels;
 };
 
@@ -1030,7 +1029,7 @@ class LLPostponedNotification
 
 // Stores only persistent notifications.
 // Class users can use connectChanged() to process persistent notifications
-// (see LLNotificationStorage for example).
+// (see LLPersistentNotificationStorage for example).
 class LLPersistentNotificationChannel : public LLNotificationChannel
 {
 	LOG_CLASS(LLPersistentNotificationChannel);
diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
deleted file mode 100644
index e4e127336b5e41c773652ef5bb25e87ed8e9a727..0000000000000000000000000000000000000000
--- a/indra/llui/llnotificationslistener.cpp
+++ /dev/null
@@ -1,354 +0,0 @@
-/**
- * @file   llnotificationslistener.cpp
- * @author Brad Kittenbrink
- * @date   2009-07-08
- * @brief  Implementation for llnotificationslistener.
- * 
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-#include "llnotificationslistener.h"
-#include "llnotifications.h"
-#include "llnotificationtemplate.h"
-#include "llsd.h"
-#include "llui.h"
-
-LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) :
-    LLEventAPI("LLNotifications",
-               "LLNotifications listener to (e.g.) pop up a notification"),
-    mNotifications(notifications)
-{
-    add("requestAdd",
-        "Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n"
-        "If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.",
-        &LLNotificationsListener::requestAdd);
-    add("listChannels",
-        "Post to [\"reply\"] a map of info on existing channels",
-        &LLNotificationsListener::listChannels,
-        LLSD().with("reply", LLSD()));
-    add("listChannelNotifications",
-        "Post to [\"reply\"] an array of info on notifications in channel [\"channel\"]",
-        &LLNotificationsListener::listChannelNotifications,
-        LLSD().with("reply", LLSD()).with("channel", LLSD()));
-    add("respond",
-        "Respond to notification [\"uuid\"] with data in [\"response\"]",
-        &LLNotificationsListener::respond,
-        LLSD().with("uuid", LLSD()));
-    add("cancel",
-        "Cancel notification [\"uuid\"]",
-        &LLNotificationsListener::cancel,
-        LLSD().with("uuid", LLSD()));
-    add("ignore",
-        "Ignore future notification [\"name\"]\n"
-        "(from <notification name= > in notifications.xml)\n"
-        "according to boolean [\"ignore\"].\n"
-        "If [\"name\"] is omitted or undefined, [un]ignore all future notifications.\n"
-        "Note that ignored notifications are not forwarded unless intercepted before\n"
-        "the \"Ignore\" channel.",
-        &LLNotificationsListener::ignore);
-    add("forward",
-        "Forward to [\"pump\"] future notifications on channel [\"channel\"]\n"
-        "according to boolean [\"forward\"]. When enabled, only types matching\n"
-        "[\"types\"] are forwarded, as follows:\n"
-        "omitted or undefined: forward all notifications\n"
-        "string: forward only the specific named [sig]type\n"
-        "array of string: forward any notification matching any named [sig]type.\n"
-        "When boolean [\"respond\"] is true, we auto-respond to each forwarded\n"
-        "notification.",
-        &LLNotificationsListener::forward,
-        LLSD().with("channel", LLSD()));
-}
-
-// This is here in the .cpp file so we don't need the definition of class
-// Forwarder in the header file.
-LLNotificationsListener::~LLNotificationsListener()
-{
-}
-
-void LLNotificationsListener::requestAdd(const LLSD& event_data) const
-{
-	if(event_data.has("reply"))
-	{
-		mNotifications.add(event_data["name"], 
-						   event_data["substitutions"], 
-						   event_data["payload"],
-						   boost::bind(&LLNotificationsListener::NotificationResponder, 
-									   this, 
-									   event_data["reply"].asString(), 
-									   _1, _2
-									   )
-						   );
-	}
-	else
-	{
-		mNotifications.add(event_data["name"], 
-						   event_data["substitutions"], 
-						   event_data["payload"]);
-	}
-}
-
-void LLNotificationsListener::NotificationResponder(const std::string& reply_pump, 
-										const LLSD& notification, 
-										const LLSD& response) const
-{
-	LLSD reponse_event;
-	reponse_event["notification"] = notification;
-	reponse_event["response"] = response;
-	LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event);
-}
-
-void LLNotificationsListener::listChannels(const LLSD& params) const
-{
-    LLReqID reqID(params);
-    LLSD response(reqID.makeResponse());
-    for (LLNotificationChannel::instance_iter cmi(LLNotificationChannel::beginInstances()),
-                                                     cmend(LLNotificationChannel::endInstances());
-         cmi != cmend; ++cmi)
-    {
-        LLSD channelInfo;
-        //channelInfo["parent"] = cmi->second->getParentChannelName();
-        response[cmi->getName()] = channelInfo;
-    }
-    LLEventPumps::instance().obtain(params["reply"]).post(response);
-}
-
-void LLNotificationsListener::listChannelNotifications(const LLSD& params) const
-{
-    LLReqID reqID(params);
-    LLSD response(reqID.makeResponse());
-    LLNotificationChannelPtr channel(mNotifications.getChannel(params["channel"]));
-    if (channel)
-    {
-        LLSD notifications(LLSD::emptyArray());
-        for (LLNotificationChannel::Iterator ni(channel->begin()), nend(channel->end());
-             ni != nend; ++ni)
-        {
-            notifications.append(asLLSD(*ni));
-        }
-        response["notifications"] = notifications;
-    }
-    LLEventPumps::instance().obtain(params["reply"]).post(response);
-}
-
-void LLNotificationsListener::respond(const LLSD& params) const
-{
-    LLNotificationPtr notification(mNotifications.find(params["uuid"]));
-    if (notification)
-    {
-        notification->respond(params["response"]);
-    }
-}
-
-void LLNotificationsListener::cancel(const LLSD& params) const
-{
-    LLNotificationPtr notification(mNotifications.find(params["uuid"]));
-    if (notification)
-    {
-        mNotifications.cancel(notification);
-    }
-}
-
-void LLNotificationsListener::ignore(const LLSD& params) const
-{
-    // Calling a method named "ignore", but omitting its "ignore" Boolean
-    // argument, should by default cause something to be ignored. Explicitly
-    // pass ["ignore"] = false to cancel ignore.
-    bool ignore = true;
-    if (params.has("ignore"))
-    {
-        ignore = params["ignore"].asBoolean();
-    }
-    // This method can be used to affect either a single notification name or
-    // all future notifications. The two use substantially different mechanisms.
-    if (params["name"].isDefined())
-    {
-        // ["name"] was passed: ignore just that notification
-		LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]);
-		if (templatep)
-		{
-			templatep->mForm->setIgnored(ignore);
-		}
-    }
-    else
-    {
-        // no ["name"]: ignore all future notifications
-        mNotifications.setIgnoreAllNotifications(ignore);
-    }
-}
-
-class LLNotificationsListener::Forwarder: public LLEventTrackable
-{
-    LOG_CLASS(LLNotificationsListener::Forwarder);
-public:
-    Forwarder(LLNotifications& llnotifications, const std::string& channel):
-        mNotifications(llnotifications),
-        mRespond(false)
-    {
-        // Connect to the specified channel on construction. Because
-        // LLEventTrackable is a base, we should automatically disconnect when
-        // destroyed.
-        LLNotificationChannelPtr channelptr(llnotifications.getChannel(channel));
-        if (channelptr)
-        {
-            // Insert our processing as a "passed filter" listener. This way
-            // we get to run before all the "changed" listeners, and we get to
-            // swipe it (hide it from the other listeners) if desired.
-            channelptr->connectPassedFilter(boost::bind(&Forwarder::handle, this, _1));
-        }
-    }
-
-    void setPumpName(const std::string& name) { mPumpName = name; }
-    void setTypes(const LLSD& types) { mTypes = types; }
-    void setRespond(bool respond) { mRespond = respond; }
-
-private:
-    bool handle(const LLSD& notification) const;
-    bool matchType(const LLSD& filter, const std::string& type) const;
-
-    LLNotifications& mNotifications;
-    std::string mPumpName;
-    LLSD mTypes;
-    bool mRespond;
-};
-
-void LLNotificationsListener::forward(const LLSD& params)
-{
-    std::string channel(params["channel"]);
-    // First decide whether we're supposed to start forwarding or stop it.
-    // Default to true.
-    bool forward = true;
-    if (params.has("forward"))
-    {
-        forward = params["forward"].asBoolean();
-    }
-    if (! forward)
-    {
-        // This is a request to stop forwarding notifications on the specified
-        // channel. The rest of the params don't matter.
-        // Because mForwarders contains scoped_ptrs, erasing the map entry
-        // DOES delete the heap Forwarder object. Because Forwarder derives
-        // from LLEventTrackable, destroying it disconnects it from the
-        // channel.
-        mForwarders.erase(channel);
-        return;
-    }
-    // From here on, we know we're being asked to start (or modify) forwarding
-    // on the specified channel. Find or create an appropriate Forwarder.
-    ForwarderMap::iterator
-        entry(mForwarders.insert(ForwarderMap::value_type(channel, ForwarderMap::mapped_type())).first);
-    if (! entry->second)
-    {
-        entry->second.reset(new Forwarder(mNotifications, channel));
-    }
-    // Now, whether this Forwarder is brand-new or not, update it with the new
-    // request info.
-    Forwarder& fwd(*entry->second);
-    fwd.setPumpName(params["pump"]);
-    fwd.setTypes(params["types"]);
-    fwd.setRespond(params["respond"]);
-}
-
-bool LLNotificationsListener::Forwarder::handle(const LLSD& notification) const
-{
-    LL_INFOS("LLNotificationsListener") << "handle(" << notification << ")" << LL_ENDL;
-    if (notification["sigtype"].asString() == "delete")
-    {
-        LL_INFOS("LLNotificationsListener") << "ignoring delete" << LL_ENDL;
-        // let other listeners see the "delete" operation
-        return false;
-    }
-    LLNotificationPtr note(mNotifications.find(notification["id"]));
-    if (! note)
-    {
-        LL_INFOS("LLNotificationsListener") << notification["id"] << " not found" << LL_ENDL;
-        return false;
-    }
-    if (! matchType(mTypes, note->getType()))
-    {
-        LL_INFOS("LLNotificationsListener") << "didn't match types " << mTypes << LL_ENDL;
-        // We're not supposed to intercept this particular notification. Let
-        // other listeners process it.
-        return false;
-    }
-    LL_INFOS("LLNotificationsListener") << "sending via '" << mPumpName << "'" << LL_ENDL;
-    // This is a notification we care about. Forward it through specified
-    // LLEventPump.
-    LLEventPumps::instance().obtain(mPumpName).post(asLLSD(note));
-    // Are we also being asked to auto-respond?
-    if (mRespond)
-    {
-        LL_INFOS("LLNotificationsListener") << "should respond" << LL_ENDL;
-        note->respond(LLSD::emptyMap());
-        // Did that succeed in removing the notification? Only cancel() if
-        // it's still around -- otherwise we get an LL_ERRS crash!
-        note = mNotifications.find(notification["id"]);
-        if (note)
-        {
-            LL_INFOS("LLNotificationsListener") << "respond() didn't clear, canceling" << LL_ENDL;
-            mNotifications.cancel(note);
-        }
-    }
-    // If we've auto-responded to this notification, then it's going to be
-    // deleted. Other listeners would get the change operation, try to look it
-    // up and be baffled by lookup failure. So when we auto-respond, suppress
-    // this notification: don't pass it to other listeners.
-    return mRespond;
-}
-
-bool LLNotificationsListener::Forwarder::matchType(const LLSD& filter, const std::string& type) const
-{
-    // Decide whether this notification matches filter:
-    // undefined: forward all notifications
-    if (filter.isUndefined())
-    {
-        return true;
-    }
-    // array of string: forward any notification matching any named type
-    if (filter.isArray())
-    {
-        for (LLSD::array_const_iterator ti(filter.beginArray()), tend(filter.endArray());
-             ti != tend; ++ti)
-        {
-            if (ti->asString() == type)
-            {
-                return true;
-            }
-        }
-        // Didn't match any entry in the array
-        return false;
-    }
-    // string: forward only the specific named type
-    return (filter.asString() == type);
-}
-
-LLSD LLNotificationsListener::asLLSD(LLNotificationPtr note)
-{
-    LLSD notificationInfo(note->asLLSD());
-    // For some reason the following aren't included in LLNotification::asLLSD().
-    notificationInfo["summary"] = note->summarize();
-    notificationInfo["id"]      = note->id();
-    notificationInfo["type"]    = note->getType();
-    notificationInfo["message"] = note->getMessage();
-    notificationInfo["label"]   = note->getLabel();
-    return notificationInfo;
-}
diff --git a/indra/llui/llnotificationslistener.h b/indra/llui/llnotificationslistener.h
deleted file mode 100644
index f9f7641de6c5fb1f8d4d7073a435d73d7348fc5b..0000000000000000000000000000000000000000
--- a/indra/llui/llnotificationslistener.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * @file   llnotificationslistener.h
- * @author Brad Kittenbrink
- * @date   2009-07-08
- * @brief  Wrap subset of LLNotifications API in event API for test scripts.
- * 
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLNOTIFICATIONSLISTENER_H
-#define LL_LLNOTIFICATIONSLISTENER_H
-
-#include "lleventapi.h"
-#include "llnotificationptr.h"
-#include <boost/shared_ptr.hpp>
-#include <map>
-#include <string>
-
-class LLNotifications;
-class LLSD;
-
-class LLNotificationsListener : public LLEventAPI
-{
-public:
-    LLNotificationsListener(LLNotifications & notifications);
-    ~LLNotificationsListener();
-
-private:
-    void requestAdd(LLSD const & event_data) const;
-
-	void NotificationResponder(const std::string& replypump, 
-							   const LLSD& notification, 
-							   const LLSD& response) const;
-
-    void listChannels(const LLSD& params) const;
-    void listChannelNotifications(const LLSD& params) const;
-    void respond(const LLSD& params) const;
-    void cancel(const LLSD& params) const;
-    void ignore(const LLSD& params) const;
-    void forward(const LLSD& params);
-
-    static LLSD asLLSD(LLNotificationPtr);
-
-    class Forwarder;
-    typedef std::map<std::string, boost::shared_ptr<Forwarder> > ForwarderMap;
-    ForwarderMap mForwarders;
-	LLNotifications & mNotifications;
-};
-
-#endif // LL_LLNOTIFICATIONSLISTENER_H
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index 906b83a4005a7a76836a64cdb31f0e96ae126d2d..18a82190b53b16471e9dd32e1cbd7ab69c5b9c4c 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -49,7 +49,6 @@
 //#include "llfunctorregistry.h"
 //#include "llpointer.h"
 #include "llinitparam.h"
-//#include "llnotificationslistener.h"
 //#include "llnotificationptr.h"
 //#include "llcachename.h"
 #include "llnotifications.h"
diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp
index 87aeb4d7a74b6755b58263c84ccaff2ac92b05d7..4b9add820f7efbbddb4bb270b80ba90744de13c6 100644
--- a/indra/llui/llresizebar.cpp
+++ b/indra/llui/llresizebar.cpp
@@ -45,7 +45,8 @@ LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
 	mSide( p.side ),
 	mSnappingEnabled(p.snapping_enabled),
 	mAllowDoubleClickSnapping(p.allow_double_click_snapping),
-	mResizingView(p.resizing_view)
+	mResizingView(p.resizing_view),
+	mResizeListener(NULL)
 {
 	setFollowsNone();
 	// set up some generically good follow code.
@@ -261,6 +262,11 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
 		}
 	}
 
+	if (mResizeListener)
+	{
+		mResizeListener(NULL);
+	}
+
 	return handled;
 } // end LLResizeBar::handleHover
 
diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h
index 6daf191918558f1076a3dea4fb43ef23094db756..8190a95a71b14212fa8435554eb016c45d566f52 100644
--- a/indra/llui/llresizebar.h
+++ b/indra/llui/llresizebar.h
@@ -71,6 +71,7 @@ class LLResizeBar : public LLView
 	void			setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; }
 	void			setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; }
 	bool			canResize() { return getEnabled() && mMaxSize > mMinSize; }
+	void            setResizeListener(boost::function<void(void*)> listener) {mResizeListener = listener;}
 
 private:
 	S32				mDragLastScreenX;
@@ -84,6 +85,7 @@ class LLResizeBar : public LLView
 	BOOL			mSnappingEnabled;
 	BOOL			mAllowDoubleClickSnapping;
 	LLView*			mResizingView;
+	boost::function<void(void*)>  mResizeListener;
 };
 
 #endif  // LL_RESIZEBAR_H
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 5bcdae921d23bf641d4b7f9a7894338cf2a76356..3613a40e2c6c8021fce9c8fb8997f31eef03eaf0 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -55,6 +55,8 @@
 #include "lltexteditor.h"
 #include "lltextbox.h"
 
+static const S32 LINE_HEIGHT = 15;
+
 S32		LLView::sDepth = 0;
 bool	LLView::sDebugRects = false;
 bool	LLView::sDebugRectsShowNames = true;
@@ -1203,11 +1205,24 @@ void LLView::drawDebugRect()
 			&& preview_iter == sPreviewHighlightedElements.end()
 			&& sDebugRectsShowNames)
 		{
-			//char temp[256];
 			S32 x, y;
 			gGL.color4fv( border_color.mV );
-			x = debug_rect.getWidth()/2;
-			y = debug_rect.getHeight()/2;
+
+			x = debug_rect.getWidth() / 2;
+
+			S32 rect_height = debug_rect.getHeight();
+			S32 lines = rect_height / LINE_HEIGHT + 1;
+
+			S32 depth = 0;
+			LLView * viewp = this;
+			while (NULL != viewp)
+			{
+				viewp = viewp->getParent();
+				depth++;
+			}
+
+			y = rect_height - LINE_HEIGHT * (depth % lines + 1);
+
 			std::string debug_text = llformat("%s (%d x %d)", getName().c_str(),
 										debug_rect.getWidth(), debug_rect.getHeight());
 			LLFontGL::getFontSansSerifSmall()->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color,
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index c9176d71fbdd0287fe401e017dbdd8a80c6b8004..d43f9e9988a84cd6ce763d463bc31582ec7a9c57 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -137,6 +137,7 @@ set(viewer_SOURCE_FILES
     llcommanddispatcherlistener.cpp
     llcommandhandler.cpp
     llcommandlineparser.cpp
+    llcommunicationchannel.cpp
     llcompilequeue.cpp
     llconfirmationmanager.cpp
     llconversationlog.cpp
@@ -152,6 +153,7 @@ set(viewer_SOURCE_FILES
     lldebugview.cpp
     lldelayedgestureerror.cpp
     lldirpicker.cpp
+    lldonotdisturbnotificationstorage.cpp
     lldndbutton.cpp
     lldrawable.cpp
     lldrawpool.cpp
@@ -448,6 +450,7 @@ set(viewer_SOURCE_FILES
     llpathfindingobject.cpp
     llpathfindingobjectlist.cpp
     llpathfindingpathtool.cpp
+    llpersistentnotificationstorage.cpp
     llphysicsmotion.cpp
     llphysicsshapebuilderutil.cpp
     llplacesinventorybridge.cpp
@@ -722,6 +725,7 @@ set(viewer_HEADER_FILES
     llcommanddispatcherlistener.h
     llcommandhandler.h
     llcommandlineparser.h
+    llcommunicationchannel.h
     llcompilequeue.h
     llconfirmationmanager.h
     llconversationlog.h
@@ -737,6 +741,7 @@ set(viewer_HEADER_FILES
     lldebugview.h
     lldelayedgestureerror.h
     lldirpicker.h
+    lldonotdisturbnotificationstorage.h
     lldndbutton.h
     lldrawable.h
     lldrawpool.h
@@ -1021,6 +1026,7 @@ set(viewer_HEADER_FILES
     llpathfindingobject.h
     llpathfindingobjectlist.h
     llpathfindingpathtool.h
+    llpersistentnotificationstorage.h
     llphysicsmotion.h
     llphysicsshapebuilderutil.h
     llplacesinventorybridge.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 24fa0a0cd46d728edc48bafe716c14831547eebe..507eb33f2d3a4d87312e7846cb7178decf45cfde 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4676,7 +4676,7 @@
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>1</integer>
     </map>
     <key>LandBrushSize</key>
     <map>
@@ -13173,7 +13173,7 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <real>0.25</real>
+      <real>0.5</real>
     </map>
     <key>WindLightUseAtmosShaders</key>
     <map>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index ca22041671f9f48d57bc9842dddf60b8de437298..4ff494fbfb3aa4ed419ea719c94e8e4b813f0557 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -53,7 +53,7 @@
         <key>Type</key>
             <string>S32</string>
         <key>Value</key>
-            <integer>268</integer>
+            <integer>205</integer>
     </map>
     <key>ConversationsMessagePaneCollapsed</key>
     <map>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 22a21ffaeb3b0b8e1afc9106328268ee8a790828..fc3be9ca21c43d8bd2839a46cdb970b3fc2bf1ac 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -41,6 +41,7 @@
 #include "llchannelmanager.h"
 #include "llchicletbar.h"
 #include "llconsole.h"
+#include "lldonotdisturbnotificationstorage.h"
 #include "llenvmanager.h"
 #include "llfirstuse.h"
 #include "llfloatercamera.h"
@@ -1389,11 +1390,16 @@ BOOL LLAgent::getAFK() const
 //-----------------------------------------------------------------------------
 // setDoNotDisturb()
 //-----------------------------------------------------------------------------
-void LLAgent::setDoNotDisturb(bool pIsDotNotDisturb)
+void LLAgent::setDoNotDisturb(bool pIsDoNotDisturb)
 {
-	mIsDoNotDisturb = pIsDotNotDisturb;
-	sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, (pIsDotNotDisturb ? ANIM_REQUEST_START : ANIM_REQUEST_STOP));
-	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDotNotDisturb);
+	bool isDoNotDisturbSwitchedOff = (mIsDoNotDisturb && !pIsDoNotDisturb);
+	mIsDoNotDisturb = pIsDoNotDisturb;
+	sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, (pIsDoNotDisturb ? ANIM_REQUEST_START : ANIM_REQUEST_STOP));
+	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDoNotDisturb);
+	if (isDoNotDisturbSwitchedOff)
+	{
+		LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications();
+	}
 }
 
 //-----------------------------------------------------------------------------
@@ -2541,51 +2547,21 @@ void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReas
 
 U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent)
 {
-	// stinson 05/24/2012 Pathfinding regions have re-defined the response behavior.  In the old server code,
-	// if you attempted to change the preferred maturity to the same value, the response content would be an
-	// undefined LLSD block.  In the new server code with pathfinding, the response content should always be
-	// defined.  Thus, the check for isUndefined() can be replaced with an assert after pathfinding is merged
-	// into server trunk and fully deployed.
 	U8 maturity = SIM_ACCESS_MIN;
-	if (pContent.isUndefined())
-	{
-		maturity = mPreferredMaturity;
-	}
-	else
-	{
-		llassert(!pContent.isUndefined());
-		llassert(pContent.isMap());
-	
-		if (!pContent.isUndefined() && pContent.isMap())
-		{
-			// stinson 05/24/2012 Pathfinding regions have re-defined the response syntax.  The if statement catches
-			// the new syntax, and the else statement catches the old syntax.  After pathfinding is merged into
-			// server trunk and fully deployed, we can remove the else statement.
-			if (pContent.has("access_prefs"))
-			{
-				llassert(pContent.has("access_prefs"));
-				llassert(pContent.get("access_prefs").isMap());
-				llassert(pContent.get("access_prefs").has("max"));
-				llassert(pContent.get("access_prefs").get("max").isString());
-				if (pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max") &&
-					pContent.get("access_prefs").get("max").isString())
-				{
-					LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString();
-					LLStringUtil::trim(actualPreference);
-					maturity = LLViewerRegion::shortStringToAccess(actualPreference);
-				}
-			}
-			else if (pContent.has("max"))
-			{
-				llassert(pContent.get("max").isString());
-				if (pContent.get("max").isString())
-				{
-					LLSD::String actualPreference = pContent.get("max").asString();
-					LLStringUtil::trim(actualPreference);
-					maturity = LLViewerRegion::shortStringToAccess(actualPreference);
-				}
-			}
-		}
+
+	llassert(!pContent.isUndefined());
+	llassert(pContent.isMap());
+	llassert(pContent.has("access_prefs"));
+	llassert(pContent.get("access_prefs").isMap());
+	llassert(pContent.get("access_prefs").has("max"));
+	llassert(pContent.get("access_prefs").get("max").isString());
+	if (!pContent.isUndefined() && pContent.isMap() && pContent.has("access_prefs")
+		&& pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max")
+		&& pContent.get("access_prefs").get("max").isString())
+	{
+		LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString();
+		LLStringUtil::trim(actualPreference);
+		maturity = LLViewerRegion::shortStringToAccess(actualPreference);
 	}
 
 	return maturity;
diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp
index 9e608d2c8b5723290430c6b472180c940046ca34..19747757dbcc13b4af68d5f039a5470d61764784 100644
--- a/indra/newview/llbrowsernotification.cpp
+++ b/indra/newview/llbrowsernotification.cpp
@@ -35,6 +35,11 @@
 
 using namespace LLNotificationsUI;
 
+LLBrowserNotification::LLBrowserNotification()
+	: LLSystemNotificationHandler("Browser", "browser")
+{
+}
+
 bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification)
 {
 	LLUUID media_id = notification->getPayload()["media_id"].asUUID();
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 987651fc80435dfc493761b8ead5925b67e72b24..43757d0174f96309596896189a7ee027e00291f8 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -29,7 +29,8 @@
 #include "llchannelmanager.h"
 
 #include "llappviewer.h"
-#include "llnotificationstorage.h"
+#include "lldonotdisturbnotificationstorage.h"
+#include "llpersistentnotificationstorage.h"
 #include "llviewercontrol.h"
 #include "llviewerwindow.h"
 #include "llrootview.h"
@@ -138,6 +139,9 @@ void LLChannelManager::onLoginCompleted()
 	}
 
 	LLPersistentNotificationStorage::getInstance()->loadNotifications();
+
+	LLDoNotDisturbNotificationStorage::getInstance()->initialize();
+	LLDoNotDisturbNotificationStorage::getInstance()->loadNotifications();
 }
 
 //--------------------------------------------------------------------------
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 27138e6c066ea6e25df7cf020e77ca427f075335..7d0331757bed74a6c3887127f417d104d105d47d 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -669,47 +669,3 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl)
 		mGestureCombo->setFocus(FALSE);
 	}
 }
-
-
-/* Cruft - global gChatHandler declared below has been commented out,
-   so this class is never used.  See similar code in llfloaterimnearbychatbar.cpp
-class LLChatHandler : public LLCommandHandler
-{
-public:
-	// not allowed from outside the app
-	LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
-
-    // Your code here
-	bool handle(const LLSD& tokens, const LLSD& query_map,
-				LLMediaCtrl* web)
-	{
-		bool retval = false;
-		// Need at least 2 tokens to have a valid message.
-		if (tokens.size() < 2) 
-		{
-			retval = false;
-		}
-		else
-		{
-		S32 channel = tokens[0].asInteger();
-			// VWR-19499 Restrict function to chat channels greater than 0.
-			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
-			{
-				retval = true;
-				// Say mesg on channel
-		std::string mesg = tokens[1].asString();
-		send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
-			}
-			else
-			{
-				retval = false;
-				// Tell us this is an unsupported SLurl.
-			}
-		}
-		return retval;
-	}
-};
-
-// Creating the object registers with the dispatcher.
-//LLChatHandler gChatHandler;
-cruft */
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 1acbdd32b7b175bc07a9d34b745fb39a33a26f02..3dbb43c657407c8b559d8ae68c2dd742ee6affca 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -27,15 +27,17 @@
 #include "llviewerprecompiledheaders.h" // must be first include
 #include "llchiclet.h"
 
+#include "llchicletbar.h"
 #include "llfloaterimsession.h"
 #include "llfloaterimcontainer.h"
 #include "llfloaterreg.h"
 #include "lllocalcliprect.h"
-#include "llnotifications.h"
 #include "llscriptfloater.h"
 #include "llsingleton.h"
+#include "llsyswellwindow.h"
 
 static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
+static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
 static LLDefaultChildRegistry::Register<LLScriptChiclet> t6("chiclet_script");
 static LLDefaultChildRegistry::Register<LLInvOfferChiclet> t7("chiclet_offer");
 
@@ -46,6 +48,195 @@ boost::signals2::signal<LLChiclet* (const LLUUID&),
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
+LLSysWellChiclet::Params::Params()
+	: button("button")
+	, unread_notifications("unread_notifications")
+	, max_displayed_count("max_displayed_count", 99)
+{
+	button.name = "button";
+	button.tab_stop = FALSE;
+	button.label = LLStringUtil::null;
+}
+
+LLSysWellChiclet::LLSysWellChiclet(const Params& p)
+	: LLChiclet(p)
+	, mButton(NULL)
+	, mCounter(0)
+	, mMaxDisplayedCount(p.max_displayed_count)
+	, mIsNewMessagesState(false)
+	, mFlashToLitTimer(NULL)
+	, mContextMenu(NULL)
+{
+	LLButton::Params button_params = p.button;
+	mButton = LLUICtrlFactory::create<LLButton>(button_params);
+	addChild(mButton);
+
+	mFlashToLitTimer = new LLFlashTimer(boost::bind(&LLSysWellChiclet::changeLitState, this, _1));
+}
+
+LLSysWellChiclet::~LLSysWellChiclet()
+{
+	mFlashToLitTimer->unset();
+}
+
+void LLSysWellChiclet::setCounter(S32 counter)
+{
+	// do nothing if the same counter is coming. EXT-3678.
+	if (counter == mCounter) return;
+
+	// note same code in LLChicletNotificationCounterCtrl::setCounter(S32 counter)
+	std::string s_count;
+	if(counter != 0)
+	{
+		static std::string more_messages_exist("+");
+		std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : "");
+		s_count = llformat("%d%s"
+			, llmin(counter, mMaxDisplayedCount)
+			, more_messages.c_str()
+			);
+	}
+
+	mButton->setLabel(s_count);
+
+	mCounter = counter;
+}
+
+boost::signals2::connection LLSysWellChiclet::setClickCallback(
+	const commit_callback_t& cb)
+{
+	return mButton->setClickedCallback(cb);
+}
+
+void LLSysWellChiclet::setToggleState(BOOL toggled) {
+	mButton->setToggleState(toggled);
+}
+
+void LLSysWellChiclet::changeLitState(bool blink)
+{
+	setNewMessagesState(!mIsNewMessagesState);
+}
+
+void LLSysWellChiclet::setNewMessagesState(bool new_messages)
+{
+	/*
+	Emulate 4 states of button by background images, see detains in EXT-3147
+	xml attribute           Description
+	image_unselected        "Unlit" - there are no new messages
+	image_selected          "Unlit" + "Selected" - there are no new messages and the Well is open
+	image_pressed           "Lit" - there are new messages
+	image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well is open
+	*/
+	mButton->setForcePressedState(new_messages);
+
+	mIsNewMessagesState = new_messages;
+}
+
+void LLSysWellChiclet::updateWidget(bool is_window_empty)
+{
+	mButton->setEnabled(!is_window_empty);
+
+	if (LLChicletBar::instanceExists())
+	{
+		LLChicletBar::getInstance()->showWellButton(getName(), !is_window_empty);
+	}
+}
+// virtual
+BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	if(!mContextMenu)
+	{
+		createMenu();
+	}
+	if (mContextMenu)
+	{
+		mContextMenu->show(x, y);
+		LLMenuGL::showPopup(this, mContextMenu, x, y);
+	}
+	return TRUE;
+}
+
+/************************************************************************/
+/*               LLNotificationChiclet implementation                   */
+/************************************************************************/
+LLNotificationChiclet::LLNotificationChiclet(const Params& p)
+:	LLSysWellChiclet(p),
+	mUreadSystemNotifications(0)
+{
+	mNotificationChannel.reset(new ChicletNotificationChannel(this));
+	// ensure that notification well window exists, to synchronously
+	// handle toast add/delete events.
+	LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);
+}
+
+void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
+{
+	std::string action = user_data.asString();
+	if("close all" == action)
+	{
+		LLNotificationWellWindow::getInstance()->closeAll();
+	}
+}
+
+bool LLNotificationChiclet::enableMenuItem(const LLSD& user_data)
+{
+	std::string item = user_data.asString();
+	if (item == "can close all")
+	{
+		return mUreadSystemNotifications != 0;
+	}
+	return true;
+}
+
+void LLNotificationChiclet::createMenu()
+{
+	if(mContextMenu)
+	{
+		llwarns << "Menu already exists" << llendl;
+		return;
+	}
+
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	registrar.add("NotificationWellChicletMenu.Action",
+		boost::bind(&LLNotificationChiclet::onMenuItemClicked, this, _2));
+
+	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+	enable_registrar.add("NotificationWellChicletMenu.EnableItem",
+		boost::bind(&LLNotificationChiclet::enableMenuItem, this, _2));
+
+	mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
+		("menu_notification_well_button.xml",
+		 LLMenuGL::sMenuContainer,
+		 LLViewerMenuHolderGL::child_registry_t::instance());
+}
+
+/*virtual*/
+void LLNotificationChiclet::setCounter(S32 counter)
+{
+	LLSysWellChiclet::setCounter(counter);
+	updateWidget(getCounter() == 0);
+	
+}
+
+bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
+{
+	if (notification->getName() == "ScriptDialog")
+	{
+		return false;
+	}
+
+	if( !(notification->canLogToIM() && notification->hasFormElements())
+		&& (!notification->getPayload().has("give_inventory_notification")
+			|| notification->getPayload()["give_inventory_notification"]))
+	{
+		return true;
+	}
+	return false;
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
 LLChiclet::Params::Params()
  : show_counter("show_counter", true)
  , enable_counter("enable_counter", false)
@@ -57,12 +248,6 @@ LLChiclet::LLChiclet(const Params& p)
 , mSessionId(LLUUID::null)
 , mShowCounter(p.show_counter)
 {
-
-}
-
-LLChiclet::~LLChiclet()
-{
-
 }
 
 boost::signals2::connection LLChiclet::setLeftButtonClickCallback(
@@ -125,6 +310,15 @@ BOOL LLIMChiclet::postBuild()
 	return TRUE;
 }
 
+void LLIMChiclet::enableCounterControl(bool enable) 
+{
+	mCounterEnabled = enable;
+	if(!enable)
+	{
+		LLChiclet::setShowCounter(false);
+	}
+}
+
 void LLIMChiclet::setRequiredWidth()
 {
 	S32 required_width = mDefaultWidth;
@@ -791,13 +985,19 @@ bool LLChicletPanel::isAnyIMFloaterDoked()
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
+LLChicletNotificationCounterCtrl::Params::Params()
+	: max_displayed_count("max_displayed_count", 99)
+{
+}
 
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
 LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
  : LLAvatarIconCtrl(p)
 {
 }
 
-
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index bd6c1a3e7194b8802a181fe44dc82079fea806d3..efaf03384ae3d186887c4b1eb6f29d60c6a83b5f 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -29,10 +29,70 @@
 
 #include "llavatariconctrl.h"
 #include "llbutton.h"
+#include "llnotifications.h"
+#include "lltextbox.h"
 
 class LLMenuGL;
 class LLFloaterIMSession;
 
+/**
+ * Class for displaying amount of messages/notifications(unread).
+ */
+class LLChicletNotificationCounterCtrl : public LLTextBox
+{
+public:
+
+	struct Params :	public LLInitParam::Block<Params, LLTextBox::Params>
+	{
+		/**
+		 * Contains maximum displayed count of unread messages. Default value is 9.
+		 *
+		 * If count is less than "max_unread_count" will be displayed as is.
+		 * Otherwise 9+ will be shown (for default value).
+		 */
+		Optional<S32> max_displayed_count;
+
+		Params();
+	};
+
+	/**
+	 * Sets number of notifications
+	 */
+	virtual void setCounter(S32 counter);
+
+	/**
+	 * Returns number of notifications
+	 */
+	virtual S32 getCounter() const { return mCounter; }
+
+	/**
+	 * Returns width, required to display amount of notifications in text form.
+	 * Width is the only valid value.
+	 */
+	/*virtual*/ LLRect getRequiredRect();
+
+	/**
+	 * Sets number of notifications using LLSD
+	 */
+	/*virtual*/ void setValue(const LLSD& value);
+
+	/**
+	 * Returns number of notifications wrapped in LLSD
+	 */
+	/*virtual*/ LLSD getValue() const;
+
+protected:
+
+	LLChicletNotificationCounterCtrl(const Params& p);
+	friend class LLUICtrlFactory;
+
+private:
+
+	S32 mCounter;
+	S32 mInitialWidth;
+	S32 mMaxDisplayedCount;
+};
+
 /**
  * Class for displaying avatar's icon in P2P chiclet.
  */
@@ -104,7 +164,7 @@ class LLChiclet : public LLUICtrl
 		Params();
 	};
 
-	/*virtual*/ ~LLChiclet();
+	virtual ~LLChiclet() {}
 
 	/**
 	 * Associates chat session id with chiclet.
@@ -116,6 +176,11 @@ class LLChiclet : public LLUICtrl
 	 */
 	virtual const LLUUID& getSessionId() const { return mSessionId; }
 
+	/**
+	 * Sets show counter state.
+	 */
+	virtual void setShowCounter(bool show) { mShowCounter = show; }
+
 	/**
 	 * Connects chiclet clicked event with callback.
 	 */
@@ -194,6 +259,22 @@ class LLIMChiclet : public LLChiclet
 	 */
 	BOOL postBuild();
 
+	/**
+	 * Sets IM session name. This name will be displayed in chiclet tooltip.
+	 */
+	virtual void setIMSessionName(const std::string& name) { setToolTip(name); }
+
+	/**
+	 * Sets id of person/group user is chatting with.
+	 * Session id should be set before calling this
+	 */
+	virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }
+
+	/**
+	 * Enables/disables the counter control for a chiclet.
+	 */
+	virtual void enableCounterControl(bool enable);
+
 	/**
 	* Sets required width for a chiclet according to visible controls.
 	*/
@@ -366,6 +447,131 @@ class LLInvOfferChiclet: public LLIMChiclet
 	LLChicletInvOfferIconCtrl* mChicletIconCtrl;
 };
 
+/**
+ * Implements notification chiclet. Used to display total amount of unread messages 
+ * across all IM sessions, total amount of system notifications. See EXT-3147 for details
+ */
+class LLSysWellChiclet : public LLChiclet
+{
+public:
+		
+	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
+	{
+		Optional<LLButton::Params> button;
+
+		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
+
+		/**
+		 * Contains maximum displayed count of unread messages. Default value is 9.
+		 *
+		 * If count is less than "max_unread_count" will be displayed as is.
+		 * Otherwise 9+ will be shown (for default value).
+		 */
+		Optional<S32> max_displayed_count;
+
+		Params();
+	};
+
+	/*virtual*/ void setCounter(S32 counter);
+
+	// *TODO: mantipov: seems getCounter is not necessary for LLNotificationChiclet
+	// but inherited interface requires it to implement. 
+	// Probably it can be safe removed.
+	/*virtual*/S32 getCounter() { return mCounter; }
+
+	boost::signals2::connection setClickCallback(const commit_callback_t& cb);
+
+	/*virtual*/ ~LLSysWellChiclet();
+
+	void setToggleState(BOOL toggled);
+
+	void setNewMessagesState(bool new_messages);
+	//this method should change a widget according to state of the SysWellWindow 
+	virtual void updateWidget(bool is_window_empty);
+
+protected:
+
+	LLSysWellChiclet(const Params& p);
+	friend class LLUICtrlFactory;
+
+	/**
+	 * Change Well 'Lit' state from 'Lit' to 'Unlit' and vice-versa.
+	 *
+	 * There is an assumption that it will be called 2*N times to do not change its start state.
+	 * @see FlashToLitTimer
+	 */
+	void changeLitState(bool blink);
+
+	/**
+	 * Displays menu.
+	 */
+	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+	virtual void createMenu() = 0;
+
+protected:
+	class FlashToLitTimer;
+	LLButton* mButton;
+	S32 mCounter;
+	S32 mMaxDisplayedCount;
+	bool mIsNewMessagesState;
+
+	LLFlashTimer* mFlashToLitTimer;
+	LLContextMenu* mContextMenu;
+};
+
+class LLNotificationChiclet : public LLSysWellChiclet
+{
+	LOG_CLASS(LLNotificationChiclet);
+			
+	friend class LLUICtrlFactory;
+public:
+	struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};
+		
+protected:
+	struct ChicletNotificationChannel : public LLNotificationChannel
+	{
+		ChicletNotificationChannel(LLNotificationChiclet* chiclet) 
+			: LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString()))
+			, mChiclet(chiclet)
+		{
+			// connect counter handlers to the signals
+			connectToChannel("Group Notifications");
+			connectToChannel("Offer");
+			connectToChannel("Notifications");
+		}
+				
+		static bool filterNotification(LLNotificationPtr notify);
+		// connect counter updaters to the corresponding signals
+		/*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
+		/*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); }
+				
+		LLNotificationChiclet* const mChiclet;
+	};
+				
+	boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel;
+				
+	LLNotificationChiclet(const Params& p);
+				
+	/**
+	 * Processes clicks on chiclet menu.
+	 */
+	void onMenuItemClicked(const LLSD& user_data);
+				
+	/**
+	 * Enables chiclet menu items.
+	 */
+	bool enableMenuItem(const LLSD& user_data);
+				
+	/**
+	 * Creates menu.
+	 */
+	/*virtual*/ void createMenu();
+
+	/*virtual*/ void setCounter(S32 counter);
+	S32 mUreadSystemNotifications;
+};
+
 /**
  * Storage class for all IM chiclets. Provides mechanism to display, 
  * scroll, create, remove chiclets.
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index fde77641296093ede8b0c8f680682c1ad8708f88..a51c844775e0e8a1f51d6ffa4cd9ffda629d2e2f 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -30,6 +30,7 @@
 #include "llchiclet.h"
 #include "lllayoutstack.h"
 #include "llpaneltopinfobar.h"
+#include "llsyswellwindow.h"
 
 namespace
 {
@@ -58,6 +59,8 @@ BOOL LLChicletBar::postBuild()
 	mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
 	mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
 
+	showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty());
+
 	LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
 	LLPanelTopInfoBar::instance().setVisibleCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
 
diff --git a/indra/newview/llcommunicationchannel.cpp b/indra/newview/llcommunicationchannel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b0a70ffd862893145143b0bc145c51658c16d3a
--- /dev/null
+++ b/indra/newview/llcommunicationchannel.cpp
@@ -0,0 +1,79 @@
+/** 
+* @file llcommunicationchannel.cpp
+* @brief Implementation of llcommunicationchannel
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h" // must be first include
+
+#include "llcommunicationchannel.h"
+
+#include <string>
+#include <map>
+
+#include "llagent.h"
+#include "lldate.h"
+#include "llnotifications.h"
+
+
+LLCommunicationChannel::LLCommunicationChannel(const std::string& pName, const std::string& pParentName)
+	: LLNotificationChannel(pName, pParentName, filterByDoNotDisturbStatus)
+	, mHistory()
+{
+}
+
+LLCommunicationChannel::~LLCommunicationChannel()
+{
+}
+
+bool LLCommunicationChannel::filterByDoNotDisturbStatus(LLNotificationPtr)
+{
+	return !gAgent.isDoNotDisturb();
+}
+
+LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::beginHistory() const
+{
+	return mHistory.begin();
+}
+
+LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::endHistory() const
+{
+	return mHistory.end();
+}
+
+void LLCommunicationChannel::clearHistory()
+{
+	mHistory.clear();
+}
+
+void LLCommunicationChannel::onFilterFail(LLNotificationPtr pNotificationPtr)
+{
+	std::string notificationType = pNotificationPtr->getType();
+	if ((notificationType == "groupnotify")
+		|| (notificationType == "offer")
+		|| (notificationType == "notifytoast"))
+	{
+		mHistory.insert(std::make_pair<LLDate, LLNotificationPtr>(pNotificationPtr->getDate(), pNotificationPtr));
+	}
+}
diff --git a/indra/newview/llcommunicationchannel.h b/indra/newview/llcommunicationchannel.h
new file mode 100644
index 0000000000000000000000000000000000000000..0e15e1cd1506083a1d72254321351ac258296afb
--- /dev/null
+++ b/indra/newview/llcommunicationchannel.h
@@ -0,0 +1,61 @@
+/** 
+* @file   llcommunicationchannel.h
+* @brief  Header file for llcommunicationchannel
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLCOMMUNICATIONCHANNEL_H
+#define LL_LLCOMMUNICATIONCHANNEL_H
+
+#include <string>
+#include <map>
+
+#include "lldate.h"
+#include "llerror.h"
+#include "llnotifications.h"
+
+class LLCommunicationChannel : public LLNotificationChannel
+{
+	LOG_CLASS(LLCommunicationChannel);
+public:
+	LLCommunicationChannel(const std::string& pName, const std::string& pParentName);
+	virtual ~LLCommunicationChannel();
+
+	static bool filterByDoNotDisturbStatus(LLNotificationPtr);
+
+	typedef std::multimap<LLDate, LLNotificationPtr> history_list_t;
+	history_list_t::const_iterator beginHistory() const;
+	history_list_t::const_iterator endHistory() const;
+	
+	void clearHistory();
+
+protected:
+	virtual void onFilterFail(LLNotificationPtr pNotificationPtr);
+
+private:
+
+	history_list_t mHistory;
+};
+
+#endif // LL_LLCOMMUNICATIONCHANNEL_H
+
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 3b75cd82039cdcb610b91f52b23c0d002f149201..ff1f819d7d9804db920f09ef89feea30f0567f0a 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -188,15 +188,23 @@ void LLConversationLogFriendObserver::changed(U32 mask)
 LLConversationLog::LLConversationLog() :
 	mAvatarNameCacheConnection()
 {
-	LLControlVariable* ctrl = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
-	if (ctrl)
+	LLControlVariable* log_instant_message = gSavedPerAccountSettings.getControl("LogInstantMessages").get();
+	LLControlVariable* keep_convers_log = gSavedSettings.getControl("KeepConversationLogTranscripts").get();
+	bool is_log_message = false;
+	bool is_keep_log = false;
+
+	if (log_instant_message)
 	{
-		ctrl->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
-		if (ctrl->getValue().asBoolean())
-		{
-			enableLogging(true);
-		}
+		log_instant_message->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
+		is_log_message = log_instant_message->getValue().asBoolean();
 	}
+	if (keep_convers_log)
+	{
+		keep_convers_log->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
+		is_keep_log = keep_convers_log->getValue().asBoolean();
+	}
+
+	enableLogging(is_log_message && is_keep_log);
 }
 
 void LLConversationLog::enableLogging(bool enable)
@@ -229,17 +237,20 @@ void LLConversationLog::logConversation(const LLUUID& session_id, BOOL has_offli
 	const LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
 	LLConversation* conversation = findConversation(session);
 
-	if (session && conversation)
+    if (session)
 	{
-		if(has_offline_msg)
+    	if (conversation)
 		{
-			updateOfflineIMs(session, has_offline_msg);
+			if(has_offline_msg)
+			{
+				updateOfflineIMs(session, has_offline_msg);
+			}
+			updateConversationTimestamp(conversation);
+		}
+		else
+		{
+			createConversation(session);
 		}
-		updateConversationTimestamp(conversation);
-	}
-	else if (session && !conversation)
-	{
-		createConversation(session);
 	}
 }
 
@@ -304,19 +315,17 @@ void LLConversationLog::updateConversationTimestamp(LLConversation* conversation
 
 LLConversation* LLConversationLog::findConversation(const LLIMModel::LLIMSession* session)
 {
-	if (!session)
+	if (session)
 	{
-		return NULL;
-	}
+		const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
 
-	const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
-
-	conversations_vec_t::iterator conv_it = mConversations.begin();
-	for(; conv_it != mConversations.end(); ++conv_it)
-	{
-		if (conv_it->getSessionID() == session_id)
+		conversations_vec_t::iterator conv_it = mConversations.begin();
+		for(; conv_it != mConversations.end(); ++conv_it)
 		{
-			return &*conv_it;
+			if (conv_it->getSessionID() == session_id)
+			{
+				return &*conv_it;
+			}
 		}
 	}
 
@@ -408,8 +417,8 @@ bool LLConversationLog::saveToFile(const std::string& filename)
 		// [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe|
 		// [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a|
 
-		fprintf(fp, "[%d] %d %d %d %s| %s %s %s|\n",
-				(S32)conv_it->getTime(),
+		fprintf(fp, "[%lld] %d %d %d %s| %s %s %s|\n",
+				(S64)conv_it->getTime(),
 				(S32)conv_it->getConversationType(),
 				(S32)0,
 				(S32)conv_it->hasOfflineMessages(),
@@ -443,7 +452,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 	char history_file_name[MAX_STRING];
 	int has_offline_ims;
 	int stype;
-	S32 time;
+	time_t time;
 	// before CHUI-348 it was a flag of conversation voice state
 	int prereserved_unused;
 
@@ -453,7 +462,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 		part_id_buffer[0]	= '\0';
 		conv_id_buffer[0]	= '\0';
 
-		sscanf(buffer, "[%d] %d %d %d %[^|]| %s %s %[^|]|",
+		sscanf(buffer, "[%ld] %d %d %d %[^|]| %s %s %[^|]|",
 				&time,
 				&stype,
 				&prereserved_unused,
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index bc5b72e029d235118d1f00279bd0969cd85fbdac..0243fb1c97e6efeff5d10cf29ca9465682e25e7f 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -102,35 +102,44 @@ void LLConversationItem::showProperties(void)
 {
 }
 
-void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t&   items)
-{
-    items.push_back(std::string("view_profile"));
-    items.push_back(std::string("im"));
-    items.push_back(std::string("offer_teleport"));
-    items.push_back(std::string("voice_call"));
-    items.push_back(std::string("chat_history"));
-    items.push_back(std::string("separator_chat_history"));
-    items.push_back(std::string("add_friend"));
-    items.push_back(std::string("remove_friend"));
-    items.push_back(std::string("invite_to_group"));
-    items.push_back(std::string("separator_invite_to_group"));
-    items.push_back(std::string("map"));
-    items.push_back(std::string("share"));
-    items.push_back(std::string("pay"));
-    items.push_back(std::string("block_unblock"));
-    items.push_back(std::string("MuteText"));
-
-	if(this->getType() != CONV_SESSION_1_ON_1 && mDisplayModeratorOptions)
+void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32 flags)
+{
+	if (flags & ITEM_IN_MULTI_SELECTION)
 	{
-		items.push_back(std::string("Moderator Options Separator"));
-		items.push_back(std::string("Moderator Options"));
-		items.push_back(std::string("AllowTextChat"));
-		items.push_back(std::string("moderate_voice_separator"));
-		items.push_back(std::string("ModerateVoiceToggleMuteSelected"));
-		items.push_back(std::string("ModerateVoiceMute"));
-		items.push_back(std::string("ModerateVoiceUnmute"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("offer_teleport"));
+		items.push_back(std::string("voice_call"));
+		items.push_back(std::string("remove_friends"));
+	}
+	else 
+	{
+		items.push_back(std::string("view_profile"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("offer_teleport"));
+		items.push_back(std::string("voice_call"));
+		items.push_back(std::string("chat_history"));
+		items.push_back(std::string("separator_chat_history"));
+		items.push_back(std::string("add_friend"));
+		items.push_back(std::string("remove_friend"));
+		items.push_back(std::string("invite_to_group"));
+		items.push_back(std::string("separator_invite_to_group"));
+		items.push_back(std::string("map"));
+		items.push_back(std::string("share"));
+		items.push_back(std::string("pay"));
+		items.push_back(std::string("block_unblock"));
+		items.push_back(std::string("MuteText"));
+
+		if ((getType() != CONV_SESSION_1_ON_1) && mDisplayModeratorOptions)
+		{
+			items.push_back(std::string("Moderator Options Separator"));
+			items.push_back(std::string("Moderator Options"));
+			items.push_back(std::string("AllowTextChat"));
+			items.push_back(std::string("moderate_voice_separator"));
+			items.push_back(std::string("ModerateVoiceToggleMuteSelected"));
+			items.push_back(std::string("ModerateVoiceMute"));
+			items.push_back(std::string("ModerateVoiceUnmute"));
+		}
 	}
-
 }
 
 //
@@ -306,7 +315,7 @@ void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags)
     {
         items.push_back(std::string("close_conversation"));
         items.push_back(std::string("separator_disconnect_from_voice"));
-        buildParticipantMenuOptions(items);
+        buildParticipantMenuOptions(items, flags);
     }
     else if(this->getType() == CONV_SESSION_GROUP)
     {
@@ -475,7 +484,7 @@ void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
     menuentry_vec_t items;
     menuentry_vec_t disabled_items;
 	
-	buildParticipantMenuOptions(items);
+	buildParticipantMenuOptions(items, flags);
 	
     hide_context_entries(menu, items, disabled_items);
 }
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 6ae891203d1c4786e4ca2b26f0e33afc66650446..01b3850f5e2c7e5becd85e17ab17d7327c3b4f52 100755
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -130,7 +130,7 @@ class LLConversationItem : public LLFolderViewModelItemCommon
 	
 	void postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant);
 	
-    void buildParticipantMenuOptions(menuentry_vec_t&   items);
+    void buildParticipantMenuOptions(menuentry_vec_t& items, U32 flags);
 
 protected:
 	std::string mName;	// Name of the session or the participant
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index c0a209f22d9ae550932f8a9c359b588ac65a6317..903dd2a4073abe1df62fe7adc9208ccc69f4435d 100755
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -81,7 +81,9 @@ LLConversationViewSession::LLConversationViewSession(const LLConversationViewSes
 	mSpeakingIndicator(NULL),
 	mVoiceClientObserver(NULL),
 	mCollapsedMode(false),
-    mHasArrow(true)
+    mHasArrow(true),
+	mFlashStateOn(false),
+	mFlashStarted(false)
 {
 	mFlashTimer = new LLFlashTimer();
 }
@@ -101,7 +103,17 @@ LLConversationViewSession::~LLConversationViewSession()
 void LLConversationViewSession::setFlashState(bool flash_state)
 {
 	mFlashStateOn = flash_state;
-	(flash_state ? mFlashTimer->startFlashing() : mFlashTimer->stopFlashing());
+	mFlashStarted = false;
+	mFlashTimer->stopFlashing();
+}
+
+void LLConversationViewSession::startFlashing()
+{
+	if (mFlashStateOn && !mFlashStarted)
+	{
+		mFlashStarted = true;
+		mFlashTimer->startFlashing();
+	}
 }
 
 bool LLConversationViewSession::isHighlightAllowed()
@@ -198,8 +210,11 @@ void LLConversationViewSession::draw()
 		drawOpenFolderArrow(default_params, sFgColor);
 	}
 
+	// Indicate that flash can start (moot operation if already started, done or not flashing)
+	startFlashing();
+
 	// draw highlight for selected items
-	drawHighlight(show_context, true, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
+	drawHighlight(show_context, true, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
 
 	// Draw children if root folder, or any other folder that is open. Do not draw children when animating to closed state or you get rendering overlap.
 	bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this) || isOpen();
@@ -231,6 +246,7 @@ BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
     if(result && getRoot()->getCurSelectedItem() == this)
 	{
 		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+		im_container->clearAllFlashStates();
 		im_container->selectConversationPair(session_id, false);
 		im_container->collapseMessagesPane(false);
 	}
@@ -427,6 +443,7 @@ void LLConversationViewParticipant::draw()
 	static LLUIColor sFgDisabledColor = LLUIColorTable::instance().getColor("MenuItemDisabledColor", DEFAULT_WHITE);
     static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
     static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+    static LLUIColor sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
     static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
     static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
 
@@ -450,7 +467,7 @@ void LLConversationViewParticipant::draw()
 		color = mIsSelected ? sHighlightFgColor : sFgColor;
 	}
 
-    drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFocusOutlineColor, sMouseOverColor);
+    drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
     drawLabel(font, text_left, y, color, right_x);
 	refresh();
 
@@ -530,27 +547,6 @@ void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
     LLFolderViewItem::onMouseLeave(x, y, mask);
 }
 
-BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask )
-{
-	LLConversationItem* item = NULL;
-	LLConversationViewSession* session_widget =
-			dynamic_cast<LLConversationViewSession *>(this->getParentFolder());
-	if (session_widget)
-	{
-	    item = dynamic_cast<LLConversationItem*>(session_widget->getViewModelItem());
-	}
-    LLUUID session_id = item? item->getUUID() : LLUUID();
-    BOOL result = LLFolderViewItem::handleMouseDown(x, y, mask);
-
-    if(result)
-    {
-        (LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container"))->
-            selectConversationPair(session_id, false);
-    }
-
-	return result;
-}
-
 S32 LLConversationViewParticipant::getLabelXPos()
 {
     return getIndentation() + mAvatarIcon->getRect().getWidth() + mIconPad;
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index 1e20fb8b7e9bfa1ccd8b6aa7f702fd2b3aa8e403..5f6acfb9ab04d7f2a79d13e68150863132c14c96 100755
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -58,6 +58,7 @@ class LLConversationViewSession : public LLFolderViewFolder
 
 	/*virtual*/ bool isHighlightAllowed();
 	/*virtual*/ bool isHighlightActive();
+	/*virtual*/ bool isFlashing() { return mFlashStateOn; }
 
 	LLFloaterIMContainer* mContainer;
 	
@@ -83,11 +84,12 @@ class LLConversationViewSession : public LLFolderViewFolder
 
 	virtual void refresh();
 
-	void setFlashState(bool flash_state);
+	/*virtual*/ void setFlashState(bool flash_state);
 
 private:
 
 	void onCurrentVoiceSessionChanged(const LLUUID& session_id);
+	void startFlashing();
 
 	LLPanel*				mItemPanel;
 	LLPanel*				mCallIconLayoutPanel;
@@ -95,6 +97,7 @@ class LLConversationViewSession : public LLFolderViewFolder
 	LLOutputMonitorCtrl*	mSpeakingIndicator;
 	LLFlashTimer*			mFlashTimer;
 	bool					mFlashStateOn;
+	bool					mFlashStarted;
 
 	bool					mCollapsedMode;
     bool                    mHasArrow;
@@ -129,8 +132,6 @@ class LLConversationViewParticipant : public LLFolderViewItem
     void addToFolder(LLFolderViewFolder* folder);
 	void addToSession(const LLUUID& session_id);
 
-    /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
-
     void onMouseEnter(S32 x, S32 y, MASK mask);
     void onMouseLeave(S32 x, S32 y, MASK mask);
 
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f4560d566844b55d61b1c26ce3a7e737ae728c38
--- /dev/null
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -0,0 +1,162 @@
+/** 
+* @file lldonotdisturbnotificationstorage.cpp
+* @brief Implementation of lldonotdisturbnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lldonotdisturbnotificationstorage.h"
+
+#include "llcommunicationchannel.h"
+#include "lldir.h"
+#include "llerror.h"
+#include "llfasttimer_class.h"
+#include "llnotifications.h"
+#include "llnotificationhandler.h"
+#include "llnotificationstorage.h"
+#include "llscriptfloater.h"
+#include "llsd.h"
+#include "llsingleton.h"
+#include "lluuid.h"
+
+LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
+	: LLSingleton<LLDoNotDisturbNotificationStorage>()
+	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"))
+{
+}
+
+LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
+{
+}
+
+void LLDoNotDisturbNotificationStorage::initialize()
+{
+	getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
+}
+
+static LLFastTimer::DeclareTimer FTM_SAVE_DND_NOTIFICATIONS("Save DND Notifications");
+
+void LLDoNotDisturbNotificationStorage::saveNotifications()
+{
+	LLFastTimer _(FTM_SAVE_DND_NOTIFICATIONS);
+
+	LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+	const LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+	llassert(commChannel != NULL);
+
+	LLSD output = LLSD::emptyMap();
+	LLSD& data = output["data"];
+	data = LLSD::emptyArray();
+
+	for (LLCommunicationChannel::history_list_t::const_iterator historyIter = commChannel->beginHistory();
+		historyIter != commChannel->endHistory(); ++historyIter)
+	{
+		LLNotificationPtr notificationPtr = historyIter->second;
+
+		if (!notificationPtr->isRespondedTo() && !notificationPtr->isCancelled() && !notificationPtr->isExpired())
+		{
+			data.append(notificationPtr->asLLSD());
+		}
+	}
+
+	writeNotifications(output);
+}
+
+static LLFastTimer::DeclareTimer FTM_LOAD_DND_NOTIFICATIONS("Load DND Notifications");
+
+void LLDoNotDisturbNotificationStorage::loadNotifications()
+{
+	LLFastTimer _(FTM_LOAD_DND_NOTIFICATIONS);
+	
+	LLSD input;
+	if (!readNotifications(input) ||input.isUndefined())
+	{
+		return;
+	}
+	
+	LLSD& data = input["data"];
+	if (data.isUndefined())
+	{
+		return;
+	}
+	
+	LLNotifications& instance = LLNotifications::instance();
+	
+	for (LLSD::array_const_iterator notification_it = data.beginArray();
+		 notification_it != data.endArray();
+		 ++notification_it)
+	{
+		LLSD notification_params = *notification_it;
+		LLNotificationPtr notification(new LLNotification(notification_params));
+		
+		const LLUUID& notificationID = notification->id();
+		if (instance.find(notificationID))
+		{
+			instance.update(notification);
+		}
+		else
+		{
+			LLNotificationResponderInterface* responder = createResponder(notification_params["name"], notification_params["responder"]);
+			if (responder == NULL)
+			{
+				LL_WARNS("LLDoNotDisturbNotificationStorage") << "cannot create responder for notification of type '"
+					<< notification->getType() << "'" << LL_ENDL;
+			}
+			else
+			{
+				LLNotificationResponderPtr responderPtr(responder);
+				notification->setResponseFunctor(responderPtr);
+			}
+			
+			instance.add(notification);
+		}
+	}
+
+	// Clear the communication channel history and rewrite the save file to empty it as well
+	LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+	LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+	llassert(commChannel != NULL);
+	commChannel->clearHistory();
+	
+	saveNotifications();
+}
+
+LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChannel() const
+{
+	LLNotificationChannelPtr channelPtr = LLNotifications::getInstance()->getChannel("Communication");
+	llassert(channelPtr);
+	return channelPtr;
+}
+
+
+bool LLDoNotDisturbNotificationStorage::onChannelChanged(const LLSD& pPayload)
+{
+	if (pPayload["sigtype"].asString() != "load")
+	{
+		saveNotifications();
+	}
+
+	return false;
+}
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
new file mode 100644
index 0000000000000000000000000000000000000000..60bcd89ec3dade90e201aaa5cbc4e58e4a2a3b9d
--- /dev/null
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -0,0 +1,57 @@
+/** 
+* @file   lldonotdisturbnotificationstorage.h
+* @brief  Header file for lldonotdisturbnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+#define LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+
+#include "llerror.h"
+#include "llnotifications.h"
+#include "llnotificationstorage.h"
+#include "llsingleton.h"
+
+class LLSD;
+
+class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotificationStorage>, public LLNotificationStorage
+{
+	LOG_CLASS(LLDoNotDisturbNotificationStorage);
+public:
+	LLDoNotDisturbNotificationStorage();
+	~LLDoNotDisturbNotificationStorage();
+
+	void initialize();
+
+	void saveNotifications();
+	void loadNotifications();
+
+protected:
+
+private:
+	LLNotificationChannelPtr getCommunicationChannel() const;
+	bool                     onChannelChanged(const LLSD& pPayload);
+};
+
+#endif // LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index aae0990e4bca04d98d8dba9f72b33fbafa471396..c2b9c77307854bbf57fcfb97b66f6865d49355a7 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -444,7 +444,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
 		return ;
 	}
 
-	// stinson 11/12/2012: Need to check with davep on the following.
+	// Fix for MAINT-1894
 	// Skipping the flexible update if render res is negative.  If we were to continue with a negative value,
 	// the subsequent S32 num_render_sections = 1<<mRenderRes; code will specify a really large number of
 	// render sections which will then create a length exception in the std::vector::resize() method.
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
index 089aec19052833cedf3d8196b655458d83da5e80..a40a000babfd396316ad9840e1f9ec8050413639 100644
--- a/indra/newview/llfloaterconversationlog.cpp
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -67,7 +67,8 @@ BOOL LLFloaterConversationLog::postBuild()
 	if (ctrl)
 	{
 		ctrl->getSignal()->connect(boost::bind(&LLFloaterConversationLog::onCallLoggingEnabledDisabled, this, _2));
-		onCallLoggingEnabledDisabled(ctrl->getValue().asBoolean());
+		onCallLoggingEnabledDisabled(ctrl->getValue().asBoolean()
+				&& gSavedSettings.getBOOL("KeepConversationLogTranscripts"));
 	}
 
 	return LLFloater::postBuild();
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index e1288a763cf1743b9d04f49d38ea02a5acdb79f1..ae243d64954e5ccd9a69cef2804bda977e9a5ac7 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -51,8 +51,8 @@
 #include "llconversationview.h"
 #include "llcallbacklist.h"
 #include "llworld.h"
-
 #include "llsdserialize.h"
+
 //
 // LLFloaterIMContainer
 //
@@ -171,6 +171,9 @@ BOOL LLFloaterIMContainer::postBuild()
 	// Open IM session with selected participant on double click event
 	mConversationsListPanel->setDoubleClickCallback(boost::bind(&LLFloaterIMContainer::doToSelected, this, LLSD("im")));
 
+	// The resize limits for LLFloaterIMContainer should be updated, based on current values of width of conversation and message panels
+	mConversationsPane->getResizeBar()->setResizeListener(boost::bind(&LLFloaterIMContainer::assignResizeLimits, this));
+
 	// Create the root model and view for all conversation sessions
 	LLConversationItem* base_item = new LLConversationItem(getRootViewModel());
 
@@ -247,6 +250,7 @@ void LLFloaterIMContainer::onOpen(const LLSD& key)
 {
 	LLMultiFloater::onOpen(key);
 	openNearbyChat();
+	assignResizeLimits();
 }
 
 // virtual
@@ -308,26 +312,6 @@ void LLFloaterIMContainer::onCloseFloater(LLUUID& id)
 	setFocus(TRUE);
 }
 
-// virtual
-void LLFloaterIMContainer::computeResizeLimits(S32& new_min_width, S32& new_min_height)
-{
-	// possibly increase floater's minimum height according to children's minimums
-	for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
-	{
-		LLFloater* floaterp = dynamic_cast<LLFloater*>(mTabContainer->getPanelByIndex(tab_idx));
-		if (floaterp)
-		{
-			new_min_height = llmax(new_min_height, floaterp->getMinHeight());
-		}
-	}
-
-	S32 conversations_pane_min_dim = mConversationsPane->getRelevantMinDim();
-	S32 messages_pane_min_dim = mMessagesPane->getRelevantMinDim();
-
-	// set floater's minimum width according to relevant minimal children's dimensionals
-	new_min_width = conversations_pane_min_dim + messages_pane_min_dim + LLPANEL_BORDER_WIDTH*2;
-}
-
 void LLFloaterIMContainer::onNewMessageReceived(const LLSD& data)
 {
 	LLUUID session_id = data["session_id"].asUUID();
@@ -621,6 +605,12 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
 	LLMultiFloater::setVisible(visible);
 }
 
+void LLFloaterIMContainer::updateResizeLimits()
+{
+	LLMultiFloater::updateResizeLimits();
+	assignResizeLimits();
+}
+
 void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
 {
 	if (mMessagesPane->isCollapsed() == collapse)
@@ -694,6 +684,7 @@ void LLFloaterIMContainer::collapseConversationsPane(bool collapse)
 		    {
 		    	widget->setOpen(false);
 		    }
+		    widget->requestArrange();
 }
 	}
 }
@@ -728,6 +719,15 @@ void LLFloaterIMContainer::updateState(bool collapse, S32 delta_width)
         setResizeLimits(expanded_min_size, expanded_min_size);
 	}
 
+    assignResizeLimits();
+}
+
+void LLFloaterIMContainer::assignResizeLimits()
+{
+	const LLRect& conv_rect = mConversationsPane->isCollapsed() ? LLRect() : mConversationsPane->getRect();
+	S32 msg_limits  = mMessagesPane->isCollapsed() ? 0 : mMessagesPane->getExpandedMinDim();
+	S32 x_limits = conv_rect.getWidth() + msg_limits;
+	setResizeLimits(x_limits + LLPANEL_BORDER_WIDTH * 3, getMinHeight());
 }
 
 void LLFloaterIMContainer::onAddButtonClicked()
@@ -1108,7 +1108,27 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 	uuid_vec_t uuids;
 	getParticipantUUIDs(uuids);
 
-    if("can_activate_group" == item)
+	if ("conversation_log" == item)
+	{
+		return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
+	}
+
+	//Enable Chat history item for ad-hoc and group conversations
+	if ("can_chat_history" == item)
+	{
+		if (getCurSelectedViewModelItem()->getType() != LLConversationItem::CONV_PARTICIPANT)
+		{
+			return isConversationLoggingAllowed();
+		}
+	}
+
+	// If nothing is selected(and selected item is not group chat), everything needs to be disabled
+	if (uuids.size() <= 0)
+	{
+		return getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP;
+	}
+
+	if("can_activate_group" == item)
     {
     	LLUUID selected_group_id = getCurSelectedViewModelItem()->getUUID();
     	return gAgent.getGroupID() != selected_group_id;
@@ -1119,17 +1139,6 @@ bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
 
 bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_vec_t& uuids)
 {
-	if ("conversation_log" == item)
-	{
-		return gSavedSettings.getBOOL("KeepConversationLogTranscripts");
-	}
-
-	// If nothing is selected, everything needs to be disabled
-	if (uuids.size() <= 0)
-    {
-        return false;
-    }
-	
 	// Extract the single select info
 	bool is_single_select = (uuids.size() == 1);
 	const LLUUID& single_id = uuids.front();
@@ -1236,6 +1245,19 @@ void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
     selectConversationPair(session_id, true);
 }
 
+void LLFloaterIMContainer::clearAllFlashStates()
+{
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
+	{
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+		if (widget)
+		{
+			widget->setFlashState(false);
+		}
+	}
+}
+
 void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
 {
     selectConversationPair(session_id, true);
@@ -1247,17 +1269,6 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
     BOOL handled = TRUE;
     LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
 
-	// On selection, stop the flash state on all conversation widgets
-	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
-	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
-	{
-		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
-		if (widget)
-		{
-			widget->setFlashState(false);
-		}
-	}
-	
     /* widget processing */
     if (select_widget)
     {
@@ -1419,14 +1430,14 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	// Delete the widget and the associated conversation item
 	// Note : since the mConversationsItems is also the listener to the widget, deleting 
 	// the widget will also delete its listener
-	bool isWidgetSelected = false;
+	bool is_widget_selected = false;
 	LLFolderViewItem* new_selection = NULL;
 	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
 	if (widget)
 	{
-		isWidgetSelected = widget->isSelected();
+		is_widget_selected = widget->isSelected();
 		new_selection = mConversationsRoot->getNextFromChild(widget);
-		if(new_selection == NULL)
+		if (!new_selection)
 		{
 			new_selection = mConversationsRoot->getPreviousFromChild(widget);
 		}
@@ -1441,18 +1452,24 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
 	if (change_focus)
 	{
 		setFocus(TRUE);
-		if(new_selection != NULL)
+		if (new_selection)
 		{
 			if (mConversationsWidgets.size() == 1)
-				new_selection = new_selection->getParentFolder();
-			LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
-			if(vmi != NULL)
 			{
-				selectConversationPair(vmi->getUUID(), true);
+				// If only one widget is left, it has to be the Nearby Chat. Select it directly.
+				selectConversationPair(LLUUID(NULL), true);
+			}
+			else
+			{
+				LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
+				if (vmi)
+				{
+					selectConversationPair(vmi->getUUID(), true);
+				}
 			}
 		}
 	}
-	return isWidgetSelected;
+	return is_widget_selected;
 }
 
 LLConversationViewSession* LLFloaterIMContainer::createConversationItemWidget(LLConversationItem* item)
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 1a3e64f759ac54a5c3861ea3018ddf13d08a3142..0cd1b6759b7d1c20c0b989fe7cf481559415fbd4 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -60,6 +60,7 @@ class LLFloaterIMContainer
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void draw();
 	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ void updateResizeLimits();
 	void onCloseFloater(LLUUID& id);
 
 	/*virtual*/ void addFloater(LLFloater* floaterp, 
@@ -69,6 +70,7 @@ class LLFloaterIMContainer
     void showConversation(const LLUUID& session_id);
     void selectConversation(const LLUUID& session_id);
     BOOL selectConversationPair(const LLUUID& session_id, bool select_widget);
+    void clearAllFlashStates();
 
 	/*virtual*/ void tabClose();
 	void showStub(bool visible);
@@ -105,12 +107,14 @@ class LLFloaterIMContainer
     bool enableContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS);
     void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
 
+	void assignResizeLimits();
+
 private:
 	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
 	avatarID_panel_map_t mSessions;
 	boost::signals2::connection mNewMessageConnection;
 
-	/*virtual*/ void computeResizeLimits(S32& new_min_width, S32& new_min_height);
+	/*virtual*/ void computeResizeLimits(S32& new_min_width, S32& new_min_height) {}
 
 	void onNewMessageReceived(const LLSD& data);
 
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index a9a3611970fc43a1078a0ccdd83acdd3d2d7c8a8..797d590e1f7840df0ce1d5e13e99247587f63a0b 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -113,8 +113,8 @@ BOOL LLFloaterIMNearbyChat::postBuild()
     BOOL result = LLFloaterIMSessionTab::postBuild();
 	
 	mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this));
-	mInputEditor->setKeystrokeCallback(boost::bind(&onChatBoxKeystroke, _1, this));
-	mInputEditor->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
+	mInputEditor->setKeystrokeCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxKeystroke, this));
+	mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusLost, this));
 	mInputEditor->setFocusReceivedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusReceived, this));
 	mInputEditor->setLabel(LLTrans::getString("NearbyChatTitle"));
 
@@ -354,13 +354,11 @@ BOOL LLFloaterIMNearbyChat::matchChatTypeTrigger(const std::string& in_str, std:
 	return string_was_found;
 }
 
-void LLFloaterIMNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userdata)
+void LLFloaterIMNearbyChat::onChatBoxKeystroke()
 {
 	LLFirstUse::otherAvatarChatFirst(false);
 
-	LLFloaterIMNearbyChat* self = (LLFloaterIMNearbyChat *)userdata;
-
-	LLWString raw_text = self->mInputEditor->getWText();
+	LLWString raw_text = mInputEditor->getWText();
 
 	// Can't trim the end, because that will cause autocompletion
 	// to eat trailing spaces that might be part of a gesture.
@@ -386,8 +384,8 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userd
 		// the selection will already be deleted, but we need to trim
 		// off the character before
 		std::string new_text = raw_text.substr(0, length-1);
-		self->mInputEditor->setText( new_text );
-		self->mInputEditor->setCursorToEnd();
+		mInputEditor->setText( new_text );
+		mInputEditor->setCursorToEnd();
 		length = length - 1;
 	}
 	*/
@@ -407,17 +405,17 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userd
 		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
 		{
 			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
+			mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
 
 			// Select to end of line, starting from the character
 			// after the last one the user typed.
-			self->mInputEditor->selectNext(rest_of_match, false);
+			mInputEditor->selectNext(rest_of_match, false);
 		}
 		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
 		{
 			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
-			self->mInputEditor->endOfDoc();
+			mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
+			mInputEditor->endOfDoc();
 		}
 
 		//llinfos << "GESTUREDEBUG " << trigger 
@@ -428,7 +426,7 @@ void LLFloaterIMNearbyChat::onChatBoxKeystroke(LLTextEditor* caller, void* userd
 }
 
 // static
-void LLFloaterIMNearbyChat::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata)
+void LLFloaterIMNearbyChat::onChatBoxFocusLost()
 {
 	// stop typing animation
 	gAgent.stopTyping();
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index a38824dc78758e675111bb1b2222aa8fdc3777a2..f4213eda5a8cd7120ba78825405776aca090c1c1 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -83,8 +83,8 @@ class LLFloaterIMNearbyChat
 
 protected:
 	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
-	static void onChatBoxKeystroke(LLTextEditor* caller, void* userdata);
-	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
+	void onChatBoxKeystroke();
+	void onChatBoxFocusLost();
 	void onChatBoxFocusReceived();
 
 	void sendChat( EChatType type );
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index a0ca7286f19e7209f573ca42ad0cc8c1d06d8f3e..d36b138c21de693f8de5ecb6dacd5af445725428 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -73,8 +73,7 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
 	mTypingTimer(),
 	mTypingTimeoutTimer(),
 	mPositioned(false),
-	mSessionInitialized(false),
-	mStartConferenceInSameFloater(false)
+	mSessionInitialized(false)
 {
 	mIsNearbyChat = false;
 
@@ -83,8 +82,11 @@ LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
 	setOverlapsScreenChannel(true);
 
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
+    mEnableCallbackRegistrar.add("Avatar.EnableGearItem", boost::bind(&LLFloaterIMSession::enableGearMenuItem, this, _2));
+    mCommitCallbackRegistrar.add("Avatar.GearDoToSelected", boost::bind(&LLFloaterIMSession::GearDoToSelected, this, _2));
+    mEnableCallbackRegistrar.add("Avatar.CheckGearItem", boost::bind(&LLFloaterIMSession::checkGearMenuItem, this, _2));
 
-	setDocked(true);
+    setDocked(true);
 }
 
 
@@ -190,6 +192,36 @@ void LLFloaterIMSession::onSendMsg( LLUICtrl* ctrl, void* userdata )
 	self->setTyping(false);
 }
 
+bool LLFloaterIMSession::enableGearMenuItem(const LLSD& userdata)
+{
+    std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+    selected_uuids.push_back(mOtherParticipantUUID);
+
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	return floater_container->enableContextMenuItem(command, selected_uuids);
+}
+
+void LLFloaterIMSession::GearDoToSelected(const LLSD& userdata)
+{
+	std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+    selected_uuids.push_back(mOtherParticipantUUID);
+
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	floater_container->doToParticipants(command, selected_uuids);
+}
+
+bool LLFloaterIMSession::checkGearMenuItem(const LLSD& userdata)
+{
+	std::string command = userdata.asString();
+	uuid_vec_t selected_uuids;
+	selected_uuids.push_back(mOtherParticipantUUID);
+
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	return floater_container->checkContextMenuItem(command, selected_uuids);
+}
+
 void LLFloaterIMSession::sendMsgFromInputEditor()
 {
 	if (gAgent.isGodlike()
@@ -429,8 +461,6 @@ void LLFloaterIMSession::addP2PSessionParticipants(const LLSD& notification, con
 		return;
 	}
 
-	mStartConferenceInSameFloater = true;
-
 	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
 
 	// first check whether this is a voice session
@@ -724,7 +754,7 @@ void LLFloaterIMSession::sessionInitReplyReceived(const LLUUID& im_session_id)
 	}
 
 	initIMFloater();
-	
+	LLFloaterIMSessionTab::updateGearBtn();
 	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
 
 	//need to send delayed messages collected while waiting for session initialization
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index 1d8957b1d95772a93b4bea65216bf8b191c0418b..6a2f4b29eb78a3aaf14ea363e169b1c3685e4dd0 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -99,6 +99,9 @@ class LLFloaterIMSession
 	void setPositioned(bool b) { mPositioned = b; };
 
 	void onVisibilityChange(const LLSD& new_visibility);
+	bool enableGearMenuItem(const LLSD& userdata);
+	void GearDoToSelected(const LLSD& userdata);
+	bool checkGearMenuItem(const LLSD& userdata);
 
 	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
 	// button when voice is available
@@ -124,8 +127,6 @@ class LLFloaterIMSession
 	//used as a callback on receiving new IM message
 	static void sRemoveTypingIndicator(const LLSD& data);
 	static void onIMChicletCreated(const LLUUID& session_id);
-
-	bool getStartConferenceInSameFloater() const { return mStartConferenceInSameFloater; }
     const LLUUID& getOtherParticipantUUID() {return mOtherParticipantUUID;}
 
 	static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
@@ -185,8 +186,6 @@ class LLFloaterIMSession
 	bool mSessionInitialized;
 	LLSD mQueuedMsgsForInit;
 
-	bool mStartConferenceInSameFloater;
-
 	uuid_vec_t mInvitedParticipants;
 
 	// connection to voice channel state change signal
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index ea99a1c5bfbfe9ec418bde0bb5dcb735f90e89c6..d4eb03f95d113d5c87213d1ff432e0f68c8d00b5 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -82,6 +82,13 @@ LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
 LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
 {
 	delete mRefreshTimer;
+
+	// Select Nearby Chat session
+	LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
+	if (container)
+	{
+		container->selectConversationPair(LLUUID(NULL), true);
+	}
 }
 
 //static
@@ -177,6 +184,7 @@ void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
 				// LLFloater::mLastHostHandle = floater_container (a "future" host)
 				conversp->setHost(floater_container);
 				conversp->setHost(NULL);
+				conversp->forceReshape();
 			}
 			// Added floaters share some state (like sort order) with their host
 			conversp->setSortOrder(floater_container->getSortOrder());
@@ -197,6 +205,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
 	mTearOffBtn = getChild<LLButton>("tear_off_btn");
 	mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
 
+	mGearBtn = getChild<LLButton>("gear_btn");
+
 	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
 	
 	// Add a scroller for the folder (participant) view
@@ -224,7 +234,8 @@ BOOL LLFloaterIMSessionTab::postBuild()
 
 	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
 
-	mSaveRect = isTornOff();
+	mSaveRect = isNearbyChat()
+					&&  !gSavedSettings.getBOOL("NearbyChatIsNotTornOff");
 	initRectControl();
 
 	if (isChatMultiTab())
@@ -236,14 +247,31 @@ BOOL LLFloaterIMSessionTab::postBuild()
 		result = LLDockableFloater::postBuild();
 	}
 
-	// Now ready to build the conversation and participants list
+	// Create the root using an ad-hoc base item
+	LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
+    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = mParticipantListPanel;
+    p.listener = base_item;
+    p.view_model = &mConversationViewModel;
+    p.root = NULL;
+    p.use_ellipses = true;
+    p.options_menu = "menu_conversation.xml";
+	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+	// Attach that root to the scroller
+	mScroller->addChild(mConversationsRoot);
+	mConversationsRoot->setScrollContainer(mScroller);
+	mConversationsRoot->setFollowsAll();
+	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+
 	buildConversationViewParticipant();
 	refreshConversation();
-		
+
 	// Zero expiry time is set only once to allow initial update.
 	mRefreshTimer->setTimerExpirySec(0);
 	mRefreshTimer->start();
-
+	initBtns();
 	return result;
 }
 
@@ -301,10 +329,10 @@ void LLFloaterIMSessionTab::onFocusReceived()
 
 	LLTransientDockableFloater::onFocusReceived();
 
-	LLFloaterIMContainer* container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+	LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
 	if (container)
 	{
-		container->selectConversationPair(mSessionID, ! getHost());
+		container->selectConversationPair(mSessionID, true);
 		container->showStub(! getHost());
 	}
 }
@@ -384,31 +412,6 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
 		return;
 	}
 	
-	// Create or recreate the root folder: this is a dummy folder (not shown) but required by the LLFolderView architecture 
-	// We need to redo this when rebuilding as the session id (mSessionID) *may* have changed
-	if (mConversationsRoot)
-	{
-		// Remove the old root if any
-		mScroller->removeChild(mConversationsRoot);
-	}
-	// Create the root using an ad-hoc base item
-	LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
-    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
-    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
-    p.parent_panel = mParticipantListPanel;
-    p.listener = base_item;
-    p.view_model = &mConversationViewModel;
-    p.root = NULL;
-    p.use_ellipses = true;
-    p.options_menu = "menu_conversation.xml";
-	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
-    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
-	// Attach that root to the scroller
-	mScroller->addChild(mConversationsRoot);
-	mConversationsRoot->setScrollContainer(mScroller);
-	mConversationsRoot->setFollowsAll();
-	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
-	
 	// Create the participants widgets now
 	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
 	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
@@ -610,8 +613,8 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 	// prevent start conversation before its container
     LLFloaterIMContainer::getInstance();
 
-	bool is_torn_off = checkIfTornOff();
-	if (!is_torn_off)
+	bool is_not_torn_off = !checkIfTornOff();
+	if (is_not_torn_off)
 	{
 		hideAllStandardButtons();
 	}
@@ -620,7 +623,7 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 
 	// Participant list should be visible only in torn off floaters.
 	bool is_participant_list_visible =
-			is_torn_off
+			!is_not_torn_off
 			&& gSavedSettings.getBOOL("IMShowControlPanel")
 			&& !mIsP2PChat;
 
@@ -628,27 +631,42 @@ void LLFloaterIMSessionTab::updateHeaderAndToolbar()
 
 	// Display collapse image (<<) if the floater is hosted
 	// or if it is torn off but has an open control panel.
-	bool is_expanded = !is_torn_off || is_participant_list_visible;
+	bool is_expanded = is_not_torn_off || is_participant_list_visible;
 	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
+	mExpandCollapseBtn->setToolTip(
+			is_not_torn_off?
+				getString("expcol_button_not_tearoff_tooltip") :
+				(is_expanded?
+					getString("expcol_button_tearoff_and_expanded_tooltip") :
+					getString("expcol_button_tearoff_and_collapsed_tooltip")));
 
 	// toggle floater's drag handle and title visibility
 	if (mDragHandle)
 	{
-		mDragHandle->setTitleVisible(is_torn_off);
+		mDragHandle->setTitleVisible(!is_not_torn_off);
 	}
 
 	// The button (>>) should be disabled for torn off P2P conversations.
-	mExpandCollapseBtn->setEnabled(!is_torn_off || !mIsP2PChat);
+	mExpandCollapseBtn->setEnabled(is_not_torn_off || !mIsP2PChat);
 
-	mTearOffBtn->setImageOverlay(getString(is_torn_off? "return_icon" : "tear_off_icon"));
-	mTearOffBtn->setToolTip(getString(!is_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window"));
+	mTearOffBtn->setImageOverlay(getString(is_not_torn_off? "tear_off_icon" : "return_icon"));
+	mTearOffBtn->setToolTip(getString(is_not_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window"));
 
-	mCloseBtn->setVisible(!is_torn_off && !mIsNearbyChat);
+	mCloseBtn->setVisible(is_not_torn_off && !mIsNearbyChat);
 
 	enableDisableCallBtn();
 
 	showTranslationCheckbox();
 }
+ 
+void LLFloaterIMSessionTab::forceReshape()
+{
+    LLRect floater_rect = getRect();
+    reshape(llmax(floater_rect.getWidth(), this->getMinWidth()),
+    		llmax(floater_rect.getHeight(), this->getMinHeight()),
+    		true);
+}
+
 
 void LLFloaterIMSessionTab::reshapeChatHistory()
 {
@@ -735,19 +753,6 @@ void LLFloaterIMSessionTab::onOpen(const LLSD& key)
 	}
 }
 
-// virtual
-void LLFloaterIMSessionTab::onClose(bool app_quitting)
-{
-	// Always suppress the IM from the conversations list on close if present for any reason
-	if (LLFloaterIMSessionTab::isChatMultiTab())
-	{
-		LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
-		if (im_box)
-		{
-            im_box->removeConversationListItem(mKey);
-        }
-    }
-}
 
 void LLFloaterIMSessionTab::onTearOffClicked()
 {
@@ -755,7 +760,58 @@ void LLFloaterIMSessionTab::onTearOffClicked()
     mSaveRect = isTornOff();
     initRectControl();
 	LLFloater::onClickTearOff(this);
+	if (isTornOff())
+	{
+		forceReshape();
+	}
 	refreshConversation();
+	updateGearBtn();
+}
+
+void LLFloaterIMSessionTab::updateGearBtn()
+{
+
+	BOOL prevVisibility = mGearBtn->getVisible();
+	mGearBtn->setVisible(checkIfTornOff() && mIsP2PChat);
+
+
+	// Move buttons if Gear button changed visibility
+	if(prevVisibility != mGearBtn->getVisible())
+	{
+		LLRect gear_btn_rect =  mGearBtn->getRect();
+		LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect();
+		LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect();
+		S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight;
+		S32 right_shift = gear_btn_rect.getWidth() + gap_width;
+		if(mGearBtn->getVisible())
+		{
+			// Move buttons to the right to give space for Gear button
+			add_btn_rect.translate(right_shift,0);
+			call_btn_rect.translate(right_shift,0);
+		}
+		else
+		{
+			add_btn_rect.translate(-right_shift,0);
+			call_btn_rect.translate(-right_shift,0);
+		}
+		getChild<LLButton>("add_btn")->setRect(add_btn_rect);
+		getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect);
+	}
+}
+
+void LLFloaterIMSessionTab::initBtns()
+{
+	LLRect gear_btn_rect =  mGearBtn->getRect();
+	LLRect add_btn_rect = getChild<LLButton>("add_btn")->getRect();
+	LLRect call_btn_rect = getChild<LLButton>("voice_call_btn")->getRect();
+	S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight;
+	S32 right_shift = gear_btn_rect.getWidth() + gap_width;
+
+	add_btn_rect.translate(-right_shift,0);
+	call_btn_rect.translate(-right_shift,0);
+
+	getChild<LLButton>("add_btn")->setRect(add_btn_rect);
+	getChild<LLButton>("voice_call_btn")->setRect(call_btn_rect);
 }
 
 // static
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index cd0bcd481c89c58294eb43e02fdb38443db2ba73..0fa99a46bea6d02f5a57f4b74e5e1b7e8361ed72 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -77,7 +77,6 @@ class LLFloaterIMSessionTab
 
 	// LLFloater overrides
 	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
 	/*virtual*/ void setVisible(BOOL visible);
@@ -92,10 +91,13 @@ class LLFloaterIMSessionTab
 
 	void setSortOrder(const LLConversationSort& order);
 	virtual void onTearOffClicked();
-	
+	void updateGearBtn();
+	void initBtns();
 	virtual void updateMessages() {}
 	LLConversationItem* getCurSelectedViewModelItem();
 
+	void forceReshape();
+
 protected:
 
 	// callback for click on any items of the visual states menu
@@ -157,6 +159,8 @@ class LLFloaterIMSessionTab
 	LLButton* mExpandCollapseBtn;
 	LLButton* mTearOffBtn;
 	LLButton* mCloseBtn;
+	LLButton* mGearBtn;
+
 
 private:
 	// Handling selection and contextual menu
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 18ed36d0f368945583324bdf6079ce76c35ebc1c..29a3e6ac3a020bfa16283167ecd85eeef5ba897c 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -49,6 +49,11 @@
 /// LLOutboxNotification class
 ///----------------------------------------------------------------------------
 
+LLNotificationsUI::LLOutboxNotification::LLOutboxNotification()
+	: LLSystemNotificationHandler("Outbox", "outbox")
+{
+}
+
 bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotificationPtr& notify)
 {
 	LLFloaterOutbox* outbox_floater = LLFloaterReg::getTypedInstance<LLFloaterOutbox>("outbox");
@@ -60,10 +65,10 @@ bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotifi
 
 void LLNotificationsUI::LLOutboxNotification::onDelete(LLNotificationPtr p)
 {
-	LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
-	if (sys_handler)
+	LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+	if (notification_handler)
 	{
-		sys_handler->onDelete(p);
+		notification_handler->onDelete(p);
 	}
 }
 
@@ -524,9 +529,9 @@ void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)
 
 void LLFloaterOutbox::showNotification(const LLNotificationPtr& notification)
 {
-	LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
-	llassert(sys_handler);
+	LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+	llassert(notification_handler);
 	
-	sys_handler->processNotification(notification);
+	notification_handler->processNotification(notification);
 }
 
diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp
index 0960846510416ab79448a36a4a148db234ecec43..95d57d08d853c1d2c79f39c00c858b1065d83b0c 100644
--- a/indra/newview/llhudobject.cpp
+++ b/indra/newview/llhudobject.cpp
@@ -232,11 +232,9 @@ LLHUDEffect *LLHUDObject::addHUDEffect(const U8 type)
 	case LL_HUD_EFFECT_LOOKAT:
 		hud_objectp = new LLHUDEffectLookAt(type);
 		break;
-#ifdef XXX_STINSON_CHUI_REWORK
 	case LL_HUD_EFFECT_VOICE_VISUALIZER:
 		hud_objectp = new LLVoiceVisualizer(type);
 		break;
-#endif // XXX_STINSON_CHUI_REWORK
 	case LL_HUD_EFFECT_POINTAT:
 		hud_objectp = new LLHUDEffectPointAt(type);
 		break;
diff --git a/indra/newview/llhudobject.h b/indra/newview/llhudobject.h
index 32cffe68391855aff548c164d228a3daa7dd0011..2f7a98c86cf9de08a916fd41d2316871aa5bd2a2 100644
--- a/indra/newview/llhudobject.h
+++ b/indra/newview/llhudobject.h
@@ -39,8 +39,6 @@
 #include "lldrawpool.h"		// TODO: eliminate, unused below
 #include <list>
 
-#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot
-
 class LLViewerCamera;
 class LLFontGL;
 class LLFace;
@@ -96,9 +94,7 @@ class LLHUDObject : public LLRefCount
 		LL_HUD_EFFECT_EDIT,
 		LL_HUD_EFFECT_LOOKAT,
 		LL_HUD_EFFECT_POINTAT,
-#ifdef XXX_STINSON_CHUI_REWORK
 		LL_HUD_EFFECT_VOICE_VISUALIZER,	// Ventrella
-#endif // XXX_STINSON_CHUI_REWORK
 		LL_HUD_NAME_TAG,
 		LL_HUD_EFFECT_BLOB
 	};
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 047472a282abdbb2fc8e274f973475d59d4155a7..72967eb6c7db90710d3a36291ae854bf3a4c59a2 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -38,7 +38,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLIMHandler::LLIMHandler()
-:	LLSysHandler("IM Notifications", "notifytoast")
+:	LLCommunicationNotificationHandler("IM Notifications", "notifytoast")
 {
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->createNotificationChannel()->getHandle();
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 9195ea23446730e56440345a108d4f405d2ae9ba..2bb79a39e8b4cd26c7aafaa38303dad9943b25e6 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -122,7 +122,7 @@ void on_new_message(const LLSD& msg)
     LLUUID session_id = msg["session_id"].asUUID();
     LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
 
-    // determine action for this session
+    //  determine action for this session
 
     if (session_id.isNull())
     {
@@ -148,8 +148,8 @@ void on_new_message(const LLSD& msg)
         action = gSavedSettings.getString("NotificationGroupChatOptions");
     }
 
-    // do not show notification in "do not disturb" mode or it goes from agent
-    if (gAgent.isDoNotDisturb() || gAgent.getID() == participant_id)
+    // do not show notification which goes from agent
+    if (gAgent.getID() == participant_id)
     {
         return;
     }
@@ -160,67 +160,69 @@ void on_new_message(const LLSD& msg)
     LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
 
     //session floater not focused (visible or not)
-    bool sessionFloaterNotFocused = session_floater && !session_floater->hasFocus(); 
+    bool session_floater_not_focused = session_floater && !session_floater->hasFocus();
+
+    //conv. floater is closed
+    bool conversation_floater_is_closed =
+    		!(  im_box
+    		    && im_box->isInVisibleChain()
+                && !im_box->isMinimized());
 
     //conversation floater not focused (visible or not)
-    bool conversationFloaterNotFocused = im_box && !im_box->hasFocus();
+    bool conversation_floater_not_focused =
+    		conversation_floater_is_closed || !im_box->hasFocus();
 
     if ("toast" == action)
     {
-        // Skip toasting if we have open window of IM with this session id
-        if (
-            session_floater
+        // Skip toasting and flashing if we have open window of IM with this session id
+        if (session_floater
             && session_floater->isInVisibleChain()
             && session_floater->hasFocus()
             && !session_floater->isMinimized()
-            && !(session_floater->getHost()
-            && session_floater->getHost()->isMinimized())
+            && !(session_floater->getHost() && session_floater->getHost()->isMinimized())
             )
         {
             return;
         }
 
-	    // Skip toasting for system messages and for nearby chat
-	    if (participant_id.isNull())
-        {
-            return;
-        }
-
         //User is not focused on conversation containing the message
-        if(sessionFloaterNotFocused)
+        if(session_floater_not_focused)
         {
             im_box->flashConversationItemWidget(session_id, true);
 
             //The conversation floater isn't focused/open
-            if(conversationFloaterNotFocused)
+            if(conversation_floater_not_focused)
             {
                 gToolBarView->flashCommand(LLCommandId("chat"), true);
 
                 //Show IM toasts (upper right toasts)
-                if(session_id.notNull())
+                // Skip toasting for system messages and for nearby chat
+                if(session_id.notNull() && participant_id.notNull())
                 {
                     LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
                 }
             }
         }
     }
+
     else if ("flash" == action)
     {
-        //User is not focused on conversation containing the message
-        if(sessionFloaterNotFocused && conversationFloaterNotFocused)
-        {
-            gToolBarView->flashCommand(LLCommandId("chat"), true); 
-        }
-        //conversation floater is open but a different conversation is focused
-        else if(sessionFloaterNotFocused)
-        {
+    	if (conversation_floater_not_focused)
+    	{
+            if(session_floater_not_focused)
+            {
+            	//User is not focused on conversation containing the message
+                gToolBarView->flashCommand(LLCommandId("chat"), true);
+            }
+
             im_box->flashConversationItemWidget(session_id, true);
         }
     }
+
     else if("openconversations" == action)
     {
         //User is not focused on conversation containing the message
-        if(sessionFloaterNotFocused)
+        if(session_floater_not_focused)
         {
             //Flash line item
             im_box->flashConversationItemWidget(session_id, true);
@@ -863,7 +865,8 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
 
 bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
 {
-	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages")
+			&& gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
 	{	
 		std::string from_name = from;
 
@@ -960,7 +963,7 @@ const std::string LLIMModel::getName(const LLUUID& session_id) const
 {
 	LLIMSession* session = findIMSession(session_id);
 
-	if (!session) 
+	if (!session)
 	{
 		llwarns << "session " << session_id << "does not exist " << llendl;
 		return LLTrans::getString("no_session_message");
@@ -2487,17 +2490,24 @@ void LLIMMgr::addMessage(
 		new_session_id = computeSessionID(dialog, other_participant_id);
 	}
 
-	// Open conversation log if offline messages are present
+	// Open conversation log if offline messages are present and user allows a Call Log
 	if (is_offline_msg)
-	{
-		LLFloaterConversationLog* floater_log =
-				LLFloaterReg::getTypedInstance<LLFloaterConversationLog>("conversation");
-		if (floater_log && !(floater_log->isFrontmost()))
+    {
+		if (gSavedSettings.getBOOL("KeepConversationLogTranscripts"))
 		{
-            floater_log->openFloater();
-			floater_log->setFrontmost(TRUE);
+			LLFloaterConversationLog* floater_log =
+					LLFloaterReg::getTypedInstance<LLFloaterConversationLog>("conversation");
+			if (floater_log && !(floater_log->isFrontmost()))
+			{
+				floater_log->openFloater();
+				floater_log->setFrontmost(TRUE);
+			}
 		}
-	}
+		else
+		{
+           gToolBarView->flashCommand(LLCommandId("chat"), true);
+		}
+    }
 
 	//*NOTE session_name is empty in case of incoming P2P sessions
 	std::string fixed_session_name = from;
@@ -2552,7 +2562,7 @@ void LLIMMgr::addMessage(
 		}
 
         //Play sound for new conversations
-        if(gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE)
+		if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
         {
             make_ui_sound("UISndNewIncomingIMSession");
         }
@@ -2708,12 +2718,13 @@ LLUUID LLIMMgr::addSession(
 	{
 		LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(floater_id);
 
-		if (im_floater && im_floater->getStartConferenceInSameFloater())
+		if (im_floater)
 		{
 			// The IM floater should be initialized with a new session_id
 			// so that it is found by that id when creating a chiclet in LLFloaterIMSession::onIMChicletCreated,
 			// and a new floater is not created.
 			im_floater->initIMSession(session_id);
+            im_floater->reloadMessages();
 		}
 	}
 
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 2bc9cdd3c1b16782c6d40ef3e9742bfb8e9dd864..58a9b01a45944df8e232110ac02650f7eee0a33d 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -29,6 +29,7 @@
 
 #include "llnotificationhandler.h"
 
+#include "llagentcamera.h"
 #include "llnotifications.h"
 #include "llprogressview.h"
 #include "lltoastnotifypanel.h"
@@ -41,7 +42,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLAlertHandler::LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal) 
-:	LLSysHandler(name, notification_type),
+:	LLSystemNotificationHandler(name, notification_type),
 	mIsModal(is_modal)
 {
 	LLScreenChannelBase::Params p;
@@ -123,3 +124,28 @@ void LLAlertHandler::onChange( LLNotificationPtr notification )
 	if(channel)
 		channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
 }
+
+//--------------------------------------------------------------------------
+LLViewerAlertHandler::LLViewerAlertHandler(const std::string& name, const std::string& notification_type)
+	: LLSystemNotificationHandler(name, notification_type)
+{
+}
+
+bool LLViewerAlertHandler::processNotification(const LLNotificationPtr& p)
+{
+	if (gHeadlessClient)
+	{
+		LL_INFOS("LLViewerAlertHandler") << "Alert: " << p->getName() << LL_ENDL;
+	}
+
+	// If we're in mouselook, the mouse is hidden and so the user can't click 
+	// the dialog buttons.  In that case, change to First Person instead.
+	if( gAgentCamera.cameraMouselook() )
+	{
+		gAgentCamera.changeCameraToDefault();
+	}
+
+	return false;
+}
+
+
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index 18cd94e6855ff516cf743d65355db1dbc13790cf..8fef102cf889236b44222e49954d84735ef7cf1a 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -38,7 +38,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLGroupHandler::LLGroupHandler()
-:	LLSysHandler("Group Notifications", "groupnotify")
+:	LLCommunicationNotificationHandler("Group Notifications", "groupnotify")
 {
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 4bded6ab30ed1e0c05bf056f5e1c3fc85d0bd756..bff4efa9eaebc8393b0ae5e2fe9f11ce439bed71 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -27,6 +27,7 @@
 #ifndef LL_LLNOTIFICATIONHANDLER_H
 #define LL_LLNOTIFICATIONHANDLER_H
 
+#include <boost/intrusive_ptr.hpp>
 
 #include "llwindow.h"
 
@@ -86,22 +87,37 @@ class LLEventHandler
 /**
  * Handler for system notifications.
  */
-class LLSysHandler : public LLEventHandler, public LLNotificationChannel
+class LLNotificationHandler : public LLEventHandler, public LLNotificationChannel
 {
 public:
-	LLSysHandler(const std::string& name, const std::string& notification_type);
-	virtual ~LLSysHandler() {};
+	LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName);
+	virtual ~LLNotificationHandler() {};
 
 	// base interface functions
-	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());}
+	virtual void onAdd(LLNotificationPtr p) { processNotification(p); }
+	virtual void onChange(LLNotificationPtr p) { processNotification(p); }
+	virtual void onLoad(LLNotificationPtr p) { processNotification(p); }
+	virtual void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());}
 
-	virtual bool processNotification(const LLNotificationPtr& notify)=0;
+	virtual bool processNotification(const LLNotificationPtr& notify) = 0;
+};
+
+class LLSystemNotificationHandler : public LLNotificationHandler
+{
+public:
+	LLSystemNotificationHandler(const std::string& name, const std::string& notification_type);
+	virtual ~LLSystemNotificationHandler() {};
+};
+
+class LLCommunicationNotificationHandler : public LLNotificationHandler
+{
+public:
+	LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type);
+	virtual ~LLCommunicationNotificationHandler() {};
 };
 
 /**
- * Handler for chat message notifications.
+ * Handler for chat message notifications. 
  */
 class LLChatHandler : public LLEventHandler
 {
@@ -115,67 +131,62 @@ class LLChatHandler : public LLEventHandler
  * Handler for IM notifications.
  * It manages life time of IMs, group messages.
  */
-class LLIMHandler : public LLSysHandler
+class LLIMHandler : public LLCommunicationNotificationHandler
 {
 public:
 	LLIMHandler();
 	virtual ~LLIMHandler();
+	bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	bool processNotification(const LLNotificationPtr& p);
-	/*virtual*/ void initChannel();
+	virtual void initChannel();
 };
 
 /**
  * Handler for system informational notices.
  * It manages life time of tip notices.
  */
-class LLTipHandler : public LLSysHandler
+class LLTipHandler : public LLSystemNotificationHandler
 {
 public:
 	LLTipHandler();
 	virtual ~LLTipHandler();
 
-	// base interface functions
-	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	/*virtual*/ void initChannel();
+	virtual void initChannel();
 };
 
 /**
  * Handler for system informational notices.
  * It manages life time of script notices.
  */
-class LLScriptHandler : public LLSysHandler
+class LLScriptHandler : public LLSystemNotificationHandler
 {
 public:
 	LLScriptHandler();
 	virtual ~LLScriptHandler();
 
-	/*virtual*/ void onDelete(LLNotificationPtr p);
-	// base interface functions
-	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
+	virtual void onDelete(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	/*virtual*/ void onDeleteToast(LLToast* toast);
-	/*virtual*/ void initChannel();
+	virtual void onDeleteToast(LLToast* toast);
+	virtual void initChannel();
 };
 
 
 /**
  * Handler for group system notices.
  */
-class LLGroupHandler : public LLSysHandler
+class LLGroupHandler : public LLCommunicationNotificationHandler
 {
 public:
 	LLGroupHandler();
 	virtual ~LLGroupHandler();
 	
-	// base interface functions
-	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
 	virtual void initChannel();
@@ -184,15 +195,14 @@ class LLGroupHandler : public LLSysHandler
 /**
  * Handler for alert system notices.
  */
-class LLAlertHandler : public LLSysHandler
+class LLAlertHandler : public LLSystemNotificationHandler
 {
 public:
 	LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal);
 	virtual ~LLAlertHandler();
 
-	/*virtual*/ void onChange(LLNotificationPtr p);
-	/*virtual*/ void onLoad(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
+	virtual void onChange(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
 	virtual void initChannel();
@@ -200,67 +210,85 @@ class LLAlertHandler : public LLSysHandler
 	bool	mIsModal;
 };
 
+class LLViewerAlertHandler  : public LLSystemNotificationHandler
+{
+	LOG_CLASS(LLViewerAlertHandler);
+public:
+	LLViewerAlertHandler(const std::string& name, const std::string& notification_type);
+	virtual ~LLViewerAlertHandler() {};
+
+	virtual void onDelete(LLNotificationPtr p) {};
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
+};
+
 /**
  * Handler for offers notices.
  * It manages life time of offer notices.
  */
-class LLOfferHandler : public LLSysHandler
+class LLOfferHandler : public LLCommunicationNotificationHandler
 {
 public:
 	LLOfferHandler();
 	virtual ~LLOfferHandler();
 
-	// base interface functions
-	/*virtual*/ void onChange(LLNotificationPtr p);
-	/*virtual*/ void onDelete(LLNotificationPtr notification);
-	/*virtual*/ bool processNotification(const LLNotificationPtr& p);
+	virtual void onChange(LLNotificationPtr p);
+	virtual void onDelete(LLNotificationPtr notification);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	/*virtual*/ void initChannel();
+	virtual void initChannel();
 };
 
 /**
  * Handler for UI hints.
  */
-class LLHintHandler : public LLNotificationChannel
+class LLHintHandler : public LLSystemNotificationHandler
 {
 public:
-	LLHintHandler() : LLNotificationChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint"))
-	{}
+	LLHintHandler();
 	virtual ~LLHintHandler() {}
 
-	/*virtual*/ void onAdd(LLNotificationPtr p);
-	/*virtual*/ void onLoad(LLNotificationPtr p);
-	/*virtual*/ void onDelete(LLNotificationPtr p);
+	virtual void onAdd(LLNotificationPtr p);
+	virtual void onLoad(LLNotificationPtr p);
+	virtual void onDelete(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
 };
 
 /**
  * Handler for browser notifications
  */
-class LLBrowserNotification : public LLNotificationChannel
+class LLBrowserNotification : public LLSystemNotificationHandler
 {
 public:
-	LLBrowserNotification()
-	: LLNotificationChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser"))
-	{}
-	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onChange(LLNotificationPtr p) { processNotification(p); }
-	bool processNotification(const LLNotificationPtr& p);
+	LLBrowserNotification();
+	virtual ~LLBrowserNotification() {}
+
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
 };
 	
 /**
  * Handler for outbox notifications
  */
-class LLOutboxNotification : public LLNotificationChannel
+class LLOutboxNotification : public LLSystemNotificationHandler
 {
 public:
-	LLOutboxNotification()
-	:	LLNotificationChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox"))
-	{}
-	/*virtual*/ void onAdd(LLNotificationPtr p) { processNotification(p); }
-	/*virtual*/ void onChange(LLNotificationPtr p) { }
-	/*virtual*/ void onDelete(LLNotificationPtr p);
-	bool processNotification(const LLNotificationPtr& p);
+	LLOutboxNotification();
+	virtual ~LLOutboxNotification() {};
+	virtual void onChange(LLNotificationPtr p) { }
+	virtual void onDelete(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
 };
 	
 class LLHandlerUtil
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 7f1216ff407bc4cf58fd7d291ef03e16c4d04712..f0175d677c6079728ac3495cc9e0b3754a04c2fd 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -41,8 +41,16 @@
 
 using namespace LLNotificationsUI;
 
-LLSysHandler::LLSysHandler(const std::string& name, const std::string& notification_type)
-:	LLNotificationChannel(name, "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))
+LLNotificationHandler::LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName)
+:	LLNotificationChannel(name, parentName, LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))
+{}
+
+LLSystemNotificationHandler::LLSystemNotificationHandler(const std::string& name, const std::string& notification_type)
+	: LLNotificationHandler(name, notification_type, "System")
+{}
+
+LLCommunicationNotificationHandler::LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type)
+	: LLNotificationHandler(name, notification_type, "Communication")
 {}
 
 // static
diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp
index 271f41850764fc87cc062054355dd391f417d6e3..f40369a2e061735eaa67b9eff730addf3e9c3944 100644
--- a/indra/newview/llnotificationhinthandler.cpp
+++ b/indra/newview/llnotificationhinthandler.cpp
@@ -33,6 +33,27 @@
 
 using namespace LLNotificationsUI;
 
-void LLHintHandler::onAdd(LLNotificationPtr p) { LLHints::show(p); }
-void LLHintHandler::onLoad(LLNotificationPtr p) { LLHints::show(p); }
-void LLHintHandler::onDelete(LLNotificationPtr p) { LLHints::hide(p); }
+LLHintHandler::LLHintHandler()
+	: LLSystemNotificationHandler("Hints", "hint")
+{
+}
+
+void LLHintHandler::onAdd(LLNotificationPtr p)
+{
+	LLHints::show(p);
+}
+
+void LLHintHandler::onLoad(LLNotificationPtr p)
+{
+	LLHints::show(p);
+}
+
+void LLHintHandler::onDelete(LLNotificationPtr p)
+{
+	LLHints::hide(p);
+}
+
+bool LLHintHandler::processNotification(const LLNotificationPtr& p)
+{
+	return false;
+}
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index ff5b5e21f704d4bfdb07ca2cd9b72df5d5c516db..da38c9063be2613ae4ec2d916c7e76ec078db0d2 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -41,7 +41,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLOfferHandler::LLOfferHandler()
-:	LLSysHandler("Offer", "offer")
+:	LLCommunicationNotificationHandler("Offer", "offer")
 {
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 290a81f91cd4f82250f1b2a43e42c86ba3086d88..e2d4e9f8ce58937a8037d6bf082c244f8bc3e66e 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -39,7 +39,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLScriptHandler::LLScriptHandler()
-:	LLSysHandler("Notifications", "notify")
+:	LLSystemNotificationHandler("Notifications", "notify")
 {
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index a31b95811e1761595e58ca038536cf5d97095097..b79777536963001e2834938f260a5b723d28cc49 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -25,207 +25,143 @@
 */
 
 #include "llviewerprecompiledheaders.h" // must be first include
+
 #include "llnotificationstorage.h"
 
-#include "llxmlnode.h" // for linux compilers
+#include <string>
+#include <map>
 
-#include "llchannelmanager.h"
-#include "llscreenchannel.h"
-#include "llscriptfloater.h"
+#include "llerror.h"
+#include "llfile.h"
+#include "llnotifications.h"
+#include "llpointer.h"
+#include "llsd.h"
 #include "llsdserialize.h"
+#include "llsingleton.h"
 #include "llviewermessage.h"
 
-//////////////////////////////////////////////////////////////////////////
 
-class LLResponderRegistry
+class LLResponderRegistry : public LLSingleton<LLResponderRegistry>
 {
 public:
-
-	static void registerResponders();
-
-	static LLNotificationResponderInterface* createResponder(const std::string& notification_name, const LLSD& params);
-
+	LLResponderRegistry();
+	~LLResponderRegistry();
+	
+	LLNotificationResponderInterface* createResponder(const std::string& pNotificationName, const LLSD& pParams);
+	
+protected:
+	
 private:
-
-	template<typename RESPONDER_TYPE>
-	static LLNotificationResponderInterface* create(const LLSD& params)
-	{
-		RESPONDER_TYPE* responder = new RESPONDER_TYPE();
-		responder->fromLLSD(params);
-		return responder;
-	}
-
+	template<typename RESPONDER_TYPE> static LLNotificationResponderInterface* create(const LLSD& pParams);
+	
 	typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
-
-	static void add(const std::string& notification_name, const responder_constructor_t& ctr);
-
-private:
-
+	
+	void add(const std::string& pNotificationName, const responder_constructor_t& pConstructor);
+	
 	typedef std::map<std::string, responder_constructor_t> build_map_t;
-
-	static build_map_t sBuildMap;
+	build_map_t mBuildMap;
 };
 
-//////////////////////////////////////////////////////////////////////////
-
-LLPersistentNotificationStorage::LLPersistentNotificationStorage()
+LLNotificationStorage::LLNotificationStorage(std::string pFileName)
+	: mFileName(pFileName)
 {
-	mFileName = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
 }
 
-bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
+LLNotificationStorage::~LLNotificationStorage()
 {
-	// we ignore "load" messages, but rewrite the persistence file on any other
-	const std::string sigtype = payload["sigtype"].asString();
-	if ("load" != sigtype)
-	{
-		saveNotifications();
-	}
-	return false;
 }
 
-static LLFastTimer::DeclareTimer FTM_SAVE_NOTIFICATIONS("Save Notifications");
-
-void LLPersistentNotificationStorage::saveNotifications()
+bool LLNotificationStorage::writeNotifications(const LLSD& pNotificationData) const
 {
-	LLFastTimer _(FTM_SAVE_NOTIFICATIONS);
 
-	llofstream notify_file(mFileName.c_str());
-	if (!notify_file.is_open())
-	{
-		llwarns << "Failed to open " << mFileName << llendl;
-		return;
-	}
-
-	LLSD output;
-	LLSD& data = output["data"];
+	llofstream notifyFile(mFileName.c_str());
+	bool didFileOpen = notifyFile.is_open();
 
-	boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent"));
-	if (!history_channel)
+	if (!didFileOpen)
 	{
-		return;
+		LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
 	}
-
-	for ( std::vector<LLNotificationPtr>::iterator it = history_channel->beginHistory(), end_it = history_channel->endHistory();
-		it != end_it;
-		++it)
+	else
 	{
-		LLNotificationPtr notification = *it;
-
-		// After a notification was placed in Persist channel, it can become
-		// responded, expired or canceled - in this case we are should not save it
-		if(notification->isRespondedTo() || notification->isCancelled()
-			|| notification->isExpired())
-		{
-			continue;
-		}
-
-		data.append(notification->asLLSD());
+		LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+		formatter->format(pNotificationData, notifyFile, LLSDFormatter::OPTIONS_PRETTY);
 	}
 
-	LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
-	formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
+	return didFileOpen;
 }
 
-static LLFastTimer::DeclareTimer FTM_LOAD_NOTIFICATIONS("Load Notifications");
-
-void LLPersistentNotificationStorage::loadNotifications()
+bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const
 {
-	LLFastTimer _(FTM_LOAD_NOTIFICATIONS);
-	LLResponderRegistry::registerResponders();
+	bool didFileRead;
 
-	LLNotifications::instance().getChannel("Persistent")->
-		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+	pNotificationData.clear();
 
-	llifstream notify_file(mFileName.c_str());
-	if (!notify_file.is_open())
+	llifstream notifyFile(mFileName.c_str());
+	didFileRead = notifyFile.is_open();
+	if (!didFileRead)
 	{
-		llwarns << "Failed to open " << mFileName << llendl;
-		return;
+		LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
 	}
-
-	LLSD input;
-	LLPointer<LLSDParser> parser = new LLSDXMLParser();
-	if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
+	else
 	{
-		llwarns << "Failed to parse open notifications" << llendl;
-		return;
-	}
-
-	if (input.isUndefined())
-	{
-		return;
-	}
-
-	LLSD& data = input["data"];
-	if (data.isUndefined())
-	{
-		return;
-	}
-
-	using namespace LLNotificationsUI;
-	LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
-		findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-
-	LLNotifications& instance = LLNotifications::instance();
-
-	for (LLSD::array_const_iterator notification_it = data.beginArray();
-		notification_it != data.endArray();
-		++notification_it)
-	{
-		LLSD notification_params = *notification_it;
-		LLNotificationPtr notification(new LLNotification(notification_params));
-
-		LLNotificationResponderPtr responder(LLResponderRegistry::
-			createResponder(notification_params["name"], notification_params["responder"]));
-		notification->setResponseFunctor(responder);
-
-		instance.add(notification);
-
-		// hide script floaters so they don't confuse the user and don't overlap startup toast
-		LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
-
-		if(notification_channel)
+		LLPointer<LLSDParser> parser = new LLSDXMLParser();
+		didFileRead = (parser->parse(notifyFile, pNotificationData, LLSDSerialize::SIZE_UNLIMITED) >= 0);
+		if (!didFileRead)
 		{
-			// hide saved toasts so they don't confuse the user
-			notification_channel->hideToast(notification->getID());
+			LL_WARNS("LLNotificationStorage") << "Failed to parse open notifications from file '" << mFileName 
+				<< "'" << LL_ENDL;
 		}
 	}
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
 
-LLResponderRegistry::build_map_t LLResponderRegistry::sBuildMap;
+	return didFileRead;
+}
 
-void LLResponderRegistry::registerResponders()
+LLNotificationResponderInterface* LLNotificationStorage::createResponder(const std::string& pNotificationName, const LLSD& pParams) const
 {
-	sBuildMap.clear();
+	return LLResponderRegistry::getInstance()->createResponder(pNotificationName, pParams);
+}
 
+LLResponderRegistry::LLResponderRegistry()
+	: LLSingleton<LLResponderRegistry>()
+	, mBuildMap()
+{
 	add("ObjectGiveItem", &create<LLOfferInfo>);
+	add("OwnObjectGiveItem", &create<LLOfferInfo>);
 	add("UserGiveItem", &create<LLOfferInfo>);
+
+	add("TeleportOffered", &create<LLOfferInfo>);
+	add("TeleportOffered_MaturityExceeded", &create<LLOfferInfo>);
+
+	add("OfferFriendship", &create<LLOfferInfo>);
 }
 
-LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& notification_name, const LLSD& params)
+LLResponderRegistry::~LLResponderRegistry()
 {
-	build_map_t::const_iterator it = sBuildMap.find(notification_name);
-	if(sBuildMap.end() == it)
+}
+
+LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& pNotificationName, const LLSD& pParams)
+{
+	build_map_t::const_iterator it = mBuildMap.find(pNotificationName);
+	if(mBuildMap.end() == it)
 	{
 		return NULL;
 	}
 	responder_constructor_t ctr = it->second;
-	return ctr(params);
+	return ctr(pParams);
 }
 
-void LLResponderRegistry::add(const std::string& notification_name, const responder_constructor_t& ctr)
+template<typename RESPONDER_TYPE> LLNotificationResponderInterface* LLResponderRegistry::create(const LLSD& pParams)
 {
-	if(sBuildMap.find(notification_name) != sBuildMap.end())
+	RESPONDER_TYPE* responder = new RESPONDER_TYPE();
+	responder->fromLLSD(pParams);
+	return responder;
+}
+	
+void LLResponderRegistry::add(const std::string& pNotificationName, const responder_constructor_t& pConstructor)
+{
+	if (mBuildMap.find(pNotificationName) != mBuildMap.end())
 	{
-		llwarns << "Responder is already registered : " << notification_name << llendl;
-		llassert(!"Responder already registered");
+		LL_ERRS("LLResponderRegistry") << "Responder is already registered : " << pNotificationName << LL_ENDL;
 	}
-	sBuildMap[notification_name] = ctr;
+	mBuildMap.insert(std::make_pair<std::string, responder_constructor_t>(pNotificationName, pConstructor));
 }
-
-// EOF
diff --git a/indra/newview/llnotificationstorage.h b/indra/newview/llnotificationstorage.h
index 8635c797c0c9f1f0d2cd2a98abf45332cd334913..7aabf7d09e03a9586a2516fd64b3bf30665f97a5 100644
--- a/indra/newview/llnotificationstorage.h
+++ b/indra/newview/llnotificationstorage.h
@@ -27,32 +27,27 @@
 #ifndef LL_NOTIFICATIONSTORAGE_H
 #define LL_NOTIFICATIONSTORAGE_H
 
-#include "llnotifications.h"
-
-// Class that saves not responded(unread) notifications.
-// Unread notifications are saved in open_notifications.xml in SL account folder
-//
-// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml
-// Notifications using functor responders are saved automatically (see llviewermessage.cpp
-// lure_callback_reg for example).
-// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should
-// be a) serializable(implement LLNotificationResponderInterface),
-// b) registered with LLResponderRegistry (found in llnotificationstorage.cpp).
-class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>
-{
-	LOG_CLASS(LLPersistentNotificationStorage);
-public:
+#include <string>
 
-	LLPersistentNotificationStorage();
+#include "llerror.h"
 
-	void saveNotifications();
+class LLNotificationResponderInterface;
+class LLSD;
 
-	void loadNotifications();
+class LLNotificationStorage
+{
+	LOG_CLASS(LLNotificationStorage);
+public:
+	LLNotificationStorage(std::string pFileName);
+	~LLNotificationStorage();
 
-private:
+protected:
+	bool writeNotifications(const LLSD& pNotificationData) const;
+	bool readNotifications(LLSD& pNotificationData) const;
 
-	bool onPersistentChannelChanged(const LLSD& payload);
+	LLNotificationResponderInterface* createResponder(const std::string& pNotificationName, const LLSD& pParams) const;
 
+private:
 	std::string mFileName;
 };
 
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index faa67b5ea43911fe8f4ee20f88c1efe8758d9b44..a85335f1ba9c0a3a2e5ccd8c1f05b016a78df934 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -42,7 +42,7 @@ using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
 LLTipHandler::LLTipHandler()
-:	LLSysHandler("NotificationTips", "notifytip")
+:	LLSystemNotificationHandler("NotificationTips", "notifytip")
 {
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index ecab7d2167bff7b82698b1e567479afd2d7a6251..df1ccdd9fca1354c31137c81a157737de4e996a6 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -137,6 +137,7 @@ void LLPanelBlockedList::updateButtons()
 {
 	bool hasSelected = NULL != mBlockedList->getSelectedItem();
 	getChildView("unblock_btn")->setEnabled(hasSelected);
+	getChildView("blocked_gear_btn")->setEnabled(hasSelected);
 }
 
 void LLPanelBlockedList::unblockItem()
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..224aaa21467d3f7fd453c14356fddfa0d067ba96
--- /dev/null
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -0,0 +1,145 @@
+/** 
+* @file llpersistentnotificationstorage.cpp
+* @brief Implementation of llpersistentnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llpersistentnotificationstorage.h"
+
+#include "llchannelmanager.h"
+#include "llnotificationstorage.h"
+#include "llscreenchannel.h"
+#include "llscriptfloater.h"
+#include "llviewermessage.h"
+
+LLPersistentNotificationStorage::LLPersistentNotificationStorage()
+	: LLSingleton<LLPersistentNotificationStorage>()
+	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"))
+{
+}
+
+LLPersistentNotificationStorage::~LLPersistentNotificationStorage()
+{
+}
+
+static LLFastTimer::DeclareTimer FTM_SAVE_NOTIFICATIONS("Save Notifications");
+
+void LLPersistentNotificationStorage::saveNotifications()
+{
+	LLFastTimer _(FTM_SAVE_NOTIFICATIONS);
+
+	boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent"));
+	if (!history_channel)
+	{
+		return;
+	}
+
+	LLSD output = LLSD::emptyMap();
+	LLSD& data = output["data"];
+
+	for ( std::vector<LLNotificationPtr>::iterator it = history_channel->beginHistory(), end_it = history_channel->endHistory();
+		it != end_it;
+		++it)
+	{
+		LLNotificationPtr notification = *it;
+
+		// After a notification was placed in Persist channel, it can become
+		// responded, expired or canceled - in this case we are should not save it
+		if(notification->isRespondedTo() || notification->isCancelled()
+			|| notification->isExpired())
+		{
+			continue;
+		}
+
+		data.append(notification->asLLSD());
+	}
+
+	writeNotifications(output);
+}
+
+static LLFastTimer::DeclareTimer FTM_LOAD_NOTIFICATIONS("Load Notifications");
+
+void LLPersistentNotificationStorage::loadNotifications()
+{
+	LLFastTimer _(FTM_LOAD_NOTIFICATIONS);
+
+	LLNotifications::instance().getChannel("Persistent")->
+		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+
+	LLSD input;
+	if (!readNotifications(input) ||input.isUndefined())
+	{
+		return;
+	}
+
+	LLSD& data = input["data"];
+	if (data.isUndefined())
+	{
+		return;
+	}
+
+	using namespace LLNotificationsUI;
+	LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
+		findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
+	LLNotifications& instance = LLNotifications::instance();
+
+	for (LLSD::array_const_iterator notification_it = data.beginArray();
+		notification_it != data.endArray();
+		++notification_it)
+	{
+		LLSD notification_params = *notification_it;
+		LLNotificationPtr notification(new LLNotification(notification_params));
+
+		LLNotificationResponderPtr responder(createResponder(notification_params["name"], notification_params["responder"]));
+		notification->setResponseFunctor(responder);
+
+		instance.add(notification);
+
+		// hide script floaters so they don't confuse the user and don't overlap startup toast
+		LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
+
+		if(notification_channel)
+		{
+			// hide saved toasts so they don't confuse the user
+			notification_channel->hideToast(notification->getID());
+		}
+	}
+}
+
+bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
+{
+	// we ignore "load" messages, but rewrite the persistence file on any other
+	const std::string sigtype = payload["sigtype"].asString();
+	if ("load" != sigtype)
+	{
+		saveNotifications();
+	}
+	return false;
+}
+
+// EOF
diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h
new file mode 100644
index 0000000000000000000000000000000000000000..98a825d2c139148807cd79a36225703954ad380e
--- /dev/null
+++ b/indra/newview/llpersistentnotificationstorage.h
@@ -0,0 +1,63 @@
+/** 
+* @file   llpersistentnotificationstorage.h
+* @brief  Header file for llpersistentnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $LicenseInfo:firstyear=2012&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2012, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#ifndef LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+#define LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+
+#include "llerror.h"
+#include "llnotificationstorage.h"
+#include "llsingleton.h"
+
+class LLSD;
+
+// Class that saves not responded(unread) notifications.
+// Unread notifications are saved in open_notifications.xml in SL account folder
+//
+// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml
+// Notifications using functor responders are saved automatically (see llviewermessage.cpp
+// lure_callback_reg for example).
+// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should
+// be a) serializable(implement LLNotificationResponderInterface),
+// b) registered with LLResponderRegistry (found in llpersistentnotificationstorage.cpp).
+
+class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>, public LLNotificationStorage
+{
+	LOG_CLASS(LLPersistentNotificationStorage);
+public:
+	LLPersistentNotificationStorage();
+	~LLPersistentNotificationStorage();
+
+	void saveNotifications();
+	void loadNotifications();
+
+protected:
+
+private:
+	bool onPersistentChannelChanged(const LLSD& payload);
+};
+
+#endif // LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 8a43855a7dd9e9e21cf594966bb1215611bb5695..e92bd766ca7f60b442178a37cff4b257dd289eee 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -40,6 +40,7 @@
 LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLTransientDockableFloater(NULL, true,  key),
 													mChannel(NULL),
 													mMessageList(NULL),
+													mSysWellChiclet(NULL),
 													NOTIFICATION_WELL_ANCHOR_NAME("notification_well_panel"),
 													IM_WELL_ANCHOR_NAME("im_well_panel"),
 													mIsReshapedByUser(false)
@@ -79,6 +80,15 @@ void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask)
 	setVisible(TRUE);
 }
 
+void LLSysWellWindow::setSysWellChiclet(LLSysWellChiclet* chiclet) 
+{ 
+	mSysWellChiclet = chiclet;
+	if(NULL != mSysWellChiclet)
+	{
+		mSysWellChiclet->updateWidget(isWindowEmpty());
+	}
+}
+
 //---------------------------------------------------------------------------------
 LLSysWellWindow::~LLSysWellWindow()
 {
@@ -89,6 +99,10 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
 {
 	if(mMessageList->removeItemByValue(id))
 	{
+		if (NULL != mSysWellChiclet)
+		{
+			mSysWellChiclet->updateWidget(isWindowEmpty());
+		}
 		reshapeWindow();
 	}
 	else
@@ -334,6 +348,7 @@ void LLNotificationWellWindow::addItem(LLSysWellItem::Params p)
 	LLSysWellItem* new_item = new LLSysWellItem(p);
 	if (mMessageList->addItem(new_item, value, ADD_TOP))
 	{
+		mSysWellChiclet->updateWidget(isWindowEmpty());
 		reshapeWindow();
 		new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1));
 		new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1));
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 406ab1b59eb2044f20c406b1bcebcc22bc9dd759..cc5c057d8b395c8dd5ef17e260668eb12df72026 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -66,6 +66,8 @@ class LLSysWellWindow : public LLTransientDockableFloater
 
 	void onStartUpToastClick(S32 x, S32 y, MASK mask);
 
+	void setSysWellChiclet(LLSysWellChiclet* chiclet);
+
 	// size constants for the window and for its elements
 	static const S32 MAX_WINDOW_HEIGHT		= 200;
 	static const S32 MIN_WINDOW_WIDTH		= 318;
@@ -84,6 +86,11 @@ class LLSysWellWindow : public LLTransientDockableFloater
 	LLNotificationsUI::LLScreenChannel*	mChannel;
 	LLFlatListView*	mMessageList;
 
+	/**
+	 * Reference to an appropriate Well chiclet to release "new message" state. EXT-3147
+	 */
+	LLSysWellChiclet* mSysWellChiclet;
+
 	bool mIsReshapedByUser;
 };
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index fe9c00cc2701f9f76c205e47910ddb0a39f52ca5..be9f7d645a4efa6a5abc97a5c4f6326a0b2586a9 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7586,6 +7586,20 @@ void handle_web_content_test(const LLSD& param)
 	LLWeb::loadURLInternal(url);
 }
 
+void handle_show_url(const LLSD& param)
+{
+	std::string url = param.asString();
+	if(gSavedSettings.getBOOL("UseExternalBrowser"))
+	{
+		LLWeb::loadURLExternal(url);
+	}
+	else
+	{
+		LLWeb::loadURLInternal(url);
+	}
+
+}
+
 void handle_buy_currency_test(void*)
 {
 	std::string url =
@@ -8415,6 +8429,7 @@ void initialize_menus()
 	// Advanced > UI
 	commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test,	_2));	// sigh! this one opens the MEDIA browser
 	commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2));	// this one opens the Web Content floater
+	commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2));
 	view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
 	view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
 	view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index f5da94dc87fe229d4c76139f700922349036f5d9..61716d1d5ba8a46408a5707ebf76a8d657308307 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -3169,17 +3169,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			payload["online"] = (offline == IM_ONLINE);
 			payload["sender"] = msg->getSender().getIPandPort();
 
-			if (is_do_not_disturb)
-			{
-				send_do_not_disturb_message(msg, from_id);
-				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
-			}
-			else if (is_muted)
+			if (is_muted)
 			{
 				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
 			}
 			else
 			{
+				if (is_do_not_disturb)
+				{
+					send_do_not_disturb_message(msg, from_id);
+				}
 				args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
 				if(message.empty())
 				{
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 1d7abb7c1cdaea04a31a85dc5a69b80c764939b2..1c463015e2cbe41d6075ebb45e6f34cc6c2085b4 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -37,8 +37,10 @@
 
 #include "llagent.h"
 #include "llagentcamera.h"
+#include "llcommunicationchannel.h"
 #include "llfloaterreg.h"
 #include "llmeshrepository.h"
+#include "llnotificationhandler.h"
 #include "llpanellogin.h"
 #include "llviewerkeyboard.h"
 #include "llviewermenu.h"
@@ -127,6 +129,7 @@
 #include "llmorphview.h"
 #include "llmoveview.h"
 #include "llnavigationbar.h"
+#include "llnotificationhandler.h"
 #include "llpanelpathfindingrebakenavmesh.h"
 #include "llpaneltopinfobar.h"
 #include "llpopupview.h"
@@ -1554,11 +1557,11 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard)));
 	mViewerWindowListener.reset(new LLViewerWindowListener(this));
 
-	mAlertsChannel.reset(new LLNotificationChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert")));
-	mModalAlertsChannel.reset(new LLNotificationChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal")));
+	mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything));
+	mCommunicationChannel.reset(new LLCommunicationChannel("Communication", "Visible"));
+	mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert"));
+	mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal"));
 
-	mAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
-	mModalAlertsChannel->connectChanged(&LLViewerWindow::onAlert);
 	bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications");
 	LLNotifications::instance().setIgnoreAllNotifications(ignore);
 	if (ignore)
@@ -5044,25 +5047,6 @@ LLRect LLViewerWindow::getChatConsoleRect()
 //----------------------------------------------------------------------------
 
 
-//static 
-bool LLViewerWindow::onAlert(const LLSD& notify)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if (gHeadlessClient)
-	{
-		llinfos << "Alert: " << notification->getName() << llendl;
-	}
-
-	// If we're in mouselook, the mouse is hidden and so the user can't click 
-	// the dialog buttons.  In that case, change to First Person instead.
-	if( gAgentCamera.cameraMouselook() )
-	{
-		gAgentCamera.changeCameraToDefault();
-	}
-	return false;
-}
-
 void LLViewerWindow::setUIVisibility(bool visible)
 {
 	mUIVisible = visible;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index ee6a7793f8e473e80e396613c7ffd6d196dbae2f..5a0d9652b8c62d38f669dc13670b1261940fe5ff 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -43,6 +43,7 @@
 #include "lltimer.h"
 #include "llstat.h"
 #include "llmousehandler.h"
+#include "llnotifications.h"
 #include "llhandle.h"
 #include "llinitparam.h"
 
@@ -401,7 +402,6 @@ class LLViewerWindow : public LLWindowCallbacks
 
 private:
 	bool                    shouldShowToolTipFor(LLMouseHandler *mh);
-	static bool onAlert(const LLSD& notify);
 
 	void			switchToolByMask(MASK mask);
 	void			destroyWindow();
@@ -418,8 +418,10 @@ class LLViewerWindow : public LLWindowCallbacks
 	bool			mActive;
 	bool			mUIVisible;
 
-	boost::shared_ptr<class LLNotificationChannel>	mAlertsChannel,
-													mModalAlertsChannel;
+	LLNotificationChannelPtr mSystemChannel;
+	LLNotificationChannelPtr mCommunicationChannel;
+	LLNotificationChannelPtr mAlertsChannel;
+	LLNotificationChannelPtr mModalAlertsChannel;
 
 	LLRect			mWindowRectRaw;				// whole window, including UI
 	LLRect			mWindowRectScaled;			// whole window, scaled by UI size
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 951c145f25ec641dc3f5b99a506a734906503029..ea7bf2920929ece77156cf94544d9d30430bd91d 100755
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -34,8 +34,6 @@
 
 #include "llvoavatar.h"
 
-#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot
-
 #include <stdio.h>
 #include <ctype.h>
 
@@ -711,13 +709,9 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	LLMemType mt(LLMemType::MTYPE_AVATAR);
 	//VTResume();  // VTune
 	
-#ifdef XXX_STINSON_CHUI_REWORK
 	// mVoiceVisualizer is created by the hud effects manager and uses the HUD Effects pipeline
 	const BOOL needsSendToSim = false; // currently, this HUD effect doesn't need to pack and unpack data to do its job
 	mVoiceVisualizer = ( LLVoiceVisualizer *)LLHUDManager::getInstance()->createViewerEffect( LLHUDObject::LL_HUD_EFFECT_VOICE_VISUALIZER, needsSendToSim );
-#else // XXX_STINSON_CHUI_REWORK
-	mVoiceVisualizer = new LLVoiceVisualizer();
-#endif // XXX_STINSON_CHUI_REWORK
 
 	lldebugs << "LLVOAvatar Constructor (0x" << this << ") id:" << mID << llendl;
 
@@ -893,11 +887,7 @@ void LLVOAvatar::markDead()
 		mNameText = NULL;
 		sNumVisibleChatBubbles--;
 	}
-#ifdef XXX_STINSON_CHUI_REWORK
 	mVoiceVisualizer->markDead();
-#else // XXX_STINSON_CHUI_REWORK
-	mVoiceVisualizer->setStopSpeaking();
-#endif // XXX_STINSON_CHUI_REWORK
 	LLLoadedCallbackEntry::cleanUpCallbackList(&mCallbackTextureList) ;
 	LLViewerObject::markDead();
 }
@@ -1429,9 +1419,7 @@ void LLVOAvatar::initInstance(void)
 	
 	//VTPause();  // VTune
 	
-#ifdef XXX_STINSON_CHUI_REWORK
 	mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) );
-#endif // XXX_STINSON_CHUI_REWORK
 
 }
 
@@ -2529,7 +2517,6 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 
 void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 {
-#ifdef XXX_STINSON_CHUI_REWORK
 	bool render_visualizer = voice_enabled;
 	
 	// Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled.
@@ -2542,7 +2529,6 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 	}
 	
 	mVoiceVisualizer->setVoiceEnabled(render_visualizer);
-#endif // XXX_STINSON_CHUI_REWORK
 	
 	if ( voice_enabled )
 	{		
@@ -2618,7 +2604,6 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 			}
 		}
 		
-#ifdef XXX_STINSON_CHUI_REWORK
 		//--------------------------------------------------------------------------------------------
 		// here we get the approximate head position and set as sound source for the voice symbol
 		// (the following version uses a tweak of "mHeadOffset" which handle sitting vs. standing)
@@ -2636,7 +2621,6 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 			tagPos[VZ] += ( mBodySize[VZ] + 0.125f );
 			mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos );
 		}
-#endif // XXX_STINSON_CHUI_REWORK
 	}//if ( voiceEnabled )
 }		
 
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index dd529d74e9a23731a2530f33100f244b96c5087e..b46c55321c691fe70a29c63dc92477900c1e5ecd 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -541,6 +541,7 @@ void LLVoiceClient::setMuteMic(bool muted)
 {
 	mMuteMic = muted;
 	updateMicMuteLogic();
+	mMicroChangedSignal();
 }
 
 
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index d380a8672f7c285464494940f41260e8ff8777b7..b497f80560fbc6c82d72ae920445d2d43c7168b5 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -45,7 +45,6 @@
 //29de489d-0491-fb00-7dab-f9e686d31e83
 
 
-#ifdef XXX_STINSON_CHUI_REWORK
 //--------------------------------------------------------------------------------------
 // sound symbol constants
 //--------------------------------------------------------------------------------------
@@ -61,7 +60,6 @@ const F32	BASE_BRIGHTNESS		= 0.7f;		// gray level of the voice indicator when qu
 const F32	DOT_SIZE			= 0.05f;	// size of the dot billboard texture
 const F32	DOT_OPACITY			= 0.7f;		// how opaque the dot is
 const F32	WAVE_MOTION_RATE	= 1.5f;		// scalar applied to consecutive waves as a function of speaking amplitude
-#endif // XXX_STINSON_CHUI_REWORK
 
 //--------------------------------------------------------------------------------------
 // gesticulation constants
@@ -69,13 +67,11 @@ const F32	WAVE_MOTION_RATE	= 1.5f;		// scalar applied to consecutive waves as a
 const F32 DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE	= 0.2f; 
 const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE	= 1.0f;
 
-#ifdef XXX_STINSON_CHUI_REWORK
 //--------------------------------------------------------------------------------------
 // other constants
 //--------------------------------------------------------------------------------------
 const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code. 
 const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
-#endif // XXX_STINSON_CHUI_REWORK
 
 //------------------------------------------------------------------
 // Initialize the statics
@@ -98,28 +94,12 @@ F32	 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
 //-----------------------------------------------
 // constructor
 //-----------------------------------------------
-#ifdef XXX_STINSON_CHUI_REWORK
 LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
 	: LLHUDEffect(type)
-#else // XXX_STINSON_CHUI_REWORK
-LLVoiceVisualizer::LLVoiceVisualizer()
-	: LLRefCount(),
-	mTimer(),
-	mStartTime(0.0),
-	mCurrentlySpeaking(false),
-	mSpeakingAmplitude(0.0f),
-	mMaxGesticulationAmplitude(DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE),
-	mMinGesticulationAmplitude(DEFAULT_MINIMUM_GESTICULATION_AMPLITUDE)
-#endif // XXX_STINSON_CHUI_REWORK
 {
-#ifdef XXX_STINSON_CHUI_REWORK
 	mCurrentTime					= mTimer.getTotalSeconds();
 	mPreviousTime					= mCurrentTime;
 	mStartTime						= mCurrentTime;
-#else // XXX_STINSON_CHUI_REWORK
-	mStartTime						= mTimer.getTotalSeconds();
-#endif // XXX_STINSON_CHUI_REWORK
-#ifdef XXX_STINSON_CHUI_REWORK
 	mVoiceSourceWorldPosition		= LLVector3( 0.0f, 0.0f, 0.0f );
 	mSpeakingAmplitude				= 0.0f;
 	mCurrentlySpeaking				= false;
@@ -128,11 +108,9 @@ LLVoiceVisualizer::LLVoiceVisualizer()
 	mMaxGesticulationAmplitude		= DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE;
 	mSoundSymbol.mActive			= true;
 	mSoundSymbol.mPosition			= LLVector3( 0.0f, 0.0f, 0.0f );
-#endif // XXX_STINSON_CHUI_REWORK
 	
 	mTimer.reset();
 	
-#ifdef XXX_STINSON_CHUI_REWORK
 	const char* sound_level_img[] = 
 	{
 		"voice_meter_dot.j2c",
@@ -154,7 +132,6 @@ LLVoiceVisualizer::LLVoiceVisualizer()
 	}
 
 	mSoundSymbol.mTexture[0]->setFilteringOption(LLTexUnit::TFO_ANISOTROPIC);
-#endif // XXX_STINSON_CHUI_REWORK
 
 	// The first instance loads the initial state from prefs.
 	if (!sPrefsInitialized)
@@ -174,7 +151,6 @@ LLVoiceVisualizer::LLVoiceVisualizer()
 
 }//---------------------------------------------------
 
-#ifdef XXX_STINSON_CHUI_REWORK
 //---------------------------------------------------
 void LLVoiceVisualizer::setMinGesticulationAmplitude( F32 m )
 {
@@ -195,16 +171,13 @@ void LLVoiceVisualizer::setVoiceEnabled( bool v )
 	mVoiceEnabled = v;
 
 }//---------------------------------------------------
-#endif // XXX_STINSON_CHUI_REWORK
 
 //---------------------------------------------------
 void LLVoiceVisualizer::setStartSpeaking()
 {
 	mStartTime				= mTimer.getTotalSeconds();
 	mCurrentlySpeaking		= true;
-#ifdef XXX_STINSON_CHUI_REWORK
 	mSoundSymbol.mActive	= true;
-#endif // XXX_STINSON_CHUI_REWORK
 		
 }//---------------------------------------------------
 
@@ -359,7 +332,6 @@ void LLVoiceVisualizer::lipSyncOohAah( F32& ooh, F32& aah )
 }//---------------------------------------------------
 
 
-#ifdef XXX_STINSON_CHUI_REWORK
 //---------------------------------------------------
 // this method is inherited from HUD Effect
 //---------------------------------------------------
@@ -558,7 +530,6 @@ void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
 	mVoiceSourceWorldPosition	= p;
 
 }//---------------------------------------------------
-#endif // XXX_STINSON_CHUI_REWORK
 
 //---------------------------------------------------
 VoiceGesticulationLevel LLVoiceVisualizer::getCurrentGesticulationLevel()
@@ -589,7 +560,6 @@ LLVoiceVisualizer::~LLVoiceVisualizer()
 }//----------------------------------------------
 
 
-#ifdef XXX_STINSON_CHUI_REWORK
 //---------------------------------------------------
 // "packData" is inherited from HUDEffect
 //---------------------------------------------------
@@ -639,5 +609,3 @@ void LLVoiceVisualizer::markDead()
 
 	LLHUDEffect::markDead();
 }//------------------------------------------------------------------
-
-#endif // XXX_STINSON_CHUI_REWORK
diff --git a/indra/newview/llvoicevisualizer.h b/indra/newview/llvoicevisualizer.h
index 5da592c48edbd271c917963871ebd0dc5a76cd01..36c78252d13556c5fc72a0904ee1d996b0bc271f 100644
--- a/indra/newview/llvoicevisualizer.h
+++ b/indra/newview/llvoicevisualizer.h
@@ -42,12 +42,7 @@
 #ifndef LL_VOICE_VISUALIZER_H
 #define LL_VOICE_VISUALIZER_H
 
-#define XXX_STINSON_CHUI_REWORK // temporarily re-enabling the in-world voice-dot
-#ifdef XXX_STINSON_CHUI_REWORK
 #include "llhudeffect.h"
-#else // XXX_STINSON_CHUI_REWORK
-#include "llpointer.h"
-#endif // XXX_STINSON_CHUI_REWORK
 
 //-----------------------------------------------------------------------------------------------
 // The values of voice gesticulation represent energy levels for avatar animation, based on 
@@ -65,45 +60,30 @@ enum VoiceGesticulationLevel
 	NUM_VOICE_GESTICULATION_LEVELS
 };
 
-#ifdef XXX_STINSON_CHUI_REWORK
 const static int NUM_VOICE_SYMBOL_WAVES = 7;
-#endif // XXX_STINSON_CHUI_REWORK
 
 //----------------------------------------------------
 // LLVoiceVisualizer class 
 //----------------------------------------------------
-#ifdef XXX_STINSON_CHUI_REWORK
 class LLVoiceVisualizer : public LLHUDEffect
-#else // XXX_STINSON_CHUI_REWORK
-class LLVoiceVisualizer : public LLRefCount
-#endif // XXX_STINSON_CHUI_REWORK
 {
 	//---------------------------------------------------
 	// public methods 
 	//---------------------------------------------------
 	public:
-#ifdef XXX_STINSON_CHUI_REWORK
 		LLVoiceVisualizer( const U8 type );	//constructor
-#else // XXX_STINSON_CHUI_REWORK
-		LLVoiceVisualizer();	//constructor
-#endif // XXX_STINSON_CHUI_REWORK
 		~LLVoiceVisualizer();					//destructor
 
-#ifdef XXX_STINSON_CHUI_REWORK
 		void					setVoiceSourceWorldPosition( const LLVector3 &p );		// this should be the position of the speaking avatar's head
 		void					setMinGesticulationAmplitude( F32 );					// the lower range of meaningful amplitude for setting gesticulation level 
 		void					setMaxGesticulationAmplitude( F32 );					// the upper range of meaningful amplitude for setting gesticulation level 
-#endif // XXX_STINSON_CHUI_REWORK
 		void					setStartSpeaking();										// tell me when the av starts speaking
-#ifdef XXX_STINSON_CHUI_REWORK
 		void					setVoiceEnabled( bool );								// tell me whether or not the user is voice enabled
-#endif // XXX_STINSON_CHUI_REWORK
 		void					setSpeakingAmplitude( F32 );							// tell me how loud the av is speaking (ranges from 0 to 1)
 		void					setStopSpeaking();										// tell me when the av stops speaking
 		bool					getCurrentlySpeaking();									// the get for the above set
 		VoiceGesticulationLevel	getCurrentGesticulationLevel();							// based on voice amplitude, I'll give you the current "energy level" of avatar speech
 		void					lipSyncOohAah( F32& ooh, F32& aah );
-#ifdef XXX_STINSON_CHUI_REWORK
 		void					render();												// inherited from HUD Effect
 		void 					packData(LLMessageSystem *mesgsys);						// inherited from HUD Effect
 		void 					unpackData(LLMessageSystem *mesgsys, S32 blocknum);		// inherited from HUD Effect
@@ -119,7 +99,6 @@ class LLVoiceVisualizer : public LLRefCount
 		//----------------------------------------------------------------------------------------------
 		void setMaxGesticulationAmplitude(); 
 		void setMinGesticulationAmplitude(); 
-#endif // XXX_STINSON_CHUI_REWORK
 
 	//---------------------------------------------------
 	// private members 
@@ -129,7 +108,6 @@ class LLVoiceVisualizer : public LLRefCount
 		static void				setPreferences( );
 		static void				lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats
 
-#ifdef XXX_STINSON_CHUI_REWORK
 		struct SoundSymbol
 		{
 			F32						mWaveExpansion			[ NUM_VOICE_SYMBOL_WAVES ];
@@ -140,20 +118,15 @@ class LLVoiceVisualizer : public LLRefCount
 			bool					mActive;
 			LLVector3				mPosition;
 		};
-#endif // XXX_STINSON_CHUI_REWORK
 
 		LLFrameTimer			mTimer;							// so I can ask the current time in seconds
 		F64						mStartTime;						// time in seconds when speaking started
-#ifdef XXX_STINSON_CHUI_REWORK
 		F64						mCurrentTime;					// current time in seconds, captured every step
 		F64						mPreviousTime;					// copy of "current time" from last frame
 		SoundSymbol				mSoundSymbol;					// the sound symbol that appears over the avatar's head
 		bool					mVoiceEnabled;					// if off, no rendering should happen
-#endif // XXX_STINSON_CHUI_REWORK
 		bool					mCurrentlySpeaking;				// is the user currently speaking?
-#ifdef XXX_STINSON_CHUI_REWORK
 		LLVector3				mVoiceSourceWorldPosition;		// give this to me every step - I need it to update the sound symbol
-#endif // XXX_STINSON_CHUI_REWORK
 		F32						mSpeakingAmplitude;				// this should be set as often as possible when the user is speaking
 		F32						mMaxGesticulationAmplitude;		// this is the upper-limit of the envelope of detectable gesticulation leves
 		F32						mMinGesticulationAmplitude;		// this is the lower-limit of the envelope of detectable gesticulation leves
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 05230b8bd5122cfe648499429e16e38f7b84bcef..0de217fc0d377c87e9af886bf2dc190ab96a669b 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -11,6 +11,9 @@
 	<color
 	 name="EmphasisColor_35"
 	 value="0.38 0.694 0.573 0.35" />
+	<color
+	 name="BeaconColor"
+    value="0.749 0.298 0 1" />	 
 	<color
 	 name="White"
 	 value="1 1 1 1" />
@@ -522,6 +525,9 @@
     <color
      name="MenuItemHighlightBgColor"
      reference="EmphasisColor_35" />
+    <color
+     name="MenuItemFlashBgColor"
+     reference="BeaconColor" />
     <color
      name="MenuItemHighlightFgColor"
      reference="White" />
diff --git a/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png b/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png
new file mode 100644
index 0000000000000000000000000000000000000000..0ac5b72b8f70e67faef73d07f1ffcd483690c4c1
Binary files /dev/null and b/indra/newview/skins/default/textures/bottomtray/Notices_Unread.png differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index bf6e933dfd09d3fc9a7e52826a9968d6f4c4a66f..a07d7e48553cecbbc515d14767f1cff11c24ebb1 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -365,6 +365,8 @@ with the same filename but different name
 
   <texture name="Nearby_chat_icon" file_name="icons/nearby_chat_icon.png" preload="false" />
 
+  <texture name="Notices_Unread" file_name="bottomtray/Notices_Unread.png" preload="true" />
+
   <texture name="NoEntryLines" file_name="world/NoEntryLines.png" use_mips="true" preload="false" />
   <texture name="NoEntryPassLines" file_name="world/NoEntryPassLines.png" use_mips="true" preload="false" />
 
diff --git a/indra/newview/skins/default/xui/da/menu_notification_well_button.xml b/indra/newview/skins/default/xui/da/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..40b35b5fdd201adc51bb732f335c3a88987812f9
--- /dev/null
+++ b/indra/newview/skins/default/xui/da/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Luk alle" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_notification_well_button.xml b/indra/newview/skins/default/xui/de/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0f2784f16075b7c5755531a17f562c0b79b334a7
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Alle schließen" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
index c9c52e5ce50eb37c0702fd742e4bf6d52a0ce856..256e03c4d7df22dd9b34b4bf974b5e129f81980c 100644
--- a/indra/newview/skins/default/xui/en/floater_conversation_log.xml
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -1,91 +1,86 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
 
 <floater
-  can_resize="true"
-  positioning="cascading"
-  height="400"
-  min_height="100"
-  min_width="390"
-  layout="topleft"
-  name="floater_conversation_log"
-  save_rect="true"
-  single_instance="true"
-  reuse_instance="true"
-  title="CONVERSATION LOG"
-  width="450">
-  
+ can_resize="true"
+ positioning="cascading"
+ height="200"
+ min_height="100"
+ min_width="230"
+ layout="topleft"
+ name="floater_conversation_log"
+ save_rect="true"
+ single_instance="true"
+ reuse_instance="true"
+ title="CONVERSATION LOG"
+ width="300">
   <string name="logging_calls_disabled">
      Conversations are not being logged. To log conversations in the future, select "Save IM logs on my computer" under Preferences > Privacy.
   </string>
-  
-	<panel
-      follows="left|top|right"
-      height="27"
-      layout="topleft"
-      left="0"
-      name="buttons_panel"
-      top="0">
-        <filter_editor
-          follows="left|top|right"
-          height="23"
-          layout="topleft"
-          left="8"
-          label="Filter People"
-          max_length_chars="300"
-          name="people_filter_input"
-          text_color="Black"
-          text_pad_left="10"
-          top="4"
-          width="364" />
-        <menu_button
-          follows="right"
-          height="25"
-          image_hover_unselected="Toolbar_Middle_Over"
-          image_overlay="Conv_toolbar_sort"
-          image_selected="Toolbar_Middle_Selected"
-          image_unselected="Toolbar_Middle_Off"
-          layout="topleft"
-          left_pad="5"
-          menu_filename="menu_conversation_log_view.xml"
-          menu_position="bottomleft"
-          name="conversation_view_btn"
-          tool_tip="View/sort options"
-          top="3"
-          width="31" />
-        <menu_button
-          follows="right"
-          height="25"
-          image_hover_unselected="Toolbar_Middle_Over"
-          image_overlay="OptionsMenu_Off"
-          image_selected="Toolbar_Middle_Selected"
-          image_unselected="Toolbar_Middle_Off"
-          layout="topleft"
-          left_pad="2"
-          name="conversations_gear_btn"
-          tool_tip="Actions on selected person or group"
-          top="3"
-          width="31" />
-    </panel>
-    <panel
-      follows="all"
-      height="370"
-      layout="topleft"
-      left="5"
-      name="buttons_panel"
-      right="-5"
-      top_pad="5">
+  <panel
+   follows="left|top|right"
+   height="32"
+   left="0"
+   name="buttons_panel"
+   top="0">
+    <filter_editor
+     follows="left|top|right"
+     height="23"
+     layout="topleft"
+     left="8"
+     label="Filter People"
+     max_length_chars="300"
+     name="people_filter_input"
+     text_color="Black"
+     text_pad_left="10"
+     top="4"
+     width="204" />
+    <menu_button
+     follows="top|right"
+     height="25"
+     image_hover_unselected="Toolbar_Middle_Over"
+     image_overlay="Conv_toolbar_sort"
+     image_selected="Toolbar_Middle_Selected"
+     image_unselected="Toolbar_Middle_Off"
+     layout="topleft"
+     left_pad="8"
+     menu_filename="menu_conversation_log_view.xml"
+     menu_position="bottomleft"
+     name="conversation_view_btn"
+     tool_tip="View/sort options"
+     top="3"
+     width="31" />
+    <menu_button
+     follows="top|right"
+     height="25"
+     image_hover_unselected="Toolbar_Middle_Over"
+     image_overlay="OptionsMenu_Off"
+     image_selected="Toolbar_Middle_Selected"
+     image_unselected="Toolbar_Middle_Off"
+     layout="topleft"
+     left_pad="8"
+     name="conversations_gear_btn"
+     tool_tip="Actions on selected person or group"
+     top="3"
+     width="31" />
+  </panel>
+  <panel
+   bottom="-1"
+   follows="all"
+   left="0"
+   name="log_panel"
+   right="-1"
+   top="32">
     <conversation_log_list
-      opaque="true"
-      allow_select="true"
-      follows="all"
-      height="360"
-      layout="topleft"
-      left="3"
-      keep_selection_visible_on_reshape="true"
-      item_pad="2"
-      multi_select="false"
-      name="conversation_log_list"
-      right="-3"
-      top="5" />
-    </panel>
+     allow_select="true"
+     bottom="-8"
+     opaque="true"
+     follows="all"
+     left="8"
+     keep_selection_visible_on_reshape="true"
+     item_pad="2"
+     multi_select="false"
+     name="conversation_log_list"
+     right="-8"
+     top="0" />
+  </panel>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_im_container.xml b/indra/newview/skins/default/xui/en/floater_im_container.xml
index 1128b8fef6d596ab603f0da6d3d6483936818f31..e7638fe6692db900ec9ec8cda0b93c4ad2d34b92 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -3,9 +3,8 @@
  can_close="true"  
  can_minimize="true"
  can_resize="true"
- height="230"
+ height="210"
  layout="topleft"
- min_height="50"
  name="floater_im_box"
  help_topic="floater_im_box"
  save_rect="true"
@@ -24,22 +23,20 @@
      value="Conv_toolbar_expand"/>
     <layout_stack
      animate="true" 
+     bottom="-1"
      follows="all"
-     height="230"
      layout="topleft"
      left="0"
      name="conversations_stack"
      orientation="horizontal"
-     top="0"
-     width="450">
+     right="-1"
+     top="0">
         <layout_panel
          auto_resize="false"
          user_resize="true"        
-         height="430"
          name="conversations_layout_panel"
          min_dim="38"
-         width="268"
-         expanded_min_dim="120">
+         expanded_min_dim="156">
             <layout_stack
              animate="false" 
              follows="left|top|right"
@@ -48,8 +45,8 @@
              left="0"
              name="conversations_pane_buttons_stack"
              orientation="horizontal"
-             top="0"
-             width="268">
+             right="-1"
+             top="0">
                 <layout_panel
                  auto_resize="true"
                  height="35"
@@ -109,46 +106,44 @@
                      image_unselected="Toolbar_Middle_Off"
                      layout="topleft"
                      top="5"
-                     left="5"
+                     left="1"
                      name="expand_collapse_btn"
                      tool_tip="Collapse/Expand this list"
                      width="31" />
                 </layout_panel>
             </layout_stack>
             <panel
+             bottom="-5"
              follows="all"
              layout="topleft"
              name="conversations_list_panel"
              opaque="true"
-             top_pad="0"
+             top="35"
              left="5"
-             height="390"
-             width="263"/>
+             right="-1"/>
         </layout_panel>
         <layout_panel
          auto_resize="true"
          user_resize="true"
-         height="430"
          name="messages_layout_panel"
-         width="412"
-         expanded_min_dim="225">
+         expanded_min_dim="222">
             <panel_container
+             bottom="-5"
              follows="all"
-             height="430"
              layout="topleft"
              left="0"
              name="im_box_tab_container"
-             top="0"
-             width="412">
+             right="-1"
+             top="0">
              <panel
+               bottom="-1"
                follows="all"
                layout="topleft"
                name="stub_panel"
                opaque="true"
                top_pad="0"
                left="0"
-               height="430"
-               width="412">
+               right="-1">
                  <button
                  follows="right|top"
                  height="25"
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index e4b127b7b93f5d2a3688880231a9f50ef2d0701b..8f0574177f3a97981505e2afbf31ae4a37fc8f8f 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -49,6 +49,15 @@
   <floater.string
      name="end_call_button_tooltip"
      value="Close voice connection"/>
+   <floater.string
+     name="expcol_button_not_tearoff_tooltip"
+     value="Collapse this pane"/>
+   <floater.string
+     name="expcol_button_tearoff_and_expanded_tooltip"
+     value="Collapse participant list"/>
+   <floater.string
+     name="expcol_button_tearoff_and_collapsed_tooltip"
+     value="Expand participant list"/>
     <view
         follows="all"
         layout="topleft"
@@ -79,6 +88,21 @@
                  tool_tip="View/sort options"
                  top="5"
                  width="31" />
+             <menu_button
+				 menu_filename="menu_im_conversation.xml"
+				 follows="top|left"
+				 height="25"
+				 image_hover_unselected="Toolbar_Middle_Over"
+				 image_overlay="OptionsMenu_Off"
+				 image_selected="Toolbar_Middle_Selected"
+				 image_unselected="Toolbar_Middle_Off"
+				 layout="topleft"
+			 	 top="5"
+			 	 left_pad="4"
+				 name="gear_btn"
+				 visible="false"
+				 tool_tip="Actions on selected person"
+				 width="31"/>
              <button
                  enabled="false"
                  follows="top|left"
@@ -191,7 +215,7 @@
        auto_resize="true"
        visible="true"
        name="left_part_holder"
-       min_width="225">
+       min_width="221">
         <panel
          name="trnsAndChat_panel"
          follows="all"
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
index e0edf384d64c6b379f966c4d7c278e5f7c8be4fc..46c6e19fa5ef3450d38f24dae27d3201025a10d0 100644
--- a/indra/newview/skins/default/xui/en/menu_conversation.xml
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -75,6 +75,13 @@
         <on_click function="Avatar.DoToSelected" parameter="remove_friend" />
         <on_enable function="Avatar.EnableItem" parameter="can_delete" />
     </menu_item_call>	
+    <menu_item_call
+     label="Remove friends"
+     layout="topleft"
+     name="remove_friends">
+        <on_click function="Avatar.DoToSelected" parameter="remove_friend" />
+        <on_enable function="Avatar.EnableItem" parameter="can_delete" />
+    </menu_item_call>	
     <menu_item_call
      label="Invite to group..."
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8882d0a7d8ed5ce8ff757c7c5dc6a698fe0b7d00
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Conversation Gear Menu">
+    <menu_item_call
+     label="View Profile"
+     layout="topleft"
+     name="View Profile">
+        <on_click function="Avatar.GearDoToSelected" parameter="view_profile" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_view_profile" />
+    </menu_item_call>
+    <menu_item_call
+     label="Add Friend"
+     layout="topleft"
+     name="Add Friend">
+        <on_click function="Avatar.GearDoToSelected" parameter="add_friend" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_add" />
+    </menu_item_call>
+    <menu_item_call
+     label="Remove friend"
+     layout="topleft"
+     name="remove_friend">
+        <on_click function="Avatar.GearDoToSelected" parameter="remove_friend" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_delete" />
+    </menu_item_call>
+    <menu_item_call
+     label="Offer teleport"
+     layout="topleft"
+     name="offer_teleport">
+        <on_click function="Avatar.GearDoToSelected" parameter="offer_teleport"/>
+        <on_enable function="Avatar.EnableGearItem" parameter="can_offer_teleport"/>
+    </menu_item_call>
+    <menu_item_call
+     label="Invite to group..."
+     layout="topleft"
+     name="invite_to_group">
+        <on_click function="Avatar.GearDoToSelected" parameter="invite_to_group" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_invite" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft"
+     name="View Icons Separator" />
+    <menu_item_call
+     label="Chat history..."
+     layout="topleft"
+     name="chat_history">
+        <on_click function="Avatar.GearDoToSelected" parameter="chat_history"/>
+        <on_enable function="Avatar.EnableGearItem" parameter="can_chat_history"/>
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft"/>
+    <menu_item_call
+     label="Map"
+     layout="topleft"
+     name="map">
+        <on_click function="Avatar.GearDoToSelected" parameter="map" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_show_on_map" />
+    </menu_item_call>
+    <menu_item_call
+     label="Share"
+     layout="topleft"
+     name="Share">
+        <on_click function="Avatar.GearDoToSelected" parameter="share" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_share" />
+    </menu_item_call>
+    <menu_item_call
+     label="Pay"
+     layout="topleft"
+     name="Pay">
+        <on_click function="Avatar.GearDoToSelected" parameter="pay" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_pay" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft"/>
+    <menu_item_check
+     label="Block Voice"
+     layout="topleft"
+     name="Block/Unblock">
+        <on_check function="Avatar.CheckGearItem" parameter="is_blocked" />
+        <on_click function="Avatar.GearDoToSelected" parameter="block_unblock" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_block" />
+    </menu_item_check>
+    <menu_item_check
+     label="Block Text"
+     layout="topleft"
+     name="MuteText">
+        <on_check function="Avatar.CheckGearItem" parameter="is_muted" />
+        <on_click function="Avatar.GearDoToSelected" parameter="mute_unmute" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_block" />
+    </menu_item_check>
+    <menu_item_separator
+     layout="topleft"/>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_notification_well_button.xml b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..263ac40f4eb7d2aa771d7f4695e3d99491ce965d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_notification_well_button.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Notification Well Button Context Menu">
+    <menu_item_call
+     label="Close All"
+     layout="topleft"
+     name="Close All">
+        <menu_item_call.on_click
+         function="NotificationWellChicletMenu.Action"
+         parameter="close all" />
+        <menu_item_call.on_enable
+         function="NotificationWellChicletMenu.EnableItem"
+         parameter="can close all" />
+    </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 3e7329c0b5d3ac2ea32c833c5ea1fb424db4875e..76de81559bda7b36946c09a59439839c947b651a 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -1267,7 +1267,58 @@
              function="Floater.Show"
              parameter="hud" />
         </menu_item_call>-->
-
+		<menu_item_separator/>
+		
+		<menu_item_call
+             label="User’s guide"
+             name="User’s guide">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-User-s-Guide/ta-p/1244857"/>
+        </menu_item_call>
+        <menu_item_call
+             label="Knowledge Base"
+             name="Knowledge Base">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://community.secondlife.com/t5/tkb/communitypage"/>
+        </menu_item_call>
+        <menu_item_call
+             label="Wiki"
+             name="Wiki">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://wiki.secondlife.com"/>
+        </menu_item_call>
+        <menu_item_call
+             label="Community Forums"
+             name="Community Forums">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://community.secondlife.com/t5/Forums/ct-p/Forums"/>
+        </menu_item_call>         
+        <menu_item_call
+             label="Support portal"
+             name="Support portal">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="https://support.secondlife.com/"/>         
+        </menu_item_call>
+        <menu_item_separator/>
+        <menu_item_call
+             label="[SECOND_LIFE] News"
+             name="Second Life News">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>  
+        </menu_item_call>
+        <menu_item_call
+             label="[SECOND_LIFE] Blogs"
+             name="Second Life Blogs">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/>
+        </menu_item_call>
         <menu_item_separator/>
 
         <menu_item_call
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 94307d2f93eebbef1857783ba8b73814ddf24181..05798da8e2c4e124a8018a2f15a432995a4cf2f7 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3696,7 +3696,6 @@ Do Not Disturb is on.  You will not be notified of incoming communications.
 - Other residents will receive your Do Not Disturb response (set in Preferences &gt; General).
 - Teleportation offers will be declined.
 - Voice calls will be rejected.
-- Inventory offers will go to your Trash.
     <usetemplate
      ignoretext="I change my status to Do Not Disturb mode"
      name="okignore"
@@ -6584,7 +6583,7 @@ However, this region contains content accessible to adults only.
    log_to_im="true"
    log_to_chat="false"
    show_toast="false"
-   type="offer">
+   type="notify">
 	Teleport offer sent to [TO_NAME]
   </notification>
 
@@ -6637,7 +6636,7 @@ However, this region contains content accessible to adults only.
    name="FriendshipOffered"
    log_to_im="true"   
    show_toast="false"   
-   type="offer">
+   type="notify">
     <tag>friendship</tag>
 	You have offered friendship to [TO_NAME]
   </notification>
@@ -6667,7 +6666,7 @@ However, this region contains content accessible to adults only.
    icon="notify.tga"
    name="FriendshipAccepted"
    log_to_im="true"   
-   type="offer">
+   type="notify">
     <tag>friendship</tag>
 &lt;nolink&gt;[NAME]&lt;/nolink&gt; accepted your friendship offer.
   </notification>
@@ -6687,7 +6686,7 @@ However, this region contains content accessible to adults only.
    name="FriendshipAcceptedByMe"
    log_to_im="true"   
    show_toast="false"
-   type="offer">
+   type="notify">
     <tag>friendship</tag>
 Friendship offer accepted.
   </notification>
@@ -6697,7 +6696,7 @@ Friendship offer accepted.
    name="FriendshipDeclinedByMe"
    log_to_im="true"   
    show_toast="false"   
-   type="offer">
+   type="notify">
     <tag>friendship</tag>
 Friendship offer declined.
   </notification>
diff --git a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
index 390047d493b814155b26fc5dcc3e16e4c45395b2..fc321fdd2355026ce7d936e8605af3a762ed3460 100644
--- a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
@@ -77,5 +77,49 @@
                  width="12" />
       </chiclet_panel>
     </layout_panel>
+    <layout_panel auto_resize="false"
+                      width="4"
+                      min_width="4"/>
+    <layout_panel
+         auto_resize="false"
+         follows="right"
+         height="28"
+         layout="topleft"
+         min_height="28"
+         min_width="37"
+         name="notification_well_panel"
+         top="0"
+         width="37">
+      <chiclet_notification
+             follows="right"
+             height="23"
+             layout="topleft"
+             left="0"
+             max_displayed_count="99"
+             name="notification_well"
+             top="5"
+             width="35">
+        <button
+                 auto_resize="false"
+                 bottom_pad="3"
+                 follows="right"
+                 halign="center"
+                 height="23"
+                 image_overlay="Notices_Unread"
+                 image_overlay_alignment="center"
+                 image_pressed="WellButton_Lit"
+                 image_pressed_selected="WellButton_Lit_Selected"
+                 image_selected="PushButton_Press"
+                 label_color="Black"
+                 left="0"
+                 name="Unread"
+                 tool_tip="Notifications"
+                 width="34">
+          <init_callback
+                     function="Button.SetDockableFloaterToggle"
+                     parameter="notification_well_window" />
+        </button>
+      </chiclet_notification>
+    </layout_panel>
   </layout_stack>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
index 053b213ef4dfc1927b837a4f84cf1c0df167ea8f..0ace37a5dc10685e052652f87dc6a56a4741a63b 100644
--- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
@@ -30,9 +30,9 @@
                         image_overlay_alignment="left"
                         use_ellipses="true"
                         auto_resize="true"
-                        button_flash_count="3"
-                        button_flash_rate="0.25"
-                        flash_color="EmphasisColor"/>
+                        button_flash_count="4"
+                        button_flash_rate="0.5"
+                        flash_color="BeaconColor"/>
   <button_icon pad_left="10"
                pad_right="10"
                image_bottom_pad="10"
@@ -51,7 +51,7 @@
                chrome="true"
                use_ellipses="true"
                auto_resize="true"
-               button_flash_count="3"
-               button_flash_rate="0.25"
-               flash_color="EmphasisColor"/>
+               button_flash_count="4"
+               button_flash_rate="0.5"
+               flash_color="BeaconColor"/>
 </toolbar>
diff --git a/indra/newview/skins/default/xui/es/menu_notification_well_button.xml b/indra/newview/skins/default/xui/es/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0562d35be72dc2054f0bd6f4c5a386c162ae1739
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Cerrar todo" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..323bfdbf165831da9cb17f451ec5c61eac895634
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Tout fermer" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/it/menu_notification_well_button.xml b/indra/newview/skins/default/xui/it/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8c82e30f0ed78c3240b284926d26556baa11b74d
--- /dev/null
+++ b/indra/newview/skins/default/xui/it/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Chiudi tutto" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..913bae89586f31ada4a7e5d8f47b99009a17f5dd
--- /dev/null
+++ b/indra/newview/skins/default/xui/ja/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="すべて閉じる" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..bd3d42f9b1facfeef347dcd3aeaaf36cbac0423e
--- /dev/null
+++ b/indra/newview/skins/default/xui/pl/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Zamknij" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml b/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..43ad4134ec114139c73a9e0831d9825c64b7f93a
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Fechar tudo" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml b/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4d067e232a95309abb5ceebe14dbfeef6476a603
--- /dev/null
+++ b/indra/newview/skins/default/xui/ru/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Закрыть все" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml b/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..39c66268f5300c843c042e3e9e38129e4767bcbe
--- /dev/null
+++ b/indra/newview/skins/default/xui/tr/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="Tümünü Kapat" name="Close All"/>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b629f735848ca9aa234d19469458a650b1e648a7
--- /dev/null
+++ b/indra/newview/skins/default/xui/zh/menu_notification_well_button.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<context_menu name="Notification Well Button Context Menu">
+	<menu_item_call label="全部關閉" name="Close All"/>
+</context_menu>