From f05df68656d2abdc38d86cd6746398fa90eb8614 Mon Sep 17 00:00:00 2001
From: Steven Bennetts <steve@lindenlab.com>
Date: Thu, 1 Oct 2009 17:44:44 +0000
Subject: [PATCH] merge
 https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0@1868
 https://svn.aws.productengine.com/secondlife/pe/stable-2@1876 ->
 viewer-2.0.0-3 * Bugs: EXT-1111 EXT-915 EXT-1131 EXT-1200 EXT-1202 EXT-1201
 EXT-1205 EXT-1212 EXT-1173 EXT-1229 EXT-1218 EXT-1164 EXT-996 EXT-821
 EXT-1030 EXT-1031 EXT-816 * Major Bugs: EXT-1142 (timeout during login due to
 processing group IMs) * Changes: EXT-1216 (minimize message well)

---
 indra/llui/CMakeLists.txt                     |   2 +
 indra/llui/lldockablefloater.cpp              |  18 +-
 indra/llui/lldockcontrol.cpp                  |  78 ++--
 indra/llui/lldockcontrol.h                    |  10 +-
 indra/llui/llflatlistview.cpp                 |   4 +-
 indra/llui/lltexteditor.cpp                   |  43 ++
 indra/llui/lltexteditor.h                     |  10 +-
 indra/newview/llavatarlist.cpp                | 136 ++++--
 indra/newview/llavatarlist.h                  |  25 +-
 indra/newview/llbottomtray.cpp                |   5 +-
 indra/newview/llchannelmanager.cpp            |  54 ++-
 indra/newview/llchannelmanager.h              |  16 +-
 indra/newview/llchatitemscontainerctrl.cpp    | 392 +++---------------
 indra/newview/llchatitemscontainerctrl.h      |  86 +---
 indra/newview/llchatmsgbox.cpp                |   2 +-
 indra/newview/llchiclet.cpp                   |  31 +-
 indra/newview/llchiclet.h                     |   3 +-
 indra/newview/llfavoritesbar.cpp              |  11 +
 indra/newview/llfavoritesbar.h                |   2 +-
 indra/newview/llfloaterchatterbox.cpp         |   3 +-
 indra/newview/llgrouplist.cpp                 |  49 ++-
 indra/newview/llgrouplist.h                   |  24 +-
 indra/newview/llimfloater.cpp                 |  73 ++--
 indra/newview/llimfloater.h                   |   6 +-
 indra/newview/llimhandler.cpp                 |   4 +-
 indra/newview/llimpanel.cpp                   |  87 +---
 indra/newview/llimpanel.h                     |   7 +-
 indra/newview/llimview.cpp                    | 246 +++++++++--
 indra/newview/llimview.h                      |  67 ++-
 indra/newview/llnearbychat.cpp                |  29 +-
 indra/newview/llnearbychat.h                  |   6 +-
 indra/newview/llnearbychathandler.cpp         | 242 ++++++++++-
 indra/newview/llnotificationalerthandler.cpp  |  13 +-
 indra/newview/llnotificationgrouphandler.cpp  |   5 +-
 indra/newview/llnotificationhandler.h         |   4 +-
 indra/newview/llnotificationscripthandler.cpp |  11 +-
 indra/newview/llnotificationtiphandler.cpp    |   5 +-
 indra/newview/llpanelavatar.cpp               |   2 +-
 indra/newview/llpanelgroup.cpp                |  15 +-
 indra/newview/llpanelgroupgeneral.cpp         |   2 +
 indra/newview/llpanelpeople.cpp               | 285 +++----------
 indra/newview/llpanelpeople.h                 |  27 +-
 indra/newview/llpanelpick.cpp                 |  47 ++-
 indra/newview/llpanelpick.h                   |   5 +
 indra/newview/llpanelpicks.cpp                |   7 +-
 indra/newview/llpanelpicks.h                  |   2 +-
 indra/newview/llpanelplaces.cpp               |  10 +-
 indra/newview/llpanelteleporthistory.cpp      |   8 +-
 indra/newview/llscreenchannel.cpp             |  74 +++-
 indra/newview/llscreenchannel.h               | 139 ++++---
 indra/newview/llsidetray.cpp                  |  10 +-
 indra/newview/llstatusbar.cpp                 |  17 +-
 indra/newview/llstatusbar.h                   |   4 +-
 indra/newview/llsyswellwindow.cpp             |  43 +-
 indra/newview/llsyswellwindow.h               |   6 +-
 indra/newview/lltoast.cpp                     |  19 +-
 indra/newview/lltoast.h                       |   3 +
 indra/newview/lltoastpanel.h                  |   6 +
 indra/newview/llviewermenu.cpp                |  13 +
 indra/newview/llviewermenu.h                  |   1 +
 indra/newview/llviewerwindow.cpp              |   6 +-
 .../skins/default/xui/en/floater_sys_well.xml |  12 +-
 .../skins/default/xui/en/menu_viewer.xml      |   4 +-
 .../skins/default/xui/en/panel_bottomtray.xml |   3 -
 .../xui/en/panel_group_info_sidetray.xml      |   3 +-
 .../default/xui/en/panel_nearby_chat_bar.xml  |   2 +
 .../skins/default/xui/en/panel_notes.xml      |   4 +-
 .../skins/default/xui/en/panel_picks.xml      |   4 +-
 .../skins/default/xui/en/panel_profile.xml    |   6 +-
 .../default/xui/en/panel_profile_view.xml     |   4 +-
 .../default/xui/en/panel_teleport_history.xml |   2 +-
 .../default/xui/en/widgets/scroll_list.xml    |   6 +-
 .../xui/en/widgets/search_combo_box.xml       |   5 +-
 73 files changed, 1467 insertions(+), 1148 deletions(-)

diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index d7d411dee65..0a284f0088b 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -85,6 +85,7 @@ set(llui_SOURCE_FILES
     lltextbox.cpp
     lltexteditor.cpp
     lltextparser.cpp
+    lltransientfloatermgr.cpp
     lltransutil.cpp
     lltooltip.cpp
     llui.cpp
@@ -171,6 +172,7 @@ set(llui_HEADER_FILES
     lltexteditor.h
     lltextparser.h
     lltooltip.h
+    lltransientfloatermgr.h
     lltransutil.h
     lluicolortable.h
     lluiconstants.h
diff --git a/indra/llui/lldockablefloater.cpp b/indra/llui/lldockablefloater.cpp
index 93d62fd7c2e..4525f0a45b4 100644
--- a/indra/llui/lldockablefloater.cpp
+++ b/indra/llui/lldockablefloater.cpp
@@ -71,9 +71,9 @@ void LLDockableFloater::resetInstance()
 		if (sInstanceHandle.get() != NULL && sInstanceHandle.get()->isDocked())
 		{
 			sInstanceHandle.get()->setVisible(FALSE);
-			}
+		}
 		sInstanceHandle = getHandle();
-			}
+	}
 }
 
 void LLDockableFloater::setVisible(BOOL visible)
@@ -105,11 +105,11 @@ void LLDockableFloater::setDocked(bool docked, bool pop_on_undock)
 			mDockControl.get()->off();
 		}
 
-	if (!docked && pop_on_undock)
-	{
-		// visually pop up a little bit to emphasize the undocking
-		translate(0, UNDOCK_LEAP_HEIGHT);
-	}
+		if (!docked && pop_on_undock)
+		{
+			// visually pop up a little bit to emphasize the undocking
+			translate(0, UNDOCK_LEAP_HEIGHT);
+		}
 	}
 	else
 	{
@@ -126,8 +126,8 @@ void LLDockableFloater::draw()
 		mDockControl.get()->repositionDockable();
 		if (isDocked())
 		{
-		mDockControl.get()->drawToungue();
-	}
+			mDockControl.get()->drawToungue();
+		}
 	}
 	LLFloater::draw();
 }
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index 0b16b2554c4..146c7a969a0 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -35,7 +35,7 @@
 #include "lldockcontrol.h"
 
 LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
-		const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback) :
+		const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
 		mDockWidget(dockWidget), mDockableFloater(dockableFloater), mDockTongue(dockTongue)		
 {
 	mDockAt = dockAt;
@@ -49,13 +49,13 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
 		off();
 	}
 
-	if (!(get_rect_callback))
+	if (!(get_allowed_rect_callback))
 	{
-		mGetRectCallback = boost::bind(&LLDockControl::getEnabledRect, this, _1);
+		mGetAllowedRectCallback = boost::bind(&LLDockControl::getAllowedRect, this, _1);
 	}
 	else
 	{
-		mGetRectCallback = get_rect_callback;
+		mGetAllowedRectCallback = get_allowed_rect_callback;
 	}
 
 	if (dockWidget != NULL) 
@@ -77,7 +77,7 @@ void LLDockControl::setDock(LLView* dockWidget)
 	}
 }
 
-void LLDockControl::getEnabledRect(LLRect& rect)
+void LLDockControl::getAllowedRect(LLRect& rect)
 {
 	rect = mDockableFloater->getRootView()->getRect();
 }
@@ -86,7 +86,7 @@ void LLDockControl::repositionDockable()
 {
 	LLRect dockRect = mDockWidget->calcScreenRect();
 	LLRect rootRect;
-	mGetRectCallback(rootRect);
+	mGetAllowedRectCallback(rootRect);
 	static BOOL prev_visibility = !mDockWidget->getVisible();
 
 	// recalculate dockable position if dock position changed, dock visibility changed,
@@ -100,7 +100,7 @@ void LLDockControl::repositionDockable()
 			mDockableFloater->setDocked(false);
 			// force off() since dockable may not have dockControll at this time
 			off();
-	}
+		}
 		else
 		{
 			moveDockable();
@@ -123,10 +123,10 @@ bool LLDockControl::isDockVisible()
 		res = mDockWidget->isInVisibleChain();
 		if (res)
 		{
-	LLRect dockRect = mDockWidget->calcScreenRect();
+			LLRect dockRect = mDockWidget->calcScreenRect();
 
 			switch (mDockAt)
-	{
+			{
 			case TOP:
 				// check is dock inside parent rect
 				LLRect dockParentRect =
@@ -149,25 +149,25 @@ void LLDockControl::moveDockable()
 	// calculate new dockable position
 	LLRect dockRect = mDockWidget->calcScreenRect();
 	LLRect rootRect;
-	mGetRectCallback(rootRect);
+	mGetAllowedRectCallback(rootRect);
 
-		LLRect dockableRect = mDockableFloater->calcScreenRect();
-		S32 x = 0;
-		S32 y = 0;
-		switch (mDockAt)
-		{
-		case TOP:
-			x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
+	LLRect dockableRect = mDockableFloater->calcScreenRect();
+	S32 x = 0;
+	S32 y = 0;
+	switch (mDockAt)
+	{
+	case TOP:
+		x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
 		y = dockRect.mTop + mDockTongue->getHeight() + dockableRect.getHeight();
 		// check is dockable inside root view rect
-			if (x < rootRect.mLeft)
-			{
-				x = rootRect.mLeft;
-			}
-			if (x + dockableRect.getWidth() > rootRect.mRight)
-			{
-				x = rootRect.mRight - dockableRect.getWidth();
-			}
+		if (x < rootRect.mLeft)
+		{
+			x = rootRect.mLeft;
+		}
+		if (x + dockableRect.getWidth() > rootRect.mRight)
+		{
+			x = rootRect.mRight - dockableRect.getWidth();
+		}
 
 
 		// calculate dock tongue position
@@ -185,21 +185,21 @@ void LLDockControl::moveDockable()
 		{
 			mDockTongueX = dockRect.getCenterX() - mDockTongue->getWidth() / 2;
 		}
-			mDockTongueY = dockRect.mTop;
+		mDockTongueY = dockRect.mTop;
 
-			break;
-		}
+		break;
+	}
 
 	// move dockable
-		dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
-				dockableRect.getHeight());
-		LLRect localDocableParentRect;
-		mDockableFloater->getParent()->screenRectToLocal(dockableRect,
-				&localDocableParentRect);
-		mDockableFloater->setRect(localDocableParentRect);
+	dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+			dockableRect.getHeight());
+	LLRect localDocableParentRect;
+	mDockableFloater->getParent()->screenRectToLocal(dockableRect,
+			&localDocableParentRect);
+	mDockableFloater->setRect(localDocableParentRect);
 
-		mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
-				&mDockTongueX, &mDockTongueY);
+	mDockableFloater->screenPointToLocal(mDockTongueX, mDockTongueY,
+			&mDockTongueX, &mDockTongueY);
 
 }
 
@@ -207,9 +207,9 @@ void LLDockControl::on()
 {
 	 if (isDockVisible())
 	{
-	mDockableFloater->setCanDrag(false);
-	mEnabled = true;
-	mRecalculateDocablePosition = true;
+		mDockableFloater->setCanDrag(false);
+		mEnabled = true;
+		mRecalculateDocablePosition = true;
 	}
 }
 
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index 219ddfd0925..e8ffcac0ac9 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -52,11 +52,11 @@ class LLDockControl
 
 public:
 	// callback for a function getting a rect valid for control's position
-	typedef boost::function<void (LLRect& )> get_rect_callback_t;
+	typedef boost::function<void (LLRect& )> get_allowed_rect_callback_t;
 
 	LOG_CLASS(LLDockControl);
 	LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
-			const LLUIImagePtr& dockTongue, DocAt dockAt, get_rect_callback_t get_rect_callback = NULL);
+			const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_rect_callback = NULL);
 	virtual ~LLDockControl();
 
 public:
@@ -67,13 +67,13 @@ class LLDockControl
 	void drawToungue();
 	bool isDockVisible();
 
-	// gets a rect that bounds possible positions for a dockable control
-	void getEnabledRect(LLRect& rect);
+	// gets a rect that bounds possible positions for a dockable control (EXT-1111)
+	void getAllowedRect(LLRect& rect);
 
 private:
 	virtual void moveDockable();
 private:
-	get_rect_callback_t mGetRectCallback;
+	get_allowed_rect_callback_t mGetAllowedRectCallback;
 	bool mEnabled;
 	bool mRecalculateDocablePosition;
 	DocAt mDockAt;
diff --git a/indra/llui/llflatlistview.cpp b/indra/llui/llflatlistview.cpp
index 9fcd386c193..e9df3614726 100644
--- a/indra/llui/llflatlistview.cpp
+++ b/indra/llui/llflatlistview.cpp
@@ -39,8 +39,8 @@
 
 static const LLDefaultChildRegistry::Register<LLFlatListView> flat_list_view("flat_list_view");
 
-const LLSD SELECTED_EVENT = LLSD().insert("selected", true);
-const LLSD UNSELECTED_EVENT = LLSD().insert("selected", false);
+const LLSD SELECTED_EVENT	= LLSD().insert("selected", true);
+const LLSD UNSELECTED_EVENT	= LLSD().insert("selected", false);
 
 static const std::string COMMENT_TEXTBOX = "comment_text";
 
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 8d5f277b59e..39f09b297f5 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2001,6 +2001,8 @@ void LLTextEditor::cut()
 	deleteSelection( FALSE );
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 BOOL LLTextEditor::canCopy() const
@@ -2105,6 +2107,8 @@ void LLTextEditor::pasteHelper(bool is_primary)
 	deselect();
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 
@@ -2492,6 +2496,8 @@ BOOL LLTextEditor::handleKeyHere(KEY key, MASK mask )
 		if(text_may_have_changed)
 		{
 			needsReflow();
+
+			onKeyStroke();
 		}
 		needsScroll();
 	}
@@ -2534,6 +2540,8 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
 		deselect();
 
 		needsReflow();
+
+		onKeyStroke();
 	}
 
 	return handled;
@@ -2588,6 +2596,8 @@ void LLTextEditor::doDelete()
 			setCursorPos(mCursorPos + 1);
 			removeChar();
 		}
+
+		onKeyStroke();
 	}
 
 	needsReflow();
@@ -2634,6 +2644,8 @@ void LLTextEditor::undo()
 		setCursorPos(pos);
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 BOOL LLTextEditor::canRedo() const
@@ -2676,6 +2688,8 @@ void LLTextEditor::redo()
 		setCursorPos(pos);
 
 	needsReflow();
+
+	onKeyStroke();
 }
 
 void LLTextEditor::onFocusReceived()
@@ -4402,6 +4416,8 @@ void LLTextEditor::updatePreedit(const LLWString &preedit_string,
 
 	// Update of the preedit should be caused by some key strokes.
 	mKeystrokeTimer.reset();
+
+	onKeyStroke();
 }
 
 BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect *bounds, LLRect *control) const
@@ -4648,3 +4664,30 @@ void LLInlineViewSegment::linkToDocument(LLTextBase* editor)
 		ed->addDocumentChild(mView);
 	}
 }
+
+BOOL LLTextEditor::isDirty() const
+{
+	if(mReadOnly)
+	{
+		return FALSE;
+	}
+
+	if( mPristineCmd )
+	{
+		return ( mPristineCmd == mLastCmd );
+	}
+	else
+	{
+		return ( NULL != mLastCmd );
+	}
+}
+
+void LLTextEditor::setKeystrokeCallback(const keystroke_signal_t::slot_type& callback)
+{
+	mKeystrokeSignal.connect(callback);
+}
+
+void LLTextEditor::onKeyStroke()
+{
+	mKeystrokeSignal(this);
+}
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 68b8f2c3b1b..a04261c4be9 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -139,6 +139,10 @@ class LLTextEditor :
 
 	virtual ~LLTextEditor();
 
+	typedef boost::signals2::signal<void (LLTextEditor* caller)> keystroke_signal_t;
+
+	void	setKeystrokeCallback(const keystroke_signal_t::slot_type& callback);
+
 	void	setParseHighlights(BOOL parsing) {mParseHighlights=parsing;}
 
 	// mousehandler overrides
@@ -169,7 +173,7 @@ class LLTextEditor :
 	virtual void	clear();
 	virtual void	setFocus( BOOL b );
 	virtual BOOL	acceptsTextInput() const;
-	virtual BOOL	isDirty() const { return isPristine(); }
+	virtual BOOL	isDirty() const;
 	virtual void 	setValue(const LLSD& value);
 
 	// LLEditMenuHandler interface
@@ -503,6 +507,8 @@ class LLTextEditor :
 
 	S32				getFirstVisibleLine() const;
 
+	void			onKeyStroke();
+
 	//
 	// Data
 	//
@@ -568,6 +574,8 @@ class LLTextEditor :
 	BOOL			mHandleEditKeysDirectly;  
 
 	LLCoordGL		mLastIMEPosition;		// Last position of the IME editor
+
+	keystroke_signal_t mKeystrokeSignal;
 }; // end class LLTextEditor
 
 
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index ee14a2ff865..36f9780ad0b 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -41,6 +41,10 @@
 
 static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
 
