From 73a97010e6c8c7874fdc1778ab46e492f77d9394 Mon Sep 17 00:00:00 2001
From: Steven Bennetts <steve@lindenlab.com>
Date: Tue, 21 Jul 2009 00:57:23 +0000
Subject: [PATCH] merge
 https://svn.aws.productengine.com/secondlife/export-from-ll/viewer-2-0/indra@1059
 https://svn.aws.productengine.com/secondlife/pe/stable-1/indra@1070 ->
 svn+ssh://svn.lindenlab.com/svn/linden/branches/viewer/viewer-2.0.0-3

---
 indra/llui/llui.h                             |   5 +
 indra/newview/CMakeLists.txt                  |  12 +-
 indra/newview/llagent.cpp                     |  13 +-
 indra/newview/llavataractions.cpp             | 276 ++++++
 indra/newview/llavataractions.h               |  88 ++
 indra/newview/llavatariconctrl.cpp            |   8 +-
 indra/newview/llbottomtray.cpp                | 361 ++++---
 indra/newview/llbottomtray.h                  |  57 +-
 indra/newview/llchatbar.cpp                   | 692 --------------
 indra/newview/llchatbar.h                     | 120 ---
 indra/newview/llchiclet.cpp                   | 900 +++++++++++-------
 indra/newview/llchiclet.h                     | 584 ++++++++++--
 indra/newview/llfavoritesbar.cpp              |  66 +-
 indra/newview/llfavoritesbar.h                |   2 +-
 indra/newview/llfloaterchat.cpp               |  22 -
 indra/newview/llfloaterchat.h                 |   1 -
 indra/newview/llfloaterfriends.cpp            |  16 +-
 indra/newview/llfloaterinspect.cpp            |   6 +-
 indra/newview/llfloaterland.cpp               |   6 +-
 indra/newview/llfloaterproperties.cpp         |   6 +-
 indra/newview/llgesturemgr.cpp                |   4 +-
 indra/newview/llhudtext.cpp                   |   5 -
 indra/newview/llimpanel.cpp                   |   4 +-
 indra/newview/llimview.cpp                    |   2 +-
 indra/newview/llinventorybridge.cpp           |  19 +-
 indra/newview/llmenucommands.cpp              |  13 +-
 indra/newview/lloverlaybar.cpp                |   8 -
 indra/newview/llpanelavatar.cpp               |  12 +-
 indra/newview/llpanelclassified.cpp           |   5 +-
 indra/newview/llpanelgroupgeneral.cpp         |   4 +-
 indra/newview/llpanelgrouproles.cpp           |   4 +-
 indra/newview/llpanellandmarks.cpp            |   5 +
 indra/newview/llpanellandmarks.h              |   1 +
 indra/newview/llpanelpeople.cpp               |  30 +-
 indra/newview/llpanelpermissions.cpp          |   6 +-
 indra/newview/llpanelpick.cpp                 |  18 +-
 indra/newview/llpanelpick.h                   |   5 +
 indra/newview/llpanelplaceinfo.cpp            |  43 +-
 indra/newview/llpanelplaceinfo.h              |   6 +-
 indra/newview/llpanelplaces.cpp               |  75 +-
 indra/newview/llpanelplaces.h                 |  16 +-
 indra/newview/llsidetray.cpp                  |   6 +-
 indra/newview/llviewergesture.cpp             |   5 +-
 indra/newview/llviewerkeyboard.cpp            |  27 +-
 indra/newview/llviewermenu.cpp                |  12 +-
 indra/newview/llviewerwindow.cpp              |  53 +-
 .../skins/default/xui/en/accordion_drag.xml   |   8 +
 .../default/xui/en/menu_imchiclet_group.xml   |  27 +
 .../default/xui/en/menu_imchiclet_p2p.xml     |  43 +
 .../skins/default/xui/en/notifications.xml    |   5 +-
 .../skins/default/xui/en/panel_bottomtray.xml |  42 +-
 .../skins/default/xui/en/panel_edit_pick.xml  |   1 +
 .../default/xui/en/panel_pick_list_item.xml   |   3 +-
 .../skins/default/xui/en/panel_places.xml     |  10 +-
 .../skins/default/xui/en/panel_side_tray.xml  | 124 +--
 .../xui/en/widgets/gesture_combo_box.xml      |  29 +
 56 files changed, 2156 insertions(+), 1765 deletions(-)
 create mode 100644 indra/newview/llavataractions.cpp
 create mode 100644 indra/newview/llavataractions.h
 delete mode 100644 indra/newview/llchatbar.cpp
 delete mode 100644 indra/newview/llchatbar.h
 create mode 100644 indra/newview/skins/default/xui/en/accordion_drag.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
 create mode 100644 indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
 create mode 100644 indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml

diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 6f0da055358..9399eff2ab9 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -397,7 +397,12 @@ class LLUISingleton: public LLUIFactory<T, LLUISingleton<T, VISIBILITY_POLICY>,
 		delete sInstance;
 		sInstance = NULL;
 	}
+
+	static bool instanceExists() { return NULL != sInstance; }
 	
+private:
+	LLUISingleton(const LLUISingleton&){}
+	LLUISingleton& operator=(const LLUISingleton&){}
 private:
 	static T*	sInstance;
 };
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index d9d2f6f7327..ac3163a1bd3 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -63,6 +63,7 @@ include_directories(
     )
 
 set(viewer_SOURCE_FILES
+    llaccordionctrltab.cpp
     llaccordionpanel.cpp
     llagent.cpp
     llagentaccess.cpp
@@ -75,6 +76,7 @@ set(viewer_SOURCE_FILES
     llassetuploadresponders.cpp
     llassetuploadqueue.cpp
     llaudiosourcevo.cpp
+    llavataractions.cpp
     llavatariconctrl.cpp
     llavatarlist.cpp
     llavatarlistitem.cpp
@@ -86,13 +88,11 @@ set(viewer_SOURCE_FILES
     llcallingcard.cpp
     llcapabilitylistener.cpp
     llcaphttpsender.cpp
-    llchatbar.cpp
     llchathistoryscroll.cpp
     llchiclet.cpp
     llclassifiedinfo.cpp
     llclassifiedstatsresponder.cpp
     llcloud.cpp
-    llcollapsiblectrl.cpp
     llcolorswatch.cpp
     llcommandhandler.cpp
     llcommandlineparser.cpp
@@ -213,7 +213,6 @@ set(viewer_SOURCE_FILES
     llfolderview.cpp
     llfolderviewitem.cpp
     llfollowcam.cpp
-    llfriendactions.cpp
     llgesturemgr.cpp
     llgivemoney.cpp
     llglsandbox.cpp
@@ -350,6 +349,7 @@ set(viewer_SOURCE_FILES
     lltexturectrl.cpp
     lltexturefetch.cpp
     lltextureview.cpp
+    lltoggleablemenu.cpp
     lltoolbar.cpp
     lltoolbrush.cpp
     lltoolcomp.cpp
@@ -483,6 +483,7 @@ endif (LINUX)
 set(viewer_HEADER_FILES
     CMakeLists.txt
     ViewerInstall.cmake
+    llaccordionctrltab.h
     llaccordionpanel.h
     llagent.h
     llagentaccess.h
@@ -496,6 +497,7 @@ set(viewer_HEADER_FILES
     llassetuploadresponders.h
     llassetuploadqueue.h
     llaudiosourcevo.h
+    llavataractions.h
     llavatariconctrl.h
     llavatarlist.h
     llavatarlistitem.h
@@ -508,13 +510,11 @@ set(viewer_HEADER_FILES
     llcapabilitylistener.h
     llcapabilityprovider.h
     llcaphttpsender.h
-    llchatbar.h
     llchathistoryscroll.h
     llchiclet.h
     llclassifiedinfo.h
     llclassifiedstatsresponder.h
     llcloud.h
-    llcollapsiblectrl.h
     llcolorswatch.h
     llcommandhandler.h
     llcommandlineparser.h
@@ -637,7 +637,6 @@ set(viewer_HEADER_FILES
     llfoldervieweventlistener.h
     llfolderviewitem.h
     llfollowcam.h
-    llfriendactions.h
     llgesturemgr.h
     llgivemoney.h
     llgroupactions.h
@@ -777,6 +776,7 @@ set(viewer_HEADER_FILES
     lltexturectrl.h
     lltexturefetch.h
     lltextureview.h
+    lltoggleablemenu.h
     lltool.h
     lltoolbar.h
     lltoolbrush.h
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index cdf9a6b059f..afad88770ef 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -37,7 +37,6 @@
 
 #include "llanimationstates.h"
 #include "llcallingcard.h"
-#include "llchatbar.h"
 #include "llconsole.h"
 #include "lldrawable.h"
 #include "llfirstuse.h"
@@ -2722,8 +2721,7 @@ void LLAgent::startTyping()
 	{
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
 	}
-	if(gBottomTray)
-		gBottomTray->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
+	LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
 }
 
 //-----------------------------------------------------------------------------
@@ -2735,8 +2733,7 @@ void LLAgent::stopTyping()
 	{
 		clearRenderState(AGENT_STATE_TYPING);
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
-		if(gBottomTray)
-			gBottomTray->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
+		LLBottomTray::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
 	}
 }
 
@@ -2811,8 +2808,7 @@ void LLAgent::endAnimationUpdateUI()
 		LLNavigationBar::getInstance()->setVisible(TRUE);
 		gStatusBar->setVisibleForMouselook(true);
 
-		if(gBottomTray)
-			gBottomTray->setVisible(TRUE);
+		LLBottomTray::getInstance()->setVisible(TRUE);
 
 		LLSideTray::getInstance()->setVisible(TRUE);
 
@@ -2902,8 +2898,7 @@ void LLAgent::endAnimationUpdateUI()
 		LLNavigationBar::getInstance()->setVisible(FALSE);
 		gStatusBar->setVisibleForMouselook(false);
 
-		if(gBottomTray)
-			gBottomTray->setVisible(FALSE);
+		LLBottomTray::getInstance()->setVisible(FALSE);
 
 		LLSideTray::getInstance()->setVisible(FALSE);
 
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
new file mode 100644
index 00000000000..2cf7298569f
--- /dev/null
+++ b/indra/newview/llavataractions.cpp
@@ -0,0 +1,276 @@
+/** 
+ * @file llavataractions.cpp
+ * @brief Friend-related actions (add, remove, offer teleport, etc)
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llavataractions.h"
+
+#include "llsd.h"
+#include "lldarray.h"
+#include "llnotifications.h"
+
+#include "llagent.h"
+#include "llappviewer.h"		// for gLastVersionChannel
+#include "llcallingcard.h"		// for LLAvatarTracker
+#include "llinventorymodel.h"
+#include "llimview.h"			// for gIMMgr
+#include "llsidetray.h"
+#include "llviewermessage.h"	// for handle_lure
+#include "llviewerregion.h"
+
+// static
+void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::string& name)
+{
+	if(id == gAgentID)
+	{
+		LLNotifications::instance().add("AddSelfFriend");
+		return;
+	}
+
+	LLSD args;
+	args["NAME"] = name;
+	LLSD payload;
+	payload["id"] = id;
+	payload["name"] = name;
+    // Look for server versions like: Second Life Server 1.24.4.95600
+	if (gLastVersionChannel.find(" 1.24.") != std::string::npos)
+	{
+		// Old and busted server version, doesn't support friend
+		// requests with messages.
+    	LLNotifications::instance().add("AddFriend", args, payload, &callbackAddFriend);
+	}
+	else
+	{
+    	LLNotifications::instance().add("AddFriendWithMessage", args, payload, &callbackAddFriendWithMessage);
+	}
+}
+
+// static
+void LLAvatarActions::removeFriendDialog(const LLUUID& id)
+{
+	if (id.isNull())
+		return;
+
+	std::vector<LLUUID> ids;
+	ids.push_back(id);
+	removeFriendsDialog(ids);
+}
+
+// static
+void LLAvatarActions::removeFriendsDialog(const std::vector<LLUUID>& ids)
+{
+	if(ids.size() == 0)
+		return;
+
+	LLSD args;
+	std::string msgType;
+	if(ids.size() == 1)
+	{
+		LLUUID agent_id = ids[0];
+		std::string first, last;
+		if(gCacheName->getName(agent_id, first, last))
+		{
+			args["FIRST_NAME"] = first;
+			args["LAST_NAME"] = last;	
+		}
+
+		msgType = "RemoveFromFriends";
+	}
+	else
+	{
+		msgType = "RemoveMultipleFromFriends";
+	}
+
+	LLSD payload;
+	for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+	{
+		payload["ids"].append(*it);
+	}
+
+	LLNotifications::instance().add(msgType,
+		args,
+		payload,
+		&handleRemove);
+}
+
+// static
+void LLAvatarActions::offerTeleport(const LLUUID& invitee)
+{
+	if (invitee.isNull())
+		return;
+
+	LLDynamicArray<LLUUID> ids;
+	ids.push_back(invitee);
+	offerTeleport(ids);
+}
+
+// static
+void LLAvatarActions::offerTeleport(const std::vector<LLUUID>& ids) 
+{
+	if (ids.size() > 0)
+		handle_lure(ids);
+}
+
+// static
+void LLAvatarActions::startIM(const LLUUID& id)
+{
+	if (id.isNull())
+		return;
+
+	std::string name;
+	gCacheName->getFullName(id, name);
+	gIMMgr->addSession(name, IM_NOTHING_SPECIAL, id);
+	make_ui_sound("UISndStartIM");
+}
+
+// static
+void LLAvatarActions::startConference(const std::vector<LLUUID>& ids)
+{
+	// *HACK: Copy into dynamic array
+	LLDynamicArray<LLUUID> id_array;
+	for (std::vector<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+	{
+		id_array.push_back(*it);
+	}
+	gIMMgr->addSession("Friends Conference", IM_SESSION_CONFERENCE_START, ids[0], id_array);
+	make_ui_sound("UISndStartIM");
+}
+
+// static
+void LLAvatarActions::showProfile(const LLUUID& id)
+{
+	if (id.notNull())
+	{
+		LLSD params;
+		params["id"] = id;
+		params["open_tab_name"] = "panel_profile";
+
+		//Show own profile
+		if(gAgent.getID() == id)
+		{
+			LLSideTray::getInstance()->showPanel("panel_me_profile", params);
+		}
+		//Show other user profile
+		else
+		{
+			LLSideTray::getInstance()->showPanel("panel_profile_view", params);
+		}
+	}
+}
+
+//== private methods ========================================================================================
+
+// static
+bool LLAvatarActions::handleRemove(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotification::getSelectedOption(notification, response);
+
+	const LLSD& ids = notification["payload"]["ids"];
+	for (LLSD::array_const_iterator itr = ids.beginArray(); itr != ids.endArray(); ++itr)
+	{
+		LLUUID id = itr->asUUID();
+		const LLRelationship* ip = LLAvatarTracker::instance().getBuddyInfo(id);
+		if (ip)
+		{
+			switch (option)
+			{
+			case 0: // YES
+				if( ip->isRightGrantedTo(LLRelationship::GRANT_MODIFY_OBJECTS))
+				{
+					LLAvatarTracker::instance().empower(id, FALSE);
+					LLAvatarTracker::instance().notifyObservers();
+				}
+				LLAvatarTracker::instance().terminateBuddy(id);
+				LLAvatarTracker::instance().notifyObservers();
+				gInventory.addChangedMask(LLInventoryObserver::LABEL | LLInventoryObserver::CALLING_CARD, LLUUID::null);
+				gInventory.notifyObservers();
+				break;
+
+			case 1: // NO
+			default:
+				llinfos << "No removal performed." << llendl;
+				break;
+			}
+		}
+	}
+	return false;
+}
+
+// static
+bool LLAvatarActions::callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if (option == 0)
+	{
+		requestFriendship(notification["payload"]["id"].asUUID(), 
+		    notification["payload"]["name"].asString(),
+		    response["message"].asString());
+	}
+	return false;
+}
+
+// static
+bool LLAvatarActions::callbackAddFriend(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotification::getSelectedOption(notification, response);
+	if (option == 0)
+	{
+		// Servers older than 1.25 require the text of the message to be the
+		// calling card folder ID for the offering user. JC
+		LLUUID calling_card_folder_id = 
+			gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
+		std::string message = calling_card_folder_id.asString();
+		requestFriendship(notification["payload"]["id"].asUUID(), 
+		    notification["payload"]["name"].asString(),
+		    message);
+	}
+    return false;
+}
+
+// static
+void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message)
+{
+	LLUUID calling_card_folder_id = gInventory.findCategoryUUIDForType(LLAssetType::AT_CALLINGCARD);
+	send_improved_im(target_id,
+					 target_name,
+					 message,
+					 IM_ONLINE,
+					 IM_FRIENDSHIP_OFFERED,
+					 calling_card_folder_id);
+}
+
+//static
+bool LLAvatarActions::isFriend(const LLUUID& id)
+{
+	return ( NULL != LLAvatarTracker::instance().getBuddyInfo(id) );
+}
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
new file mode 100644
index 00000000000..73325d21f14
--- /dev/null
+++ b/indra/newview/llavataractions.h
@@ -0,0 +1,88 @@
+/** 
+ * @file llavataractions.h
+ * @brief Friend-related actions (add, remove, offer teleport, etc)
+ *
+ * $LicenseInfo:firstyear=2009&license=viewergpl$
+ * 
+ * Copyright (c) 2009, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAVATARACTIONS_H
+#define LL_LLAVATARACTIONS_H
+
+/**
+ * Friend-related actions (add, remove, offer teleport, etc)
+ */
+class LLAvatarActions
+{
+public:
+	/**
+	 * Show a dialog explaining what friendship entails, then request friendship.
+	 */
+	static void requestFriendshipDialog(const LLUUID& id, const std::string& name);
+
+	/**
+	 * Show a friend removal dialog.
+	 */
+	static void removeFriendDialog(const LLUUID& id);
+	static void removeFriendsDialog(const std::vector<LLUUID>& ids);
+	
+	/**
+	 * Show teleport offer dialog.
+	 */
+	static void offerTeleport(const LLUUID& invitee);
+	static void offerTeleport(const std::vector<LLUUID>& ids);
+
+	/**
+	 * Start instant messaging session.
+	 */
+	static void startIM(const LLUUID& id);
+
+	/**
+	 * Start conference chat with the given avatars.
+	 */
+	static void startConference(const std::vector<LLUUID>& ids);
+
+	/**
+	 * Show avatar profile.
+	 */
+	static void showProfile(const LLUUID& id);
+
+	/**
+	 * Return true if avatar with "id" is a friend
+	 */
+	static bool isFriend(const LLUUID& id);
+
+private:
+	static bool callbackAddFriend(const LLSD& notification, const LLSD& response);
+	static bool callbackAddFriendWithMessage(const LLSD& notification, const LLSD& response);
+	static bool handleRemove(const LLSD& notification, const LLSD& response);
+
+	// Just request friendship, no dialog.
+	static void requestFriendship(const LLUUID& target_id, const std::string& target_name, const std::string& message);
+};
+
+#endif // LL_LLAVATARACTIONS_H
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index bf18abfdb34..a3b8f6726d0 100644
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -36,7 +36,7 @@
 #include "llavatarconstants.h"
 #include "llavatariconctrl.h"
 #include "llcallingcard.h" // for LLAvatarTracker
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "llimview.h"
 #include "llmenugl.h"
 #include "lluictrlfactory.h"
@@ -230,7 +230,7 @@ void LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked(const LLSD& userdata)
 
 	if (level == "profile")
 	{
-		LLFriendActions::showProfile(id);
+		LLAvatarActions::showProfile(id);
 	}
 	else if (level == "im")
 	{
@@ -248,10 +248,10 @@ void LLAvatarIconCtrl::onAvatarIconContextMenuItemClicked(const LLSD& userdata)
 		name.append(" ");
 		name.append(getLastName());
 
-		LLFriendActions::requestFriendshipDialog(id, name);
+		LLAvatarActions::requestFriendshipDialog(id, name);
 	}
 	else if (level == "remove")
 	{
-		LLFriendActions::removeFriendDialog(id);
+		LLAvatarActions::removeFriendDialog(id);
 	}
 }
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index d7fd97e0674..e37b6609519 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -40,24 +40,133 @@
 #include "llgesturemgr.h"
 #include "llanimationstates.h"
 #include "llmultigesture.h"
+#include "llviewerstats.h"
+#include "llcommandhandler.h"
 
-//FIXME: temporary, for send_chat_from_viewer() proto
-#include "llchatbar.h"
 //FIXME: temporary, for stand up proto
 #include "llselectmgr.h" 
 #include "llvoavatarself.h"
-//
-// Globals
-//
-//FIXME: made it adjustable
-const F32 AGENT_TYPING_TIMEOUT = 5.f;	// seconds
 
-LLBottomTray* gBottomTray = NULL;
+S32 LLBottomTray::mLastSpecialChatChannel = 0;
 
-LLBottomTray::LLBottomTray()
-	: mLastSpecialChatChannel(0)
+// legacy calllback glue
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
+
+static LLDefaultChildRegistry::Register<LLGestureComboBox> r("gesture_combo_box");
+
+LLGestureComboBox::LLGestureComboBox(const LLComboBox::Params& p)
+	: LLComboBox(p)
 	, mGestureLabelTimer()
-	, mChatBox(NULL)
+{
+	setCommitCallback(boost::bind(&LLGestureComboBox::onCommitGesture, this, _1));
+
+	// now register us as observer since we have a place to put the results
+	gGestureManager.addObserver(this);
+
+	// refresh list from current active gestures
+	refreshGestures();
+}
+
+LLGestureComboBox::~LLGestureComboBox()
+{
+	gGestureManager.removeObserver(this);
+}
+
+void LLGestureComboBox::refreshGestures()
+{
+	//store current selection so we can maintain it
+	std::string cur_gesture = getValue().asString();
+	selectFirstItem();
+	std::string label = getValue().asString();;
+	// clear
+	clearRows();
+
+	// collect list of unique gestures
+	std::map <std::string, BOOL> unique;
+	LLGestureManager::item_map_t::iterator it;
+	for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it)
+	{
+		LLMultiGesture* gesture = (*it).second;
+		if (gesture)
+		{
+			if (!gesture->mTrigger.empty())
+			{
+				unique[gesture->mTrigger] = TRUE;
+			}
+		}
+	}
+
+	// add unique gestures
+	std::map <std::string, BOOL>::iterator it2;
+	for (it2 = unique.begin(); it2 != unique.end(); ++it2)
+	{
+		addSimpleElement((*it2).first);
+	}
+
+	sortByName();
+	// Insert label after sorting, at top, with separator below it
+	addSeparator(ADD_TOP);		
+	//FIXME: get it from xml
+	addSimpleElement("Gestures", ADD_TOP);	
+
+	if (!cur_gesture.empty())
+	{ 
+		selectByValue(LLSD(cur_gesture));
+	}
+	else
+	{
+		selectFirstItem();
+	}
+}
+
+void LLGestureComboBox::onCommitGesture(LLUICtrl* ctrl)
+{
+	LLCtrlListInterface* gestures = getListInterface();
+	if (gestures)
+	{
+		S32 index = gestures->getFirstSelectedIndex();
+		if (index == 0)
+		{
+			return;
+		}
+		const std::string& trigger = gestures->getSelectedValue().asString();
+
+		// pretend the user chatted the trigger string, to invoke
+		// substitution and logging.
+		std::string text(trigger);
+		std::string revised_text;
+		gGestureManager.triggerAndReviseString(text, &revised_text);
+
+		revised_text = utf8str_trim(revised_text);
+		if (!revised_text.empty())
+		{
+			// Don't play nodding animation
+			LLBottomTray::sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE);
+		}
+	}
+
+	mGestureLabelTimer.start();
+	// free focus back to chat bar
+	setFocus(FALSE);
+}
+
+//virtual
+void LLGestureComboBox::draw()
+{
+	// HACK: Leave the name of the gesture in place for a few seconds.
+	const F32 SHOW_GESTURE_NAME_TIME = 2.f;
+	if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME)
+	{
+		LLCtrlListInterface* gestures = getListInterface();
+		if (gestures) gestures->selectFirstItem();
+		mGestureLabelTimer.stop();
+	}
+
+	LLComboBox::draw();
+}
+
+LLBottomTray::LLBottomTray(const LLSD&)
+	: mChatBox(NULL)
 	, mChicletPanel(NULL)
 	, mIMWell(NULL)
 	, mSysWell(NULL)
@@ -72,7 +181,7 @@ LLBottomTray::LLBottomTray()
 	mSysWell = getChild<LLNotificationChiclet>("sys_well",TRUE,FALSE);
 	mChatBox = getChild<LLLineEditor>("chat_box",TRUE,FALSE);
 
-	mChicletPanel->setChicletClickCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));
+	mChicletPanel->setChicletClickedCallback(boost::bind(&LLBottomTray::onChicletClick,this,_1));
 
 	if (mChatBox)
 	{
@@ -91,17 +200,7 @@ LLBottomTray::LLBottomTray()
 
 	}
 
-	mGestureCombo = getChild<LLComboBox>( "Gesture", TRUE, FALSE);
-	if (mGestureCombo)
-	{
-		mGestureCombo->setCommitCallback(boost::bind(&LLBottomTray::onCommitGesture, this, _1));
-
-		// now register us as observer since we have a place to put the results
-		gGestureManager.addObserver(this);
-
-		// refresh list from current active gestures
-		refreshGestures();
-	}
+	mGestureCombo = getChild<LLGestureComboBox>( "Gesture", TRUE, FALSE);
 
 	////FIXME: temporary, for stand up proto
 	mStandUpBtn = getChild<LLButton> ("stand", TRUE, FALSE);
@@ -116,11 +215,13 @@ LLBottomTray::LLBottomTray()
 	//and thus is deleted at the end of the viewers lifetime, but to be cleanly
 	//destroyed LLBottomTray requires some subsystems that are long gone
 	LLUI::getRootView()->addChild(this);
+
+	// Necessary for focus movement among child controls
+	setFocusRoot(TRUE);
 }
 
 LLBottomTray::~LLBottomTray()
 {
-	gGestureManager.removeObserver(this);
 	if (!LLSingleton<LLIMMgr>::destroyed())
 	{
 		LLIMMgr::getInstance()->removeSessionObserver(this);
@@ -132,7 +233,7 @@ void LLBottomTray::onChicletClick(LLUICtrl* ctrl)
 	LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl);
 	if (chiclet)
 	{
-		LLFloaterReg::showInstance("communicate", chiclet->getIMSessionId());
+		LLFloaterReg::showInstance("communicate", chiclet->getSessionId());
 	}
 }
 
@@ -278,30 +379,23 @@ void LLBottomTray::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata
 	gAgent.stopTyping();
 }
 
