diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 17aecaf32fd81860635a48c03dcd1bac799d5844..47db990a372411e172137bb280326bebacef9810 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1009,6 +1009,16 @@ void LLTextBase::draw()
 void LLTextBase::setColor( const LLColor4& c )
 {
 	mFgColor = c;
+	//textsegments have own style property , 
+	//so we have to update it also to apply changes, EXT-4433
+	for(segment_set_t::iterator it = mSegments.begin(); it != mSegments.end(); it++)
+	{
+		LLTextSegment* segment = it->get(); 
+		if(segment)
+		{
+			segment->setColor(mFgColor);
+		}
+	}
 }
 
 //virtual 
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index c29a3a0035a3dbded4adbab335eb3bcb82389578..72d2e1aba08ee1bdc380c9413ce522446fbb5f0f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -10314,6 +10314,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>VoiceDefaultInternalLevel</key>
+    <map>
+      <key>Comment</key>
+      <string>Internal level of voice set by default. Is equivalent to 0.5 (from 0.0-1.0 range) external voice level (internal = 400 * external^2).</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>100</integer>
+    </map>
     <key>VoiceEarLocation</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 40c9bb6afabeedd4fcccbca94f16c8f1f350df78..bb14c41cec821d93c712a6bfd39898532f52c22d 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -263,18 +263,9 @@ bool LLAvatarActions::isCalling(const LLUUID &id)
 }
 
 //static
-bool LLAvatarActions::canCall(const LLUUID &id)
+bool LLAvatarActions::canCall()
 {
-	// For now we do not need to check whether passed UUID is ID of agent's friend.
-	// Use common check of Voice Client state.
-	{
-		// don't need to check online/offline status because "usual resident" (resident that is not a friend)
-		// can be only ONLINE. There is no way to see "usual resident" in OFFLINE status. If we see "usual
-		// resident" it automatically means that the resident is ONLINE. So to make a call to the "usual resident"
-		// we need to check only that "our" voice is enabled.
-		return LLVoiceClient::voiceEnabled();
-	}
-
+		return LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
 }
 
 // static
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index a4504ae679b946b513670d19731b7c9e35e0c88c..ebfd40b796fb7c3399287eb50dc316b402792e4d 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -129,10 +129,10 @@ class LLAvatarActions
 	static bool isCalling(const LLUUID &id);
 
 	/**
-	 * @return true if call to the resident can be made (resident is online and voice is enabled)
+	 * @return true if call to the resident can be made
 	 */
 
-	static bool canCall(const LLUUID &id);
+	static bool canCall();
 	/**
 	 * Invite avatar to a group.
 	 */	
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 66ab32f3e88bd599ac39c3d232bc75a0ffc3fecc..2bcd097717539f3bacdb033f78d2b90878474f4f 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -440,17 +440,17 @@ LLAvatarListItem::icon_color_map_t& LLAvatarListItem::getItemIconColorMap()
 // static
 void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
 {
+	//speaking indicator width + padding
+	S32 speaking_indicator_width = avatar_item->getRect().getWidth() - avatar_item->mSpeakingIndicator->getRect().mLeft;
+
 	//profile btn width + padding
-	S32 profile_btn_width = avatar_item->getRect().getWidth() - avatar_item->mProfileBtn->getRect().mLeft;
+	S32 profile_btn_width = avatar_item->mSpeakingIndicator->getRect().mLeft - avatar_item->mProfileBtn->getRect().mLeft;
 
 	//info btn width + padding
 	S32 info_btn_width = avatar_item->mProfileBtn->getRect().mLeft - avatar_item->mInfoBtn->getRect().mLeft;
 
-	//speaking indicator width + padding
-	S32 speaking_indicator_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mSpeakingIndicator->getRect().mLeft;
-
 	// last interaction time textbox width + padding
-	S32 last_interaction_time_width = avatar_item->mSpeakingIndicator->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
+	S32 last_interaction_time_width = avatar_item->mInfoBtn->getRect().mLeft - avatar_item->mLastInteractionTime->getRect().mLeft;
 
 	// icon width + padding
 	S32 icon_width = avatar_item->mAvatarName->getRect().mLeft - avatar_item->mAvatarIcon->getRect().mLeft;
@@ -462,9 +462,9 @@ void LLAvatarListItem::initChildrenWidths(LLAvatarListItem* avatar_item)
 	sChildrenWidths[--index] = icon_width;
 	sChildrenWidths[--index] = 0; // for avatar name we don't need its width, it will be calculated as "left available space"
 	sChildrenWidths[--index] = last_interaction_time_width;
-	sChildrenWidths[--index] = speaking_indicator_width;
 	sChildrenWidths[--index] = info_btn_width;
 	sChildrenWidths[--index] = profile_btn_width;
+	sChildrenWidths[--index] = speaking_indicator_width;
 }
 
 void LLAvatarListItem::updateChildren()
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index 479a4833cb94bb8bcfec844a9c866dbb3ccde582..61c0a8660e3f5e0fe9325c1e7739230bc49b6232 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -129,9 +129,9 @@ class LLAvatarListItem : public LLPanel, public LLFriendObserver
 	 * @see updateChildren()
 	 */
 	typedef enum e_avatar_item_child {
+		ALIC_SPEAKER_INDICATOR,
 		ALIC_PROFILE_BUTTON,
 		ALIC_INFO_BUTTON,
-		ALIC_SPEAKER_INDICATOR,
 		ALIC_INTERACTION_TIME,
 		ALIC_NAME,
 		ALIC_ICON,
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
index d4c8adadc64b2a6476a30db21a7b231f02100af6..d9df537e032057a823835bc82b3b394a7e49e5e8 100644
--- a/indra/newview/llcallfloater.cpp
+++ b/indra/newview/llcallfloater.cpp
@@ -43,6 +43,7 @@
 #include "llavatariconctrl.h"
 #include "llavatarlist.h"
 #include "llbottomtray.h"
+#include "lldraghandle.h"
 #include "llimfloater.h"
 #include "llfloaterreg.h"
 #include "llparticipantlist.h"
@@ -158,6 +159,11 @@ BOOL LLCallFloater::postBuild()
 
 	connectToChannel(LLVoiceChannel::getCurrentVoiceChannel());
 
+	setIsChrome(true);
+	//chrome="true" hides floater caption 
+	if (mDragHandle)
+		mDragHandle->setTitleVisible(TRUE);
+
 	return TRUE;
 }
 
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index a46cd84b60876e775437a28223d8e0567e12ded6..d6a7edee5b4742c10b88fb97ba5b563ceaf30d0d 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -550,8 +550,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_
 		if (mLastFromName == chat.mFromName 
 			&& mLastFromID == chat.mFromID
 			&& mLastMessageTime.notNull() 
-			&& (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0 
-			)
+			&& (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0
+			&& mLastMessageTimeStr.size() == chat.mTimeStr.size())  //*HACK to distinguish between current and previous chat session's histories
 		{
 			view = getSeparator();
 			p.top_pad = mTopSeparatorPad;
@@ -585,6 +585,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const bool use_plain_text_
 		mLastFromName = chat.mFromName;
 		mLastFromID = chat.mFromID;
 		mLastMessageTime = new_message_time;
+		mLastMessageTimeStr = chat.mTimeStr;
 	}
 
 	std::string message = irc_me ? chat.mText.substr(3) : chat.mText;
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index f2d403f63932ca64572514525c757fc9333bb2de..c2c60e60cf9fd64b8e07fec0c97c013574dbde16 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -125,6 +125,8 @@ class LLChatHistory : public LLUICtrl
 		std::string mLastFromName;
 		LLUUID mLastFromID;
 		LLDate mLastMessageTime;
+		std::string mLastMessageTimeStr;
+
 		std::string mMessageHeaderFilename;
 		std::string mMessageSeparatorFilename;
 
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index 29f415bd43904b5288ab32731908e34d4ea080e3..c71764c2e54d086464f82ad29815bde54f845c2d 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -75,7 +75,7 @@ LLFloaterGroupPicker::~LLFloaterGroupPicker()
 void LLFloaterGroupPicker::setPowersMask(U64 powers_mask)
 {
 	mPowersMask = powers_mask;
-	postBuild();
+	init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID(), mPowersMask);
 }
 
 
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index fc036cb354851b8daa1feed7eede8ad9d16a73ee..60c15c253d75ed39b5696e8c90b4c9f3c71ee710 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1435,6 +1435,7 @@ BOOL LLPanelPreference::postBuild()
 		media_enabled_ctrl->set(enabled);
 		media_enabled_ctrl->setTentative(!(video_enabled == music_enabled == media_enabled));
 		getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(enabled);
