diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 734e2cfda7d79f667802f9e95d0f0a0da005a151..27dd7f5b324338e744c6afcd9834c730b7227c9f 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -812,6 +812,20 @@ void LLFloater::closeFloater(bool app_quitting)
 	}
 }
 
+/*virtual*/
+void LLFloater::closeHostedFloater()
+{
+	// When toggling *visibility*, close the host instead of the floater when hosted
+	if (getHost())
+	{
+		getHost()->closeFloater();
+	}
+	else
+	{
+		closeFloater();
+	}
+}
+
 /*virtual*/
 void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
@@ -1609,8 +1623,17 @@ void LLFloater::bringToFront( S32 x, S32 y )
 // virtual
 void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
 {
-	setVisible(TRUE);
-	setFrontmost(take_focus);
+	LLMultiFloater* hostp = getHost();
+	if (hostp)
+	{
+		hostp->setVisible(TRUE);
+		hostp->setFrontmost(take_focus);
+	}
+	else
+	{
+		setVisible(TRUE);
+		setFrontmost(take_focus);
+	}
 }
 
 void LLFloater::setFrontmost(BOOL take_focus)
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index 157b9b01133a8387a34c4fb6dc653dd107dc06ed..cb5bf28db3c0e003f08ad524512836117ed79dd1 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -226,6 +226,9 @@ public:
 	// If allowed, close the floater cleanly, releasing focus.
 	virtual void	closeFloater(bool app_quitting = false);
 
+	// Close the floater or its host. Use when hidding or toggling a floater instance.
+	virtual void	closeHostedFloater();
+
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 	
 	// Release keyboard and mouse focus
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 306caf2b91be82137fa44d6589cae5dbbe754d4a..c20d8636126224d4b611969aa71697a5552c2a59 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -264,17 +264,9 @@ bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
 	LLFloater* instance = findInstance(name, key); 
 	if (instance)
 	{
-		// When toggling *visibility*, close the host instead of the floater when hosted
-		if (instance->getHost())
-			instance->getHost()->closeFloater();
-		else
-			instance->closeFloater();
-		return true;
-	}
-	else
-	{
-		return false;
+		instance->closeHostedFloater();
 	}
+	return (instance != NULL);
 }
 
 //static
@@ -284,11 +276,7 @@ bool LLFloaterReg::toggleInstance(const std::string& name, const LLSD& key)
 	LLFloater* instance = findInstance(name, key); 
 	if (LLFloater::isShown(instance))
 	{
-		// When toggling *visibility*, close the host instead of the floater when hosted
-		if (instance->getHost())
-			instance->getHost()->closeFloater();
-		else
-			instance->closeFloater();
+		instance->closeHostedFloater();
 		return false;
 	}
 	else
@@ -481,31 +469,58 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
 	//       * Also, if it is not on top, bring it forward when focus is given.
 	// * Else the target floater is open, close it.
 	// 
-
 	std::string name = sdname.asString();
 	LLFloater* instance = getInstance(name, key); 
+	
 
 	if (!instance)
 	{
 		lldebugs << "Unable to get instance of floater '" << name << "'" << llendl;
+		return;
 	}
