diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index b087205a5cc9802e1679d28b9fc118b0a72911a8..56359053271613b7b2fcfcc8a40ed8e8047278e2 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1635,6 +1635,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
 		// give focus to new window to keep continuity for the user
 		self->setFocus(TRUE);
 		self->setTornOff(true);
+
 	}
 	else  //Attach to parent.
 	{
@@ -1649,6 +1650,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
 		self->setTornOff(false);
 	}
 	self->updateTitleButtons();
+	self->setOpenPositioning(LLFloaterEnums::OPEN_POSITIONING_NONE);
 }
 
 // static
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index a7cc9ae961782ef39f3f1e4c1439d44fc9adc88a..cd02310bf86404cc75a7e0ed6fe3f79714281766 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -329,6 +329,8 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 	virtual void    setDocked(bool docked, bool pop_on_undock = true);
 
 	virtual void    setTornOff(bool torn_off) { mTornOff = torn_off; }
+	bool getTornOff() {return mTornOff;}
+	void setOpenPositioning(LLFloaterEnums::EOpenPositioning pos) {mOpenPositioning = pos;}
 
 	// Return a closeable floater, if any, given the current focus.
 	static LLFloater* getClosableFloaterFromFocus(); 
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 421166dcd4dcf7a983118827e1c601be629a7b87..166cd99d03036a8f3eb89a67c140df48a3e139db 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -349,7 +349,7 @@ void LLView::removeChild(LLView* child)
 	}
 	else
 	{
-		llwarns << child->getName() << "is not a child of " << getName() << llendl;
+		llwarns << "\"" << child->getName() << "\" is not a child of " << getName() << llendl;
 	}
 	updateBoundingRect();
 }
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index b780a27ce27613e5bfda6583cdc4d1bfa84183bd..86d30c239f2475fdd92e7352d0d501834cd15be2 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -277,6 +277,7 @@ set(viewer_SOURCE_FILES
     llhudrender.cpp
     llhudtext.cpp
     llhudview.cpp
+    llimconversation.cpp
     llimfloater.cpp
     llimfloatercontainer.cpp
     llimhandler.cpp
@@ -834,6 +835,7 @@ set(viewer_HEADER_FILES
     llhudrender.h
     llhudtext.h
     llhudview.h
+    llimconversation.h
     llimfloater.h
     llimfloatercontainer.h
     llimview.h
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 3ed575086c0ff6218064d554655907fffd3a9f80..18ab9dc264d46c91ed65d8611bb2b5b70007f589 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -423,13 +423,9 @@ void LLFloaterPreference::saveAvatarProperties( void )
 
 BOOL LLFloaterPreference::postBuild()
 {
-	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate));
+//	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
 
-	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate));
-
-	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate));
-
-	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate));
+	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMConversation::processChatHistoryStyleUpdate));
 
 	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
 
diff --git a/indra/newview/llimconversation.cpp b/indra/newview/llimconversation.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7220ab6a82dbe231efe9ab08512fd98411530b93
--- /dev/null
+++ b/indra/newview/llimconversation.cpp
@@ -0,0 +1,280 @@
+/**
+ * @file llimconversation.cpp
+ * @brief LLIMConversation class implements the common behavior of LNearbyChatBar
+ * @brief and LLIMFloater for hosting both in LLIMContainer
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llpanelimcontrolpanel.h"
+
+#include "lldraghandle.h"
+#include "llfloaterreg.h"
+#include "llimconversation.h"
+#include "llimfloater.h"
+#include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
+#include "lllayoutstack.h"
+#include "llnearbychat.h"
+#include "llnearbychatbar.h"
+
+LLIMConversation::LLIMConversation(const LLUUID& session_id)
+  : LLTransientDockableFloater(NULL, true, session_id)
+  ,  mControlPanel(NULL)
+  ,  mIsP2PChat(false)
+  ,  mExpandCollapseBtn(NULL)
+  ,  mTearOffBtn(NULL)
+  ,  mCloseBtn(NULL)
+  ,  mSessionID(session_id)
+{
+	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
+			boost::bind(&LLIMConversation::onIMSessionMenuItemClicked,  this, _2));
+//	mCommitCallbackRegistrar.add("IMSession.ExpCollapseBtn.Click",
+//			boost::bind(&LLIMConversation::onSlide,  this));
+//	mCommitCallbackRegistrar.add("IMSession.CloseBtn.Click",
+//			boost::bind(&LLFloater::onClickClose, this));
+	mCommitCallbackRegistrar.add("IMSession.TearOffBtn.Click",
+			boost::bind(&LLIMConversation::onTearOffClicked, this));
+	mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
+			boost::bind(&LLIMConversation::onIMCompactExpandedMenuItemCheck, this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem",
+			boost::bind(&LLIMConversation::onIMShowModesMenuItemCheck,   this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
+			boost::bind(&LLIMConversation::onIMShowModesMenuItemEnable,  this, _2));
+}
+
+BOOL LLIMConversation::postBuild()
+{
+	mCloseBtn = getChild<LLButton>("close_btn");
+	mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
+
+	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
+	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMConversation::onSlide, this));
+
+	if (mControlPanel)
+	{
+	    mControlPanel->setSessionId(mSessionID);
+	    mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel"));
+
+		mExpandCollapseBtn->setImageOverlay(
+				getString(mControlPanel->getParent()->getVisible() ? "collapse_icon" : "expand_icon"));
+	}
+	else
+	{
+		mExpandCollapseBtn->setEnabled(false);
+		getChild<LLLayoutPanel>("im_control_panel_holder")->setVisible(false);
+	}
+
+	mTearOffBtn = getChild<LLButton>("tear_off_btn");
+	mTearOffBtn->setCommitCallback(boost::bind(&LLIMConversation::onTearOffClicked, this));
+
+	if (!getTornOff())
+	{
+		setOpenPositioning(LLFloaterEnums::OPEN_POSITIONING_NONE);
+	}
+
+	if (isChatMultiTab())
+	{
+		return LLFloater::postBuild();
+	}
+	else
+	{
+		return LLDockableFloater::postBuild();
+	}
+
+}
+
+void LLIMConversation::onIMSessionMenuItemClicked(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+
+	if (item == "compact_view" || item == "expanded_view")
+	{
+		gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view");
+	}
+	else
+	{
+		bool prev_value = gSavedSettings.getBOOL(item);
+		gSavedSettings.setBOOL(item, !prev_value);
+	}
+
+	LLIMConversation::processChatHistoryStyleUpdate();
+}
+
+
+bool LLIMConversation::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+	bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory");
+
+	return is_plain_text_mode? item == "compact_view" : item == "expanded_view";
+}
+
+
+bool LLIMConversation::onIMShowModesMenuItemCheck(const LLSD& userdata)
+{
+	return gSavedSettings.getBOOL(userdata.asString());
+}
+
+// enable/disable states for the "show time" and "show names" items of the show-modes menu
+bool LLIMConversation::onIMShowModesMenuItemEnable(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+	bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory");
+	bool is_not_names = (item != "IMShowNamesForP2PConv");
+	return (plain_text && (is_not_names || mIsP2PChat));
+}
+
+void LLIMConversation::updateHeaderAndToolbar()
+{
+	bool is_hosted = getHost() != NULL;
+
+	if (is_hosted)
+	{
+		for (S32 i = 0; i < BUTTON_COUNT; i++)
+		{
+			if (mButtons[i])
+			{
+				// Hide the standard header buttons in a docked IM floater.
+				mButtons[i]->setVisible(false);
+			}
+		}
+	}
+
+	bool is_control_panel_visible = false;
+	if (mControlPanel)
+	{
+		// Control panel should be visible only in torn off floaters.
+		is_control_panel_visible = !is_hosted && gSavedSettings.getBOOL("IMShowControlPanel");
+		mControlPanel->getParent()->setVisible(is_control_panel_visible);
+	}
+
+	// Display collapse image (<<) if the floater is hosted
+	// or if it is torn off but has an open control panel.
+	bool is_expanded = is_hosted || is_control_panel_visible;
+	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
+
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
+	if (session)
+	{
+		// The button (>>) should be disabled for torn off P2P conversations.
+		mExpandCollapseBtn->setEnabled(is_hosted || !session->isP2PSessionType());
+	}
+	else
+	{
+		if (!mIsNearbyChat)
+		{
+			llwarns << "IM session not found." << llendl;
+		}
+	}
+
+	if (mDragHandle)
+	{
+		// toggle floater's drag handle and title visibility
+		mDragHandle->setVisible(!is_hosted);
+	}
+
+	mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon"));
+
+	mCloseBtn->setVisible(is_hosted);
+
+	enableDisableCallBtn();
+}
+
+// static
+void LLIMConversation::processChatHistoryStyleUpdate()
+{
+	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
+	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+			iter != inst_list.end(); ++iter)
+	{
+		LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
+		if (floater)
+		{
+			floater->reloadMessages();
+		}
+	}
+
+	LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance();
+	if (nearby_chat_bar)
+	{
+		nearby_chat_bar->reloadMessages();
+	}
+}
+
+void LLIMConversation::updateCallBtnState(bool callIsActive)
+{
+	getChild<LLButton>("voice_call_btn")->setImageOverlay(
+			callIsActive? getString("call_btn_stop") : getString("call_btn_start"));
+    enableDisableCallBtn();
+
+}
+
+void LLIMConversation::onSlide(LLIMConversation* self)
+{
+	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(self->getHost());
+	if (host_floater)
+	{
+		// Hide the messages pane if a floater is hosted in the Conversations
+		host_floater->collapseMessagesPane(true);
+	}
+	else ///< floater is torn off
+	{
+		if (self->mControlPanel)
+		{
+			bool expand = !self->mControlPanel->getParent()->getVisible();
+
+			// Expand/collapse the IM control panel
+			self->mControlPanel->getParent()->setVisible(expand);
+
+			gSavedSettings.setBOOL("IMShowControlPanel", expand);
+
+			self->mExpandCollapseBtn->setImageOverlay(self->getString(expand ? "collapse_icon" : "expand_icon"));
+		}
+	}
+}
+
+/*virtual*/
+void LLIMConversation::onOpen(const LLSD& key)
+{
+	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
+	if (host_floater)
+	{
+		// Show the messages pane when opening a floater hosted in the Conversations
+		host_floater->collapseMessagesPane(false);
+	}
+
+	updateHeaderAndToolbar();
+}
+
+void LLIMConversation::onTearOffClicked()
+{
+	onClickTearOff(this);
+	updateHeaderAndToolbar();
+}
+
+// static
+bool LLIMConversation::isChatMultiTab()
+{
+	// Restart is required in order to change chat window type.
+	static bool is_single_window = gSavedSettings.getS32("ChatWindow") == 1;
+	return is_single_window;
+}
diff --git a/indra/newview/llimconversation.h b/indra/newview/llimconversation.h
new file mode 100644
index 0000000000000000000000000000000000000000..501977e061016085740cc09b725c69cfe64386bb
--- /dev/null
+++ b/indra/newview/llimconversation.h
@@ -0,0 +1,97 @@
+/**
+ * @file llimconversation.h
+ * @brief LLIMConversation class implements the common behavior of LNearbyChatBar
+ * @brief and LLIMFloater for hosting both in LLIMContainer
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_IMCONVERSATION_H
+#define LL_IMCONVERSATION_H
+
+#include "lltransientdockablefloater.h"
+#include "llviewercontrol.h"
+
+class LLPanelChatControlPanel;
+
+class LLIMConversation
+	: public LLTransientDockableFloater
+{
+
+public:
+	LOG_CLASS(LLIMConversation);
+
+	LLIMConversation(const LLUUID& session_id);
+
+	// reload all message with new settings of visual modes
+	static void processChatHistoryStyleUpdate();
+
+	/**
+	 * Returns true if chat is displayed in multi tabbed floater
+	 *         false if chat is displayed in multiple windows
+	 */
+	static bool isChatMultiTab();
+
+	// LLFloater overrides
+	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ BOOL postBuild();
+
+protected:
+
+	// callback for click on any items of the visual states menu
+	void onIMSessionMenuItemClicked(const LLSD& userdata);
+
+	// callback for check/uncheck of the expanded/collapse mode's switcher
+	bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata);
+
+	//
+	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
+	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
+	static void onSlide(LLIMConversation *self);
+	void onTearOffClicked();
+
+	// refresh a visual state of the Call button
+	void updateCallBtnState(bool callIsActive);
+
+	// set the enable/disable state for the Call button
+	virtual void enableDisableCallBtn() = 0;
+
+//	/* virtual */ void updateTitleButtons();
+
+
+	LLPanelChatControlPanel* mControlPanel;
+	bool mIsNearbyChat;
+	bool mIsP2PChat;
+
+	LLUUID mSessionID;
+
+	LLButton* mExpandCollapseBtn;
+	LLButton* mTearOffBtn;
+	LLButton* mCloseBtn;
+
+private:
+	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
+	void updateHeaderAndToolbar();
+};
+
+
+#endif // LL_IMCONVERSATION_H
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index cd795fcfc7dde296faae532d0e50179ca5af4364..5339bcb936a7a67c6e51e5ab23054a58c66977ef 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -41,10 +41,9 @@
 #include "llfloaterreg.h"
 #include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
 #include "llinventoryfunctions.h"