+		getChild<LLCheckBoxCtrl>("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2));
 	}
 	
 	apply();
@@ -1485,6 +1486,14 @@ void LLPanelPreference::saveSettings()
 	}	
 }
 
+void LLPanelPreference::showFriendsOnlyWarning(LLUICtrl* checkbox, const LLSD& value)
+{
+	if (checkbox && checkbox->getValue())
+	{
+		LLNotificationsUtil::add("FriendsAndGroupsOnly");
+	}
+}
+
 void LLPanelPreference::cancel()
 {
 	for (control_values_map_t::iterator iter =  mSavedValues.begin();
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 6f382620ee034577086607db56b002d6156b5094..8b02a4049d1f2a5d15d05c96ea82b8333bc289b8 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -166,6 +166,9 @@ class LLPanelPreference : public LLPanel
 	virtual void saveSettings();
 	
 private:
+	//for "Only friends and groups can call or IM me"
+	static void showFriendsOnlyWarning(LLUICtrl*, const LLSD&);
+
 	typedef std::map<LLControlVariable*, LLSD> control_values_map_t;
 	control_values_map_t mSavedValues;
 
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 2efae0c8dbf8d38b6f4cbaca88b9e20a9f53dd38..4a1eb51dbe9db149c91e08d2f268ffdd529796f0 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -324,7 +324,7 @@ void LLFloaterReporter::setFromAvatar(const LLUUID& avatar_id, const std::string
 
 	std::string avatar_link = LLSLURL::buildCommand("agent", mObjectID, "inspect");
 	childSetText("owner_name", avatar_link);
-	childSetText("object_name", avatar_name); // name
+	childSetText("object_name", avatar_name);
 	childSetText("abuser_name_edit", avatar_name);
 }
 
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index e75d35bea411f5665b5b98b69436a08cd1c3283c..e01709aa3a0e625561a08bb23d1f29900c9da7e3 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -48,6 +48,7 @@
 #include "lltextutil.h"
 #include "llviewercontrol.h"	// for gSavedSettings
 #include "llviewermenu.h"		// for gMenuHolder
+#include "llvoiceclient.h"
 
 static LLDefaultChildRegistry::Register<LLGroupList> r("group_list");
 S32 LLGroupListItem::sIconWidth = 0;
@@ -271,6 +272,9 @@ bool LLGroupList::onContextMenuItemEnable(const LLSD& userdata)
 	if (userdata.asString() == "activate")
 		return gAgent.getGroupID() != selected_group_id;
 
+	if (userdata.asString() == "call")
+		return LLVoiceClient::voiceEnabled()&&gVoiceClient->voiceWorking();
+
 	return real_group_selected;
 }
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index c2a7969c0d05a880cd36c6b16befbbd5efc3e0bf..32b0cbff3899d398e6630750113196bea476d4d2 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1680,6 +1680,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
 	case LLVoiceChannel::STATE_ERROR :
 		getChild<LLTextBox>("noanswer")->setVisible(true);
 		getChild<LLButton>("Cancel")->setVisible(false);
+		setCanClose(true);
 		mLifetimeTimer.start();
 		break;
 	case LLVoiceChannel::STATE_HUNG_UP :
@@ -1692,6 +1693,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
 			getChild<LLTextBox>("nearby")->setVisible(true);
 		}
 		getChild<LLButton>("Cancel")->setVisible(false);
+		setCanClose(true);
 		mLifetimeTimer.start();
 	}
 
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 7ee4c64f8fb57d1d41582ca6a1b3efae57f50fc5..c1666f566674af9148557fb2641c0e76f2cc4a1c 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -52,23 +52,15 @@
 
 #include <boost/tokenizer.hpp>
 
-#include "llcrc.h"
-#include "lldir.h"
 #include "lldispatcher.h"
-#include "llsdserialize.h"
 #include "llxfermanager.h"
-#include "message.h"
 
 #include "llagent.h"
 #include "llviewergenericmessage.h"	// for gGenericDispatcher
-#include "llviewerwindow.h"
 #include "llworld.h" //for particle system banning
-#include "llchat.h"
 #include "llimpanel.h"
 #include "llimview.h"
 #include "llnotifications.h"
-#include "lluistring.h"
-#include "llviewerobject.h" 
 #include "llviewerobjectlist.h"
 #include "lltrans.h"
 
@@ -219,61 +211,17 @@ LLMuteList* LLMuteList::getInstance()
 // LLMuteList()
 //-----------------------------------------------------------------------------
 LLMuteList::LLMuteList() :
-	mIsLoaded(FALSE),
-	mUserVolumesLoaded(FALSE)
+	mIsLoaded(FALSE)
 {
 	gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList);
 }
 
-void LLMuteList::loadUserVolumes()
-{
-	// call once, after LLDir::setLindenUserDir() has been called
-	if (mUserVolumesLoaded)
-		return;
-	mUserVolumesLoaded = TRUE;
-	
-	// load per-resident voice volume information
-	// conceptually, this is part of the mute list information, although it is only stored locally
-	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "volume_settings.xml");
-
-	LLSD settings_llsd;
-	llifstream file;
-	file.open(filename);
-	if (file.is_open())
-	{
-		LLSDSerialize::fromXML(settings_llsd, file);
-	}
-
-	for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
-		 iter != settings_llsd.endMap(); ++iter)
-	{
-		mUserVolumeSettings.insert(std::make_pair(LLUUID(iter->first), (F32)iter->second.asReal()));
-	}
-}
-
 //-----------------------------------------------------------------------------
 // ~LLMuteList()
 //-----------------------------------------------------------------------------
 LLMuteList::~LLMuteList()
 {
-	// If we quit from the login screen we will not have an SL account
-	// name.  Don't try to save, otherwise we'll dump a file in
-	// C:\Program Files\SecondLife\ or similar. JC
-	std::string user_dir = gDirUtilp->getLindenUserDir();
-	if (!user_dir.empty())
-	{
-		std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "volume_settings.xml");
-		LLSD settings_llsd;
-
-		for(user_volume_map_t::iterator iter = mUserVolumeSettings.begin(); iter != mUserVolumeSettings.end(); ++iter)
-		{
-			settings_llsd[iter->first.asString()] = iter->second;
-		}
 
-		llofstream file;
-		file.open(filename);
-		LLSDSerialize::toPrettyXML(settings_llsd, file);
-	}
 }
 
 BOOL LLMuteList::isLinden(const std::string& name) const
@@ -715,8 +663,6 @@ BOOL LLMuteList::isMuted(const LLUUID& id, const std::string& name, U32 flags) c
 //-----------------------------------------------------------------------------
 void LLMuteList::requestFromServer(const LLUUID& agent_id)
 {
-	loadUserVolumes();
-	
 	std::string agent_id_string;
 	std::string filename;
 	agent_id.toString(agent_id_string);
@@ -751,26 +697,6 @@ void LLMuteList::cache(const LLUUID& agent_id)
 	}
 }
 