-	else if (instance->isMinimized())
+	
+	// If hosted, we need to take that into account
+	LLFloater* host = instance->getHost();
+	
+	if (host)
 	{
-		instance->setMinimized(FALSE);
-		instance->setVisibleAndFrontmost();
-	}
-	else if (!instance->isShown())
-	{
-		instance->openFloater(key);
-		instance->setVisibleAndFrontmost();
-	}
-	else if (!instance->isFrontmost())
-	{
-		instance->setVisibleAndFrontmost();
+		if (host->isMinimized() || !host->isShown() || !host->isFrontmost())
+		{
+			host->setMinimized(FALSE);
+			instance->openFloater(key);
+			instance->setVisibleAndFrontmost();
+		}
+		else if (!instance->getVisible())
+		{
+			instance->openFloater(key);
+			instance->setVisibleAndFrontmost();
+			instance->setFocus(TRUE);
+		}
+		else
+		{
+			instance->closeHostedFloater();
+		}
 	}
 	else
 	{
-		instance->closeFloater();
+		if (instance->isMinimized())
+		{
+			instance->setMinimized(FALSE);
+			instance->setVisibleAndFrontmost();
+		}
+		else if (!instance->isShown())
+		{
+			instance->openFloater(key);
+			instance->setVisibleAndFrontmost();
+		}
+		else if (!instance->isFrontmost())
+		{
+			instance->setVisibleAndFrontmost();
+		}
+		else
+		{
+			instance->closeHostedFloater();
+		}
 	}
 }
 
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index d6e457887bca46fef656bb39dccd8f06fd6ba6aa..ce063a9887a777d58d0671f010226cc79da6b250 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -44,6 +44,7 @@
 #include "llcallingcard.h"		// for LLAvatarTracker
 #include "llconversationlog.h"
 #include "llfloateravatarpicker.h"	// for LLFloaterAvatarPicker
+#include "llfloaterconversationpreview.h"
 #include "llfloatergroupinvite.h"
 #include "llfloatergroups.h"
 #include "llfloaterreg.h"
@@ -926,9 +927,20 @@ void LLAvatarActions::viewChatHistory(const LLUUID& id)
 		if (iter->getParticipantID() == id)
 		{
 			LLFloaterReg::showInstance("preview_conversation", iter->getSessionID(), true);
-			break;
+			return;
 		}
 	}
+
+	if (LLLogChat::isTranscriptExist(id))
+	{
+		LLAvatarName avatar_name;
+		LLSD extended_id(id);
+
+		LLAvatarNameCache::get(id, &avatar_name);
+		extended_id[LL_FCP_COMPLETE_NAME] = avatar_name.getCompleteName();
+		extended_id[LL_FCP_ACCOUNT_NAME] = avatar_name.getAccountName();
+		LLFloaterReg::showInstance("preview_conversation", extended_id, true);
+	}
 }
 
 //== private methods ========================================================================================
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index 48e0caa0ce59af1dea119e45acdc121f9a68bf36..a3d715530d0a8dd48576b21d4248c69f888ac90e 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -33,13 +33,19 @@
 #include "llspinctrl.h"
 #include "lltrans.h"
 
+const std::string LL_FCP_COMPLETE_NAME("complete_name");
+const std::string LL_FCP_ACCOUNT_NAME("user_name");
+
 LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id)
 :	LLFloater(session_id),
 	mChatHistory(NULL),
 	mSessionID(session_id.asUUID()),
 	mCurrentPage(0),
-	mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize"))
-{}
+	mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")),
+	mAccountName(session_id[LL_FCP_ACCOUNT_NAME]),
+	mCompleteName(session_id[LL_FCP_COMPLETE_NAME])
+{
+}
 
 BOOL LLFloaterConversationPreview::postBuild()
 {
@@ -49,7 +55,12 @@ BOOL LLFloaterConversationPreview::postBuild()
 	std::string name;
 	std::string file;
 
-	if (mSessionID != LLUUID::null && conv)
+	if (mAccountName != "")
+	{
+		name = mCompleteName;
+		file = mAccountName;
+	}
+	else if (mSessionID != LLUUID::null && conv)
 	{
 		name = conv->getConversationName();
 		file = conv->getHistoryFileName();
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
index 0341e5d2a0719521ecf96a59b945d1cb7c2713a4..b17ae84b632e9fecc21a7ce5360afc2335fc484d 100644
--- a/indra/newview/llfloaterconversationpreview.h
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -29,6 +29,9 @@
 #include "llchathistory.h"
 #include "llfloater.h"
 
+extern const std::string LL_FCP_COMPLETE_NAME;	//"complete_name"
+extern const std::string LL_FCP_ACCOUNT_NAME;		//"user_name"
+
 class LLSpinCtrl;
 
 class LLFloaterConversationPreview : public LLFloater
@@ -54,6 +57,8 @@ private:
 	int				mPageSize;
 
 	std::list<LLSD> mMessages;
+	std::string		mAccountName;
+	std::string		mCompleteName;
 };
 
 #endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 2d12d4ec21bf6e2903484fc32f1799906e656e39..c5edd11c123583e9ce67ed6fd4b65dd49b9e0a4f 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -1337,6 +1337,30 @@ void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
     selectConversationPair(session_id, true);
 }
 