+// Maximum number of avatars that can be added to a list in one pass.
+// Used to limit time spent for avatar list update per frame.
+static const unsigned ADD_LIMIT = 50;
+
 static bool findInsensitive(std::string haystack, const std::string& needle_upper)
 {
     LLStringUtil::toUpper(haystack);
@@ -65,6 +69,7 @@ LLAvatarList::LLAvatarList(const Params& p)
 :	LLFlatListView(p)
 , mOnlineGoFirst(p.online_go_first)
 , mContextMenu(NULL)
+, mDirty(true) // to force initial update
 {
 	setCommitOnSelectionChange(true);
 
@@ -72,44 +77,40 @@ LLAvatarList::LLAvatarList(const Params& p)
 	setComparator(&NAME_COMPARATOR);
 }
 
-void LLAvatarList::computeDifference(
-	const std::vector<LLUUID>& vnew_unsorted,
-	std::vector<LLUUID>& vadded,
-	std::vector<LLUUID>& vremoved)
+// virtual
+void LLAvatarList::draw()
 {
-	std::vector<LLUUID> vcur;
-	std::vector<LLUUID> vnew = vnew_unsorted;
+	if (mDirty)
+		refresh();
 
-	// Convert LLSDs to LLUUIDs.
-	{
-		std::vector<LLSD> vcur_values;
-		getValues(vcur_values);
+	LLFlatListView::draw();
+}
 
-		for (size_t i=0; i<vcur_values.size(); i++)
-			vcur.push_back(vcur_values[i].asUUID());
+void LLAvatarList::setNameFilter(const std::string& filter)
+{
+	if (mNameFilter != filter)
+	{
+		mNameFilter = filter;
+		setDirty();
 	}
+}
 
-	std::sort(vcur.begin(), vcur.end());
-	std::sort(vnew.begin(), vnew.end());
-
-	std::vector<LLUUID>::iterator it;
-	size_t maxsize = llmax(vcur.size(), vnew.size());
-	vadded.resize(maxsize);
-	vremoved.resize(maxsize);
-
-	// what to remove
-	it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
-	vremoved.erase(it, vremoved.end());
-
-	// what to add
-	it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
-	vadded.erase(it, vadded.end());
+void LLAvatarList::sortByName()
+{
+	setComparator(&NAME_COMPARATOR);
+	sort();
 }
 
-BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::string& name_filter)
+//////////////////////////////////////////////////////////////////////////
+// PROTECTED SECTION
+//////////////////////////////////////////////////////////////////////////
+
+void LLAvatarList::refresh()
 {
-	BOOL have_names = TRUE;
-	bool have_filter = name_filter != LLStringUtil::null;
+	bool have_names			= TRUE;
+	bool add_limit_exceeded	= false;
+	bool modified			= false;
+	bool have_filter		= !mNameFilter.empty();
 
 	// Save selection.	
 	std::vector<LLUUID> selected_ids;
@@ -118,22 +119,36 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
 
 	// Determine what to add and what to remove.
 	std::vector<LLUUID> added, removed;
-	LLAvatarList::computeDifference(all_buddies, added, removed);
+	LLAvatarList::computeDifference(getIDs(), added, removed);
 
 	// Handle added items.
+	unsigned nadded = 0;
 	for (std::vector<LLUUID>::const_iterator it=added.begin(); it != added.end(); it++)
 	{
 		std::string name;
 		const LLUUID& buddy_id = *it;
-		have_names &= gCacheName->getFullName(buddy_id, name);
-		if (!have_filter || findInsensitive(name, name_filter))
-		addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+		have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+		if (!have_filter || findInsensitive(name, mNameFilter))
+		{
+			if (nadded >= ADD_LIMIT)
+			{
+				add_limit_exceeded = true;
+				break;
+			}
+			else
+			{
+				addNewItem(buddy_id, name, LLAvatarTracker::instance().isBuddyOnline(buddy_id));
+				modified = true;
+				nadded++;
+			}
+		}
 	}
 
 	// Handle removed items.
 	for (std::vector<LLUUID>::const_iterator it=removed.begin(); it != removed.end(); it++)
 	{
 		removeItemByUUID(*it);
+		modified = true;
 	}
 
 	// Handle filter.
@@ -146,9 +161,12 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
 		{
 			std::string name;
 			const LLUUID& buddy_id = it->asUUID();
-			have_names &= gCacheName->getFullName(buddy_id, name);
-			if (!findInsensitive(name, name_filter))
+			have_names &= (bool)gCacheName->getFullName(buddy_id, name);
+			if (!findInsensitive(name, mNameFilter))
+			{
 				removeItemByUUID(buddy_id);
+				modified = true;
+			}
 		}
 	}
 
@@ -167,18 +185,15 @@ BOOL LLAvatarList::update(const std::vector<LLUUID>& all_buddies, const std::str
 	//
 	// Otherwise, if we have no filter then no need to update again
 	// because the items will update their names.
-	return !have_filter || have_names;
-}
+	bool dirty = add_limit_exceeded || (have_filter && !have_names);
+	setDirty(dirty);
 
-void LLAvatarList::sortByName()
-{
-	setComparator(&NAME_COMPARATOR);
-	sort();
+	// Commit if we've added/removed items.
+	if (modified)
+		onCommit();
 }
 
-//////////////////////////////////////////////////////////////////////////
-// PROTECTED SECTION
-//////////////////////////////////////////////////////////////////////////
+
 void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos)
 {
 	LLAvatarListItem* item = new LLAvatarListItem();
@@ -194,8 +209,39 @@ void LLAvatarList::addNewItem(const LLUUID& id, const std::string& name, BOOL is
 	addItem(item, id, pos);
 }
 
+void LLAvatarList::computeDifference(
+	const std::vector<LLUUID>& vnew_unsorted,
+	std::vector<LLUUID>& vadded,
+	std::vector<LLUUID>& vremoved)
+{
+	std::vector<LLUUID> vcur;
+	std::vector<LLUUID> vnew = vnew_unsorted;
 
+	// Convert LLSDs to LLUUIDs.
+	{
+		std::vector<LLSD> vcur_values;
+		getValues(vcur_values);
 
+		for (size_t i=0; i<vcur_values.size(); i++)
+			vcur.push_back(vcur_values[i].asUUID());
+	}
+
+	std::sort(vcur.begin(), vcur.end());
+	std::sort(vnew.begin(), vnew.end());
+
+	std::vector<LLUUID>::iterator it;
+	size_t maxsize = llmax(vcur.size(), vnew.size());
+	vadded.resize(maxsize);
+	vremoved.resize(maxsize);
+
+	// what to remove
+	it = set_difference(vcur.begin(), vcur.end(), vnew.begin(), vnew.end(), vremoved.begin());
+	vremoved.erase(it, vremoved.end());
+
+	// what to add
+	it = set_difference(vnew.begin(), vnew.end(), vcur.begin(), vcur.end(), vadded.begin());
+	vadded.erase(it, vadded.end());
+}
 
 bool LLAvatarItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
 {
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 8d79e073d2c..ec801645feb 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -37,10 +37,22 @@
 
 #include "llavatarlistitem.h"
 
+/**
+ * Generic list of avatars.
+ * 
+ * Updates itself when it's dirty, using optional name filter.
+ * To initiate update, modify the UUID list and call setDirty().
+ * 
+ * @see getIDs()
+ * @see setDirty()
+ * @see setNameFilter()
+ */
 class LLAvatarList : public LLFlatListView
 {
 	LOG_CLASS(LLAvatarList);
 public:
+	typedef std::vector<LLUUID> uuid_vector_t;
+
 	struct Params : public LLInitParam::Block<Params, LLFlatListView::Params> 
 	{
 		Optional<S32> volume_column_width;
@@ -51,14 +63,19 @@ class LLAvatarList : public LLFlatListView
 	LLAvatarList(const Params&);
 	virtual	~LLAvatarList() {}
 
-	BOOL update(const std::vector<LLUUID>& all_buddies,
-		const std::string& name_filter = LLStringUtil::null);
+	virtual void draw(); // from LLView
+
+	void setNameFilter(const std::string& filter);
+	void setDirty(bool val = true)						{ mDirty = val; }
+	uuid_vector_t& getIDs() 							{ return mIDs; }
 
 	void setContextMenu(LLAvatarListItem::ContextMenu* menu) { mContextMenu = menu; }
 
 	void sortByName();
 
 protected:
+	void refresh();
+
 	void addNewItem(const LLUUID& id, const std::string& name, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
 	void computeDifference(
 		const std::vector<LLUUID>& vnew,
@@ -68,6 +85,10 @@ class LLAvatarList : public LLFlatListView
 private:
 
 	bool mOnlineGoFirst;
+	bool mDirty;
+
+	std::string				mNameFilter;
+	uuid_vector_t			mIDs;
 
 	LLAvatarListItem::ContextMenu* mContextMenu;
 };
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 46151b469f2..8771611b1c5 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -133,6 +133,7 @@ LLIMChiclet* LLBottomTray::createIMChiclet(const LLUUID& session_id)
 	case LLIMChiclet::TYPE_IM:
 		return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id);
 	case LLIMChiclet::TYPE_GROUP:
+	case LLIMChiclet::TYPE_AD_HOC:
 		return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id);
 	case LLIMChiclet::TYPE_UNKNOWN:
 		break;
@@ -231,7 +232,7 @@ void LLBottomTray::showBottomTrayContextMenu(S32 x, S32 y, MASK mask)
 			mBottomTrayContextMenu->updateParent(LLMenuGL::sMenuContainer);
 			LLMenuGL::showPopup(this, mBottomTrayContextMenu, x, y);
 		
-		}
+	}
 }
 
 void LLBottomTray::showGestureButton(BOOL visible)
@@ -243,7 +244,7 @@ void LLBottomTray::showGestureButton(BOOL visible)
 		mGestureCombo->setVisible(visible);
 
 		if (!visible)
-	{
+		{
 			LLFloaterReg::hideFloaterInstance("gestures");
 			r.mRight -= mGestureCombo->getRect().getWidth();
 		}
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 7ae99763382..b4b680416c8 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -77,7 +77,7 @@ LLScreenChannel* LLChannelManager::createNotificationChannel()
 	p.channel_align = CA_RIGHT;
 
 	// Getting a Channel for our notifications
-	return LLChannelManager::getInstance()->getChannel(p);
+	return dynamic_cast<LLScreenChannel*> (LLChannelManager::getInstance()->createChannel(p));
 }
 
 //--------------------------------------------------------------------------
@@ -113,7 +113,7 @@ void LLChannelManager::onLoginCompleted()
 	LLChannelManager::Params p;
 	p.id = LLUUID(gSavedSettings.getString("StartUpChannelUUID"));
 	p.channel_align = CA_RIGHT;
-	mStartUpChannel = getChannel(p);
+	mStartUpChannel = createChannel(p);
 
 	if(!mStartUpChannel)
 	{
@@ -147,22 +147,32 @@ void LLChannelManager::onStartUpToastClose()
 	LLScreenChannel::setStartUpToastShown();
 
 	// force NEARBY CHAT CHANNEL to repost all toasts if present
-	LLScreenChannel* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
-	nearby_channel->loadStoredToastsToChannel();
-	nearby_channel->setCanStoreToasts(false);
+	//LLScreenChannelBase* nearby_channel = findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+	//!!!!!!!!!!!!!!
+	//FIXME
+	//nearby_channel->loadStoredToastsToChannel();
+	//nearby_channel->setCanStoreToasts(false);
 }
 
 //--------------------------------------------------------------------------
-LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
+
+LLScreenChannelBase*	LLChannelManager::addChannel(LLScreenChannelBase* channel)
 {
-	LLScreenChannel* new_channel = NULL;
+	if(!channel)
+		return 0;
 
-	new_channel = findChannelByID(p.id);
+	ChannelElem new_elem;
+	new_elem.id = channel->getChannelID();
+	new_elem.channel = channel;
 
-	if(new_channel)
-		return new_channel;
+	mChannelList.push_back(new_elem); 
 
-	new_channel = new LLScreenChannel(p.id); 
+	return channel;
+}
+
+LLScreenChannel* LLChannelManager::createChannel(LLChannelManager::Params& p)
+{
+	LLScreenChannel* new_channel = new LLScreenChannel(p.id); 
 
 	if(!new_channel)
 	{
@@ -172,20 +182,26 @@ LLScreenChannel* LLChannelManager::getChannel(LLChannelManager::Params& p)
 	{
 		new_channel->setToastAlignment(p.toast_align);
 		new_channel->setChannelAlignment(p.channel_align);
-	new_channel->setDisplayToastsAlways(p.display_toasts_always);
-
-	ChannelElem new_elem;
-	new_elem.id = p.id;
-	new_elem.channel = new_channel;
+		new_channel->setDisplayToastsAlways(p.display_toasts_always);
 
-		mChannelList.push_back(new_elem); 
+		addChannel(new_channel);
 	}
-
 	return new_channel;
 }
 
+LLScreenChannelBase* LLChannelManager::getChannel(LLChannelManager::Params& p)
+{
+	LLScreenChannelBase* new_channel = findChannelByID(p.id);
+
+	if(new_channel)
+		return new_channel;
+
+	return createChannel(p);
+
+}
+
 //--------------------------------------------------------------------------
-LLScreenChannel* LLChannelManager::findChannelByID(const LLUUID id)
+LLScreenChannelBase* LLChannelManager::findChannelByID(const LLUUID id)
 {
 	std::vector<ChannelElem>::iterator it = find(mChannelList.begin(), mChannelList.end(), id); 
 	if(it != mChannelList.end())
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
index 811fa06d2b4..b927d369cd4 100644
--- a/indra/newview/llchannelmanager.h
+++ b/indra/newview/llchannelmanager.h
@@ -52,8 +52,8 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
 public:	
 	struct Params
 	{
-		LLUUID			id;
-		bool			display_toasts_always;
+		LLUUID				id;
+		bool				display_toasts_always;
 		EToastAlignment		toast_align;
 		EChannelAlignment	channel_align;
 
@@ -64,7 +64,7 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
 	struct ChannelElem
 	{
 		LLUUID				id;
-		LLScreenChannel*	channel;
+		LLScreenChannelBase*	channel;
 
 		ChannelElem() : id(LLUUID("")), channel(NULL) { }
 
@@ -89,19 +89,23 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
 	void onStartUpToastClose();
 
 	// creates a new ScreenChannel according to the given parameters or returns existing if present
-	LLScreenChannel*	getChannel(LLChannelManager::Params& p);
+	LLScreenChannelBase*	getChannel(LLChannelManager::Params& p);
+
+	LLScreenChannelBase*	addChannel(LLScreenChannelBase* channel);
 
 	// returns a channel by its ID
-	LLScreenChannel*	findChannelByID(const LLUUID id);
+	LLScreenChannelBase*	findChannelByID(const LLUUID id);
 
 	// creator of the Notification channel, that is used in more than one handler
-	LLScreenChannel*	createNotificationChannel();
+	LLScreenChannel*		createNotificationChannel();
 
 	// remove channel methods
 	void	removeChannelByID(const LLUUID id);
 
 private:
 
+	LLScreenChannel* createChannel(LLChannelManager::Params& p);
+
 	LLScreenChannel*			mStartUpChannel;
 	std::vector<ChannelElem>	mChannelList;
 };
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 6fb6552f2db..c2d7e0d9359 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -44,6 +44,7 @@
 #include "llviewercontrol.h"
 #include "llagentdata.h"
 
+/*
 static const S32 BORDER_MARGIN = 2;
 static const S32 PARENT_BORDER_MARGIN = 0;
 
@@ -53,33 +54,27 @@ static const F32 MIN_AUTO_SCROLL_RATE = 120.f;
 static const F32 MAX_AUTO_SCROLL_RATE = 500.f;
 static const F32 AUTO_SCROLL_RATE_ACCEL = 120.f;
 
-static const S32 msg_left_offset = 30;
-static const S32 msg_right_offset = 10;
-
 #define MAX_CHAT_HISTORY 100
+*/
 
+static const S32 msg_left_offset = 30;
+static const S32 msg_right_offset = 10;
 
-static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl>	t2("chat_items_container");
-
-
+//static LLDefaultChildRegistry::Register<LLChatItemsContainerCtrl>	t2("chat_items_container");
 
 //*******************************************************************************************************************
 //LLChatItemCtrl
 //*******************************************************************************************************************
 
-LLChatItemCtrl* LLChatItemCtrl::createInstance()
+LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance()
 {
-	LLChatItemCtrl* item = new LLChatItemCtrl();
+	LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel();
 	LLUICtrlFactory::getInstance()->buildPanel(item, "panel_chat_item.xml");
+	item->setFollows(FOLLOWS_NONE);
 	return item;
 }
 
-void	LLChatItemCtrl::draw()
-{
-	LLPanel::draw();
-}
-
-void	LLChatItemCtrl::reshape		(S32 width, S32 height, BOOL called_from_parent )
+void	LLNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_parent )
 {
 	LLPanel::reshape(width, height,called_from_parent);
 
@@ -101,13 +96,13 @@ void	LLChatItemCtrl::reshape		(S32 width, S32 height, BOOL called_from_parent )
 	}
 }
 
-BOOL LLChatItemCtrl::postBuild()
+BOOL LLNearbyChatToastPanel::postBuild()
 {
 	return LLPanel::postBuild();
 }
 
 
-std::string LLChatItemCtrl::appendTime()
+std::string LLNearbyChatToastPanel::appendTime()
 {
 	time_t utc_time;
 	utc_time = time_corrected();
@@ -124,48 +119,63 @@ std::string LLChatItemCtrl::appendTime()
 
 
 
-void	LLChatItemCtrl::addText		(const std::string& message)
+void	LLNearbyChatToastPanel::addText		(const std::string& message)
 {
 	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
 	msg_text->addText(message);
 	mMessages.push_back(message);
 }
 
-void	LLChatItemCtrl::setMessage	(const LLChat& msg)
+void LLNearbyChatToastPanel::init(LLSD& notification)
 {
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 
+	mText = notification["message"].asString();		// UTF-8 line of text
+	mFromName = notification["from"].asString();	// agent or object name
+	mFromID = notification["from_id"].asUUID();		// agent id or object id
+	int sType = notification["source"].asInteger();
+    mSourceType = (EChatSourceType)sType;
+
 	std::string str_sender;
 
-	
-	if(gAgentID != msg.mFromID)
-		str_sender = msg.mFromName;
+	if(gAgentID != mFromID)
+		str_sender = mFromName;
 	else
 		str_sender = LLTrans::getString("You");;
 
 	caption->getChild<LLTextBox>("sender_name", false)->setText(str_sender);
 	
-	std::string tt = appendTime();
-	
-	caption->getChild<LLTextBox>("msg_time", false)->setText(tt);
-
-
-	caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(msg.mFromID);
+	caption->getChild<LLTextBox>("msg_time", false)->setText(appendTime());
 
-	mOriginalMessage = msg;
 
 	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
-	msg_text->setText(msg.mText);
+	msg_text->setText(mText);
 
 	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
-	if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+	if(mSourceType != CHAT_SOURCE_AGENT)
 		msg_inspector->setVisible(false);
 
 	mMessages.clear();
 
+	snapToMessageHeight	();
+
+	mIsDirty = true;//will set Avatar Icon in draw
+}
+
+void	LLNearbyChatToastPanel::setMessage	(const LLChat& chat_msg)
+{
+	LLSD notification;
+	notification["message"] = chat_msg.mText;
+	notification["from"] = chat_msg.mFromName;
+	notification["from_id"] = chat_msg.mFromID;
+	notification["time"] = chat_msg.mTime;
+	notification["source"] = (S32)chat_msg.mSourceType;
+
+	init(notification);
+
 }
 
-void	LLChatItemCtrl::snapToMessageHeight	()
+void	LLNearbyChatToastPanel::snapToMessageHeight	()
 {
 	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
 	S32 new_height = text_box->getTextPixelHeight();
@@ -184,14 +194,14 @@ void	LLChatItemCtrl::snapToMessageHeight	()
 }
 
 
-void	LLChatItemCtrl::setWidth(S32 width)
+void	LLNearbyChatToastPanel::setWidth(S32 width)
 {
 	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
 	text_box->reshape(width - msg_left_offset - msg_right_offset,100/*its not magic number, we just need any number*/);
 
 	LLChatMsgBox* msg_text = getChild<LLChatMsgBox>("msg_text", false);
-	if(mOriginalMessage.mText.length())
-		msg_text->setText(mOriginalMessage.mText);
+	if(mText.length())
+		msg_text->setText(mText);
 	
 	for(size_t i=0;i<mMessages.size();++i)
 		msg_text->addText(mMessages[i]);
@@ -200,25 +210,25 @@ void	LLChatItemCtrl::setWidth(S32 width)
 	snapToMessageHeight	();
 }
 
-void LLChatItemCtrl::onMouseLeave			(S32 x, S32 y, MASK mask)
+void LLNearbyChatToastPanel::onMouseLeave			(S32 x, S32 y, MASK mask)
 {
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
 	msg_inspector->setVisible(false);
 	
 }
-void LLChatItemCtrl::onMouseEnter				(S32 x, S32 y, MASK mask)
+void LLNearbyChatToastPanel::onMouseEnter				(S32 x, S32 y, MASK mask)
 {
-	if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+	if(mSourceType != CHAT_SOURCE_AGENT)
 		return;
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
 	msg_inspector->setVisible(true);
 }
 
-BOOL	LLChatItemCtrl::handleMouseDown	(S32 x, S32 y, MASK mask)
+BOOL	LLNearbyChatToastPanel::handleMouseDown	(S32 x, S32 y, MASK mask)
 {
-	if(mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+	if(mSourceType != CHAT_SOURCE_AGENT)
 		return LLPanel::handleMouseDown(x,y,mask);
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 	LLUICtrl* msg_inspector = caption->getChild<LLUICtrl>("msg_inspector");
@@ -226,12 +236,16 @@ BOOL	LLChatItemCtrl::handleMouseDown	(S32 x, S32 y, MASK mask)
 	S32 local_y = y - msg_inspector->getRect().mBottom - caption->getRect().mBottom;
 	if(msg_inspector->pointInView(local_x, local_y))
 	{
-		LLFloaterReg::showInstance("inspect_avatar", mOriginalMessage.mFromID);
+		LLFloaterReg::showInstance("inspect_avatar", mFromID);
+	}
+	else
+	{
+		LLFloaterReg::showInstance("nearby_chat",LLSD());
 	}
 	return LLPanel::handleMouseDown(x,y,mask);
 }
 
-void	LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
+void	LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
 {
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 
@@ -243,7 +257,7 @@ void	LLChatItemCtrl::setHeaderVisibility(EShowItemHeader e)
 
 }
 
-bool	LLChatItemCtrl::canAddText	()
+bool	LLNearbyChatToastPanel::canAddText	()
 {
 	LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
 	if(!msg_text)
@@ -251,7 +265,7 @@ bool	LLChatItemCtrl::canAddText	()
 	return msg_text->getTextLinesNum()<10;
 }
 
-BOOL	LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+BOOL	LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	LLPanel* caption = getChild<LLPanel>("msg_caption", false);
 	LLUICtrl* avatar_icon = caption->getChild<LLUICtrl>("avatar_icon", false);
@@ -260,296 +274,20 @@ BOOL	LLChatItemCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
 	S32 local_y = y - avatar_icon->getRect().mBottom - caption->getRect().mBottom;
 
 	//eat message for avatar icon if msg was from object
-	if(avatar_icon->pointInView(local_x, local_y) && mOriginalMessage.mSourceType != CHAT_SOURCE_AGENT)
+	if(avatar_icon->pointInView(local_x, local_y) && mSourceType != CHAT_SOURCE_AGENT)
 		return TRUE;
 	return LLPanel::handleRightMouseDown(x,y,mask);
 }
-
-
-//*******************************************************************************************************************
-//LLChatItemsContainerCtrl
-//*******************************************************************************************************************
-
-LLChatItemsContainerCtrl::LLChatItemsContainerCtrl(const Params& params):LLPanel(params)
-{
-	mEShowItemHeader = CHATITEMHEADER_SHOW_BOTH;
-}
-
-
-void	LLChatItemsContainerCtrl::addMessage(const LLChat& msg)
-{
-	/*
-	if(msg.mChatType == CHAT_TYPE_DEBUG_MSG)
-		return;
-	*/
-	if(mItems.size() >= MAX_CHAT_HISTORY)
-	{
-		LLChatItemCtrl* item = mItems[0];
-		removeChild(item);
-		delete item;
-		mItems.erase(mItems.begin());
-	}
-
-	
-	if(mItems.size() > 0 
-		&& msg.mFromID == mItems[mItems.size()-1]->getMessage().mFromID 
-		&& (msg.mTime-mItems[mItems.size()-1]->getMessage().mTime)<60
-		&& mItems[mItems.size()-1]->canAddText()
-		)
-	{
-		mItems[mItems.size()-1]->addText(msg.mText);
-		mItems[mItems.size()-1]->snapToMessageHeight();
-	}
-	else
-	{
-		LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
-		mItems.push_back(item);
-		addChild(item,0);
-		item->setWidth(getRect().getWidth() - 16);
-		item->setMessage(msg);
-		item->snapToMessageHeight();
-		
-		item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
-
-		item->setVisible(true);
-	}
-
-	arrange(getRect().getWidth(),getRect().getHeight());
-	updateLayout(getRect().getWidth(),getRect().getHeight());
-	scrollToBottom();
-}
-
-void	LLChatItemsContainerCtrl::scrollToBottom	()
-{
-	if(mScrollbar->getVisible())
-	{
-		mScrollbar->setDocPos(mScrollbar->getDocPosMax());
-		onScrollPosChangeCallback(0,0);
-	}
-}
-
-void	LLChatItemsContainerCtrl::draw()
-{
-	LLLocalClipRect clip(getRect());
-	LLPanel::draw();
-}
-
-void	LLChatItemsContainerCtrl::reshape					(S32 width, S32 height, BOOL called_from_parent )
-{
-	S32 delta_width = width - getRect().getWidth();
-	S32 delta_height = height - getRect().getHeight();
-
-	if (delta_width || delta_height || sForceReshape)
-	{
-		arrange(width, height);
-	}
-
-	updateBoundingRect();
-}
-
-void	LLChatItemsContainerCtrl::arrange					(S32 width, S32 height)
+void LLNearbyChatToastPanel::draw()
 {
-	S32 delta_width = width - getRect().getWidth();
-	if(delta_width)//width changed...too bad. now we need to reformat all items
-		reformatHistoryScrollItems(width);
-
-	calcRecuiredHeight();
-
-	show_hide_scrollbar(width,height);
-
-	updateLayout(width,height);
-}
-
-void	LLChatItemsContainerCtrl::reformatHistoryScrollItems(S32 width)
-{
-	for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
-	{
-		(*it)->setWidth(width);
-	}
-}
-
-S32		LLChatItemsContainerCtrl::calcRecuiredHeight	()
-{
-	S32 rec_height = 0;
-	
-	std::vector<LLChatItemCtrl*>::iterator it;
-	for(it=mItems.begin(); it!=mItems.end(); ++it)
-	{
-		rec_height += (*it)->getRect().getHeight();
-	}
-
-	mInnerRect.setLeftTopAndSize(0,rec_height + BORDER_MARGIN*2,getRect().getWidth(),rec_height + BORDER_MARGIN);
-
-	return mInnerRect.getHeight();
-}
-
-
-void	LLChatItemsContainerCtrl::updateLayout				(S32 width, S32 height)
-{
-	S32 panel_top = height - BORDER_MARGIN ;
-	S32 panel_width = width;
-	if(mScrollbar->getVisible())
-	{
-		static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-		
-		panel_top+=mScrollbar->getDocPos();
-		panel_width-=scrollbar_size;
-	}
-
-
-	//set sizes for first panels and dragbars
-	for(size_t i=0;i<mItems.size();++i)
-	{
-		LLRect panel_rect = mItems[i]->getRect();
-		panelSetLeftTopAndSize(mItems[i],panel_rect.mLeft,panel_top,panel_width,panel_rect.getHeight());
-		panel_top-=panel_rect.getHeight();
-	}
-}
-
-void	LLChatItemsContainerCtrl::show_hide_scrollbar		(S32 width, S32 height)
-{
-	calcRecuiredHeight();
-	if(getRecuiredHeight() > height )
-		showScrollbar(width, height);
-	else
-		hideScrollbar(width, height);
-}
-
-void	LLChatItemsContainerCtrl::showScrollbar			(S32 width, S32 height)
-{
-	bool was_visible = mScrollbar->getVisible();
-
-	mScrollbar->setVisible(true);
-
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-	
-	panelSetLeftTopAndSize(mScrollbar,width-scrollbar_size
-		,height-PARENT_BORDER_MARGIN,scrollbar_size,height-2*PARENT_BORDER_MARGIN);
-	
-	mScrollbar->setPageSize(height);
-	mScrollbar->setDocParams(mInnerRect.getHeight(),mScrollbar->getDocPos());
-
-	if(was_visible)
-	{
-		S32 scroll_pos = llmin(mScrollbar->getDocPos(), getRecuiredHeight() - height - 1);
-		mScrollbar->setDocPos(scroll_pos);
-		updateLayout(width,height);
-		return;
-	}
-}
-
-void	LLChatItemsContainerCtrl::hideScrollbar			(S32 width, S32 height)
-{
-	if(mScrollbar->getVisible() == false)
-		return;
-	mScrollbar->setVisible(false);
-
-	mScrollbar->setDocPos(0);
-
-	if(mItems.size()>0)
-	{
-		S32 panel_top = height - BORDER_MARGIN;		  // Top coordinate of the first panel
-		S32 diff = panel_top - mItems[0]->getRect().mTop;
-		shiftPanels(diff);
-	}
-}
-
-//---------------------------------------------------------------------------------
-void LLChatItemsContainerCtrl::panelSetLeftTopAndSize(LLView* panel, S32 left, S32 top, S32 width, S32 height)
-{
-	if(!panel)
-		return;
-	LLRect panel_rect = panel->getRect();
-	panel_rect.setLeftTopAndSize( left, top, width, height);
-	panel->reshape( width, height, 1);
-	panel->setRect(panel_rect);
-}
-
-void LLChatItemsContainerCtrl::panelShiftVertical(LLView* panel,S32 delta)
-{
-	if(!panel)
-		return;
-	panel->translate(0,delta);
-}
-
-void LLChatItemsContainerCtrl::shiftPanels(S32 delta)
-{
-	//Arrange panels
-	for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
-	{
-		panelShiftVertical((*it),delta);
-	}	
-
-}
-
-//---------------------------------------------------------------------------------
-
-void	LLChatItemsContainerCtrl::onScrollPosChangeCallback(S32, LLScrollbar*)
-{
-	updateLayout(getRect().getWidth(),getRect().getHeight());
-}
-
-BOOL LLChatItemsContainerCtrl::postBuild()
-{
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
-
-	LLRect scroll_rect;
-	scroll_rect.setOriginAndSize( 
-		getRect().getWidth() - scrollbar_size,
-		1,
-		scrollbar_size,
-		getRect().getHeight() - 1);
-	
-
-	LLScrollbar::Params sbparams;
-	sbparams.name("scrollable vertical");
-	sbparams.rect(scroll_rect);
-	sbparams.orientation(LLScrollbar::VERTICAL);
-	sbparams.doc_size(mInnerRect.getHeight());
-	sbparams.doc_pos(0);
-	sbparams.page_size(mInnerRect.getHeight());
-	sbparams.step_size(VERTICAL_MULTIPLE);
-	sbparams.follows.flags(FOLLOWS_RIGHT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
-	sbparams.change_callback(boost::bind(&LLChatItemsContainerCtrl::onScrollPosChangeCallback, this, _1, _2));
-	
-	mScrollbar = LLUICtrlFactory::create<LLScrollbar> (sbparams);
-	LLView::addChild( mScrollbar );
-	mScrollbar->setVisible( true );
-	mScrollbar->setFollowsRight();
-	mScrollbar->setFollowsTop();
-	mScrollbar->setFollowsBottom();
-
-	reformatHistoryScrollItems(getRect().getWidth());
-	arrange(getRect().getWidth(),getRect().getHeight());
-
-	return LLPanel::postBuild();
-}
-BOOL	LLChatItemsContainerCtrl::handleMouseDown	(S32 x, S32 y, MASK mask)
-{
-	return LLPanel::handleMouseDown(x,y,mask);
-}
-BOOL LLChatItemsContainerCtrl::handleKeyHere			(KEY key, MASK mask)
-{
-	if( mScrollbar->getVisible() && mScrollbar->handleKeyHere( key,mask ) )
-		return TRUE;
-	return LLPanel::handleKeyHere(key,mask);
-}
-BOOL LLChatItemsContainerCtrl::handleScrollWheel		( S32 x, S32 y, S32 clicks )
-{
-	if( mScrollbar->getVisible() && mScrollbar->handleScrollWheel( 0, 0, clicks ) )
-		return TRUE;
-	return false;
-}
-
-void	LLChatItemsContainerCtrl::setHeaderVisibility(EShowItemHeader e)
-{
-	if(e == mEShowItemHeader)
-		return;
-	mEShowItemHeader = e;
-	for(std::vector<LLChatItemCtrl*>::iterator it = mItems.begin(); it != mItems.end();++it)
+	if(mIsDirty)
 	{
-		(*it)->setHeaderVisibility(e);
+		LLPanel* caption = findChild<LLPanel>("msg_caption", false);
+		if(caption)
+			caption->getChild<LLAvatarIconCtrl>("avatar_icon", false)->setValue(mFromID);
+		mIsDirty = false;
 	}
+	LLToastPanelBase::draw();
 }
 
 
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
index de16cf9505c..8fb045b6d91 100644
--- a/indra/newview/llchatitemscontainerctrl.h
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -37,6 +37,7 @@
 #include "llscrollbar.h"
 #include "string"
 #include "llchat.h"
+#include "lltoastpanel.h"
 
 typedef enum e_show_item_header
 {
@@ -45,20 +46,18 @@ typedef enum e_show_item_header
 	CHATITEMHEADER_SHOW_BOTH
 } EShowItemHeader;
 
-class LLChatItemCtrl: public LLPanel
+class LLNearbyChatToastPanel: public LLToastPanelBase
 {
 protected:
-	LLChatItemCtrl(){};
+	LLNearbyChatToastPanel():mIsDirty(false){};
 public:
 	
 
-	~LLChatItemCtrl(){}
+	~LLNearbyChatToastPanel(){}
 	
-	static LLChatItemCtrl* createInstance();
+	static LLNearbyChatToastPanel* createInstance();
 
-	void	draw();
-
-	const LLChat& getMessage() const { return mOriginalMessage;}
+	const LLUUID& getFromID() const { return mFromID;}
 	
 	void	addText		(const std::string& message);
 	void	setMessage	(const LLChat& msg);
@@ -77,78 +76,27 @@ class LLChatItemCtrl: public LLPanel
 
 	void	setHeaderVisibility(EShowItemHeader e);
 	BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);
-private:
-	
-	std::string appendTime	();
-
-private:
-	LLChat mOriginalMessage;
-
-	std::vector<std::string> mMessages;
-};
-
-class LLChatItemsContainerCtrl: public LLPanel
-{
-public:
-	struct Params 
-	:	public LLInitParam::Block<Params, LLPanel::Params>
-	{
-		Params(){};
-	};
-
-	LLChatItemsContainerCtrl(const Params& params);
-
-
-	~LLChatItemsContainerCtrl(){}
-
-	void	addMessage	(const LLChat& msg);
-
-	void	draw();
-
-	void	reshape					(S32 width, S32 height, BOOL called_from_parent = TRUE);
-
-	void	onScrollPosChangeCallback(S32, LLScrollbar*);
-
-	virtual BOOL postBuild();
-
-	BOOL	handleMouseDown	(S32 x, S32 y, MASK mask);
-	BOOL	handleKeyHere	(KEY key, MASK mask);
-	BOOL	handleScrollWheel( S32 x, S32 y, S32 clicks );
-
-	void	scrollToBottom	();
-
-	void	setHeaderVisibility(EShowItemHeader e);
-	EShowItemHeader	getHeaderVisibility() const { return mEShowItemHeader;};
 
+	virtual void init(LLSD& data);
 
+	virtual void draw();
 private:
-	void	reformatHistoryScrollItems(S32 width);
-	void	arrange					(S32 width, S32 height);
-
-	S32		calcRecuiredHeight		();
-	S32		getRecuiredHeight		() const { return mInnerRect.getHeight(); }
-
-	void	updateLayout			(S32 width, S32 height);
-
-	void	show_hide_scrollbar		(S32 width, S32 height);
-
-	void	showScrollbar			(S32 width, S32 height);
-	void	hideScrollbar			(S32 width, S32 height);
-
-	void	panelSetLeftTopAndSize	(LLView* panel, S32 left, S32 top, S32 width, S32 height);
-	void	panelShiftVertical		(LLView* panel,S32 delta);
-	void	shiftPanels				(S32 delta);
+	
+	std::string appendTime	();
 
 private:
-	std::vector<LLChatItemCtrl*> mItems;
+	std::string		mText;		// UTF-8 line of text
+	std::string		mFromName;	// agent or object name
+	LLUUID			mFromID;	// agent id or object id
+	EChatSourceType	mSourceType;
 
-	EShowItemHeader mEShowItemHeader;
 
-	LLRect			mInnerRect;
-	LLScrollbar*	mScrollbar;
+	std::vector<std::string> mMessages;
 
+	bool mIsDirty;
 };
 
+
 #endif
 
 
diff --git a/indra/newview/llchatmsgbox.cpp b/indra/newview/llchatmsgbox.cpp
index e6398dd47ab..bd0c36b44a2 100644
--- a/indra/newview/llchatmsgbox.cpp
+++ b/indra/newview/llchatmsgbox.cpp
@@ -102,7 +102,7 @@ void LLChatMsgBox::drawText(S32 x, S32 y, const LLWString &text, const LLColor4
 
 	// iterate through each block of text that has been added
 	y -= mLineSpacing;
-	for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); true ;)
+	for (std::vector<S32>::iterator it = mSeparatorOffset.begin(); it != mSeparatorOffset.end() ;)
 	{
 		// display the text for this block
 		S32 num_chars = *it - start;
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 20c44d5b114..98e492cadae 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -49,6 +49,7 @@
 #include "llvoicecontrolpanel.h"
 #include "llgroupmgr.h"
 #include "llnotificationmanager.h"
+#include "lltransientfloatermgr.h"
 
 static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
 static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");
@@ -243,26 +244,36 @@ void LLIMChiclet::draw()
 LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id)
 {
 	EType				type	= TYPE_UNKNOWN;
-	LLFloaterIMPanel*	im		= NULL;
 
 	if(session_id.isNull())
 		return type;
 
-	if (!(im = LLIMMgr::getInstance()->findFloaterBySession(session_id)))
+	EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id);
+	if (IM_COUNT == im_type)
 	{
 		llassert_always(0 && "IM session not found"); // should never happen
 		return type;
 	}
 
-	switch(im->getDialogType())
+	switch(im_type)
 	{
 	case IM_NOTHING_SPECIAL:
+	case IM_SESSION_P2P_INVITE:
 		type = TYPE_IM;
 		break;
 	case IM_SESSION_GROUP_START:
 	case IM_SESSION_INVITE:
-		type = TYPE_GROUP;
+		if (gAgent.isInGroup(session_id))
+		{
+			type = TYPE_GROUP;
+		}
+		else
+		{
+			type = TYPE_AD_HOC;
+		}
 		break;
+	case IM_SESSION_CONFERENCE_START:
+		type = TYPE_AD_HOC;
 	default:
 		break;
 	}
@@ -285,6 +296,11 @@ LLIMP2PChiclet::Params::Params()
 
 	avatar_icon.name("avatar_icon");
 	avatar_icon.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP | FOLLOWS_BOTTOM);
+
+	// *NOTE dzaporozhan
+	// Changed icon height from 25 to 24 to fix ticket EXT-794.
+	// In some cases(after changing UI scale) 25 pixel height icon was 
+	// drawn incorrectly, i'm not sure why.
 	avatar_icon.rect(LLRect(0, 24, 25, 0));
 	avatar_icon.mouse_opaque(false);
 
@@ -458,6 +474,11 @@ LLIMGroupChiclet::Params::Params()
 	rect(LLRect(0, 25, 45, 0));
 
 	group_icon.name("group_icon");
+	
+	// *NOTE dzaporozhan
+	// Changed icon height from 25 to 24 to fix ticket EXT-794.
+	// In some cases(after changing UI scale) 25 pixel height icon was 
+	// drawn incorrectly, i'm not sure why.
 	group_icon.rect(LLRect(0, 24, 25, 0));
 
 	unread_notifications.name("unread");
@@ -1164,6 +1185,7 @@ LLTalkButton::LLTalkButton(const Params& p)
 	speak_params.rect(speak_rect);
 	mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);
 	addChild(mSpeakBtn);
+	LLTransientFloaterMgr::getInstance()->addControlView(mSpeakBtn);
 
 	mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this));
 	mSpeakBtn->setToggleState(FALSE);
@@ -1172,6 +1194,7 @@ LLTalkButton::LLTalkButton(const Params& p)
 	show_params.rect(show_rect);
 	mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
 	addChild(mShowBtn);
+	LLTransientFloaterMgr::getInstance()->addControlView(mShowBtn);
 
 	mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this));
 	mShowBtn->setToggleState(FALSE);
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 316348cf1d4..ef47b543331 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -275,7 +275,8 @@ class LLIMChiclet : public LLChiclet
 	enum EType {
 		TYPE_UNKNOWN,
 		TYPE_IM,
-		TYPE_GROUP
+		TYPE_GROUP,
+		TYPE_AD_HOC
 	};
 	
 	/*virtual*/ ~LLIMChiclet() {};
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 6b18984f885..ea947a55656 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -934,6 +934,17 @@ void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S
 	LLMenuGL::showPopup(fav_button, menu, x, y);
 }
 
+BOOL LLFavoritesBarCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	BOOL handled = childrenHandleRightMouseDown( x, y, mask) != NULL;
+	if(!handled && !gMenuHolder->hasVisibleMenu())
+	{
+		show_navbar_context_menu(this,x,y);
+		handled = true;
+	}
+	
+	return handled;
+}
 void copy_slurl_to_clipboard_cb(std::string& slurl)
 {
 	gClipboard.copyFromString(utf8str_to_wstring(slurl));
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 0be8de29a96..97117c3b4a0 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -62,7 +62,7 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 								   std::string& tooltip_msg);
 
 	/*virtual*/ BOOL	handleHover(S32 x, S32 y, MASK mask);
-
+	/*virtual*/ BOOL	handleRightMouseDown(S32 x, S32 y, MASK mask);
 	// LLInventoryObserver observer trigger
 	virtual void changed(U32 mask);
 	virtual void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
diff --git a/indra/newview/llfloaterchatterbox.cpp b/indra/newview/llfloaterchatterbox.cpp
index 05ea800d0ef..dea656b0e49 100644
--- a/indra/newview/llfloaterchatterbox.cpp
+++ b/indra/newview/llfloaterchatterbox.cpp
@@ -363,7 +363,8 @@ LLFloater* LLFloaterChatterBox::getCurrentVoiceFloater()
 			{
 				// only LLFloaterIMPanels are called "im_floater"
 				LLFloaterIMPanel* im_floaterp = (LLFloaterIMPanel*)panelp;
-				if (im_floaterp->getVoiceChannel()  == LLVoiceChannel::getCurrentVoiceChannel())
+				LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(im_floaterp->getSessionID());
+				if (voice_channel  == LLVoiceChannel::getCurrentVoiceChannel())
 				{
 					return im_floaterp;
 				}
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index d3b013237ba..905857f393d 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -73,7 +73,11 @@ LLGroupList::Params::Params()
 
 LLGroupList::LLGroupList(const Params& p)
 :	LLFlatListView(p)
+	, mDirty(true) // to force initial update
 {
+	// Listen for agent group changes.
+	gAgent.addListener(this, "new group");
+
 	mShowIcons = gSavedSettings.getBOOL("GroupListShowIcons");
 	setCommitOnSelectionChange(true);
 	// TODO: implement context menu
@@ -84,17 +88,41 @@ LLGroupList::LLGroupList(const Params& p)
 	setComparator(&GROUP_COMPARATOR);
 }
 
+LLGroupList::~LLGroupList()
+{
+	gAgent.removeListener(this);
+}
+
+// virtual
+void LLGroupList::draw()
+{
+	if (mDirty)
+		refresh();
+
+	LLFlatListView::draw();
+}
+
+void LLGroupList::setNameFilter(const std::string& filter)
+{
+	if (mNameFilter != filter)
+	{
+		mNameFilter = filter;
+		setDirty();
+	}
+}
+
 static bool findInsensitive(std::string haystack, const std::string& needle_upper)
 {
     LLStringUtil::toUpper(haystack);
     return haystack.find(needle_upper) != std::string::npos;
 }
 
-BOOL LLGroupList::update(const std::string& name_filter)
+void LLGroupList::refresh()
 {
 	const LLUUID& 		highlight_id	= gAgent.getGroupID();
 	S32					count			= gAgent.mGroups.count();
 	LLUUID				id;
+	bool				have_filter		= !mNameFilter.empty();
 
 	clear();
 
@@ -102,7 +130,7 @@ BOOL LLGroupList::update(const std::string& name_filter)
 	{
 		id = gAgent.mGroups.get(i).mID;
 		const LLGroupData& group_data = gAgent.mGroups.get(i);
-		if (name_filter != LLStringUtil::null && !findInsensitive(group_data.mName, name_filter))
+		if (have_filter && !findInsensitive(group_data.mName, mNameFilter))
 			continue;
 		addNewItem(id, group_data.mName, group_data.mInsigniaID, highlight_id == id, ADD_BOTTOM);
 	}
@@ -113,13 +141,14 @@ BOOL LLGroupList::update(const std::string& name_filter)
 	// add "none" to list at top
 	{
 		std::string loc_none = LLTrans::getString("GroupsNone");
-		if (name_filter == LLStringUtil::null || findInsensitive(loc_none, name_filter))
+		if (have_filter || findInsensitive(loc_none, mNameFilter))
 			addNewItem(LLUUID::null, loc_none, LLUUID::null, highlight_id.isNull(), ADD_TOP);
 	}
 
 	selectItemByUUID(highlight_id);
 
-	return TRUE;
+	setDirty(false);
+	onCommit();
 }
 
 void LLGroupList::toggleIcons()
@@ -158,6 +187,18 @@ void LLGroupList::addNewItem(const LLUUID& id, const std::string& name, const LL
 //	setCommentVisible(false);
 }
 
+// virtual
+bool LLGroupList::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+	// Why is "new group" sufficient?
+	if (event->desc() == "new group")
+	{
+		setDirty();
+		return true;
+	}
+
+	return false;
+}
 
 /************************************************************************/
 /*          LLGroupListItem implementation                              */
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 7708b58de68..9c3ab88901b 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -33,10 +33,19 @@
 #ifndef LL_LLGROUPLIST_H
 #define LL_LLGROUPLIST_H
 