-void LLMuteList::setSavedResidentVolume(const LLUUID& id, F32 volume)
-{
-	// store new value in volume settings file
-	mUserVolumeSettings[id] = volume;
-}
-
-F32 LLMuteList::getSavedResidentVolume(const LLUUID& id)
-{
-	const F32 DEFAULT_VOLUME = 0.5f;
-
-	user_volume_map_t::iterator found_it = mUserVolumeSettings.find(id);
-	if (found_it != mUserVolumeSettings.end())
-	{
-		return found_it->second;
-	}
-	//FIXME: assumes default, should get this from somewhere
-	return DEFAULT_VOLUME;
-}
-
-
 //-----------------------------------------------------------------------------
 // Static message handlers
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 409b637bf2d6c3dbfce828af103c652c3bda203f..e1e81a24b4c353e8cb7ac2e8e4c3f39c654856b3 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -127,12 +127,7 @@ class LLMuteList : public LLSingleton<LLMuteList>
 	// call this method on logout to save everything.
 	void cache(const LLUUID& agent_id);
 
-	void setSavedResidentVolume(const LLUUID& id, F32 volume);
-	F32 getSavedResidentVolume(const LLUUID& id);
-
 private:
-	void loadUserVolumes();
-	
 	BOOL loadFromFile(const std::string& filename);
 	BOOL saveToFile(const std::string& filename);
 
@@ -179,12 +174,8 @@ class LLMuteList : public LLSingleton<LLMuteList>
 	observer_set_t mObservers;
 
 	BOOL mIsLoaded;
-	BOOL mUserVolumesLoaded;
 
 	friend class LLDispatchEmptyMuteList;
-
-	typedef std::map<LLUUID, F32> user_volume_map_t; 
-	user_volume_map_t mUserVolumeSettings;
 };
 
 class LLMuteListObserver
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index a7c1e73328e6e1e3b6908f7ac8ffb408b0033c92..0a8d020b4fffeaf92defc9c40f19a7cb0be7ad3b 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -101,6 +101,11 @@ BOOL LLNearbyChat::postBuild()
 			getDockTongue(), LLDockControl::TOP, boost::bind(&LLNearbyChat::getAllowedRect, this, _1)));
 	}
 
+	setIsChrome(true);
+	//chrome="true" hides floater caption 
+	if (mDragHandle)
+		mDragHandle->setTitleVisible(TRUE);
+
 	return true;
 }
 
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 85e95ca1d65bcc502c04795c2e853ba8fb5d9eeb..fe5b20813ac7562c535d996400c553a0036300d7 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -165,6 +165,8 @@ BOOL LLPanelAvatarNotes::postBuild()
 	resetControls();
 	resetData();
 
+	gVoiceClient->addObserver((LLVoiceClientStatusObserver*)this);
+
 	return TRUE;
 }
 
@@ -337,6 +339,8 @@ LLPanelAvatarNotes::~LLPanelAvatarNotes()
 	if(getAvatarId().notNull())
 	{
 		LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+		if(LLVoiceClient::getInstance())
+			LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
 	}
 }
 
@@ -346,6 +350,17 @@ void LLPanelAvatarNotes::changed(U32 mask)
 	childSetEnabled("teleport", LLAvatarTracker::instance().isBuddyOnline(getAvatarId()));
 }
 
+// virtual
+void LLPanelAvatarNotes::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+	{
+		return;
+	}
+
+	childSetEnabled("call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
+}
+
 void LLPanelAvatarNotes::setAvatarId(const LLUUID& id)
 {
 	if(id.notNull())
@@ -437,7 +452,6 @@ void LLPanelProfileTab::updateButtons()
 
 	bool enable_map_btn = is_avatar_online && gAgent.isGodlike() || is_agent_mappable(getAvatarId());
 	childSetEnabled("show_on_map_btn", enable_map_btn);
-	childSetEnabled("call", LLAvatarActions::canCall(getAvatarId()));
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -485,6 +499,8 @@ BOOL LLPanelAvatarProfile::postBuild()
 	pic = getChild<LLTextureCtrl>("real_world_pic");
 	pic->setFallbackImageName("default_profile_picture.j2c");
 
+	gVoiceClient->addObserver((LLVoiceClientStatusObserver*)this);
+
 	resetControls();
 	resetData();
 
@@ -568,8 +584,6 @@ void LLPanelAvatarProfile::processProfileProperties(const LLAvatarData* avatar_d
 
 	fillPartnerData(avatar_data);
 
-	fillOnlineStatus(avatar_data);
-
 	fillAccountStatus(avatar_data);
 }
 
@@ -637,21 +651,6 @@ void LLPanelAvatarProfile::fillPartnerData(const LLAvatarData* avatar_data)
 	}
 }
 
-void LLPanelAvatarProfile::fillOnlineStatus(const LLAvatarData* avatar_data)
-{
-	bool online = avatar_data->flags & AVATAR_ONLINE;
-	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!
-		online = LLAvatarTracker::instance().isBuddyOnline(avatar_data->avatar_id);
-	}
-	childSetValue("online_status", online ?
-		"Online" : "Offline");
-	childSetColor("online_status", online ? 
-		LLColor4::green : LLColor4::red);
-}
-
 void LLPanelAvatarProfile::fillAccountStatus(const LLAvatarData* avatar_data)
 {
 	LLStringUtil::format_map_t args;
@@ -757,6 +756,8 @@ LLPanelAvatarProfile::~LLPanelAvatarProfile()
 	if(getAvatarId().notNull())
 	{
 		LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
+		if(LLVoiceClient::getInstance())
+			LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
 	}
 }
 
@@ -766,6 +767,17 @@ void LLPanelAvatarProfile::changed(U32 mask)
 	childSetEnabled("teleport", LLAvatarTracker::instance().isBuddyOnline(getAvatarId()));
 }
 
+// virtual
+void LLPanelAvatarProfile::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+	{
+		return;
+	}
+
+	childSetEnabled("call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
+}
+
 void LLPanelAvatarProfile::setAvatarId(const LLUUID& id)
 {
 	if(id.notNull())
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index 22efa5dc351917757c1df2e7991b606cfdb29fa7..ce59f1e93d20b7080345be6062506cb6ff1f8c79 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -36,6 +36,7 @@
 #include "llpanel.h"
 #include "llavatarpropertiesprocessor.h"
 #include "llcallingcard.h"
+#include "llvoiceclient.h"
 
 class LLComboBox;
 class LLLineEditor;
@@ -122,6 +123,7 @@ class LLPanelProfileTab
 class LLPanelAvatarProfile
 	: public LLPanelProfileTab
 	, public LLFriendObserver
+	, public LLVoiceClientStatusObserver
 {
 public:
 	LLPanelAvatarProfile();
@@ -134,6 +136,10 @@ class LLPanelAvatarProfile
 	 */
 	virtual void changed(U32 mask);
 
+	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
+	// button when voice is available
+	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
 	/*virtual*/ void setAvatarId(const LLUUID& id);
 
 	/**
@@ -171,11 +177,6 @@ class LLPanelAvatarProfile
 	 */
 	virtual void fillPartnerData(const LLAvatarData* avatar_data);
 
-	/**
-	 * Fills Avatar's online status.
-	 */
-	virtual void fillOnlineStatus(const LLAvatarData* avatar_data);
-
 	/**
 	 * Fills account status.
 	 */
@@ -257,6 +258,7 @@ class LLPanelMyProfile
 class LLPanelAvatarNotes 
 	: public LLPanelProfileTab
 	, public LLFriendObserver
+	, public LLVoiceClientStatusObserver
 {
 public:
 	LLPanelAvatarNotes();
@@ -269,6 +271,10 @@ class LLPanelAvatarNotes
 	 */
 	virtual void changed(U32 mask);
 
+	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
+	// button when voice is available
+	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
 	/*virtual*/ void onOpen(const LLSD& key);
 
 	/*virtual*/ BOOL postBuild();
diff --git a/indra/newview/llpanelgroup.cpp b/indra/newview/llpanelgroup.cpp
index c30ef3221d4f43bf47a5ba21a5c434b11fbdce42..1d447a22d73ca102d022ecace49c9b6ebdd2ce28 100644
--- a/indra/newview/llpanelgroup.cpp
+++ b/indra/newview/llpanelgroup.cpp
@@ -101,6 +101,8 @@ LLPanelGroup::LLPanelGroup()
 LLPanelGroup::~LLPanelGroup()
 {
 	LLGroupMgr::getInstance()->removeObserver(this);
+	if(LLVoiceClient::getInstance())
+		LLVoiceClient::getInstance()->removeObserver(this);
 }
 
 void LLPanelGroup::onOpen(const LLSD& key)
@@ -188,6 +190,8 @@ BOOL LLPanelGroup::postBuild()
 
 	if(panel_general)
 		panel_general->setupCtrls(this);
+
+	gVoiceClient->addObserver(this);
 	
 	return TRUE;
 }
@@ -300,6 +304,17 @@ void LLPanelGroup::changed(LLGroupChange gc)
 	update(gc);
 }
 
+// virtual
+void LLPanelGroup::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+	{
+		return;
+	}
+
+	childSetEnabled("btn_call", LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking());
+}
+
 void LLPanelGroup::notifyObservers()
 {
 	changed(GC_ALL);
@@ -356,6 +371,13 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
 	for(std::vector<LLPanelGroupTab* >::iterator it = mTabs.begin();it!=mTabs.end();++it)
 		(*it)->setGroupID(group_id);
 
+	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
+	if(gdatap)
+	{
+		childSetValue("group_name", gdatap->mName);
+		childSetToolTip("group_name",gdatap->mName);
+	}
+
 	LLButton* button_apply = findChild<LLButton>("btn_apply");
 	LLButton* button_refresh = findChild<LLButton>("btn_refresh");
 	LLButton* button_create = findChild<LLButton>("btn_create");
@@ -457,17 +479,6 @@ void LLPanelGroup::setGroupID(const LLUUID& group_id)
 	}
 
 	reposButtons();