-void LLBottomTray::refresh()
+BOOL LLBottomTray::inputEditorHasFocus()
 {
-	// HACK: Leave the name of the gesture in place for a few seconds.
-	const F32 SHOW_GESTURE_NAME_TIME = 2.f;
-	if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME)
-	{
-		LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL;
-		if (gestures) gestures->selectFirstItem();
-		mGestureLabelTimer.stop();
-	}
+	return mChatBox && mChatBox->hasFocus();
+}
 
-	if ((gAgent.getTypingTime() > AGENT_TYPING_TIMEOUT) && (gAgent.getRenderState() & AGENT_STATE_TYPING))
-	{
-		gAgent.stopTyping();
-	}
-	
-	LLPanel::refresh();
+std::string LLBottomTray::getCurrentChat()
+{
+	return mChatBox ? mChatBox->getText() : LLStringUtil::null;
 }
 
+//virtual
 void LLBottomTray::draw()
 {
 	refreshStandUp();
 	LLPanel::draw();
 }
+
 void LLBottomTray::refreshStandUp()
 {
 	//FIXME: temporary, for stand up proto
@@ -329,39 +423,6 @@ void LLBottomTray::updateRightPosition(const S32 new_right_position)
 	}
 }
 
-void LLBottomTray::onCommitGesture(LLUICtrl* ctrl)
-{
-	LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL;
-	if (gestures)
-	{
-		S32 index = gestures->getFirstSelectedIndex();
-		if (index == 0)
-		{
-			return;
-		}
-		const std::string& trigger = gestures->getSelectedValue().asString();
-
-		// pretend the user chatted the trigger string, to invoke
-		// substitution and logging.
-		std::string text(trigger);
-		std::string revised_text;
-		gGestureManager.triggerAndReviseString(text, &revised_text);
-
-		revised_text = utf8str_trim(revised_text);
-		if (!revised_text.empty())
-		{
-			// Don't play nodding animation
-			sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE);
-		}
-	}
-	mGestureLabelTimer.start();
-	if (mGestureCombo != NULL)
-	{
-		// free focus back to chat bar
-		mGestureCombo->setFocus(FALSE);
-	}
-}
-
 //FIXME: temporary, for stand up proto
 void LLBottomTray::onCommitStandUp(LLUICtrl* ctrl)
 {
@@ -369,80 +430,56 @@ void LLBottomTray::onCommitStandUp(LLUICtrl* ctrl)
 	gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
 }
 
-void LLBottomTray::refreshGestures()
+//virtual
+void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
 {
-	if (mGestureCombo)
+	if(getChicletPanel())
 	{
-		
-		//store current selection so we can maintain it
-		std::string cur_gesture = mGestureCombo->getValue().asString();
-		mGestureCombo->selectFirstItem();
-		std::string label = mGestureCombo->getValue().asString();;
-		// clear
-		mGestureCombo->clearRows();
-		
-		// collect list of unique gestures
-		std::map <std::string, BOOL> unique;
-		LLGestureManager::item_map_t::iterator it;
-		for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it)
-		{
-			LLMultiGesture* gesture = (*it).second;
-			if (gesture)
-			{
-				if (!gesture->mTrigger.empty())
-				{
-					unique[gesture->mTrigger] = TRUE;
-				}
-			}
-		}
-		
-		// add unique gestures
-		std::map <std::string, BOOL>::iterator it2;
-		for (it2 = unique.begin(); it2 != unique.end(); ++it2)
+		if(getChicletPanel()->findChiclet<LLChiclet>(session_id))
 		{
-			mGestureCombo->addSimpleElement((*it2).first);
-		}
-		
-		mGestureCombo->sortByName();
-		// Insert label after sorting, at top, with separator below it
-		mGestureCombo->addSeparator(ADD_TOP);		
-		mGestureCombo->addSimpleElement(getString("gesture_label"), ADD_TOP);
-		
-		if (!cur_gesture.empty())
-		{ 
-			mGestureCombo->selectByValue(LLSD(cur_gesture));
+
 		}
 		else
 		{
-			mGestureCombo->selectFirstItem();
+			LLIMChiclet* chicklet = getChicletPanel()->createChiclet<LLIMChiclet>(session_id);
+			chicklet->setIMSessionName(name);
+			chicklet->setOtherParticipantId(other_participant_id);
+
+			if(getChicletPanel()->getChicletCount())
+			{
+				setChicletPanelVisible(true);
+			}
 		}
 	}
 }
 
 //virtual
-void LLBottomTray::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+void LLBottomTray::sessionRemoved(const LLUUID& session_id)
 {
 	if(getChicletPanel())
 	{
-		if(getChicletPanel()->findIMChiclet(session_id))
-		{
+		getChicletPanel()->removeChiclet(session_id);
 
-		}
-		else
+		if(0 == getChicletPanel()->getChicletCount())
 		{
-			LLIMChiclet* chicklet = (LLIMChiclet *)getChicletPanel()->createChiclet(session_id);
-			chicklet->setIMSessionName(name);
-			chicklet->setOtherParticipantId(other_participant_id);
+			setChicletPanelVisible(false);
 		}
 	}
 }
 
-//virtual
-void LLBottomTray::sessionRemoved(const LLUUID& session_id)
+void LLBottomTray::setChicletPanelVisible(bool visible)
 {
-	if(getChicletPanel())
+	// Chiclet panel is placed in layout_panel, which is child of layout_stack.
+	// To gide chiclet panel we need to also hide layout_panel to make layout_stack resize its
+	// content.
+	getChicletPanel()->getParent()->setVisible(visible);
+	if(visible)
 	{
-		getChicletPanel()->removeIMChiclet(session_id);
+		// Reshape layout stack after making chiclet panel visible
+		LLView* layout = getChild<LLView>("toolbar_stack");
+		LLRect rc = layout->getRect();
+		layout->reshape(rc.getWidth(), rc.getHeight());
+		layout->setRect(rc);
 	}
 }
 
@@ -503,6 +540,41 @@ void LLBottomTray::setVisible(BOOL visible)
 
 }
 
+// static 
+void LLBottomTray::startChat(const char* line)
+{
+	LLBottomTray *bt = LLBottomTray::getInstance();
+
+	if(bt && bt->getChatBox())
+	{
+		bt->setVisible(TRUE);
+		bt->getChatBox()->setFocus(TRUE);
+
+		if (line)
+		{
+			std::string line_string(line);
+			bt->getChatBox()->setText(line_string);
+		}
+
+		bt->getChatBox()->setCursorToEnd();
+	}
+}
+
+// Exit "chat mode" and do the appropriate focus changes
+// static
+void LLBottomTray::stopChat()
+{
+	LLBottomTray *bt = LLBottomTray::getInstance();
+
+	if(bt && bt->getChatBox())
+	{
+		bt->getChatBox()->setFocus(FALSE);
+	}
+
+ 	// stop typing animation
+ 	gAgent.stopTyping();
+}
+
 void LLBottomTray::sendChat( EChatType type )
 {
 	if (mChatBox)
@@ -593,3 +665,42 @@ LLWString LLBottomTray::stripChannelNumber(const LLWString &mesg, S32* channel)
 		return mesg;
 	}
 }
+
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
+{
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_ChatFromViewer);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->nextBlockFast(_PREHASH_ChatData);
+	msg->addStringFast(_PREHASH_Message, utf8_out_text);
+	msg->addU8Fast(_PREHASH_Type, type);
+	msg->addS32("Channel", channel);
+
+	gAgent.sendReliableMessage();
+
+	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
+}
+
+class LLChatHandler : public LLCommandHandler
+{
+public:
+	// not allowed from outside the app
+	LLChatHandler() : LLCommandHandler("chat", true) { }
+
+    // Your code here
+	bool handle(const LLSD& tokens, const LLSD& query_map,
+				LLWebBrowserCtrl* web)
+	{
+		if (tokens.size() < 2) return false;
+		S32 channel = tokens[0].asInteger();
+		std::string mesg = tokens[1].asString();
+		send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
+		return true;
+	}
+};
+
+// Creating the object registers with the dispatcher.
+LLChatHandler gChatHandler;
+
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 0d477122d1d..1d4e271f804 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -37,20 +37,40 @@
 #include "llimview.h"
 #include "llchat.h"
 #include "llgesturemgr.h"
+#include "llcombobox.h"
 
 class LLChicletPanel;
 class LLNotificationChiclet;
 class LLTalkButton;
-class LLComboBox;
 
-class LLBottomTray 
-	: public LLPanel
-	, public LLIMSessionObserver
+class LLGestureComboBox
+	: public LLComboBox
 	, public LLGestureManagerObserver
 {
+protected:
+	LLGestureComboBox(const LLComboBox::Params&);
+	friend class LLUICtrlFactory;
 public:
-	LLBottomTray();
+	~LLGestureComboBox();
+
+	void refreshGestures();
+	void onCommitGesture(LLUICtrl* ctrl);
+	virtual void draw();
+
+	// LLGestureManagerObserver trigger
+	virtual void changed() { refreshGestures(); }
+
+protected:
+	LLFrameTimer mGestureLabelTimer;
+};
 
+class LLBottomTray 
+	: public LLUISingleton<LLBottomTray>
+	, public LLPanel
+	, public LLIMSessionObserver
+{
+	friend class LLUISingleton<LLBottomTray>;
+public:
 	~LLBottomTray();
 
 	LLLineEditor*		getChatBox()	{return mChatBox;}
@@ -59,12 +79,14 @@ class LLBottomTray
 	LLNotificationChiclet*	getSysWell()	{return mSysWell;}
 
 	void onChatBoxCommit();
-	void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
-	void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
+	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
+	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
 	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
 	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
 
-	void refresh();
+	BOOL inputEditorHasFocus();
+	std::string getCurrentChat();
+
 	/*virtual*/void draw();
 	void refreshStandUp();
 	void updateRightPosition(const S32 new_right_position);
@@ -77,33 +99,34 @@ class LLBottomTray
 	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
 	virtual void sessionRemoved(const LLUUID& session_id);
 
-	// LLGestureManagerObserver trigger
-	virtual void changed() { refreshGestures(); }
-
 	virtual void onFocusLost();
 	virtual BOOL handleKeyHere(KEY key, MASK mask);
 	virtual void setVisible(BOOL visible);
 
+	static void startChat(const char* line);
+	static void stopChat();
+
 protected:
 
+	LLBottomTray(const LLSD& key = LLSD());
+
 	void sendChat( EChatType type );
-	LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
+	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
 
 	void onChicletClick(LLUICtrl* ctrl);
 
+	void setChicletPanelVisible(bool visible);
+
 	// Which non-zero channel did we last chat on?
-	S32 mLastSpecialChatChannel;
+	static S32 mLastSpecialChatChannel;
 
 	LLLineEditor*		mChatBox;
 	LLChicletPanel* 	mChicletPanel;
 	LLNotificationChiclet* 	mIMWell;
 	LLNotificationChiclet* 	mSysWell;
 	LLTalkButton* 		mTalkBtn;
-	LLComboBox* 		mGestureCombo;
-	LLFrameTimer 		mGestureLabelTimer;
+	LLGestureComboBox*	mGestureCombo;
 	LLButton*           mStandUpBtn;
 };
 