+#include "llevent.h"
 #include "llflatlistview.h"
 #include "llpanel.h"
+#include "llpointer.h"
 
-class LLGroupList: public LLFlatListView
+/**
+ * Auto-updating list of agent groups.
+ * 
+ * Can use optional group name filter.
+ * 
+ * @see setNameFilter()
+ */
+class LLGroupList: public LLFlatListView, public LLOldEvents::LLSimpleListener
 {
 	LOG_CLASS(LLGroupList);
 public:
@@ -46,14 +55,23 @@ class LLGroupList: public LLFlatListView
 	};
 
 	LLGroupList(const Params& p);
-	BOOL update(const std::string& name_filter = LLStringUtil::null);
+	virtual ~LLGroupList();
+
+	virtual void draw(); // from LLView
+
+	void setNameFilter(const std::string& filter);
 	void toggleIcons();
 	bool getIconsVisible() const { return mShowIcons; }
-
+	
 private:
+	void setDirty(bool val = true)		{ mDirty = val; }
+	void refresh();
 	void addNewItem(const LLUUID& id, const std::string& name, const LLUUID& icon_id, BOOL is_bold, EAddPosition pos = ADD_BOTTOM);
+	bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata); // called on agent group list changes
 
 	bool mShowIcons;
+	bool mDirty;
+	std::string mNameFilter;
 };
 
 class LLButton;
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index 254e16e1fb9..1c144b11b00 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -48,6 +48,7 @@
 #include "lltrans.h"
 #include "llviewertexteditor.h"
 #include "llviewerwindow.h"
+#include "lltransientfloatermgr.h"
 
 
 
@@ -62,33 +63,46 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mInputEditor(NULL), 
 	mPositioned(false)
 {
-	LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
-	if(session)
+	EInstantMessage type = LLIMModel::getInstance()->getType(session_id);
+	if(IM_COUNT != type)
 	{
-		mDialog = session->mType;
-	}
+		mDialog = type;
 
-	if (mDialog == IM_NOTHING_SPECIAL)
-	{
-		mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
-	}
-	else
-	{
-		mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
+		if (IM_NOTHING_SPECIAL == mDialog || IM_SESSION_P2P_INVITE == mDialog)
+		{
+			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
+		}
+		else
+		{
+			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
+		}
 	}
-// 	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_im_session.xml");
 
 	LLUI::getRootView()->setFocusLostCallback(boost::bind(&LLIMFloater::focusChangeCallback, this));
 
 	mCloseSignal.connect(boost::bind(&LLIMFloater::onClose, this));
+
+	LLTransientFloaterMgr::getInstance()->registerTransientFloater(this);
 }
 
 void LLIMFloater::onClose()
 {
 	LLIMModel::instance().sendLeaveSession(mSessionID, mOtherParticipantUUID);
+
+	//*TODO - move to the IMModel::sendLeaveSession() for the integrity (IB)
 	gIMMgr->removeSession(mSessionID);
 }
 
+void LLIMFloater::setMinimized(BOOL minimize)
+{
+	if(!isDocked())
+	{
+		setVisible(!minimize);
+	}	
+
+	LLFloater::setMinimized(minimize);
+}
+
 /* static */
 void LLIMFloater::newIMCallback(const LLSD& data){
 	
@@ -152,16 +166,17 @@ void LLIMFloater::sendMsg()
 
 LLIMFloater::~LLIMFloater()
 {
+	LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this);
 }
 
 //virtual
 BOOL LLIMFloater::postBuild()
 {
-	LLIMModel::LLIMSession* session = get_if_there(LLIMModel::instance().sSessionsMap, mSessionID, (LLIMModel::LLIMSession*)NULL);
-	if(session)
+	const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
+	if (other_party_id.notNull())
 	{
-		mOtherParticipantUUID = session->mOtherParticipantID;
-		mControlPanel->setID(session->mOtherParticipantID);
+		mOtherParticipantUUID = other_party_id;
+		mControlPanel->setID(mOtherParticipantUUID);
 	}
 
 	LLButton* slide_left = getChild<LLButton>("slide_left_btn");
@@ -216,17 +231,6 @@ void* LLIMFloater::createPanelGroupControl(void* userdata)
 	return self->mControlPanel;
 }
 
-
-
-void LLIMFloater::focusChangeCallback()
-{
-	// hide docked floater if user clicked inside in-world area
-	if (isDocked())
-	{
-		setVisible(false);
-	}
-}
-
 void LLIMFloater::onSlide()
 {
 	LLPanel* im_control_panel = getChild<LLPanel>("panel_im_control_panel");
@@ -271,13 +275,13 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 		}
 
 		floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(),
-				LLDockControl::TOP,  boost::bind(&LLIMFloater::getEnabledRect, floater, _1)));
+				LLDockControl::TOP,  boost::bind(&LLIMFloater::getAllowedRect, floater, _1)));
 	}
 
 	return floater;
 }
 
-void LLIMFloater::getEnabledRect(LLRect& rect)
+void LLIMFloater::getAllowedRect(LLRect& rect)
 {
 	rect = gViewerWindow->getWorldViewRect();
 }
@@ -285,8 +289,10 @@ void LLIMFloater::getEnabledRect(LLRect& rect)
 void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
 {
 	// update notification channel state
-	LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->
-											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+	LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
+		(LLNotificationsUI::LLChannelManager::getInstance()->
+											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+	
 	LLDockableFloater::setDocked(docked, pop_on_undock);
 
 	// update notification channel state
@@ -298,8 +304,9 @@ void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
 
 void LLIMFloater::setVisible(BOOL visible)
 {
-	LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->
-											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
+	LLNotificationsUI::LLScreenChannel* channel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>
+		(LLNotificationsUI::LLChannelManager::getInstance()->
+											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
 	LLDockableFloater::setVisible(visible);
 
 	// update notification channel state
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 276f38e8296..a183212f041 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -57,6 +57,8 @@ class LLIMFloater : public LLDockableFloater
 
 	// LLFloater overrides
 	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
+	// override LLFloater's minimization according to EXT-1216
+	/*virtual*/ void setMinimized(BOOL minimize);
 
 	// Make IM conversion visible and update the message history
 	static LLIMFloater* show(const LLUUID& session_id);
@@ -90,8 +92,8 @@ class LLIMFloater : public LLDockableFloater
 	void			onSlide();
 	static void*	createPanelIMControl(void* userdata);
 	static void*	createPanelGroupControl(void* userdata);
-	void focusChangeCallback();
-	void getEnabledRect(LLRect& rect);
+	// gets a rect that bounds possible positions for the LLIMFloater on a screen (EXT-1111)
+	void getAllowedRect(LLRect& rect);
 	
 	LLPanelChatControlPanel* mControlPanel;
 	LLUUID mSessionID;
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 46067c081f6..74971f3fd85 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -109,7 +109,9 @@ bool LLIMHandler::processNotification(const LLSD& notify)
 		p.panel = im_box;
 		p.can_be_stored = false;
 		p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
-		mChannel->addToast(p);
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->addToast(p);
 
 		// send a signal to the counter manager;
 		mNewNotificationSignal();
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index aa2beabf3d4..abd3cd4def2 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -940,7 +940,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 	mHistoryEditor(NULL),
 	mSessionUUID(session_id),
 	mSessionLabel(session_label),
-	mVoiceChannel(NULL),
 	mSessionInitialized(FALSE),
 	mSessionStartMsgPos(0),
 	mOtherParticipantUUID(other_participant_id),
@@ -956,7 +955,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 	mTextIMPossible(TRUE),
 	mProfileButtonEnabled(TRUE),
 	mCallBackEnabled(TRUE),
-	mSpeakers(NULL),
 	mSpeakerPanel(NULL),
 	mFirstKeystrokeTimer(),
 	mLastKeystrokeTimer()
@@ -967,7 +965,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 	case IM_SESSION_GROUP_START:
 		mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
 		xml_filename = "floater_instant_message_group.xml";
-		mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
 		break;
 	case IM_SESSION_INVITE:
 		mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
@@ -979,16 +976,13 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 		{
 			xml_filename = "floater_instant_message_ad_hoc.xml";
 		}
-		mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
 		break;
 	case IM_SESSION_P2P_INVITE:
 		xml_filename = "floater_instant_message.xml";
-		mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
 		break;
 	case IM_SESSION_CONFERENCE_START:
 		mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, this);
 		xml_filename = "floater_instant_message_ad_hoc.xml";
-		mVoiceChannel = new LLVoiceChannelGroup(mSessionUUID, mSessionLabel);
 		break;
 	// just received text from another user
 	case IM_NOTHING_SPECIAL:
@@ -998,8 +992,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 		mTextIMPossible = LLVoiceClient::getInstance()->isSessionTextIMPossible(mSessionUUID);
 		mProfileButtonEnabled = LLVoiceClient::getInstance()->isParticipantAvatar(mSessionUUID);
 		mCallBackEnabled = LLVoiceClient::getInstance()->isSessionCallBackPossible(mSessionUUID);
-		
-		mVoiceChannel = new LLVoiceChannelP2P(mSessionUUID, mSessionLabel, mOtherParticipantUUID);
 		break;
 	default:
 		llwarns << "Unknown session type" << llendl;
@@ -1007,10 +999,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 		break;
 	}
 
-	mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
-	// All participants will be added to the list of people we've recently interacted with.
-	mSpeakers->addListener(&LLRecentPeople::instance(), "add");
-
 	LLUICtrlFactory::getInstance()->buildFloater(this, xml_filename, NULL);
 
 	setTitle(mSessionLabel);
@@ -1058,33 +1046,6 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 
 LLFloaterIMPanel::~LLFloaterIMPanel()
 {
-	delete mSpeakers;
-	mSpeakers = NULL;
-	
-	// End the text IM session if necessary
-	if(gVoiceClient && mOtherParticipantUUID.notNull())
-	{
-		switch(mDialog)
-		{
-			case IM_NOTHING_SPECIAL:
-			case IM_SESSION_P2P_INVITE:
-				gVoiceClient->endUserIMSession(mOtherParticipantUUID);
-			break;
-			
-			default:
-				// Appease the compiler
-			break;
-		}
-	}
-	
-	//kicks you out of the voice channel if it is currently active
-
-	// HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
-	mVoiceChannel->deactivate();
-	
-	delete mVoiceChannel;
-	mVoiceChannel = NULL;
-
 	//delete focus lost callback
 	mFocusCallbackConnection.disconnect();
 }
@@ -1152,7 +1113,8 @@ BOOL LLFloaterIMPanel::postBuild()
 void* LLFloaterIMPanel::createSpeakersPanel(void* data)
 {
 	LLFloaterIMPanel* floaterp = (LLFloaterIMPanel*)data;
-	floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(floaterp->mSpeakers, TRUE);
+	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(floaterp->mSessionUUID);
+	floaterp->mSpeakerPanel = new LLPanelActiveSpeakers(speaker_mgr, TRUE);
 	return floaterp->mSpeakerPanel;
 }
 
@@ -1198,12 +1160,14 @@ void LLFloaterIMPanel::draw()
 					  && mCallBackEnabled;
 
 	// hide/show start call and end call buttons
-	childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
-	childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID);
+	childSetVisible("end_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED);
+	childSetVisible("start_call_btn", LLVoiceClient::voiceEnabled() && voice_channel->getState() < LLVoiceChannel::STATE_CALL_STARTED);
 	childSetEnabled("start_call_btn", enable_connect);
 	childSetEnabled("send_btn", !childGetValue("chat_editor").asString().empty());
 	
-	LLPointer<LLSpeaker> self_speaker = mSpeakers->findSpeaker(gAgent.getID());
+	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID);
+	LLPointer<LLSpeaker> self_speaker = speaker_mgr->findSpeaker(gAgent.getID());
 	if(!mTextIMPossible)
 	{
 		mInputEditor->setEnabled(FALSE);
@@ -1227,7 +1191,7 @@ void LLFloaterIMPanel::draw()
 	}
 
 	// show speakers window when voice first connects
-	if (mShowSpeakersOnConnect && mVoiceChannel->isActive())
+	if (mShowSpeakersOnConnect && voice_channel->isActive())
 	{
 		childSetVisible("active_speakers_panel", TRUE);
 		mShowSpeakersOnConnect = FALSE;
@@ -1263,11 +1227,11 @@ void LLFloaterIMPanel::draw()
 	else
 	{
 		// refresh volume and mute checkbox
-		childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
+		childSetVisible("speaker_volume", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
 		childSetValue("speaker_volume", gVoiceClient->getUserVolume(mOtherParticipantUUID));
 
 		childSetValue("mute_btn", LLMuteList::getInstance()->isMuted(mOtherParticipantUUID, LLMute::flagVoiceChat));
-		childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && mVoiceChannel->isActive());
+		childSetVisible("mute_btn", LLVoiceClient::voiceEnabled() && voice_channel->isActive());
 	}
 	LLFloater::draw();
 }
@@ -1403,12 +1367,6 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
 	{
 		mNumUnreadMessages++;
 	}
-
-	if (source != LLUUID::null)
-	{
-		mSpeakers->speakerChatted(source);
-		mSpeakers->setSpeakerTyping(source, FALSE);
-	}
 }
 
 
@@ -1589,7 +1547,7 @@ void LLFloaterIMPanel::onClickStartCall(void* userdata)
 {
 	LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
 
-	self->mVoiceChannel->activate();
+	LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->activate();
 }
 
 // static
@@ -1597,7 +1555,7 @@ void LLFloaterIMPanel::onClickEndCall(void* userdata)
 {
 	LLFloaterIMPanel* self = (LLFloaterIMPanel*) userdata;
 
-	self->getVoiceChannel()->deactivate();
+	LLIMModel::getInstance()->getVoiceChannel(self->mSessionUUID)->deactivate();
 }
 
 // static
@@ -1671,7 +1629,8 @@ void LLFloaterIMPanel::onVisibilityChange(const LLSD& new_visibility)
 		mNumUnreadMessages = 0;
 	}
 	
-	if (new_visibility.asBoolean() && mVoiceChannel->getState() == LLVoiceChannel::STATE_CONNECTED)
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionUUID);
+	if (new_visibility.asBoolean() && voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
 		LLFloaterReg::showInstance("voice_call", mSessionUUID);
 	else
 		LLFloaterReg::hideInstance("voice_call", mSessionUUID);
@@ -1723,11 +1682,6 @@ void LLFloaterIMPanel::sendMsg()
 	mSentTypingState = TRUE;
 }
 
-void LLFloaterIMPanel::updateSpeakersList(const LLSD& speaker_updates)
-{
-	mSpeakers->updateSpeakers(speaker_updates); 
-}
-
 void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
 {
 	if (
@@ -1751,15 +1705,9 @@ void LLFloaterIMPanel::processSessionUpdate(const LLSD& session_update)
 	}
 }
 
-void LLFloaterIMPanel::setSpeakers(const LLSD& speaker_list)
-{
-	mSpeakers->setSpeakers(speaker_list);
-}
-
 void LLFloaterIMPanel::sessionInitReplyReceived(const LLUUID& session_id)
 {
 	mSessionUUID = session_id;
-	mVoiceChannel->updateSessionID(session_id);
 	mSessionInitialized = TRUE;
 
 	//we assume the history editor hasn't moved at all since
@@ -1790,6 +1738,7 @@ void LLFloaterIMPanel::requestAutoConnect()
 
 void LLFloaterIMPanel::setTyping(BOOL typing)
 {
+	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionUUID);
 	if (typing)
 	{
 		// Every time you type something, reset this timer
@@ -1804,7 +1753,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
 			mSentTypingState = FALSE;
 		}
 
-		mSpeakers->setSpeakerTyping(gAgent.getID(), TRUE);
+		speaker_mgr->setSpeakerTyping(gAgent.getID(), TRUE);
 	}
 	else
 	{
@@ -1814,7 +1763,7 @@ void LLFloaterIMPanel::setTyping(BOOL typing)
 			sendTypingState(FALSE);
 			mSentTypingState = TRUE;
 		}
-		mSpeakers->setSpeakerTyping(gAgent.getID(), FALSE);
+		speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
 	}
 
 	mTyping = typing;
@@ -1874,7 +1823,7 @@ void LLFloaterIMPanel::removeTypingIndicator(const LLIMInfo* im_info)
 		mHistoryEditor->removeTextFromEnd(chars_to_remove);
 		if (im_info)
 		{
-			mSpeakers->setSpeakerTyping(im_info->mFromID, FALSE);
+			LLIMModel::getInstance()->getSpeakerManager(mSessionUUID)->setSpeakerTyping(im_info->mFromID, FALSE);
 		}
 	}
 }
diff --git a/indra/newview/llimpanel.h b/indra/newview/llimpanel.h
index fd1134ee5e6..fb9b28ad16b 100644
--- a/indra/newview/llimpanel.h
+++ b/indra/newview/llimpanel.h
@@ -33,6 +33,7 @@
 #ifndef LL_IMPANEL_H
 #define LL_IMPANEL_H
 
+#include "llimview.h" //for LLIMModel
 #include "lldockablefloater.h"
 #include "lllogchat.h"
 #include "lluuid.h"
@@ -245,11 +246,7 @@ class LLFloaterIMPanel : public LLFloater
 
 	const LLUUID& getSessionID() const { return mSessionUUID; }
 	const LLUUID& getOtherParticipantID() const { return mOtherParticipantUUID; }
-	LLIMSpeakerMgr* getSpeakerManager() const { return mSpeakers; }
-	void updateSpeakersList(const LLSD& speaker_updates);
 	void processSessionUpdate(const LLSD& update);
-	void setSpeakers(const LLSD& speaker_list);
-	LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
 	EInstantMessage getDialogType() const { return mDialog; }
 	void setDialogType(EInstantMessage dialog) { mDialog = dialog; }
 
@@ -305,7 +302,6 @@ class LLFloaterIMPanel : public LLFloater
 	LLUUID mSessionUUID;
 
 	std::string mSessionLabel;
-	LLVoiceChannel*	mVoiceChannel;
 
 	BOOL mSessionInitialized;
 	LLSD mQueuedMsgsForInit;
@@ -346,7 +342,6 @@ class LLFloaterIMPanel : public LLFloater
 	BOOL mProfileButtonEnabled;
 	BOOL mCallBackEnabled;
 
-	LLIMSpeakerMgr* mSpeakers;
 	LLPanelActiveSpeakers* mSpeakerPanel;
 	
 	// Optimization:  Don't send "User is typing..." until the
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 3cf78f957b3..556eb5ffd70 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -114,10 +114,84 @@ void toast_callback(const LLSD& msg){
 
 LLIMModel::LLIMModel() 
 {
-	addChangedCallback(toast_callback);
 	addChangedCallback(LLIMFloater::newIMCallback);
+	addChangedCallback(toast_callback);
+}
+
+
+LLIMModel::LLIMSession::LLIMSession( const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id )
+:	mSessionID(session_id),
+	mName(name),
+	mType(type),
+	mNumUnread(0),
+	mOtherParticipantID(other_participant_id),
+	mVoiceChannel(NULL),
+	mSpeakers(NULL)
+{
+	if (IM_NOTHING_SPECIAL == type || IM_SESSION_P2P_INVITE == type)
+	{
+		mVoiceChannel  = new LLVoiceChannelP2P(session_id, name, other_participant_id);
+	}
+	else
+	{
+		mVoiceChannel = new LLVoiceChannelGroup(session_id, name);
+	}
+	mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
+
+	// All participants will be added to the list of people we've recently interacted with.
+	mSpeakers->addListener(&LLRecentPeople::instance(), "add");
+}
+
+LLIMModel::LLIMSession::~LLIMSession()
+{
+	delete mSpeakers;
+	mSpeakers = NULL;
+
+	// End the text IM session if necessary
+	if(gVoiceClient && mOtherParticipantID.notNull())
+	{
+		switch(mType)
+		{
+		case IM_NOTHING_SPECIAL:
+		case IM_SESSION_P2P_INVITE:
+			gVoiceClient->endUserIMSession(mOtherParticipantID);
+			break;
+
+		default:
+			// Appease the linux compiler
+			break;
+		}
+	}
+
+	// HAVE to do this here -- if it happens in the LLVoiceChannel destructor it will call the wrong version (since the object's partially deconstructed at that point).
+	mVoiceChannel->deactivate();
+	
+	delete mVoiceChannel;
+	mVoiceChannel = NULL;
 }
 
+LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
+{
+	return get_if_there(LLIMModel::instance().sSessionsMap, session_id,
+		(LLIMModel::LLIMSession*) NULL);
+}
+
+void LLIMModel::updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id)
+{
+	if (new_session_id == old_session_id) return;
+
+	LLIMSession* session = findIMSession(old_session_id);
+	if (session)
+	{
+		session->mSessionID = new_session_id;
+		session->mVoiceChannel->updateSessionID(new_session_id);
+
+		//*TODO set session initialized flag here? (IB)
+
+		sSessionsMap.erase(old_session_id);
+		sSessionsMap[new_session_id] = session;
+	}
+}
 
 void LLIMModel::testMessages()
 {
@@ -153,7 +227,7 @@ bool LLIMModel::newSession(LLUUID session_id, std::string name, EInstantMessage
 		return false;
 	}
 
-	LLIMSession* session = new LLIMSession(name, type, other_participant_id);
+	LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id);
 	sSessionsMap[session_id] = session;
 
 	LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, name, other_participant_id);