-
-	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mID);
-
-	if(gdatap)
-	{
-		childSetValue("group_name", gdatap->mName);
-		childSetToolTip("group_name",gdatap->mName);
-		
-		//group data is already present, call update manually
-		update(GC_ALL);
-	}
 }
 
 bool LLPanelGroup::apply(LLPanelGroupTab* tab)
diff --git a/indra/newview/llpanelgroup.h b/indra/newview/llpanelgroup.h
index 7ea5e67b44f30be8911de4ffbb0e1f133076e0d3..8c846956771348b370ce399778ea18cb74774cbf 100644
--- a/indra/newview/llpanelgroup.h
+++ b/indra/newview/llpanelgroup.h
@@ -35,6 +35,7 @@
 #include "llgroupmgr.h"
 #include "llpanel.h"
 #include "lltimer.h"
+#include "llvoiceclient.h"
 
 struct LLOfferInfo;
 
@@ -47,7 +48,8 @@ class LLAgent;
 
 
 class LLPanelGroup : public LLPanel,
-					 public LLGroupMgrObserver 
+					 public LLGroupMgrObserver,
+					 public LLVoiceClientStatusObserver
 {
 public:
 	LLPanelGroup();
@@ -64,6 +66,10 @@ class LLPanelGroup : public LLPanel,
 	// Group manager observer trigger.
 	virtual void changed(LLGroupChange gc);
 
+	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
+	// button when voice is available
+	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
 	void showNotice(const std::string& subject,
 					const std::string& message,
 					const bool& has_inventory,
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index a334eb9d6804964517f45f1df76c1aba89d77b3d..ff1e43b52688dada8ca5522c41993f5d882a96d4 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -64,21 +64,52 @@ void LLPanelChatControlPanel::onOpenVoiceControlsClicked()
 	LLFloaterReg::showInstance("voice_controls");
 }
 
+void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+	{
+		return;
+	}
+
+	updateCallButton();
+}
+
 void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
 {
 	updateButtons(new_state >= LLVoiceChannel::STATE_CALL_STARTED);
 }
 
+void LLPanelChatControlPanel::updateCallButton()
+{
+	// hide/show call button
+	bool voice_enabled = LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
+
+	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId);
+	if (!session) return;
+
+	bool session_initialized = session->mSessionInitialized;
+	bool callback_enabled = session->mCallBackEnabled;
+
+	BOOL enable_connect = session_initialized
+		&& voice_enabled
+		&& callback_enabled;
+	childSetEnabled("call_btn", enable_connect);
+}
+
 void LLPanelChatControlPanel::updateButtons(bool is_call_started)
 {
 	childSetVisible("end_call_btn_panel", is_call_started);
 	childSetVisible("voice_ctrls_btn_panel", is_call_started);
 	childSetVisible("call_btn_panel", ! is_call_started);
+	updateCallButton();
+	
 }
 
 LLPanelChatControlPanel::~LLPanelChatControlPanel()
 {
 	mVoiceChannelStateChangeConnection.disconnect();
+	if(LLVoiceClient::getInstance())
+		LLVoiceClient::getInstance()->removeObserver(this);
 }
 
 BOOL LLPanelChatControlPanel::postBuild()
@@ -87,26 +118,9 @@ BOOL LLPanelChatControlPanel::postBuild()
 	childSetAction("end_call_btn", boost::bind(&LLPanelChatControlPanel::onEndCallButtonClicked, this));
 	childSetAction("voice_ctrls_btn", boost::bind(&LLPanelChatControlPanel::onOpenVoiceControlsClicked, this));
 
-	return TRUE;
-}
-
-void LLPanelChatControlPanel::draw()
-{
-	// hide/show start call and end call buttons
-	bool voice_enabled = LLVoiceClient::voiceEnabled();
-
-	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId);
-	if (!session) return;
+	gVoiceClient->addObserver(this);
 
-	bool session_initialized = session->mSessionInitialized;
-	bool callback_enabled = session->mCallBackEnabled;
-
-	BOOL enable_connect = session_initialized
-		&& voice_enabled
-		&& callback_enabled;
-	childSetEnabled("call_btn", enable_connect);
-
-	LLPanel::draw();
+	return TRUE;
 }
 
 void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
@@ -266,6 +280,8 @@ void LLPanelGroupControlPanel::draw()
 	// Need to resort the participant list if it's in sort by recent speaker order.
 	if (mParticipantList)
 		mParticipantList->updateRecentSpeakersOrder();
+	//* TODO: find better way to properly enable call button for group and remove this call from draw()
+	updateCallButton();
 	LLPanelChatControlPanel::draw();
 }
 
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
index 25fdf944c925a2cb81ff7e941ebc3bbbe40eb9b0..3ab505a084d914487437e7ebfd6136222199f4ce 100644
--- a/indra/newview/llpanelimcontrolpanel.h
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -39,7 +39,9 @@
 
 class LLParticipantList;
 