-extern LLBottomTray* gBottomTray;
-
 #endif // LL_LLBOTTOMPANEL_H
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
deleted file mode 100644
index b94229704fd..00000000000
--- a/indra/newview/llchatbar.cpp
+++ /dev/null
@@ -1,692 +0,0 @@
-/** 
- * @file llchatbar.cpp
- * @brief LLChatBar class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- * 
- * Copyright (c) 2002-2009, Linden Research, Inc.
- * 
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab.  Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- * 
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- * 
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- * 
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llchatbar.h"
-
-#include "imageids.h"
-#include "llfontgl.h"
-#include "llrect.h"
-#include "llerror.h"
-#include "llparcel.h"
-#include "llstring.h"
-#include "message.h"
-#include "llfocusmgr.h"
-
-#include "llagent.h"
-#include "llbutton.h"
-#include "llcombobox.h"
-#include "llcommandhandler.h"	// secondlife:///app/chat/ support
-#include "llviewercontrol.h"
-#include "llfloaterchat.h"
-#include "llgesturemgr.h"
-#include "llkeyboard.h"
-#include "lllineeditor.h"
-#include "llstatusbar.h"
-#include "lltextbox.h"
-#include "lluiconstants.h"
-#include "llviewergesture.h"			// for triggering gestures
-#include "llviewermenu.h"		// for deleting object with DEL key
-#include "llviewerstats.h"
-#include "llviewerwindow.h"
-#include "llframetimer.h"
-#include "llresmgr.h"
-#include "llworld.h"
-#include "llinventorymodel.h"
-#include "llmultigesture.h"
-#include "llui.h"
-#include "llviewermenu.h"
-#include "lluictrlfactory.h"
-#include "llbottomtray.h"
-
-//
-// Globals
-//
-const F32 AGENT_TYPING_TIMEOUT = 5.f;	// seconds
-
-LLChatBar *gChatBar = NULL;
-
-class LLChatBarGestureObserver : public LLGestureManagerObserver
-{
-public:
-	LLChatBarGestureObserver(LLChatBar* chat_barp) : mChatBar(chat_barp){}
-	virtual ~LLChatBarGestureObserver() {}
-	virtual void changed() { mChatBar->refreshGestures(); }
-private:
-	LLChatBar* mChatBar;
-};
-
-
-//
-// Functions
-//
-
-LLChatBar::LLChatBar() 
-:	LLPanel(),
-	mInputEditor(NULL),
-	mGestureLabelTimer(),
-	mLastSpecialChatChannel(0),
-	mIsBuilt(FALSE),
-	mGestureCombo(NULL),
-	mObserver(NULL)
-{
-	setIsChrome(TRUE);
-	
-#if !LL_RELEASE_FOR_DOWNLOAD
-	childDisplayNotFound();
-#endif
-}
-
-
-LLChatBar::~LLChatBar()
-{
-	gGestureManager.removeObserver(mObserver);
-	delete mObserver;
-	mObserver = NULL;
-	// LLView destructor cleans up children
-}
-
-BOOL LLChatBar::postBuild()
-{
-	getChild<LLUICtrl>("Say")->setCommitCallback(boost::bind(&LLChatBar::onClickSay, this, _1));
-
-	// attempt to bind to an existing combo box named gesture
-	setGestureCombo(getChild<LLComboBox>( "Gesture", TRUE, FALSE));
-
-	mInputEditor = getChild<LLLineEditor>("Chat Editor");
-	mInputEditor->setKeystrokeCallback(&onInputEditorKeystroke, this);
-	mInputEditor->setFocusLostCallback(&onInputEditorFocusLost, this);
-	mInputEditor->setFocusReceivedCallback( &onInputEditorGainFocus, this );
-	mInputEditor->setCommitOnFocusLost( FALSE );
-	mInputEditor->setRevertOnEsc( FALSE );
-	mInputEditor->setIgnoreTab(TRUE);
-	mInputEditor->setPassDelete(TRUE);
-	mInputEditor->setReplaceNewlinesWithSpaces(FALSE);
-
-	mInputEditor->setMaxTextLength(1023);
-	mInputEditor->setEnableLineHistory(TRUE);
-
-	mIsBuilt = TRUE;
-
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------
-// Overrides
-//-----------------------------------------------------------------------
-
-// virtual
-BOOL LLChatBar::handleKeyHere( KEY key, MASK mask )
-{
-	BOOL handled = FALSE;
-
-	// ALT-RETURN is reserved for windowed/fullscreen toggle
-	if( KEY_RETURN == key )
-	{
-		if (mask == MASK_CONTROL)
-		{
-			// shout
-			sendChat(CHAT_TYPE_SHOUT);
-			handled = TRUE;
-		}
-		else if (mask == MASK_NONE)
-		{
-			// say
-			sendChat( CHAT_TYPE_NORMAL );
-			handled = TRUE;
-		}
-	}
-	// only do this in main chatbar
-	else if ( KEY_ESCAPE == key && gChatBar == this)
-	{
-		stopChat();
-
-		handled = TRUE;
-	}
-
-	return handled;
-}
-
-void LLChatBar::refresh()
-{
-	// HACK: Leave the name of the gesture in place for a few seconds.
-	const F32 SHOW_GESTURE_NAME_TIME = 2.f;
-	if (mGestureLabelTimer.getStarted() && mGestureLabelTimer.getElapsedTimeF32() > SHOW_GESTURE_NAME_TIME)
-	{
-		LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL;
-		if (gestures) gestures->selectFirstItem();
-		mGestureLabelTimer.stop();
-	}
-
-	if ((gAgent.getTypingTime() > AGENT_TYPING_TIMEOUT) && (gAgent.getRenderState() & AGENT_STATE_TYPING))
-	{
-		gAgent.stopTyping();
-	}
-
-	childSetEnabled("Say", mInputEditor->getText().size() > 0);
-
-}
-
-void LLChatBar::refreshGestures()
-{
-	if (mGestureCombo)
-	{
-		//store current selection so we can maintain it
-		std::string cur_gesture = mGestureCombo->getValue().asString();
-		mGestureCombo->selectFirstItem();
-		std::string label = mGestureCombo->getValue().asString();;
-		// clear
-		mGestureCombo->clearRows();
-
-		// collect list of unique gestures
-		std::map <std::string, BOOL> unique;
-		LLGestureManager::item_map_t::iterator it;
-		for (it = gGestureManager.mActive.begin(); it != gGestureManager.mActive.end(); ++it)
-		{
-			LLMultiGesture* gesture = (*it).second;
-			if (gesture)
-			{
-				if (!gesture->mTrigger.empty())
-				{
-					unique[gesture->mTrigger] = TRUE;
-				}
-			}
-		}
-
-		// add unique gestures
-		std::map <std::string, BOOL>::iterator it2;
-		for (it2 = unique.begin(); it2 != unique.end(); ++it2)
-		{
-			mGestureCombo->addSimpleElement((*it2).first);
-		}
-		
-		mGestureCombo->sortByName();
-		// Insert label after sorting, at top, with separator below it
-		mGestureCombo->addSeparator(ADD_TOP);
-		mGestureCombo->addSimpleElement(getString("gesture_label"), ADD_TOP);
-		
-		if (!cur_gesture.empty())
-		{ 
-			mGestureCombo->selectByValue(LLSD(cur_gesture));
-		}
-		else
-		{
-			mGestureCombo->selectFirstItem();
-		}
-	}
-}
-
-// Move the cursor to the correct input field.
-void LLChatBar::setKeyboardFocus(BOOL focus)
-{
-	if (focus)
-	{
-		if (mInputEditor)
-		{
-			mInputEditor->setFocus(TRUE);
-			mInputEditor->selectAll();
-		}
-	}
-	else if (gFocusMgr.childHasKeyboardFocus(this))
-	{
-		if (mInputEditor)
-		{
-			mInputEditor->deselect();
-		}
-		setFocus(FALSE);
-	}
-}
-
-
-// Ignore arrow keys in chat bar
-void LLChatBar::setIgnoreArrowKeys(BOOL b)
-{
-	if (mInputEditor)
-	{
-		mInputEditor->setIgnoreArrowKeys(b);
-	}
-}
-
-BOOL LLChatBar::inputEditorHasFocus()
-{
-	return mInputEditor && mInputEditor->hasFocus();
-}
-
-std::string LLChatBar::getCurrentChat()
-{
-	return mInputEditor ? mInputEditor->getText() : LLStringUtil::null;
-}
-
-void LLChatBar::setGestureCombo(LLComboBox* combo)
-{
-	mGestureCombo = combo;
-	if (mGestureCombo)
-	{
-		mGestureCombo->setCommitCallback(boost::bind(&LLChatBar::onCommitGesture, this, _1));
-
-		// now register observer since we have a place to put the results
-		mObserver = new LLChatBarGestureObserver(this);
-		gGestureManager.addObserver(mObserver);
-
-		// refresh list from current active gestures
-		refreshGestures();
-	}
-}
-
-//-----------------------------------------------------------------------
-// Internal functions
-//-----------------------------------------------------------------------
-
-// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
-// Otherwise returns input and channel 0.
-LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)
-{
-	if (mesg[0] == '/'
-		&& mesg[1] == '/')
-	{
-		// This is a "repeat channel send"
-		*channel = mLastSpecialChatChannel;
-		return mesg.substr(2, mesg.length() - 2);
-	}
-	else if (mesg[0] == '/'
-			 && mesg[1]
-			 && LLStringOps::isDigit(mesg[1]))
-	{
-		// This a special "/20" speak on a channel
-		S32 pos = 0;
-
-		// Copy the channel number into a string
-		LLWString channel_string;
-		llwchar c;
-		do
-		{
-			c = mesg[pos+1];
-			channel_string.push_back(c);
-			pos++;
-		}
-		while(c && pos < 64 && LLStringOps::isDigit(c));
-		
-		// Move the pointer forward to the first non-whitespace char
-		// Check isspace before looping, so we can handle "/33foo"
-		// as well as "/33 foo"
-		while(c && iswspace(c))
-		{
-			c = mesg[pos+1];
-			pos++;
-		}
-		
-		mLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
-		*channel = mLastSpecialChatChannel;
-		return mesg.substr(pos, mesg.length() - pos);
-	}
-	else
-	{
-		// This is normal chat.
-		*channel = 0;
-		return mesg;
-	}
-}
-
-
-void LLChatBar::sendChat( EChatType type )
-{
-	if (mInputEditor)
-	{
-		LLWString text = mInputEditor->getConvertedText();
-		if (!text.empty())
-		{
-			// store sent line in history, duplicates will get filtered
-			if (mInputEditor) mInputEditor->updateHistory();
-			// Check if this is destined for another channel
-			S32 channel = 0;
-			stripChannelNumber(text, &channel);
-			
-			std::string utf8text = wstring_to_utf8str(text);
-			// Try to trigger a gesture, if not chat to a script.
-			std::string utf8_revised_text;
-			if (0 == channel)
-			{
-				// discard returned "found" boolean
-				gGestureManager.triggerAndReviseString(utf8text, &utf8_revised_text);
-			}
-			else
-			{
-				utf8_revised_text = utf8text;
-			}
-
-			utf8_revised_text = utf8str_trim(utf8_revised_text);
-
-			if (!utf8_revised_text.empty())
-			{
-				// Chat with animation
-				sendChatFromViewer(utf8_revised_text, type, TRUE);
-			}
-		}
-	}
-
-	childSetValue("Chat Editor", LLStringUtil::null);
-
-	gAgent.stopTyping();
-
-	// If the user wants to stop chatting on hitting return, lose focus
-	// and go out of chat mode.
-	if (gChatBar == this && gSavedSettings.getBOOL("CloseChatOnReturn"))
-	{
-		stopChat();
-	}
-}
-
-
-//-----------------------------------------------------------------------
-// Static functions
-//-----------------------------------------------------------------------
-
-// static 
-void LLChatBar::startChat(const char* line)
-{
-	//TODO* remove DUMMY chat
-	if(gBottomTray && gBottomTray->getChatBox())
-	{
-		gBottomTray->setVisible(TRUE);
-		gBottomTray->getChatBox()->setFocus(TRUE);
-	}
-
-	// *TODO Vadim: Why was this code commented out?
-
-// 	gChatBar->setVisible(TRUE);
-// 	gChatBar->setKeyboardFocus(TRUE);
-// 	gSavedSettings.setBOOL("ChatVisible", TRUE);
-// 
-// 	if (line && gChatBar->mInputEditor)
-// 	{
-// 		std::string line_string(line);
-// 		gChatBar->mInputEditor->setText(line_string);
-// 	}
-// 	// always move cursor to end so users don't obliterate chat when accidentally hitting WASD
-// 	gChatBar->mInputEditor->setCursorToEnd();
-}
-
-
-// Exit "chat mode" and do the appropriate focus changes
-// static
-void LLChatBar::stopChat()
-{
-	//TODO* remove DUMMY chat
-	if(gBottomTray && gBottomTray->getChatBox())
-	{
-		gBottomTray->getChatBox()->setFocus(FALSE);
-	}
-
-	// *TODO Vadim: Why was this code commented out?
-
-// 	// In simple UI mode, we never release focus from the chat bar
-// 	gChatBar->setKeyboardFocus(FALSE);
-// 
-// 	// If we typed a movement key and pressed return during the
-// 	// same frame, the keyboard handlers will see the key as having
-// 	// gone down this frame and try to move the avatar.
-// 	gKeyboard->resetKeys();
-// 	gKeyboard->resetMaskKeys();
-// 
-// 	// stop typing animation
-// 	gAgent.stopTyping();
-// 
-// 	// hide chat bar so it doesn't grab focus back
-// 	gChatBar->setVisible(FALSE);
-// 	gSavedSettings.setBOOL("ChatVisible", FALSE);
-}
-
-// static
-void LLChatBar::onInputEditorKeystroke( LLLineEditor* caller, void* userdata )
-{
-	LLChatBar* self = (LLChatBar *)userdata;
-
-	LLWString raw_text;
-	if (self->mInputEditor) raw_text = self->mInputEditor->getWText();
-
-	// Can't trim the end, because that will cause autocompletion
-	// to eat trailing spaces that might be part of a gesture.
-	LLWStringUtil::trimHead(raw_text);
-
-	S32 length = raw_text.length();
-
-	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences
-	{
-		gAgent.startTyping();
-	}
-	else
-	{
-		gAgent.stopTyping();
-	}
-
-	/* Doesn't work -- can't tell the difference between a backspace
-	   that killed the selection vs. backspace at the end of line.
-	if (length > 1 
-		&& text[0] == '/'
-		&& key == KEY_BACKSPACE)
-	{
-		// the selection will already be deleted, but we need to trim
-		// off the character before
-		std::string new_text = raw_text.substr(0, length-1);
-		self->mInputEditor->setText( new_text );
-		self->mInputEditor->setCursorToEnd();
-		length = length - 1;
-	}
-	*/
-
-	KEY key = gKeyboard->currentKey();
-
-	// Ignore "special" keys, like backspace, arrows, etc.
-	if (length > 1 
-		&& raw_text[0] == '/'
-		&& key < KEY_SPECIAL)
-	{
-		// we're starting a gesture, attempt to autocomplete
-
-		std::string utf8_trigger = wstring_to_utf8str(raw_text);
-		std::string utf8_out_str(utf8_trigger);
-
-		if (gGestureManager.matchPrefix(utf8_trigger, &utf8_out_str))
-		{
-			if (self->mInputEditor)
-			{
-				std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-				self->mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
-				S32 outlength = self->mInputEditor->getLength(); // in characters
-			
-				// Select to end of line, starting from the character
-				// after the last one the user typed.
-				self->mInputEditor->setSelection(length, outlength);
-			}
-		}
-
-		//llinfos << "GESTUREDEBUG " << trigger 
-		//	<< " len " << length
-		//	<< " outlen " << out_str.getLength()
-		//	<< llendl;
-	}
-}
-
-// static
-void LLChatBar::onInputEditorFocusLost( LLFocusableElement* caller, void* userdata)
-{
-	// stop typing animation
-	gAgent.stopTyping();
-}
-
-// static
-void LLChatBar::onInputEditorGainFocus( LLFocusableElement* caller, void* userdata )
-{
-	LLFloaterChat::setHistoryCursorAndScrollToEnd();
-}
-
-void LLChatBar::onClickSay( LLUICtrl* ctrl )
-{
-	std::string cmd = ctrl->getValue().asString();
-	e_chat_type chat_type = CHAT_TYPE_NORMAL;
-	if (cmd == "shout")
-	{
-		chat_type = CHAT_TYPE_SHOUT;
-	}
-	else if (cmd == "whisper")
-	{
-		chat_type = CHAT_TYPE_WHISPER;
-	}
-	sendChat(chat_type);
-}
-
-void LLChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
-{
-	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
-}
-
-void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
-{
-	// Look for "/20 foo" channel chats.
-	S32 channel = 0;
-	LLWString out_text = stripChannelNumber(wtext, &channel);
-	std::string utf8_out_text = wstring_to_utf8str(out_text);
-	std::string utf8_text = wstring_to_utf8str(wtext);
-
-	utf8_text = utf8str_trim(utf8_text);
-	if (!utf8_text.empty())
-	{
-		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
-	}
-
-	// Don't animate for chats people can't hear (chat to scripts)
-	if (animate && (channel == 0))
-	{
-		if (type == CHAT_TYPE_WHISPER)
-		{
-			lldebugs << "You whisper " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
-		}
-		else if (type == CHAT_TYPE_NORMAL)
-		{
-			lldebugs << "You say " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
-		}
-		else if (type == CHAT_TYPE_SHOUT)
-		{
-			lldebugs << "You shout " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
-		}
-		else
-		{
-			llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
-			return;
-		}
-	}
-	else
-	{
-		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
-		{
-			lldebugs << "Channel chat: " << utf8_text << llendl;
-		}
-	}
-
-	send_chat_from_viewer(utf8_out_text, type, channel);
-}
-
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
-{
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_ChatFromViewer);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_ChatData);
-	msg->addStringFast(_PREHASH_Message, utf8_out_text);
-	msg->addU8Fast(_PREHASH_Type, type);
-	msg->addS32("Channel", channel);
-
-	gAgent.sendReliableMessage();
-
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
-}
-
-
-void LLChatBar::onCommitGesture(LLUICtrl* ctrl)
-{
-	LLCtrlListInterface* gestures = mGestureCombo ? mGestureCombo->getListInterface() : NULL;
-	if (gestures)
-	{
-		S32 index = gestures->getFirstSelectedIndex();
-		if (index == 0)
-		{
-			return;
-		}
-		const std::string& trigger = gestures->getSelectedValue().asString();
-
-		// pretend the user chatted the trigger string, to invoke
-		// substitution and logging.
-		std::string text(trigger);
-		std::string revised_text;
-		gGestureManager.triggerAndReviseString(text, &revised_text);
-
-		revised_text = utf8str_trim(revised_text);
-		if (!revised_text.empty())
-		{
-			// Don't play nodding animation
-			sendChatFromViewer(revised_text, CHAT_TYPE_NORMAL, FALSE);
-		}
-	}
-	mGestureLabelTimer.start();
-	if (mGestureCombo != NULL)
-	{
-		// free focus back to chat bar
-		mGestureCombo->setFocus(FALSE);
-	}
-}
-
-class LLChatHandler : public LLCommandHandler
-{
-public:
-	// not allowed from outside the app
-	LLChatHandler() : LLCommandHandler("chat", true) { }
-
-    // Your code here
-	bool handle(const LLSD& tokens, const LLSD& query_map,
-				LLWebBrowserCtrl* web)
-	{
-		if (tokens.size() < 2) return false;
-		S32 channel = tokens[0].asInteger();
-		std::string mesg = tokens[1].asString();
-		send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
-		return true;
-	}
-};
-
-// Creating the object registers with the dispatcher.
-LLChatHandler gChatHandler;
diff --git a/indra/newview/llchatbar.h b/indra/newview/llchatbar.h
deleted file mode 100644
index e0e324af6b9..00000000000
--- a/indra/newview/llchatbar.h
+++ /dev/null
@@ -1,120 +0,0 @@
-/** 
- * @file llchatbar.h
- * @brief LLChatBar class definition
- *
- * $LicenseInfo:firstyear=2002&license=viewergpl$
- * 
- * Copyright (c) 2002-2009, Linden Research, Inc.
- * 
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab.  Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- * 
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- * 
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- * 
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLCHATBAR_H
-#define LL_LLCHATBAR_H
-
-#include "llpanel.h"
-#include "llframetimer.h"
-#include "llchat.h"
-
-class LLLineEditor;
-class LLMessageSystem;
-class LLUICtrl;
-class LLUUID;
-class LLFrameTimer;
-class LLChatBarGestureObserver;
-class LLComboBox;
-
-// legacy calllback glue
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
-
-class LLChatBar
-:	public LLPanel
-{
-public:
-	// constructor for inline chat-bars (e.g. hosted in chat history window)
-	LLChatBar();
-	~LLChatBar();
-	virtual BOOL postBuild();
-
-	virtual BOOL handleKeyHere(KEY key, MASK mask);
-
-	void		refresh();
-	void		refreshGestures();
-
-	// Move cursor into chat input field.
-	void		setKeyboardFocus(BOOL b);
-
-	// Ignore arrow keys for chat bar
-	void		setIgnoreArrowKeys(BOOL b);
-
-	BOOL		inputEditorHasFocus();
-	std::string	getCurrentChat();
-
-	// since chat bar logic is reused for chat history
-	// gesture combo box might not be a direct child
-	void		setGestureCombo(LLComboBox* combo);
-
-	// Send a chat (after stripping /20foo channel chats).
-	// "Animate" means the nodding animation for regular text.
-	void		sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
-	void		sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
-
-	// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
-	// Otherwise returns input and channel 0.
-	LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
-
-	// callbacks
-	void onClickSay(LLUICtrl* ctrl);
-
-	static void	onTabClick( void* userdata );
-	static void	onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
-	static void	onInputEditorFocusLost(LLFocusableElement* caller,void* userdata);
-	static void	onInputEditorGainFocus(LLFocusableElement* caller,void* userdata);
-
-	void onCommitGesture(LLUICtrl* ctrl);
-
-	static void startChat(const char* line);
-	static void stopChat();
-
-protected:
-	void sendChat(EChatType type);
-	void updateChat();
-
-protected:
-	LLLineEditor*	mInputEditor;
-
-	LLFrameTimer	mGestureLabelTimer;
-
-	// Which non-zero channel did we last chat on?
-	S32				mLastSpecialChatChannel;
-
-	BOOL			mIsBuilt;
-	LLComboBox*		mGestureCombo;
-
-	LLChatBarGestureObserver* mObserver;
-};
-
-extern LLChatBar *gChatBar;
-
-#endif
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 4999d05e44e..bd946a79d69 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -32,72 +32,58 @@
 
 #include "llviewerprecompiledheaders.h" // must be first include
 #include "llchiclet.h"
-#include "llvoiceclient.h"
 #include "llagent.h"
-#include "lltextbox.h"
-#include "lliconctrl.h"
-#include "llvoicecontrolpanel.h"
-#include "lloutputmonitorctrl.h"
-#include "llimview.h"
+#include "llavataractions.h"
 #include "llbottomtray.h"
+#include "llgroupactions.h"
+#include "lliconctrl.h"
 #include "llimpanel.h"
+#include "llimview.h"
+#include "llfloatergroupinfo.h"
+#include "llmenugl.h"
+#include "lloutputmonitorctrl.h"
+#include "lltextbox.h"
+#include "llvoiceclient.h"
+#include "llvoicecontrolpanel.h"
 
-static const S32 CHICLET_HEIGHT = 25;
-static const S32 CHICLET_SPACING = 0;
-static const S32 CHICLET_PADDING = 3;
-static const S32 AVATAR_WIDTH = 25;
-static const S32 SPEAKER_WIDTH = 20;
-static const S32 COUNTER_WIDTH = 20;
-static const S32 SCROLL_BUTTON_WIDTH = 19;
-static const S32 SCROLL_BUTTON_HEIGHT = 20;
-static const S32 NOTIFICATION_TEXT_TOP_PAD = 5;
+static const std::string P2P_MENU_NAME = "IMChiclet P2P Menu";
+static const std::string GROUP_MENU_NAME = "IMChiclet Group Menu";
 
 static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
 static LLDefaultChildRegistry::Register<LLTalkButton> t2("chiclet_talk");
 static LLDefaultChildRegistry::Register<LLNotificationChiclet> t3("chiclet_notification");
-static LLDefaultChildRegistry::Register<LLChicletPanel> t4("chiclet_panel");
+static LLDefaultChildRegistry::Register<LLIMChiclet> t4("chiclet_im");
 
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
 LLNotificationChiclet::Params::Params()
-: image_unselected("image_unselected")
-, image_selected("image_selected")
-, image_overlay("image_overlay")
+: button("button")
+, unread_notifications("unread_notifications")
 {
+	button.tab_stop(FALSE);
+	button.label(LLStringUtil::null);
+
+	unread_notifications.font(LLFontGL::getFontSansSerif());
+	unread_notifications.text_color=(LLColor4::white);
+	unread_notifications.font_halign(LLFontGL::HCENTER);
+	unread_notifications.mouse_opaque(FALSE);
 }
 
 LLNotificationChiclet::LLNotificationChiclet(const Params& p)
 : LLChiclet(p)
 , mButton(NULL)
-, mCounterText(NULL)
-{
-	LLRect rc(p.rect);
-
-	LLButton::Params button_params;
-	button_params.name("btn");
-	button_params.label(LLStringUtil::null);
-	button_params.rect(LLRect(0,rc.getHeight(),rc.getWidth(),0));
-	button_params.image_overlay(p.image_overlay);
-	button_params.image_unselected(p.image_unselected);
-	button_params.image_selected(p.image_selected);
-	button_params.tab_stop(false);
+, mCounterCtrl(NULL)
+{
+	LLButton::Params button_params = p.button;
+	button_params.rect(p.rect());
 	mButton = LLUICtrlFactory::create<LLButton>(button_params);
 	addChild(mButton);
 
-	LLTextBox::Params textbox_params;
-	textbox_params.name("txt");
-	textbox_params.rect(LLRect(p.label_left,rc.getHeight(),
-		rc.getWidth()-p.label_left,0));
-	textbox_params.mouse_opaque(false);
-	textbox_params.v_pad(NOTIFICATION_TEXT_TOP_PAD);
-	textbox_params.font.style("SansSerif");
-	textbox_params.font_halign(LLFontGL::HCENTER);
-	mCounterText = LLUICtrlFactory::create<LLTextBox>(textbox_params);
-	addChild(mCounterText);
-	mCounterText->setColor(LLColor4::white);
-	mCounterText->setText(LLStringUtil::null);
+ 	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
+	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
+	addChild(mCounterCtrl);
 }
 
 LLNotificationChiclet::~LLNotificationChiclet()
@@ -105,18 +91,15 @@ LLNotificationChiclet::~LLNotificationChiclet()
 
 }
 
-LLChiclet* LLNotificationChiclet::create(const Params& p)
+void LLNotificationChiclet::setCounter(S32 counter)
 {
-	LLChiclet* chiclet = new LLNotificationChiclet(p);
-	return chiclet;
+	mCounterCtrl->setCounter(counter);
 }
 
-void LLNotificationChiclet::setCounter(S32 counter)
+void LLNotificationChiclet::setShowCounter(bool show)
 {
-	std::stringstream stream;
-	mCounter = counter;
-	stream << mCounter;
-	mCounterText->setText(stream.str());
+	LLChiclet::setShowCounter(show);
+	mCounterCtrl->setVisible(getShowCounter());
 }
 
 boost::signals2::connection LLNotificationChiclet::setClickCallback(
@@ -129,10 +112,16 @@ boost::signals2::connection LLNotificationChiclet::setClickCallback(
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
+LLChiclet::Params::Params()
+ : show_counter("show_counter")
+{
+	show_counter = true;
+}
+
 LLChiclet::LLChiclet(const Params& p)
 : LLUICtrl(p)
-, mCounter(0)
-, mShowCounter(true)
+, mSessionId(LLUUID::null)
+, mShowCounter(p.show_counter)
 {
 
 }
@@ -155,91 +144,133 @@ BOOL LLChiclet::handleMouseDown(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
+boost::signals2::connection LLChiclet::setChicletSizeChangedCallback(
+	const chiclet_size_changed_callback_t& cb)
+{
+	return mChicletSizeChangedSignal.connect(cb);
+}
+
+void LLChiclet::onChicletSizeChanged()
+{
+	mChicletSizeChangedSignal(this, getValue());
+}
+
+LLSD LLChiclet::getValue() const
+{
+	return LLSD(getSessionId());
+}
+
+void LLChiclet::setValue(const LLSD& value)
+{
+	if(value.isUUID())
+		setSessionId(value.asUUID());
+}
+
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
-LLIMChiclet::LLIMChiclet(const LLChiclet::Params& p)
-: LLChiclet(p)
-, mAvatar(NULL)
-, mCounterText(NULL)
-, mSpeaker(NULL)
-, mIMSessionId(LLUUID::null)
-, mShowSpeaker(false)
-, mSpeakerStatus(SPEAKER_IDLE)
-{
-	LLAvatarIconCtrl::Params avatar_params;
-	avatar_params.control_name("avatar");
-	avatar_params.draw_tooltip = FALSE;
-	mAvatar = LLUICtrlFactory::create<LLAvatarIconCtrl>(avatar_params);
-
-	addChild(mAvatar);
-
-	LLTextBox::Params unread_params;
-	unread_params.font.style("SansSerif");
-	unread_params.font_halign(LLFontGL::HCENTER);
-	unread_params.v_pad(5);
-	mCounterText = LLUICtrlFactory::create<LLTextBox>(unread_params);
-	addChild(mCounterText);
-	mCounterText->setColor(LLColor4::white);
-	setCounter(getCounter());
+LLIMChiclet::Params::Params()
+: avatar_icon("avatar_icon")
+, unread_notifications("unread_notifications")
+, speaker("speaker")
+, show_speaker("show_speaker")
+{
+	rect(LLRect(0, 25, 45, 0));
+
+	avatar_icon.name("avatar_icon");
+	avatar_icon.rect(LLRect(0, 25, 25, 0));
 
-	LLIconCtrl::Params speaker_params;
-	speaker_params.image( LLUI::getUIImage("icn_voice_ptt-on-lvl2.tga") );
-	mSpeaker = LLUICtrlFactory::create<LLIconCtrl>(speaker_params);
-	addChild(mSpeaker);
-	mSpeaker->setVisible(getShowSpeaker());
+	unread_notifications.name("unread");
+	unread_notifications.rect(LLRect(25, 25, 45, 0));
+	unread_notifications.font(LLFontGL::getFontSansSerif());
+	unread_notifications.font_halign(LLFontGL::HCENTER);
+	unread_notifications.v_pad(5);
+	unread_notifications.text_color(LLColor4::white);
 
-	S32 left = 0;
-	mAvatar->setRect(LLRect(left,CHICLET_HEIGHT,AVATAR_WIDTH,0));
-	left += AVATAR_WIDTH + CHICLET_SPACING;
-	mCounterText->setRect(LLRect(left,CHICLET_HEIGHT,left + COUNTER_WIDTH,0));
-	left += COUNTER_WIDTH + CHICLET_SPACING;
-	mSpeaker->setRect(LLRect(left,CHICLET_HEIGHT,left + SPEAKER_WIDTH,0));
+	speaker.name("speaker");
+	speaker.rect(LLRect(45, 25, 65, 0));
+
+	show_speaker = false;
 }
 
-LLIMChiclet::~LLIMChiclet()
+LLIMChiclet::LLIMChiclet(const Params& p)
+: LLChiclet(p)
+, mAvatarCtrl(NULL)
+, mCounterCtrl(NULL)
+, mSpeakerCtrl(NULL)
+, mShowSpeaker(p.show_speaker)
+, mPopupMenu(NULL)
 {
+	LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
+	mAvatarCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
+	addChild(mAvatarCtrl);
+
+	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
+	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
+	addChild(mCounterCtrl);
+
+	setCounter(getCounter());
+	setShowCounter(getShowCounter());
+
+	LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
+	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
+	addChild(mSpeakerCtrl);
 
+	setShowSpeaker(getShowSpeaker());
 }
 
-LLChiclet* LLIMChiclet::create(const LLUUID& im_session_id /* = LLUUID::null */)
+LLIMChiclet::~LLIMChiclet()
 {
-	LLIMChiclet* chiclet = new LLIMChiclet(LLChiclet::Params());
-	chiclet->setIMSessionId(im_session_id);
-	return chiclet;
+
 }
 
 void LLIMChiclet::setCounter(S32 counter)
 {
-	mCounter = counter;
-	std::stringstream stream;
-	stream << mCounter;
-	mCounterText->setText(stream.str());
+	mCounterCtrl->setCounter(counter);
 
-	LLRect rc = mCounterText->getRect();
-	rc.mRight = rc.mLeft + calcCounterWidth();
-	mCounterText->setRect(rc);
+	if(getShowCounter())
+	{
+		LLRect counter_rect = mCounterCtrl->getRect();
+		LLRect required_rect = mCounterCtrl->getRequiredRect();
+		bool needs_resize = required_rect.getWidth() != counter_rect.getWidth();
+
+		if(needs_resize)
+		{
+			counter_rect.mRight = counter_rect.mLeft + required_rect.getWidth();
+			mCounterCtrl->reshape(counter_rect.getWidth(), counter_rect.getHeight());
+			mCounterCtrl->setRect(counter_rect);
+
+			onChicletSizeChanged();
+		}
+	}
 }
 
 LLRect LLIMChiclet::getRequiredRect()
 {
-	LLRect rect(0,CHICLET_HEIGHT,AVATAR_WIDTH,0);
+	LLRect rect(0, 0, mAvatarCtrl->getRect().getWidth(), 0);
 	if(getShowCounter())
 	{
-		rect.mRight += CHICLET_SPACING + calcCounterWidth();
+		rect.mRight += mCounterCtrl->getRequiredRect().getWidth();
 	}
 	if(getShowSpeaker())
 	{
-		rect.mRight += CHICLET_SPACING + SPEAKER_WIDTH;
+		rect.mRight += mSpeakerCtrl->getRect().getWidth();
 	}
 	return rect;
 }
 
 void LLIMChiclet::setShowCounter(bool show)
 {
+	bool needs_resize = getShowCounter() != show;
+
 	LLChiclet::setShowCounter(show);
-	mCounterText->setVisible(getShowCounter());
+	mCounterCtrl->setVisible(getShowCounter());
+
+	if(needs_resize)
+	{
+		onChicletSizeChanged();
+	}
 }
 
 void LLIMChiclet::setIMSessionName(const std::string& name)
@@ -249,16 +280,39 @@ void LLIMChiclet::setIMSessionName(const std::string& name)
 
 void LLIMChiclet::setOtherParticipantId(const LLUUID& other_participant_id)
 {
-	if (mAvatar)
+	if (mAvatarCtrl)
 	{
-		mAvatar->setValue(other_participant_id);
+		mAvatarCtrl->setValue(other_participant_id);
+	}
+}
+
+void LLIMChiclet::updateMenuItems()
+{
+	if(!mPopupMenu)
+		return;
+	if(getSessionId().isNull())
+		return;
+
+	if(P2P_MENU_NAME == mPopupMenu->getName())
+	{
+		bool is_friend = LLAvatarActions::isFriend(mAvatarCtrl->getAvatarId());
+
+		mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend);
+		mPopupMenu->getChild<LLUICtrl>("Remove Friend")->setEnabled(is_friend);
 	}
 }
 
 void LLIMChiclet::setShowSpeaker(bool show)
 {
+	bool needs_resize = getShowSpeaker() != show;
+
 	mShowSpeaker = show;
-	mSpeaker->setVisible(getShowSpeaker());
+	mSpeakerCtrl->setVisible(getShowSpeaker());
+
+	if(needs_resize)
+	{
+		onChicletSizeChanged();
+	}
 }
 
 void LLIMChiclet::draw()
@@ -267,45 +321,140 @@ void LLIMChiclet::draw()
 	gl_rect_2d(0, getRect().getHeight(), getRect().getWidth(), 0, LLColor4(0.0f,0.0f,0.0f,1.f), FALSE);
 }
 