@@ -170,12 +244,12 @@ bool LLIMModel::clearSession(LLUUID session_id)
 	return true;
 }
 
+//*TODO remake it, instead of returing the list pass it as as parameter (IB)
 std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
 {
 	std::list<LLSD> return_list;
 
-	LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
-
+	LLIMSession* session = findIMSession(session_id);
 	if (!session) 
 	{
 		llwarns << "session " << session_id << "does not exist " << llendl;
@@ -202,13 +276,14 @@ std::list<LLSD> LLIMModel::getMessages(LLUUID session_id, int start_index)
 	mChangedSignal(arg);
 
     // TODO: in the future is there a more efficient way to return these
+	//of course there is - return as parameter (IB)
 	return return_list;
 
 }
 
 bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string utf8_text) { 
 	
-	LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+	LLIMSession* session = findIMSession(session_id);
 
 	if (!session) 
 	{
@@ -231,7 +306,7 @@ bool LLIMModel::addToHistory(LLUUID session_id, std::string from, std::string ut
 		
 bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id, std::string utf8_text) { 
 
-	LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+	LLIMSession* session = findIMSession(session_id);
 
 	if (!session) 
 	{
@@ -260,9 +335,9 @@ bool LLIMModel::addMessage(LLUUID session_id, std::string from, LLUUID from_id,
 }
 
 
-const std::string& LLIMModel::getName(LLUUID session_id)
+const std::string& LLIMModel::getName(const LLUUID& session_id) const
 {
-	LLIMSession* session = get_if_there(sSessionsMap, session_id, (LLIMSession*)NULL);
+	LLIMSession* session = findIMSession(session_id);
 
 	if (!session) 
 	{
@@ -273,6 +348,66 @@ const std::string& LLIMModel::getName(LLUUID session_id)
 	return session->mName;
 }
 
+const S32 LLIMModel::getNumUnread(const LLUUID& session_id) const
+{
+	LLIMSession* session = findIMSession(session_id);
+	if (!session)
+	{
+		llwarns << "session " << session_id << "does not exist " << llendl;
+		return -1;
+	}
+
+	return session->mNumUnread;
+}
+
+const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const
+{
+	LLIMSession* session = findIMSession(session_id);
+	if (!session)
+	{
+		llwarns << "session " << session_id << "does not exist " << llendl;
+		return LLUUID::null;
+	}
+
+	return session->mOtherParticipantID;
+}
+
+EInstantMessage LLIMModel::getType(const LLUUID& session_id) const
+{
+	LLIMSession* session = findIMSession(session_id);
+	if (!session)
+	{
+		llwarns << "session " << session_id << "does not exist " << llendl;
+		return IM_COUNT;
+	}
+
+	return session->mType;
+}
+
+LLVoiceChannel* LLIMModel::getVoiceChannel( const LLUUID& session_id ) const
+{
+	LLIMSession* session = findIMSession(session_id);
+	if (!session)
+	{
+		llwarns << "session " << session_id << "does not exist " << llendl;
+		return NULL;
+	}
+
+	return session->mVoiceChannel;
+}
+
+LLIMSpeakerMgr* LLIMModel::getSpeakerManager( const LLUUID& session_id ) const
+{
+	LLIMSession* session = findIMSession(session_id);
+	if (!session)
+	{
+		llwarns << "session " << session_id << "does not exist " << llendl;
+		return NULL;
+	}
+
+	return session->mSpeakers;
+}
+
 
 // TODO get rid of other participant ID
 void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing) 
@@ -316,7 +451,7 @@ void LLIMModel::sendLeaveSession(LLUUID session_id, LLUUID other_participant_id)
 }
 
 
-
+//*TODO update list of messages in a LLIMSession (IB)
 void LLIMModel::sendMessage(const std::string& utf8_text,
 					 const LLUUID& im_session_id,
 					 const LLUUID& other_participant_id,
@@ -415,9 +550,16 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
 		LLFloaterIMPanel* floater = gIMMgr->findFloaterBySession(im_session_id);
 		if (floater) floater->addHistoryLine(history_echo, LLUIColorTable::instance().getColor("IMChatColor"), true, gAgent.getID());
 
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(im_session_id);
+		if (speaker_mgr)
+		{
+			speaker_mgr->speakerChatted(gAgentID);
+			speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
+		}
 	}
 
 	// Add the recipient to the recent people list.
+	//*TODO should be deleted, because speaker manager updates through callback the recent list
 	LLRecentPeople::instance().add(other_participant_id);
 }
 										  
@@ -633,10 +775,8 @@ class LLViewerChatterBoxInvitationAcceptResponder :
 	{
 		if ( gIMMgr)
 		{
-			LLFloaterIMPanel* floaterp =
-				gIMMgr->findFloaterBySession(mSessionID);
-
-			if (floaterp)
+			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+			if (speaker_mgr)
 			{
 				//we've accepted our invitation
 				//and received a list of agents that were
@@ -650,15 +790,20 @@ class LLViewerChatterBoxInvitationAcceptResponder :
 				//but unfortunately, our base that we are receiving here
 				//may not be the most up to date.  It was accurate at
 				//some point in time though.
-				floaterp->setSpeakers(content);
+				speaker_mgr->setSpeakers(content);
 
 				//we now have our base of users in the session
 				//that was accurate at some point, but maybe not now
 				//so now we apply all of the udpates we've received
 				//in case of race conditions
-				floaterp->updateSpeakersList(
-					gIMMgr->getPendingAgentListUpdates(mSessionID));
+				speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(mSessionID));
+			}
+			
+			LLFloaterIMPanel* floaterp =
+				gIMMgr->findFloaterBySession(mSessionID);
 
+			if (floaterp)
+			{
 				if ( mInvitiationType == LLIMMgr::INVITATION_TYPE_VOICE )
 				{
 					floaterp->requestAutoConnect();
@@ -1104,6 +1249,12 @@ void LLIMMgr::addMessage(
 		//no session ID...compute new one
 		new_session_id = computeSessionID(dialog, other_participant_id);
 	}
+
+	if (!LLIMModel::getInstance()->findIMSession(new_session_id))
+	{
+		LLIMModel::instance().newSession(session_id, session_name, dialog, other_participant_id);
+	}
+
 	floater = findFloaterBySession(new_session_id);
 	if (!floater)
 	{
@@ -1169,6 +1320,14 @@ void LLIMMgr::addMessage(
 	else
 	{
 		floater->addHistoryLine(msg, color, true, other_participant_id, from); // Insert linked name to front of message
+
+		//*TODO consider moving that speaker management stuff into model (IB)
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(new_session_id);
+		if (speaker_mgr)
+		{
+			speaker_mgr->speakerChatted(gAgentID);
+			speaker_mgr->setSpeakerTyping(gAgentID, FALSE);
+		}
 	}
 
 	LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg);
@@ -1273,11 +1432,10 @@ LLUUID LLIMMgr::addP2PSession(const std::string& name,
 {
 	LLUUID session_id = addSession(name, IM_NOTHING_SPECIAL, other_participant_id);
 
-	LLFloaterIMPanel* floater = findFloaterBySession(session_id);
-	if(floater)
+	LLVoiceChannelP2P* voice_channel = (LLVoiceChannelP2P*) LLIMModel::getInstance()->getSpeakerManager(session_id);
+	if (voice_channel)
 	{
-		LLVoiceChannelP2P* voice_channelp = (LLVoiceChannelP2P*)floater->getVoiceChannel();
-		voice_channelp->setSessionHandle(voice_session_handle, caller_uri);		
+		voice_channel->setSessionHandle(voice_session_handle, caller_uri);
 	}
 
 	return session_id;
@@ -1312,6 +1470,11 @@ LLUUID LLIMMgr::addSession(
 
 	LLUUID session_id = computeSessionID(dialog,other_participant_id);
 
+	if (!LLIMModel::getInstance()->findIMSession(session_id))
+	{
+		LLIMModel::instance().newSession(session_id, name, dialog, other_participant_id);
+	}
+
 	LLFloaterIMPanel* floater = findFloaterBySession(session_id);
 	if(!floater)
 	{
@@ -1335,17 +1498,10 @@ LLUUID LLIMMgr::addSession(
 			noteMutedUsers(floater, ids);
 		}
 	}
-	else
-	{
-		// *TODO: Remove this?  Otherwise old communicate window opens on
-		// second initiation of IM session from People panel?
-		// floater->openFloater();
-	}
-	//mTabContainer->selectTabPanel(panel);
 	floater->setInputFocus(TRUE);
 	LLIMFloater::show(session_id);
-	notifyObserverSessionAdded(floater->getSessionID(), name, other_participant_id);
-	return floater->getSessionID();
+
+	return session_id;
 }
 
 // This removes the panel referenced by the uuid, and then restores
@@ -1705,7 +1861,6 @@ LLFloaterIMPanel* LLIMMgr::createFloater(
 	LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
 	LLFloaterChatterBox::getInstance()->addFloater(floater, FALSE, i_pt);
 	mFloaters.insert(floater->getHandle());
-	LLIMModel::instance().newSession(session_id, session_label, dialog, other_participant_id);
 	return floater;
 }
 
@@ -1825,24 +1980,25 @@ class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
 			gIMMgr->updateFloaterSessionID(
 				temp_session_id,
 				session_id);
+
+			LLIMModel::getInstance()->updateSessionID(temp_session_id, session_id);
+
+			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+			if (speaker_mgr)
+			{
+				speaker_mgr->setSpeakers(body);
+				speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id));
+			}
+
 			LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(session_id);
 			if (floaterp)
 			{
-				floaterp->setSpeakers(body);
-
-				//apply updates we've possibly received previously
-				floaterp->updateSpeakersList(
-					gIMMgr->getPendingAgentListUpdates(session_id));
-
 				if ( body.has("session_info") )
 				{
 					floaterp->processSessionUpdate(body["session_info"]);
 				}
-
-				//aply updates we've possibly received previously
-				floaterp->updateSpeakersList(
-					gIMMgr->getPendingAgentListUpdates(session_id));
 			}
+
 			gIMMgr->clearPendingAgentListUpdates(session_id);
 		}
 		else
@@ -1932,15 +2088,15 @@ class LLViewerChatterBoxSessionAgentListUpdates : public LLHTTPNode
 		const LLSD& context,
 		const LLSD& input) const
 	{
-		LLFloaterIMPanel* floaterp = gIMMgr->findFloaterBySession(input["body"]["session_id"].asUUID());
-		if (floaterp)
+		const LLUUID& session_id = input["body"]["session_id"].asUUID();
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
+		if (speaker_mgr)
 		{
-			floaterp->updateSpeakersList(
-				input["body"]);
+			speaker_mgr->updateSpeakers(input["body"]);
 		}
 		else
 		{
-			//we don't have a floater yet..something went wrong
+			//we don't have a speaker manager yet..something went wrong
 			//we are probably receiving an update here before
 			//a start or an acceptance of an invitation.  Race condition.
 			gIMMgr->addPendingAgentListUpdates(
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 219af0705d8..9a94d01bb29 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -34,6 +34,8 @@
 #define LL_LLIMVIEW_H
 
 #include "lldarray.h"
+#include "llfloateractivespeakers.h" //for LLIMSpeakerMgr
+#include "llimpanel.h" //for voice channels
 #include "llmodaldialog.h"
 #include "llinstantmessage.h"
 #include "lluuid.h"
@@ -50,21 +52,40 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 
 	struct LLIMSession
 	{
-		LLIMSession(std::string name, EInstantMessage type, LLUUID other_participant_id) 
-			:mName(name), mType(type), mNumUnread(0), mOtherParticipantID(other_participant_id) {}
-		
+		LLIMSession(const LLUUID& session_id, const std::string& name, 
+			const EInstantMessage& type, const LLUUID& other_participant_id);
+		virtual ~LLIMSession();
+
+		LLUUID mSessionID;
 		std::string mName;
 		EInstantMessage mType;
 		LLUUID mOtherParticipantID;
 		S32 mNumUnread;
 		std::list<LLSD> mMsgs;
+
+		LLVoiceChannel* mVoiceChannel;
+		LLIMSpeakerMgr* mSpeakers;
 	};
 	
 
 	LLIMModel();
 
+	//*TODO make it non-static as LLIMMOdel is a singleton (IB)
 	static std::map<LLUUID, LLIMSession*> sSessionsMap;  //mapping session_id to session
+
 	boost::signals2::signal<void(const LLSD&)> mChangedSignal;
+	
+	/** 
+	 * Find an IM Session corresponding to session_id
+	 * Returns NULL if the session does not exist
+	 */
+	LLIMSession* findIMSession(const LLUUID& session_id) const;
+
+	/**
+	 * Rebind session data to a new session id.
+	 */
+	void updateSessionID(const LLUUID& old_session_id, const LLUUID& new_session_id);
+
 	boost::signals2::connection addChangedCallback( boost::function<void (const LLSD& data)> cb );
 
 	bool newSession(LLUUID session_id, std::string name, EInstantMessage type, LLUUID other_participant_id);
@@ -72,10 +93,42 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	std::list<LLSD> getMessages(LLUUID session_id, int start_index = 0);
 	bool addMessage(LLUUID session_id, std::string from, LLUUID other_participant_id, std::string utf8_text);
 	bool addToHistory(LLUUID session_id, std::string from, std::string utf8_text); 
-    //used to get the name of the session, for use as the title
-    //currently just the other avatar name
-	const std::string& getName(LLUUID session_id);
-	
+	//used to get the name of the session, for use as the title
+	//currently just the other avatar name
+	const std::string& getName(const LLUUID& session_id) const;
+
+	/** 
+	 * Get number of unread messages in a session with session_id
+	 * Returns -1 if the session with session_id doesn't exist
+	 */
+	const S32 getNumUnread(const LLUUID& session_id) const;
+
+	/**
+	 * Get uuid of other participant in a session with session_id
+	 * Returns LLUUID::null if the session doesn't exist
+	 *
+ 	 * *TODO what to do with other participants in ad-hoc and group chats?
+	 */
+	const LLUUID& getOtherParticipantID(const LLUUID& session_id) const;
+
+	/**
+	 * Get type of a session specified by session_id
+	 * Returns EInstantMessage::IM_COUNT if the session does not exist
+	 */
+	EInstantMessage getType(const LLUUID& session_id) const;
+
+	/**
+	 * Get voice channel for the session specified by session_id
+	 * Returns NULL if the session does not exist
+	 */
+	LLVoiceChannel* getVoiceChannel(const LLUUID& session_id) const;
+
+	/**
+	* Get im speaker manager for the session specified by session_id
+	* Returns NULL if the session does not exist
+	*/
+	LLIMSpeakerMgr* getSpeakerManager(const LLUUID& session_id) const;
+
 	static void sendLeaveSession(LLUUID session_id, LLUUID other_participant_id);
 	static bool sendStartSession(const LLUUID& temp_session_id, const LLUUID& other_participant_id,
 						  const std::vector<LLUUID>& ids, EInstantMessage dialog);
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index b53bb586f39..84309379336 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -65,6 +65,7 @@ LLNearbyChat::LLNearbyChat(const LLSD& key) :
 	mChatCaptionPanel(NULL),
 	mChatHistoryEditor(NULL)
 {
+	m_isDirty = false;
 }
 
 LLNearbyChat::~LLNearbyChat()
@@ -181,7 +182,7 @@ LLColor4 nearbychat_get_text_color(const LLChat& chat)
 	return text_color;
 }
 
-void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color)
+void LLNearbyChat::add_timestamped_line(const LLChat& chat, const LLColor4& color)
 {
 	std::string line = chat.mText;
 
@@ -194,25 +195,28 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons
 	bool prepend_newline = true;
 	if (gSavedSettings.getBOOL("ChatShowTimestamps"))
 	{
-		edit->appendTime(prepend_newline);
+		mChatHistoryEditor->appendTime(prepend_newline);
 		prepend_newline = false;
 	}
 
 	// If the msg is from an agent (not yourself though),
 	// extract out the sender name and replace it with the hotlinked name.
+	
+	std::string		str_URL = chat.mURL;
+
 	if (chat.mSourceType == CHAT_SOURCE_AGENT &&
 		chat.mFromID != LLUUID::null)
 	{
-		chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
+		str_URL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
 	}
 
 	// If the chat line has an associated url, link it up to the name.
-	if (!chat.mURL.empty()
+	if (!str_URL.empty()
 		&& (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0))
 	{
 		std::string start_line = line.substr(0, chat.mFromName.length() + 1);
 		line = line.substr(chat.mFromName.length() + 1);
-		edit->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,chat.mURL));
+		mChatHistoryEditor->appendStyledText(start_line, false, prepend_newline, LLStyleMap::instance().lookup(chat.mFromID,str_URL));
 		prepend_newline = false;
 	}
 
@@ -225,11 +229,9 @@ void nearbychat_add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, cons
 	else if (2 == font_size)
 		font_name = "sansserifbig";
 
-	edit->appendColoredText(line, false, prepend_newline, color, font_name);
+	mChatHistoryEditor->appendColoredText(line, false, prepend_newline, color, font_name);
 }
 
-
-
 void	LLNearbyChat::addMessage(const LLChat& chat)
 {
 	LLColor4 color = nearbychat_get_text_color(chat);
@@ -254,7 +256,7 @@ void	LLNearbyChat::addMessage(const LLChat& chat)
 	mChatHistoryEditor->setParseHighlights(TRUE);
 	
 	if (!chat.mMuted)
-		nearbychat_add_timestamped_line(mChatHistoryEditor, chat, color);
+		add_timestamped_line(chat, color);
 }
 
 void LLNearbyChat::onNearbySpeakers()
@@ -482,9 +484,16 @@ BOOL LLNearbyChat::handleRightMouseDown(S32 x, S32 y, MASK mask)
 
 void	LLNearbyChat::onOpen(const LLSD& key )
 {
-	LLNotificationsUI::LLScreenChannel* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+	LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
 	if(chat_channel)
 	{
 		chat_channel->removeToastsFromChannel();
 	}
 }
+
+void	LLNearbyChat::draw		()
+{
+	LLFloater::draw();
+}
+
+
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index efa2e479e66..599e6b6859a 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -76,7 +76,10 @@ class LLNearbyChat: public LLFloater
 
 	virtual void	onOpen		(const LLSD& key);
 
+	virtual void	draw		();
+
 private:
+	void	add_timestamped_line(const LLChat& chat, const LLColor4& color);
 	
 	void	pinn_panel();
 	void	float_panel();
@@ -86,10 +89,11 @@ class LLNearbyChat: public LLFloater
 	S32		mStart_X;
 	S32		mStart_Y;
 
-	//LLResizeBar*		mResizeBar[RESIZE_BAR_COUNT];
 	LLHandle<LLView>	mPopupMenuHandle;
 	LLPanel*			mChatCaptionPanel;
 	LLViewerTextEditor*	mChatHistoryEditor;
+
+	bool				m_isDirty;
 };
 
 #endif
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index 7eb5d91e539..eb42e83994f 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -41,30 +41,227 @@
 #include "llviewercontrol.h"
 
 #include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
+#include "llviewerwindow.h"//for screen channel position
 
 //add LLNearbyChatHandler to LLNotificationsUI namespace
-namespace LLNotificationsUI{
+using namespace LLNotificationsUI;
 
+//-----------------------------------------------------------------------------------------------
+//LLNearbyChatScreenChannel
+//-----------------------------------------------------------------------------------------------	
+LLToastPanelBase* createToastPanel()
+{
+	LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance();
+	static S32 chat_item_width = 304;
+	item->setWidth(chat_item_width);
+	return item;
+}
+
+
+class LLNearbyChatScreenChannel: public LLScreenChannelBase
+{
+public:
+	LLNearbyChatScreenChannel(const LLUUID& id):LLScreenChannelBase(id) { mActiveMessages = 0;};
 
+	void init				(S32 channel_left, S32 channel_right);
+
+	void addNotification	(LLSD& notification);
+	void arrangeToasts		();
+	void showToastsBottom	();
+	
+	typedef boost::function<LLToastPanelBase* (void )> create_toast_panel_callback_t;
+	void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
+
+	void onToastDestroyed	(LLToast* toast);
+	void onToastFade		(LLToast* toast);
+
+	// hide all toasts from screen, but not remove them from a channel
+	virtual void		hideToastsFromScreen() 
+	{
+	};
+	// removes all toasts from a channel
+	virtual void		removeToastsFromChannel() 
+	{
+		for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+		{
+			LLToast* toast = (*it);
+			toast->setVisible(FALSE);
+			toast->stopTimer();
+			m_toast_pool.push_back(toast);
+
+		}
+		m_active_toasts.clear();
+	};
+
+protected:
+	void	createOverflowToast(S32 bottom, F32 timer);
+
+	create_toast_panel_callback_t m_create_toast_panel_callback_t;
+
+	bool	createPoolToast();
+	
+	std::vector<LLToast*> m_active_toasts;
+	std::list<LLToast*> m_toast_pool;
+
+	S32 mActiveMessages;
+};
+
+void LLNearbyChatScreenChannel::init(S32 channel_left, S32 channel_right)
+{
+	S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
+	S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom;
+	setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
+	setVisible(TRUE);
+}
+
+
+void	LLNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer)
+{
+	//we don't need overflow toast in nearby chat
+}
+
+void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast)
+{	
+}
+
+void LLNearbyChatScreenChannel::onToastFade(LLToast* toast)
+{	
+	//fade mean we put toast to toast pool
+	if(!toast)
+		return;
+	m_toast_pool.push_back(toast);
+
+	std::vector<LLToast*>::iterator pos = std::find(m_active_toasts.begin(),m_active_toasts.end(),toast);
+	if(pos!=m_active_toasts.end())
+		m_active_toasts.erase(pos);
+	
+	arrangeToasts();
+}
+
+
+bool	LLNearbyChatScreenChannel::createPoolToast()
+{
+	LLToastPanelBase* panel= m_create_toast_panel_callback_t();
+	if(!panel)
+		return false;
+	
+	LLToast::Params p;
+	p.panel = panel;
+
+	LLToast* toast = new LLToast(p); 
+	
+	
+	toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1));
+	toast->setOnToastDestroyedCallback(boost::bind(&LLNearbyChatScreenChannel::onToastDestroyed, this, _1));
+	
+	m_toast_pool.push_back(toast);
+	return true;
+}
+
+void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
+{
+	//look in pool. if there is any message
+
+	
+	if(m_toast_pool.empty())
+	{
+		//"pool" is empty - create one more panel
+		if(!createPoolToast())//created toast will go to pool. so next call will find it
+			return;
+		addNotification(notification);
+		return;
+	}
+
+	//take 1st element from pool, (re)initialize it, put it in active toasts
+
+	LLToast* toast = m_toast_pool.back();
+
+	m_toast_pool.pop_back();
+
+
+	LLToastPanelBase* panel = dynamic_cast<LLToastPanelBase*>(toast->getPanel());
+	if(!panel)
+		return;
+	panel->init(notification);
+
+	toast->reshapeToPanel();
+	toast->resetTimer();
+	
+	m_active_toasts.insert(m_active_toasts.begin(),toast);
+
+	arrangeToasts();
+}
+
+void LLNearbyChatScreenChannel::arrangeToasts()
+{
+	if(m_active_toasts.size() == 0 || mIsHovering)
+		return;
+
+	hideToastsFromScreen();
+
+	showToastsBottom();					
+}
+
+void LLNearbyChatScreenChannel::showToastsBottom()
+{
+	LLRect rect = getRect();
+
+	LLRect	toast_rect;	
+	S32		bottom = getRect().mBottom;
+
+	for(std::vector<LLToast*>::iterator it = m_active_toasts.begin(); it != m_active_toasts.end(); ++it)
+	{
+		LLToast* toast = (*it);
+		toast_rect = toast->getRect();
+		toast_rect.setLeftTopAndSize(getRect().mLeft, bottom + toast_rect.getHeight()+gSavedSettings.getS32("ToastMargin"), toast_rect.getWidth() ,toast_rect.getHeight());
+		
+		toast->setRect(toast_rect);
+
+		if(toast->getRect().mTop > getRect().getHeight())
+		{
+			while(it!=m_active_toasts.end())
+			{
+				(*it)->setVisible(FALSE);
+				(*it)->stopTimer();
+				m_toast_pool.push_back(*it);
+				it=m_active_toasts.erase(it);
+			}
+			break;
+		}
+		toast->setVisible(TRUE);
+		bottom = toast->getRect().mTop;
+	}
+}
+
+
+//-----------------------------------------------------------------------------------------------
+//LLNearbyChatHandler
+//-----------------------------------------------------------------------------------------------
 LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)
 {
 	mType = type;
-	LLChannelManager::Params p;
-	p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
 
 	// Getting a Channel for our notifications
-	mChannel = LLChannelManager::getInstance()->getChannel(p);
+	LLNearbyChatScreenChannel* channel = new LLNearbyChatScreenChannel(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+	
+	LLNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
+
+	channel->setCreatePanelCallback(callback);
+
+	mChannel = LLChannelManager::getInstance()->addChannel(channel);
 	mChannel->setOverflowFormatString("You have %d unread nearby chat messages");
 }
+
 LLNearbyChatHandler::~LLNearbyChatHandler()
 {
 }
 
+
 void LLNearbyChatHandler::initChannel()
 {
 	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
 	S32 channel_right_bound = nearby_chat->getRect().mRight;
-	S32 channel_width = nearby_chat->getRect().mRight - 16;   //HACK: 16 - ?
+	S32 channel_width = nearby_chat->getRect().mRight; 
 	mChannel->init(channel_right_bound - channel_width, channel_right_bound);
 }
 
@@ -77,41 +274,42 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
 
 	if(chat_msg.mText.empty())
 		return;//don't process empty messages
-
+	
 	LLNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLNearbyChat>("nearby_chat", LLSD());
 	nearby_chat->addMessage(chat_msg);
 	if(nearby_chat->getVisible())
 		return;//no need in toast if chat is visible
-
+	
 	// arrange a channel on a screen
 	if(!mChannel->getVisible())
 	{
 		initChannel();
 	}
-	
+
 	LLUUID id;
 	id.generate();
 
-	LLChatItemCtrl* item = LLChatItemCtrl::createInstance();
-	
-	item->setMessage(chat_msg);
-	//static S32 chat_item_width = nearby_chat->getRect().getWidth() - 16;
-	static S32 chat_item_width = 304;
-	item->setWidth(chat_item_width);
-	item->setHeaderVisibility((EShowItemHeader)gSavedSettings.getS32("nearbychat_showicons_and_names"));
+	LLNearbyChatScreenChannel* channel = dynamic_cast<LLNearbyChatScreenChannel*>(mChannel);
 	
-	item->setVisible(true);
 
-	LLToast::Params p;
-	p.notif_id = id;
-	p.panel = item;
-	p.on_delete_toast = boost::bind(&LLNearbyChatHandler::onDeleteToast, this, _1);
-	mChannel->addToast(p);	
+	if(channel)
+	{
+		LLSD notification;
+		notification["id"] = id;
+		notification["message"] = chat_msg.mText;
+		notification["from"] = chat_msg.mFromName;
+		notification["from_id"] = chat_msg.mFromID;
+		notification["time"] = chat_msg.mTime;
+		notification["source"] = (S32)chat_msg.mSourceType;
+
+		channel->addNotification(notification);	
+	}
+	
 }
 
 void LLNearbyChatHandler::onDeleteToast(LLToast* toast)
 {
 }
 