-#include "lllayoutstack.h"
+//#include "lllayoutstack.h"
 #include "lllineeditor.h"
 #include "lllogchat.h"
-#include "llnearbychat.h"
 #include "llpanelimcontrolpanel.h"
 #include "llscreenchannel.h"
 #include "llsyswellwindow.h"
@@ -60,18 +59,12 @@
 #include "llnotificationmanager.h"
 
 LLIMFloater::LLIMFloater(const LLUUID& session_id)
-  : LLTransientDockableFloater(NULL, true, session_id),
-	mControlPanel(NULL),
-	mSessionID(session_id),
+  : LLIMConversation(session_id),
 	mLastMessageIndex(-1),
 	mDialog(IM_NOTHING_SPECIAL),
 	mInputEditor(NULL),
-	mCloseBtn(NULL),
-	mExpandCollapseBtn(NULL),
-	mTearOffBtn(NULL),
 	mSavedTitle(),
 	mTypingStart(),
-	mIsP2PChat(false),
 	mShouldSendTypingState(false),
 	mChatHistory(NULL),
 	mMeTyping(false),
@@ -81,6 +74,8 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	mPositioned(false),
 	mSessionInitialized(false)
 {
+	mIsNearbyChat = false;
+
 	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
 
 	if (mSession)
@@ -97,7 +92,7 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 		case IM_SESSION_GROUP_START:
 			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
 			break;
-		case IM_SESSION_INVITE:		
+		case IM_SESSION_INVITE:
 			if (gAgent.isInGroup(mSessionID))
 			{
 				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
@@ -116,60 +111,30 @@ LLIMFloater::LLIMFloater(const LLUUID& session_id)
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
 
 	setDocked(true);
-	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
-			boost::bind(&LLIMFloater::onIMSessionMenuItemClicked,  this, _2));
-	mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
-			boost::bind(&LLIMFloater::onIMCompactExpandedMenuItemCheck, this, _2));
-	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem",
-			boost::bind(&LLIMFloater::onIMShowModesMenuItemCheck,   this, _2));
-	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
-			boost::bind(&LLIMFloater::onIMShowModesMenuItemEnable,  this, _2));
-}
-
-bool LLIMFloater::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
-{
-	std::string item = userdata.asString();
-	bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory");
-
-	return is_plain_text_mode? item == "compact_view" : item == "expanded_view";
-}
-
-bool LLIMFloater::onIMShowModesMenuItemCheck(const LLSD& userdata)
-{
-	return gSavedSettings.getBOOL(userdata.asString());
 }
 
-// enable/disable states for the "show time" and "show names" items of the show-modes menu
-bool LLIMFloater::onIMShowModesMenuItemEnable(const LLSD& userdata)
+// static
+void* LLIMFloater::createPanelGroupControl(void* userdata)
 {
-	std::string item = userdata.asString();
-	bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory");
-	bool is_not_names = (item != "IMShowNamesForP2PConv");
-	return (plain_text && (is_not_names || mIsP2PChat));
+	LLIMFloater *self = (LLIMFloater*) userdata;
+	self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID);
+	self->mControlPanel->setXMLFilename("panel_group_control_panel.xml");
+	return self->mControlPanel;
 }
 