-S32 LLIMChiclet::calcCounterWidth()
+BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	if(!mPopupMenu)
+		createPopupMenu();
+
+	updateMenuItems();
+	
+	mPopupMenu->arrangeAndClear();
+
+	LLMenuGL::showPopup(this, mPopupMenu, x, y);
+
+	return TRUE;
+}
+
+void LLIMChiclet::createPopupMenu()
 {
-	S32 font_width = mCounterText->getFont()->getWidth("0");
-	S32 text_size = mCounterText->getText().size();
+	if(mPopupMenu)
+	{
+		llwarns << "Menu already exists" << llendl;
+		return;
+	}
+	if(getSessionId().isNull())
+		return;
 
-	return llmax(font_width * text_size, COUNTER_WIDTH);
+	LLFloaterIMPanel*floater = gIMMgr->findFloaterBySession(getSessionId());
+	if(!floater)
+		return;
+
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMChiclet::onMenuItemClicked, this, _2));
+
+	switch(floater->getDialogType())
+	{
+	case IM_SESSION_GROUP_START:
+		mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+			("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+		break;
+	case IM_NOTHING_SPECIAL:
+		mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
+			("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+		break;
+	default:
+		llwarns << "Unexpected dialog type" << llendl;
+		break;
+	}
+}
+
+void LLIMChiclet::onMenuItemClicked(const LLSD& user_data)
+{
+	std::string level = user_data.asString();
+	LLUUID other_participant_id = mAvatarCtrl->getAvatarId();
+
+	if("profile" == level)
+	{
+		LLAvatarActions::showProfile(other_participant_id);
+	}
+	else if("im" == level)
+	{
+		LLAvatarActions::startIM(other_participant_id);
+	}
+	else if("add" == level)
+	{
+		std::string name;
+		gCacheName->getFullName(other_participant_id,name);
+		LLAvatarActions::requestFriendshipDialog(other_participant_id,name);
+	}
+	else if("remove" == level)
+	{
+		LLAvatarActions::removeFriendDialog(other_participant_id);
+	}
+	else if("group chat" == level)
+	{
+		LLGroupActions::startChat(other_participant_id);
+	}
+	else if("info" == level)
+	{
+		LLFloaterGroupInfo::showFromUUID(other_participant_id);
+	}
 }
 
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
+LLChicletPanel::Params::Params()
+: chiclet_padding("chiclet_padding")
+, scrolling_offset("scrolling_offset")
+, left_scroll_button("left_scroll_button")
+, right_scroll_button("right_scroll_button")
+{
+	chiclet_padding = 3;
+	scrolling_offset = 40;
+
+	LLRect scroll_button_rect(0, 25, 19, 5);
+
+	left_scroll_button.name("left_scroll");
+	left_scroll_button.label(LLStringUtil::null);
+	left_scroll_button.rect(scroll_button_rect);
+	left_scroll_button.tab_stop(false);
+	left_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
+	left_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
+	left_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
+
+	right_scroll_button.name("right_scroll");
+	right_scroll_button.label(LLStringUtil::null);
+	right_scroll_button.rect(scroll_button_rect);
+	right_scroll_button.tab_stop(false);
+	right_scroll_button.image_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
+	right_scroll_button.image_unselected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
+	right_scroll_button.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
+};
+
 LLChicletPanel::LLChicletPanel(const Params&p)
 : LLPanel(p)
 , mScrollArea(NULL)
-, mLeftScroll(NULL)
-, mRightScroll(NULL)
-{
-	LLButton::Params params;
-
-	params.name("scroll_left");
-	params.label(LLStringUtil::null);
-	params.tab_stop(false);
-	params.image_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
-	params.image_unselected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
-	params.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_left.tga"));
-	mLeftScroll = LLUICtrlFactory::create<LLButton>(params);
-	addChild(mLeftScroll);
-	mLeftScroll->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this));
-	mLeftScroll->setEnabled(false);
-
-	params.name("scroll_right");
-	params.image_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
-	params.image_unselected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
-	params.image_hover_selected(LLUI::getUIImage("bottom_tray_scroll_right.tga"));
-	mRightScroll = LLUICtrlFactory::create<LLButton>(params);
-	addChild(mRightScroll);
-	mRightScroll->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this));
-	mRightScroll->setEnabled(false);
+, mLeftScrollButton(NULL)
+, mRightScrollButton(NULL)
+, mChicletPadding(p.chiclet_padding)
+, mScrollingOffset(p.scrolling_offset)
+{
+	LLButton::Params scroll_button_params = p.left_scroll_button;
+
+	mLeftScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params);
+	addChild(mLeftScrollButton);
+
+	mLeftScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onLeftScrollClick,this));
+	mLeftScrollButton->setEnabled(false);
+
+	scroll_button_params = p.right_scroll_button;
+	mRightScrollButton = LLUICtrlFactory::create<LLButton>(scroll_button_params);
+	addChild(mRightScrollButton);
+
+	mRightScrollButton->setClickedCallback(boost::bind(&LLChicletPanel::onRightScrollClick,this));
+	mRightScrollButton->setEnabled(false);
 
 	LLPanel::Params panel_params;
 	mScrollArea = LLUICtrlFactory::create<LLPanel>(panel_params,this);
@@ -320,7 +469,7 @@ LLChicletPanel::~LLChicletPanel()
 void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
 	
 	LLUUID session_id = data["session_id"].asUUID();
-	LLChiclet* chiclet = panel->findIMChiclet(session_id);
+	LLChiclet* chiclet = panel->findChiclet<LLChiclet>(session_id);
 
 	if (chiclet)
 	{
@@ -341,38 +490,28 @@ BOOL LLChicletPanel::postBuild()
 	return TRUE;
 }
 
-LLChiclet* LLChicletPanel::createChiclet(const LLUUID& im_session_id /* = LLUUID::null */, S32 pos /* = 0 */)
-{
-	LLChiclet* chiclet = LLIMChiclet::create(im_session_id);
-	if(!chiclet)
-	{
-		assert(false);
-		return NULL;
-	}
-
-	if(!addChiclet(chiclet, pos))
-	{
-		assert(false);
-		return NULL;
-	}
-
-	return chiclet;
-}
-
-bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 pos)
+bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 index)
 {
 	if(mScrollArea->addChild(chiclet))
 	{
-		// if first chiclet is scrolled left, the created one should be scrolled left too
-		if(0 == pos && canScrollLeft())
+		S32 offset = 0;
+		// Do not scroll chiclets if chiclets are scrolled right and new
+		// chiclet is added to the beginning of the list
+		if(canScrollLeft())
 		{
-			LLRect first_chiclet_rect = getChiclet(0)->getRect();
-			chiclet->setRect(first_chiclet_rect);
+			offset = - (chiclet->getRequiredRect().getWidth() + getChicletPadding());
+			if(0 == index)
+			{
+				offset += getChiclet(0)->getRect().mLeft;
+			}
 		}
 
-		mChicletList.insert(mChicletList.begin() + pos, chiclet);
+		mChicletList.insert(mChicletList.begin() + index, chiclet);
+
+		getChiclet(0)->translate(offset, 0);
 
 		chiclet->setLeftButtonClickCallback(boost::bind(&LLChicletPanel::onChicletClick, this, _1, _2));
+		chiclet->setChicletSizeChangedCallback(boost::bind(&LLChicletPanel::onChicletSizeChanged, this, _1, index));
 
 		arrange();
 		showScrollButtonsIfNeeded();
@@ -383,6 +522,29 @@ bool LLChicletPanel::addChiclet(LLChiclet* chiclet, S32 pos)
 	return false;
 }
 
+void LLChicletPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param)
+{
+	S32 chiclet_width = ctrl->getRect().getWidth();
+	S32 chiclet_new_width = ctrl->getRequiredRect().getWidth();
+
+	if(chiclet_new_width == chiclet_width)
+	{
+		return;
+	}
+
+	LLRect chiclet_rect = ctrl->getRect();
+	chiclet_rect.mRight = chiclet_rect.mLeft + chiclet_new_width;	
+
+	ctrl->setRect(chiclet_rect);
+
+	S32 offset = chiclet_new_width - chiclet_width;
+	S32 index = getChicletIndex(ctrl);
+
+	shiftChiclets(offset, index + 1);
+	trimChiclets();
+	showScrollButtonsIfNeeded();
+}
+
 void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD&param)
 {
 	LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(ctrl);
@@ -391,66 +553,42 @@ void LLChicletPanel::onChicletClick(LLUICtrl*ctrl,const LLSD&param)
 		S32 x, y;
 		LLRect rect = getRect();
 		localPointToScreen(rect.getCenterX(), 0, &x, &y);
-		LLIMFloater::show(chiclet->getIMSessionId(), x);
+		LLIMFloater::show(chiclet->getSessionId(), x);
 	}
 	mCommitSignal(ctrl,param);
 }
 
-LLChiclet* LLChicletPanel::findIMChiclet(const LLUUID& im_session_id)
-{
-	chiclet_list_t::const_iterator it = mChicletList.begin();
-	for( ; mChicletList.end() != it; ++it)
-	{
-		// Only IM Chiclets have session id, skip non IM Chiclets
-		LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
-		if(!chiclet)
-		{
-			continue;
-		}
-
-		if(chiclet->getIMSessionId() == im_session_id)
-		{
-			return chiclet;
-		}
-	}
-	return NULL;
-}
-
-LLChiclet* LLChicletPanel::getChiclet(S32 pos)
-{
-	return mChicletList[pos];
-}
-
 void LLChicletPanel::removeChiclet(chiclet_list_t::iterator it)
 {
-	// if possible, after deletion shift chiclets right
-	if(canScrollLeft() && !canScrollRight())
-	{
-		LLChiclet* chiclet = *it;
-		LLRect first_chiclet_rect = getChiclet(0)->getRect();
-		S32 deleted_chiclet_width = chiclet->getRect().getWidth();
-		deleted_chiclet_width += CHICLET_PADDING;
-		
-		first_chiclet_rect.mLeft += deleted_chiclet_width;
-		first_chiclet_rect.mRight += deleted_chiclet_width;
-
-		getChiclet(0)->setRect(first_chiclet_rect);
-	}
-
 	mScrollArea->removeChild(*it);
 	mChicletList.erase(it);
 	
 	arrange();
+	trimChiclets();
 	showScrollButtonsIfNeeded();
 }
 
-void LLChicletPanel::removeChiclet(S32 pos)
+void LLChicletPanel::removeChiclet(S32 index)
 {
-	if(0 > pos || getChicletCount() <= pos)
+	if(index >= 0 && index < getChicletCount())
 	{
-		return;
+		removeChiclet(mChicletList.begin() + index);
 	}
-	removeChiclet(mChicletList.begin() + pos);
+}
+
+S32 LLChicletPanel::getChicletIndex(const LLChiclet* chiclet)
+{
+	if(mChicletList.empty())
+		return -1;
+
+	S32 size = getChicletCount();
+	for(int n = 0; n < size; ++n)
+	{
+		if(chiclet == mChicletList[n])
+			return n;
+	}
+
+	return -1;
 }
 
 void LLChicletPanel::removeChiclet(LLChiclet*chiclet)
@@ -467,19 +605,14 @@ void LLChicletPanel::removeChiclet(LLChiclet*chiclet)
 	}
 }
 