-}
+
 
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 3893eaa0d4e..755f1235a67 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -100,16 +100,23 @@ bool LLAlertHandler::processNotification(const LLSD& notify)
 		p.can_fade = false;
 		p.is_modal = mIsModal;
 		p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
-		mChannel->addToast(p);
+
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->addToast(p);
 	}
 	else if (notify["sigtype"].asString() == "change")
 	{
 		LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
-		mChannel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
 	}
 	else
 	{
-		mChannel->killToastByNotificationID(notification->getID());
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->killToastByNotificationID(notification->getID());
 	}
 	return true;
 }
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index c488d37ea5a..ffa92b543cc 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -89,7 +89,10 @@ bool LLGroupHandler::processNotification(const LLSD& notify)
 		p.notification = notification;
 		p.panel = notify_box;
 		p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
-		mChannel->addToast(p);
+
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->addToast(p);
 
 		// send a signal to the counter manager
 		mNewNotificationSignal();
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 90ff5fbaaca..cd4e640ec48 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -104,8 +104,8 @@ class LLEventHandler
 	// at the moment, when a handlers creates a channel.
 	virtual void initChannel()=0;
 
-	LLScreenChannel*	mChannel;
-	e_notification_type	mType;
+	LLScreenChannelBase*	mChannel;
+	e_notification_type		mType;
 
 };
 
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 72855ac0fda..070af432d6c 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -48,7 +48,11 @@ LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id)
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->createNotificationChannel();
 	mChannel->setControlHovering(true);
-	mChannel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
+	
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+	if(channel)
+		channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
+
 }
 
 //--------------------------------------------------------------------------
@@ -92,7 +96,10 @@ bool LLScriptHandler::processNotification(const LLSD& notify)
 		p.notification = notification;
 		p.panel = notify_box;	
 		p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
-		mChannel->addToast(p);
+
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->addToast(p);
 
 		// send a signal to the counter manager
 		mNewNotificationSignal();
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index 740acb63659..5186a935694 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -93,8 +93,9 @@ bool LLTipHandler::processNotification(const LLSD& notify)
 		p.is_tip = true;
 		p.can_be_stored = false;
 		
-		mChannel->addToast(p);
-
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel);
+		if(channel)
+			channel->addToast(p);
 	}
 	else if (notify["sigtype"].asString() == "delete")
 	{
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 649697e0912..7ccff730804 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -313,7 +313,7 @@ void LLPanelProfileTab::scrollToTop()
 {
 	LLScrollContainer* scrollContainer = findChild<LLScrollContainer>("profile_scroll");
 	if (scrollContainer)
-	scrollContainer->goToTop();
+		scrollContainer->goToTop();
 }
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index 490c845c949..2b584910a35 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -195,7 +195,7 @@ BOOL LLPanelGroup::postBuild()
 	if(panel_land)		mTabs.push_back(panel_land);
 
 	if(panel_general)
-	panel_general->setupCtrls(this);
+		panel_general->setupCtrls(this);
 	
 	return TRUE;
 }
@@ -206,8 +206,8 @@ void LLPanelGroup::reposButton(const std::string& name)
 	if(!button)
 		return;
 	LLRect btn_rect = button->getRect();
-		btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
-		button->setRect(btn_rect);
+	btn_rect.setLeftTopAndSize( btn_rect.mLeft, btn_rect.getHeight() + 2, btn_rect.getWidth(), btn_rect.getHeight());
+	button->setRect(btn_rect);
 }
 
 void LLPanelGroup::reshape(S32 width, S32 height, BOOL called_from_parent )
@@ -235,7 +235,14 @@ void LLPanelGroup::onBtnCreate()
 	if(!panel_general)
 		return;
 	std::string apply_mesg;
-	panel_general->apply(apply_mesg);//yes yes you need to call apply to create...
+	if(panel_general->apply(apply_mesg))//yes yes you need to call apply to create...
+		return;
+	if ( !apply_mesg.empty() )
+	{
+		LLSD args;
+		args["MESSAGE"] = apply_mesg;
+		LLNotifications::instance().add("GenericAlert", args);
+	}
 }
 
 void LLPanelGroup::onBtnRefresh(void* user_data)
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 5eb7b8f5f5d..2e1d9719953 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -835,6 +835,7 @@ void LLPanelGroupGeneral::reset()
 	{
 		std::string empty_str = "";
 		mEditCharter->setText(empty_str);
+		mGroupNameEditor->setText(empty_str);
 	}
 	
 	{
@@ -850,6 +851,7 @@ void LLPanelGroupGeneral::reset()
 	{
 		mComboMature->setEnabled(true);
 		mComboMature->setVisible( !gAgent.isTeen() );
+		mComboMature->selectFirstItem();
 	}
 
 
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 6a41b6feb98..b2a0a01005a 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -60,11 +60,8 @@
 #include "llvoiceclient.h"
 #include "llworld.h"
 
-using namespace LLOldEvents;
-
 #define FRIEND_LIST_UPDATE_TIMEOUT	0.5
 #define NEARBY_LIST_UPDATE_INTERVAL 1
-#define RECENT_LIST_UPDATE_DELAY	1
 
 static const std::string NEARBY_TAB_NAME	= "nearby_panel";
 static const std::string FRIENDS_TAB_NAME	= "friends_panel";
@@ -102,7 +99,7 @@ static LLRegisterPanelClassWrapper<LLPanelPeople> t_people("panel_people");
 class LLPanelPeople::Updater
 {
 public:
-	typedef boost::function<bool(U32)> callback_t;
+	typedef boost::function<void()> callback_t;
 	Updater(callback_t cb)
 	: mCallback(cb)
 	{
@@ -112,16 +109,6 @@ class LLPanelPeople::Updater
 	{
 	}
 
-	/**
-	 * Force the list updates.
-	 * 
-	 * This may start repeated updates until all names are complete.
-	 */
-	virtual void forceUpdate()
-	{
-		updateList();
-	}
-
 	/**
 	 * Activate/deactivate updater.
 	 *
@@ -130,9 +117,9 @@ class LLPanelPeople::Updater
 	virtual void setActive(bool) {}
 
 protected:
-	bool updateList(U32 mask = 0)
+	void updateList()
 	{
-		return mCallback(mask);
+		mCallback();
 	}
 
 	callback_t		mCallback;
@@ -147,6 +134,11 @@ class LLAvatarListUpdater : public LLPanelPeople::Updater, public LLEventTimer
 	{
 		mEventTimer.stop();
 	}
+
+	virtual BOOL tick() // from LLEventTimer
+	{
+		return FALSE;
+	}
 };
 
 /**
@@ -178,13 +170,6 @@ class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver
 		LLAvatarTracker::instance().removeObserver(this);
 	}
 
-	/*virtual*/ void forceUpdate()
-	{
-		// Perform updates until all names are loaded.
-		if (!updateList(LLFriendObserver::ADD))
-			changed(LLFriendObserver::ADD);
-	}
-
 	/*virtual*/ void changed(U32 mask)
 	{
 		// events can arrive quickly in bulk - we need not process EVERY one of them -
@@ -198,12 +183,12 @@ class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver
 
 	/*virtual*/ BOOL tick()
 	{
-		if (updateList(mMask))
-		{
-			// Got all names, stop updates.
-			mEventTimer.stop();
-			mMask = 0;
-		}
+		if (mMask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
+			updateList();
+
+		// Stop updates.
+		mEventTimer.stop();
+		mMask = 0;
 
 		return FALSE;
 	}
@@ -329,68 +314,9 @@ class LLRecentListUpdater : public LLAvatarListUpdater, public boost::signals2::
 
 public:
 	LLRecentListUpdater(callback_t cb)
-	:	LLAvatarListUpdater(cb, RECENT_LIST_UPDATE_DELAY)
-	{
-		LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::onRecentPeopleChanged, this));
-	}
-
-private:
-	/*virtual*/ void forceUpdate()
-	{
-		onRecentPeopleChanged();
-	}
-	
-	/*virtual*/ BOOL tick()
-	{
-		// Update the list until we get all the names. 
-		if (updateList())
-		{
-			// Got all names, stop updates.
-			mEventTimer.stop();
-		}
-
-		return FALSE;
-	}
-
-	void onRecentPeopleChanged()
-	{
-		if (!updateList())
-		{
-			// Some names are incomplete, schedule another update.
-			mEventTimer.start();
-		}
-	}
-};
-
-/**
- * Updates the group list on events from LLAgent.
- */
-class LLGroupListUpdater : public LLPanelPeople::Updater, public LLSimpleListener
-{
-	LOG_CLASS(LLGroupListUpdater);
-
-public:
-	LLGroupListUpdater(callback_t cb)
-	:	LLPanelPeople::Updater(cb)
-	{
-		gAgent.addListener(this, "new group");
-	}
-
-	~LLGroupListUpdater()
+	:	LLAvatarListUpdater(cb, 0)
 	{
-		gAgent.removeListener(this);
-	}
-
-	/*virtual*/ bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-	{
-		// Why is "new group" sufficient?
-		if (event->desc() == "new group")
-		{
-			updateList();
-			return true;
-		}
-
-		return false;
+		LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::updateList, this));
 	}
 };
 
@@ -404,12 +330,12 @@ LLPanelPeople::LLPanelPeople()
 		mOnlineFriendList(NULL),
 		mAllFriendList(NULL),
 		mNearbyList(NULL),
-		mRecentList(NULL)
+		mRecentList(NULL),
+		mGroupList(NULL)
 {
-	mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::onFriendListUpdate,this, _1));
+	mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList,	this));
 	mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList,	this));
 	mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList,	this));
-	mGroupListUpdater  = new LLGroupListUpdater	(boost::bind(&LLPanelPeople::updateGroupList,	this));
 }
 
 LLPanelPeople::~LLPanelPeople()
@@ -417,7 +343,6 @@ LLPanelPeople::~LLPanelPeople()
 	delete mNearbyListUpdater;
 	delete mFriendListUpdater;
 	delete mRecentListUpdater;
-	delete mGroupListUpdater;
 
 	LLView::deleteViewByHandle(mGroupPlusMenuHandle);
 	LLView::deleteViewByHandle(mNearbyViewSortMenuHandle);
@@ -512,7 +437,7 @@ BOOL LLPanelPeople::postBuild()
 	buttonSetAction("share_btn",		boost::bind(&LLPanelPeople::onShareButtonClicked,		this));
 
 	getChild<LLPanel>(NEARBY_TAB_NAME)->childSetAction("nearby_view_sort_btn",boost::bind(&LLPanelPeople::onNearbyViewSortButtonClicked,		this));
-	getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked,		this));
+	getChild<LLPanel>(RECENT_TAB_NAME)->childSetAction("recent_viewsort_btn",boost::bind(&LLPanelPeople::onRecentViewSortButtonClicked,			this));
 	getChild<LLPanel>(FRIENDS_TAB_NAME)->childSetAction("friends_viewsort_btn",boost::bind(&LLPanelPeople::onFriendsViewSortButtonClicked,		this));
 	getChild<LLPanel>(GROUP_TAB_NAME)->childSetAction("groups_viewsort_btn",boost::bind(&LLPanelPeople::onGroupsViewSortButtonClicked,		this));
 
@@ -547,137 +472,71 @@ BOOL LLPanelPeople::postBuild()
 	if(recent_view_sort)
 		mRecentViewSortMenuHandle  = recent_view_sort->getHandle();
 
-
-
-	// Perform initial update.
-	mFriendListUpdater->forceUpdate();
-	mNearbyListUpdater->forceUpdate();
-	mGroupListUpdater->forceUpdate();
-	mRecentListUpdater->forceUpdate();
-
 	// call this method in case some list is empty and buttons can be in inconsistent state
 	updateButtons();
 
 	return TRUE;
 }
 