-class LLPanelChatControlPanel : public LLPanel
+class LLPanelChatControlPanel 
+	: public LLPanel
+	, public LLVoiceClientStatusObserver
 {
 public:
 	LLPanelChatControlPanel() :
@@ -47,15 +49,21 @@ class LLPanelChatControlPanel : public LLPanel
 	~LLPanelChatControlPanel();
 
 	virtual BOOL postBuild();
-	virtual void draw();
 
 	void onCallButtonClicked();
 	void onEndCallButtonClicked();
 	void onOpenVoiceControlsClicked();
 
+	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
+	// button when voice is available
+	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
+
 	virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
 
 	void updateButtons(bool is_call_started);
+	
+	// Enables/disables call button depending on voice availability
+	void updateCallButton();
 
 	virtual void setSessionId(const LLUUID& session_id);
 	const LLUUID& getSessionId() { return mSessionId; }
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index ece93125b322bc87e5d2552771a50f8a1b3af848..0f0fb4b94ea34b854318e07b06a11c88a6b84fdb 100644
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -198,8 +198,6 @@ void LLPanelMyProfileEdit::processProfileProperties(const LLAvatarData* avatar_d
 {
 	fillCommonData(avatar_data);
 
-	fillOnlineStatus(avatar_data);
-
 	fillPartnerData(avatar_data);
 
 	fillAccountStatus(avatar_data);
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index c14b282488c72c479d10df46fb91c315425a24b2..b01cdcc832b25bd4dd4c0ae96cc7626d23be4d14 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -462,6 +462,9 @@ LLPanelPeople::~LLPanelPeople()
 	delete mFriendListUpdater;
 	delete mRecentListUpdater;
 
+	if(LLVoiceClient::getInstance())
+		LLVoiceClient::getInstance()->removeObserver(this);
+
 	LLView::deleteViewByHandle(mGroupPlusMenuHandle);
 	LLView::deleteViewByHandle(mNearbyViewSortMenuHandle);
 	LLView::deleteViewByHandle(mFriendsViewSortMenuHandle);
@@ -612,6 +615,8 @@ BOOL LLPanelPeople::postBuild()
 	if(recent_view_sort)
 		mRecentViewSortMenuHandle  = recent_view_sort->getHandle();
 
+	gVoiceClient->addObserver(this);
+
 	// call this method in case some list is empty and buttons can be in inconsistent state
 	updateButtons();
 
@@ -621,6 +626,17 @@ BOOL LLPanelPeople::postBuild()
 	return TRUE;
 }
 
+// virtual
+void LLPanelPeople::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
+	{
+		return;
+	}
+	
+	updateButtons();
+}
+
 void LLPanelPeople::updateFriendList()
 {
 	if (!mOnlineFriendList || !mAllFriendList)
@@ -775,41 +791,20 @@ void LLPanelPeople::updateButtons()
 		}
 	}
 
+	bool enable_calls = gVoiceClient->voiceWorking() && gVoiceClient->voiceEnabled();
+
 	buttonSetEnabled("teleport_btn",		friends_tab_active && item_selected && isFriendOnline(selected_uuids.front()));
 	buttonSetEnabled("view_profile_btn",	item_selected);
 	buttonSetEnabled("im_btn",				multiple_selected); // allow starting the friends conference for multiple selection
-	buttonSetEnabled("call_btn",			multiple_selected && canCall());
+	buttonSetEnabled("call_btn",			multiple_selected && enable_calls);
 	buttonSetEnabled("share_btn",			item_selected); // not implemented yet
 
 	bool none_group_selected = item_selected && selected_id.isNull();
 	buttonSetEnabled("group_info_btn", !none_group_selected);
-	buttonSetEnabled("group_call_btn", !none_group_selected);
+	buttonSetEnabled("group_call_btn", !none_group_selected && enable_calls);
 	buttonSetEnabled("chat_btn", !none_group_selected);
 }
 
-bool LLPanelPeople::canCall()
-{
-	std::vector<LLUUID> selected_uuids;
-	getCurrentItemIDs(selected_uuids);
-
-	bool result = false;
-
-	std::vector<LLUUID>::const_iterator
-		id = selected_uuids.begin(),
-		uuids_end = selected_uuids.end();
-
-	for (;id != uuids_end; ++id)
-	{
-		if (LLAvatarActions::canCall(*id))
-		{
-			result = true;
-			break;
-		}
-	}
-
-	return result;
-}
-
 std::string LLPanelPeople::getActiveTabName() const
 {
 	return mTabContainer->getCurrentPanel()->getName();
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 7580fdbeeffb122545070be93f6f26705ade4810..6d3d43615683373faee3b2c1a04b245d441de475 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -36,13 +36,16 @@
 #include <llpanel.h>
 
 #include "llcallingcard.h" // for avatar tracker
+#include "llvoiceclient.h"
 
 class LLFilterEditor;
 class LLTabContainer;
 class LLAvatarList;
 class LLGroupList;
 
-class LLPanelPeople : public LLPanel
+class LLPanelPeople 
+	: public LLPanel
+	, public LLVoiceClientStatusObserver
 {
 	LOG_CLASS(LLPanelPeople);
 public:
@@ -52,6 +55,9 @@ class LLPanelPeople : public LLPanel
 	/*virtual*/ BOOL 	postBuild();
 	/*virtual*/ void	onOpen(const LLSD& key);
 	/*virtual*/ bool	notifyChildren(const LLSD& info);
+	// Implements LLVoiceClientStatusObserver::onChange() to enable call buttons
+	// when voice is available
+	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
 
 	// internals
 	class Updater;
@@ -73,7 +79,6 @@ class LLPanelPeople : public LLPanel
 
 	bool					isFriendOnline(const LLUUID& id);
 	bool					isItemsFreeOfFriends(const std::vector<LLUUID>& uuids);
-	bool 					canCall();
 
 	void					updateButtons();
 	std::string				getActiveTabName() const;
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index c1c10e6022091db4786d5b2683ebcdc399b43aa7..d9651a60450abfed328b95dbfc36b91ebfbc4393 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -183,20 +183,7 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
 	}
 	else if (item == std::string("can_call"))
 	{
-		bool result = false;
-		std::vector<LLUUID>::const_iterator
-			id = mUUIDs.begin(),
-			uuids_end = mUUIDs.end();
-
-		for (;id != uuids_end; ++id)
-		{
-			if (LLAvatarActions::canCall(*id))
-			{
-				result = true;
-				break;
-			}
-		}
-		return result;
+		return LLAvatarActions::canCall();
 	}
 	return false;
 }
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index a4f0e55a93258b36d1f0427ed823d844356e27aa..a8a9717750ba5d9d275084b5328e89af51d43b97 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -384,6 +384,10 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 	// Otherwise stop using land selection and deselect land.
 	if (mPlaceInfoType == AGENT_INFO_TYPE)
 	{
+		// We don't know if we are already added to LLViewerParcelMgr observers list
+		// so try to remove observer not to add an extra one.
+		parcel_mgr->removeObserver(mParcelObserver);
+
 		parcel_mgr->addObserver(mParcelObserver);
 		parcel_mgr->selectParcelAt(gAgent.getPositionGlobal());
 	}
@@ -898,6 +902,8 @@ void LLPanelPlaces::changedParcelSelection()
 	if (!region || !parcel)
 		return;
 
+	LLVector3d prev_pos_global = mPosGlobal;
+
 	// If agent is inside the selected parcel show agent's region<X, Y, Z>,
 	// otherwise show region<X, Y, Z> of agent's selection point.
 	bool is_current_parcel = is_agent_in_selected_parcel(parcel);
@@ -914,7 +920,13 @@ void LLPanelPlaces::changedParcelSelection()
 		}
 	}
 
-	mPlaceProfile->resetLocation();
+	// Reset location info only if global position is changed
+	// to reduce unnecessary text and icons updates.
+	if (prev_pos_global != mPosGlobal)
+	{
+		mPlaceProfile->resetLocation();
+	}
+
 	mPlaceProfile->displaySelectedParcelInfo(parcel, region, mPosGlobal, is_current_parcel);
 
 	updateVerbs();
diff --git a/indra/newview/llpanelprofileview.cpp b/indra/newview/llpanelprofileview.cpp
index 7832f63e6a698e9f8f302b6e00fde196043c97df..044036ea50e6b46d1d8437af0e2f619c71c998bd 100644
--- a/indra/newview/llpanelprofileview.cpp
+++ b/indra/newview/llpanelprofileview.cpp
@@ -101,8 +101,6 @@ void LLPanelProfileView::onOpen(const LLSD& key)
 		id = key["id"];
 	}
 