-void LLChicletPanel::removeIMChiclet(const LLUUID& im_session_id)
+void LLChicletPanel::removeChiclet(const LLUUID& im_session_id)
 {
 	chiclet_list_t::iterator it = mChicletList.begin();
 	for( ; mChicletList.end() != it; ++it)
 	{
-		// Only IM Chiclets have session id, skip non IM Chiclets
 		LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
-		if(!chiclet)
-		{
-			continue;
-		}
 
-		if(chiclet->getIMSessionId() == im_session_id)
+		if(chiclet->getSessionId() == im_session_id)
 		{
 			removeChiclet(it);
 			return;
@@ -489,7 +622,11 @@ void LLChicletPanel::removeIMChiclet(const LLUUID& im_session_id)
 
 void LLChicletPanel::removeAll()
 {
-	mScrollArea->deleteAllChildren();
+	S32 size = getChicletCount();
+	for(S32 n = 0; n < size; ++n)
+	{
+		mScrollArea->removeChild(mChicletList[n]);
+	}
 
 	mChicletList.erase(mChicletList.begin(), mChicletList.end());
 
@@ -500,75 +637,67 @@ void LLChicletPanel::reshape(S32 width, S32 height, BOOL called_from_parent )
 {
 	LLPanel::reshape(width,height,called_from_parent);
 
-	mLeftScroll->setRect(LLRect(0,CHICLET_HEIGHT,SCROLL_BUTTON_WIDTH,
-		CHICLET_HEIGHT - SCROLL_BUTTON_HEIGHT));
-	mRightScroll->setRect(LLRect(width-SCROLL_BUTTON_WIDTH,CHICLET_HEIGHT,
-		width,CHICLET_HEIGHT - SCROLL_BUTTON_HEIGHT));
+	static const S32 SCROLL_BUTTON_PAD = 5;
 
-	S32 old_scroll_width = mScrollArea->getRect().getWidth();
+	LLRect scroll_button_rect = mLeftScrollButton->getRect();
+	mLeftScrollButton->setRect(LLRect(0,height,scroll_button_rect.getWidth(),
+		height - scroll_button_rect.getHeight()));
 
-	mScrollArea->setRect(LLRect(SCROLL_BUTTON_WIDTH + 5,CHICLET_HEIGHT + 1,
-		width - SCROLL_BUTTON_WIDTH - 5, 0));
+	scroll_button_rect = mRightScrollButton->getRect();
+	mRightScrollButton->setRect(LLRect(width - scroll_button_rect.getWidth(),height,
+		width, height - scroll_button_rect.getHeight()));
 
-	S32 current_scroll_width = mScrollArea->getRect().getWidth();
-	reshapeScrollArea(current_scroll_width - old_scroll_width);
+	mScrollArea->setRect(LLRect(scroll_button_rect.getWidth() + SCROLL_BUTTON_PAD,
+		height + 1, width - scroll_button_rect.getWidth() - SCROLL_BUTTON_PAD, 0));
+
+	trimChiclets();
 
 	showScrollButtonsIfNeeded();
 }
 
-void LLChicletPanel::reshapeScrollArea(S32 delta_width)
+void LLChicletPanel::arrange()
 {
 	if(mChicletList.empty())
 		return;
 
-	S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
-	S32 scroll_width = mScrollArea->getRect().getWidth();
+	S32 chiclet_left = getChiclet(0)->getRect().mLeft;
 
-	// Align all chiclets to last chiclet
-	// if there is a gap between last chiclet and scroll area right side
-	// or last chiclet is at visible area right side
-	if( last_chiclet_right < scroll_width 
-		|| last_chiclet_right == scroll_width - delta_width)
+	S32 size = getChicletCount();
+	for( int n = 0; n < size; ++n)
 	{
-		LLRect first_chiclet_rect = getChiclet(0)->getRect();
-		// if we can right shift all chiclets
-		if(first_chiclet_rect.mLeft < 0)
-		{
-			first_chiclet_rect.mLeft += delta_width;
-			first_chiclet_rect.mRight += delta_width;
+		LLChiclet* chiclet = getChiclet(n);
 
-			getChiclet(0)->setRect(first_chiclet_rect);
+		S32 chiclet_width = chiclet->getRequiredRect().getWidth();
+		LLRect rect = chiclet->getRect();
+		rect.set(chiclet_left, rect.mTop, chiclet_left + chiclet_width, rect.mBottom);
 
-			arrange();
-		}
+		chiclet->setRect(rect);
+
+		chiclet_left += chiclet_width + getChicletPadding();
 	}
 }
 
-void LLChicletPanel::arrange()
+void LLChicletPanel::trimChiclets()
 {
-	if(mChicletList.empty())
-		return;
-
-	LLRect first_chiclet_rect = getChiclet(0)->getRect();
-	// don't allow gap between first chiclet and scroll area left side
-	if(first_chiclet_rect.mLeft > 0)
+	// trim right
+	if(canScrollLeft() && !canScrollRight())
 	{
-		first_chiclet_rect.mRight = first_chiclet_rect.getWidth();
-		first_chiclet_rect.mLeft = 0;
+		S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
+		S32 scroll_width = mScrollArea->getRect().getWidth();
+		if(last_chiclet_right < scroll_width)
+		{
+			shiftChiclets(scroll_width - last_chiclet_right);
+		}
 	}
 
-	S32 left = first_chiclet_rect.mLeft;
-
-	S32 size = getChicletCount();
-	for( int n = 0; n < size; ++n)
+	// trim left
+	if(!mChicletList.empty())
 	{
-		LLChiclet* chiclet = getChiclet(n);
-		S32 chiclet_width = chiclet->getRequiredRect().getWidth();
-		LLRect rc(left, CHICLET_HEIGHT, left + chiclet_width, 0);
-
-		chiclet->setRect(rc);
-
-		left += chiclet_width + CHICLET_PADDING;
+		LLRect first_chiclet_rect = getChiclet(0)->getRect();
+		if(first_chiclet_rect.mLeft > 0)
+		{
+			shiftChiclets( - first_chiclet_rect.mLeft);
+		}
 	}
 }
 
@@ -577,13 +706,13 @@ void LLChicletPanel::showScrollButtonsIfNeeded()
 	bool can_scroll_left = canScrollLeft();
 	bool can_scroll_right = canScrollRight();
 
-	mLeftScroll->setEnabled(can_scroll_left);
-	mRightScroll->setEnabled(can_scroll_right);
+	mLeftScrollButton->setEnabled(can_scroll_left);
+	mRightScrollButton->setEnabled(can_scroll_right);
 
 	bool show_scroll_buttons = can_scroll_left || can_scroll_right;
 
-	mLeftScroll->setVisible(show_scroll_buttons);
-	mRightScroll->setVisible(show_scroll_buttons);
+	mLeftScrollButton->setVisible(show_scroll_buttons);
+	mRightScrollButton->setVisible(show_scroll_buttons);
 }
 
 void LLChicletPanel::draw()
@@ -626,42 +755,19 @@ bool LLChicletPanel::canScrollLeft()
 	return getChiclet(0)->getRect().mLeft < 0;
 }
 
-void LLChicletPanel::scroll(ScrollDirection direction)
+void LLChicletPanel::scroll(S32 offset)
 {
-	S32 first_visible_chiclet = getFirstVisibleChiclet();
-	if(-1 == first_visible_chiclet)
-		return;
-
-	S32 offset = 0;
+	shiftChiclets(offset);
+}
 
-	if(SCROLL_LEFT == direction)
-	{
-		if(0 == first_visible_chiclet)
-		{
-			// shift chiclets in case first chiclet is partially visible
-			offset = llabs(getChiclet(first_visible_chiclet)->getRect().mLeft);
-		}
-		else
-		{
-			offset = getChiclet(first_visible_chiclet - 1)->getRect().getWidth() + CHICLET_PADDING;
-		}
-	}
-	else if(SCROLL_RIGHT == direction)
+void LLChicletPanel::shiftChiclets(S32 offset, S32 start_index /* = 0 */)
+{
+	if(start_index < 0 || start_index >= getChicletCount())
 	{
-		S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
-		S32 scroll_rect_width = mScrollArea->getRect().getWidth();
-
-		offset = getChiclet(first_visible_chiclet)->getRect().getWidth() + CHICLET_PADDING;
-		offset *= direction;
-		// if after scrolling, the last chiclet will not be aligned to 
-		// scroll area right side - align it.
-		if( last_chiclet_right + offset < scroll_rect_width )
-		{
-			offset = scroll_rect_width - last_chiclet_right;
-		}
+		return;
 	}
 
-	chiclet_list_t::const_iterator it = mChicletList.begin();
+	chiclet_list_t::const_iterator it = mChicletList.begin() + start_index;
 	for(;mChicletList.end() != it; ++it)
 	{
 		LLChiclet* chiclet = *it;
@@ -669,31 +775,20 @@ void LLChicletPanel::scroll(ScrollDirection direction)
 	}
 }
 
-S32 LLChicletPanel::getFirstVisibleChiclet()
+void LLChicletPanel::scrollLeft()
 {
-	if(mChicletList.empty())
-		return -1;
-
-	for(int n = 0; n < getChicletCount(); ++n)
+	if(canScrollLeft())
 	{
-		LLRect rc = getChiclet(n)->getRect();
-		if(n > 0)
-			rc.mLeft -= CHICLET_PADDING;
-		// bottom left of scroll area is first visible point
-		if(rc.pointInRect(0,0))
+		S32 offset = getScrollingOffset();
+		LLRect first_chiclet_rect = getChiclet(0)->getRect();
+
+		// shift chiclets in case first chiclet is partially visible
+		if(first_chiclet_rect.mLeft < 0 && first_chiclet_rect.mRight > 0)
 		{
-			return n;
+			offset = llabs(first_chiclet_rect.mLeft);
 		}
-	}
 
-	return -1;
-}
-
-void LLChicletPanel::scrollLeft()
-{
-	if(canScrollLeft())
-	{
-		scroll(SCROLL_LEFT);
+		scroll(offset);
 		
 		showScrollButtonsIfNeeded();
 	}
@@ -703,7 +798,18 @@ void LLChicletPanel::scrollRight()
 {
 	if(canScrollRight())
 	{
-		scroll(SCROLL_RIGHT);
+		S32 offset = - getScrollingOffset();
+
+		S32 last_chiclet_right = (*mChicletList.rbegin())->getRect().mRight;
+		S32 scroll_rect_width = mScrollArea->getRect().getWidth();
+		// if after scrolling, the last chiclet will not be aligned to 
+		// scroll area right side - align it.
+		if( last_chiclet_right + offset < scroll_rect_width )
+		{
+			offset = scroll_rect_width - last_chiclet_right;
+		}
+
+		scroll(offset);
 		
 		showScrollButtonsIfNeeded();
 	}
@@ -719,7 +825,7 @@ void LLChicletPanel::onRightScrollClick()
 	scrollRight();
 }
 
-boost::signals2::connection LLChicletPanel::setChicletClickCallback(
+boost::signals2::connection LLChicletPanel::setChicletClickedCallback(
 	const commit_callback_t& cb)
 {
 	return mCommitSignal.connect(cb);
@@ -742,62 +848,83 @@ BOOL LLChicletPanel::handleScrollWheel(S32 x, S32 y, S32 clicks)
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
-LLTalkButton::LLTalkButton(const LLUICtrl::Params& p)
+LLTalkButton::Params::Params()
+ : speak_button("speak_button")
+ , show_button("show_button")
+ , monitor("monitor")
+{
+	speak_button.name("left");
+	speak_button.label("Speak");
+	speak_button.label_selected("Speak");
+	speak_button.font(LLFontGL::getFontSansSerifSmall());
+	speak_button.tab_stop(false);
+	speak_button.is_toggle(true);
+	speak_button.picture_style(true);
+	speak_button.image_selected(LLUI::getUIImage("SegmentedBtn_Left_Selected"));
+	speak_button.image_unselected(LLUI::getUIImage("SegmentedBtn_Left_Off"));
+
+	show_button.name("right");
+	show_button.label(LLStringUtil::null);
+	show_button.rect(LLRect(0, 0, 20, 0));
+	show_button.tab_stop(false);
+	show_button.is_toggle(true);
+	show_button.picture_style(true);
+	show_button.image_selected(LLUI::getUIImage("ComboButton_Selected"));
+	show_button.image_unselected(LLUI::getUIImage("ComboButton_Off"));
+
+	monitor.name("monitor");
+	monitor.rect(LLRect(0, 10, 16, 0));
+}
+
+LLTalkButton::LLTalkButton(const Params& p)
 : LLUICtrl(p)
+, mPrivateCallPanel(NULL)
+, mOutputMonitor(NULL)
+, mSpeakBtn(NULL)
+, mShowBtn(NULL)
 {
-	static S32 DROPDOWN_BTN_WIDTH = 20;
-
-	LLRect rc(p.rect);
-
-	LLButton::Params speak_params;
-	speak_params.name("left");
-	speak_params.rect(LLRect(0,rc.getHeight(),rc.getWidth()-DROPDOWN_BTN_WIDTH,0));
-	speak_params.label("Speak");
-	speak_params.label_selected("Speak");
-	speak_params.font(LLFontGL::getFontSansSerifSmall());
-	speak_params.tab_stop(false);
-	speak_params.is_toggle(true);
-	speak_params.picture_style(true);
-	speak_params.image_selected(LLUI::getUIImage("SegmentedBtn_Left_Selected")); 
-	speak_params.image_unselected(LLUI::getUIImage("SegmentedBtn_Left_Off"));
+	LLRect rect = p.rect();
+	LLRect speak_rect(0, rect.getHeight(), rect.getWidth(), 0);
+	LLRect show_rect = p.show_button.rect();
+	show_rect.set(0, rect.getHeight(), show_rect.getWidth(), 0);
+
+	speak_rect.mRight -= show_rect.getWidth();
+	show_rect.mLeft = speak_rect.getWidth();
+	show_rect.mRight = rect.getWidth();
+
+	LLButton::Params speak_params = p.speak_button;
+	speak_params.rect(speak_rect);
 	mSpeakBtn = LLUICtrlFactory::create<LLButton>(speak_params);
 	addChild(mSpeakBtn);
 
 	mSpeakBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_SpeakBtn, this));
-	mSpeakBtn->setToggleState(false);
-
-	LLButton::Params show_params;
-	show_params.name("right");
-	show_params.rect(LLRect(rc.getWidth()-DROPDOWN_BTN_WIDTH,rc.getHeight(),rc.getWidth(),0));
-	show_params.label("");
-	show_params.tab_stop(false);
-	show_params.is_toggle(true);
-	show_params.picture_style(true);
-	show_params.image_selected(LLUI::getUIImage("ComboButton_Selected"));
-	show_params.image_unselected(LLUI::getUIImage("ComboButton_Off"));
+	mSpeakBtn->setToggleState(FALSE);
+
+	LLButton::Params show_params = p.show_button;
+	show_params.rect(show_rect);
 	mShowBtn = LLUICtrlFactory::create<LLButton>(show_params);
 	addChild(mShowBtn);
 
 	mShowBtn->setClickedCallback(boost::bind(&LLTalkButton::onClick_ShowBtn, this));
-	mShowBtn->setToggleState(false);
-
-	mSpeakBtn->setToggleState(FALSE);
 	mShowBtn->setToggleState(FALSE);
 
-	rc = mSpeakBtn->getRect();
+	static const S32 MONITOR_RIGHT_PAD = 2;
 
-	LLOutputMonitorCtrl::Params monitor_param;
-	monitor_param.name("monitor");
-	monitor_param.draw_border(false);
-	monitor_param.rect(LLRect(rc.getWidth()-20,18,rc.getWidth()-3,2));
-	monitor_param.visible(true);
-	mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_param);
-	// never show "muted" because you can't mute yourself
-	mOutputMonitor->setIsMuted(false);
+	LLRect monitor_rect = p.monitor.rect();
+	S32 monitor_height = monitor_rect.getHeight();
+	monitor_rect.mLeft = speak_rect.getWidth() - monitor_rect.getWidth() - MONITOR_RIGHT_PAD;
+	monitor_rect.mRight = speak_rect.getWidth() - MONITOR_RIGHT_PAD;
+	monitor_rect.mBottom = (rect.getHeight() / 2) - (monitor_height / 2);
+	monitor_rect.mTop = monitor_rect.mBottom + monitor_height;
 
+	LLOutputMonitorCtrl::Params monitor_params = p.monitor;
+	monitor_params.draw_border(false);
+	monitor_params.rect(monitor_rect);
+	mOutputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(monitor_params);
 	mSpeakBtn->addChild(mOutputMonitor);
 
-	mPrivateCallPanel = NULL;
+	// never show "muted" because you can't mute yourself
+	mOutputMonitor->setIsMuted(false);
 }
 
 LLTalkButton::~LLTalkButton()
@@ -838,8 +965,7 @@ void LLTalkButton::onClick_ShowBtn()
 	mPrivateCallPanel = new LLVoiceControlPanel;
 	getRootView()->addChild(mPrivateCallPanel);
 
- 	if(gBottomTray)
- 		y = gBottomTray->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight();
+	y = LLBottomTray::getInstance()->getRect().getHeight() + mPrivateCallPanel->getRect().getHeight();
 
 	LLRect rect;
 	rect.setLeftTopAndSize(x, y, mPrivateCallPanel->getRect().getWidth(), mPrivateCallPanel->getRect().getHeight());
@@ -857,3 +983,63 @@ void LLTalkButton::onClick_ShowBtn()
 
 	mShowBtn->setToggleState(TRUE);
 }
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p)
+ : LLTextBox(p)
+ , mCounter(0)
+ , mInitialWidth(0)
+{
+	mInitialWidth = getRect().getWidth();
+}
+
+void LLChicletNotificationCounterCtrl::setCounter(S32 counter)
+{
+	mCounter = counter;
+
+	std::stringstream stream;
+	stream << getCounter();
+	setText(stream.str());
+}
+
+LLRect LLChicletNotificationCounterCtrl::getRequiredRect()
+{
+	LLRect rc;
+	S32 text_width = getFont()->getWidth(getText());
+
+	rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth);
+	
+	return rc;
+}
+
+void LLChicletNotificationCounterCtrl::setValue(const LLSD& value)
+{
+	if(value.isInteger())
+		setCounter(value.asInteger());
+}
+
+LLSD LLChicletNotificationCounterCtrl::getValue() const
+{
+	return LLSD(getCounter());
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
+ : LLAvatarIconCtrl(p)
+{
+}
+
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+//////////////////////////////////////////////////////////////////////////
+
+LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
+ : LLIconCtrl(p)
+{
+}
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index ceda61adea0..e467ec012a7 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -33,134 +33,333 @@
 #ifndef LL_LLCHICLET_H
 #define LL_LLCHICLET_H
 
+#include "llavatariconctrl.h"
 #include "llpanel.h"
+#include "lltextbox.h"
+#include "lloutputmonitorctrl.h"
 
-class LLTextBox;
-class LLIconCtrl;
-class LLAvatarIconCtrl;
 class LLVoiceControlPanel;
-class LLOutputMonitorCtrl;
+class LLMenuGL;
 
+/*
+ * Class for displaying amount of messages/notifications(unread).
+*/
+class LLChicletNotificationCounterCtrl : public LLTextBox
+{
+public:
+
+	struct Params :	public LLInitParam::Block<Params, LLTextBox::Params>
+	{
+		Params()
+		{};
+	};
+
+	/*
+	 * Sets number of notifications
+	*/
+	virtual void setCounter(S32 counter);
+
+	/*
+	 * Returns number of notifications
+	*/
+	virtual S32 getCounter() const { return mCounter; }
+
+	/*
+	 * Returns width, required to display amount of notifications in text form.
+	 * Width is the only valid value.
+	*/
+	/*virtual*/ LLRect getRequiredRect();
+
+	/*
+	 * Sets number of notifications using LLSD
+	*/
+	/*virtual*/ void setValue(const LLSD& value);
+
+	/*
+	 * Returns number of notifications wrapped in LLSD
+	*/
+	/*virtual*/ LLSD getValue() const;
+
+protected:
+
+	LLChicletNotificationCounterCtrl(const Params& p);
+	friend class LLUICtrlFactory;
+
+private:
+
+	S32 mCounter;
+	S32 mInitialWidth;
+};
+
+/*
+ * Class for displaying avatar's icon.
+*/
+class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
+{
+public:
+
+	struct Params :	public LLInitParam::Block<Params, LLAvatarIconCtrl::Params>
+	{
+		Params()
+		{
+			draw_tooltip(FALSE);
+			mouse_opaque(FALSE);
+		};
+	};
+
+protected:
+
+	LLChicletAvatarIconCtrl(const Params& p);
+	friend class LLUICtrlFactory;
+};
+
+/*
+ * Class for displaying status of Voice Chat 
+*/
+class LLChicletSpeakerCtrl : public LLIconCtrl
+{
+public:
+
+	struct Params : public LLInitParam::Block<Params, LLIconCtrl::Params>
+	{
+		Params(){};
+	};
+protected:
+
+	LLChicletSpeakerCtrl(const Params&p);
+	friend class LLUICtrlFactory;
+};
+
+/*
+ * Base class for all chiclets.
+ */
 class LLChiclet : public LLUICtrl
 {
 public:
 
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
-		Params(){};
+		Optional<bool> show_counter;
+
+		Params();
 	};
 
-	virtual ~LLChiclet();
+	/*virtual*/ ~LLChiclet();
+
+	/*
+	 * Associates chat session id with chiclet.
+	*/
+	virtual void setSessionId(const LLUUID& session_id) { mSessionId = session_id; }
 
+	/*
+	 * Returns associated chat session.
+	*/
+	virtual const LLUUID& getSessionId() const { return mSessionId; }
+
+	/*
+	 * Sets number of unread notifications.
+	*/
 	virtual void setCounter(S32 counter) = 0;
 
+	/*
+	 * Returns number of unread notifications.
+	*/
 	virtual S32 getCounter() = 0;
 
-	virtual void setShowCounter(bool show) {mShowCounter = show;};
+	/*
+	 * Sets show counter state.
+	*/
+	virtual void setShowCounter(bool show) { mShowCounter = show; }
 
+	/*
+	 * Returns show counter state.
+	*/
 	virtual bool getShowCounter() {return mShowCounter;};
 
-	virtual boost::signals2::connection setLeftButtonClickCallback(
+	/*
+	 * Connects chiclet clicked event with callback.
+	*/
+	/*virtual*/ boost::signals2::connection setLeftButtonClickCallback(
 		const commit_callback_t& cb);
 
+	typedef boost::function<void (LLChiclet* ctrl, const LLSD& param)> 
+		chiclet_size_changed_callback_t;
+
+	/*
+	 * Connects chiclets size changed event with callback.
+	*/
+	virtual boost::signals2::connection setChicletSizeChangedCallback(
+		const chiclet_size_changed_callback_t& cb);
+
+	/*
+	 * Sets IM Session id using LLSD
+	*/
+	/*virtual*/ LLSD getValue() const;
+
+	/*
+	 * Returns IM Session id using LLSD
+	*/
+	/*virtual*/ void setValue(const LLSD& value);
+
 protected:
 
 	friend class LLUICtrlFactory;
 	LLChiclet(const Params& p);
 
-	virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+	/*
+	 * Notifies subscribers about click on chiclet.
+	*/
+	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
+
+	/*
+	 * Notifies subscribers about chiclet size changed event.
+	*/
+	virtual void onChicletSizeChanged();
+
+private:
+
+	LLUUID mSessionId;
 
-protected:
-	S32 mCounter;
 	bool mShowCounter;
+
+	typedef boost::signals2::signal<void (LLChiclet* ctrl, const LLSD& param)> 
+		chiclet_size_changed_signal_t;
+
+	chiclet_size_changed_signal_t mChicletSizeChangedSignal;
 };
 
+/*
+* Implements Instant Message chiclet.
+* IMChiclet displays avatar's icon, number of unread messages(optional)
+* and voice chat status(optional).
+*/
 class LLIMChiclet : public LLChiclet
 {
 public:
-	static LLChiclet* create(const LLUUID& im_session_id = LLUUID::null);
-
-	void setCounter(S32);
-
-	S32 getCounter() {return mCounter;};
-
-	const LLUUID& getIMSessionId() const {return mIMSessionId;};
+	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
+	{
+		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
 
-	void setIMSessionId(const LLUUID& im_session_id) { mIMSessionId = im_session_id; }
-	void setIMSessionName(const std::string& name);
-	void setOtherParticipantId(const LLUUID& other_participant_id);
+		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
 
-	void setShowSpeaker(bool show);
+		Optional<LLChicletSpeakerCtrl::Params> speaker;
 
-	bool getShowSpeaker() {return mShowSpeaker;};
+		Optional<bool>	show_speaker;
 
-	enum SpeakerStatus
-	{
-		SPREAKER_ACTIVE,
-		SPEAKER_IDLE
+		Params();
 	};
 
-	void setSpeakerStatus(SpeakerStatus status);
-
-	SpeakerStatus getSpeakerStatus() {return mSpeakerStatus;};
-
-	~LLIMChiclet();
+	/*virtual*/ ~LLIMChiclet();
+
+	/*
+	 * Sets IM session name. This name will be displayed in chiclet tooltip.
+	*/
+	virtual void setIMSessionName(const std::string& name);
+
+	/*
+	 * Sets id of person/group user is chatting with.
+	*/
+	virtual void setOtherParticipantId(const LLUUID& other_participant_id);
+
+	/*
+	 * Shows/hides voice chat status control.
+	*/
+	virtual void setShowSpeaker(bool show);
+
+	/*
+	 * Returns voice chat status control visibility.
+	*/
+	virtual bool getShowSpeaker() {return mShowSpeaker;};
+
+	/*
+	 * Sets number of unread messages. Will update chiclet's width if number text 
+	 * exceeds size of counter and notify it's parent about size change.
+	*/
+	/*virtual*/ void setCounter(S32);
+
+	/*
+	 * Returns number of unread messages.
+	*/
+	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
+
+	/*
+	 * Shows/hides number of unread messages.
+	*/
+	/*virtual*/ void setShowCounter(bool show);
+
+	/*
+	 * Draws border around chiclet.
+	*/
+	/*virtual*/ void draw();
+
+	/*
+	 * Returns rect, required to display chiclet.
+	 * Width is the only valid value.
+	*/
+	/*virtual*/ LLRect getRequiredRect();
 
 protected:
-	LLIMChiclet(const LLChiclet::Params& p);
-	friend class LLUICtrlFactory;
 
-	S32 calcCounterWidth();
+	LLIMChiclet(const Params& p);
+	friend class LLUICtrlFactory;
 
-	//overrides
-public:
+	/*
+	 * Creates chiclet popup menu. Will create P2P or Group IM Chat menu 
+	 * based on other participant's id.
+	*/
+	virtual void createPopupMenu();
 
-	void setShowCounter(bool show);
+	/*
+	 * Processes clicks on chiclet popup menu.
+	*/
+	virtual void onMenuItemClicked(const LLSD& user_data);
 
-	void draw();
+	/* 
+	 * Enables/disables menus based on relationship with other participant.
+	*/
+	virtual void updateMenuItems();
 
-	LLRect getRequiredRect();
+	/*
+	 * Displays popup menu.
+	*/
+	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
 
 protected:
-	LLAvatarIconCtrl* mAvatar;
-	LLTextBox* mCounterText;
-	LLIconCtrl* mSpeaker;
+	LLChicletAvatarIconCtrl* mAvatarCtrl;
+	LLChicletNotificationCounterCtrl* mCounterCtrl;
+	LLChicletSpeakerCtrl* mSpeakerCtrl;
+
+	LLMenuGL* mPopupMenu;
 
-	LLUUID mIMSessionId;
 	bool mShowSpeaker;
-	SpeakerStatus mSpeakerStatus;
 };
 
+/*
+ * Implements notification chiclet. Used to display total amount of unread messages 
+ * across all IM sessions, total amount of system notifications.
+*/
 class LLNotificationChiclet : public LLChiclet
 {
 public:
 
 	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
 	{
-		Optional<LLUIImage*>	
-			image_unselected,
-			image_selected,
-			image_hover_selected,
-			image_hover_unselected,
-			image_disabled_selected,
-			image_disabled,
-			image_overlay;
-
-		Optional<S32>			
-			label_left;
+		Optional<LLButton::Params> button;
+
+		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
 
 		Params();
 	};
 
-	static LLChiclet* create(const Params& p);
+	/*virtual*/ void setCounter(S32 counter);
 
-	void setCounter(S32 counter);
+	/*virtual*/S32 getCounter() { return mCounterCtrl->getCounter(); }
 
-	S32 getCounter() {return mCounter;};
+	/*virtual*/ void setShowCounter(bool show);
 
 	boost::signals2::connection setClickCallback(const commit_callback_t& cb);
 
-	virtual ~ LLNotificationChiclet();
+	/*virtual*/ ~ LLNotificationChiclet();
 
 protected:
 	LLNotificationChiclet(const Params& p);
@@ -168,112 +367,223 @@ class LLNotificationChiclet : public LLChiclet
 
 protected:
 	LLButton* mButton;
-	LLTextBox* mCounterText;
+	LLChicletNotificationCounterCtrl* mCounterCtrl;
 };
 
+/*
+ * Storage class for all IM chiclets. Provides mechanism to display, 
+ * scroll, create, remove chiclets.
+*/
 class LLChicletPanel : public LLPanel
 {
 public:
 
 	struct Params :	public LLInitParam::Block<Params, LLPanel::Params>
 	{
-		Params(){};
-	};
+		Optional<S32> chiclet_padding,
+					  scrolling_offset;
 
-	~LLChicletPanel();
+		Optional<LLButton::Params> left_scroll_button,
+								   right_scroll_button;
 
-	LLChiclet* createChiclet(const LLUUID& im_session_id = LLUUID::null, S32 pos = 0);
+		Params();
+	};
 
-	bool addChiclet(LLChiclet*, S32 pos);
+	virtual ~LLChicletPanel();
 
-	LLChiclet* getChiclet(S32 pos);
+	/*
+	 * Creates chiclet and adds it to chiclet list.
+	*/
+	template<class T> T* createChiclet(const LLUUID& session_id = LLUUID::null, S32 index = 0);
 
-	LLChiclet* findIMChiclet(const LLUUID& im_session_id);
+	/*
+	 * Returns pointer to chiclet of specified type at specified index.
+	*/
+	template<class T> T* getChiclet(S32 index);
 
-	S32 getChicletCount() {return mChicletList.size();};
+	/*
+	 * Returns pointer to LLChiclet at specified index.
+	*/
+	LLChiclet* getChiclet(S32 index) { return getChiclet<LLChiclet>(index); }
 
-	void removeChiclet(S32 pos);
+	/*
+	 * Searches a chiclet using IM session id.
+	*/
+	template<class T> T* findChiclet(const LLUUID& im_session_id);
 
-	void removeChiclet(LLChiclet*);
-
-	void removeIMChiclet(const LLUUID& im_session_id);
+	/*
+	 * Returns number of hosted chiclets.
+	*/
+	S32 getChicletCount() {return mChicletList.size();};
 
+	/*
+	 * Returns index of chiclet in list.
+	*/
+	S32 getChicletIndex(const LLChiclet* chiclet);
+
+	/*
+	 * Removes chiclet by index.
+	*/
+	void removeChiclet(S32 index);
+
+	/*
+	 * Removes chiclet by pointer.
+	*/
+	void removeChiclet(LLChiclet* chiclet);
+
+	/*
+	 * Removes chiclet by IM session id.
+	*/
+	void removeChiclet(const LLUUID& im_session_id);
+
+	/*
+	 * Removes all chiclets.
+	*/
 	void removeAll();
 
-	void scrollLeft();
-
-	void scrollRight();
-
-	void onLeftScrollClick();
-
-	void onRightScrollClick();
-
-	boost::signals2::connection setChicletClickCallback(
+	boost::signals2::connection setChicletClickedCallback(
 		const commit_callback_t& cb);
 
-	void onChicletClick(LLUICtrl*ctrl,const LLSD&param);
-
-	//overrides
-public:
 	/*virtual*/ BOOL postBuild();
 
-	void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE );
+	/*
+	 * Reshapes controls and rearranges chiclets if needed.
+	*/
+	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE );
 
-	void draw();
+	/*virtual*/ void draw();
 
 protected:
 	LLChicletPanel(const Params&p);
 	friend class LLUICtrlFactory;
 
+	/*
+	 * Adds chiclet to list and rearranges all chiclets.
+	*/
+	bool addChiclet(LLChiclet*, S32 index);
+
+	/*
+	 * Arranges chiclets.
+	*/
 	void arrange();
 
+	/*
+	 * Returns true if chiclets can be scrolled right.
+	*/
 	bool canScrollRight();
 
+	/*
+	* Returns true if chiclets can be scrolled left.
+	*/
 	bool canScrollLeft();
 
+	/*
+	* Shows or hides chiclet scroll buttons if chiclets can or can not be scrolled.
+	*/
 	void showScrollButtonsIfNeeded();
 
-	S32 getFirstVisibleChiclet();
+	/*
+	 * Shifts chiclets left or right.
+	*/
+	void shiftChiclets(S32 offset, S32 start_index = 0);
+
+	/*
+	 * Removes gaps between first chiclet and scroll area left side,
+	 * last chiclet and scroll area right side.
+	*/
+	void trimChiclets();
+
+	/*
+	 * Scrolls chiclets to right or left.
+	*/
+	void scroll(S32 offset);
+
+	/*
+	 * Verifies that chiclets can be scrolled left, then calls scroll()
+	*/
+	void scrollLeft();
 
-	void reshapeScrollArea(S32 delta_width);
+	/*
+	 * Verifies that chiclets can be scrolled right, then calls scroll()
+	*/
+	void scrollRight();
 
-	enum ScrollDirection
-	{
-		SCROLL_LEFT = 1,
-		SCROLL_RIGHT = -1
-	};
+	/*
+	 * Callback for left scroll button clicked
+	*/
+	void onLeftScrollClick();
+
+	/*
+	* Callback for right scroll button clicked
+	*/
+	void onRightScrollClick();
 
-	void scroll(ScrollDirection direction);
+	/*
+	 * Callback for mouse wheel scrolled, calls scrollRight() or scrollLeft()
+	*/
+	BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+
+	/*
+	 * Notifies subscribers about click on chiclet.
+	 * Do not place any code here, instead subscribe on event (see setChicletClickedCallback).
+	*/
+	void onChicletClick(LLUICtrl*ctrl,const LLSD&param);
+
+	/*
+	 * Callback for chiclet size changed event, rearranges chiclets.
+	*/
+	void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param);
 
 	typedef std::vector<LLChiclet*> chiclet_list_t;
 
+	/*
+	 * Removes chiclet from scroll area and chiclet list.
+	*/
 	void removeChiclet(chiclet_list_t::iterator it);
 
-	BOOL handleScrollWheel(S32 x, S32 y, S32 clicks);
+	S32 getChicletPadding() { return mChicletPadding; }
+
+	S32 getScrollingOffset() { return mScrollingOffset; }
 
 protected:
 
 	chiclet_list_t mChicletList;
-	LLButton* mLeftScroll;
-	LLButton* mRightScroll;
+	LLButton* mLeftScrollButton;
+	LLButton* mRightScrollButton;
 	LLPanel* mScrollArea;
-};
 
+	S32 mChicletPadding;
+	S32 mScrollingOffset;
+};
 
+/*
+ * Button displaying voice chat status. Displays voice chat options When clicked.
+*/
 class LLTalkButton : public LLUICtrl
 {
 public:
 
-	virtual ~LLTalkButton();
+	struct Params :	public LLInitParam::Block<Params, LLUICtrl::Params>
+	{
+		Optional<LLButton::Params>	speak_button,
+									show_button;
 
-	void onClick_SpeakBtn();
-	void onClick_ShowBtn();
+		Optional<LLOutputMonitorCtrl::Params> monitor;
 
-	void draw();
+		Params();
+	};
+
+	/*virtual*/ ~LLTalkButton();
+
+	/*virtual*/ void draw();
 
 protected:
 	friend class LLUICtrlFactory;
-	LLTalkButton(const LLUICtrl::Params& p);
+	LLTalkButton(const Params& p);
+
+	void onClick_SpeakBtn();
+
+	void onClick_ShowBtn();
 
 private:
 	LLButton*	mSpeakBtn;
@@ -282,4 +592,68 @@ class LLTalkButton : public LLUICtrl
 	LLOutputMonitorCtrl* mOutputMonitor;
 };
 
+template<class T> 
+T* LLChicletPanel::createChiclet(const LLUUID& session_id /*= LLUUID::null*/, S32 index /*= 0*/)
+{
+	typename T::Params params;
+	T* chiclet = LLUICtrlFactory::create<T>(params);
+	if(!chiclet)
+	{
+		llwarns << "Could not create chiclet" << llendl;
+		return NULL;
+	}
+	if(!addChiclet(chiclet, index))
+	{
+		delete chiclet;
+		llwarns << "Could not add chiclet to chiclet panel" << llendl;
+		return NULL;
+	}
+
+	chiclet->setSessionId(session_id);
+
+	return chiclet;
+}
+
+template<class T>
+T* LLChicletPanel::findChiclet(const LLUUID& im_session_id)
+{
+	if(im_session_id.isNull())
+	{
+		return NULL;
+	}
+
+	chiclet_list_t::const_iterator it = mChicletList.begin();
+	for( ; mChicletList.end() != it; ++it)
+	{
+		LLChiclet* chiclet = *it;
+
+		if(chiclet->getSessionId() == im_session_id)
+		{
+			T* result = dynamic_cast<T*>(chiclet);
+			if(!result && chiclet)
+			{
+				llwarns << "Found chiclet but of wrong type " << llendl;
+			}
+			return result;
+		}
+	}
+	return NULL;
+}
+
+template<class T> T* LLChicletPanel::getChiclet(S32 index)
+{
+	if(index < 0 || index >= getChicletCount())
+	{
+		return NULL;
+	}
+
+	LLChiclet* chiclet = mChicletList[index];
+	T*result = dynamic_cast<T*>(chiclet);
+	if(!result && chiclet)
+	{
+		llwarns << "Found chiclet but of wrong type " << llendl;
+	}
+	return result;
+}
+
 #endif // LL_LLCHICLET_H
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 92e2d3563a8..00d4f800542 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -43,6 +43,8 @@
 #include "llagent.h"
 #include "llinventorybridge.h"
 #include "llinventorymodel.h"
+#include "llsidetray.h"
+#include "lltoggleablemenu.h"
 #include "llviewerinventory.h"
 #include "llviewermenu.h"
 #include "llviewermenu.h"
@@ -69,41 +71,6 @@ struct LLFavoritesSort
 	}
 };
 