-void LLIMFloater::onIMSessionMenuItemClicked(const LLSD& userdata)
+// static
+void* LLIMFloater::createPanelAdHocControl(void* userdata)
 {
-	std::string item = userdata.asString();
-
-	if (item == "compact_view" || item == "expanded_view")
-	{
-		gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view");
-	}
-	else
-	{
-		bool prev_value = gSavedSettings.getBOOL(item);
-		gSavedSettings.setBOOL(item, !prev_value);
-	}
-
-	LLIMFloater::processChatHistoryStyleUpdate();
-	LLNearbyChat::processChatHistoryStyleUpdate();
+	LLIMFloater *self = (LLIMFloater*) userdata;
+	self->mControlPanel = new LLPanelAdHocControlPanel(self->mSessionID);
+	self->mControlPanel->setXMLFilename("panel_adhoc_control_panel.xml");
+	return self->mControlPanel;
 }
 
 void LLIMFloater::onFocusLost()
 {
 	LLIMModel::getInstance()->resetActiveSessionID();
-	
+
 	LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, false);
 }
 
@@ -185,19 +150,6 @@ void LLIMFloater::onFocusReceived()
 	}
 }
 
-/*virtual*/
-void LLIMFloater::onOpen(const LLSD& key)
-{
-	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
-	if (host_floater)
-	{
-		// Show the messages pane when opening a floater hosted in the Conversations
-		host_floater->collapseMessagesPane(false);
-	}
-
-	updateHeaderAndToolbar();
-}
-
 // virtual
 void LLIMFloater::onClose(bool app_quitting)
 {
@@ -219,10 +171,9 @@ void LLIMFloater::newIMCallback(const LLSD& data)
 		LLUUID session_id = data["session_id"].asUUID();
 
 		LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-		if (floater == NULL) return;
 
         // update if visible, otherwise will be updated when opened
-		if (floater->getVisible())
+		if (floater && floater->getVisible())
 		{
 			floater->updateMessages();
 		}
@@ -255,38 +206,39 @@ void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
 
 void LLIMFloater::sendMsg()
 {
-	if (!gAgent.isGodlike() 
-		&& (mDialog == IM_NOTHING_SPECIAL)
-		&& mOtherParticipantUUID.isNull())
-	{
-		llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
-		return;
-	}
-
-	if (mInputEditor)
+	if (gAgent.isGodlike()
+		|| (mDialog != IM_NOTHING_SPECIAL)
+		|| !mOtherParticipantUUID.isNull())
 	{
-		LLWString text = mInputEditor->getConvertedText();
-		if(!text.empty())
+		if (mInputEditor)
 		{
-			// Truncate and convert to UTF8 for transport
-			std::string utf8_text = wstring_to_utf8str(text);
-			utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
-			
-			if (mSessionInitialized)
+			LLWString text = mInputEditor->getConvertedText();
+			if(!text.empty())
 			{
-				LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
-			}
-			else
-			{
-				//queue up the message to send once the session is initialized
-				mQueuedMsgsForInit.append(utf8_text);
-			}
+				// Truncate and convert to UTF8 for transport
+				std::string utf8_text = wstring_to_utf8str(text);
+				utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
 
-			mInputEditor->setText(LLStringUtil::null);
+				if (mSessionInitialized)
+				{
+					LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
+				}
+				else
+				{
+					//queue up the message to send once the session is initialized
+					mQueuedMsgsForInit.append(utf8_text);
+				}
+
+				mInputEditor->setText(LLStringUtil::null);
 
-			updateMessages();
+				updateMessages();
+			}
 		}
 	}
+	else
+	{
+		llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
+	}
 }
 
 LLIMFloater::~LLIMFloater()
@@ -312,28 +264,6 @@ BOOL LLIMFloater::postBuild()
 
 	boundVoiceChannel();
 
-	mCloseBtn = getChild<LLButton>("close_btn");
-	mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
-
-	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
-	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
-
-	if (mControlPanel)
-	{
-	mControlPanel->setSessionId(mSessionID);
-	mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel"));
-
-		mExpandCollapseBtn->setImageOverlay(
-				getString(mControlPanel->getParent()->getVisible() ? "collapse_icon" : "expand_icon"));
-	}
-	else
-	{
-		mExpandCollapseBtn->setEnabled(false);
-		getChild<LLLayoutPanel>("im_control_panel_holder")->setVisible(false);
-	}
-
-	mTearOffBtn = getChild<LLButton>("tear_off_btn");
-	mTearOffBtn->setCommitCallback(boost::bind(&LLIMFloater::onTearOffClicked, this));
 
 	mInputEditor = getChild<LLLineEditor>("chat_editor");
 	mInputEditor->setMaxTextLength(1023);
@@ -386,21 +316,7 @@ BOOL LLIMFloater::postBuild()
 	//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
 	//see LLFloaterIMPanel for how it is done (IB)
 
-	if(isChatMultiTab())
-	{
-		return LLFloater::postBuild();
-	}
-	else
-	{
-		return LLDockableFloater::postBuild();
-	}
-}
-
-void LLIMFloater::onTearOffClicked()
-{
-	onClickTearOff(this);
-
-	updateHeaderAndToolbar();
+	return LLIMConversation::postBuild();
 }
 
 void LLIMFloater::boundVoiceChannel()
@@ -412,37 +328,29 @@ void LLIMFloater::boundVoiceChannel()
 				boost::bind(&LLIMFloater::onVoiceChannelStateChanged, this, _1, _2));
 
 		//call (either p2p, group or ad-hoc) can be already in started state
-		updateCallState(voice_channel->getState());
+		bool callIsActive = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED;
+		updateCallBtnState(callIsActive);
 	}
 }
 
-void LLIMFloater::updateCallState(LLVoiceChannel::EState state)
-{
-	bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED;
-	getChild<LLButton>("voice_call_btn")->setImageOverlay(
-			is_call_started? getString("call_btn_stop") : getString("call_btn_start"));
-    enableDisableCallBtn();
-
-}
-
 void LLIMFloater::enableDisableCallBtn()
 {
 	bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled()
 			&& LLVoiceClient::getInstance()->isVoiceWorking();
 
-	if (!mSession)
+	if (mSession)
+	{
+		bool session_initialized = mSession->mSessionInitialized;
+		bool callback_enabled = mSession->mCallBackEnabled;
+
+		BOOL enable_connect =
+				session_initialized && voice_enabled && callback_enabled;
+		getChildView("voice_call_btn")->setEnabled(enable_connect);
+	}
+	else
 	{
 		getChildView("voice_call_btn")->setEnabled(false);
-		return;
 	}
-
-	bool session_initialized = mSession->mSessionInitialized;
-	bool callback_enabled = mSession->mCallBackEnabled;
-
-	BOOL enable_connect = session_initialized
-		&& voice_enabled
-		&& callback_enabled;
-	getChildView("voice_call_btn")->setEnabled(enable_connect);
 }
 
 
@@ -470,18 +378,17 @@ void LLIMFloater::onCallButtonClicked()
 
 void LLIMFloater::onChange(EStatusType status, const std::string &channelURI, bool proximal)
 {
-	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+	if(status != STATUS_JOINING && status != STATUS_LEFT_CHANNEL)
 	{
-		return;
+		enableDisableCallBtn();
 	}
-
-	enableDisableCallBtn();
 }
 
 void LLIMFloater::onVoiceChannelStateChanged(
 		const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
 {
-	updateCallState(new_state);
+	bool callIsActive = new_state >= LLVoiceChannel::STATE_CALL_STARTED;
+	updateCallBtnState(callIsActive);
 }
 
 void LLIMFloater::updateSessionName(const std::string& ui_title,
@@ -516,48 +423,6 @@ void LLIMFloater::draw()
 	LLTransientDockableFloater::draw();
 }
 
-// static
-void* LLIMFloater::createPanelGroupControl(void* userdata)
-{
-	LLIMFloater *self = (LLIMFloater*)userdata;
-	self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID);
-	self->mControlPanel->setXMLFilename("panel_group_control_panel.xml");
-	return self->mControlPanel;
-}
-
-// static
-void* LLIMFloater::createPanelAdHocControl(void* userdata)
-{
-	LLIMFloater *self = (LLIMFloater*)userdata;
-	self->mControlPanel = new LLPanelAdHocControlPanel(self->mSessionID);
-	self->mControlPanel->setXMLFilename("panel_adhoc_control_panel.xml");
-	return self->mControlPanel;
-}
-
-void LLIMFloater::onSlide()
-{
-	LLIMFloaterContainer* host_floater = dynamic_cast<LLIMFloaterContainer*>(getHost());
-	if (host_floater)
-	{
-		// Hide the messages pane if a floater is hosted in the Conversations
-		host_floater->collapseMessagesPane(true);
-	}
-	else ///< floater is torn off
-	{
-		if (mControlPanel)
-		{
-			bool expand = !mControlPanel->getParent()->getVisible();
-
-			// Expand/collapse the IM control panel
-			mControlPanel->getParent()->setVisible(expand);
-
-			gSavedSettings.setBOOL("IMShowControlPanel", expand);
-
-			mExpandCollapseBtn->setImageOverlay(getString(expand ? "collapse_icon" : "expand_icon"));
-		}
-	}
-}
-
 //static
 LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 {
@@ -635,6 +500,22 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 
 	return floater;
 }