-	// subscribe observer to get online status. Request will be sent by LLPanelAvatarProfile itself
-	mAvatarStatusObserver->subscribe();
 	if(id.notNull() && getAvatarId() != id)
 	{
 		setAvatarId(id);
@@ -111,12 +109,9 @@ void LLPanelProfileView::onOpen(const LLSD& key)
 	// Update the avatar name.
 	gCacheName->get(getAvatarId(), FALSE,
 		boost::bind(&LLPanelProfileView::onAvatarNameCached, this, _1, _2, _3, _4));
-/*
-// disable this part of code according to EXT-2022. See processOnlineStatus
-	// status should only show if viewer has permission to view online/offline. EXT-453 
-	mStatusText->setVisible(isGrantedToSeeOnlineStatus());
+
 	updateOnlineStatus();
-*/
+
 
 	LLPanelProfile::onOpen(key);
 }
@@ -164,27 +159,43 @@ bool LLPanelProfileView::isGrantedToSeeOnlineStatus()
 	// *NOTE: GRANT_ONLINE_STATUS is always set to false while changing any other status.
 	// When avatar disallow me to see her online status processOfflineNotification Message is received by the viewer
 	// see comments for ChangeUserRights template message. EXT-453.
-//	return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);
-	return true;
+	// If GRANT_ONLINE_STATUS flag is changed it will be applied when viewer restarts. EXT-3880
+	return relationship->isRightGrantedFrom(LLRelationship::GRANT_ONLINE_STATUS);
 }
 
+// method was disabled according to EXT-2022. Re-enabled & improved according to EXT-3880
 void LLPanelProfileView::updateOnlineStatus()
 {
+	// set text box visible to show online status for non-friends who has not set in Preferences
+	// "Only Friends & Groups can see when I am online"
+	mStatusText->setVisible(TRUE);
+
 	const LLRelationship* relationship = LLAvatarTracker::instance().getBuddyInfo(getAvatarId());
 	if (NULL == relationship)
-		return;
+	{
+		// this is non-friend avatar. Status will be updated from LLAvatarPropertiesProcessor.
+		// in LLPanelProfileView::processOnlineStatus()
 
-	bool online = relationship->isOnline();
+		// subscribe observer to get online status. Request will be sent by LLPanelAvatarProfile itself.
+		// do not subscribe for friend avatar because online status can be wrong overridden
+		// via LLAvatarData::flags if Preferences: "Only Friends & Groups can see when I am online" is set.
+		mAvatarStatusObserver->subscribe();
+		return;
+	}
+	// For friend let check if he allowed me to see his status
 
-	std::string status = getString(online ? "status_online" : "status_offline");
+	// status should only show if viewer has permission to view online/offline. EXT-453, EXT-3880
+	mStatusText->setVisible(isGrantedToSeeOnlineStatus());
 
-	mStatusText->setValue(status);
+	bool online = relationship->isOnline();
+	processOnlineStatus(online);
 }
 
 void LLPanelProfileView::processOnlineStatus(bool online)
 {
-	mAvatarIsOnline = online;
-	mStatusText->setVisible(online);
+	std::string status = getString(online ? "status_online" : "status_offline");
+
+	mStatusText->setValue(status);
 }
 
 void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string& first_name, const std::string& last_name, BOOL is_group)
@@ -193,17 +204,4 @@ void LLPanelProfileView::onAvatarNameCached(const LLUUID& id, const std::string&
 	getChild<LLUICtrl>("user_name", FALSE)->setValue(first_name + " " + last_name);
 }
 
-void LLPanelProfileView::togglePanel(LLPanel* panel, const LLSD& key)
-{
-	// *TODO: unused method?
-
-	LLPanelProfile::togglePanel(panel);
-	if(FALSE == panel->getVisible())
-	{
-		// LLPanelProfile::togglePanel shows/hides all children,
-		// we don't want to display online status for non friends, so re-hide it here
-		mStatusText->setVisible(mAvatarIsOnline);
-	}
-}
-
 // EOF
diff --git a/indra/newview/llpanelprofileview.h b/indra/newview/llpanelprofileview.h
index 5dc617d4a04e568b04a3f81114f8e4c2c2f59a6a..9b87e146a86a4b10f8c1a2b7d669d19232250f14 100644
--- a/indra/newview/llpanelprofileview.h
+++ b/indra/newview/llpanelprofileview.h
@@ -64,8 +64,6 @@ class LLPanelProfileView : public LLPanelProfile
 	
 	/*virtual*/ BOOL postBuild();
 
-	/*virtual*/ void togglePanel(LLPanel* panel, const LLSD& key = LLSD());
-
 	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
 						   BOOL drop, EDragAndDropType cargo_type,
 						   void *cargo_data, EAcceptance *accept,
@@ -81,8 +79,21 @@ class LLPanelProfileView : public LLPanelProfile
 protected:
 
 	void onBackBtnClick();
-	bool isGrantedToSeeOnlineStatus(); // deprecated after EXT-2022 is implemented
-	void updateOnlineStatus(); // deprecated after EXT-2022 is implemented
+	bool isGrantedToSeeOnlineStatus();
+
+	/**
+	 * Displays avatar's online status if possible.
+	 *
+	 * Requirements from EXT-3880:
+	 * For friends:
+	 * - Online when online and privacy settings allow to show
+	 * - Offline when offline and privacy settings allow to show
+	 * - Else: nothing
+	 * For other avatars:
+	 *  - Online when online and was not set in Preferences/"Only Friends & Groups can see when I am online"
+	 *  - Else: Offline
+	 */
+	void updateOnlineStatus();
 	void processOnlineStatus(bool online);
 
 private:
@@ -96,7 +107,6 @@ class LLPanelProfileView : public LLPanelProfile
 
 	LLTextBox* mStatusText;
 	AvatarStatusObserver* mAvatarStatusObserver;
-	bool mAvatarIsOnline;
 };
 
 #endif //LL_LLPANELPROFILEVIEW_H
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 88b706fb6bf9aab3c7ab9cb99a214f5dc70cb6d9..c0302eee9e0fce6005bf5a400f7269d881644b06 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -628,7 +628,7 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&
 	}
 	else if (item == "can_call")
 	{
-		return LLVoiceClient::voiceEnabled();
+		return LLVoiceClient::voiceEnabled()&&gVoiceClient->voiceWorking();
 	}
 
 	return true;
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 9608cd1263766a72ae959744ab76aad4d6c395b7..6f9a1ccdbe0cc601d42dbf7251fa6beac7e58c7e 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -70,8 +70,6 @@ LLSpeaker::LLSpeaker(const LLUUID& id, const std::string& name, const ESpeakerTy
 	{
 		mDisplayName = name;
 	}
-
-	gVoiceClient->setUserVolume(id, LLMuteList::getInstance()->getSavedResidentVolume(id));
 }
 
 
diff --git a/indra/newview/lltransientdockablefloater.cpp b/indra/newview/lltransientdockablefloater.cpp
index c9bfe178ce430a3e417e0feaa32541dc3cd05011..9d39aa518241a760acecd38d9f60bb4b60ae5f6a 100644
--- a/indra/newview/lltransientdockablefloater.cpp
+++ b/indra/newview/lltransientdockablefloater.cpp
@@ -48,6 +48,14 @@ LLTransientDockableFloater::LLTransientDockableFloater(LLDockControl* dockContro
 LLTransientDockableFloater::~LLTransientDockableFloater()
 {
 	LLTransientFloaterMgr::getInstance()->unregisterTransientFloater(this);
+	LLView* dock = getDockWidget();
+	LLTransientFloaterMgr::getInstance()->removeControlView(
+			LLTransientFloaterMgr::DOCKED, this);
+	if (dock != NULL)
+	{
+		LLTransientFloaterMgr::getInstance()->removeControlView(
+				LLTransientFloaterMgr::DOCKED, dock);
+	}
 }
 
 void LLTransientDockableFloater::setVisible(BOOL visible)
@@ -55,18 +63,18 @@ void LLTransientDockableFloater::setVisible(BOOL visible)
 	LLView* dock = getDockWidget();
 	if(visible && isDocked())
 	{
-		LLTransientFloaterMgr::getInstance()->addControlView(this);
+		LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, this);
 		if (dock != NULL)
 		{
-			LLTransientFloaterMgr::getInstance()->addControlView(dock);
+			LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, dock);
 		}
 	}
 	else
 	{
-		LLTransientFloaterMgr::getInstance()->removeControlView(this);
+		LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, this);
 		if (dock != NULL)
 		{
-			LLTransientFloaterMgr::getInstance()->removeControlView(dock);
+			LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, dock);
 		}
 	}
 