-class LLVisibilityTrackingMenuGL : public LLMenuGL
-{
-protected:
-	LLVisibilityTrackingMenuGL(const LLMenuGL::Params&);
-	friend class LLUICtrlFactory;
-public:
-	virtual void onVisibilityChange (BOOL curVisibilityIn);
-	void setChevronRect(const LLRect& rect) { mChevronRect = rect; }
-
-	bool getClosedByChevronClick() { return mClosedByChevronClick; }
-	void resetClosedByChevronClick() { mClosedByChevronClick = false; }
-	
-protected:
-	bool mClosedByChevronClick;
-	LLRect mChevronRect;
-};
-
-LLVisibilityTrackingMenuGL::LLVisibilityTrackingMenuGL(const LLMenuGL::Params& p)
-:	LLMenuGL(p),
-	mClosedByChevronClick(false)
-{
-}
-
-//virtual
-void LLVisibilityTrackingMenuGL::onVisibilityChange (BOOL curVisibilityIn)
-{
-	S32 x,y;
-	LLUI::getCursorPositionLocal(LLUI::getRootView(), &x, &y);
-
-	if (!curVisibilityIn && mChevronRect.pointInRect(x, y))
-	{
-		mClosedByChevronClick = true;
-	}
-}
-
 LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
 :	LLUICtrl(p),
 	mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()),
@@ -269,10 +236,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
 				LLRect rect;
 				rect.setOriginAndSize(bar_width - chevron_button_width - buttonHGap, buttonVGap, chevron_button_width, getRect().getHeight()-buttonVGap);
 				chevron_button->setRect(rect);
-
-				S32 chevron_root_x, chevron_root_y;
-				localPointToOtherView(rect.mLeft, rect.mBottom, &chevron_root_x, &chevron_root_y, LLUI::getRootView());
-				mChevronRect.setOriginAndSize(chevron_root_x, chevron_root_y, rect.getWidth(), rect.getHeight());
+				mChevronRect = rect;
 			}
 			return;
 		}
@@ -355,9 +319,7 @@ void LLFavoritesBarCtrl::updateButtons(U32 bar_width)
 
 		addChildInBack(LLUICtrlFactory::create<LLButton> (bparams));
 
-		S32 chevron_root_x, chevron_root_y;
-		localPointToOtherView(rect.mLeft, rect.mBottom, &chevron_root_x, &chevron_root_y, LLUI::getRootView());
-		mChevronRect.setOriginAndSize(chevron_root_x, chevron_root_y, rect.getWidth(), rect.getHeight());
+		mChevronRect = rect;
 	}
 }
 
@@ -400,25 +362,25 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 		menu_p.visible(false);
 		menu_p.scrollable(true);
 
-		LLVisibilityTrackingMenuGL* menu = LLUICtrlFactory::create<LLVisibilityTrackingMenuGL>(menu_p);
+		LLToggleableMenu* menu = LLUICtrlFactory::create<LLToggleableMenu>(menu_p);
 
 		mPopupMenuHandle = menu->getHandle();
 	}
 
-	LLVisibilityTrackingMenuGL* menu = (LLVisibilityTrackingMenuGL*)mPopupMenuHandle.get();
+	LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get();
 
 	if(menu)
 	{
-		if (menu->getClosedByChevronClick())
+		if (menu->getClosedByButtonClick())
 		{
-			menu->resetClosedByChevronClick();
+			menu->resetClosedByButtonClick();
 			return;
 		}
 
 		if (menu->getVisible())
 		{
 			menu->setVisible(FALSE);
-			menu->resetClosedByChevronClick();
+			menu->resetClosedByButtonClick();
 			return;
 		}
 
@@ -449,7 +411,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 				menu->buildDrawLabels();
 				menu->updateParent(LLMenuGL::sMenuContainer);
 
-				menu->setChevronRect(mChevronRect);
+				menu->setButtonRect(mChevronRect, this);
 
 				LLMenuGL::showPopup(this, menu, getRect().getWidth() - menu->getRect().getWidth(), 0);
 				return;
@@ -514,7 +476,7 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 		menu->buildDrawLabels();
 		menu->updateParent(LLMenuGL::sMenuContainer);
 
-		menu->setChevronRect(mChevronRect);
+		menu->setButtonRect(mChevronRect, this);
 
 		LLMenuGL::showPopup(this, menu, getRect().getWidth() - max_width, 0);
 	}
@@ -565,7 +527,11 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
 	}
 	else if (action == "about")
 	{
-		LLFloaterReg::showInstance("preview_landmark", LLSD(mSelectedItemID), TAKE_FOCUS_YES);
+		LLSD key;
+		key["type"] = "landmark";
+		key["id"] = mSelectedItemID;
+
+		LLSideTray::getInstance()->showPanel("panel_places", key);
 	}
 	else if (action == "rename")
 	{
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 646e98cabba..a5596923313 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -34,7 +34,7 @@
 #define LL_LLFAVORITESBARCTRL_H
 
 #include "lluictrl.h"
-#include "lliconctrl.h"
+
 #include "llinventorymodel.h"
 
 class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index 1bfb11e3aee..dd0df15348f 100644
--- a/indra/newview/llfloaterchat.cpp
+++ b/indra/newview/llfloaterchat.cpp
@@ -54,7 +54,6 @@
 //#include "lllineeditor.h"
 #include "llmutelist.h"
 //#include "llresizehandle.h"
-#include "llchatbar.h"
 #include "llrecentpeople.h"
 #include "llstatusbar.h"
 #include "llviewertexteditor.h"
@@ -63,7 +62,6 @@
 #include "llviewerwindow.h"
 #include "llviewercontrol.h"
 #include "lluictrlfactory.h"
-#include "llchatbar.h"
 #include "lllogchat.h"
 #include "lltexteditor.h"
 #include "lltextparser.h"
@@ -99,7 +97,6 @@ LLFloaterChat::LLFloaterChat(const LLSD& seed)
 	: LLFloater(seed),
 	  mPanel(NULL)
 {
-	mFactoryMap["chat_panel"] = LLCallbackMap(createChatPanel, NULL);
 	mFactoryMap["active_speakers_panel"] = LLCallbackMap(createSpeakersPanel, NULL);
 	//Called from floater reg: LLUICtrlFactory::getInstance()->buildFloater(this,"floater_chat_history.xml");
 
@@ -121,12 +118,6 @@ void LLFloaterChat::draw()
 		
 	childSetValue("toggle_active_speakers_btn", childIsVisible("active_speakers_panel"));
 
-	LLChatBar* chat_barp = findChild<LLChatBar>("chat_panel", TRUE);
-	if (chat_barp)
-	{
-		chat_barp->refresh();
-	}
-
 	mPanel->refreshSpeakers();
 	LLFloater::draw();
 }
@@ -135,12 +126,6 @@ BOOL LLFloaterChat::postBuild()
 {
 	mPanel = (LLPanelActiveSpeakers*)getChild<LLPanel>("active_speakers_panel");
 
-	LLChatBar* chat_barp = findChild<LLChatBar>("chat_panel", TRUE);
-	if (chat_barp)
-	{
-		chat_barp->setGestureCombo(getChild<LLComboBox>( "Gesture"));
-	}
-
 	childSetCommitCallback("show mutes",onClickToggleShowMute,this); //show mutes
 	childSetVisible("Chat History Editor with mute",FALSE);
 	childSetAction("toggle_active_speakers_btn", onClickToggleActiveSpeakers, this);
@@ -540,13 +525,6 @@ void* LLFloaterChat::createSpeakersPanel(void* data)
 	return new LLPanelActiveSpeakers(LLLocalSpeakerMgr::getInstance(), TRUE);
 }
 
-//static
-void* LLFloaterChat::createChatPanel(void* data)
-{
-	LLChatBar* chatp = new LLChatBar();
-	return chatp;
-}
-
 // static
 void LLFloaterChat::onClickToggleActiveSpeakers(void* userdata)
 {
diff --git a/indra/newview/llfloaterchat.h b/indra/newview/llfloaterchat.h
index 2bae4ea0c29..042d270aa6e 100644
--- a/indra/newview/llfloaterchat.h
+++ b/indra/newview/llfloaterchat.h
@@ -82,7 +82,6 @@ class LLFloaterChat : public LLFloater
 	static void chatFromLogFile(LLLogChat::ELogLineType type,std::string line, void* userdata);
 	static void loadHistory();
 	static void* createSpeakersPanel(void* data);
-	static void* createChatPanel(void* data);
 	
 	static LLFloaterChat* getInstance(); // *TODO:Skinning Deprecate
 	
diff --git a/indra/newview/llfloaterfriends.cpp b/indra/newview/llfloaterfriends.cpp
index 1e8129c7d3f..1e8e7bad74f 100644
--- a/indra/newview/llfloaterfriends.cpp
+++ b/indra/newview/llfloaterfriends.cpp
@@ -46,7 +46,7 @@
 #include "llfloateravatarpicker.h"
 #include "llviewerwindow.h"
 #include "llbutton.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "llinventorymodel.h"
 #include "llnamelistctrl.h"
 #include "llnotify.h"
@@ -62,7 +62,7 @@
 #include "lltextbox.h"
 #include "llvoiceclient.h"
 
-// *TODO: Move more common stuff to LLFriendActions?
+// *TODO: Move more common stuff to LLAvatarActions?
 
 //Maximum number of people you can select to do an operation on at once.
 #define MAX_FRIEND_SELECT 20
@@ -546,7 +546,7 @@ void LLPanelFriends::onClickProfile(void* user_data)
 	if(ids.size() > 0)
 	{
 		LLUUID agent_id = ids[0];
-		LLFriendActions::showProfile(agent_id);
+		LLAvatarActions::showProfile(agent_id);
 	}
 }
 
@@ -560,11 +560,11 @@ void LLPanelFriends::onClickIM(void* user_data)
 	{
 		if(ids.size() == 1)
 		{
-			LLFriendActions::startIM(ids[0]);
+			LLAvatarActions::startIM(ids[0]);
 		}
 		else
 		{
-			LLFriendActions::startConference(ids);
+			LLAvatarActions::startConference(ids);
 		}
 	}
 }
@@ -576,7 +576,7 @@ void LLPanelFriends::onPickAvatar(const std::vector<std::string>& names,
 {
 	if (names.empty()) return;
 	if (ids.empty()) return;
-	LLFriendActions::requestFriendshipDialog(ids[0], names[0]);
+	LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
 }
 
 // static
@@ -595,14 +595,14 @@ void LLPanelFriends::onClickAddFriend(void* user_data)
 void LLPanelFriends::onClickRemove(void* user_data)
 {
 	LLPanelFriends* panelp = (LLPanelFriends*)user_data;
-	LLFriendActions::removeFriendsDialog(panelp->getSelectedIDs());
+	LLAvatarActions::removeFriendsDialog(panelp->getSelectedIDs());
 }
 
 // static
 void LLPanelFriends::onClickOfferTeleport(void* user_data)
 {
 	LLPanelFriends* panelp = (LLPanelFriends*)user_data;
-	LLFriendActions::offerTeleport(panelp->getSelectedIDs());
+	LLAvatarActions::offerTeleport(panelp->getSelectedIDs());
 }
 
 // static
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index 972b3b95288..e26937e93ff 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -36,7 +36,7 @@
 
 #include "llfloaterreg.h"
 #include "llfloatertools.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "llcachename.h"
 #include "llscrolllistctrl.h"
 #include "llscrolllistitem.h"
@@ -144,7 +144,7 @@ void LLFloaterInspect::onClickCreatorProfile()
 		LLSelectNode* node = mObjectSelection->getFirstNode(&func);
 		if(node)
 		{
-			LLFriendActions::showProfile(node->mPermissions->getCreator());
+			LLAvatarActions::showProfile(node->mPermissions->getCreator());
 		}
 	}
 }
@@ -170,7 +170,7 @@ void LLFloaterInspect::onClickOwnerProfile()
 		if(node)
 		{
 			const LLUUID& owner_id = node->mPermissions->getOwner();
-			LLFriendActions::showProfile(owner_id);
+			LLAvatarActions::showProfile(owner_id);
 		}
 	}
 }
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index f7e5eaadd30..4b665a789e1 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -52,7 +52,7 @@
 #include "llfloaterauction.h"
 #include "llfloatergroups.h"
 #include "llfloatergroupinfo.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "lllineeditor.h"
 #include "llnamelistctrl.h"
 #include "llnotify.h"
@@ -811,7 +811,7 @@ void LLPanelLandGeneral::onClickProfile(void* data)
 	else
 	{
 		const LLUUID& avatar_id = parcel->getOwnerID();
-		LLFriendActions::showProfile(avatar_id);
+		LLAvatarActions::showProfile(avatar_id);
 	}
 }
 
@@ -1084,7 +1084,7 @@ void LLPanelLandObjects::onDoubleClickOwner(void *userdata)
 		}
 		else
 		{
-			LLFriendActions::showProfile(owner_id);
+			LLAvatarActions::showProfile(owner_id);
 		}
 	}
 }
diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp
index dc72b66949b..efc273c6e52 100644
--- a/indra/newview/llfloaterproperties.cpp
+++ b/indra/newview/llfloaterproperties.cpp
@@ -44,7 +44,7 @@
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
 #include "llfloatergroupinfo.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "llinventorymodel.h"
 #include "lllineeditor.h"
 #include "llradiogroup.h"
@@ -611,7 +611,7 @@ void LLFloaterProperties::onClickCreator(void* data)
 	if(!item) return;
 	if(!item->getCreatorUUID().isNull())
 	{
-		LLFriendActions::showProfile(item->getCreatorUUID());
+		LLAvatarActions::showProfile(item->getCreatorUUID());
 	}
 }
 
@@ -628,7 +628,7 @@ void LLFloaterProperties::onClickOwner(void* data)
 	}
 	else
 	{
-		LLFriendActions::showProfile(item->getPermissions().getOwner());
+		LLAvatarActions::showProfile(item->getPermissions().getOwner());
 	}
 }
 
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 66ed680984b..8ec9eac1969 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -50,7 +50,6 @@
 
 // newview
 #include "llagent.h"
-#include "llchatbar.h"
 #include "lldelayedgestureerror.h"
 #include "llinventorymodel.h"
 #include "llnotify.h"
@@ -872,8 +871,7 @@ void LLGestureManager::runStep(LLMultiGesture* gesture, LLGestureStep* step)
 
 			const BOOL animate = FALSE;
 
-			if(gBottomTray)
-				gBottomTray->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
+			LLBottomTray::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
 
 			gesture->mCurrentStep++;
 			break;
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 953d99c7acc..c71262c311f 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -39,7 +39,6 @@
 
 #include "llagent.h"
 #include "llviewercontrol.h"
-#include "llchatbar.h"
 #include "llcriticaldamp.h"
 #include "lldrawable.h"
 #include "llfontgl.h"
@@ -803,10 +802,6 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)
 
 	LLRect world_rect = gViewerWindow->getVirtualWorldViewRect();
 	S32 bottom = world_rect.mBottom + STATUS_BAR_HEIGHT;
-	if (gChatBar && gChatBar->getVisible())
-	{
-		bottom += CHAT_BAR_HEIGHT;
-	}
 
 	LLVector2 screen_center;
 	screen_center.mV[VX] = llclamp((F32)screen_pos_vec.mV[VX], (F32)world_rect.mLeft + mWidth * 0.5f, (F32)world_rect.mRight - mWidth * 0.5f);
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 9bf147584a6..0652119f18e 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -51,7 +51,7 @@
 #include "llfloater.h"
 #include "llfloatercall.h"
 #include "llfloatergroupinfo.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "llimview.h"
 #include "llinventory.h"
 #include "llinventorymodel.h"
@@ -1569,7 +1569,7 @@ void LLFloaterIMPanel::onClickProfile( void* userdata )
 	
 	if (self->getOtherParticipantID().notNull())
 	{
-		LLFriendActions::showProfile(self->getOtherParticipantID());
+		LLAvatarActions::showProfile(self->getOtherParticipantID());
 	}
 }
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index f8dd35e956b..38335fe68f4 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -51,7 +51,7 @@
 #include "llresmgr.h"
 #include "llfloaterchat.h"
 #include "llfloaterchatterbox.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "llhttpnode.h"
 #include "llimpanel.h"
 #include "llresizebar.h"
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 54d8208e9eb..b705543e444 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -57,7 +57,7 @@
 #include "llfloaterworldmap.h"
 #include "llfocusmgr.h"
 #include "llfolderview.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "llgesturemgr.h"
 #include "lliconctrl.h"
 #include "llinventorymodel.h"
@@ -88,6 +88,7 @@
 #include "lltabcontainer.h"
 #include "lluictrlfactory.h"
 #include "llselectmgr.h"
+#include "llsidetray.h"
 #include "llfloateropenobject.h"
 #include "lltrans.h"
 
@@ -2825,7 +2826,15 @@ void LLLandmarkBridge::performAction(LLFolderView* folder, LLInventoryModel* mod
 		LLViewerInventoryItem* item = getItem();
 		if(item)
 		{
-			LLFloaterReg::showInstance("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES);
+			LLSD key;
+			key["type"] = "landmark";
+			key["id"] = item->getUUID();
+
+			LLSideTray::getInstance()->showPanel("panel_places", key);
+			
+			// Floater preview_landmark disabled, 
+			// its functionality moved to Side Tray Places Panel 
+			//LLFloaterReg::showInstance("preview_landmark", LLSD(item->getUUID()), TAKE_FOCUS_YES);
 		}
 	}
 	else 
@@ -2925,7 +2934,7 @@ void LLCallingCardBridge::performAction(LLFolderView* folder, LLInventoryModel*
 		if (item && (item->getCreatorUUID() != gAgent.getID()) &&
 			(!item->getCreatorUUID().isNull()))
 		{
-			LLFriendActions::offerTeleport(item->getCreatorUUID());
+			LLAvatarActions::offerTeleport(item->getCreatorUUID());
 		}
 	}
 	else LLItemBridge::performAction(folder, model, action);
@@ -2967,7 +2976,7 @@ void LLCallingCardBridge::openItem()
 	LLViewerInventoryItem* item = getItem();
 	if(item && !item->getCreatorUUID().isNull())
 	{
-		LLFriendActions::showProfile(item->getCreatorUUID());
+		LLAvatarActions::showProfile(item->getCreatorUUID());
 	}
 */
 }
@@ -4891,7 +4900,7 @@ void	LLCallingCardBridgeAction::doIt()
 	LLViewerInventoryItem* item = getItem();
 	if(item && item->getCreatorUUID().notNull())
 	{
-		LLFriendActions::showProfile(item->getCreatorUUID());
+		LLAvatarActions::showProfile(item->getCreatorUUID());
 	}
 
 	LLInvFVBridgeAction::doIt();
diff --git a/indra/newview/llmenucommands.cpp b/indra/newview/llmenucommands.cpp
index c0225ebfcad..0c652621f48 100644
--- a/indra/newview/llmenucommands.cpp
+++ b/indra/newview/llmenucommands.cpp
@@ -44,7 +44,6 @@
 
 #include "llagent.h"
 #include "llcallingcard.h"
-#include "llchatbar.h"
 #include "llviewercontrol.h"
 #include "llfirstuse.h"
 #include "llfloaterchat.h"
@@ -84,20 +83,20 @@ void handle_mouselook(void*)
 void handle_chat(void*)
 {
 	// give focus to chatbar if it's open but not focused
-	if (gBottomTray && gSavedSettings.getBOOL("ChatVisible") && 
-		gFocusMgr.childHasKeyboardFocus(gBottomTray->getChatBox()))
+	if (gSavedSettings.getBOOL("ChatVisible") && 
+		gFocusMgr.childHasKeyboardFocus(LLBottomTray::getInstance()->getChatBox()))
 	{
-		LLChatBar::stopChat();
+		LLBottomTray::stopChat();
 	}
 	else
 	{
-		LLChatBar::startChat(NULL);
+		LLBottomTray::startChat(NULL);
 	}
 }
 
 void handle_slash_key(void*)
 {
-	// LLChatBar::startChat("/");
+	// LLBottomTray::startChat("/");
 	//
 	// Don't do this, it results in a double-slash in the input field.
 	// Another "/" will be automatically typed for us, because the WM_KEYDOWN event
@@ -107,5 +106,5 @@ void handle_slash_key(void*)
 	// menu accelerators that put input focus into a field.   And Mac works
 	// the same way.  JC
 
-	LLChatBar::startChat(NULL);
+	LLBottomTray::startChat(NULL);
 }
diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp
index d03e39280fa..a24d1ed54a4 100644
--- a/indra/newview/lloverlaybar.cpp
+++ b/indra/newview/lloverlaybar.cpp
@@ -41,7 +41,6 @@
 #include "llrender.h"
 #include "llagent.h"
 #include "llbutton.h"
-#include "llchatbar.h"
 #include "llfocusmgr.h"
 #include "llimview.h"
 #include "llmediaremotectrl.h"
@@ -92,12 +91,6 @@ void* LLOverlayBar::createVoiceRemote(void* userdata)
 	return self->mVoiceRemote;
 }
 
-void* LLOverlayBar::createChatBar(void* userdata)
-{
-	gChatBar = new LLChatBar();
-	return gChatBar;
-}
-
 LLOverlayBar::LLOverlayBar()
 	:	LLPanel(),
 		mMediaRemote(NULL),
@@ -111,7 +104,6 @@ LLOverlayBar::LLOverlayBar()
 
 	mFactoryMap["media_remote"] = LLCallbackMap(LLOverlayBar::createMediaRemote, this);
 	mFactoryMap["voice_remote"] = LLCallbackMap(LLOverlayBar::createVoiceRemote, this);
-	mFactoryMap["chat_bar"] = LLCallbackMap(LLOverlayBar::createChatBar, this);
 	
 	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_overlaybar.xml");
 }
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index e3c4167d731..868d4d9200c 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -38,7 +38,7 @@
 #include "llavatarconstants.h"
 #include "llcallingcard.h"
 #include "llcombobox.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "llimview.h"
 #include "lltexteditor.h"
 #include "lltexturectrl.h"
@@ -182,7 +182,7 @@ void LLPanelProfileTab::onAddFriend()
 	{
 		std::string name;
 		gCacheName->getFullName(getAvatarId(),name);
-		LLFriendActions::requestFriendshipDialog(getAvatarId(), name);
+		LLAvatarActions::requestFriendshipDialog(getAvatarId(), name);
 	}
 }
 
@@ -200,7 +200,7 @@ void LLPanelProfileTab::onTeleport()
 {
 	if(getAvatarId().notNull())
 	{
-		LLFriendActions::offerTeleport(getAvatarId());
+		LLAvatarActions::offerTeleport(getAvatarId());
 	}
 }
 
@@ -296,7 +296,7 @@ void LLPanelAvatarProfile::processProperties(void* data, EAvatarProcessorType ty
 
 
 			bool online = avatar_data->flags & AVATAR_ONLINE;
-			if(LLFriendActions::isFriend(avatar_data->avatar_id))
+			if(LLAvatarActions::isFriend(avatar_data->avatar_id))
 			{
 				// Online status NO could be because they are hidden
 				// If they are a friend, we may know the truth!
@@ -536,7 +536,7 @@ void LLPanelAvatarProfile::updateChildrenList()
 		childSetVisible("partner_edit_link", false);
 
 		//hide for friends
-		childSetEnabled("add_friend", !LLFriendActions::isFriend(getAvatarId()));
+		childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId()));
 
 		//need to update profile view on every activate
 		mUpdated = false;
@@ -730,5 +730,5 @@ void LLPanelAvatarNotes::onActivate(const LLUUID& id)
 void LLPanelAvatarNotes::updateChildrenList()
 {
 	//hide for friends
-	childSetEnabled("add_friend", !LLFriendActions::isFriend(getAvatarId()));
+	childSetEnabled("add_friend", !LLAvatarActions::isFriend(getAvatarId()));
 }
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index bd4625ab116..df687ffb309 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -42,10 +42,12 @@
 #include "lldispatcher.h"
 #include "llfloaterreg.h"
 #include "llparcel.h"
+#include "lltabcontainer.h"
 #include "message.h"
 
 #include "llagent.h"
 #include "llalertdialog.h"
+#include "llavataractions.h"
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
 #include "llclassifiedflags.h"
@@ -53,7 +55,6 @@
 #include "llcommandhandler.h" // for classified HTML detail page click tracking
 #include "llviewercontrol.h"
 #include "lllineeditor.h"
-#include "llfloateravatarinfo.h"
 #include "llfloaterclassified.h"
 #include "lltextbox.h"
 #include "llcombobox.h"
@@ -959,7 +960,7 @@ void LLPanelClassified::onClickMap(void* data)
 void LLPanelClassified::onClickProfile(void* data)
 {
 	LLPanelClassified* self = (LLPanelClassified*)data;
-	LLFloaterAvatarInfo::showFromDirectory(self->mCreatorID);
+	LLAvatarActions::showProfile(self->mCreatorID);
 	self->sendClassifiedClickMessage("profile");
 }
 
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index d495373cc4b..6f8d1610017 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -44,7 +44,7 @@
 #include "llcheckboxctrl.h"
 #include "llcombobox.h"
 #include "lldbstrings.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "lllineeditor.h"
 #include "llnamebox.h"
 #include "llnamelistctrl.h"