-void LLPanelPeople::applyFilterToTab(const std::string& tab_name)
-{
-	if (tab_name == FRIENDS_TAB_NAME) // this tab has two lists
-		filterFriendList();
-	else if (tab_name == NEARBY_TAB_NAME)
-		filterNearbyList();
-	else if (tab_name == RECENT_TAB_NAME)
-		filterRecentList();
-	else if (tab_name == GROUP_TAB_NAME)
-		updateGroupList();
-}
-
-bool LLPanelPeople::updateFriendList(U32 changed_mask)
+void LLPanelPeople::updateFriendList()
 {
-	// Refresh names.
-	if (changed_mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
-	{
-		// get all buddies we know about
-		const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
-		LLAvatarTracker::buddy_map_t all_buddies;
-		av_tracker.copyBuddyList(all_buddies);
-
-		// *TODO: it's suboptimal to rebuild the whole lists on online status change.
+	if (!mOnlineFriendList || !mAllFriendList)
+		return;
 
-		// save them to the online and all friends vectors
-		mOnlineFriendVec.clear();
-		mAllFriendVec.clear();
+	// get all buddies we know about
+	const LLAvatarTracker& av_tracker = LLAvatarTracker::instance();
+	LLAvatarTracker::buddy_map_t all_buddies;
+	av_tracker.copyBuddyList(all_buddies);
 
-		LLFriendCardsManager::folderid_buddies_map_t listMap;
+	// save them to the online and all friends vectors
+	LLAvatarList::uuid_vector_t& online_friendsp = mOnlineFriendList->getIDs();
+	LLAvatarList::uuid_vector_t& all_friendsp = mAllFriendList->getIDs();
 
-		// *NOTE: For now collectFriendsLists returns data only for Friends/All folder. EXT-694.
-		LLFriendCardsManager::instance().collectFriendsLists(listMap);
-		if (listMap.size() > 0)
-		{
-			lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl;
-			mAllFriendVec = listMap.begin()->second;
-		}
-		else
-		{
-			lldebugs << "Friends Cards were not found" << llendl;
-		}
+	all_friendsp.clear();
+	online_friendsp.clear();
 
-		LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
-		for (; buddy_it != all_buddies.end(); ++buddy_it)
-		{
-			LLUUID buddy_id = buddy_it->first;
-			if (av_tracker.isBuddyOnline(buddy_id))
-				mOnlineFriendVec.push_back(buddy_id);
-		}
+	LLFriendCardsManager::folderid_buddies_map_t listMap;
 
-		return filterFriendList();
+	// *NOTE: For now collectFriendsLists returns data only for Friends/All folder. EXT-694.
+	LLFriendCardsManager::instance().collectFriendsLists(listMap);
+	if (listMap.size() > 0)
+	{
+		lldebugs << "Friends Cards were found, count: " << listMap.begin()->second.size() << llendl;
+		all_friendsp = listMap.begin()->second;
+	}
+	else
+	{
+		lldebugs << "Friends Cards were not found" << llendl;
 	}
 
-	return true;
-}
-
-bool LLPanelPeople::updateNearbyList()
-{
-	LLWorld::getInstance()->getAvatars(&mNearbyVec, NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
-	filterNearbyList();
-
-	return true;
-}
-
-bool LLPanelPeople::updateRecentList()
-{
-	LLRecentPeople::instance().get(mRecentVec);
-	filterRecentList();
-
-	return true;
-}
-
-bool LLPanelPeople::updateGroupList()
-{
-	if (!mGroupList)
-		return true; // there's no point in further updates
+	LLAvatarTracker::buddy_map_t::const_iterator buddy_it = all_buddies.begin();
+	for (; buddy_it != all_buddies.end(); ++buddy_it)
+	{
+		LLUUID buddy_id = buddy_it->first;
+		if (av_tracker.isBuddyOnline(buddy_id))
+			online_friendsp.push_back(buddy_id);
+	}
 
-	bool have_names = mGroupList->update(mFilterSubString);
-	updateButtons();
-	return have_names;
+	mOnlineFriendList->setDirty();
+	mAllFriendList->setDirty();
 }
 
-bool LLPanelPeople::filterFriendList()
+void LLPanelPeople::updateNearbyList()
 {
-	if (!mOnlineFriendList || !mAllFriendList)
-		return true; // there's no point in further updates
-
-	// We must always update Friends list to clear the latest removed friend.
-	bool have_names =
-			mOnlineFriendList->update(mOnlineFriendVec, mFilterSubString) &
-			mAllFriendList->update(mAllFriendVec, mFilterSubString);
-
-
-	updateButtons();
-	return have_names;
-}
+	if (!mNearbyList)
+		return;
 
-bool LLPanelPeople::filterNearbyList()
-{
-	bool have_names = mNearbyList->update(mNearbyVec, mFilterSubString);
-	updateButtons();
-	return have_names;
+	LLWorld::getInstance()->getAvatars(&mNearbyList->getIDs(), NULL, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+	mNearbyList->setDirty();
 }
 
-bool LLPanelPeople::filterRecentList()
+void LLPanelPeople::updateRecentList()
 {
 	if (!mRecentList)
-		return true;
-
-	if (mRecentVec.size() > 0)
-	{
-		bool updated = mRecentList->update(mRecentVec, mFilterSubString);
-		updateButtons();
-		return updated;
-	}
+		return;
 
-	return true;
+	LLRecentPeople::instance().get(mRecentList->getIDs());
+	mRecentList->setDirty();
 }
 
 void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
@@ -846,16 +705,19 @@ void LLPanelPeople::onFilterEdit(const std::string& search_string)
 	LLStringUtil::toUpper(mFilterSubString);
 	LLStringUtil::trimHead(mFilterSubString);
 
-	// Apply new filter to current tab.
-	applyFilterToTab(getActiveTabName());
+	// Apply new filter.
+	mNearbyList->setNameFilter(mFilterSubString);
+	mOnlineFriendList->setNameFilter(mFilterSubString);
+	mAllFriendList->setNameFilter(mFilterSubString);
+	mRecentList->setNameFilter(mFilterSubString);
+	mGroupList->setNameFilter(mFilterSubString);
 }
 
 void LLPanelPeople::onTabSelected(const LLSD& param)
 {
 	std::string tab_name = getChild<LLPanel>(param.asString())->getName();
 	mNearbyListUpdater->setActive(tab_name == NEARBY_TAB_NAME);
-	applyFilterToTab(tab_name);
-	// No need to call updateButtons() because applyFilterToTab() does that.
+	updateButtons();
 
 	if (GROUP_TAB_NAME == tab_name)
 		mFilterEditor->setLabel(getString("groups_filter_label"));
@@ -960,17 +822,6 @@ void LLPanelPeople::onAvatarPicked(
 		LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
 }
 
-bool LLPanelPeople::onFriendListUpdate(U32 changed_mask)
-{
-	bool have_names = updateFriendList(changed_mask);
-
-	// Update online status in the Recent tab.
-	// *TODO: isn't it too much to update the whole list?
-//	updateRecentList(); // mantipov: seems online status should be supported by LLAvatarListItem itself.
-
-	return have_names;
-}
-
 void LLPanelPeople::onGroupPlusButtonClicked()
 {
 	LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get();
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 8cd3cc7feba..de27814388b 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -58,15 +58,10 @@ class LLPanelPeople : public LLPanel
 
 private:
 	// methods indirectly called by the updaters
-	bool					updateFriendList(U32 changed_mask);
-	bool					updateNearbyList();
-	bool					updateRecentList();
-	bool					updateGroupList();
-
-	bool					filterFriendList();
-	bool					filterNearbyList();
-	bool					filterRecentList();
-	void					applyFilterToTab(const std::string& tab_name);
+	void					updateFriendList();
+	void					updateNearbyList();
+	void					updateRecentList();
+
 	void					updateButtons();
 	const std::string&		getActiveTabName() const;
 	LLUUID					getCurrentItemID() const;
@@ -110,7 +105,6 @@ class LLPanelPeople : public LLPanel
 	void					onRecentViewSortMenuItemClicked(const LLSD& userdata);
 
 	// misc callbacks
-	bool					onFriendListUpdate(U32 changed_mask);
 	static void				onAvatarPicked(
 								const std::vector<std::string>& names,
 								const std::vector<LLUUID>& ids,
@@ -135,21 +129,8 @@ class LLPanelPeople : public LLPanel
 	Updater*				mFriendListUpdater;
 	Updater*				mNearbyListUpdater;
 	Updater*				mRecentListUpdater;
-	Updater*				mGroupListUpdater;
 
 	std::string				mFilterSubString;
-
-	// The vectors below contain up-to date avatar lists
-	// for the corresponding tabs.
-	// When the user enters a filter, it gets applied
-	// to all the vectors and the result is shown in the tabs.
-	// We don't need to have such a vector for the groups tab
-	// since re-fetching the groups list is always fast.
-	typedef std::vector<LLUUID> uuid_vector_t;
-	uuid_vector_t			mNearbyVec;
-	uuid_vector_t			mOnlineFriendVec;
-	uuid_vector_t			mAllFriendVec;
-	uuid_vector_t			mRecentVec;
 };
 
 #endif //LL_LLPANELPEOPLE_H
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 42185d28e5c..5df3d4f1d63 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -39,8 +39,10 @@
 #include "message.h"
 #include "llagent.h"
 #include "llbutton.h"
+#include "lllineeditor.h"
 #include "llparcel.h"
 #include "llviewerparcelmgr.h"
+#include "lltexteditor.h"
 #include "lltexturectrl.h"
 #include "lluiconstants.h"
 #include "llworldmap.h"
@@ -73,7 +75,8 @@ LLPanelPick::LLPanelPick(BOOL edit_mode/* = FALSE */)
 	mPickId(LLUUID::null),
 	mCreatorId(LLUUID::null),
 	mDataReceived(FALSE),
-	mIsPickNew(false)
+	mIsPickNew(false),
+	mLocationChanged(false)
 {
 	if (edit_mode)
 	{
@@ -123,6 +126,16 @@ BOOL LLPanelPick::postBuild()
 
 	if (mEditMode)
 	{
+		enableSaveButton(FALSE);
+
+		mSnapshotCtrl->setOnSelectCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1));
+
+		LLLineEditor* line_edit = getChild<LLLineEditor>("pick_name");
+		line_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1), NULL);
+		
+		LLTextEditor* text_edit = getChild<LLTextEditor>("pick_desc");
+		text_edit->setKeystrokeCallback(boost::bind(&LLPanelPick::onPickChanged, this, _1));
+
 		childSetAction("cancel_btn", boost::bind(&LLPanelPick::onClickCancel, this));
 		childSetAction("set_to_curr_location_btn", boost::bind(&LLPanelPick::onClickSet, this));
 		childSetAction(XML_BTN_SAVE, boost::bind(&LLPanelPick::onClickSave, this));
@@ -287,6 +300,26 @@ void LLPanelPick::setEditMode( BOOL edit_mode )
 	updateButtons();
 }
 
+void LLPanelPick::onPickChanged(LLUICtrl* ctrl)
+{
+	if(mLocationChanged)
+	{
+		// Pick was enabled in onClickSet
+		return;
+	}
+
+	if( mSnapshotCtrl->isDirty()
+		|| getChild<LLLineEditor>("pick_name")->isDirty()
+		|| getChild<LLTextEditor>("pick_desc")->isDirty() )
+	{
+		enableSaveButton(TRUE);
+	}
+	else
+	{
+		enableSaveButton(FALSE);
+	}
+}
+
 //////////////////////////////////////////////////////////////////////////
 // PROTECTED AREA
 //////////////////////////////////////////////////////////////////////////
@@ -466,6 +499,9 @@ void LLPanelPick::onClickSet()
 		mSimName = parcel->getName();
 	}
 	setPickLocation(createLocationText(std::string(""), SET_LOCATION_NOTICE, mSimName, mPosGlobal));
+
+	mLocationChanged = true;
+	enableSaveButton(TRUE);
 }
 
 // static
@@ -552,3 +588,12 @@ void LLPanelPick::processParcelInfo(const LLParcelData& parcel_data)
 
 	//*NOTE we don't removeObserver(...) ourselves cause LLRemoveParcelProcessor does it for us
 }
+
+void LLPanelPick::enableSaveButton(bool enable)
+{
+	if(!mEditMode)
+	{
+		return;
+	}
+	childSetEnabled(XML_BTN_SAVE, enable);
+}
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index 7ce58b59afd..82cba72bc48 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -74,6 +74,8 @@ class LLPanelPick : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteP
 	// switches the panel to either View or Edit mode
 	void setEditMode(BOOL edit_mode);
 
+	void onPickChanged(LLUICtrl* ctrl);
+
 	// because this panel works in two modes (edit/view) we are  
 	// free from managing two panel for editing and viewing picks and so
 	// are free from controlling switching between them in the parent panel (e.g. Me Profile)
@@ -128,6 +130,8 @@ class LLPanelPick : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteP
 	void onClickSave();
 	void onClickCancel();
 
+	void enableSaveButton(bool enable);
+
 protected:
 	BOOL mEditMode;
 	LLTextureCtrl*	mSnapshotCtrl;
@@ -146,6 +150,7 @@ class LLPanelPick : public LLPanel, public LLAvatarPropertiesObserver, LLRemoteP
 	std::string mLocation;
 
 	commit_callback_t mBackCb;
+	bool mLocationChanged;
 };
 
 #endif // LL_LLPANELPICK_H
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 93317e613f4..e74afba25ac 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -126,8 +126,7 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
 				mPicksList->addItem(picture, pick_value);
 
 				picture->setDoubleClickCallback(boost::bind(&LLPanelPicks::onDoubleClickItem, this, _1));
-				picture->setRightMouseDownCallback(boost::bind(&LLPanelPicks::onRightMouseDownItem, this, _1, _2, _3, _4));
-				picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
+				picture->setRightMouseUpCallback(boost::bind(&LLPanelPicks::onRightMouseUpItem, this, _1, _2, _3, _4));
 				picture->setMouseUpCallback(boost::bind(&LLPanelPicks::updateButtons, this));
 			}
 
@@ -260,8 +259,10 @@ void LLPanelPicks::onClickMap()
 }
 
 
-void LLPanelPicks::onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
+void LLPanelPicks::onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask)
 {
+	updateButtons();
+
 	if (mPopupMenu)
 	{
 		mPopupMenu->buildDrawLabels();
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 27a21305b3f..7ebdc3089c8 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -100,7 +100,7 @@ class LLPanelPicks
 	void updateButtons();
 
 	virtual void onDoubleClickItem(LLUICtrl* item);
-	virtual void onRightMouseDownItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
+	virtual void onRightMouseUpItem(LLUICtrl* item, S32 x, S32 y, MASK mask);
 
 	LLPanelProfile* getProfilePanel();
 
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 4e070df7eb6..80ecc95afb3 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -337,7 +337,7 @@ void LLPanelPlaces::onFilterEdit(const std::string& search_string)
 		LLStringUtil::trimHead(mFilterSubString);
 
 		if (mActivePanel)
-		mActivePanel->onSearchEdit(mFilterSubString);
+			mActivePanel->onSearchEdit(mFilterSubString);
 	}
 }
 
@@ -386,7 +386,7 @@ void LLPanelPlaces::onTeleportButtonClicked()
 	else
 	{
 		if (mActivePanel)
-		mActivePanel->onTeleport();
+			mActivePanel->onTeleport();
 	}
 }
 
@@ -432,7 +432,7 @@ void LLPanelPlaces::onShowOnMapButtonClicked()
 	else
 	{
 		if (mActivePanel)
-		mActivePanel->onShowOnMap();
+			mActivePanel->onShowOnMap();
 	}
 }
 
@@ -510,7 +510,7 @@ void LLPanelPlaces::onOverflowMenuItemClicked(const LLSD& param)
 			addChild(mPickPanel);
 
 			mPickPanel->setExitCallback(boost::bind(&LLPanelPlaces::togglePickPanel, this, FALSE));
-	}
+		}
 
 		togglePickPanel(TRUE);
 
@@ -733,7 +733,7 @@ void LLPanelPlaces::updateVerbs()
 	else
 	{
 		if (mActivePanel)
-		mActivePanel->updateVerbs();
+			mActivePanel->updateVerbs();
 	}
 }
 
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index f6672d9c8b6..32cccc4ac08 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -306,12 +306,12 @@ void LLTeleportHistoryPanel::showTeleportHistory()
 					
 					if (curr_tab <= tabs_cnt - 4)
 					{
-					curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
+						curr_date.secondsSinceEpoch(curr_date.secondsSinceEpoch() - seconds_in_day);
 					}
 					else if (curr_tab == tabs_cnt - 3) // 6 day and older, low boundary is 1 month
 					{
 						curr_date =  LLDate::now();
-					curr_date.split(&curr_year, &curr_month, &curr_day);
+						curr_date.split(&curr_year, &curr_month, &curr_day);
 						curr_month--;
 						if (0 == curr_month)
 						{
@@ -376,7 +376,7 @@ void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
 	S32 tabs_cnt = mItemContainers.size();
 
 	for (S32 n = 0; n < tabs_cnt; n++)
-		{
+	{
 		LLAccordionCtrlTab* tab = mItemContainers.get(n);
 
 		if (!tab->getVisible())
@@ -390,7 +390,7 @@ void LLTeleportHistoryPanel::handleItemSelect(LLFlatListView* selected)
 			continue;
 
 		flv->resetSelection(true);
-		}
+	}
 
 	updateVerbs();
 }
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 082bba027ff..06bdf64b196 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -55,36 +55,30 @@ using namespace LLNotificationsUI;
 bool LLScreenChannel::mWasStartUpToastShown = false;
 
 //--------------------------------------------------------------------------
-LLScreenChannel::LLScreenChannel(LLUUID& id):	mOverflowToastPanel(NULL), mStartUpToastPanel(NULL),
-												mToastAlignment(NA_BOTTOM), mCanStoreToasts(true),
-												mHiddenToastsNum(0), mOverflowToastHidden(false),
-												mIsHovering(false), mControlHovering(false),
-												mShowToasts(true)
+//////////////////////
+// LLScreenChannelBase
+//////////////////////
+LLScreenChannelBase::LLScreenChannelBase(const LLUUID& id) :
+												mOverflowToastPanel(NULL) 
+												,mToastAlignment(NA_BOTTOM)
+												,mCanStoreToasts(true)
+												,mHiddenToastsNum(0)
+												,mOverflowToastHidden(false)
+												,mIsHovering(false)
+												,mControlHovering(false)
+												,mShowToasts(false)
 {	
 	mID = id;
 	mOverflowFormatString = LLTrans::getString("OverflowInfoChannelString");
-	mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannel::updatePositionAndSize, this, _1, _2));
+	mWorldViewRectConnection = gViewerWindow->setOnWorldViewRectUpdated(boost::bind(&LLScreenChannelBase::updatePositionAndSize, this, _1, _2));
 	setMouseOpaque( false );
 	setVisible(FALSE);
 }
-
-//--------------------------------------------------------------------------
-void LLScreenChannel::init(S32 channel_left, S32 channel_right)
-{
-	S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
-	S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
-	setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
-	setVisible(TRUE);
-}
-
-//--------------------------------------------------------------------------
-LLScreenChannel::~LLScreenChannel() 
+LLScreenChannelBase::~LLScreenChannelBase()
 {
 	mWorldViewRectConnection.disconnect();
 }
-
-//--------------------------------------------------------------------------
-void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
+void LLScreenChannelBase::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
 {
 	S32 top_delta = old_world_rect.mTop - new_world_rect.mTop;
 	S32 right_delta = old_world_rect.mRight - new_world_rect.mRight;
@@ -105,6 +99,42 @@ void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_wo
 	}
 	setRect(this_rect);
 	redrawToasts();
+	
+}
+
+void LLScreenChannelBase::init(S32 channel_left, S32 channel_right)
+{
+	S32 channel_top = gViewerWindow->getWorldViewRect().getHeight();
+	S32 channel_bottom = gViewerWindow->getWorldViewRect().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
+	setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
+	setVisible(TRUE);
+}
+
+//--------------------------------------------------------------------------
+//////////////////////
+// LLScreenChannel
+//////////////////////
+//--------------------------------------------------------------------------
+LLScreenChannel::LLScreenChannel(LLUUID& id):	LLScreenChannelBase(id)
+{	
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::init(S32 channel_left, S32 channel_right)
+{
+	LLScreenChannelBase::init(channel_left, channel_right);
+}
+
+//--------------------------------------------------------------------------
+LLScreenChannel::~LLScreenChannel() 
+{
+	
+}
+
+//--------------------------------------------------------------------------
+void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
+{
+	LLScreenChannelBase::updatePositionAndSize(old_world_rect, new_world_rect);
 }
 
 //--------------------------------------------------------------------------
@@ -561,7 +591,7 @@ void LLScreenChannel::removeAndStoreAllStorableToasts()
 		else
 		{
 			++it;
-	}
+		}
 	}
 	redrawToasts();
 }
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index f1ef6bd64df..459c28ac7c3 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -55,10 +55,95 @@ typedef enum e_channel_alignment
 	CA_RIGHT,
 } EChannelAlignment;
 
+class LLScreenChannelBase : public LLUICtrl
+{
+	friend class LLChannelManager;
+public:
+	LLScreenChannelBase(const LLUUID& id);
+	~LLScreenChannelBase();
+
+	// Channel's outfit-functions
+	// update channel's size and position in the World View
+	virtual void		updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
+	// initialization of channel's shape and position
+	virtual void		init(S32 channel_left, S32 channel_right);
+
+
+	virtual void		setToastAlignment(EToastAlignment align) {mToastAlignment = align;}
+	
+	virtual void		setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;}
+	virtual void		setOverflowFormatString ( const std::string& str)  { mOverflowFormatString = str; }
+	
+	// kill or modify a toast by its ID
+	virtual void		killToastByNotificationID(LLUUID id) {};
+	virtual void		modifyToastNotificationByID(LLUUID id, LLSD data) {};
+	
+	// hide all toasts from screen, but not remove them from a channel
+	virtual void		hideToastsFromScreen() {};
+	// removes all toasts from a channel
+	virtual void		removeToastsFromChannel() {};
+	
+	// show all toasts in a channel
+	virtual void		redrawToasts() {};
+
+	virtual void 		closeOverflowToastPanel() {};
+	virtual void 		hideOverflowToastPanel() {};
+
+	
+	// Channel's behavior-functions
+	// set whether a channel will control hovering inside itself or not
+	virtual void setControlHovering(bool control) { mControlHovering = control; }
+	// set Hovering flag for a channel
+	virtual void setHovering(bool hovering) { mIsHovering = hovering; }
+	
+	void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
+
+	void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
+	bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
+
+	// get number of hidden notifications from a channel
+	S32	 getNumberOfHiddenToasts() { return mHiddenToastsNum;}
+
+	
+	void setShowToasts(bool show) { mShowToasts = show; }
+	bool getShowToasts() { return mShowToasts; }
+
+	// get toast allignment preset for a channel
+	e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
+	
+	// get ID of a channel
+	LLUUID	getChannelID() { return mID; }
+
+protected:
+	// Channel's flags
+	bool		mControlHovering;
+	bool		mIsHovering;
+	bool		mCanStoreToasts;
+	bool		mDisplayToastsAlways;
+	bool		mOverflowToastHidden;
+	// controls whether a channel shows toasts or not
+	bool		mShowToasts;
+	// 
+	EToastAlignment		mToastAlignment;
+	EChannelAlignment	mChannelAlignment;
+
+	// attributes for the Overflow Toast
+	S32			mHiddenToastsNum;
+	LLToast*	mOverflowToastPanel;	
+	std::string mOverflowFormatString;
+
+	// channel's ID
+	LLUUID	mID;
+
+	// store a connection to prevent futher crash that is caused by sending a signal to a destroyed channel
+	boost::signals2::connection mWorldViewRectConnection;
+};
+
+
 /**
  * Screen channel manages toasts visibility and positioning on the screen.
  */