+//static
+LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id)
+{
+    LLIMFloater* conversation =
+    		LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
+
+	return conversation;
+}
+
+LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
+{
+	LLIMFloater* conversation =
+				LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", session_id);
+
+	return conversation;
+}
 
 void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
 {
@@ -697,6 +578,8 @@ void LLIMFloater::setVisible(BOOL visible)
 
 BOOL LLIMFloater::getVisible()
 {
+	bool visible;
+
 	if(isChatMultiTab())
 	{
 		LLIMFloaterContainer* im_container =
@@ -708,17 +591,21 @@ BOOL LLIMFloater::getVisible()
 		//torn off floater is always inactive
 		if (!is_active && getHost() != im_container)
 		{
-			return LLTransientDockableFloater::getVisible();
+			visible = LLTransientDockableFloater::getVisible();
+		}
+		else
+		{
+			// getVisible() returns TRUE when Tabbed IM window is minimized.
+			visible = is_active && !im_container->isMinimized()
+						&& im_container->getVisible();
 		}
-
-		// getVisible() returns TRUE when Tabbed IM window is minimized.
-		return is_active && !im_container->isMinimized()
-				&& im_container->getVisible();
 	}
 	else
 	{
-		return LLTransientDockableFloater::getVisible();
+		visible = LLTransientDockableFloater::getVisible();
 	}
+
+	return visible;
 }
 
 //static
@@ -748,17 +635,6 @@ bool LLIMFloater::toggle(const LLUUID& session_id)
 	return true;
 }
 
-//static
-LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id)
-{
-	return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-}
-
-LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
-{
-	return LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", session_id);
-}
-
 void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 {
 	mSessionInitialized = true;
@@ -782,14 +658,15 @@ void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
 	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
 
 	//need to send delayed messaged collected while waiting for session initialization
-	if (!mQueuedMsgsForInit.size())
-		return;
-	LLSD::array_iterator iter;
-	for ( iter = mQueuedMsgsForInit.beginArray();
-			iter != mQueuedMsgsForInit.endArray(); ++iter)
+	if (mQueuedMsgsForInit.size())
 	{
-		LLIMModel::sendMessage(iter->asString(), mSessionID,
-			mOtherParticipantUUID, mDialog);
+		LLSD::array_iterator iter;
+		for ( iter = mQueuedMsgsForInit.beginArray();
+				iter != mQueuedMsgsForInit.endArray(); ++iter)
+		{
+			LLIMModel::sendMessage(iter->asString(), mSessionID,
+				mOtherParticipantUUID, mDialog);
+		}
 	}
 }
 
@@ -878,16 +755,16 @@ void LLIMFloater::updateMessages()
 			if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL)
 			{
 				if (++iter == iter_end)
-				{
-					break;
-				}
-				else
-				{
-					mLastMessageIndex++;
-				}
-			}
-		}
-	}
+			    {
+				    break;
+			    }
+			    else
+			    {
+				    mLastMessageIndex++;
+			    }
+		    }
+	    }
+    }
 }
 
 void LLIMFloater::reloadMessages()
@@ -895,6 +772,7 @@ void LLIMFloater::reloadMessages()
 	mChatHistory->clear();
 	mLastMessageIndex = -1;
 	updateMessages();
+	mInputEditor->setFont(LLViewerChat::getChatFont());
 }
 
 // static
@@ -923,28 +801,22 @@ void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userd
 // static
 void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
 {
-	LLIMFloater* self = (LLIMFloater*)userdata;
+	LLIMFloater* self = (LLIMFloater*) userdata;
 	std::string text = self->mInputEditor->getText();
-	if (!text.empty())
-	{
-		self->setTyping(true);
-	}
-	else
-	{
-		// Deleting all text counts as stopping typing.
-		self->setTyping(false);
-	}
+
+	// Deleting all text counts as stopping typing.
+	self->setTyping(!text.empty());
 }
 
 void LLIMFloater::setTyping(bool typing)
 {
-	if ( typing )
+	if (typing)
 	{
 		// Started or proceeded typing, reset the typing timeout timer
 		mTypingTimeoutTimer.reset();
 	}
 
-	if ( mMeTyping != typing )
+	if (mMeTyping != typing)
 	{
 		// Typing state is changed
 		mMeTyping = typing;
@@ -956,24 +828,16 @@ void LLIMFloater::setTyping(bool typing)
 
 	// Don't want to send typing indicators to multiple people, potentially too
 	// much network traffic. Only send in person-to-person IMs.
-	if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL )
+	if (mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL)
 	{
-		if ( mMeTyping )
-		{
-			if ( mTypingTimer.getElapsedTimeF32() > 1.f )
-			{
-				// Still typing, send 'start typing' notification
-				LLIMModel::instance().sendTypingState(mSessionID,
-						mOtherParticipantUUID, TRUE);
-				mShouldSendTypingState = false;
-			}
-		}
-		else
+		// Still typing, send 'start typing' notification or
+		// send 'stop typing' notification immediately
+		if (!mMeTyping || mTypingTimer.getElapsedTimeF32() > 1.f)
 		{
-			// Send 'stop typing' notification immediately
 			LLIMModel::instance().sendTypingState(mSessionID,
-					mOtherParticipantUUID, FALSE);
+					mOtherParticipantUUID, mMeTyping);
 			mShouldSendTypingState = false;
+
 		}
 	}
 
@@ -985,7 +849,7 @@ void LLIMFloater::setTyping(bool typing)
 
 void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
 {
-	if ( typing )
+	if (typing)
 	{
 		// other user started typing
 		addTypingIndicator(im_info);
@@ -999,10 +863,7 @@ void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
 
 void LLIMFloater::processAgentListUpdates(const LLSD& body)
 {
-	if (!body.isMap())
-		return;
-
-	if ( body.has("agent_updates") && body["agent_updates"].isMap() )
+	if (body.isMap() && body.has("agent_updates") && body["agent_updates"].isMap())
 	{
 		LLSD agent_data = body["agent_updates"].get(gAgentID.asString());
 		if (agent_data.isMap() && agent_data.has("info"))
@@ -1011,7 +872,7 @@ void LLIMFloater::processAgentListUpdates(const LLSD& body)
 
 			if (agent_info.has("mutes"))
 			{
-				BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean(); 
+				BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean();
 				mInputEditor->setEnabled(!moderator_muted_text);
 				std::string label;
 				if (moderator_muted_text)
@@ -1027,27 +888,11 @@ void LLIMFloater::processAgentListUpdates(const LLSD& body)
 	}
 }
 
-void LLIMFloater::processChatHistoryStyleUpdate()
-{
-	LLFontGL* font = LLViewerChat::getChatFont();
-	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
-	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
-		 iter != inst_list.end(); ++iter)
-	{
-		LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
-		if (floater)
-		{
-			floater->reloadMessages();
-			floater->mInputEditor->setFont(font);
-		}
-	}
-}
-
 void LLIMFloater::processSessionUpdate(const LLSD& session_update)
 {
 	// *TODO : verify following code when moderated mode will be implemented
-	if ( false && session_update.has("moderated_mode") &&
-		 session_update["moderated_mode"].has("voice") )
+	if (false && session_update.has("moderated_mode") &&
+			session_update["moderated_mode"].has("voice"))
 	{
 		BOOL voice_moderated = session_update["moderated_mode"]["voice"];
 		const std::string session_label = LLIMModel::instance().getName(mSessionID);
@@ -1069,14 +914,14 @@ void LLIMFloater::processSessionUpdate(const LLSD& session_update)
 }
 
 BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
-						   BOOL drop, EDragAndDropType cargo_type,
-						   void *cargo_data, EAcceptance *accept,
-						   std::string& tooltip_msg)
+		BOOL drop, EDragAndDropType cargo_type,
+		void *cargo_data, EAcceptance *accept,
+		std::string& tooltip_msg)
 {
 	if (mDialog == IM_NOTHING_SPECIAL)
 	{
 		LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
-												 cargo_type, cargo_data, accept);
+				cargo_type, cargo_data, accept);
 	}
 
 	// handle case for dropping calling cards (and folders of calling cards) onto invitation panel for invites