@@ -375,7 +375,7 @@ void LLPanelGroupGeneral::openProfile(void* data)
 		LLScrollListItem* selected = self->mListVisibleMembers->getFirstSelected();
 		if (selected)
 		{
-			LLFriendActions::showProfile(selected->getUUID());
+			LLAvatarActions::showProfile(selected->getUUID());
 		}
 	}
 }
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 365f07e4b6f..1c52c3cea47 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -37,7 +37,7 @@
 #include "llagent.h"
 #include "llbutton.h"
 #include "llfloatergroupinvite.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "lliconctrl.h"
 #include "lllineeditor.h"
 #include "llnamelistctrl.h"
@@ -1289,7 +1289,7 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick()
 	LLScrollListItem* selected = mMembersList->getFirstSelected();
 	if (selected)
 	{
-		LLFriendActions::showProfile(selected->getUUID());
+		LLAvatarActions::showProfile(selected->getUUID());
 	}
 }
 
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index 6fad582eeee..453183ad741 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -268,3 +268,8 @@ void LLLandmarksPanel::onSelectorButtonClicked()
 		LLSideTray::getInstance()->showPanel("panel_places", key);
 	}
 }
+
+void LLLandmarksPanel::setSelectedItem(const LLUUID& obj_id)
+{
+	mInventoryPanel->setSelection(obj_id, FALSE);
+}
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 8889a99925b..0b11270fb57 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -52,6 +52,7 @@ class LLLandmarksPanel : public LLPanelPlacesTab
 
 	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
 	void onSelectorButtonClicked();
+	void setSelectedItem(const LLUUID& obj_id);
 
 private:
 	LLInventoryPanel*			mInventoryPanel;
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 82c8f97d4d7..d2879a675f7 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -47,7 +47,7 @@
 #include "llcallingcard.h"			// for LLAvatarTracker
 #include "llfloateravatarpicker.h"
 #include "llfloaterminiinspector.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "llgroupactions.h"
 #include "llgrouplist.h"
 #include "llrecentpeople.h"
@@ -508,17 +508,19 @@ void LLPanelPeople::updateButtons()
 
 	if (group_tab_active)
 	{
+		bool item_selected = mGroupList->getFirstSelected() != NULL;
 		bool cur_group_active = true;
 
-		selected_id = mGroupList->getCurrentID();
-		if (selected_id.notNull())
+		if (item_selected)
+		{
+			selected_id = mGroupList->getCurrentID();
 			cur_group_active = (gAgent.getGroupID() == selected_id);
-
-		bool item_selected = selected_id.notNull();
+		}
+	
 		LLPanel* groups_panel = mTabContainer->getCurrentPanel();
-		groups_panel->childSetEnabled("activate_btn",	!item_selected || !cur_group_active); // "none" or a non-active group selected
+		groups_panel->childSetEnabled("activate_btn",	item_selected && !cur_group_active); // "none" or a non-active group selected
 		groups_panel->childSetEnabled("plus_btn",		item_selected);
-		groups_panel->childSetEnabled("minus_btn",		item_selected);
+		groups_panel->childSetEnabled("minus_btn",		item_selected && selected_id.notNull());
 	}
 	else
 	{
@@ -623,6 +625,8 @@ void LLPanelPeople::onSearchEdit(const std::string& search_string)
 	filterFriendList();
 	filterRecentList();
 	updateGroupList();
+
+	updateButtons();
 }
 
 void LLPanelPeople::onTabSelected(const LLSD& param)
@@ -653,7 +657,7 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)
 void LLPanelPeople::onViewProfileButtonClicked()
 {
 	LLUUID id = getCurrentItemID();
-	LLFriendActions::showProfile(id);
+	LLAvatarActions::showProfile(id);
 }
 
 void LLPanelPeople::onAddFriendButtonClicked()
@@ -663,7 +667,7 @@ void LLPanelPeople::onAddFriendButtonClicked()
 	{
 		std::string name;
 		gCacheName->getFullName(id, name);
-		LLFriendActions::requestFriendshipDialog(id, name);
+		LLAvatarActions::requestFriendshipDialog(id, name);
 	}
 }
 
@@ -680,7 +684,7 @@ void LLPanelPeople::onAddFriendWizButtonClicked()
 
 void LLPanelPeople::onDeleteFriendButtonClicked()
 {
-	LLFriendActions::removeFriendDialog(getCurrentItemID());
+	LLAvatarActions::removeFriendDialog(getCurrentItemID());
 }
 
 void LLPanelPeople::onGroupInfoButtonClicked()
@@ -702,7 +706,7 @@ void LLPanelPeople::onImButtonClicked()
 	LLUUID id = getCurrentItemID();
 	if (id.notNull())
 	{
-		LLFriendActions::startIM(id);
+		LLAvatarActions::startIM(id);
 	}
 }
 
@@ -718,7 +722,7 @@ void LLPanelPeople::onAvatarPicked(
 		void*)
 {
 	if (!names.empty() && !ids.empty())
-		LLFriendActions::requestFriendshipDialog(ids[0], names[0]);
+		LLAvatarActions::requestFriendshipDialog(ids[0], names[0]);
 }
 
 bool LLPanelPeople::onFriendListUpdate(U32 changed_mask)
@@ -765,7 +769,7 @@ void LLPanelPeople::onCallButtonClicked()
 
 void LLPanelPeople::onTeleportButtonClicked()
 {
-	LLFriendActions::offerTeleport(getCurrentItemID());
+	LLAvatarActions::offerTeleport(getCurrentItemID());
 }
 
 void LLPanelPeople::onShareButtonClicked()
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index 9fdde9e757d..96e8cbfd710 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -59,7 +59,7 @@
 #include "lldbstrings.h"
 #include "llfloatergroupinfo.h"
 #include "llfloatergroups.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "llnamebox.h"
 #include "llviewercontrol.h"
 #include "lluictrlfactory.h"
@@ -811,7 +811,7 @@ void LLPanelPermissions::onClickCreator(void *data)
 {
 	LLPanelPermissions *self = (LLPanelPermissions *)data;
 
-	LLFriendActions::showProfile(self->mCreatorID);
+	LLAvatarActions::showProfile(self->mCreatorID);
 }
 
 // static
@@ -827,7 +827,7 @@ void LLPanelPermissions::onClickOwner(void *data)
 	}
 	else
 	{
-		LLFriendActions::showProfile(self->mOwnerID);
+		LLAvatarActions::showProfile(self->mOwnerID);
 	}
 }
 
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index b1efb71abbd..961c54d667c 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -219,9 +219,6 @@ void LLPanelPick::setEditMode( BOOL edit_mode )
 	mEditMode = edit_mode;
 
 	// preserve data before killing controls
-	std::string name = getPickName();
-	std::string desc = getPickDesc();
-	std::string location = getPickLocation();
 	LLUUID snapshot_id = mSnapshotCtrl->getImageAssetID();
 	LLRect old_rect = getRect();
 
@@ -242,9 +239,9 @@ void LLPanelPick::setEditMode( BOOL edit_mode )
 	setRect(old_rect);
 
 	// time to restore data
-	setPickName(name);
-	setPickDesc(desc);
-	setPickLocation(location);
+	setPickName(mName);
+	setPickDesc(mDesc);
+	setPickLocation(mLocation);
 	mSnapshotCtrl->setImageAssetID(snapshot_id);
 
 	updateButtons();
@@ -260,6 +257,9 @@ void LLPanelPick::setPickName(std::string name)
 	{
 		childSetWrappedText(XML_NAME, name);
 	}
+	
+	//preserving non-wrapped text for info/edit modes switching
+	mName = name;
 }
 
 void LLPanelPick::setPickDesc(std::string desc)
@@ -272,11 +272,17 @@ void LLPanelPick::setPickDesc(std::string desc)
 	{
 		childSetWrappedText(XML_DESC, desc);
 	}
+
+	//preserving non-wrapped text for info/edit modes switching
+	mDesc = desc;
 }
 
 void LLPanelPick::setPickLocation(std::string location)
 {
 	childSetWrappedText(XML_LOCATION, location);
+
+	//preserving non-wrapped text for info/edit modes switching
+	mLocation = location;
 }
 
 std::string LLPanelPick::getPickName()
diff --git a/indra/newview/llpanelpick.h b/indra/newview/llpanelpick.h
index db943f4eafd..15b0d6c5415 100644
--- a/indra/newview/llpanelpick.h
+++ b/indra/newview/llpanelpick.h
@@ -122,6 +122,11 @@ class LLPanelPick : public LLPanel, public LLAvatarPropertiesObserver
 	LLUUID mParcelId;
 	std::string mSimName;
 
+	//These strings are used to keep non-wrapped text
+	std::string mName;
+	std::string mDesc;
+	std::string mLocation;
+
 	commit_callback_t mBackCb;
 };
 
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 5bbcf4207ff..590eae555ec 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -235,27 +235,46 @@ void LLPanelPlaceInfo::setInfoType(INFO_TYPE type)
 	if (!mInfoPanel)
 	    return;
 
-	if (type == PLACE)
+	switch(type)
 	{
-		mCurrentTitle = getString("title_place");
-	}
-	else
-	{
-		mCurrentTitle = getString("title_landmark");
+		case PLACE:
+			mCurrentTitle = getString("title_place");
+
+			if (!isMediaPanelVisible())
+			{
+				mTitle->setText(mCurrentTitle);
+			}
+		break;
+
+		// Hide Media Panel if showing information about
+		// a landmark or a teleport history item
+		case LANDMARK:
+			mCurrentTitle = getString("title_landmark");
+
+			toggleMediaPanel(FALSE);
+		break;
+		
+		case TELEPORT_HISTORY:
+			mCurrentTitle = getString("title_place");
+ 
+			toggleMediaPanel(FALSE);
+		break;
 	}
+}
+
+BOOL LLPanelPlaceInfo::isMediaPanelVisible()
+{
+	if (!mMediaPanel)
+		return FALSE;
 	
-	if (mInfoPanel->getVisible())
-	{
-		mTitle->setText(mCurrentTitle);
-	}
+	return mMediaPanel->getVisible();
 }
 
-void LLPanelPlaceInfo::toggleMediaPanel()
+void LLPanelPlaceInfo::toggleMediaPanel(BOOL visible)
 {
     if (!(mMediaPanel && mInfoPanel))
         return;
 
-    bool visible = mInfoPanel->getVisible();
     if (visible)
 	{
 		mTitle->setText(getString("title_media"));
diff --git a/indra/newview/llpanelplaceinfo.h b/indra/newview/llpanelplaceinfo.h
index 8b00507ba0d..7f98b6cb764 100644
--- a/indra/newview/llpanelplaceinfo.h
+++ b/indra/newview/llpanelplaceinfo.h
@@ -56,7 +56,8 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
 	enum INFO_TYPE
 	{
 		PLACE,
-		LANDMARK
+		LANDMARK,
+		TELEPORT_HISTORY
 	};
 
 	LLPanelPlaceInfo();
@@ -77,7 +78,8 @@ class LLPanelPlaceInfo : public LLPanel, LLRemoteParcelInfoObserver
 	// sets a corresponding title and contents.
 	void setInfoType(INFO_TYPE type);
 
-	void toggleMediaPanel();
+	BOOL isMediaPanelVisible();
+	void toggleMediaPanel(BOOL visible);
 	void displayItemInfo(const LLInventoryItem* pItem);
 	/*virtual*/ void setErrorStatus(U32 status, const std::string& reason);
 
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index f5e225c51b8..c162a9ba337 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -44,8 +44,23 @@
 #include "llpanelplaces.h"
 #include "llpanellandmarks.h"
 #include "llpanelteleporthistory.h"
+#include "llsidetray.h"
+#include "llviewerparcelmgr.h"
 #include "llviewerregion.h"
 
+LLPanelPlaces::LLParcelUpdateTimer::LLParcelUpdateTimer(F32 period)
+:	LLEventTimer(period)
+{
+};
+
+// virtual
+BOOL LLPanelPlaces::LLParcelUpdateTimer::tick()
+{
+	LLSideTray::getInstance()->showPanel("panel_places", LLSD().insert("type", "agent"));
+	
+	return TRUE;
+}
+
 static LLRegisterPanelClassWrapper<LLPanelPlaces> t_places("panel_places");
 
 LLPanelPlaces::LLPanelPlaces()
@@ -57,6 +72,9 @@ LLPanelPlaces::LLPanelPlaces()
 {
 	gInventory.addObserver(this);
 
+	LLViewerParcelMgr::getInstance()->setAgentParcelChangedCallback(
+			boost::bind(&LLPanelPlaces::onAgentParcelChange, this));
+
 	//LLUICtrlFactory::getInstance()->buildPanel(this, "panel_places.xml"); // Called from LLRegisterPanelClass::defaultPanelClassBuilder()
 }
 
@@ -90,7 +108,7 @@ BOOL LLPanelPlaces::postBuild()
 		}
 
 		// *TODO: Assign the action to an appropriate event.
-		childSetAction("overflow_btn", boost::bind(&LLPanelPlaceInfo::toggleMediaPanel, mPlaceInfo), this);
+		childSetAction("overflow_btn", boost::bind(&LLPanelPlaces::toggleMediaPanel, this), this);
 	}
 
 	//childSetAction("share_btn", boost::bind(&LLPanelPlaces::onShareButtonClicked, this), this);
@@ -100,19 +118,14 @@ BOOL LLPanelPlaces::postBuild()
 	return TRUE;
 }
 
-void LLPanelPlaces::draw()
-{
-	LLPanel::draw();
-}
-
 void LLPanelPlaces::onOpen(const LLSD& key)
 {
 	if(key.size() == 0)
 		return;
 
-	togglePlaceInfoPanel(TRUE);
-
 	mPlaceInfoType = key["type"].asString();
+	
+	togglePlaceInfoPanel(TRUE);
 
 	if (mPlaceInfoType == "agent")
 	{
@@ -127,7 +140,8 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 	}
 	else if (mPlaceInfoType == "landmark")
 	{
-		LLInventoryItem* item = gInventory.getItem(key["id"].asUUID());
+		LLUUID item_uuid = key["id"].asUUID();
+		LLInventoryItem* item = gInventory.getItem(item_uuid);
 		if (!item)
 			return;
 
@@ -138,6 +152,12 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 		if (!landmark)
 			return;
 
+		// Select Landmarks tab and set selection to requested landmark so that
+		// context dependent Verbs buttons update properly.
+		mTabContainer->selectFirstTab(); // Assume that first tab is Landmarks tab.
+		LLLandmarksPanel* landmarks_panel = dynamic_cast<LLLandmarksPanel*>(mTabContainer->getCurrentPanel());
+		landmarks_panel->setSelectedItem(item_uuid);
+
 		LLUUID region_id;
 		landmark->getRegionID(region_id);
 		LLVector3d pos_global;
@@ -145,7 +165,6 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 		mPlaceInfo->displayParcelInfo(landmark->getRegionPos(),
 									  region_id,
 									  pos_global);
-
 	}
 	else if (mPlaceInfoType == "teleport_history")
 	{
@@ -161,7 +180,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 
 		LLVector3 pos_local(region_x, region_y, (F32)pos_global.mdV[VZ]);
 
-		mPlaceInfo->setInfoType(LLPanelPlaceInfo::PLACE);
+		mPlaceInfo->setInfoType(LLPanelPlaceInfo::TELEPORT_HISTORY);
 		mPlaceInfo->displayParcelInfo(pos_local,
 									  hist_items[index].mRegionID,
 									  pos_global);
@@ -186,11 +205,11 @@ void LLPanelPlaces::onSearchEdit(const std::string& search_string)
 void LLPanelPlaces::onTabSelected()
 {
 	mActivePanel = dynamic_cast<LLPanelPlacesTab*>(mTabContainer->getCurrentPanel());
-	if (mActivePanel)
-	{
-		mActivePanel->onSearchEdit(mFilterSubString);
-		mActivePanel->updateVerbs();
-	}
+	if (!mActivePanel)
+		return;
+
+	onSearchEdit(mFilterSubString);	
+	mActivePanel->updateVerbs();
 }
 
 void LLPanelPlaces::onShareButtonClicked()
@@ -242,6 +261,13 @@ void LLPanelPlaces::onBackButtonClicked()
 	togglePlaceInfoPanel(FALSE);
 }
 
+void LLPanelPlaces::toggleMediaPanel()
+{
+	if (!mPlaceInfo)
+			return;
+
+	mPlaceInfo->toggleMediaPanel(!mPlaceInfo->isMediaPanelVisible());
+}
 void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
 {
 	if (!mPlaceInfo)
@@ -250,6 +276,9 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
 	mPlaceInfo->setVisible(visible);
 	mSearchEditor->setVisible(!visible);
 	mTabContainer->setVisible(!visible);
+	
+	// Enable overflow button only for the information about agent's current location.
+	getChild<LLButton>("overflow_btn")->setEnabled(visible && mPlaceInfoType == "agent");
 
 	if (visible)
 	{
@@ -275,7 +304,7 @@ void LLPanelPlaces::changed(U32 mask)
 		mTabContainer->addTabPanel(
 			LLTabContainer::TabPanelParams().
 			panel(landmarks_panel).
-			label("Landmarks").
+			label(getString("landmarks_tab_title")).
 			insert_at(LLTabContainer::END));
 	}
 
@@ -287,7 +316,7 @@ void LLPanelPlaces::changed(U32 mask)
 		mTabContainer->addTabPanel(
 			LLTabContainer::TabPanelParams().
 			panel(teleport_history_panel).
-			label("Teleport History").
+			label(getString("teleport_history_tab_title")).
 			insert_at(LLTabContainer::END));
 	}
 
@@ -299,3 +328,13 @@ void LLPanelPlaces::changed(U32 mask)
 	// so remove the observer
 	gInventory.removeObserver(this);
 }
+
+void LLPanelPlaces::onAgentParcelChange()
+{
+	if (mPlaceInfo->getVisible() && mPlaceInfoType == "agent")
+	{
+		// Using timer to delay obtaining agent's coordinates
+		// not to get the coordinates of previous parcel.
+		new LLParcelUpdateTimer(.5);
+	}
+}
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 89758fc34f4..6fbb7562c91 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -32,6 +32,8 @@
 #ifndef LL_LLPANELPLACES_H
 #define LL_LLPANELPLACES_H
 
+#include "lltimer.h"
+
 #include "llpanel.h"
 
 #include "llinventory.h"
@@ -50,7 +52,6 @@ class LLPanelPlaces : public LLPanel, LLInventoryObserver
 	virtual ~LLPanelPlaces();
 
 	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void draw();
 	/*virtual*/ void changed(U32 mask);
 	/*virtual*/ void onOpen(const LLSD& key);
 
@@ -62,7 +63,9 @@ class LLPanelPlaces : public LLPanel, LLInventoryObserver
 	void onTeleportButtonClicked();
 	void onShowOnMapButtonClicked();
 	void onBackButtonClicked();
+	void toggleMediaPanel();
 	void togglePlaceInfoPanel(BOOL visible);
+	void onAgentParcelChange();
 
 private:
 	LLSearchEditor*			mSearchEditor;
@@ -73,6 +76,17 @@ class LLPanelPlaces : public LLPanel, LLInventoryObserver
 
 	// Place information type currently shown in Information panel
 	std::string				mPlaceInfoType;
+
+	// Helper class to delay the coordinates update 
+	// when agent changes parcel
+	class LLParcelUpdateTimer : public LLEventTimer
+	{
+	public:
+		LLParcelUpdateTimer(F32 period);
+		virtual ~LLParcelUpdateTimer() {};
+
+		virtual BOOL tick();
+	};
 };
 
 #endif //LL_LLPANELPLACES_H
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index f50f5a3db02..d8be1386c33 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -40,7 +40,7 @@
 #include "llfocusmgr.h"
 #include "llrootview.h"
 
-#include "llcollapsiblectrl.h"
+#include "llaccordionctrltab.h"
 
 #include "llfloater.h" //for gFloaterView
 #include "lliconctrl.h"//for Home tab icon
@@ -664,7 +664,7 @@ void LLSideTray::createHomeTab()
 
 		panel->setCommitCallback(boost::bind(&LLSideTray::onTabButtonClick, this, sidebar_tab->getName()));
 
-		LLCollapsibleCtrl::Params panel_params; 
+		LLAccordionCtrlTab::Params panel_params; 
 		panel_params.display_children(true);
 		panel_params.collapsible(false);
 		panel_params.header_visible(false);
@@ -676,7 +676,7 @@ void LLSideTray::createHomeTab()
 		panel_params.padding_bottom(5);
 		panel_params.name(sidebar_tab->getTabTitle());
 
-		LLCollapsibleCtrl* ctrl = LLUICtrlFactory::create<LLCollapsibleCtrl>(panel_params);
+		LLAccordionCtrlTab* ctrl = LLUICtrlFactory::create<LLAccordionCtrlTab>(panel_params);
 
 		
 		ctrl->setPanel(panel);
diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp
index bbd34835ca6..62ed861c86e 100644
--- a/indra/newview/llviewergesture.cpp
+++ b/indra/newview/llviewergesture.cpp
@@ -39,7 +39,6 @@
 #include "llviewerinventory.h"
 #include "sound_ids.h"		// for testing
 
-#include "llchatbar.h"
 #include "llkeyboard.h"		// for key shortcuts for testing
 #include "llinventorymodel.h"
 #include "llvoavatar.h"
@@ -133,11 +132,11 @@ void LLViewerGesture::doTrigger( BOOL send_chat )
 		}
 	}
 
-	if (gBottomTray && send_chat && !mOutputString.empty())
+	if (send_chat && !mOutputString.empty())
 	{
 		// Don't play nodding animation, since that might not blend
 		// with the gesture animation.
-		gBottomTray->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
+		LLBottomTray::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
 	}
 }
 
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index ab5cdeba443..63234c29901 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -36,7 +36,7 @@
 #include "llviewerkeyboard.h"
 #include "llmath.h"
 #include "llagent.h"
-#include "llchatbar.h"
+#include "llbottomtray.h"
 #include "llviewercontrol.h"
 #include "llfocusmgr.h"
 #include "llmorphview.h"
@@ -500,8 +500,7 @@ void stop_moving( EKeystate s )
 void start_chat( EKeystate s )
 {
 	// start chat
-	LLChatBar::startChat(NULL);
-//	gChatBar->startChat(NULL);
+	LLBottomTray::startChat(NULL);
 }
 
 void start_gesture( EKeystate s )
@@ -509,18 +508,16 @@ void start_gesture( EKeystate s )
 	if (KEYSTATE_UP == s &&
 		!(gFocusMgr.getKeyboardFocus() && gFocusMgr.getKeyboardFocus()->acceptsTextInput()))
 	{
-		//TODO* remove DUMMY chatbar
-		LLChatBar::startChat(NULL);
-// 		if (gChatBar->getCurrentChat().empty())
-// 		{
-// 			// No existing chat in chat editor, insert '/'
-// 			gChatBar->startChat("/");
-// 		}
-// 		else
-// 		{
-// 			// Don't overwrite existing text in chat editor
-// 			gChatBar->startChat(NULL);
-// 		}
+ 		if (LLBottomTray::getInstance()->getCurrentChat().empty())
+ 		{
+ 			// No existing chat in chat editor, insert '/'
+ 			LLBottomTray::getInstance()->startChat("/");
+ 		}
+ 		else
+ 		{
+ 			// Don't overwrite existing text in chat editor
+ 			LLBottomTray::getInstance()->startChat(NULL);
+ 		}
 	}
 }
 
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 63854abfeac..e06e180ed5d 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -131,7 +131,7 @@
 #include "llfloaterworldmap.h"
 #include "llfloatermemleak.h"
 #include "llfasttimerview.h"
-#include "llfriendactions.h"
+#include "llavataractions.h"
 #include "llmemoryview.h"
 #include "llgivemoney.h"
 #include "llgroupmgr.h"