@@ -78,18 +86,18 @@ void LLTransientDockableFloater::setDocked(bool docked, bool pop_on_undock)
 	LLView* dock = getDockWidget();
 	if(docked)
 	{
-		LLTransientFloaterMgr::getInstance()->addControlView(this);
+		LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, this);
 		if (dock != NULL)
 		{
-			LLTransientFloaterMgr::getInstance()->addControlView(dock);
+			LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::DOCKED, dock);
 		}
 	}
 	else
 	{
-		LLTransientFloaterMgr::getInstance()->removeControlView(this);
+		LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, this);
 		if (dock != NULL)
 		{
-			LLTransientFloaterMgr::getInstance()->removeControlView(dock);
+			LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::DOCKED, dock);
 		}
 	}
 
diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp
index 8f1a738453f996e81bbe71b1a53248ecb4ff1402..d82403070bee8188f068bf2217cb3a19dd6386a8 100644
--- a/indra/newview/lltransientfloatermgr.cpp
+++ b/indra/newview/lltransientfloatermgr.cpp
@@ -46,6 +46,7 @@ LLTransientFloaterMgr::LLTransientFloaterMgr()
 			&LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3));
 
 	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>()));
+	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(DOCKED, std::set<LLView*>()));
 	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(IM, std::set<LLView*>()));
 }
 
@@ -132,7 +133,8 @@ void LLTransientFloaterMgr::leftMouseClickCallback(S32 x, S32 y,
 		return;
 	}
 
-	bool hide = isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);
+	bool hide = isControlClicked(mGroupControls.find(DOCKED)->second, x, y)
+			&& isControlClicked(mGroupControls.find(GLOBAL)->second, x, y);
 	if (hide)
 	{
 		hideTransientFloaters(x, y);
diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h
index 1f99325a7fb98f4d1fb388d8009b8426ff1f788e..9c5ae295f28f379ad3575a19b11acbfb8d115240 100644
--- a/indra/newview/lltransientfloatermgr.h
+++ b/indra/newview/lltransientfloatermgr.h
@@ -51,7 +51,7 @@ class LLTransientFloaterMgr: public LLSingleton<LLTransientFloaterMgr>
 public:
 	enum ETransientGroup
 	{
-		GLOBAL, IM
+		GLOBAL, DOCKED, IM
 	};
 
 	void registerTransientFloater(LLTransientFloater* floater);
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index c84afa5af12a2fba3299441e8ca3395a58050ffd..8ca0fd6ef6c01fb314e2d2d45bc66a5e90366aad 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -37,8 +37,10 @@
 
 // library includes
 #include "llnotificationsutil.h"
+#include "llsdserialize.h"
 #include "llsdutil.h"
 
+
 // project includes
 #include "llvoavatar.h"
 #include "llbufferstream.h"
@@ -1092,6 +1094,119 @@ static void killGateway()
 
 #endif
 
+class LLSpeakerVolumeStorage : public LLSingleton<LLSpeakerVolumeStorage>
+{
+	LOG_CLASS(LLSpeakerVolumeStorage);
+public:
+
+	/**
+	 * Sets internal voluem level for specified user.
+	 *
+	 * @param[in] speaker_id - LLUUID of user to store volume level for
+	 * @param[in] volume - internal volume level to be stored for user.
+	 */
+	void storeSpeakerVolume(const LLUUID& speaker_id, S32 volume);
+
+	/**
+	 * Gets stored internal volume level for specified speaker.
+	 *
+	 * If specified user is not found default level will be returned. It is equivalent of 
+	 * external level 0.5 from the 0.0..1.0 range.
+	 * Default internal level is calculated as: internal = 400 * external^2
+	 * Maps 0.0 to 1.0 to internal values 0-400 with default 0.5 == 100
+	 *
+	 * @param[in] speaker_id - LLUUID of user to get his volume level
+	 */
+	S32 getSpeakerVolume(const LLUUID& speaker_id);
+
+private:
+	friend class LLSingleton<LLSpeakerVolumeStorage>;
+	LLSpeakerVolumeStorage();
+	~LLSpeakerVolumeStorage();
+
+	const static std::string SETTINGS_FILE_NAME;
+
+	void load();
+	void save();
+
+	typedef std::map<LLUUID, S32> speaker_data_map_t;
+	speaker_data_map_t mSpeakersData;
+};
+
+const std::string LLSpeakerVolumeStorage::SETTINGS_FILE_NAME = "volume_settings.xml";
+
+LLSpeakerVolumeStorage::LLSpeakerVolumeStorage()
+{
+	load();
+}
+
+LLSpeakerVolumeStorage::~LLSpeakerVolumeStorage()
+{
+	save();
+}
+
+void LLSpeakerVolumeStorage::storeSpeakerVolume(const LLUUID& speaker_id, S32 volume)
+{
+	mSpeakersData[speaker_id] = volume;
+}
+
+S32 LLSpeakerVolumeStorage::getSpeakerVolume(const LLUUID& speaker_id)
+{
+	// default internal level of user voice.
+	const static LLUICachedControl<S32> DEFAULT_INTERNAL_VOLUME_LEVEL("VoiceDefaultInternalLevel", 100);
+	S32 ret_val = DEFAULT_INTERNAL_VOLUME_LEVEL;
+	speaker_data_map_t::const_iterator it = mSpeakersData.find(speaker_id);
+	
+	if (it != mSpeakersData.end())
+	{
+		ret_val = it->second;
+	}
+	return ret_val;
+}
+
+void LLSpeakerVolumeStorage::load()
+{
+	// load per-resident voice volume information
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SETTINGS_FILE_NAME);
+
+	LLSD settings_llsd;
+	llifstream file;
+	file.open(filename);
+	if (file.is_open())
+	{
+		LLSDSerialize::fromXML(settings_llsd, file);
+	}
+
+	for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
+		iter != settings_llsd.endMap(); ++iter)
+	{
+		mSpeakersData.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
+	}
+}
+
+void LLSpeakerVolumeStorage::save()
+{
+	// If we quit from the login screen we will not have an SL account
+	// name.  Don't try to save, otherwise we'll dump a file in
+	// C:\Program Files\SecondLife\ or similar. JC
+	std::string user_dir = gDirUtilp->getLindenUserDir();
+	if (!user_dir.empty())
+	{
+		std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SETTINGS_FILE_NAME);
+		LLSD settings_llsd;
+
+		for(speaker_data_map_t::const_iterator iter = mSpeakersData.begin(); iter != mSpeakersData.end(); ++iter)
+		{
+			settings_llsd[iter->first.asString()] = iter->second;
+		}
+
+		llofstream file;
+		file.open(filename);
+		LLSDSerialize::toPrettyXML(settings_llsd, file);
+	}
+}
+
+
 ///////////////////////////////////////////////////////////////////////////////////////////////
 
 LLVoiceClient::LLVoiceClient() :
@@ -4914,7 +5029,9 @@ LLVoiceClient::participantState *LLVoiceClient::sessionState::addParticipant(con
 		}
 		
 		mParticipantsByUUID.insert(participantUUIDMap::value_type(&(result->mAvatarID), result));
-		
+
+		result->mUserVolume = LLSpeakerVolumeStorage::getInstance()->getSpeakerVolume(result->mAvatarID);
+
 		LL_DEBUGS("Voice") << "participant \"" << result->mURI << "\" added." << LL_ENDL;
 	}
 	