@@ -1086,14 +931,14 @@ BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
 
 		if (cargo_type == DAD_CALLINGCARD)
 		{
-			if (dropCallingCard((LLInventoryItem*)cargo_data, drop))
+			if (dropCallingCard((LLInventoryItem*) cargo_data, drop))
 			{
 				*accept = ACCEPT_YES_MULTI;
 			}
 		}
 		else if (cargo_type == DAD_CATEGORY)
 		{
-			if (dropCategory((LLInventoryCategory*)cargo_data, drop))
+			if (dropCategory((LLInventoryCategory*) cargo_data, drop))
 			{
 				*accept = ACCEPT_YES_MULTI;
 			}
@@ -1105,9 +950,9 @@ BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
 BOOL LLIMFloater::dropCallingCard(LLInventoryItem* item, BOOL drop)
 {
 	BOOL rv = isInviteAllowed();
-	if(rv && item && item->getCreatorUUID().notNull())
+	if (rv && item && item->getCreatorUUID().notNull())
 	{
-		if(drop)
+		if (drop)
 		{
 			uuid_vec_t ids;
 			ids.push_back(item->getCreatorUUID());
@@ -1125,26 +970,26 @@ BOOL LLIMFloater::dropCallingCard(LLInventoryItem* item, BOOL drop)
 BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
 {
 	BOOL rv = isInviteAllowed();
-	if(rv && category)
+	if (rv && category)
 	{
 		LLInventoryModel::cat_array_t cats;
 		LLInventoryModel::item_array_t items;
 		LLUniqueBuddyCollector buddies;
 		gInventory.collectDescendentsIf(category->getUUID(),
-										cats,
-										items,
-										LLInventoryModel::EXCLUDE_TRASH,
-										buddies);
+				cats,
+				items,
+				LLInventoryModel::EXCLUDE_TRASH,
+				buddies);
 		S32 count = items.count();
-		if(count == 0)
+		if (count == 0)
 		{
 			rv = FALSE;
 		}
-		else if(drop)
+		else if (drop)
 		{
 			uuid_vec_t ids;
 			ids.reserve(count);
-			for(S32 i = 0; i < count; ++i)
+			for (S32 i = 0; i < count; ++i)
 			{
 				ids.push_back(items.get(i)->getCreatorUUID());
 			}
@@ -1156,11 +1001,11 @@ BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
 
 BOOL LLIMFloater::isInviteAllowed() const
 {
-	return ( (IM_SESSION_CONFERENCE_START == mDialog)
-			 || (IM_SESSION_INVITE == mDialog) );
+	return ((IM_SESSION_CONFERENCE_START == mDialog)
+			|| (IM_SESSION_INVITE == mDialog));
 }
 
-class LLSessionInviteResponder : public LLHTTPClient::Responder
+class LLSessionInviteResponder: public LLHTTPClient::Responder
 {
 public:
 	LLSessionInviteResponder(const LLUUID& session_id)
@@ -1181,60 +1026,60 @@ class LLSessionInviteResponder : public LLHTTPClient::Responder
 BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
 {
 	LLViewerRegion* region = gAgent.getRegion();
-	if (!region)
+	bool is_region_exist = !!region;
+
+	if (is_region_exist)
 	{
-		return FALSE;
-	}
+		S32 count = ids.size();
 
-	S32 count = ids.size();
+		if (isInviteAllowed() && (count > 0))
+		{
+			llinfos << "LLIMFloater::inviteToSession() - inviting participants" << llendl;
 
-	if( isInviteAllowed() && (count > 0) )
-	{
-		llinfos << "LLIMFloater::inviteToSession() - inviting participants" << llendl;
+			std::string url = region->getCapability("ChatSessionRequest");
 
-		std::string url = region->getCapability("ChatSessionRequest");
+			LLSD data;
 
-		LLSD data;
+			data["params"] = LLSD::emptyArray();
+			for (int i = 0; i < count; i++)
+			{
+				data["params"].append(ids[i]);
+			}
 
-		data["params"] = LLSD::emptyArray();
-		for (int i = 0; i < count; i++)
+			data["method"] = "invite";
+			data["session-id"] = mSessionID;
+			LLHTTPClient::post(
+					url,
+					data,
+					new LLSessionInviteResponder(mSessionID));
+		}
+		else
 		{
-			data["params"].append(ids[i]);
+			llinfos << "LLIMFloater::inviteToSession -"
+					<< " no need to invite agents for "
+					<< mDialog << llendl;
+			// successful add, because everyone that needed to get added
+			// was added.
 		}
-
-		data["method"] = "invite";
-		data["session-id"] = mSessionID;
-		LLHTTPClient::post(
-			url,
-			data,
-				new LLSessionInviteResponder(mSessionID));
-	}
-	else
-	{
-		llinfos << "LLIMFloater::inviteToSession -"
-				<< " no need to invite agents for "
-				<< mDialog << llendl;
-		// successful add, because everyone that needed to get added
-		// was added.
 	}
 
-	return TRUE;
+	return is_region_exist;
 }
 
 void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info)
 {
 	// We may have lost a "stop-typing" packet, don't add it twice
-	if ( im_info && !mOtherTyping )
+	if (im_info && !mOtherTyping)
 	{
 		mOtherTyping = true;
 
 		// Save and set new title
 		mSavedTitle = getTitle();
-		setTitle (mTypingStart);
+		setTitle(mTypingStart);
 
 		// Update speaker
 		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-		if ( speaker_mgr )
+		if (speaker_mgr)
 		{
 			speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE);
 		}
@@ -1243,18 +1088,18 @@ void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info)
 
 void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
 {
-	if ( mOtherTyping )
+	if (mOtherTyping)
 	{
 		mOtherTyping = false;
 
 		// Revert the title to saved one
 		setTitle(mSavedTitle);
 
-		if ( im_info )
+		if (im_info)
 		{
 			// Update speaker
 			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-			if ( speaker_mgr )
+			if (speaker_mgr)
 			{
 				speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
 			}
@@ -1262,59 +1107,6 @@ void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
 	}
 }
 
-void LLIMFloater::updateHeaderAndToolbar()
-{
-	bool is_hosted = getHost() != NULL;
-
-	if (is_hosted)
-	{
-		for (S32 i = 0; i < BUTTON_COUNT; i++)
-		{
-			if (!mButtons[i])
-			{
-				continue;
-			}
-
-			// Hide the standard header buttons in a docked IM floater.
-			mButtons[i]->setVisible(false);
-	}
-}
-
-	bool is_control_panel_visible = false;
-	if (mControlPanel)
-	{
-		// Control panel should be visible only in torn off floaters.
-		is_control_panel_visible = !is_hosted && gSavedSettings.getBOOL("IMShowControlPanel");
-		mControlPanel->getParent()->setVisible(is_control_panel_visible);
-	}
-
-	// Display collapse image (<<) if the floater is hosted
-	// or if it is torn off but has an open control panel.
-	bool is_expanded = is_hosted || is_control_panel_visible;
-	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
-
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
-	if (session)
-	{
-		// The button (>>) should be disabled for torn off P2P conversations.
-		mExpandCollapseBtn->setEnabled(is_hosted || !session->isP2PSessionType());
-	}
-	else
-	{
-		llwarns << "IM session not found." << llendl;
-	}
-
-	if (mDragHandle)
-	{
-		// toggle floater's drag handle and title visibility
-		mDragHandle->setVisible(!is_hosted);
-	}
-
-	mTearOffBtn->setImageOverlay(getString(is_hosted ? "tear_off_icon" : "return_icon"));
-
-	mCloseBtn->setVisible(is_hosted);
-}
-
 // static
 void LLIMFloater::closeHiddenIMToasts()
 {
@@ -1351,14 +1143,6 @@ void LLIMFloater::confirmLeaveCallCallback(const LLSD& notification, const LLSD&
 	return;
 }
 
-// static
-bool LLIMFloater::isChatMultiTab()
-{
-	// Restart is required in order to change chat window type.
-	static bool is_single_window = gSavedSettings.getS32("ChatWindow") == 1;
-	return is_single_window;
-}
-
 // static
 void LLIMFloater::initIMFloater()
 {
@@ -1390,28 +1174,32 @@ void LLIMFloater::sRemoveTypingIndicator(const LLSD& data)
 
 void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
 {
+	LLIMFloater::addToHost(session_id);
+}
 
-	if (isChatMultiTab())
+void LLIMFloater::addToHost(const LLUUID& session_id)
+{
+	if (LLIMConversation::isChatMultiTab())
 	{
-		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
+		LLIMFloaterContainer* im_box = LLIMFloaterContainer::findInstance();
 		if (!im_box)
-			return;
-
-		if (LLIMFloater::findInstance(session_id))
-			return;
-
-		LLIMFloater* new_tab = LLIMFloater::getInstance(session_id);
+	    {
+			im_box = LLIMFloaterContainer::getInstance();
+	    }
 
-		im_box->addFloater(new_tab, FALSE, LLTabContainer::END);
+		if (im_box && !LLIMFloater::findInstance(session_id))
+		{
+			LLIMFloater* new_tab = LLIMFloater::getInstance(session_id);
+			im_box->addFloater(new_tab, FALSE, LLTabContainer::END);
+		}
 	}
-
 }
 
 void	LLIMFloater::onClickCloseBtn()
 {
 
 	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-				mSessionID);
+			mSessionID);
 
 	if (session == NULL)
 	{
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index 8e7ab4cc21db0d20052d71c751c2f2208ac8f3b0..c7793f73eb3dd6a214573903449aeea447e23ff7 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -28,17 +28,16 @@
 #define LL_IMFLOATER_H
 
 #include "llimview.h"
+#include "llimconversation.h"
 #include "llinstantmessage.h"
 #include "lllogchat.h"
 #include "lltooldraganddrop.h"
 #include "llvoicechannel.h"
 #include "llvoiceclient.h"
-#include "lltransientdockablefloater.h"
 
 class LLAvatarName;
 class LLButton;
 class LLLineEditor;
-class LLPanelChatControlPanel;
 class LLChatHistory;
 class LLInventoryItem;
 class LLInventoryCategory;
@@ -48,8 +47,8 @@ class LLInventoryCategory;
  * optionally "docked" to the bottom tray.
  */
 class LLIMFloater
-    : public LLTransientDockableFloater
-	, public LLVoiceClientStatusObserver
+    : public LLVoiceClientStatusObserver
+    , public LLIMConversation
 {
 	LOG_CLASS(LLIMFloater);
 public:
@@ -64,11 +63,16 @@ class LLIMFloater
 	// Check typing timeout timer.
 	/*virtual*/ void draw();
 
+	static void* createPanelGroupControl(void* userdata);
+	static void* createPanelAdHocControl(void* userdata);
+
+	static LLIMFloater* findInstance(const LLUUID& session_id);
+	static LLIMFloater* getInstance(const LLUUID& session_id);
+	static void addToHost(const LLUUID& session_id);
+
 	// LLFloater overrides
-	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
-
 	// Make IM conversion visible and update the message history
 	static LLIMFloater* show(const LLUUID& session_id);
 
@@ -76,10 +80,6 @@ class LLIMFloater
 	// Returns true iff panel became visible
 	static bool toggle(const LLUUID& session_id);
 
-	static LLIMFloater* findInstance(const LLUUID& session_id);
-
-	static LLIMFloater* getInstance(const LLUUID& session_id);
-
 	void sessionInitReplyReceived(const LLUUID& im_session_id);
 
 	// get new messages from LLIMModel
@@ -102,6 +102,7 @@ class LLIMFloater
 	void onChange(EStatusType status, const std::string &channelURI,
 			bool proximal);
 
+	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
 	virtual void onVoiceChannelStateChanged(
 			const LLVoiceChannel::EState& old_state,
 			const LLVoiceChannel::EState& new_state);
@@ -110,28 +111,18 @@ class LLIMFloater
 	void processAgentListUpdates(const LLSD& body);
 	void processSessionUpdate(const LLSD& session_update);
 
-	static void processChatHistoryStyleUpdate();
-
 	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
 			BOOL drop, EDragAndDropType cargo_type,
 			void *cargo_data, EAcceptance *accept,
 			std::string& tooltip_msg);
 
-	/**
-	 * Returns true if chat is displayed in multi tabbed floater
-	 *         false if chat is displayed in multiple windows
-	 */
-	static bool isChatMultiTab();
 
 	static void initIMFloater();
 
 	//used as a callback on receiving new IM message
 	static void sRemoveTypingIndicator(const LLSD& data);
-
 	static void onIMChicletCreated(const LLUUID& session_id);
 
-	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
-
 protected:
 	/* virtual */ void onClickCloseBtn();
 
@@ -156,23 +147,13 @@ class LLIMFloater
 	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
 	static void onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
 	void setTyping(bool typing);
-	void onSlide();
-	static void* createPanelGroupControl(void* userdata);
-	static void* createPanelAdHocControl(void* userdata);
 
-	void onTearOffClicked();
-
-	bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata);
-	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
-	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
-	void onIMSessionMenuItemClicked(const LLSD& userdata);
 	void onCallButtonClicked();
 
-	void boundVoiceChannel();
-	void enableDisableCallBtn();
+	// set the enable/disable state for the Call button
+	virtual void enableDisableCallBtn();
 
-	// refresh a visual state of the Call button
-	void updateCallState(LLVoiceChannel::EState state);
+	void boundVoiceChannel();
 
 	// Add the "User is typing..." indicator.
 	void addTypingIndicator(const LLIMInfo* im_info);
@@ -180,15 +161,11 @@ class LLIMFloater
 	// Remove the "User is typing..." indicator.
 	void removeTypingIndicator(const LLIMInfo* im_info = NULL);
 
-	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
-	void updateHeaderAndToolbar();
-
 	static void closeHiddenIMToasts();
 
 	static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
 
-	LLPanelChatControlPanel* mControlPanel;
-	LLUUID mSessionID;
+
 	LLIMModel::LLIMSession* mSession;
 	S32 mLastMessageIndex;
 
@@ -204,7 +181,6 @@ class LLIMFloater
 	bool mMeTyping;
 	bool mOtherTyping;
 	bool mShouldSendTypingState;
-	bool mIsP2PChat;
 	LLFrameTimer mTypingTimer;
 	LLFrameTimer mTypingTimeoutTimer;
 
@@ -213,10 +189,6 @@ class LLIMFloater
 
 	// connection to voice channel state change signal
 	boost::signals2::connection mVoiceChannelStateChangeConnection;
-
-	LLButton* mCloseBtn;
-	LLButton* mExpandCollapseBtn;
-	LLButton* mTearOffBtn;
 };
 
 #endif  // LL_IMFLOATER_H
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
index b051440589475060566eb54a21edada0053cb232..f72ddef4126465f117b95b564f247f9e625664e9 100644
--- a/indra/newview/llimfloatercontainer.cpp
+++ b/indra/newview/llimfloatercontainer.cpp
@@ -31,6 +31,7 @@
 
 #include "llfloaterreg.h"
 #include "lllayoutstack.h"
+#include "llnearbychatbar.h"
 
 #include "llagent.h"
 #include "llavatariconctrl.h"
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 18d39b7aa4194303b5b9ce753e66fe1e68be6c92..c3ac1d32cbd1eac5ba6d179009be5b37344bcc83 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -41,7 +41,7 @@
 #include "lltextutil.h"
 #include "lltrans.h"
 #include "lluictrlfactory.h"
-
+#include "llimconversation.h"
 #include "llagent.h"
 #include "llagentui.h"
 #include "llappviewer.h"
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 3c4b0b9aae7ccba2a9b9a2516cb2c7002f535b54..497690d656871b49d98c731086711046766151d4 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -25,7 +25,6 @@
  */
 
 #include "llviewerprecompiledheaders.h"
-#include "llnearbychat.h"
 #include "llviewercontrol.h"
 #include "llviewerwindow.h"
 #include "llrootview.h"
@@ -93,9 +92,9 @@ static const S32 RESIZE_BAR_THICKNESS = 3;
 
 static LLRegisterPanelClassWrapper<LLNearbyChat> t_panel_nearby_chat("panel_nearby_chat");
 
-LLNearbyChat::LLNearbyChat(const LLNearbyChat::Params& p) 
-:	LLPanel(p),
-	mChatHistory(NULL)
+LLNearbyChat::LLNearbyChat(const LLNearbyChat::Params& p)
+	: LLPanel(p),
+	  mChatHistory(NULL)
 {
 }
 
@@ -117,10 +116,7 @@ BOOL LLNearbyChat::postBuild()
 
 	mChatHistory = getChild<LLChatHistory>("chat_history");
 
-	if(!LLPanel::postBuild())
-		return false;
-	
-	return true;
+    return LLPanel::postBuild();
 }
 
 
@@ -139,8 +135,7 @@ void LLNearbyChat::appendMessage(const LLChat& chat, const LLSD &args)
 		chat_args["use_plain_text_chat_history"] =
 				gSavedSettings.getBOOL("PlainTextChatHistory");
 		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
-		chat_args["show_names_for_p2p_conv"] = false
-				|| gSavedSettings.getBOOL("IMShowNamesForP2PConv");
+		chat_args["show_names_for_p2p_conv"] = true;
 
 		mChatHistory->appendMessage(chat, chat_args);
 	}
@@ -223,7 +218,7 @@ void LLNearbyChat::getAllowedRect(LLRect& rect)
 	rect = gViewerWindow->getWorldViewRectScaled();
 }
 
-void LLNearbyChat::updateChatHistoryStyle()
+void LLNearbyChat::reloadMessages()
 {
 	mChatHistory->clear();
 
@@ -236,15 +231,6 @@ void LLNearbyChat::updateChatHistoryStyle()
 	}
 }
 
-//static 
-void LLNearbyChat::processChatHistoryStyleUpdate()
-{
-	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
-	LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
-	if(nearby_chat)
-		nearby_chat->updateChatHistoryStyle();
-}
-
 void LLNearbyChat::loadHistory()
 {
 	LLSD do_not_log;
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 47f4de1c6d8bfb7c8c3acebae2f68569ab97f161..62a41c17cba92dbaa46da30dd11e03a9a26c51f2 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -29,13 +29,13 @@
 
 #include "llscrollbar.h"
 #include "llviewerchat.h"
-#include "llfloater.h"
+#include "llpanel.h"
 
 class LLResizeBar;
 class LLChatHistory;
 
 class LLNearbyChat
-: public LLPanel
+	: public LLPanel
 {
 public:
 	LLNearbyChat(const Params& p = LLPanel::getDefaultParams());
@@ -56,12 +56,8 @@ class LLNearbyChat
 	
 	/*virtual*/ void	setVisible(BOOL visible);
 	
-	virtual void updateChatHistoryStyle();
-
-	static void processChatHistoryStyleUpdate();
-
 	void loadHistory();
-
+    void reloadMessages();
 	static LLNearbyChat* getInstance();
 	void removeScreenChat();
 
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index b4224e30e688d884104a85403e20e022f98fdfad..82c00253e86f4400adb1961b8e34d52822ec13b4 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -31,7 +31,7 @@
 #include "llappviewer.h"
 #include "llfloaterreg.h"
 #include "lltrans.h"
-
+#include "llimfloatercontainer.h"
 #include "llfirstuse.h"
 #include "llnearbychatbar.h"
 #include "llagent.h"
@@ -54,7 +54,7 @@
 
 S32 LLNearbyChatBar::sLastSpecialChatChannel = 0;
 
-const S32 EXPANDED_HEIGHT = 300;
+const S32 EXPANDED_HEIGHT = 266;
 const S32 COLLAPSED_HEIGHT = 60;
 const S32 EXPANDED_MIN_HEIGHT = 150;
 
@@ -72,7 +72,7 @@ static LLChatTypeTrigger sChatTypeTriggers[] = {
 };
 
 LLNearbyChatBar::LLNearbyChatBar(const LLSD& key)
-:	LLFloater(key),
+:	LLIMConversation(key),
 	mChatBox(NULL),
 	mNearbyChat(NULL),
 	mOutputMonitor(NULL),
@@ -116,14 +116,44 @@ BOOL LLNearbyChatBar::postBuild()
 	// Register for font change notifications
 	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1));
 
+	// childSetAction("voice_call_btn", boost::bind(&LLNearbyChatBar::onCallButtonClicked, this));
+
 	enableResizeCtrls(true, true, false);
 
-	return TRUE;
+	addToHost();
+
+	return LLIMConversation::postBuild();;
+}
+
+void LLNearbyChatBar::onCallButtonClicked()
+{
+	LLAgent::toggleMicrophone(NULL);
+}
+
+void LLNearbyChatBar::enableDisableCallBtn()
+{
+	// bool btn_enabled = LLAgent::isActionAllowed("speak");
+
+	getChildView("voice_call_btn")->setEnabled(false /*btn_enabled*/);
+}
+
+void LLNearbyChatBar::addToHost()
+{
+	if (LLIMConversation::isChatMultiTab())
+	{
+		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
+
+		if (im_box)
+		{
+			im_box->addFloater(this, FALSE, LLTabContainer::END);
+		}
+	}
 }
 
 // virtual
 void LLNearbyChatBar::onOpen(const LLSD& key)
 {
+	LLIMConversation::onOpen(key);
 	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 }
 
@@ -160,6 +190,12 @@ LLNearbyChatBar* LLNearbyChatBar::getInstance()
 	return LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar");
 }
 
+//static
+//LLNearbyChatBar* LLNearbyChatBar::findInstance()
+//{
+//	return LLFloaterReg::findTypedInstance<LLNearbyChatBar>("chat_bar");
+//}
+
 void LLNearbyChatBar::showHistory()
 {
 	openFloater();
@@ -178,7 +214,8 @@ void LLNearbyChatBar::showTranslationCheckbox(BOOL show)
 void LLNearbyChatBar::draw()
 {
 	displaySpeakingIndicator();
-	LLFloater::draw();
+	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
+	LLIMConversation::draw();
 }
 
 std::string LLNearbyChatBar::getCurrentChat()
@@ -206,22 +243,24 @@ BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::strin
 	U32 in_len = in_str.length();
 	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
 	
-	for (S32 n = 0; n < cnt; n++)
-	{
-		if (in_len > sChatTypeTriggers[n].name.length())
-			continue;
-
-		std::string trigger_trunc = sChatTypeTriggers[n].name;
-		LLStringUtil::truncate(trigger_trunc, in_len);
+	bool string_was_found = false;
 
-		if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
+	for (S32 n = 0; n < cnt && !string_was_found; n++)
+	{
+		if (in_len <= sChatTypeTriggers[n].name.length())
 		{
-			*out_str = sChatTypeTriggers[n].name;
-			return TRUE;
+			std::string trigger_trunc = sChatTypeTriggers[n].name;
+			LLStringUtil::truncate(trigger_trunc, in_len);
+
+			if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
+			{
+				*out_str = sChatTypeTriggers[n].name;
+				string_was_found = true;
+			}
 		}
 	}
 
-	return FALSE;
+	return string_was_found;
 }
 
 void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
@@ -421,6 +460,11 @@ void LLNearbyChatBar::onToggleNearbyChatPanel()
 	gSavedSettings.setBOOL("nearbychat_history_visibility", mNearbyChat->getVisible());
 }
 
+void LLNearbyChatBar::reloadMessages()
+{
+	LLNearbyChat::getInstance()->reloadMessages();
+}
+
 void LLNearbyChatBar::setMinimized(BOOL b)
 {
 	LLNearbyChat* nearby_chat = getChild<LLNearbyChat>("nearby_chat");
@@ -531,20 +575,20 @@ void LLNearbyChatBar::startChat(const char* line)
 {
 	LLNearbyChatBar* cb = LLNearbyChatBar::getInstance();
 
-	if (!cb )
-		return;
+	if (cb )
+	{
+		cb->setVisible(TRUE);
+		cb->setFocus(TRUE);
+		cb->mChatBox->setFocus(TRUE);
 
-	cb->setVisible(TRUE);
-	cb->setFocus(TRUE);
-	cb->mChatBox->setFocus(TRUE);
+		if (line)
+		{
+			std::string line_string(line);
+			cb->mChatBox->setText(line_string);
+		}
 
-	if (line)
-	{
-		std::string line_string(line);
-		cb->mChatBox->setText(line_string);
+		cb->mChatBox->setCursorToEnd();
 	}
-
-	cb->mChatBox->setCursorToEnd();
 }
 
 // Exit "chat mode" and do the appropriate focus changes
@@ -553,13 +597,13 @@ void LLNearbyChatBar::stopChat()
 {
 	LLNearbyChatBar* cb = LLNearbyChatBar::getInstance();
 
-	if (!cb)
-		return;
-
-	cb->mChatBox->setFocus(FALSE);
+	if (cb)
+	{
+		cb->mChatBox->setFocus(FALSE);
 
- 	// stop typing animation
- 	gAgent.stopTyping();
+		// stop typing animation
+		gAgent.stopTyping();
+	}
 }
 
 // If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index 8547cf0bcedbf83b5a05bc61d1fbcce8d4508d92..e714c04498842f442e50fb696c46e3ab85e5ef25 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -27,26 +27,31 @@
 #ifndef LL_LLNEARBYCHATBAR_H
 #define LL_LLNEARBYCHATBAR_H
 
-#include "llfloater.h"
+#include "llimconversation.h"
 #include "llcombobox.h"
 #include "llgesturemgr.h"
 #include "llchat.h"
+#include "llnearbychat.h"
 #include "llvoiceclient.h"
 #include "lloutputmonitorctrl.h"
 #include "llspeakers.h"
 
-class LLNearbyChatBar :	public LLFloater
+class LLNearbyChatBar :	public LLIMConversation
 {
 public:
 	// constructor for inline chat-bars (e.g. hosted in chat history window)
 	LLNearbyChatBar(const LLSD& key);
 	~LLNearbyChatBar() {}
 
-	virtual BOOL postBuild();
+	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 
 	static LLNearbyChatBar* getInstance();
+//	static LLNearbyChatBar* findInstance();
 
+	void addToHost();
+
+	void reloadMessages();
 	LLLineEditor* getChatBox() { return mChatBox; }
 
 	virtual void draw();
@@ -83,6 +88,11 @@ class LLNearbyChatBar :	public LLFloater
 
 	void displaySpeakingIndicator();
 
+	void onCallButtonClicked();
+
+	// set the enable/disable state for the Call button
+	virtual void enableDisableCallBtn();
+
 	// Which non-zero channel did we last chat on?
 	static S32 sLastSpecialChatChannel;
 
diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
index 63992462b34a33973cdd5675a6ad6eadfb203399..7688525e139592a7760a740ec3a3ce86f832221a 100644
--- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
@@ -3,32 +3,151 @@
  open_positioning="specified"
  specified_left="10"
  specified_bottom="10"
- height="60"
+ background_visible="true"
+ default_tab_group="1"
+ height="355"
+ help_topic="chat_bar"
  layout="topleft"
- legacy_header_height="25"
- single_instance="true"
- title="NEARBY CHAT"
- save_rect="true"
- save_visibility="true"
- can_close="true"
+ name="chat_bar"
+ can_dock="false"
  can_minimize="true"
- help_topic="chat_bar"
- min_height="60"
- min_width="150"
+ can_close="true"
+ visible="false"
+ width="394"
  can_resize="true"
- default_tab_group="1"
- name="chat_bar"
- width="300">
+ can_tear_off="false"
+ min_width="250"
+ min_height="80"
+ single_instance="true"
+ title="Nearby chat">
+    <floater.string name="call_btn_start">VoicePTT_Off</floater.string>
+    <floater.string name="call_btn_stop">VoicePTT_On</floater.string>
+    <floater.string
+     name="collapse_icon"
+     value="TabIcon_Open_Off"/>
+    <floater.string
+     name="expand_icon"
+     value="TabIcon_Close_Off"/>
+    <floater.string
+     name="tear_off_icon"
+     value="tearoffbox.tga"/>
+    <floater.string
+     name="return_icon"
+     value="Icon_Dock_Foreground"/>
+     <view
+        follows="all"
+        layout="topleft"
+        name="contents_view"
+        top="0"
+        left="0"
+        height="355"
+        width="394">
+      <panel
+         follows="left|top|right"
+         layout="topleft"
+         name="toolbar_panel"
+         top="0"
+         left="0"
+         height="35"
+         width="394">         
+             <menu_button
+                 menu_filename="menu_im_session_showmodes.xml"
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Left_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Left_Selected"
+                 image_unselected="Toolbar_Left_Off"
+                 layout="topleft"
+                 left="5"
+                 name="view_options_btn"
+                 top="5"
+                 width="31" />
+             <button
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="AddItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="4"
+                 name="add_btn"
+                 width="31">
+                 <commit_callback
+                    function="Chats.add" />
+             </button>   
+             <button
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Right_Over"
+                 image_overlay="VoicePTT_Off"
+                 image_selected="Toolbar_Right_Selected"
+                 image_unselected="Toolbar_Right_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="4"
+                 name="voice_call_btn"
+                 width="31">
+                 <commit_callback
+                    function="Chats.add" />
+             </button>
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Icon_Close_Foreground"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left="283"
+                 name="close_btn"
+                 width="31">
+             </button>
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TabIcon_Open_Off"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="5"
+                 name="expand_collapse_btn"
+                 width="31">
+             </button>
+             <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="tearoffbox.tga"
+                 image_selected="Toolbar_Middle_Selected"
+             	 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="5"
+                 name="tear_off_btn"
+                 width="31">
+             </button>
+     </panel>
     <panel
-        top="20"
+        top="35"
+        left="0"
         class="panel_nearby_chat"
         follow="all"
-        width="300"
+        width="390"
         height="0"
         visible="false"
         filename="panel_nearby_chat.xml"
         name="nearby_chat" />
-    <panel width="300" 
+    <panel
+    	width="390"
+    	height="10"
+    	visible="true" />
+    <panel width="394" 
            height="31" 
            left="0" 
            name="bottom_panel"
@@ -39,18 +158,15 @@
         border_style="line"
         border_thickness="1"
         follows="left|right"
-        height="23"
+        height="20"
         label="Click here to chat."
         layout="topleft"
-        left_delta="7"
-        left="0"
+        left="1"
         max_length_bytes="1023"
         name="chat_box"
-        text_pad_left="5"
-        text_pad_right="25"
         tool_tip="Press Enter to say, Ctrl+Enter to shout"
         top="2"
-        width="255" />
+        width="384" />
       <output_monitor
         auto_update="true"
         follows="right"
@@ -65,6 +181,7 @@
         width="20" />
       <button
         follows="right"
+        visible="false"
         is_toggle="true"
         width="20"
         top="2"
@@ -81,4 +198,5 @@
         tool_tip="Shows/hides nearby chat log">
       </button>
     </panel>
+  </view>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
index d683116eb8b339321114fc75732a3f7a260d5246..b415ba780d9691d5f98be3f737a202c271ce9c5e 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
@@ -1,20 +1,21 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel
  follows="all"
- height="300"
+ top="0"
+ bottom_delta="10"
  help_topic="nearby_chat"
  layout="topleft"
  name="nearby_chat"
- width="320">
+ width="394">
   <layout_stack
    follows="all"
-   height="295"
+   height="278"
    layout="topleft"
    left="0"
    name="stack"
    top="5"
    orientation="vertical"
-   width="320">
+   width="394">
     <layout_panel
      auto_resize="false"
      height="26"
@@ -23,7 +24,7 @@
      name="translate_chat_checkbox_lp"
      top_delta="0"
      visible="true"
-     width="313">
+     width="387">
       <check_box
        top="10"
        control_name="TranslateChat"
@@ -33,15 +34,15 @@
        layout="topleft"
        left="5"
        name="translate_chat_checkbox"
-       width="300" />
+       width="374" />
     </layout_panel>
     <layout_panel
      auto_resize="true"
-     height="277"
+     height="256"
      left_delta="0"
      layout="topleft"
      name="chat_history_lp"
-     width="318">
+     width="394">
       <chat_history
        bg_readonly_color="ChatHistoryBgColor"
        bg_writeable_color="ChatHistoryBgColor"
@@ -49,7 +50,7 @@
        layout="topleft"
        left="5"
        left_widget_pad="0"
-       height="272"
+       height="240"
        name="chat_history"
        parse_highlights="true"
        parse_urls="true"
@@ -57,7 +58,7 @@
        text_color="ChatHistoryTextColor"
        text_readonly_color="ChatHistoryTextColor"
        top="0"
-       width="313" />
+       width="384" />
     </layout_panel>
   </layout_stack>
 </panel>