+// Select the conversation *after* (or before if none after) the passed uuid conversation
+// Used to change the selection on key hits
+void LLFloaterIMContainer::selectNextConversation(const LLUUID& uuid)
+{
+	LLFolderViewItem* new_selection = NULL;
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
+	if (widget)
+	{
+		new_selection = mConversationsRoot->getNextFromChild(widget, FALSE);
+		if (!new_selection)
+		{
+			new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
+		}
+	}
+	if (new_selection)
+	{
+		LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
+		if (vmi)
+		{
+			selectConversationPair(vmi->getUUID(), true);
+		}
+	}
+}
+
 // Synchronous select the conversation item and the conversation floater
 BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget)
 {
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 5ba29b8cfbf13f4e0ca0d076d4456705bf9a0729..419239f90bb381396cdb5aa7c63d9cdb06662f9a 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -69,6 +69,7 @@ public:
 	void returnFloaterToHost();
     void showConversation(const LLUUID& session_id);
     void selectConversation(const LLUUID& session_id);
+	void selectNextConversation(const LLUUID& session_id);
     BOOL selectConversationPair(const LLUUID& session_id, bool select_widget);
     void clearAllFlashStates();
 
@@ -187,6 +188,7 @@ public:
 	void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes);
 	bool isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget);
 	boost::signals2::connection mMicroChangedSignal;
+	S32 getConversationListItemSize() { return mConversationsWidgets.size(); }
 
 private:
 	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 430326203f5bc6b72dceb3c68f9a42f68047eebc..a3b81e037a63d9ca621330057f535d4d9685c53a 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -135,6 +135,25 @@ BOOL LLFloaterIMNearbyChat::postBuild()
 	return result;
 }
 
+// virtual
+void LLFloaterIMNearbyChat::closeHostedFloater()
+{
+	// Should check how many conversations are ongoing. Close all if 1 only (the Nearby Chat), select next one otherwise
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	if (floater_container->getConversationListItemSize() == 1)
+	{
+		floater_container->closeFloater();
+	}
+	else
+	{
+		if (!getHost())
+		{
+			setVisible(FALSE);
+		}
+		floater_container->selectNextConversation(LLUUID());
+	}
+}
+
 // virtual
 void LLFloaterIMNearbyChat::refresh()
 {
diff --git a/indra/newview/llfloaterimnearbychat.h b/indra/newview/llfloaterimnearbychat.h
index 14c7d01ecdcb44f3d1cdf5f48ed80c3fe3122f42..2992c12436f0e34618be44a7ae8f1098594d9af5 100644
--- a/indra/newview/llfloaterimnearbychat.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -54,6 +54,7 @@ public:
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ void closeHostedFloater();
 
 	void loadHistory();
     void reloadMessages(bool clean_messages = false);
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 17b72c50234091181b7bcccbe8ca4aad250338c7..09f816a4e6ea127bc1d78a10ab31ecb2825d7661 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -28,6 +28,7 @@
 
 #include "llagent.h"
 #include "llagentui.h"
+#include "llavatarnamecache.h"
 #include "lllogchat.h"
 #include "lltrans.h"
 #include "llviewercontrol.h"
@@ -540,6 +541,31 @@ void LLLogChat::deleteTranscripts()
 	LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
 }
 