@@ -5853,6 +5970,11 @@ bool LLVoiceClient::voiceEnabled()
 	return gSavedSettings.getBOOL("EnableVoiceChat") && !gSavedSettings.getBOOL("CmdLineDisableVoice");
 }
 
+bool LLVoiceClient::voiceWorking()
+{
+	return (stateLoggedIn <= mState) && (mState <= stateLeavingSession);
+}
+
 void LLVoiceClient::setLipSyncEnabled(BOOL enabled)
 {
 	mLipSyncEnabled = enabled;
@@ -6158,6 +6280,9 @@ void LLVoiceClient::setUserVolume(const LLUUID& id, F32 volume)
 			participant->mUserVolume = llclamp(ivol, 0, 400);
 			participant->mVolumeDirty = TRUE;
 			mAudioSession->mVolumeDirty = TRUE;
+
+			// store this volume setting for future sessions
+			LLSpeakerVolumeStorage::getInstance()->storeSpeakerVolume(id, participant->mUserVolume);
 		}
 	}
 }
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 6231c6ba29f47b3bb92090a2d93ba986779bd32a..8f668dff196973b6e76d1f671993f90e4a1548ad 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -191,6 +191,8 @@ static	void updatePosition(void);
 		void inputUserControlState(bool down); // interpret any sort of up-down mic-open control input according to ptt-toggle prefs
 		void setVoiceEnabled(bool enabled);
 		static bool voiceEnabled();
+		// Checks is voice working judging from mState
+		bool voiceWorking();
 		void setUsePTT(bool usePTT);
 		void setPTTIsToggle(bool PTTIsToggle);
 		bool getPTTIsToggle();
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 613530b7aa9bd922303ba88dd83b692cd60ffc1d..d2e54731573870fe48dfb4261048a507f01aadb1 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -11,7 +11,7 @@
  can_dock="false"
  can_minimize="true"
  can_close="true"
- visible="true"
+ visible="false"
  width="360"
  can_resize="true"
  min_width="250"
diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
index f473a51ff6da4ea5b7c202749e7cf153e0243a84..c4411db8c5b6a798ed3514bd81b5a023c64f73ee 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
@@ -56,7 +56,7 @@
              height="18"
              default_icon_name="Generic_Person"
              layout="topleft"
-             left="0"
+             left="5"
              name="user_icon"
              top="0"
              width="18" />
@@ -78,6 +78,7 @@
              follows="top|right"
              height="16"
              layout="topleft"
+             right="-3"
              name="speaking_indicator"
              left_pad="5"
              visible="true"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 960da7a27468b1ab25db723893b67cca775d22b1..41f4621d665d1e03b705288d63cbd352b6f1435a 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -242,6 +242,16 @@ Save all changes to clothing/body parts?
      yestext="Save All"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="FriendsAndGroupsOnly"
+   type="alertmodal">
+    Non-friends won't know that you've choosen to ignore their calls and instant messages.
+    <usetemplate
+     name="okbutton"
+     yestext="Yes"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="GrantModifyRights"
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index 615ade99a2bcbe90456786b8ffb25df48f6f2900..c605975c8e17db5fc7b0540b4953e8b57f7c62b8 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -65,28 +65,18 @@
      height="15"
      layout="topleft"
      left_pad="5"
+     right="-72"
      name="last_interaction"
      text_color="LtGray_50"
      value="0s"
      width="24" />
-    <output_monitor
-     auto_update="true"
-     follows="right"
-     draw_border="false"
-     height="16"
-     layout="topleft"
-     left_pad="5"
-     mouse_opaque="true"
-     name="speaking_indicator"
-     visible="true"
-     width="20" />
     <button
      follows="right"
      height="16"
      image_pressed="Info_Press"
      image_unselected="Info_Over"
      left_pad="3"
-     right="-31"
+     right="-53"
      name="info_btn"
      top_delta="-2"
      width="16" />
@@ -96,9 +86,21 @@
      image_overlay="ForwardArrow_Off"
      layout="topleft"
      left_pad="5"
-     right="-3"
+     right="-28"
      name="profile_btn"
      tool_tip="View profile"
      top_delta="-2"
      width="20" />
+    <output_monitor
+     auto_update="true"
+     follows="right"
+     draw_border="false"
+     height="16"
+     layout="topleft"
+     left_pad="5"
+     right="-3"
+     mouse_opaque="true"
+     name="speaking_indicator"
+     visible="true"
+     width="20" />
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
index 2075d7e05b518abbce55a73d3e0b5f81124a87d7..db156f7877c25ba1b50b30ee6b509ffaee818bc6 100644
--- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
@@ -2,7 +2,7 @@
 <panel
  border="false"
  follows="all"
- height="380"
+ height="420"
  label="Land &amp; L$"
  layout="topleft"
  left="0"
@@ -237,7 +237,7 @@
     </text>
     <tab_container
      follows="all"
-     height="173"
+     height="180"
      halign="center"
      layout="topleft"
      left="0"
@@ -250,7 +250,7 @@
         <panel
          border="false"
          follows="all"
-         height="173"
+         height="180"
          label="PLANNING"
          layout="topleft"
          left="0"
@@ -275,7 +275,7 @@
       <panel
          border="false"
          follows="all"
-         height="173"
+         height="180"
          label="DETAILS"
          layout="topleft"
          left="0"
@@ -296,41 +296,44 @@
              word_wrap="true">
                 Loading...
             </text_editor>
+
+          <button
+             height="20"
+             image_overlay="Arrow_Left_Off"
+             layout="topleft"
+             left="5"
+             name="earlier_details_button"
+             tool_tip="Go back in time"
+             top_pad="10"
+             width="25" />
             <button
-	     follows="left|top"
-	     height="18"
-	     image_overlay="Arrow_Left_Off"
-	     layout="topleft"
-	     name="earlier_details_button"
-	     tool_tip="Back"
-             right="-45"
-             bottom="0"
-	     width="25" />
-             <button
-	     follows="left|top"
-	     height="18"
-	     image_overlay="Arrow_Right_Off"
-	     layout="topleft"
-	     left_pad="10"
-       name="later_details_button"
-	     tool_tip="Next"
-	     width="25" />
-        </panel>
+             height="20"
+             image_overlay="Arrow_Right_Off"
+             layout="topleft"
+             left_pad="5"
+             name="later_details_button"
+             tool_tip="Go forward in time"
+             top_delta="0"
+             width="25" />  
+
+
+      </panel>
       <panel
          border="false"
          follows="all"
-         height="173"
+         height="180"
          label="SALES"
          layout="topleft"
          left_delta="0"
          help_topic="group_money_sales_tab"
+         mouse_opaque="false"
          name="group_money_sales_tab"
          top="0"
          width="300">
             <text_editor
              type="string"
              follows="all"
-             height="140"
+             height="130"
              layout="topleft"
              left="0"
              max_length="4096"
@@ -340,25 +343,24 @@
              word_wrap="true">
                 Loading...
             </text_editor>
-                         <button
-             bottom="0"
-	     follows="left|top"
-	     height="18"
-	     image_overlay="Arrow_Left_Off"
-	     layout="topleft"
-	     name="earlier_sales_button"
-	     tool_tip="Back"
-         right="-45"
-	     width="25" />
-             <button
-	     follows="left|top"
-	     height="18"
-	     image_overlay="Arrow_Right_Off"
-	     layout="topleft"
-	     left_pad="10"
-         name="later_sales_button"
-	     tool_tip="Next"
-	     width="25" />
+            <button
+             height="20"
+             image_overlay="Arrow_Left_Off"
+             layout="topleft"
+             left="5"
+             name="earlier_sales_button"
+             tool_tip="Go back in time"
+             top_pad="10"
+             width="25" />
+            <button
+             height="20"
+             image_overlay="Arrow_Right_Off"
+             layout="topleft"
+             left_pad="5"
+             name="later_sales_button"
+             tool_tip="Go forward in time"
+             top_delta="0"
+             width="25" />
         </panel>
     </tab_container>
 </panel>