-class LLScreenChannel : public LLUICtrl
+class LLScreenChannel : public LLScreenChannelBase
 {
 	friend class LLChannelManager;
 public:
@@ -70,12 +155,6 @@ class LLScreenChannel : public LLUICtrl
 	void		updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
 	// initialization of channel's shape and position
 	void		init(S32 channel_left, S32 channel_right);
-	// set allignment of toasts inside a channel
-	void		setToastAlignment(EToastAlignment align) {mToastAlignment = align;}
-	// set allignment of channel inside a world view
-	void		setChannelAlignment(EChannelAlignment align) {mChannelAlignment = align;}
-	// set a template for a string in the OverflowToast
-	void		setOverflowFormatString ( std::string str)  { mOverflowFormatString = str; }
 	
 	// Operating with toasts
 	// add a toast to a channel
@@ -104,37 +183,17 @@ class LLScreenChannel : public LLUICtrl
 	// close the StartUp Toast
 	void		closeStartUpToast();
 
-	// Channel's behavior-functions
-	// set whether a channel will control hovering inside itself or not
-	void setControlHovering(bool control) { mControlHovering = control; }
-	// set Hovering flag for a channel
-	void setHovering(bool hovering) { mIsHovering = hovering; }
-	// set whether a channel will store faded toasts or not
-	void setCanStoreToasts(bool store) { mCanStoreToasts = store; }
-	// tell all channels that the StartUp toast was shown and allow them showing of toasts
-	static void	setStartUpToastShown() { mWasStartUpToastShown = true; }
 	// get StartUp Toast's state
 	static bool	getStartUpToastShown() { return mWasStartUpToastShown; }
-	// set mode for dislaying of toasts
-	void setDisplayToastsAlways(bool display_toasts) { mDisplayToastsAlways = display_toasts; }
-	// get mode for dislaying of toasts
-	bool getDisplayToastsAlways() { return mDisplayToastsAlways; }
-	// tell a channel to show toasts or not
-	void setShowToasts(bool show) { mShowToasts = show; }
-	// determine whether channel shows toasts or not
-	bool getShowToasts() { return mShowToasts; }
+	// tell all channels that the StartUp toast was shown and allow them showing of toasts
+	static void	setStartUpToastShown() { mWasStartUpToastShown = true; }
 	// let a channel update its ShowToast flag
 	void updateShowToastsState();
 
+
 	// Channel's other interface functions functions
-	// get number of hidden notifications from a channel
-	S32		getNumberOfHiddenToasts() { return mHiddenToastsNum;}
 	// update number of notifications in the StartUp Toast
 	void	updateStartUpString(S32 num);
-	// get toast allignment preset for a channel
-	e_notification_toast_alignment getToastAlignment() {return mToastAlignment;}
-	// get ID of a channel
-	LLUUID	getChannelID() { return mID; }
 
 	// Channel's signals
 	// signal on storing of faded toasts event
@@ -201,30 +260,10 @@ class LLScreenChannel : public LLUICtrl
 
 	// Channel's flags
 	static bool	mWasStartUpToastShown;
-	bool		mControlHovering;
-	bool		mIsHovering;
-	bool		mCanStoreToasts;
-	bool		mDisplayToastsAlways;
-	bool		mOverflowToastHidden;
-	// controls whether a channel shows toasts or not
-	bool		mShowToasts;
-	// 
-	EToastAlignment		mToastAlignment;
-	EChannelAlignment	mChannelAlignment;
-
-	// attributes for the Overflow Toast
-	S32			mHiddenToastsNum;
-	LLToast*	mOverflowToastPanel;	
-	std::string mOverflowFormatString;
 
 	// attributes for the StartUp Toast	
 	LLToast* mStartUpToastPanel;
 
-	// channel's ID
-	LLUUID	mID;
-
-	// store a connection to prevent futher crash that is caused by sending a signal to a destroyed channel
-	boost::signals2::connection mWorldViewRectConnection;
 
 	std::vector<ToastElem>		mToastList;
 	std::vector<ToastElem>		mStoredToastList;
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 381e63f020b..2be0aa40d28 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -48,6 +48,7 @@
 #include "lliconctrl.h"//for Home tab icon
 #include "llsidetraypanelcontainer.h"
 #include "llwindow.h"//for SetCursor
+#include "lltransientfloatermgr.h"
 
 //#include "llscrollcontainer.h"
 
@@ -248,6 +249,7 @@ LLSideTray::LLSideTray(Params& params)
 	// register handler function to process data from the xml. 
 	// panel_name should be specified via "parameter" attribute.
 	commit.add("SideTray.ShowPanel", boost::bind(&LLSideTray::showPanel, this, _2, LLUUID::null));
+	LLTransientFloaterMgr::getInstance()->addControlView(this);
 }
 
 
@@ -448,13 +450,17 @@ void LLSideTray::reflectCollapseChange()
 	setPanelRect();
 
 	if(mCollapsed)
+	{
 		gFloaterView->setSnapOffsetRight(0);
+		setFocus(FALSE);
+	}
 	else
+	{
 		gFloaterView->setSnapOffsetRight(mMaxBarWidth);
+		setFocus(TRUE);
+	}
 
 	gFloaterView->refresh();
-
-	setFocus( FALSE );
 }
 
 void LLSideTray::arrange			()
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index d7df258750a..b0930cd86de 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -225,22 +225,14 @@ void LLStatusBar::draw()
 
 BOOL LLStatusBar::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
-	if (mHideNavbarContextMenu)
-	{
-		mHideNavbarContextMenu->buildDrawLabels();
-		mHideNavbarContextMenu->updateParent(LLMenuGL::sMenuContainer);
-		LLMenuGL::showPopup(this, mHideNavbarContextMenu, x, y);
-	}
-
+	show_navbar_context_menu(this,x,y);
 	return TRUE;
 }
 
 BOOL LLStatusBar::postBuild()
 {
-	mHideNavbarContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	gMenuHolder->addChild(mHideNavbarContextMenu);
 
-	gMenuBarView->setRightMouseDownCallback(boost::bind(&LLStatusBar::onMainMenuRightClicked, this, _1, _2, _3, _4));
+	gMenuBarView->setRightMouseDownCallback(boost::bind(&show_navbar_context_menu, _1, _2, _3));
 
 	return TRUE;
 }
@@ -560,11 +552,6 @@ void LLStatusBar::setupDate()
 	}
 }
 
-void LLStatusBar::onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
-{
-	handleRightMouseDown(x, y, mask);
-}
-
 // static
 void LLStatusBar::onClickStatGraph(void* data)
 {
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 81a69e9590e..d5629e6f1eb 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -91,7 +91,6 @@ class LLStatusBar
 	// simple method to setup the part that holds the date
 	void setupDate();
 
-	void onMainMenuRightClicked(LLUICtrl* ctrl, S32 x, S32 y, MASK mask);
 	static void onCommitSearch(LLUICtrl*, void* data);
 	static void onClickSearch(void* data);
 	static void onClickStatGraph(void* data);
@@ -111,8 +110,7 @@ class LLStatusBar
 	S32				mSquareMetersCommitted;
 	LLFrameTimer*	mBalanceTimer;
 	LLFrameTimer*	mHealthTimer;
-	LLMenuGL*		mHideNavbarContextMenu;
-	
+		
 	static std::vector<std::string> sDays;
 	static std::vector<std::string> sMonths;
 	static const U32 MAX_DATE_STRING_LENGTH;
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index c1eecf4c12c..2206e79c6f6 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -108,6 +108,14 @@ BOOL LLSysWellWindow::postBuild()
 	return LLDockableFloater::postBuild();
 }
 
+//---------------------------------------------------------------------------------
+void LLSysWellWindow::setMinimized(BOOL minimize)
+{
+	setVisible(!minimize);
+
+	LLFloater::setMinimized(minimize);
+}
+
 //---------------------------------------------------------------------------------
 void LLSysWellWindow::connectListUpdaterToSignal(std::string notification_type)
 {
@@ -155,10 +163,10 @@ void LLSysWellWindow::addItem(LLSysWellItem::Params p)
 	{
 		handleItemAdded(IT_NOTIFICATION);
 
-	reshapeWindow();
+		reshapeWindow();
 
-	new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
-	new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
+		new_item->setOnItemCloseCallback(boost::bind(&LLSysWellWindow::onItemClose, this, _1));
+		new_item->setOnItemClickCallback(boost::bind(&LLSysWellWindow::onItemClick, this, _1));
 	}
 	else
 	{
@@ -226,11 +234,11 @@ void LLSysWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
 //---------------------------------------------------------------------------------
 void LLSysWellWindow::initChannel() 
 {
-	LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
+	LLNotificationsUI::LLScreenChannelBase* channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(
 																LLUUID(gSavedSettings.getString("NotificationChannelUUID")));
-	if(channel)
+	mChannel = dynamic_cast<LLNotificationsUI::LLScreenChannel*>(channel);
+	if(mChannel)
 	{
-		mChannel = channel;
 		mChannel->setOnStoreToastCallback(boost::bind(&LLSysWellWindow::onStoreToast, this, _1, _2));
 	}
 	else
@@ -240,7 +248,7 @@ void LLSysWellWindow::initChannel()
 }
 
 //---------------------------------------------------------------------------------
-void LLSysWellWindow::getEnabledRect(LLRect& rect)
+void LLSysWellWindow::getAllowedRect(LLRect& rect)
 {
 	rect = gViewerWindow->getWorldViewRect();
 }
@@ -252,7 +260,7 @@ void LLSysWellWindow::toggleWindow()
 	{
 		setDockControl(new LLDockControl(
 				LLBottomTray::getInstance()->getSysWell(), this,
-				getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getEnabledRect, this, _1)));
+				getDockTongue(), LLDockControl::TOP, boost::bind(&LLSysWellWindow::getAllowedRect, this, _1)));
 	}
 
 	if(!getVisible())
@@ -404,20 +412,18 @@ bool LLSysWellWindow::isWindowEmpty()
 
 //---------------------------------------------------------------------------------
 //virtual
-void LLSysWellWindow::sessionAdded(const LLUUID& sessionId,
-		const std::string& name, const LLUUID& otherParticipantId)
+void LLSysWellWindow::sessionAdded(const LLUUID& session_id,
+		const std::string& name, const LLUUID& other_participant_id)
 {
-	if (mMessageList->getItemByValue(get_session_value(sessionId)) == NULL)
+	//*TODO get rid of get_session_value, session_id's are unique, cause performance degradation with lots chiclets (IB)
+	if (mMessageList->getItemByValue(get_session_value(session_id)) == NULL)
 	{
-		S32 chicletCounter = 0;
-		LLIMModel::LLIMSession* session = get_if_there(LLIMModel::sSessionsMap,
-				sessionId, (LLIMModel::LLIMSession*) NULL);
-		if (session != NULL)
+		S32 chicletCounter = LLIMModel::getInstance()->getNumUnread(session_id);
+		if (chicletCounter > -1)
 		{
-			chicletCounter = session->mNumUnread;
+			addIMRow(session_id, chicletCounter, name, other_participant_id);	
+			reshapeWindow();
 		}
-		addIMRow(sessionId, chicletCounter, name, otherParticipantId);
-		reshapeWindow();
 	}
 }
 
@@ -491,6 +497,7 @@ LLSysWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID&
 	switch (im_chiclet_type)
 	{
 	case LLIMChiclet::TYPE_GROUP:
+	case LLIMChiclet::TYPE_AD_HOC:
 		mChiclet = getChild<LLIMChiclet>("group_chiclet");
 		childSetVisible("p2p_chiclet", false);
 		break;
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 37a2690a828..203b9497154 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -68,6 +68,8 @@ class LLSysWellWindow : public LLDockableFloater, LLIMSessionObserver
 	void toggleWindow();
 	/*virtual*/ BOOL	canClose() { return FALSE; }
 	/*virtual*/ void	setDocked(bool docked, bool pop_on_undock = true);
+	// override LLFloater's minimization according to EXT-1216
+	/*virtual*/ void	setMinimized(BOOL minimize);
 
 	// Handlers
 	void onItemClick(LLSysWellItem* item);
@@ -86,8 +88,8 @@ class LLSysWellWindow : public LLDockableFloater, LLIMSessionObserver
 		IT_INSTANT_MESSAGE
 	}EItemType; 
 
-	// gets a rect valid for SysWellWindow's position on a screen (EXT-1111)
-	void getEnabledRect(LLRect& rect);
+	// gets a rect that bounds possible positions for the SysWellWindow on a screen (EXT-1111)
+	void getAllowedRect(LLRect& rect);
 	// connect counter and list updaters to the corresponding signals
 	void connectListUpdaterToSignal(std::string notification_type);
 	// init Window's channel
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 97a15759bf8..ecaf4fb1503 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -167,15 +167,30 @@ void LLToast::tick()
 }
 
 //--------------------------------------------------------------------------
-void LLToast::insertPanel(LLPanel* panel)
+
+void LLToast::reshapeToPanel()
 {
-	LLRect panel_rect, toast_rect;
+	LLPanel* panel = getPanel();
+	if(!panel)
+		return;
+
+	LLRect panel_rect;
 
 	panel_rect = panel->getRect();
 	reshape(panel_rect.getWidth(), panel_rect.getHeight());
 	panel_rect.setLeftTopAndSize(0, panel_rect.getHeight(), panel_rect.getWidth(), panel_rect.getHeight());
 	panel->setRect(panel_rect);
+	
+	LLRect toast_rect = getRect();
+	toast_rect.setLeftTopAndSize(toast_rect.mLeft,toast_rect.mTop,panel_rect.getWidth(), panel_rect.getHeight());
+	setRect(toast_rect);
+
+}
+
+void LLToast::insertPanel(LLPanel* panel)
+{
 	addChild(panel);	
+	reshapeToPanel();
 }
 
 //--------------------------------------------------------------------------
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 9248747c439..2166351fd03 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -99,6 +99,9 @@ class LLToast : public LLFloater
 	// Operating with toasts
 	// insert a panel to a toast
 	void insertPanel(LLPanel* panel);
+
+	void reshapeToPanel();
+
 	// get toast's panel
 	LLPanel* getPanel() { return mPanel; }
 	// enable/disable Toast's Hide button
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index bc9888f4b48..418373e8c60 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -39,6 +39,12 @@
 
 #include <string>
 
+class LLToastPanelBase: public LLPanel 
+{
+public:
+	virtual void init(LLSD& data){};
+};
+
 /**
  * Base class for all panels that can be added to the toast.
  * All toast panels should contain necessary logic for representing certain notification
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 671a62962b3..12253455a39 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -7666,6 +7666,19 @@ class LLHelpShowFirstTimeTip : public view_listener_t
 	}
 };
 
+void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y)
+{
+	static LLMenuGL*	show_navbar_context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_hide_navbar.xml",
+			gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	if(gMenuHolder->hasVisibleMenu())
+	{
+		gMenuHolder->hideMenus();
+	}
+	show_navbar_context_menu->buildDrawLabels();
+	show_navbar_context_menu->updateParent(LLMenuGL::sMenuContainer);
+	LLMenuGL::showPopup(ctrl, show_navbar_context_menu, x, y);
+}
+
 void initialize_menus()
 {
 	// A parameterized event handler used as ctrl-8/9/0 zoom controls below.
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index cf482266d6c..dd6aac2dd3d 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -52,6 +52,7 @@ void show_debug_menus(); // checks for if menus should be shown first.
 void toggle_debug_menus(void*);
 void show_context_menu( S32 x, S32 y, MASK mask );
 void show_build_mode_context_menu(S32 x, S32 y, MASK mask);
+void show_navbar_context_menu(LLView* ctrl, S32 x, S32 y);
 BOOL enable_save_into_inventory(void*);
 void handle_reset_view();
 void handle_cut(void*);
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index d23f10f8801..4a0efbaddc2 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -3223,9 +3223,9 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_trans
 	// assume that pickAsync put the results in the back of the mPicks list
 	if(mPicks.size() != 0)
 	{
-	mLastPick = mPicks.back();
-	mLastPick.fetchResults();
-	mPicks.pop_back();
+		mLastPick = mPicks.back();
+		mLastPick.fetchResults();
+		mPicks.pop_back();
 	}
 	else
 	{
diff --git a/indra/newview/skins/default/xui/en/floater_sys_well.xml b/indra/newview/skins/default/xui/en/floater_sys_well.xml
index 30406cad63e..aef5707fd4e 100644
--- a/indra/newview/skins/default/xui/en/floater_sys_well.xml
+++ b/indra/newview/skins/default/xui/en/floater_sys_well.xml
@@ -12,7 +12,7 @@
  width="320"
  min_width="320"
  height="23"
- can_minimize="false"
+ can_minimize="true"
  can_tear_off="false"
  can_resize="false"
  can_drag_on_left="false"
@@ -22,10 +22,10 @@
     <flat_list_view
 	    color="FloaterDefaultBackgroundColor"
 	    follows="all"
-	layout="topleft"
-			name="notification_list"
-			left="1"
+	    layout="topleft"
+	    name="notification_list"
+	    left="1"
 	    top="20"
-			height="0"
-			width="318"/>
+	    height="0"
+	    width="318"/>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 648c3458e0e..2c77f61da68 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -128,13 +128,13 @@
                  function="World.SetAway" />
             </menu_item_call>
             <menu_item_separator
-				layout="topleft"/>
+             layout="topleft"/>
             <menu_item_call
              label="Set Busy"
              layout="topleft"
              name="Set Busy">
                 <menu_item_call.on_click
-					function="World.SetBusy"/>
+                 function="World.SetBusy"/>
             </menu_item_call>
         </menu>
         <menu_item_separator
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 90b331a39f7..cd7e340ff1a 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -79,7 +79,6 @@
              label="Move"
              layout="topleft"
              name="movement_btn"
-             tab_stop="false"
              tool_tip="Shows/Hide Movement controls" 
              top="6"
              width="70">
@@ -117,7 +116,6 @@
              label="View"
              layout="topleft"
              left="0"
-             tab_stop="false"
              tool_tip="Shows/Hide Camera controls" 
              top="6"
              name="camera_btn"
@@ -133,7 +131,6 @@
              height="20"
              width="20"
              left_pad="0"
-             tab_stop="false"
              is_toggle="true"
              picture_style="true"
          	 image_selected="toggle_button_selected"
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index c4c8aa24c44..fb4ce436e8c 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -28,7 +28,7 @@
      width="25"
      height="25"
      label=""
-     follows="top|left"
+     follows="top|right"
      image_overlay="BackArrow_Off"
      tab_stop="false" />
     <text
@@ -41,6 +41,7 @@
      text_color="white"
      follows="top|left|right"
      mouse_opaque="true"
+     use_ellipses="true"
      name="group_name">(Loading...)</text>
     <line_editor
      follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index 683a54b3662..4088d96ebf5 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -35,6 +35,8 @@
      follows="right"
      height="20"
      speak_button.font="SansSerifMedium"
+     speak_button.tab_stop="true"
+     show_button.tab_stop="true"
      layout="topleft"
      left_pad="5"
      name="talk"
diff --git a/indra/newview/skins/default/xui/en/panel_notes.xml b/indra/newview/skins/default/xui/en/panel_notes.xml
index 58ebac2a842..2056ec14d52 100644
--- a/indra/newview/skins/default/xui/en/panel_notes.xml
+++ b/indra/newview/skins/default/xui/en/panel_notes.xml
@@ -2,7 +2,7 @@
 <panel
  bevel_style="in"
  follows="left|top|right|bottom"
- height="420"
+ height="460"
  label="Notes &amp; Privacy"
  layout="topleft"
  left="0"
@@ -16,7 +16,7 @@
      layout="topleft"
      left="0"
      top="0"
-     height="420"
+     height="430"
      width="313"
      border_size="0">
         <panel
diff --git a/indra/newview/skins/default/xui/en/panel_picks.xml b/indra/newview/skins/default/xui/en/panel_picks.xml
index d0bde77cf29..1bd19533972 100644
--- a/indra/newview/skins/default/xui/en/panel_picks.xml
+++ b/indra/newview/skins/default/xui/en/panel_picks.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
  follows="left|top|right|bottom"
- height="515"
+ height="555"
  label="Picks"
  layout="topleft"
  left="0"
@@ -11,7 +11,7 @@
         <flat_list_view
          color="DkGray2"
          follows="left|top|right|bottom"
-         height="495"
+         height="465"
          layout="topleft"
          left="0"
          name="picks_list"
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index 56ba5970f20..02d179d5032 100644
--- a/indra/newview/skins/default/xui/en/panel_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
  follows="all"
- height="515"
+ height="560"
  label="Profile"
  layout="topleft"
  left="0"
@@ -25,7 +25,7 @@
     <scroll_container
      color="DkGray2"
      follows="left|top|right|bottom"
-     height="515"
+     height="500"
      min_height="300"
      layout="topleft"
      name="profile_scroll"
@@ -265,6 +265,7 @@
      left="0"
      name="profile_buttons_panel"
      top_pad="0"
+     height="25"
      width="313">
         <button
          follows="bottom|left"
@@ -316,6 +317,7 @@
      name="profile_me_buttons_panel"
      top_pad="0"
      visible="false"
+     height="25"
      width="313">
         <button
          follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml
index cbe646f3cca..606535115d3 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml
@@ -2,7 +2,7 @@
 <panel
  background_visible="true"
  follows="all"
- height="660"
+ height="570"
  layout="topleft"
  min_height="350"
  min_width="240"
@@ -50,7 +50,7 @@
      width="25" />
     <tab_container
      follows="left|top|right|bottom"
-     height="660"
+     height="560"
      layout="topleft"
      left="10"
      name="tabs"
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
index a0fc9864237..aa95a2baefe 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
@@ -111,7 +111,7 @@
              width="380">
 	    </flat_list_view>
 	</accordion_tab>     
-     
+          
         <accordion_tab
          can_resize="false"
          layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
index cb876da8d80..824a815a99d 100644
--- a/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
+++ b/indra/newview/skins/default/xui/en/widgets/scroll_list.xml
@@ -10,9 +10,9 @@
              highlighted_color="ScrollHighlightedColor"
              column_padding="5"
              draw_stripes="true"
+             scroll_bar_bg_visible="false"
+             scroll_bar_bg_color="black"
              background_visible="false"
              heading_height="23"
              draw_border="false"
-             draw_heading="false"
-             scroll_bar_bg_visible="false"
-             scroll_bar_bg_color="black" />
+             draw_heading="false" />
diff --git a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
index 6e73e997e06..e998635d201 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_combo_box.xml
@@ -12,17 +12,20 @@
  <combo_editor
   select_on_focus="true"
   text_pad_left="20" 
+  tool_tip="Search"
   background_image="TextField_Search_Off"
   background_image_disabled="TextField_Search_Disabled"
   background_image_focused="TextField_Search_Active"/>
  <combo_list
   multi_select="false"
-  page_lines="10" />
+  page_lines="10"
+  scroll_bar_bg_visible="true" />
  <search_button label=""
   top_pad="4"
   left_pad="4" 
   width="13"
   height="13" 
+  tool_tip="Search"
   image_unselected="Search"
   image_selected="Search" />
 </search_combo_box>
\ No newline at end of file
-- 
GitLab