@@ -3607,7 +3607,7 @@ bool LLHaveCallingcard::operator()(LLInventoryCategory* cat,
 
 BOOL is_agent_mappable(const LLUUID& agent_id)
 {
-	return (LLFriendActions::isFriend(agent_id) &&
+	return (LLAvatarActions::isFriend(agent_id) &&
 		LLAvatarTracker::instance().getBuddyInfo(agent_id)->isOnline() &&
 		LLAvatarTracker::instance().getBuddyInfo(agent_id)->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION)
 		);
@@ -3620,7 +3620,7 @@ class LLAvatarEnableAddFriend : public view_listener_t
 	bool handleEvent(const LLSD& userdata)
 	{
 		LLVOAvatar* avatar = find_avatar_from_object(LLSelectMgr::getInstance()->getSelection()->getPrimaryObject());
-		bool new_value = avatar && !LLFriendActions::isFriend(avatar->getID());
+		bool new_value = avatar && !LLAvatarActions::isFriend(avatar->getID());
 		return new_value;
 	}
 };
@@ -3644,7 +3644,7 @@ void request_friendship(const LLUUID& dest_id)
 		}
 		if (!fullname.empty())
 		{
-			LLFriendActions::requestFriendshipDialog(dest_id, fullname);
+			LLAvatarActions::requestFriendshipDialog(dest_id, fullname);
 		}
 		else
 		{
@@ -5376,7 +5376,7 @@ class LLAvatarAddFriend : public view_listener_t
 	bool handleEvent(const LLSD& userdata)
 	{
 		LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
-		if(avatar && !LLFriendActions::isFriend(avatar->getID()))
+		if(avatar && !LLAvatarActions::isFriend(avatar->getID()))
 		{
 			request_friendship(avatar->getID());
 		}
@@ -5720,7 +5720,7 @@ class LLShowAgentProfile : public view_listener_t
 		LLVOAvatar* avatar = find_avatar_from_object(agent_id);
 		if (avatar)
 		{
-			LLFriendActions::showProfile(avatar->getID());
+			LLAvatarActions::showProfile(avatar->getID());
 		}
 		return true;
 	}
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 039faa2bf9c..1468b376b03 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -78,7 +78,6 @@
 #include "llagent.h"
 #include "llalertdialog.h"
 #include "llbox.h"
-#include "llchatbar.h"
 #include "llconsole.h"
 #include "llviewercontrol.h"
 #include "llcylinder.h"
@@ -1557,13 +1556,12 @@ void LLViewerWindow::initWorldUI()
 	getRootView()->sendChildToFront(gSnapshotFloaterView);
 
 	// new bottom panel
-	gBottomTray = new LLBottomTray();
-	LLRect rc = gBottomTray->getRect();
+	LLRect rc = LLBottomTray::getInstance()->getRect();
 	rc.mLeft = 0;
 	rc.mRight = mRootView->getRect().getWidth();
-	mRootView->addChild(gBottomTray);
-	gBottomTray->reshape(rc.getWidth(),rc.getHeight(),FALSE);
-	gBottomTray->setRect(rc);
+	mRootView->addChild(LLBottomTray::getInstance());
+	LLBottomTray::getInstance()->reshape(rc.getWidth(),rc.getHeight(),FALSE);
+	LLBottomTray::getInstance()->setRect(rc);
 
 	// View for hover information
 	LLHoverView::Params hvp;
@@ -1595,9 +1593,9 @@ void LLViewerWindow::initWorldUI()
 	LLRect floater_view_rect = gFloaterView->getRect();
 	LLRect notify_view_rect = gNotifyBoxView->getRect();
 	floater_view_rect.mTop -= NAVIGATION_BAR_HEIGHT;
-	floater_view_rect.mBottom += gBottomTray->getRect().getHeight();
+	floater_view_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight();
 	notify_view_rect.mTop -= NAVIGATION_BAR_HEIGHT;
-	notify_view_rect.mBottom += gBottomTray->getRect().getHeight();
+	notify_view_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight();
 	gFloaterView->setRect(floater_view_rect);
 	gNotifyBoxView->setRect(notify_view_rect);
 
@@ -1854,10 +1852,10 @@ void LLViewerWindow::reshape(S32 width, S32 height)
 // Hide normal UI when a logon fails
 void LLViewerWindow::setNormalControlsVisible( BOOL visible )
 {
-	if(gBottomTray)
+	if(LLBottomTray::instanceExists())
 	{
-		gBottomTray->setVisible(visible);
-		gBottomTray->setEnabled(visible);
+		LLBottomTray::getInstance()->setVisible(visible);
+		LLBottomTray::getInstance()->setEnabled(visible);
 	}
 
 	if ( gMenuBarView )
@@ -2165,11 +2163,11 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	LLUICtrl* keyboard_focus = gFocusMgr.getKeyboardFocus();
 	if( keyboard_focus )
 	{
-		LLLineEditor* chat_bar = gBottomTray ? gBottomTray->getChatBox() : NULL;
+		LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getChatBox() : NULL;
 		// arrow keys move avatar while chatting hack
-		if (chat_bar && chat_bar->hasFocus())
+		if (chat_editor && chat_editor->hasFocus())
 		{
-			if (chat_bar->getText().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar"))
+			if (chat_editor->getText().empty() || gSavedSettings.getBOOL("ArrowKeysMoveAvatar"))
 			{
 				switch(key)
 				{
@@ -2399,10 +2397,14 @@ void LLViewerWindow::updateUI()
 
 	updateWorldViewRect();
 
-	if(gBottomTray && LLSideTray::instanceCreated())
+	if(LLBottomTray::instanceExists() && LLSideTray::instanceCreated())
 	{
-		S32 delta = llround((F32)LLSideTray::getInstance()->getTrayWidth() * mDisplayScale.mV[VX]);
-		gBottomTray->updateRightPosition(mWindowRect.mRight - delta);
+		S32 delta = 0;
+		if(LLSideTray::getInstance()->getVisible())
+		{
+			delta = llround((F32)LLSideTray::getInstance()->getTrayWidth() * mDisplayScale.mV[VX]);
+		}
+		LLBottomTray::getInstance()->updateRightPosition(mWindowRect.mRight - delta);
 	}
 
 	LLView::sMouseHandlerMessage.clear();
@@ -2939,19 +2941,6 @@ void LLViewerWindow::updateKeyboardFocus()
 
 	if(LLSideTray::instanceCreated())//just getInstance will create sidetray. we don't want this
 		LLSideTray::getInstance()->highlightFocused();
-
-	//NOTE: this behavior is no longer desirable with a permanently visible chat batr
-	// which would *always* steal focus, disallowing navigation of the world via WASD controls --RN
-	
-	//if (gSavedSettings.getBOOL("ChatBarStealsFocus") 
-	//	&& gChatBar 
-	//	&& gFocusMgr.getKeyboardFocus() == NULL 
-	//	&& gChatBar->isInVisibleChain())
-	//{
-	//	gChatBar->startChat(NULL);
-	//}
-
-
 }
 
 void LLViewerWindow::updateWorldViewRect(bool use_full_window)
@@ -4912,8 +4901,8 @@ S32 LLViewerWindow::getChatConsoleBottomPad()
 {
 	S32 offset = 0;
 
-	if(gBottomTray)
-		offset += gBottomTray->getRect().getHeight();
+	if(LLBottomTray::instanceExists())
+		offset += LLBottomTray::getInstance()->getRect().getHeight();
 
 	return offset;
 }
diff --git a/indra/newview/skins/default/xui/en/accordion_drag.xml b/indra/newview/skins/default/xui/en/accordion_drag.xml
new file mode 100644
index 00000000000..94839a75939
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/accordion_drag.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel  border_thickness="2" visible ="true" name="splitter_drag"
+  width="100"
+  height="5"
+  left="50"
+  top="50"
+  follows="left|bottom|right" background_visible="true" label="splitter_drag" title="">
+</panel>
diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
new file mode 100644
index 00000000000..542e319792b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_imchiclet_group.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="101"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="IMChiclet Group Menu"
+ top="724"
+ visible="false"
+ width="128">
+    <menu_item_call
+     label="Chat..."
+     layout="topleft"
+     name="Chat">
+        <menu_item_call.on_click
+         function="IMChicletMenu.Action"
+         parameter="group chat" />
+    </menu_item_call>
+    <menu_item_call
+     label="Info..."
+     layout="topleft"
+     name="Show Profile">
+        <menu_item_call.on_click
+         function="IMChicletMenu.Action"
+         parameter="info" />
+    </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
new file mode 100644
index 00000000000..bad6e1e212c
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_imchiclet_p2p.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<menu
+ height="101"
+ layout="topleft"
+ left="100"
+ mouse_opaque="false"
+ name="IMChiclet P2P Menu"
+ top="724"
+ visible="false"
+ width="128">
+    <menu_item_call
+     label="Show Profile..."
+     layout="topleft"
+     name="Show Profile">
+        <menu_item_call.on_click
+         function="IMChicletMenu.Action"
+         parameter="profile" />
+    </menu_item_call>
+    <menu_item_call
+     label="Send IM..."
+     layout="topleft"
+     name="Send IM">
+        <menu_item_call.on_click
+         function="IMChicletMenu.Action"
+         parameter="im" />
+    </menu_item_call>
+    <menu_item_call
+     label="Add Friend..."
+     layout="topleft"
+     name="Add Friend">
+        <menu_item_call.on_click
+         function="IMChicletMenu.Action"
+         parameter="add" />
+    </menu_item_call>
+    <menu_item_call
+     label="Remove Friend..."
+     layout="topleft"
+     name="Remove Friend">
+        <menu_item_call.on_click
+         function="IMChicletMenu.Action"
+         parameter="remove" />
+    </menu_item_call>
+</menu>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index ef6f2237ad1..d890edcfed5 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -3068,9 +3068,10 @@ Are you sure you want to teleport?
    type="alertmodal">
 Teleport to [PICK]?
     <usetemplate
-     name="okcancelbuttons"
+     ignoretext="When teleporting from double-clicking a pick"
+     name="okcancelignore"
      notext="Cancel"
-     yestext="OK"/>
+     yestext="Teleport"/>
   </notification>
   
   <notification
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 6c4f47a34f0..7006203dcde 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -11,10 +11,6 @@
  top="28"
  border_visible="true"
  width="1000">
-    <panel.string
-     name="gesture_label">
-        Gestures
-    </panel.string>
     <layout_stack
      border_size="0"
      follows="left|right|bottom|top"
@@ -53,7 +49,7 @@
              layout="topleft"
              left="0"
              name="chat_box"
-				     right="-39"
+             right="-39"
              top="3"
              width="250" />
             <button follows="right" width="36" top="3" left="214" resize="false"
@@ -131,7 +127,7 @@
          width="90"
          top="0"
          min_width="90">
-            <combo_box
+            <gesture_combo_box
              bottom="22"
              follows="right"
              height="20"
@@ -192,8 +188,8 @@
          min_height="28"
          top="0"
          name="chiclet_list_panel"
-         width="250"
-         min_width="100">
+         width="150"
+         min_width="70">
             <chiclet_panel
              follows="left|right"
              height="25"
@@ -201,7 +197,9 @@
              left="0"
              name="chiclet_list"
              top="1"
-             width="250" />
+             chiclet_padding="3"
+             scrolling_offset="40"
+             width="150" />
         </layout_panel>
         <icon
          auto_resize="false"
@@ -227,13 +225,19 @@
             <chiclet_notification
              follows="right"
              height="25"
-             image_selected="im_notifications.tga"
-             image_unselected="im_notifications.tga"
              layout="topleft"
              left="0"
              name="im_well"
              top="1"
-             width="40" >
+             width="40">
+              <button
+               image_selected="im_notifications.tga"
+               image_unselected="im_notifications.tga"/>
+              <unread_notifications
+               width="20"
+               height="20"
+               left="18"
+               top="23"/>
 			  <chiclet_notification.commit_callback
 				 function="Notification.Show"
 				 parameter="ClickUnimplemented" />
@@ -254,7 +258,7 @@
          auto_resize="false"
          bevel_style="in"
          follows="left|right"
-         height="30"
+         height="28"
          layout="topleft"
          left="270"
          name="well_separator"
@@ -284,13 +288,19 @@
             <chiclet_notification
              follows="right"
              height="25"
-             image_selected="bottom_tray_sys_notifications.tga"
-             image_unselected="bottom_tray_sys_notifications.tga"
              layout="topleft"
              left="0"
              name="sys_well"
              top="1"
-             width="48" >
+             width="48">
+              <button
+               image_selected="bottom_tray_sys_notifications.tga"
+               image_unselected="bottom_tray_sys_notifications.tga"/>
+              <unread_notifications
+               width="20"
+               height="20"
+               left="22"
+               top="23"/>
 			  <chiclet_notification.commit_callback
 				 function="Notification.Show"
 				 parameter="ClickUnimplemented" />
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index a017e7398eb..9cc3a006965 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -77,6 +77,7 @@
          height="20"
          layout="topleft"
          left="10"
+         max_length="63"
          name="pick_name"
          right="-10"
          text_color="black"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
index 6a819d0ef4d..686dc931d39 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_list_item.xml
@@ -32,7 +32,8 @@
      name="picture_name"
      text_color="black"
      top="5"
-     width="170" />
+     use_ellipses="true"
+     width="170"/>
     <text
      follows="right"
      font="SansSerif"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index 2aa566543f3..366c3ecf6cd 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -12,6 +12,14 @@
  name="places panel"
  top="400"
  width="355">
+    <panel.string
+     name="landmarks_tab_title">
+        Landmarks
+    </panel.string>
+    <panel.string
+     name="teleport_history_tab_title">
+        Teleport History
+    </panel.string>
     <search_editor
      follows="left|top|right"
      height="16"
@@ -73,7 +81,7 @@
      top_delta="0"
      width="60" />
     <button
-     enabled="true"
+     enabled="false"
      follows="bottom|right"
      font="SansSerifSmallBold"
      height="25"
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray.xml b/indra/newview/skins/default/xui/en/panel_side_tray.xml
index feba6a7d028..01052f4bbe5 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray.xml
@@ -17,7 +17,7 @@
     background_visible="true" 
     bg_opaque_color="0.5 0.5 0.5 1.0"
   >
-    <collapsible_ctrl 
+    <accordionctrl_tab 
       name="people_accordion" 
       title="People" 
       collapsable="true" 
@@ -35,7 +35,7 @@
         label="People" 
         border="true" 
       />
-    </collapsible_ctrl>
+    </accordionctrl_tab>
   </sidetray_tab>
   <!-- *TODO Vadim: isn't the sidetray_tab "label" attribute redundant since we have "tab_title" ? -->
   <sidetray_tab 
@@ -48,7 +48,7 @@
     background_visible="true" 
     bg_opaque_color="0.5 0.5 0.5 1.0"
   >
-    <collapsible_ctrl 
+    <accordionctrl_tab 
       name="places_accordian" 
       title="Places" 
       collapsable="true" 
@@ -63,7 +63,7 @@
         label="Places" 
         border="true"
       />
-    </collapsible_ctrl>
+    </accordionctrl_tab>
   </sidetray_tab>
   
   <sidetray_tab 
@@ -75,7 +75,7 @@
     background_visible="true" 
     bg_opaque_color="0.5 0.5 0.5 1.0"
   >
-    <collapsible_ctrl 
+    <accordionctrl_tab 
       name="me_accordion" 
       title="Me" 
       collapsable="false" 
@@ -90,7 +90,7 @@
         label="Me" 
         border="true"
       />
-    </collapsible_ctrl>
+    </accordionctrl_tab>
   </sidetray_tab>
   
   <!--
@@ -103,7 +103,7 @@
     tab_title="Groups"
     description="Manage Groups."
   >
-    <collapsible_ctrl 
+    <accordionctrl_tab 
       name="group_accordion" 
       title="Group General"
       expanded="true"
@@ -119,12 +119,12 @@
         label="Group" 
         border="true"
       />
-    </collapsible_ctrl>
-     <collapsible_ctrl 
+    </accordionctrl_tab>
+     <accordionctrl_tab 
       name="groupland_accordion" 
       title="Group Land and Money"
       expanded="false"
-      collapsable="true" 
+      collapsible="true" 
       min_width="200" 
       min_height="200" 
       header_visible="true"
@@ -136,12 +136,12 @@
         label="Group" 
         border="true"
       />
-    </collapsible_ctrl>
-     <collapsible_ctrl 
+    </accordionctrl_tab>
+     <accordionctrl_tab 
       name="groupnotices_accordion" 
       title="Group Notices"
       expanded="false"
-      collapsable="true" 
+      collapsible="true" 
       min_width="200" 
       min_height="200" 
       header_visible="true"
@@ -153,12 +153,12 @@
         label="Group" 
         border="true"
       />
-    </collapsible_ctrl>
-     <collapsible_ctrl 
+    </accordionctrl_tab>
+     <accordionctrl_tab 
       name="grouproles_accordion" 
       title="Group Roles"
       expanded="false"
-      collapsable="true" 
+      collapsible="true" 
       min_width="200" 
       min_height="200" 
       header_visible="true"
@@ -170,7 +170,7 @@
         label="Group" 
         border="true"
       />
-    </collapsible_ctrl>
+    </accordionctrl_tab>
   </sidetray_tab>  
   
 
@@ -184,7 +184,7 @@
     tab_title="Previews"
     description="Previews."
   >
-    <collapsible_ctrl 
+    <accordionctrl_tab 
       name="floater_preview_animation" 
       title="Preview Animation" 
       collapsable="true"
@@ -202,8 +202,8 @@
         label="Preview_Animation" 
         border="true" 
       />
-    </collapsible_ctrl>
-    <collapsible_ctrl 
+    </accordionctrl_tab>
+    <accordionctrl_tab 
       name="floater_preview_gesture" 
       title="Preview Gesture" 
       collapsable="true"
@@ -221,8 +221,8 @@
         label="Preview_Gesture" 
         border="true" 
       />
-    </collapsible_ctrl>
-    <collapsible_ctrl 
+    </accordionctrl_tab>
+    <accordionctrl_tab 
       name="floater_preview_existing_landmark" 
       title="Preview Existing Landmark" 
       collapsable="true"
@@ -240,8 +240,8 @@
         label="Preview_Existing_Landmark" 
         border="true" 
       />
-    </collapsible_ctrl>
-    <collapsible_ctrl 
+    </accordionctrl_tab>
+    <accordionctrl_tab 
       name="floater_preview_sound" 
       title="Preview Sound" 
       collapsable="true"
@@ -259,8 +259,8 @@
         label="Preview_Sound" 
         border="true" 
       />
-    </collapsible_ctrl>
-    <collapsible_ctrl 
+    </accordionctrl_tab>
+    <accordionctrl_tab 
       name="floater_preview_url" 
       title="Preview URL" 
       collapsable="true"
@@ -278,8 +278,8 @@
         label="Preview_URL" 
         border="true" 
       />
-    </collapsible_ctrl>
-    <collapsible_ctrl 
+    </accordionctrl_tab>
+    <accordionctrl_tab 
       name="floater_URL_entry" 
       title="URL Entry" 
       collapsable="true"
@@ -297,7 +297,7 @@
         label="URL_entry" 
         border="true" 
       />
-    </collapsible_ctrl>
+    </accordionctrl_tab>
   </sidetray_tab>
 
   <sidetray_tab 	
@@ -310,7 +310,7 @@
     tab_title="Region"
     description="Region."
   >
-    <collapsible_ctrl 
+    <accordionctrl_tab 
       name="panel_region_covenant" 
       title="Region Covenant" 
       collapsable="true" 
@@ -328,8 +328,8 @@
         label="Panel_Region_Covenant" 
         border="true" 
       />
-    </collapsible_ctrl>
-    <collapsible_ctrl 
+    </accordionctrl_tab>
+    <accordionctrl_tab 
       name="panel_region_debug" 
       title="Region Debug" 
       collapsable="true" 
@@ -347,8 +347,8 @@
         label="Panel_Region_Debug" 
         border="true" 
       />
-    </collapsible_ctrl>
-  <collapsible_ctrl 
+    </accordionctrl_tab>
+  <accordionctrl_tab 
       name="panel_region_estate" 
       title="Region Estate" 
       collapsable="true" 
@@ -366,8 +366,8 @@
         label="Panel_Region_Estate" 
         border="true" 
       />
-    </collapsible_ctrl>
-  <collapsible_ctrl 
+    </accordionctrl_tab>
+  <accordionctrl_tab 
       name="panel_region_general" 
       title="Region General" 
       collapsable="true" 
@@ -385,8 +385,8 @@
         label="Panel_Region_General" 
         border="true" 
       />
-    </collapsible_ctrl>
-  <collapsible_ctrl 
+    </accordionctrl_tab>
+  <accordionctrl_tab 
       name="panel_region_terrain" 
       title="Region Terrain" 
       collapsable="true" 
@@ -404,8 +404,8 @@
         label="Panel_Region_Terrain" 
         border="true" 
       />
-    </collapsible_ctrl>
-  <collapsible_ctrl 
+    </accordionctrl_tab>
+  <accordionctrl_tab 
       name="panel_region_texture" 
       title="Region Texture" 
       collapsable="true" 
@@ -423,8 +423,8 @@
         label="Panel_Region_Texture" 
         border="true" 
       />
-    </collapsible_ctrl>
-  <collapsible_ctrl 
+    </accordionctrl_tab>
+  <accordionctrl_tab 
       name="floater_region_info" 
       title="Region Info" 
       collapsable="true" 
@@ -442,7 +442,7 @@
         label="Floater_Region_Info" 
         border="true" 
       />
-    </collapsible_ctrl>
+    </accordionctrl_tab>
   </sidetray_tab>
  
   <sidetray_tab 	
@@ -455,7 +455,7 @@
     tab_title="Build"
     description="Build"
   >
-    <collapsible_ctrl 
+    <accordionctrl_tab 
       name="floater_tools" 
       title="Tools" 
       collapsable="true" 
@@ -473,8 +473,8 @@
         label="Tools" 
         border="true" 
       />
-    </collapsible_ctrl>
-    <collapsible_ctrl 
+    </accordionctrl_tab>
+    <accordionctrl_tab 
       name="floater_bulk_perms" 
       title="Bulk Perms" 
       collapsable="true" 
@@ -492,8 +492,8 @@
         label="Tools" 
         border="true" 
       />
-    </collapsible_ctrl>
-    <collapsible_ctrl 
+    </accordionctrl_tab>
+    <accordionctrl_tab 
       name="floater_build_options" 
       title="Build Options" 
       collapsable="true" 
@@ -511,7 +511,7 @@
         label="Tools" 
         border="true" 
       />
-    </collapsible_ctrl>
+    </accordionctrl_tab>
     
   </sidetray_tab>
 
@@ -525,7 +525,7 @@
     tab_title="Other Tools"
     description="Other Tools"
   >
-    <collapsible_ctrl 
+    <accordionctrl_tab 
       name="floater_gesture" 
       title="Gestures" 
       collapsable="true" 
@@ -543,9 +543,9 @@
         label="Gesture" 
         border="true" 
       />
-    </collapsible_ctrl>
+    </accordionctrl_tab>
     
-    <collapsible_ctrl 
+    <accordionctrl_tab 
       name="floater_buy_contents" 
       title="Buy Contents" 
       collapsable="true" 
@@ -563,8 +563,8 @@
         label="buy_contents" 
         border="true" 
       />
-    </collapsible_ctrl>
-    <collapsible_ctrl 
+    </accordionctrl_tab>
+    <accordionctrl_tab 
       name="floater_buy_object" 
       title="Buy Object" 
       collapsable="true" 
@@ -583,7 +583,7 @@
         border="true" 
       />
     </collapsible_ctrl>
-    <collapsible_ctrl 
+    <accordionctrl_tab 
       name="floater_inventory_view_finder" 
       title="Inventory View Finder" 
       collapsable="true" 
@@ -601,8 +601,8 @@
         label="view_finder" 
         border="true" 
       />
-    </collapsible_ctrl>
-    <collapsible_ctrl 
+    </accordionctrl_tab>
+    <accordionctrl_tab 
       name="floater_mute" 
       title="Mute" 
       collapsable="true" 
@@ -620,8 +620,8 @@
         label="mute" 
         border="true" 
       />
-    </collapsible_ctrl>
-     <collapsible_ctrl 
+    </accordionctrl_tab>
+     <accordionctrl_tab 
       name="floater_sell_land" 
       title="Sell Land" 
       collapsable="true" 
@@ -639,8 +639,8 @@
         label="sell_land" 
         border="true" 
       />
-    </collapsible_ctrl>
-     <collapsible_ctrl 
+    </accordionctrl_tab>
+     <accordionctrl_tab 
       name="floater_telehub" 
       title="Telehub" 
       collapsable="true" 
@@ -658,7 +658,7 @@
         label="telehub" 
         border="true" 
       />
-    </collapsible_ctrl>
+    </accordionctrl_tab>
     
   </sidetray_tab>
  --> 
diff --git a/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml
new file mode 100644
index 00000000000..45b1e1eb9f6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/gesture_combo_box.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<combo_box font="SansSerifSmall"
+           list_position="below"
+           max_chars="20"
+           follows="right|top">
+  <combo_box.combo_button name="Combobox Button"
+                          label=""
+                          hover_glow_amount="0.15"
+                          font="SansSerifSmall"
+                          scale_image="true"
+                          image_unselected="ComboButton_Off"
+                          image_selected="ComboButton_Selected"
+                          image_disabled="ComboButton_Disabled"
+                          image_disabled_selected="ComboButton_Disabled_Selected" />
+  <combo_box.drop_down_button name="Drop Down Button"
+                              label=""
+                              hover_glow_amount="0.15"
+                              font="SansSerifSmall"
+                              scale_image="true"
+                              pad_right="24"
+                              image_unselected="DropDown_Off"
+                              image_selected="DropDown_Selected"
+                              image_disabled="DropDown_Disabled"
+                              image_disabled_selected="DropDown_Disabled_Selected" />
+  <combo_box.combo_list bg_writeable_color="white" />
+  <combo_box.combo_editor name="Combo Text Entry"
+                          select_on_focus="true"
+                          font="SansSerifSmall" />
+</combo_box>
-- 
GitLab