+// static
+bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id)
+{
+	std::vector<std::string> list_of_transcriptions;
+	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions);
+
+	if (list_of_transcriptions.size() > 0)
+	{
+		LLAvatarName avatar_name;
+		LLAvatarNameCache::get(avatar_id, &avatar_name);
+		std::string avatar_user_name = avatar_name.getAccountName();
+		std::replace(avatar_user_name.begin(), avatar_user_name.end(), '.', '_');
+
+		BOOST_FOREACH(std::string& transcript_file_name, list_of_transcriptions)
+		{
+			if (std::string::npos != transcript_file_name.find(avatar_user_name))
+			{
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
 //*TODO mark object's names in a special way so that they will be distinguishable form avatar name 
 //which are more strict by its nature (only firstname and secondname)
 //Example, an object's name can be written like "Object <actual_object's_name>"
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 5fbb4ade96a567afb0cb742c2f4df4720d507523..b981d9ce0410494785426e9a825283ed5515de7a 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -57,6 +57,7 @@ public:
 	static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
 
 	static void deleteTranscripts();
+	static bool isTranscriptExist(const LLUUID& avatar_id);
 
 private:
 	static std::string cleanFileName(std::string filename);
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 6667706333e66c358c836c61e657664ef34d5527..c5283404f13e64ce8f1429873201fbdda8fc1152 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -812,19 +812,20 @@ void LLPanelPeople::updateButtons()
 	else
 	{
 		bool is_friend = true;
-
+		bool is_self = false;
 		// Check whether selected avatar is our friend.
 		if (item_selected)
 		{
 			selected_id = selected_uuids.front();
 			is_friend = LLAvatarTracker::instance().getBuddyInfo(selected_id) != NULL;
+			is_self = gAgent.getID() == selected_id;
 		}
 
 		LLPanel* cur_panel = mTabContainer->getCurrentPanel();
 		if (cur_panel)
 		{
 			if (cur_panel->hasChild("add_friend_btn", TRUE))
-				cur_panel->getChildView("add_friend_btn")->setEnabled(item_selected && !is_friend);
+				cur_panel->getChildView("add_friend_btn")->setEnabled(item_selected && !is_friend && !is_self);
 
 			if (friends_tab_active)
 			{
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index 61e9468ce5a928a068a2980b6566d3e7bb12defb..47d6b49a50606cc6558118d7999f72dc51eba4b1 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -37,6 +37,7 @@
 #include "llagentdata.h"			// for gAgentID
 #include "llavataractions.h"
 #include "llcallingcard.h"			// for LLAvatarTracker
+#include "lllogchat.h"
 #include "llviewermenu.h"			// for gMenuHolder
 
 namespace LLPanelPeopleMenus
@@ -180,7 +181,11 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
 	{
 		return LLAvatarActions::canOfferTeleport(mUUIDs);
 	}
-	else if (item == std::string("can_im") || item == std::string("can_callog") || item == std::string("can_invite") ||
+	else if (item == std::string("can_callog"))
+	{
+		return LLLogChat::isTranscriptExist(mUUIDs.front());
+	}
+	else if (item == std::string("can_im") || item == std::string("can_invite") ||
 	         item == std::string("can_share") || item == std::string("can_pay"))
 	{
 		return true;
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index b50deb7d7aa5b9c4029378442367eb8d20df863c..544f06ac0c4a2d2bb85c09bcbe00a5af26403ac7 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -183,8 +183,7 @@
         </menu_item_call>
          <menu_item_call
          label="Toolbar buttons..."
-         name="Toolbars"
-         shortcut="control|T">
+         name="Toolbars">
             <menu_item_call.on_click
              function="Floater.Toggle"
              parameter="toybox" />
@@ -223,7 +222,8 @@
      tear_off="true">
        <menu_item_check
          label="Conversations..."
-         name="Conversations">
+         name="Conversations"
+         shortcut="control|T">
             <menu_item_check.on_check
              function="Floater.IsOpen"
              parameter="im_container" />
@@ -240,7 +240,7 @@
              function="Floater.Visible"
              parameter="nearby_chat" />
             <menu_item_check.on_click
-             function="Floater.Toggle"
+             function="Floater.ToggleOrBringToFront"
              parameter="nearby_chat" />
         </menu_item_check>
         <menu_item_check