diff --git a/doc/contributions.txt b/doc/contributions.txt
index cf10ecccfbbc46a1de4231072ddd11babfde302f..2e4d80325253576e7ffbcd441766c2b5b50d0e88 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -500,6 +500,7 @@ Ringo Tuxing
 	CT-231
 	CT-321
 Robin Cornelius
+	SNOW-108
 	SNOW-204
 	VWR-2488
 	VWR-9557
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index ac7cc2cdac75b429c7f3cf4b36b80e39c5b057d3..9ead183a9e043cc5de702403426dc2fb816d8661 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -50,7 +50,7 @@ set(llcommon_SOURCE_FILES
     lleventdispatcher.cpp
     lleventfilter.cpp
     llevents.cpp
-    llfasttimer.cpp
+    llfasttimer_class.cpp
     llfile.cpp
     llfindlocale.cpp
     llfixedbuffer.cpp
@@ -250,7 +250,7 @@ list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
 
 if(LLCOMMON_LINK_SHARED)
     add_library (llcommon SHARED ${llcommon_SOURCE_FILES})
-	ll_stage_sharedlib(llcommon)
+    ll_stage_sharedlib(llcommon)
 else(LLCOMMON_LINK_SHARED)
     add_library (llcommon ${llcommon_SOURCE_FILES})
 endif(LLCOMMON_LINK_SHARED)
diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h
index 9920921a58df78bf5ca9cc12e977637acc11ba1b..476d75380f3b81b8ba4d76b601f5b5c585714594 100644
--- a/indra/llcommon/llerrorlegacy.h
+++ b/indra/llcommon/llerrorlegacy.h
@@ -34,7 +34,7 @@
 #ifndef LL_LLERRORLEGACY_H
 #define LL_LLERRORLEGACY_H
 
-
+#include "llpreprocessor.h"
 
 /*
 	LEGACY -- DO NOT USE THIS STUFF ANYMORE
@@ -107,7 +107,7 @@ const int LL_ERR_PRICE_MISMATCH = -23018;
 
 #define llwarning(msg, num)		llwarns << "Warning # " << num << ": " << msg << llendl;
 
-#define llassert_always(func)	if (!(func)) llerrs << "ASSERT (" << #func << ")" << llendl;
+#define llassert_always(func)	if (LL_UNLIKELY(!(func))) llerrs << "ASSERT (" << #func << ")" << llendl;
 
 #ifdef SHOW_ASSERT
 #define llassert(func)			llassert_always(func)
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 8af79c90fd6417602f22e60c1b7d10f8ed861573..48461df6ae3028ec87965e71a25ccbfe931a2cdc 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -1,6 +1,6 @@
 /**
  * @file llfasttimer.h
- * @brief Declaration of a fast timer.
+ * @brief Inline implementations of fast timers.
  *
  * $LicenseInfo:firstyear=2004&license=viewergpl$
  *
@@ -33,13 +33,13 @@
 #ifndef LL_FASTTIMER_H
 #define LL_FASTTIMER_H
 
-#include "llinstancetracker.h"
-
-#define FAST_TIMER_ON 1
-#define TIME_FAST_TIMERS 0
+// pull in the actual class definition
+#include "llfasttimer_class.h"
 
 #if LL_WINDOWS
-#define LL_INLINE __forceinline
+//
+// Windows implementation of CPU clock
+//
 
 //
 // NOTE: put back in when we aren't using platform sdk anymore
@@ -52,21 +52,21 @@
 //#undef _interlockedbittestandset
 //#undef _interlockedbittestandreset
 
-//inline U32 get_cpu_clock_count_32()
+//inline U32 LLFastTimer::getCPUClockCount32()
 //{
 //	U64 time_stamp = __rdtsc();
 //	return (U32)(time_stamp >> 8);
 //}
 //
 //// return full timer value, *not* shifted by 8 bits
-//inline U64 get_cpu_clock_count_64()
+//inline U64 LLFastTimer::getCPUClockCount64()
 //{
 //	return __rdtsc();
 //}
 
 // shift off lower 8 bits for lower resolution but longer term timing
 // on 1Ghz machine, a 32-bit word will hold ~1000 seconds of timing
-inline U32 get_cpu_clock_count_32()
+inline U32 LLFastTimer::getCPUClockCount32()
 {
 	U32 ret_val;
 	__asm
@@ -82,7 +82,7 @@ inline U32 get_cpu_clock_count_32()
 }
 
 // return full timer value, *not* shifted by 8 bits
-inline U64 get_cpu_clock_count_64()
+inline U64 LLFastTimer::getCPUClockCount64()
 {
 	U64 ret_val;
 	__asm
@@ -96,269 +96,71 @@ inline U64 get_cpu_clock_count_64()
 	}
     return ret_val;
 }
-#else
-#define LL_INLINE
 #endif
 
-#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
-inline U32 get_cpu_clock_count_32()
+
+#if LL_LINUX || LL_SOLARIS
+//
+// Linux and Solaris implementation of CPU clock - all architectures.
+//
+// Try to use the MONOTONIC clock if available, this is a constant time counter
+// with nanosecond resolution (but not necessarily accuracy) and attempts are made
+// to synchronize this value between cores at kernel start. It should not be affected
+// by CPU frequency. If not available use the REALTIME clock, but this may be affected by
+// NTP adjustments or other user activity affecting the system time.
+inline U64 LLFastTimer::getCPUClockCount64()
+{
+	struct timespec tp;
+	
+#ifdef CLOCK_MONOTONIC // MONOTONIC supported at build-time?
+	if (-1 == clock_gettime(CLOCK_MONOTONIC,&tp)) // if MONOTONIC isn't supported at runtime then ouch, try REALTIME
+#endif
+		clock_gettime(CLOCK_REALTIME,&tp);
+
+	return (tp.tv_sec*LLFastTimer::sClockResolution)+tp.tv_nsec;        
+}
+
+inline U32 LLFastTimer::getCPUClockCount32()
+{
+	return (U32)(LLFastTimer::getCPUClockCount64() >> 8);
+}
+#endif // (LL_LINUX || LL_SOLARIS))
+
+
+#if (LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
+//
+// Mac x86 implementation of CPU clock
+inline U32 LLFastTimer::getCPUClockCount32()
 {
 	U64 x;
 	__asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
-	return (U32)x >> 8;
+	return (U32)(x >> 8);
 }
 
-inline U32 get_cpu_clock_count_64()
+inline U64 LLFastTimer::getCPUClockCount64()
 {
 	U64 x;
 	__asm__ volatile (".byte 0x0f, 0x31": "=A"(x));
-	return x >> 8;
+	return x;
 }
 #endif
 
-#if ( LL_DARWIN && !(defined(__i386__) || defined(__amd64__))) || (LL_SOLARIS && defined(__sparc__))
+
+#if ( LL_DARWIN && !(defined(__i386__) || defined(__amd64__)))
 //
-// Mac PPC (deprecated) & Solaris SPARC implementation of CPU clock
+// Mac PPC (deprecated) implementation of CPU clock
 //
 // Just use gettimeofday implementation for now
 
-inline U32 get_cpu_clock_count_32()
+inline U32 LLFastTimer::getCPUClockCount32()
 {
-	return (U32)get_clock_count();
+	return (U32)(get_clock_count()>>8);
 }
 
-inline U32 get_cpu_clock_count_64()
+inline U64 LLFastTimer::getCPUClockCount64()
 {
 	return get_clock_count();
 }
 #endif
 
-class LLMutex;
-
-#include <queue>
-#include "llsd.h"
-
-class LL_COMMON_API LLFastTimer
-{
-public:
-
-	class NamedTimer;
-
-	struct LL_COMMON_API FrameState
-	{
-		FrameState(NamedTimer* timerp);
-
-		U32 				mSelfTimeCounter;
-		U32 				mCalls;
-		FrameState*			mParent;		// info for caller timer
-		FrameState*			mLastCaller;	// used to bootstrap tree construction
-		NamedTimer*			mTimer;
-		U16					mActiveCount;	// number of timers with this ID active on stack
-		bool				mMoveUpTree;	// needs to be moved up the tree of timers at the end of frame
-	};
-
-	// stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
-	class LL_COMMON_API NamedTimer
-	:	public LLInstanceTracker<NamedTimer>
-	{
-		friend class DeclareTimer;
-	public:
-		~NamedTimer();
-
-		enum { HISTORY_NUM = 60 };
-
-		const std::string& getName() const { return mName; }
-		NamedTimer* getParent() const { return mParent; }
-		void setParent(NamedTimer* parent);
-		S32 getDepth();
-		std::string getToolTip(S32 history_index = -1);
-
-		typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
-		child_const_iter beginChildren();
-		child_const_iter endChildren();
-		std::vector<NamedTimer*>& getChildren();
-
-		void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
-		bool getCollapsed() const { return mCollapsed; }
-
-		U32 getCountAverage() const { return mCountAverage; }
-		U32 getCallAverage() const { return mCallAverage; }
-
-		U32 getHistoricalCount(S32 history_index = 0) const;
-		U32 getHistoricalCalls(S32 history_index = 0) const;
-
-		static NamedTimer& getRootNamedTimer();
-
-		S32 getFrameStateIndex() const { return mFrameStateIndex; }
-
-		FrameState& getFrameState() const;
-
-	private:
-		friend class LLFastTimer;
-		friend class NamedTimerFactory;
-
-		//
-		// methods
-		//
-		NamedTimer(const std::string& name);
-		// recursive call to gather total time from children
-		static void accumulateTimings();
-
-		// updates cumulative times and hierarchy,
-		// can be called multiple times in a frame, at any point
-		static void processTimes();
-
-		static void buildHierarchy();
-		static void resetFrame();
-		static void reset();
-
-		//
-		// members
-		//
-		S32			mFrameStateIndex;
-
-		std::string	mName;
-
-		U32 		mTotalTimeCounter;
-
-		U32 		mCountAverage;
-		U32			mCallAverage;
-
-		U32*		mCountHistory;
-		U32*		mCallHistory;
-
-		// tree structure
-		NamedTimer*					mParent;				// NamedTimer of caller(parent)
-		std::vector<NamedTimer*>	mChildren;
-		bool						mCollapsed;				// don't show children
-		bool						mNeedsSorting;			// sort children whenever child added
-	};
-
-	// used to statically declare a new named timer
-	class LL_COMMON_API DeclareTimer
-	:	public LLInstanceTracker<DeclareTimer>
-	{
-		friend class LLFastTimer;
-	public:
-		DeclareTimer(const std::string& name, bool open);
-		DeclareTimer(const std::string& name);
-
-		static void updateCachedPointers();
-
-	private:
-		NamedTimer&		mTimer;
-		FrameState*		mFrameState;
-	};
-
-public:
-	LLFastTimer(LLFastTimer::FrameState* state);
-
-	LL_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer)
-	:	mFrameState(timer.mFrameState)
-	{
-#if TIME_FAST_TIMERS
-		U64 timer_start = get_cpu_clock_count_64();
-#endif
-#if FAST_TIMER_ON
-		LLFastTimer::FrameState* frame_state = mFrameState;
-		mStartTime = get_cpu_clock_count_32();
-
-		frame_state->mActiveCount++;
-		frame_state->mCalls++;
-		// keep current parent as long as it is active when we are
-		frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
-
-		LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData;
-		mLastTimerData = *cur_timer_data;
-		cur_timer_data->mCurTimer = this;
-		cur_timer_data->mFrameState = frame_state;
-		cur_timer_data->mChildTime = 0;
-#endif
-#if TIME_FAST_TIMERS
-		U64 timer_end = get_cpu_clock_count_64();
-		sTimerCycles += timer_end - timer_start;
-#endif
-	}
-
-	LL_INLINE ~LLFastTimer()
-	{
-#if TIME_FAST_TIMERS
-		U64 timer_start = get_cpu_clock_count_64();
-#endif
-#if FAST_TIMER_ON
-		LLFastTimer::FrameState* frame_state = mFrameState;
-		U32 total_time = get_cpu_clock_count_32() - mStartTime;
-
-		frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime;
-		frame_state->mActiveCount--;
-
-		// store last caller to bootstrap tree creation
-		// do this in the destructor in case of recursion to get topmost caller
-		frame_state->mLastCaller = mLastTimerData.mFrameState;
-
-		// we are only tracking self time, so subtract our total time delta from parents
-		mLastTimerData.mChildTime += total_time;
-
-		LLFastTimer::sCurTimerData = mLastTimerData;
-#endif
-#if TIME_FAST_TIMERS
-		U64 timer_end = get_cpu_clock_count_64();
-		sTimerCycles += timer_end - timer_start;
-		sTimerCalls++;
-#endif
-	}
-
-public:
-	static LLMutex*			sLogLock;
-	static std::queue<LLSD> sLogQueue;
-	static BOOL				sLog;
-	static BOOL				sMetricLog;
-	static bool 			sPauseHistory;
-	static bool 			sResetHistory;
-	static U64				sTimerCycles;
-	static U32				sTimerCalls;
-
-	typedef std::vector<FrameState> info_list_t;
-	static info_list_t& getFrameStateList();
-
-
-	// call this once a frame to reset timers
-	static void nextFrame();
-
-	// dumps current cumulative frame stats to log
-	// call nextFrame() to reset timers
-	static void dumpCurTimes();
-
-	// call this to reset timer hierarchy, averages, etc.
-	static void reset();
-
-	static U64 countsPerSecond();
-	static S32 getLastFrameIndex() { return sLastFrameIndex; }
-	static S32 getCurFrameIndex() { return sCurFrameIndex; }
-
-	static void writeLog(std::ostream& os);
-	static const NamedTimer* getTimerByName(const std::string& name);
-
-	struct CurTimerData
-	{
-		LLFastTimer*	mCurTimer;
-		FrameState*		mFrameState;
-		U32				mChildTime;
-	};
-	static CurTimerData		sCurTimerData;
-
-private:
-	static S32				sCurFrameIndex;
-	static S32				sLastFrameIndex;
-	static U64				sLastFrameTime;
-	static info_list_t*		sTimerInfos;
-
-	U32							mStartTime;
-	LLFastTimer::FrameState*	mFrameState;
-	LLFastTimer::CurTimerData	mLastTimerData;
-
-};
-
-typedef class LLFastTimer LLFastTimer;
-
 #endif // LL_LLFASTTIMER_H
diff --git a/indra/llcommon/llfasttimer_class.cpp b/indra/llcommon/llfasttimer_class.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..fae0a6687322afe8ea6b21e42d160cbf621e7248
--- /dev/null
+++ b/indra/llcommon/llfasttimer_class.cpp
@@ -0,0 +1,751 @@
+/** 
+ * @file llfasttimer_class.cpp
+ * @brief Implementation of the fast timer.
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ * 
+ * Copyright (c) 2004-2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS."LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+
+#include "llfasttimer.h"
+
+#include "llmemory.h"
+#include "llprocessor.h"
+#include "llsingleton.h"
+#include "lltreeiterators.h"
+#include "llsdserialize.h"
+
+#include <boost/bind.hpp>
+
+#if LL_WINDOWS
+#elif LL_LINUX || LL_SOLARIS
+#include <sys/time.h>
+#include <sched.h>
+#elif LL_DARWIN
+#include <sys/time.h>
+#include "lltimer.h"	// get_clock_count()
+#else 
+#error "architecture not supported"
+#endif
+
+//////////////////////////////////////////////////////////////////////////////
+// statics
+
+S32 LLFastTimer::sCurFrameIndex = -1;
+S32 LLFastTimer::sLastFrameIndex = -1;
+U64 LLFastTimer::sLastFrameTime = LLFastTimer::getCPUClockCount64();
+bool LLFastTimer::sPauseHistory = 0;
+bool LLFastTimer::sResetHistory = 0;
+LLFastTimer::CurTimerData LLFastTimer::sCurTimerData;
+BOOL LLFastTimer::sLog = FALSE;
+BOOL LLFastTimer::sMetricLog = FALSE;
+LLMutex* LLFastTimer::sLogLock = NULL;
+std::queue<LLSD> LLFastTimer::sLogQueue;
+
+#if LL_LINUX || LL_SOLARIS
+U64 LLFastTimer::sClockResolution = 1000000000; // Nanosecond resolution
+#else
+U64 LLFastTimer::sClockResolution = 1000000; // Microsecond resolution
+#endif
+
+std::vector<LLFastTimer::FrameState>* LLFastTimer::sTimerInfos = NULL;
+U64				LLFastTimer::sTimerCycles = 0;
+U32				LLFastTimer::sTimerCalls = 0;
+
+
+// FIXME: move these declarations to the relevant modules
+
+// helper functions
+typedef LLTreeDFSPostIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_bottom_up_iterator_t;
+
+static timer_tree_bottom_up_iterator_t begin_timer_tree_bottom_up(LLFastTimer::NamedTimer& id) 
+{ 
+	return timer_tree_bottom_up_iterator_t(&id, 
+							boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1), 
+							boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
+}
+
+static timer_tree_bottom_up_iterator_t end_timer_tree_bottom_up() 
+{ 
+	return timer_tree_bottom_up_iterator_t(); 
+}
+
+typedef LLTreeDFSIter<LLFastTimer::NamedTimer, LLFastTimer::NamedTimer::child_const_iter> timer_tree_dfs_iterator_t;
+
+
+static timer_tree_dfs_iterator_t begin_timer_tree(LLFastTimer::NamedTimer& id) 
+{ 
+	return timer_tree_dfs_iterator_t(&id, 
+		boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::beginChildren), _1), 
+							boost::bind(boost::mem_fn(&LLFastTimer::NamedTimer::endChildren), _1));
+}
+
+static timer_tree_dfs_iterator_t end_timer_tree() 
+{ 
+	return timer_tree_dfs_iterator_t(); 
+}
+
+
+
+// factory class that creates NamedTimers via static DeclareTimer objects
+class NamedTimerFactory : public LLSingleton<NamedTimerFactory>
+{
+public:
+	NamedTimerFactory() 
+	{}
+
+	/*virtual */ void initSingleton()
+	{
+		mTimerRoot = new LLFastTimer::NamedTimer("root");
+
+		mActiveTimerRoot = new LLFastTimer::NamedTimer("Frame");
+		mActiveTimerRoot->setCollapsed(false);
+
+		mRootFrameState = new LLFastTimer::FrameState(mActiveTimerRoot);
+		mRootFrameState->mParent = &mTimerRoot->getFrameState();
+		mActiveTimerRoot->setParent(mTimerRoot);
+
+		mAppTimer = new LLFastTimer(mRootFrameState);
+	}
+
+	~NamedTimerFactory()
+	{
+		std::for_each(mTimers.begin(), mTimers.end(), DeletePairedPointer());
+
+		delete mAppTimer;
+		delete mActiveTimerRoot; 
+		delete mTimerRoot;
+		delete mRootFrameState;
+	}
+
+	LLFastTimer::NamedTimer& createNamedTimer(const std::string& name)
+	{
+		timer_map_t::iterator found_it = mTimers.find(name);
+		if (found_it != mTimers.end())
+		{
+			return *found_it->second;
+		}
+
+		LLFastTimer::NamedTimer* timer = new LLFastTimer::NamedTimer(name);
+		timer->setParent(mTimerRoot);
+		mTimers.insert(std::make_pair(name, timer));
+
+		return *timer;
+	}
+
+	LLFastTimer::NamedTimer* getTimerByName(const std::string& name)
+	{
+		timer_map_t::iterator found_it = mTimers.find(name);
+		if (found_it != mTimers.end())
+		{
+			return found_it->second;
+		}
+		return NULL;
+	}
+
+	LLFastTimer::NamedTimer* getActiveRootTimer() { return mActiveTimerRoot; }
+	LLFastTimer::NamedTimer* getRootTimer() { return mTimerRoot; }
+	const LLFastTimer* getAppTimer() { return mAppTimer; }
+	LLFastTimer::FrameState& getRootFrameState() { return *mRootFrameState; }
+
+	typedef std::map<std::string, LLFastTimer::NamedTimer*> timer_map_t;
+	timer_map_t::iterator beginTimers() { return mTimers.begin(); }
+	timer_map_t::iterator endTimers() { return mTimers.end(); }
+	S32 timerCount() { return mTimers.size(); }
+
+private:
+	timer_map_t mTimers;
+
+	LLFastTimer::NamedTimer*		mActiveTimerRoot;
+	LLFastTimer::NamedTimer*		mTimerRoot;
+	LLFastTimer*						mAppTimer;
+	LLFastTimer::FrameState*		mRootFrameState;
+};
+
+void update_cached_pointers_if_changed()
+{
+	// detect when elements have moved and update cached pointers
+	static LLFastTimer::FrameState* sFirstTimerAddress = NULL;
+	if (&*(LLFastTimer::getFrameStateList().begin()) != sFirstTimerAddress)
+	{
+		LLFastTimer::DeclareTimer::updateCachedPointers();
+	}
+	sFirstTimerAddress = &*(LLFastTimer::getFrameStateList().begin());
+}
+
+LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name, bool open )
+:	mTimer(NamedTimerFactory::instance().createNamedTimer(name))
+{
+	mTimer.setCollapsed(!open);
+	mFrameState = &mTimer.getFrameState();
+	update_cached_pointers_if_changed();
+}
+
+LLFastTimer::DeclareTimer::DeclareTimer(const std::string& name)
+:	mTimer(NamedTimerFactory::instance().createNamedTimer(name))
+{
+	mFrameState = &mTimer.getFrameState();
+	update_cached_pointers_if_changed();
+}
+
+// static
+void LLFastTimer::DeclareTimer::updateCachedPointers()
+{
+	// propagate frame state pointers to timer declarations
+	for (DeclareTimer::instance_iter it = DeclareTimer::beginInstances();
+		it != DeclareTimer::endInstances();
+		++it)
+	{
+		// update cached pointer
+		it->mFrameState = &it->mTimer.getFrameState();
+	}
+}
+
+//static
+#if LL_LINUX || LL_SOLARIS || ( LL_DARWIN && !(defined(__i386__) || defined(__amd64__)) )
+U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
+{
+	return sClockResolution >> 8;
+}
+#else // windows or x86-mac
+U64 LLFastTimer::countsPerSecond() // counts per second for the *32-bit* timer
+{
+	static U64 sCPUClockFrequency = U64(CProcessor().GetCPUFrequency(50));
+
+	// we drop the low-order byte in out timers, so report a lower frequency
+	return sCPUClockFrequency >> 8;
+}
+#endif
+
+LLFastTimer::FrameState::FrameState(LLFastTimer::NamedTimer* timerp)
+:	mActiveCount(0),
+	mCalls(0),
+	mSelfTimeCounter(0),
+	mParent(NULL),
+	mLastCaller(NULL),
+	mMoveUpTree(false),
+	mTimer(timerp)
+{}
+
+
+LLFastTimer::NamedTimer::NamedTimer(const std::string& name)
+:	mName(name),
+	mCollapsed(true),
+	mParent(NULL),
+	mTotalTimeCounter(0),
+	mCountAverage(0),
+	mCallAverage(0),
+	mNeedsSorting(false)
+{
+	info_list_t& frame_state_list = getFrameStateList();
+	mFrameStateIndex = frame_state_list.size();
+	getFrameStateList().push_back(FrameState(this));
+
+	mCountHistory = new U32[HISTORY_NUM];
+	memset(mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
+	mCallHistory = new U32[HISTORY_NUM];
+	memset(mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
+}
+
+LLFastTimer::NamedTimer::~NamedTimer()
+{
+	delete[] mCountHistory;
+	delete[] mCallHistory;
+}
+
+std::string LLFastTimer::NamedTimer::getToolTip(S32 history_idx)
+{
+	if (history_idx < 0)
+	{
+		// by default, show average number of calls
+		return llformat("%s (%d calls)", getName().c_str(), (S32)getCallAverage());
+	}
+	else
+	{
+		return llformat("%s (%d calls)", getName().c_str(), (S32)getHistoricalCalls(history_idx));
+	}
+}
+
+void LLFastTimer::NamedTimer::setParent(NamedTimer* parent)
+{
+	llassert_always(parent != this);
+	llassert_always(parent != NULL);
+
+	if (mParent)
+	{
+		// subtract our accumulated from previous parent
+		for (S32 i = 0; i < HISTORY_NUM; i++)
+		{
+			mParent->mCountHistory[i] -= mCountHistory[i];
+		}
+
+		// subtract average timing from previous parent
+		mParent->mCountAverage -= mCountAverage;
+
+		std::vector<NamedTimer*>& children = mParent->getChildren();
+		std::vector<NamedTimer*>::iterator found_it = std::find(children.begin(), children.end(), this);
+		if (found_it != children.end())
+		{
+			children.erase(found_it);
+		}
+	}
+
+	mParent = parent;
+	if (parent)
+	{
+		getFrameState().mParent = &parent->getFrameState();
+		parent->getChildren().push_back(this);
+		parent->mNeedsSorting = true;
+	}
+}
+
+S32 LLFastTimer::NamedTimer::getDepth()
+{
+	S32 depth = 0;
+	NamedTimer* timerp = mParent;
+	while(timerp)
+	{
+		depth++;
+		timerp = timerp->mParent;
+	}
+	return depth;
+}
+
+// static
+void LLFastTimer::NamedTimer::processTimes()
+{
+	if (sCurFrameIndex < 0) return;
+
+	buildHierarchy();
+	accumulateTimings();
+}
+
+// sort timer info structs by depth first traversal order
+struct SortTimersDFS
+{
+	bool operator()(const LLFastTimer::FrameState& i1, const LLFastTimer::FrameState& i2)
+	{
+		return i1.mTimer->getFrameStateIndex() < i2.mTimer->getFrameStateIndex();
+	}
+};
+
+// sort child timers by name
+struct SortTimerByName
+{
+	bool operator()(const LLFastTimer::NamedTimer* i1, const LLFastTimer::NamedTimer* i2)
+	{
+		return i1->getName() < i2->getName();
+	}
+};
+
+//static
+void LLFastTimer::NamedTimer::buildHierarchy()
+{
+	if (sCurFrameIndex < 0 ) return;
+
+	// set up initial tree
+    for (instance_iter it = NamedTimer::beginInstances();
+		it != endInstances();
+		++it)
+	{
+		NamedTimer& timer = *it;
+		if (&timer == NamedTimerFactory::instance().getRootTimer()) continue;
+
+		// bootstrap tree construction by attaching to last timer to be on stack
+		// when this timer was called
+		if (timer.getFrameState().mLastCaller && timer.mParent == NamedTimerFactory::instance().getRootTimer())
+		{
+			timer.setParent(timer.getFrameState().mLastCaller->mTimer);
+			// no need to push up tree on first use, flag can be set spuriously
+			timer.getFrameState().mMoveUpTree = false;
+		}
+	}
+
+	// bump timers up tree if they've been flagged as being in the wrong place
+	// do this in a bottom up order to promote descendants first before promoting ancestors
+	// this preserves partial order derived from current frame's observations
+	for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getRootTimer());
+		it != end_timer_tree_bottom_up();
+		++it)
+	{
+		NamedTimer* timerp = *it;
+		// skip root timer
+		if (timerp == NamedTimerFactory::instance().getRootTimer()) continue;
+
+		if (timerp->getFrameState().mMoveUpTree)
+		{
+			// since ancestors have already been visited, reparenting won't affect tree traversal
+			//step up tree, bringing our descendants with us
+			//llinfos << "Moving " << timerp->getName() << " from child of " << timerp->getParent()->getName() <<
+			//	" to child of " << timerp->getParent()->getParent()->getName() << llendl;
+			timerp->setParent(timerp->getParent()->getParent());
+			timerp->getFrameState().mMoveUpTree = false;
+
+			// don't bubble up any ancestors until descendants are done bubbling up
+			it.skipAncestors();
+		}
+	}
+
+	// sort timers by time last called, so call graph makes sense
+	for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
+		it != end_timer_tree();
+		++it)
+	{
+		NamedTimer* timerp = (*it);
+		if (timerp->mNeedsSorting)
+		{
+			std::sort(timerp->getChildren().begin(), timerp->getChildren().end(), SortTimerByName());
+		}
+		timerp->mNeedsSorting = false;
+	}
+}
+
+//static
+void LLFastTimer::NamedTimer::accumulateTimings()
+{
+	U32 cur_time = getCPUClockCount32();
+
+	// walk up stack of active timers and accumulate current time while leaving timing structures active
+	LLFastTimer* cur_timer = sCurTimerData.mCurTimer;
+	// root defined by parent pointing to self
+	CurTimerData* cur_data = &sCurTimerData;
+	while(cur_timer->mLastTimerData.mCurTimer != cur_timer)
+	{
+		U32 cumulative_time_delta = cur_time - cur_timer->mStartTime;
+		U32 self_time_delta = cumulative_time_delta - cur_data->mChildTime;
+		cur_data->mChildTime = 0;
+		cur_timer->mFrameState->mSelfTimeCounter += self_time_delta;
+		cur_timer->mStartTime = cur_time;
+
+		cur_data = &cur_timer->mLastTimerData;
+		cur_data->mChildTime += cumulative_time_delta;
+
+		cur_timer = cur_timer->mLastTimerData.mCurTimer;
+	}
+
+	// traverse tree in DFS post order, or bottom up
+	for(timer_tree_bottom_up_iterator_t it = begin_timer_tree_bottom_up(*NamedTimerFactory::instance().getActiveRootTimer());
+		it != end_timer_tree_bottom_up();
+		++it)
+	{
+		NamedTimer* timerp = (*it);
+		timerp->mTotalTimeCounter = timerp->getFrameState().mSelfTimeCounter;
+		for (child_const_iter child_it = timerp->beginChildren(); child_it != timerp->endChildren(); ++child_it)
+		{
+			timerp->mTotalTimeCounter += (*child_it)->mTotalTimeCounter;
+		}
+
+		S32 cur_frame = sCurFrameIndex;
+		if (cur_frame >= 0)
+		{
+			// update timer history
+			int hidx = cur_frame % HISTORY_NUM;
+
+			timerp->mCountHistory[hidx] = timerp->mTotalTimeCounter;
+			timerp->mCountAverage = (timerp->mCountAverage * cur_frame + timerp->mTotalTimeCounter) / (cur_frame+1);
+			timerp->mCallHistory[hidx] = timerp->getFrameState().mCalls;
+			timerp->mCallAverage = (timerp->mCallAverage * cur_frame + timerp->getFrameState().mCalls) / (cur_frame+1);
+		}
+	}
+}
+
+// static
+void LLFastTimer::NamedTimer::resetFrame()
+{
+	if (sLog)
+	{ //output current frame counts to performance log
+		F64 iclock_freq = 1000.0 / countsPerSecond(); // good place to calculate clock frequency
+
+		F64 total_time = 0;
+		LLSD sd;
+
+		for (NamedTimer::instance_iter it = NamedTimer::beginInstances();
+					it != NamedTimer::endInstances();
+					++it)
+		{
+			NamedTimer& timer = *it;
+			FrameState& info = timer.getFrameState();
+			sd[timer.getName()]["Time"] = (LLSD::Real) (info.mSelfTimeCounter*iclock_freq);	
+			sd[timer.getName()]["Calls"] = (LLSD::Integer) info.mCalls;
+			
+			// computing total time here because getting the root timer's getCountHistory
+			// doesn't work correctly on the first frame
+			total_time = total_time + info.mSelfTimeCounter * iclock_freq;
+		}
+
+		sd["Total"]["Time"] = (LLSD::Real) total_time;
+		sd["Total"]["Calls"] = (LLSD::Integer) 1;
+
+		{		
+			LLMutexLock lock(sLogLock);
+			sLogQueue.push(sd);
+		}
+	}
+
+
+	// tag timers by position in depth first traversal of tree
+	S32 index = 0;
+	for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
+		it != end_timer_tree();
+		++it)
+	{
+		NamedTimer* timerp = (*it);
+		
+		timerp->mFrameStateIndex = index;
+		index++;
+
+		llassert_always(timerp->mFrameStateIndex < (S32)getFrameStateList().size());
+	}
+
+	// sort timers by dfs traversal order to improve cache coherency
+	std::sort(getFrameStateList().begin(), getFrameStateList().end(), SortTimersDFS());
+
+	// update pointers into framestatelist now that we've sorted it
+	DeclareTimer::updateCachedPointers();
+
+	// reset for next frame
+	for (NamedTimer::instance_iter it = NamedTimer::beginInstances();
+		it != NamedTimer::endInstances();
+		++it)
+	{
+		NamedTimer& timer = *it;
+
+		FrameState& info = timer.getFrameState();
+		info.mSelfTimeCounter = 0;
+		info.mCalls = 0;
+		info.mLastCaller = NULL;
+		info.mMoveUpTree = false;
+		// update parent pointer in timer state struct
+		if (timer.mParent)
+		{
+			info.mParent = &timer.mParent->getFrameState();
+		}
+	}
+
+	//sTimerCycles = 0;
+	//sTimerCalls = 0;
+}
+
+//static
+void LLFastTimer::NamedTimer::reset()
+{
+	resetFrame(); // reset frame data
+
+	// walk up stack of active timers and reset start times to current time
+	// effectively zeroing out any accumulated time
+	U32 cur_time = getCPUClockCount32();
+
+	// root defined by parent pointing to self
+	CurTimerData* cur_data = &sCurTimerData;
+	LLFastTimer* cur_timer = cur_data->mCurTimer;
+	while(cur_timer->mLastTimerData.mCurTimer != cur_timer)
+	{
+		cur_timer->mStartTime = cur_time;
+		cur_data->mChildTime = 0;
+
+		cur_data = &cur_timer->mLastTimerData;
+		cur_timer = cur_data->mCurTimer;
+	}
+
+	// reset all history
+	for (NamedTimer::instance_iter it = NamedTimer::beginInstances();
+		it != NamedTimer::endInstances();
+		++it)
+	{
+		NamedTimer& timer = *it;
+		if (&timer != NamedTimerFactory::instance().getRootTimer()) 
+		{
+			timer.setParent(NamedTimerFactory::instance().getRootTimer());
+		}
+
+		timer.mCountAverage = 0;
+		timer.mCallAverage = 0;
+		memset(timer.mCountHistory, 0, sizeof(U32) * HISTORY_NUM);
+		memset(timer.mCallHistory, 0, sizeof(U32) * HISTORY_NUM);
+	}
+
+	sLastFrameIndex = 0;
+	sCurFrameIndex = 0;
+}
+
+//static 
+LLFastTimer::info_list_t& LLFastTimer::getFrameStateList() 
+{ 
+	if (!sTimerInfos) 
+	{ 
+		sTimerInfos = new info_list_t(); 
+	} 
+	return *sTimerInfos; 
+}
+
+
+U32 LLFastTimer::NamedTimer::getHistoricalCount(S32 history_index) const
+{
+	S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
+	return mCountHistory[history_idx];
+}
+
+U32 LLFastTimer::NamedTimer::getHistoricalCalls(S32 history_index ) const
+{
+	S32 history_idx = (getLastFrameIndex() + history_index) % LLFastTimer::NamedTimer::HISTORY_NUM;
+	return mCallHistory[history_idx];
+}
+
+LLFastTimer::FrameState& LLFastTimer::NamedTimer::getFrameState() const
+{
+	llassert_always(mFrameStateIndex >= 0);
+	if (this == NamedTimerFactory::instance().getActiveRootTimer()) 
+	{
+		return NamedTimerFactory::instance().getRootFrameState();
+	}
+	return getFrameStateList()[mFrameStateIndex];
+}
+
+// static
+LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer()
+{ 
+	return *NamedTimerFactory::instance().getActiveRootTimer(); 
+}
+
+std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::beginChildren()
+{ 
+	return mChildren.begin(); 
+}
+
+std::vector<LLFastTimer::NamedTimer*>::const_iterator LLFastTimer::NamedTimer::endChildren()
+{
+	return mChildren.end();
+}
+
+std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren()
+{
+	return mChildren;
+}
+
+//static
+void LLFastTimer::nextFrame()
+{
+	countsPerSecond(); // good place to calculate clock frequency
+	U64 frame_time = getCPUClockCount64();
+	if ((frame_time - sLastFrameTime) >> 8 > 0xffffffff)
+	{
+		llinfos << "Slow frame, fast timers inaccurate" << llendl;
+	}
+
+	if (sPauseHistory)
+	{
+		sResetHistory = true;
+	}
+	else if (sResetHistory)
+	{
+		sLastFrameIndex = 0;
+		sCurFrameIndex = 0;
+		sResetHistory = false;
+	}
+	else // not paused
+	{
+		NamedTimer::processTimes();
+		sLastFrameIndex = sCurFrameIndex++;
+	}
+	
+	// get ready for next frame
+	NamedTimer::resetFrame();
+	sLastFrameTime = frame_time;
+}
+
+//static
+void LLFastTimer::dumpCurTimes()
+{
+	// accumulate timings, etc.
+	NamedTimer::processTimes();
+	
+	F64 clock_freq = (F64)countsPerSecond();
+	F64 iclock_freq = 1000.0 / clock_freq; // clock_ticks -> milliseconds
+
+	// walk over timers in depth order and output timings
+	for(timer_tree_dfs_iterator_t it = begin_timer_tree(*NamedTimerFactory::instance().getRootTimer());
+		it != end_timer_tree();
+		++it)
+	{
+		NamedTimer* timerp = (*it);
+		F64 total_time_ms = ((F64)timerp->getHistoricalCount(0) * iclock_freq);
+		// Don't bother with really brief times, keep output concise
+		if (total_time_ms < 0.1) continue;
+
+		std::ostringstream out_str;
+		for (S32 i = 0; i < timerp->getDepth(); i++)
+		{
+			out_str << "\t";
+		}
+
+
+		out_str << timerp->getName() << " " 
+			<< std::setprecision(3) << total_time_ms << " ms, "
+			<< timerp->getHistoricalCalls(0) << " calls";
+
+		llinfos << out_str.str() << llendl;
+	}
+}
+
+//static 
+void LLFastTimer::reset()
+{
+	NamedTimer::reset();
+}
+
+
+//static
+void LLFastTimer::writeLog(std::ostream& os)
+{
+	while (!sLogQueue.empty())
+	{
+		LLSD& sd = sLogQueue.front();
+		LLSDSerialize::toXML(sd, os);
+		LLMutexLock lock(sLogLock);
+		sLogQueue.pop();
+	}
+}
+
+//static
+const LLFastTimer::NamedTimer* LLFastTimer::getTimerByName(const std::string& name)
+{
+	return NamedTimerFactory::instance().getTimerByName(name);
+}
+
+LLFastTimer::LLFastTimer(LLFastTimer::FrameState* state)
+:	mFrameState(state)
+{
+	U32 start_time = getCPUClockCount32();
+	mStartTime = start_time;
+	mFrameState->mActiveCount++;
+	LLFastTimer::sCurTimerData.mCurTimer = this;
+	LLFastTimer::sCurTimerData.mFrameState = mFrameState;
+	LLFastTimer::sCurTimerData.mChildTime = 0;
+	mLastTimerData = LLFastTimer::sCurTimerData;
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
diff --git a/indra/llcommon/llfasttimer_class.h b/indra/llcommon/llfasttimer_class.h
new file mode 100644
index 0000000000000000000000000000000000000000..ddb1a747935627ec32ea01f903f5483da270027f
--- /dev/null
+++ b/indra/llcommon/llfasttimer_class.h
@@ -0,0 +1,272 @@
+/**
+ * @file llfasttimer_class.h
+ * @brief Declaration of a fast timer.
+ *
+ * $LicenseInfo:firstyear=2004&license=viewergpl$
+ *
+ * Copyright (c) 2004-2009, Linden Research, Inc.
+ *
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ *
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ *
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ *
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FASTTIMER_CLASS_H
+#define LL_FASTTIMER_CLASS_H
+
+#include "llinstancetracker.h"
+
+#define FAST_TIMER_ON 1
+#define TIME_FAST_TIMERS 0
+
+class LLMutex;
+
+#include <queue>
+#include "llsd.h"
+
+class LL_COMMON_API LLFastTimer
+{
+public:
+	class NamedTimer;
+
+	struct LL_COMMON_API FrameState
+	{
+		FrameState(NamedTimer* timerp);
+
+		U32 				mSelfTimeCounter;
+		U32 				mCalls;
+		FrameState*			mParent;		// info for caller timer
+		FrameState*			mLastCaller;	// used to bootstrap tree construction
+		NamedTimer*			mTimer;
+		U16					mActiveCount;	// number of timers with this ID active on stack
+		bool				mMoveUpTree;	// needs to be moved up the tree of timers at the end of frame
+	};
+
+	// stores a "named" timer instance to be reused via multiple LLFastTimer stack instances
+	class LL_COMMON_API NamedTimer
+	:	public LLInstanceTracker<NamedTimer>
+	{
+		friend class DeclareTimer;
+	public:
+		~NamedTimer();
+
+		enum { HISTORY_NUM = 60 };
+
+		const std::string& getName() const { return mName; }
+		NamedTimer* getParent() const { return mParent; }
+		void setParent(NamedTimer* parent);
+		S32 getDepth();
+		std::string getToolTip(S32 history_index = -1);
+
+		typedef std::vector<NamedTimer*>::const_iterator child_const_iter;
+		child_const_iter beginChildren();
+		child_const_iter endChildren();
+		std::vector<NamedTimer*>& getChildren();
+
+		void setCollapsed(bool collapsed) { mCollapsed = collapsed; }
+		bool getCollapsed() const { return mCollapsed; }
+
+		U32 getCountAverage() const { return mCountAverage; }
+		U32 getCallAverage() const { return mCallAverage; }
+
+		U32 getHistoricalCount(S32 history_index = 0) const;
+		U32 getHistoricalCalls(S32 history_index = 0) const;
+
+		static NamedTimer& getRootNamedTimer();
+
+		S32 getFrameStateIndex() const { return mFrameStateIndex; }
+
+		FrameState& getFrameState() const;
+
+	private:
+		friend class LLFastTimer;
+		friend class NamedTimerFactory;
+
+		//
+		// methods
+		//
+		NamedTimer(const std::string& name);
+		// recursive call to gather total time from children
+		static void accumulateTimings();
+
+		// updates cumulative times and hierarchy,
+		// can be called multiple times in a frame, at any point
+		static void processTimes();
+
+		static void buildHierarchy();
+		static void resetFrame();
+		static void reset();
+
+		//
+		// members
+		//
+		S32			mFrameStateIndex;
+
+		std::string	mName;
+
+		U32 		mTotalTimeCounter;
+
+		U32 		mCountAverage;
+		U32			mCallAverage;
+
+		U32*		mCountHistory;
+		U32*		mCallHistory;
+
+		// tree structure
+		NamedTimer*					mParent;				// NamedTimer of caller(parent)
+		std::vector<NamedTimer*>	mChildren;
+		bool						mCollapsed;				// don't show children
+		bool						mNeedsSorting;			// sort children whenever child added
+	};
+
+	// used to statically declare a new named timer
+	class LL_COMMON_API DeclareTimer
+	:	public LLInstanceTracker<DeclareTimer>
+	{
+		friend class LLFastTimer;
+	public:
+		DeclareTimer(const std::string& name, bool open);
+		DeclareTimer(const std::string& name);
+
+		static void updateCachedPointers();
+
+	private:
+		NamedTimer&		mTimer;
+		FrameState*		mFrameState;
+	};
+
+public:
+	LLFastTimer(LLFastTimer::FrameState* state);
+
+	LL_FORCE_INLINE LLFastTimer(LLFastTimer::DeclareTimer& timer)
+	:	mFrameState(timer.mFrameState)
+	{
+#if TIME_FAST_TIMERS
+		U64 timer_start = getCPUClockCount64();
+#endif
+#if FAST_TIMER_ON
+		LLFastTimer::FrameState* frame_state = mFrameState;
+		mStartTime = getCPUClockCount32();
+
+		frame_state->mActiveCount++;
+		frame_state->mCalls++;
+		// keep current parent as long as it is active when we are
+		frame_state->mMoveUpTree |= (frame_state->mParent->mActiveCount == 0);
+
+		LLFastTimer::CurTimerData* cur_timer_data = &LLFastTimer::sCurTimerData;
+		mLastTimerData = *cur_timer_data;
+		cur_timer_data->mCurTimer = this;
+		cur_timer_data->mFrameState = frame_state;
+		cur_timer_data->mChildTime = 0;
+#endif
+#if TIME_FAST_TIMERS
+		U64 timer_end = getCPUClockCount64();
+		sTimerCycles += timer_end - timer_start;
+#endif
+	}
+
+	LL_FORCE_INLINE ~LLFastTimer()
+	{
+#if TIME_FAST_TIMERS
+		U64 timer_start = getCPUClockCount64();
+#endif
+#if FAST_TIMER_ON
+		LLFastTimer::FrameState* frame_state = mFrameState;
+		U32 total_time = getCPUClockCount32() - mStartTime;
+
+		frame_state->mSelfTimeCounter += total_time - LLFastTimer::sCurTimerData.mChildTime;
+		frame_state->mActiveCount--;
+
+		// store last caller to bootstrap tree creation
+		// do this in the destructor in case of recursion to get topmost caller
+		frame_state->mLastCaller = mLastTimerData.mFrameState;
+
+		// we are only tracking self time, so subtract our total time delta from parents
+		mLastTimerData.mChildTime += total_time;
+
+		LLFastTimer::sCurTimerData = mLastTimerData;
+#endif
+#if TIME_FAST_TIMERS
+		U64 timer_end = getCPUClockCount64();
+		sTimerCycles += timer_end - timer_start;
+		sTimerCalls++;
+#endif
+	}
+
+public:
+	static LLMutex*			sLogLock;
+	static std::queue<LLSD> sLogQueue;
+	static BOOL				sLog;
+	static BOOL				sMetricLog;
+	static bool 			sPauseHistory;
+	static bool 			sResetHistory;
+	static U64				sTimerCycles;
+	static U32				sTimerCalls;
+
+	typedef std::vector<FrameState> info_list_t;
+	static info_list_t& getFrameStateList();
+
+
+	// call this once a frame to reset timers
+	static void nextFrame();
+
+	// dumps current cumulative frame stats to log
+	// call nextFrame() to reset timers
+	static void dumpCurTimes();
+
+	// call this to reset timer hierarchy, averages, etc.
+	static void reset();
+
+	static U64 countsPerSecond();
+	static S32 getLastFrameIndex() { return sLastFrameIndex; }
+	static S32 getCurFrameIndex() { return sCurFrameIndex; }
+
+	static void writeLog(std::ostream& os);
+	static const NamedTimer* getTimerByName(const std::string& name);
+
+	struct CurTimerData
+	{
+		LLFastTimer*	mCurTimer;
+		FrameState*		mFrameState;
+		U32				mChildTime;
+	};
+	static CurTimerData		sCurTimerData;
+
+private:
+	static U32 getCPUClockCount32();
+	static U64 getCPUClockCount64();
+	static U64 sClockResolution;
+
+	static S32				sCurFrameIndex;
+	static S32				sLastFrameIndex;
+	static U64				sLastFrameTime;
+	static info_list_t*		sTimerInfos;
+
+	U32							mStartTime;
+	LLFastTimer::FrameState*	mFrameState;
+	LLFastTimer::CurTimerData	mLastTimerData;
+
+};
+
+typedef class LLFastTimer LLFastTimer;
+
+#endif // LL_LLFASTTIMER_CLASS_H
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index 5eefa6a16b2f3f577f0c48e45885091d24f46efd..1c1503ca7b645696740b63503865e3150df11af1 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -55,13 +55,28 @@
 #define LL_BIG_ENDIAN 1
 #endif
 
+
 // Per-compiler switches
+
 #ifdef __GNUC__
 #define LL_FORCE_INLINE inline __attribute__((always_inline))
 #else
 #define LL_FORCE_INLINE __forceinline
 #endif
 
+// Mark-up expressions with branch prediction hints.  Do NOT use
+// this with reckless abandon - it's an obfuscating micro-optimization
+// outside of inner loops or other places where you are OVERWHELMINGLY
+// sure which way an expression almost-always evaluates.
+#if __GNUC__ >= 3
+# define LL_LIKELY(EXPR) __builtin_expect (!!(EXPR), true)
+# define LL_UNLIKELY(EXPR) __builtin_expect (!!(EXPR), false)
+#else
+# define LL_LIKELY(EXPR) (EXPR)
+# define LL_UNLIKELY(EXPR) (EXPR)
+#endif
+
+
 // Figure out differences between compilers
 #if defined(__GNUC__)
 	#define GCC_VERSION (__GNUC__ * 10000 \
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index cd493481d5b5f9948ed7437eba7e746495ca304d..46478ba3c9577b0131b277e733aa33ffb817e5d8 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -436,6 +436,8 @@ void LLImageGL::init(BOOL usemipmaps)
 	mLastBindTime = 0.f;
 
 	mPickMask = NULL;
+	mPickMaskWidth = 0;
+	mPickMaskHeight = 0;
 	mUseMipMaps = usemipmaps;
 	mHasExplicitFormat = FALSE;
 	mAutoGenMips = FALSE;
@@ -527,7 +529,12 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents)
 // 			llwarns << "Setting Size of LLImageGL with existing mTexName = " << mTexName << llendl;
 			destroyGLTexture();
 		}
-		
+
+		// pickmask validity depends on old image size, delete it
+		delete [] mPickMask;
+		mPickMask = NULL;
+		mPickMaskWidth = mPickMaskHeight = 0;
+
 		mWidth = width;
 		mHeight = height;
 		mComponents = ncomponents;
@@ -1675,12 +1682,14 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
 		return ;
 	}
 
+	delete [] mPickMask;
+	mPickMask = NULL;
+	mPickMaskWidth = mPickMaskHeight = 0;
+
 	if (mFormatType != GL_UNSIGNED_BYTE ||
 	    mFormatPrimary != GL_RGBA)
 	{
 		//cannot generate a pick mask for this texture
-		delete [] mPickMask;
-		mPickMask = NULL;
 		return;
 	}
 
@@ -1688,11 +1697,10 @@ void LLImageGL::updatePickMask(S32 width, S32 height, const U8* data_in)
 	U32 pick_height = height/2;
 
 	U32 size = llmax(pick_width, (U32) 1) * llmax(pick_height, (U32) 1);
-
 	size = size/8 + 1;
-
-	delete[] mPickMask;
 	mPickMask = new U8[size];
+	mPickMaskWidth = pick_width;
+	mPickMaskHeight = pick_height;
 
 	memset(mPickMask, 0, sizeof(U8) * size);
 
@@ -1727,35 +1735,34 @@ BOOL LLImageGL::getMask(const LLVector2 &tc)
 
 	if (mPickMask)
 	{
-		S32 width = getWidth()/2;
-		S32 height = getHeight()/2;
-
 		F32 u = tc.mV[0] - floorf(tc.mV[0]);
 		F32 v = tc.mV[1] - floorf(tc.mV[1]);
 
-		if (u < 0.f || u > 1.f ||
-		    v < 0.f || v > 1.f)
+		if (LL_UNLIKELY(u < 0.f || u > 1.f ||
+				v < 0.f || v > 1.f))
 		{
 			LL_WARNS_ONCE("render") << "Ugh, u/v out of range in image mask pick" << LL_ENDL;
 			u = v = 0.f;
 			llassert(false);
 		}
+
+		llassert(mPickMaskWidth > 0 && mPickMaskHeight > 0);
 		
-		S32 x = (S32)(u * width);
-		S32 y = (S32)(v * height);
+		S32 x = (S32)(u * mPickMaskWidth);
+		S32 y = (S32)(v * mPickMaskHeight);
 
-		if (x >= width)
+		if (LL_UNLIKELY(x >= mPickMaskWidth))
 		{
 			LL_WARNS_ONCE("render") << "Ooh, width overrun on pick mask read, that coulda been bad." << LL_ENDL;
-			x = llmax(0, width-1);
+			x = llmax(0, mPickMaskWidth-1);
 		}
-		if (y >= height)
+		if (LL_UNLIKELY(y >= mPickMaskHeight))
 		{
 			LL_WARNS_ONCE("render") << "Ooh, height overrun on pick mask read, that woulda been bad." << LL_ENDL;
-			y = llmax(0, height-1);
+			y = llmax(0, mPickMaskHeight-1);
 		}
 
-		S32 idx = y*width+x;
+		S32 idx = y*mPickMaskWidth+x;
 		S32 offset = idx%8;
 
 		res = mPickMask[idx/8] & (1 << offset) ? TRUE : FALSE;
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index facfb7bd62d2dbbcf5bc96d355c907ee6f324f0e..f0870c3fc45b2416c9ac98f8b35613a6b867fb04 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -193,6 +193,8 @@ class LLImageGL : public LLRefCount
 private:
 	LLPointer<LLImageRaw> mSaveData; // used for destroyGL/restoreGL
 	U8* mPickMask;  //downsampled bitmap approximation of alpha channel.  NULL if no alpha channel
+	U16 mPickMaskWidth;
+	U16 mPickMaskHeight;
 	S8 mUseMipMaps;
 	S8 mHasExplicitFormat; // If false (default), GL format is f(mComponents)
 	S8 mAutoGenMips;
diff --git a/indra/llui/llaccordionctrl.cpp b/indra/llui/llaccordionctrl.cpp
index b5e870228ad68f9ab140abf6b99773e725cc3d29..d0c73fbfbce62a6ca5742a3f4bceb6561fa49634 100644
--- a/indra/llui/llaccordionctrl.cpp
+++ b/indra/llui/llaccordionctrl.cpp
@@ -63,6 +63,8 @@ static LLDefaultChildRegistry::Register<LLAccordionCtrl>	t2("accordion");
 
 LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
  , mFitParent(params.fit_parent)
+ , mAutoScrolling( false )
+ , mAutoScrollRate( 0.f )
 {
   mSingleExpansion = params.single_expansion;
 	if(mFitParent && !mSingleExpansion)
@@ -72,6 +74,8 @@ LLAccordionCtrl::LLAccordionCtrl(const Params& params):LLPanel(params)
 }
 
 LLAccordionCtrl::LLAccordionCtrl() : LLPanel()
+ , mAutoScrolling( false )
+ , mAutoScrollRate( 0.f )
 {
 	mSingleExpansion = false;
 	mFitParent = false;
@@ -81,6 +85,19 @@ LLAccordionCtrl::LLAccordionCtrl() : LLPanel()
 //---------------------------------------------------------------------------------
 void LLAccordionCtrl::draw()
 {
+	if (mAutoScrolling)
+	{
+		// add acceleration to autoscroll
+		mAutoScrollRate = llmin(mAutoScrollRate + (LLFrameTimer::getFrameDeltaTimeF32() * AUTO_SCROLL_RATE_ACCEL), MAX_AUTO_SCROLL_RATE);
+	}
+	else
+	{
+		// reset to minimum for next time
+		mAutoScrollRate = MIN_AUTO_SCROLL_RATE;
+	}
+	// clear this flag to be set on next call to autoScroll
+	mAutoScrolling = false;
+
 	LLRect local_rect(0, getRect().getHeight(), getRect().getWidth(), 0);
 	
 	LLLocalClipRect clip(local_rect);
@@ -420,6 +437,64 @@ BOOL LLAccordionCtrl::handleKeyHere			(KEY key, MASK mask)
 	return LLPanel::handleKeyHere(key,mask);
 }
 
+BOOL LLAccordionCtrl::handleDragAndDrop		(S32 x, S32 y, MASK mask,
+											 BOOL drop,
+											 EDragAndDropType cargo_type,
+											 void* cargo_data,
+											 EAcceptance* accept,
+											 std::string& tooltip_msg)
+{
+	// Scroll folder view if needed.  Never accepts a drag or drop.
+	*accept = ACCEPT_NO;
+	BOOL handled = autoScroll(x, y);
+
+	if( !handled )
+	{
+		handled = childrenHandleDragAndDrop(x, y, mask, drop, cargo_type,
+											cargo_data, accept, tooltip_msg) != NULL;
+	}
+	return TRUE;
+}
+
+BOOL LLAccordionCtrl::autoScroll		(S32 x, S32 y)
+{
+	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+
+	bool scrolling = false;
+	if( mScrollbar->getVisible() )
+	{
+		LLRect rect_local( 0, getRect().getHeight(), getRect().getWidth() - scrollbar_size, 0 );
+		LLRect screen_local_extents;
+
+		// clip rect against root view
+		screenRectToLocal(getRootView()->getLocalRect(), &screen_local_extents);
+		rect_local.intersectWith(screen_local_extents);
+
+		// autoscroll region should take up no more than one third of visible scroller area
+		S32 auto_scroll_region_height = llmin(rect_local.getHeight() / 3, 10);
+		S32 auto_scroll_speed = llround(mAutoScrollRate * LLFrameTimer::getFrameDeltaTimeF32());
+
+		LLRect bottom_scroll_rect = screen_local_extents;
+		bottom_scroll_rect.mTop = rect_local.mBottom + auto_scroll_region_height;
+		if( bottom_scroll_rect.pointInRect( x, y ) && (mScrollbar->getDocPos() < mScrollbar->getDocPosMax()) )
+		{
+			mScrollbar->setDocPos( mScrollbar->getDocPos() + auto_scroll_speed );
+			mAutoScrolling = true;
+			scrolling = true;
+		}
+
+		LLRect top_scroll_rect = screen_local_extents;
+		top_scroll_rect.mBottom = rect_local.mTop - auto_scroll_region_height;
+		if( top_scroll_rect.pointInRect( x, y ) && (mScrollbar->getDocPos() > 0) )
+		{
+			mScrollbar->setDocPos( mScrollbar->getDocPos() - auto_scroll_speed );
+			mAutoScrolling = true;
+			scrolling = true;
+		}
+	}
+	return scrolling;
+}
+
 void	LLAccordionCtrl::updateLayout	(S32 width, S32 height)
 {
 	S32 panel_top = height - BORDER_MARGIN ;
diff --git a/indra/llui/llaccordionctrl.h b/indra/llui/llaccordionctrl.h
index 4cb0f382813ab9ef14fba7f462ab451751c91606..d57a42df32447aea03ab276b233875040d9366df 100644
--- a/indra/llui/llaccordionctrl.h
+++ b/indra/llui/llaccordionctrl.h
@@ -81,6 +81,11 @@ class LLAccordionCtrl: public LLPanel
 	virtual BOOL handleRightMouseDown	( S32 x, S32 y, MASK mask); 
 	virtual BOOL handleScrollWheel		( S32 x, S32 y, S32 clicks );
 	virtual BOOL handleKeyHere			(KEY key, MASK mask);
+	virtual BOOL handleDragAndDrop		(S32 x, S32 y, MASK mask, BOOL drop,
+										 EDragAndDropType cargo_type,
+										 void* cargo_data,
+										 EAcceptance* accept,
+										 std::string& tooltip_msg);
 	//
 
 	// Call reshape after changing splitter's size
@@ -112,11 +117,15 @@ class LLAccordionCtrl: public LLPanel
 	void	showScrollbar			(S32 width, S32 height);
 	void	hideScrollbar			(S32 width, S32 height);
 
+	BOOL	autoScroll				(S32 x, S32 y);
+
 private:
 	LLRect			mInnerRect;
 	LLScrollbar*	mScrollbar;
 	bool			mSingleExpansion;
 	bool			mFitParent;
+	bool			mAutoScrolling;
+	F32				mAutoScrollRate;
 };
 
 
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 4bfe44135aad29ab85914d25a8bab73924b35413..daa9e08f14097462166cb59dee136137cd308773 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -45,6 +45,7 @@ static const std::string DD_HEADER_NAME = "dd_header";
 static const S32 HEADER_HEIGHT = 20;
 static const S32 HEADER_IMAGE_LEFT_OFFSET = 5;
 static const S32 HEADER_TEXT_LEFT_OFFSET = 30;
+static const F32 AUTO_OPEN_TIME = 1.f;
 
 static LLDefaultChildRegistry::Register<LLAccordionCtrlTab> t1("accordion_tab");
 
@@ -73,6 +74,11 @@ class LLAccordionCtrlTab::LLAccordionCtrlTabHeader : public LLUICtrl
 	virtual void onMouseEnter(S32 x, S32 y, MASK mask);
 	virtual void onMouseLeave(S32 x, S32 y, MASK mask);
 	virtual BOOL handleKey(KEY key, MASK mask, BOOL called_from_parent);
+	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+								   EDragAndDropType cargo_type,
+								   void* cargo_data,
+								   EAcceptance* accept,
+								   std::string& tooltip_msg);
 private:
 
 	LLTextBox* mHeaderTextbox;
@@ -92,6 +98,8 @@ class LLAccordionCtrlTab::LLAccordionCtrlTabHeader : public LLUICtrl
 	LLUIColor mHeaderBGColor;
 
 	bool mNeedsHighlight;
+
+	LLFrameTimer mAutoOpenTimer;
 };
 
 LLAccordionCtrlTab::LLAccordionCtrlTabHeader::Params::Params()
@@ -209,6 +217,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::onMouseLeave(S32 x, S32 y, MA
 {
 	LLUICtrl::onMouseLeave(x, y, mask);
 	mNeedsHighlight = false;
+	mAutoOpenTimer.stop();
 }
 BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleKey(KEY key, MASK mask, BOOL called_from_parent)
 {
@@ -218,8 +227,33 @@ BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleKey(KEY key, MASK mask,
 	}
 	return LLUICtrl::handleKey(key, mask, called_from_parent);
 }
+BOOL LLAccordionCtrlTab::LLAccordionCtrlTabHeader::handleDragAndDrop(S32 x, S32 y, MASK mask,
+																	 BOOL drop,
+																	 EDragAndDropType cargo_type,
+																	 void* cargo_data,
+																	 EAcceptance* accept,
+																	 std::string& tooltip_msg)
+{
+	LLAccordionCtrlTab* parent = dynamic_cast<LLAccordionCtrlTab*>(getParent());
 
+	if ( parent && !parent->getDisplayChildren() && parent->getCollapsible() && parent->canOpenClose() )
+	{
+		if (mAutoOpenTimer.getStarted())
+		{
+			if (mAutoOpenTimer.getElapsedTimeF32() > AUTO_OPEN_TIME)
+			{
+				parent->changeOpenClose(false);
+				mAutoOpenTimer.stop();
+				return TRUE;
+			}
+		}
+		else
+			mAutoOpenTimer.start();
+	}
 
+	return LLUICtrl::handleDragAndDrop(x, y, mask, drop, cargo_type,
+									   cargo_data, accept, tooltip_msg);
+}
 LLAccordionCtrlTab::Params::Params()
 	: title("title")
 	,display_children("expanded", true)
diff --git a/indra/llui/llaccordionctrltab.h b/indra/llui/llaccordionctrltab.h
index b200d43438b5e2f4920a51a95965075a9a90c312..2e0260ab16df31bb319772ba8af6dddfb56d0fe5 100644
--- a/indra/llui/llaccordionctrltab.h
+++ b/indra/llui/llaccordionctrltab.h
@@ -115,6 +115,7 @@ class LLAccordionCtrlTab : public LLUICtrl
 	void changeOpenClose(bool is_open);
 
 	void canOpenClose(bool can_open_close) { mCanOpenClose = can_open_close;};
+	bool canOpenClose() const { return mCanOpenClose; };
 
 	virtual BOOL postBuild();
 
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 73e4d126f32d36e3f8ff449f00712ae83adf2b12..cb5aea272dfda06cf6b9239725057b180123241b 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -70,6 +70,8 @@ const S32   SCROLL_INCREMENT_DEL = 4;	// make space for baskspacing
 const F32   AUTO_SCROLL_TIME = 0.05f;
 const F32	TRIPLE_CLICK_INTERVAL = 0.3f;	// delay between double and triple click. *TODO: make this equal to the double click interval?
 
+const std::string PASSWORD_ASTERISK( "\xE2\x97\x8F" ); // U+25CF BLACK CIRCLE
+
 static LLDefaultChildRegistry::Register<LLLineEditor> r1("line_editor");
 
 // Compiler optimization, generate extern template
@@ -401,7 +403,7 @@ void LLLineEditor::setCursorAtLocalPos( S32 local_mouse_x )
 	{
 		for (S32 i = 0; i < mText.length(); i++)
 		{
-			asterix_text += '*';
+			asterix_text += utf8str_to_wstring(PASSWORD_ASTERISK);
 		}
 		wtext = asterix_text.c_str();
 	}
@@ -1599,7 +1601,7 @@ void LLLineEditor::draw()
 		std::string text;
 		for (S32 i = 0; i < mText.length(); i++)
 		{
-			text += '*';
+			text += PASSWORD_ASTERISK;
 		}
 		mText = text;
 	}
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 4e84013db0c37e037ea5d1cfb7ad76b01b914158..78386220d93195b4b1b22d567f476ce6dfe5937d 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -498,7 +498,7 @@ void LLScrollListCtrl::fitContents(S32 max_width, S32 max_height)
 {
 	S32 height = llmin( getRequiredRect().getHeight(), max_height );
 	if(mPageLines)
-		height = llmin( mPageLines * mLineHeight + (mDisplayColumnHeaders ? mHeadingHeight : 0), height );
+		height = llmin( mPageLines * mLineHeight + 2*mBorderThickness + (mDisplayColumnHeaders ? mHeadingHeight : 0), height );
 
 	S32 width = getRect().getWidth();
 
@@ -2760,9 +2760,13 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& element, EAddPosition
 
 LLScrollListItem* LLScrollListCtrl::addRow(const LLScrollListItem::Params& item_p, EAddPosition pos)
 {
-	if (!item_p.validateBlock()) return NULL;
-
 	LLScrollListItem *new_item = new LLScrollListItem(item_p);
+	return addRow(new_item, item_p, pos);
+}
+
+LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLScrollListItem::Params& item_p, EAddPosition pos)
+{
+	if (!item_p.validateBlock() || !new_item) return NULL;
 	new_item->setNumColumns(mColumns.size());
 
 	// Add any columns we don't already have
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 907dc90bead1c9ca429e60cf1f98a4519d0f8776..d2d237932819df054ea2feb97e6ce64839bfa769 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -148,6 +148,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	// "columns" => [ "column" => column name, "value" => value, "type" => type, "font" => font, "font-style" => style ], "id" => uuid
 	// Creates missing columns automatically.
 	virtual LLScrollListItem* addElement(const LLSD& element, EAddPosition pos = ADD_BOTTOM, void* userdata = NULL);
+	virtual LLScrollListItem* addRow(LLScrollListItem *new_item, const LLScrollListItem::Params& value, EAddPosition pos = ADD_BOTTOM);
 	virtual LLScrollListItem* addRow(const LLScrollListItem::Params& value, EAddPosition pos = ADD_BOTTOM);
 	// Simple add element. Takes a single array of:
 	// [ "value" => value, "font" => font, "font-style" => style ]
diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h
index 15b86cc945d12087a0edeb69baafdc4bd05db9a4..25ce846d90faaedf81c05578791dd1d0d986441d 100644
--- a/indra/llui/llscrolllistitem.h
+++ b/indra/llui/llscrolllistitem.h
@@ -95,7 +95,7 @@ class LLScrollListItem
 	void	setUserdata( void* userdata )	{ mUserdata = userdata; }
 	void*	getUserdata() const 			{ return mUserdata; }
 
-	LLUUID	getUUID() const					{ return mItemValue.asUUID(); }
+	virtual LLUUID	getUUID() const			{ return mItemValue.asUUID(); }
 	LLSD	getValue() const				{ return mItemValue; }
 	
 	void	setRect(LLRect rect)			{ mRectangle = rect; }
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 17aecaf32fd81860635a48c03dcd1bac799d5844..8abbc833e5df49fd09b680f30d64a1021ddfcdf7 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -244,7 +244,8 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 
 LLTextBase::~LLTextBase()
 {
-	delete mPopupMenu;
+	// Menu, like any other LLUICtrl, is deleted by its parent - gMenuHolder
+
 	clearSegments();
 }
 
@@ -1009,6 +1010,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 
@@ -1501,6 +1512,25 @@ void LLTextBase::setText(const LLStringExplicit &utf8str, const LLStyle::Params&
 	onValueChange(0, getLength());
 }
 
+void LLTextBase::addBlackListUrl(const std::string &url)
+{
+	mBlackListUrls.push_back(url);
+}
+
+bool LLTextBase::isBlackListUrl(const std::string &url) const
+{
+	std::vector<std::string>::const_iterator it;
+	for (it = mBlackListUrls.begin(); it != mBlackListUrls.end(); ++it)
+	{
+		const std::string &blacklist_url = *it;
+		if (url.find(blacklist_url) != std::string::npos)
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
 //virtual
 std::string LLTextBase::getText() const
 {
@@ -1575,20 +1605,29 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
 					prepend_newline = false;
 				}
 			}
-			// output the styled Url
-			appendAndHighlightText(match.getLabel(), prepend_newline, part, link_params);
-			prepend_newline = false;
 
-			// set the tooltip for the Url label
-			if (! match.getTooltip().empty())
+			// output the styled Url (unless we've been asked to suppress it)
+			if (isBlackListUrl(match.getUrl()))
 			{
-				segment_set_t::iterator it = getSegIterContaining(getLength()-1);
-				if (it != mSegments.end())
+				std::string orig_url = text.substr(start, end-start);
+				appendAndHighlightText(orig_url, prepend_newline, part, style_params);
+			}
+			else
+			{
+				appendAndHighlightText(match.getLabel(), prepend_newline, part, link_params);
+
+				// set the tooltip for the Url label
+				if (! match.getTooltip().empty())
 				{
-					LLTextSegmentPtr segment = *it;
-					segment->setToolTip(match.getTooltip());
+					segment_set_t::iterator it = getSegIterContaining(getLength()-1);
+					if (it != mSegments.end())
+						{
+							LLTextSegmentPtr segment = *it;
+							segment->setToolTip(match.getTooltip());
+						}
 				}
 			}
+			prepend_newline = false;
 
 			// move on to the rest of the text after the Url
 			if (end < (S32)text.length()) 
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 038b9eaa62bbfd3a3fe1ae025199b0bf0ce1d962..e1c6cc36ab676214ab1bfd59e1872aca3d9ef76f 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -41,6 +41,7 @@
 #include "llpanel.h"
 
 #include <string>
+#include <vector>
 #include <set>
 
 #include <boost/signals2.hpp>
@@ -186,6 +187,9 @@ class LLTextBase
 	const LLFontGL*			getDefaultFont() const					{ return mDefaultFont; }
 	LLStyle::Params			getDefaultStyle();
 
+	// tell the text object to suppress auto highlighting of a specific URL
+	void                    addBlackListUrl(const std::string &url);
+
 public:
 	// Fired when a URL link is clicked
 	commit_signal_t mURLClickSignal;
@@ -308,6 +312,7 @@ class LLTextBase
 	void							updateRects();
 	void							needsScroll() { mScrollNeeded = TRUE; }
 	void							replaceUrlLabel(const std::string &url, const std::string &label);
+	bool                            isBlackListUrl(const std::string &url) const;
 
 protected:
 	// text segmentation and flow
@@ -359,6 +364,9 @@ class LLTextBase
 	LLView*						mDocumentView;
 	class LLScrollContainer*	mScroller;
 
+	// list of URLs to suppress from automatic hyperlinking
+	std::vector<std::string>    mBlackListUrls;
+
 	// transient state
 	bool						mReflowNeeded;		// need to reflow text because of change to text contents or display region
 	bool						mScrollNeeded;		// need to change scroll region because of change to cursor position
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index f2c3879a6c97bc57def552a400870e0aeb38b346..06ba0d80e9ad09a5a91ebd239dc0be4544023d52 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2040,6 +2040,20 @@ void LLTextEditor::showContextMenu(S32 x, S32 y)
 																				LLMenuHolderGL::child_registry_t::instance());
 	}
 
+	// Route menu to this class
+	// previously this was done in ::handleRightMoseDown:
+	//if(hasTabStop())
+	// setFocus(TRUE)  - why? weird...
+	// and then inside setFocus
+	// ....
+	//    gEditMenuHandler = this;
+	// ....
+	// but this didn't work in all cases and just weird...
+    //why not here? 
+	// (all this was done for EXT-4443)
+
+	gEditMenuHandler = this;
+
 	S32 screen_x, screen_y;
 	localPointToScreen(x, y, &screen_x, &screen_y);
 	mContextMenu->show(screen_x, screen_y);
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 2701c0b3c129e507b39f31caf3c564fff04c8905..c8db67d3d5b758c00b03adf856003074f0824515 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -351,7 +351,6 @@ set(viewer_SOURCE_FILES
     llpanelprimmediacontrols.cpp
     llpanelprofile.cpp
     llpanelprofileview.cpp
-    llpanelshower.cpp
     llpanelteleporthistory.cpp
     llpanelvolume.cpp
     llpanelvolumepulldown.cpp
@@ -858,7 +857,6 @@ set(viewer_HEADER_FILES
     llpanelprimmediacontrols.h
     llpanelprofile.h
     llpanelprofileview.h
-    llpanelshower.h
     llpanelteleporthistory.h
     llpanelvolume.h
     llpanelvolumepulldown.h
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ffe8762f038693b7798e469595714fc4dad9384d..a73c75da88e39086d7df7a90885b1d8fbb12c83d 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -298,17 +298,6 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>AudioStreamingVideo</key>
-    <map>
-      <key>Comment</key>
-      <string>Enable streaming video</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>1</integer>
-    </map>
   <key>AuditTexture</key>
   <map>
     <key>Comment</key>
@@ -10337,6 +10326,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/gpu_table.txt b/indra/newview/gpu_table.txt
index cc8f6780e3cbf54a2fc16d8bbe7b22787862a4b3..887dab66d186e262186f1f534c63af2cff7131ba 100644
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -192,9 +192,9 @@ NVIDIA GeForce 7100				.*NVIDIA.*GeForce 71.*				0		1
 NVIDIA GeForce 7200				.*NVIDIA.*GeForce 72.*				1		1
 NVIDIA GeForce 7300				.*NVIDIA.*GeForce 73.*				1		1
 NVIDIA GeForce 7500				.*NVIDIA.*GeForce 75.*				1		1
-NVIDIA GeForce 7600				.*NVIDIA.*GeForce 76.*				2		1
-NVIDIA GeForce 7800				.*NVIDIA.*GeForce.*78.*				2		1
-NVIDIA GeForce 7900				.*NVIDIA.*GeForce.*79.*				2		1
+NVIDIA GeForce 7600				.*NVIDIA.*GeForce 76.*				3		1
+NVIDIA GeForce 7800				.*NVIDIA.*GeForce.*78.*				3		1
+NVIDIA GeForce 7900				.*NVIDIA.*GeForce.*79.*				3		1
 NVIDIA GeForce 8100				.*NVIDIA.*GeForce 81.*				1		1
 NVIDIA GeForce 8200				.*NVIDIA.*GeForce 82.*				1		1
 NVIDIA GeForce 8300				.*NVIDIA.*GeForce 83.*				1		1
@@ -207,8 +207,8 @@ NVIDIA GeForce 8800				.*NVIDIA.*GeForce 88.*				3		1
 NVIDIA GeForce 9300M			.*NVIDIA.*GeForce 9300M.*			1		1
 NVIDIA GeForce 9400M			.*NVIDIA.*GeForce 9400M.*			1		1
 NVIDIA GeForce 9500M			.*NVIDIA.*GeForce 9500M.*			2		1
-NVIDIA GeForce 9600M			.*NVIDIA.*GeForce 9600M.*			2		1
-NVIDIA GeForce 9700M			.*NVIDIA.*GeForce 9700M.*			2		1
+NVIDIA GeForce 9600M			.*NVIDIA.*GeForce 9600M.*			3		1
+NVIDIA GeForce 9700M			.*NVIDIA.*GeForce 9700M.*			3		1
 NVIDIA GeForce 9300				.*NVIDIA.*GeForce 93.*				1		1
 NVIDIA GeForce 9400				.*GeForce 94.*						1		1
 NVIDIA GeForce 9500				.*NVIDIA.*GeForce 95.*				2		1
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 03180b6a9d5e07a99aac4fce62f08838ad6cc34e..1dec8c7bd8576034ef15c7c815945e0226ab3878 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -35,6 +35,7 @@
 #include "llagent.h"
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
+#include "llcommandhandler.h"
 #include "llfloatercustomize.h"
 #include "llgesturemgr.h"
 #include "llinventorybridge.h"
@@ -47,6 +48,23 @@
 #include "llviewerregion.h"
 #include "llwearablelist.h"
 
+// support for secondlife:///app/appearance SLapps
+class LLAppearanceHandler : public LLCommandHandler
+{
+public:
+	// requests will be throttled from a non-trusted browser
+	LLAppearanceHandler() : LLCommandHandler("appearance", UNTRUSTED_THROTTLE) {}
+
+	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+	{
+		// support secondlife:///app/appearance/show, but for now we just
+		// make all secondlife:///app/appearance SLapps behave this way
+		LLSideTray::getInstance()->showPanel("sidepanel_appearance", LLSD());
+		return true;
+	}
+};
+LLAppearanceHandler gAppearanceHandler;
+
 class LLWearInventoryCategoryCallback : public LLInventoryCallback
 {
 public:
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 40c9bb6afabeedd4fcccbca94f16c8f1f350df78..7eed2e7b9a274c9816306833b3b0ead62e20a3eb 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -250,31 +250,25 @@ void LLAvatarActions::startAdhocCall(const std::vector<LLUUID>& ids)
 	make_ui_sound("UISndStartIM");
 }
 
+/* AD *TODO: Is this function needed any more?
+	I fixed it a bit(added check for canCall), but it appears that it is not used
+	anywhere. Maybe it should be removed?
 // static
 bool LLAvatarActions::isCalling(const LLUUID &id)
 {
-	if (id.isNull())
+	if (id.isNull() || !canCall())
 	{
 		return false;
 	}
 
 	LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL, id);
 	return (LLIMModel::getInstance()->findIMSession(session_id) != NULL);
-}
+}*/
 
 //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..c751661acffd08927c79b7168fa291e84199d9d9 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -126,13 +126,16 @@ class LLAvatarActions
 	/**
 	 * Return true if the avatar is in a P2P voice call with a given user
 	 */
-	static bool isCalling(const LLUUID &id);
+	/* AD *TODO: Is this function needed any more?
+		I fixed it a bit(added check for canCall), but it appears that it is not used
+		anywhere. Maybe it should be removed?
+	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..f62fd44bc06df85be868102c9669383d62fb9e06 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,13 @@ BOOL LLCallFloater::postBuild()
 
 	connectToChannel(LLVoiceChannel::getCurrentVoiceChannel());
 
+	setIsChrome(true);
+	//chrome="true" hides floater caption 
+	if (mDragHandle)
+		mDragHandle->setTitleVisible(TRUE);
+	
+	updateSession();
+
 	return TRUE;
 }
 
@@ -240,7 +248,7 @@ void LLCallFloater::updateSession()
 		}
 	}
 
-	const LLUUID& session_id = voice_channel->getSessionID();
+	const LLUUID& session_id = voice_channel ? voice_channel->getSessionID() : LLUUID::null;
 	lldebugs << "Set speaker manager for session: " << session_id << llendl;
 
 	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
@@ -562,33 +570,46 @@ void LLCallFloater::updateParticipantsVoiceState()
 
 		if (!found)
 		{
-			// If an avatarID is not found in a speakers list from VoiceClient and
-			// a panel with this ID has a JOINED status this means that this person
-			// HAS LEFT the call.
-			if ((getState(participant_id) == STATE_JOINED))
-			{
-				setState(item, STATE_LEFT);
+			updateNotInVoiceParticipantState(item);
+		}
+	}
+}
 
-				LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(item->getAvatarId());
-				if (speaker.isNull())
-				{
-					continue;
-				}
+void LLCallFloater::updateNotInVoiceParticipantState(LLAvatarListItem* item)
+{
+	LLUUID participant_id = item->getAvatarId();
+	ESpeakerState current_state = getState(participant_id);
 
-				speaker->mHasLeftCurrentCall = TRUE;
-			}
-			// If an avatarID is not found in a speakers list from VoiceClient and
-			// a panel with this ID has a LEFT status this means that this person
-			// HAS ENTERED session but it is not in voice chat yet. So, set INVITED status
-			else if ((getState(participant_id) != STATE_LEFT))
-			{
-				setState(item, STATE_INVITED);
-			}
-			else
+	switch (current_state)
+	{
+	case STATE_JOINED:
+		// If an avatarID is not found in a speakers list from VoiceClient and
+		// a panel with this ID has a JOINED status this means that this person
+		// HAS LEFT the call.
+		setState(item, STATE_LEFT);
+
+		{
+			LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(participant_id);
+			if (speaker.notNull())
 			{
-				llwarns << "Unsupported (" << getState(participant_id) << ") state: " << item->getAvatarName()  << llendl;
+				speaker->mHasLeftCurrentCall = TRUE;
 			}
 		}
+		break;
+	case STATE_INVITED:
+	case STATE_LEFT:
+		// nothing to do. These states should not be changed.
+		break;
+	case STATE_UNKNOWN:
+		// If an avatarID is not found in a speakers list from VoiceClient and
+		// a panel with this ID has an UNKNOWN status this means that this person
+		// HAS ENTERED session but it is not in voice chat yet. So, set INVITED status
+		setState(item, STATE_INVITED);
+		break;
+	default:
+		// for possible new future states.
+		llwarns << "Unsupported (" << getState(participant_id) << ") state for: " << item->getAvatarName()  << llendl;
+		break;
 	}
 }
 
diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h
index eded3a426b8fbc8c34ad9756af78025b9987fe3f..766191379ba264a9b9acf02bae630fc5f3d1a04c 100644
--- a/indra/newview/llcallfloater.h
+++ b/indra/newview/llcallfloater.h
@@ -145,6 +145,10 @@ class LLCallFloater : public LLTransientDockableFloater, LLVoiceClientParticipan
 	 */
 	void updateParticipantsVoiceState();
 
+	/**
+	 * Updates voice state of participant not in current voice channel depend on its current state.
+	 */
+	void updateNotInVoiceParticipantState(LLAvatarListItem* item);
 	void setState(LLAvatarListItem* item, ESpeakerState state);
 	void setState(const LLUUID& speaker_id, ESpeakerState state)
 	{
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/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 47f1b7c9f544bd761fff38ea65357392ebbff3fb..5c05a541204800bdb98c951fc04c46b6db01a7f7 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -446,19 +446,17 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
 
 		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
 		{
-			//TODO* CHAT: how to show this?
-			//LLSD args;
-			//args["MESSAGE"] = LLTrans::getString("CompileQueueScriptNotFound);
-			//LLNotificationsUtil::add("SystemMessage", args);
+			LLSD args;
+			args["MESSAGE"] = LLTrans::getString("CompileQueueScriptNotFound");
+			LLNotificationsUtil::add("SystemMessage", args);
 			
 			buffer = LLTrans::getString("CompileQueueProblemDownloading") + (": ") + data->mScriptName;
 		}
 		else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status)
 		{
-			//TODO* CHAT: how to show this?
-			//LLSD args;
-			//args["MESSAGE"] = LLTrans::getString("CompileQueueScriptNotFound);
-			//LLNotificationsUtil::add("SystemMessage", args);
+			LLSD args;
+			args["MESSAGE"] = LLTrans::getString("CompileQueueInsufficientPermDownload");
+			LLNotificationsUtil::add("SystemMessage", args);
 
 			buffer = LLTrans::getString("CompileQueueInsufficientPermFor") + (": ") + data->mScriptName;
 		}
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index ef69f39ad2df5b575ecc7aac9d7575b45c638a94..04f4ddf9960c720dfb1c7579ed1277f9038e0d81 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -187,6 +187,12 @@ BOOL LLFloaterAbout::postBuild()
 		support << '\n' << getString("AboutTraffic", args);
 	}
 
+	// don't make the sim hostname be a hyperlink
+	if (info.has("HOSTNAME"))
+	{
+		support_widget->addBlackListUrl(info["HOSTNAME"].asString());
+	}
+	
 	support_widget->appendText(support.str(), 
 								FALSE, 
 								LLStyle::Params()
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..e77c93b5f8e408b8c4c26ec18e3f1330ee1d36e2 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -327,6 +327,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.AutoDetectAspect",       boost::bind(&LLFloaterPreference::onCommitAutoDetectAspect, this));	
 	mCommitCallbackRegistrar.add("Pref.ParcelMediaAutoPlayEnable",       boost::bind(&LLFloaterPreference::onCommitParcelMediaAutoPlayEnable, this));	
 	mCommitCallbackRegistrar.add("Pref.MediaEnabled",           boost::bind(&LLFloaterPreference::onCommitMediaEnabled, this));	
+	mCommitCallbackRegistrar.add("Pref.MusicEnabled",           boost::bind(&LLFloaterPreference::onCommitMusicEnabled, this));	
 	mCommitCallbackRegistrar.add("Pref.onSelectAspectRatio",    boost::bind(&LLFloaterPreference::onKeystrokeAspectRatio, this));	
 	mCommitCallbackRegistrar.add("Pref.QualityPerformance",     boost::bind(&LLFloaterPreference::onChangeQuality, this, _2));	
 	mCommitCallbackRegistrar.add("Pref.applyUIColor",			boost::bind(&LLFloaterPreference::applyUIColor, this ,_1, _2));
@@ -1001,12 +1002,14 @@ void LLFloaterPreference::onCommitMediaEnabled()
 {
 	LLCheckBoxCtrl *media_enabled_ctrl = getChild<LLCheckBoxCtrl>("media_enabled");
 	bool enabled = media_enabled_ctrl->get();
-	gSavedSettings.setBOOL("AudioStreamingVideo", enabled);
-	gSavedSettings.setBOOL("AudioStreamingMusic", enabled);
 	gSavedSettings.setBOOL("AudioStreamingMedia", enabled);
-	media_enabled_ctrl->setTentative(false);
-	// Update enabled state of the "autoplay" checkbox
-	getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(enabled);
+}
+
+void LLFloaterPreference::onCommitMusicEnabled()
+{
+	LLCheckBoxCtrl *music_enabled_ctrl = getChild<LLCheckBoxCtrl>("music_enabled");
+	bool enabled = music_enabled_ctrl->get();
+	gSavedSettings.setBOOL("AudioStreamingMusic", enabled);
 }
 
 void LLFloaterPreference::refresh()
@@ -1424,17 +1427,16 @@ BOOL LLPanelPreference::postBuild()
 	}
 	
 	//////////////////////PanelPrivacy ///////////////////
-	if(hasChild("media_enabled"))
+	if (hasChild("media_enabled"))
 	{
-		bool video_enabled = gSavedSettings.getBOOL("AudioStreamingVideo");
-		bool music_enabled = gSavedSettings.getBOOL("AudioStreamingMusic");
 		bool media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");
-		bool enabled = video_enabled || music_enabled || media_enabled;
-		
-		LLCheckBoxCtrl *media_enabled_ctrl = getChild<LLCheckBoxCtrl>("media_enabled");	
-		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));
+		getChild<LLCheckBoxCtrl>("media_enabled")->set(media_enabled);
+		getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(media_enabled);
+	}
+	if (hasChild("music_enabled"))
+	{
+		getChild<LLCheckBoxCtrl>("music_enabled")->set(gSavedSettings.getBOOL("AudioStreamingMusic"));
 	}
 	
 	apply();
@@ -1485,6 +1487,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..8778d76a5aa3e911390b5ced95f88953ca340127 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -134,6 +134,7 @@ class LLFloaterPreference : public LLFloater
 	void onCommitAutoDetectAspect();
 	void onCommitParcelMediaAutoPlayEnable();
 	void onCommitMediaEnabled();
+	void onCommitMusicEnabled();
 	void applyResolution();
 	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
 	void getUIColor(LLUICtrl* ctrl, const LLSD& param);	
@@ -166,6 +167,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/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index 0964ad7f917cc88ea10eac2abce6a965f378534c..8875e35821bd3afff0d4e29ba35f3abef13bd297 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -528,7 +528,16 @@ BOOL LLPanelScriptLimitsRegionMemory::postBuild()
 		
 	std::string msg_waiting = LLTrans::getString("ScriptLimitsRequestWaiting");
 	childSetValue("loading_text", LLSD(msg_waiting));
-	
+
+	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("scripts_list");
+
+	//set all columns to resizable mode even if some columns will be empty
+	for(S32 column = 0; column < list->getNumColumns(); column++)
+	{
+		LLScrollListColumn* columnp = list->getColumn(column);
+		columnp->mHeader->setHasResizableElement(TRUE);
+	}
+
 	return StartRequestChain();
 }
 
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..f90a51c3f3794fe7133c2ffb00cbf1438477c680 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -95,7 +95,8 @@ void toast_callback(const LLSD& msg){
 	}
 
 	// check whether incoming IM belongs to an active session or not
-	if (LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
+	if (LLIMModel::getInstance()->getActiveSessionID().notNull()
+			&& LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
 	{
 		return;
 	}
@@ -1577,7 +1578,7 @@ void LLCallDialog::setIcon(const LLSD& session_id, const LLSD& participant_id)
 	}
 }
 
-bool LLOutgoingCallDialog::lifetimeHasExpired()
+bool LLCallDialog::lifetimeHasExpired()
 {
 	if (mLifetimeTimer.getStarted())
 	{
@@ -1590,7 +1591,7 @@ bool LLOutgoingCallDialog::lifetimeHasExpired()
 	return false;
 }
 
-void LLOutgoingCallDialog::onLifetimeExpired()
+void LLCallDialog::onLifetimeExpired()
 {
 	mLifetimeTimer.stop();
 	closeFloater();
@@ -1680,6 +1681,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 +1694,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
 			getChild<LLTextBox>("nearby")->setVisible(true);
 		}
 		getChild<LLButton>("Cancel")->setVisible(false);
+		setCanClose(true);
 		mLifetimeTimer.start();
 	}
 
@@ -1742,19 +1745,6 @@ LLCallDialog(payload)
 {
 }
 
-bool LLIncomingCallDialog::lifetimeHasExpired()
-{
-	if (mLifetimeTimer.getStarted())
-	{
-		F32 elapsed_time = mLifetimeTimer.getElapsedTimeF32();
-		if (elapsed_time > mLifetime) 
-		{
-			return true;
-		}
-	}
-	return false;
-}
-
 void LLIncomingCallDialog::onLifetimeExpired()
 {
 	// check whether a call is valid or not
@@ -3216,6 +3206,42 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 	}
 };
 
+LLCallInfoDialog::LLCallInfoDialog(const LLSD& payload) : LLCallDialog(payload)
+{
+}
+
+BOOL LLCallInfoDialog::postBuild()
+{
+	// init notification's lifetime
+	std::istringstream ss( getString("lifetime") );
+	if (!(ss >> mLifetime))
+	{
+		mLifetime = DEFAULT_LIFETIME;
+	}
+	return LLCallDialog::postBuild();
+}
+
+void LLCallInfoDialog::onOpen(const LLSD& key)
+{
+	if(key.has("msg"))
+	{
+		std::string msg = key["msg"];
+		getChild<LLTextBox>("msg")->setValue(msg);
+	}
+
+	mLifetimeTimer.start();
+}
+
+void LLCallInfoDialog::show(const std::string& status_name, const LLSD& args)
+{
+	LLUIString message = LLTrans::getString(status_name);
+	message.setArgs(args);
+
+	LLSD payload;
+	payload["msg"] = message;
+	LLFloaterReg::showInstance("call_info", payload);
+}
+
 LLHTTPRegistration<LLViewerChatterBoxSessionStartReply>
    gHTTPRegistrationMessageChatterboxsessionstartreply(
 	   "/message/ChatterBoxSessionStartReply");
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index a3b4f78af0c8b702c79f1bf14ccc9683c9f1ac75..0386ff234dd712a46f8c5a3d611c9f1fcc341bf8 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -512,8 +512,8 @@ class LLCallDialog : public LLDockableFloater
 	// notification's lifetime in seconds
 	S32		mLifetime;
 	static const S32 DEFAULT_LIFETIME = 5;
-	virtual bool lifetimeHasExpired() {return false;};
-	virtual void onLifetimeExpired() {};
+	virtual bool lifetimeHasExpired();
+	virtual void onLifetimeExpired();
 
 	virtual void getAllowedRect(LLRect& rect);
 
@@ -543,7 +543,6 @@ class LLIncomingCallDialog : public LLCallDialog
 	static void onStartIM(void* user_data);
 
 private:
-	/*virtual*/ bool lifetimeHasExpired();
 	/*virtual*/ void onLifetimeExpired();
 	void processCallResponse(S32 response);
 };
@@ -562,8 +561,16 @@ class LLOutgoingCallDialog : public LLCallDialog
 private:
 	// hide all text boxes
 	void hideAllText();
-	/*virtual*/ bool lifetimeHasExpired();
-	/*virtual*/ void onLifetimeExpired();
+};
+
+class LLCallInfoDialog : public LLCallDialog
+{
+public:
+	LLCallInfoDialog(const LLSD& payload);
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void onOpen(const LLSD& key);
+
+	static void show(const std::string& status_name, const LLSD& args);
 };
 
 // Globals
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 4b0539337ba56114a62ba6655f167632bc7ed105..3a41aebf2807373ad292134c2661acdf2335caba 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -229,6 +229,7 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
 	mEnableCallbackRegistrar.add("InspectAvatar.VisibleZoomIn", 
 		boost::bind(&LLInspectAvatar::onVisibleZoomIn, this));
 	mEnableCallbackRegistrar.add("InspectAvatar.Gear.Enable", boost::bind(&LLInspectAvatar::isNotFriend, this));
+	mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableCall", boost::bind(&LLAvatarActions::canCall));
 	mEnableCallbackRegistrar.add("InspectAvatar.EnableMute", boost::bind(&LLInspectAvatar::enableMute, this));
 	mEnableCallbackRegistrar.add("InspectAvatar.EnableUnmute", boost::bind(&LLInspectAvatar::enableUnmute, this));
 
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 0ab3b07aea5618f898e7e1fe50acce318755602a..5981baab60e9adc26635e339fdfefe618542373f 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -589,8 +589,16 @@ void LLPanelStandStopFlying::setVisible(BOOL visible)
 		updatePosition();
 	}
 
-	//change visibility of parent layout_panel to animate in/out
-	if (getParent()) getParent()->setVisible(visible);
+	// do not change parent visibility in case panel is attached into Move Floater: EXT-3632, EXT-4646
+	if (!mAttached) 
+	{
+		//change visibility of parent layout_panel to animate in/out. EXT-2504
+		if (getParent()) getParent()->setVisible(visible);
+	}
+
+	// also change own visibility to avoid displaying the panel in mouselook (broken when EXT-2504 was implemented).
+	// See EXT-4718.
+	LLPanel::setVisible(visible);
 }
 
 BOOL LLPanelStandStopFlying::handleToolTip(S32 x, S32 y, MASK mask)
@@ -614,7 +622,7 @@ void LLPanelStandStopFlying::reparent(LLFloaterMove* move_view)
 	LLPanel* parent = dynamic_cast<LLPanel*>(getParent());
 	if (!parent)
 	{
-		llwarns << "Stand/stop flying panel parent is unset" << llendl;
+		llwarns << "Stand/stop flying panel parent is unset, already attached?: " << mAttached << ", new parent: " << (move_view == NULL ? "NULL" : "Move Floater") << llendl;
 		return;
 	}
 
@@ -684,6 +692,7 @@ void LLPanelStandStopFlying::onStopFlyingButtonClick()
 	gAgent.setFlying(FALSE);
 
 	setFocus(FALSE); // EXT-482
+	setVisible(FALSE);
 }
 
 /**
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/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 6375362ae281ca68d2108fc3f7ae4ba01467fd09..9f04558d508282897e9b68a0669b0c9b791b0855 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -148,7 +148,7 @@ BOOL LLNameListCtrl::handleToolTip(S32 x, S32 y, MASK mask)
 		&& column_index == mNameColumnIndex)
 	{
 		// ...this is the column with the avatar name
-		LLUUID avatar_id = getItemId(hit_item);
+		LLUUID avatar_id = hit_item->getUUID();
 		if (avatar_id.notNull())
 		{
 			// ...valid avatar id
@@ -230,14 +230,15 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
 	std::string& suffix)
 {
 	LLUUID id = name_item.value().asUUID();
-	LLScrollListItem* item = NULL;
+	LLNameListItem* item = NULL;
 
 	// Store item type so that we can invoke the proper inspector.
 	// *TODO Vadim: Is there a more proper way of storing additional item data?
 	{
-		LLNameListCtrl::NameItem name_item_(name_item);
-		name_item_.value = LLSD().with("uuid", id).with("is_group", name_item.target() == GROUP);
-		item = LLScrollListCtrl::addRow(name_item_, pos);
+		LLNameListCtrl::NameItem item_p(name_item);
+		item_p.value = LLSD().with("uuid", id).with("is_group", name_item.target() == GROUP);
+		item = new LLNameListItem(item_p);
+		LLScrollListCtrl::addRow(item, item_p, pos);
 	}
 
 	if (!item) return NULL;
@@ -298,7 +299,7 @@ void LLNameListCtrl::removeNameItem(const LLUUID& agent_id)
 	for (item_list::iterator it = getItemList().begin(); it != getItemList().end(); it++)
 	{
 		LLScrollListItem* item = *it;
-		if (getItemId(item) == agent_id)
+		if (item->getUUID() == agent_id)
 		{
 			idx = getItemIndex(item);
 			break;
@@ -335,7 +336,7 @@ void LLNameListCtrl::refresh(const LLUUID& id, const std::string& first,
 	for (iter = getItemList().begin(); iter != getItemList().end(); iter++)
 	{
 		LLScrollListItem* item = *iter;
-		if (getItemId(item) == id)
+		if (item->getUUID() == id)
 		{
 			LLScrollListCell* cell = (LLScrollListCell*)item->getColumn(0);
 			cell = item->getColumn(mNameColumnIndex);
@@ -375,9 +376,3 @@ void LLNameListCtrl::updateColumns()
 		}
 	}
 }
-
-// static
-LLUUID LLNameListCtrl::getItemId(LLScrollListItem* item)
-{
-	return item->getValue()["uuid"].asUUID();
-}
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index 192a3a5afaec62607ca7eb742006ef67ac70221e..23b1cb68975a39e8e342bbe8d2bc0167941a9f54 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -122,7 +122,6 @@ class LLNameListCtrl
 	/*virtual*/ void updateColumns();
 private:
 	void showInspector(const LLUUID& avatar_id, bool is_group);
-	static LLUUID getItemId(LLScrollListItem* item);
 
 private:
 	S32    			mNameColumnIndex;
@@ -130,4 +129,24 @@ class LLNameListCtrl
 	BOOL			mAllowCallingCardDrop;
 };
 
+/**
+ * LLNameListCtrl item
+ * 
+ * We don't use LLScrollListItem to be able to override getUUID(), which is needed
+ * because the name list item value is not simply an UUID but a map (uuid, is_group).
+ */
+class LLNameListItem : public LLScrollListItem
+{
+public:
+	LLUUID	getUUID() const		{ return getValue()["uuid"].asUUID(); }
+
+protected:
+	friend class LLNameListCtrl;
+
+	LLNameListItem( const LLScrollListItem::Params& p )
+	:	LLScrollListItem(p)
+	{
+	}
+};
+
 #endif
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/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index c50e049d4c3d57928214b89e1967ec3875e3a1ff..a1a9d84c14be807ed7d6543ed267cbcd6906d653 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -356,12 +356,17 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg)
 		initChannel();
 	}
 
+	/*
+	//comment all this due to EXT-4432
+	..may clean up after some time...
+
 	//only messages from AGENTS
 	if(CHAT_SOURCE_OBJECT == chat_msg.mSourceType)
 	{
 		if(chat_msg.mChatType == CHAT_TYPE_DEBUG_MSG)
 			return;//ok for now we don't skip messeges from object, so skip only debug messages
 	}
+	*/
 
 	LLUUID id;
 	id.generate();
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index fba577360204f78c78ecbe1a07c26acbb0a0f9bf..02f948eca9dbc445043474e40594534f26c34042 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -123,7 +123,14 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
 				message);
 
 		// restore active session id
-		LLIMModel::instance().setActiveSessionID(active_session_id);
+		if (active_session_id.isNull())
+		{
+			LLIMModel::instance().resetActiveSessionID();
+		}
+		else
+		{
+			LLIMModel::instance().setActiveSessionID(active_session_id);
+		}
 	}
 }
 
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/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 45f0381d6fd839e774c05ae0ca90be971e81bf39..c6287472fed9d80a56235d276695c250207c657e 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -867,7 +867,7 @@ void LLPanelGroupMembersSubTab::handleMemberSelect()
 	for (itor = selection.begin();
 		 itor != selection.end(); ++itor)
 	{
-		LLUUID member_id = (*itor)->getValue()["uuid"];
+		LLUUID member_id = (*itor)->getUUID();
 
 		selected_members.push_back( member_id );
 		// Get this member's power mask including any unsaved changes
@@ -1093,7 +1093,7 @@ void LLPanelGroupMembersSubTab::handleEjectMembers()
 	for (itor = selection.begin() ; 
 		 itor != selection.end(); ++itor)
 	{
-		LLUUID member_id = (*itor)->getValue()["uuid"];
+		LLUUID member_id = (*itor)->getUUID();
 		selected_members.push_back( member_id );
 	}
 
@@ -1151,7 +1151,7 @@ void LLPanelGroupMembersSubTab::handleRoleCheck(const LLUUID& role_id,
 		 itor != selection.end(); ++itor)
 	{
 
-		member_id = (*itor)->getValue()["uuid"];
+		member_id = (*itor)->getUUID();
 
 		//see if we requested a change for this member before
 		if ( mMemberRoleChangeData.find(member_id) == mMemberRoleChangeData.end() )
@@ -1242,7 +1242,7 @@ void LLPanelGroupMembersSubTab::handleMemberDoubleClick()
 	LLScrollListItem* selected = mMembersList->getFirstSelected();
 	if (selected)
 	{
-		LLUUID member_id = selected->getValue()["uuid"];
+		LLUUID member_id = selected->getUUID();
 		LLAvatarActions::showProfile( member_id );
 	}
 }
@@ -1632,7 +1632,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
 
 			LLScrollListItem* member = mMembersList->addElement(row);//, ADD_SORTED);
 
-			LLUUID id = member->getValue()["uuid"];
+			LLUUID id = member->getUUID();
 			mHasMatch = TRUE;
 		}
 	}
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/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index 9654e17659862e9e1d0386dd3a03a36e852781ac..c792fd4fe3a708c20c0e575f656f5e54b1523d05 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -98,10 +98,10 @@ void LLPanelLandmarkInfo::resetLocation()
 {
 	LLPanelPlaceInfo::resetLocation();
 
-	std::string not_available = getString("not_available");
-	mCreator->setText(not_available);
-	mOwner->setText(not_available);
-	mCreated->setText(not_available);
+	std::string loading = LLTrans::getString("LoadingData");
+	mCreator->setText(loading);
+	mOwner->setText(loading);
+	mCreated->setText(loading);
 	mLandmarkTitle->setText(LLStringUtil::null);
 	mLandmarkTitleEditor->setText(LLStringUtil::null);
 	mNotesEditor->setText(LLStringUtil::null);
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/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 0c10f11bfcbcd54a08eecdc9b44d1094f64d59bc..5f75668722eca299be8d04c74534a2cba0c54c79 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -43,6 +43,8 @@
 #include "lliconctrl.h"
 #include "lltextbox.h"
 
+#include "lltrans.h"
+
 #include "llagent.h"
 #include "llexpandabletextbox.h"
 #include "llpanelpick.h"
@@ -99,12 +101,12 @@ void LLPanelPlaceInfo::resetLocation()
 	mRequestedID.setNull();
 	mPosRegion.clearVec();
 
-	std::string not_available = getString("not_available");
-	mMaturityRatingIcon->setValue(not_available);
-	mMaturityRatingText->setValue(not_available);
-	mRegionName->setText(not_available);
-	mParcelName->setText(not_available);
-	mDescEditor->setText(not_available);
+	std::string loading = LLTrans::getString("LoadingData");
+	mMaturityRatingIcon->setValue(loading);
+	mMaturityRatingText->setValue(loading);
+	mRegionName->setText(loading);
+	mParcelName->setText(loading);
+	mDescEditor->setText(loading);
 
 	mSnapshotCtrl->setImageAssetID(LLUUID::null);
 	mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c");
@@ -206,6 +208,10 @@ void LLPanelPlaceInfo::processParcelInfo(const LLParcelData& parcel_data)
 	{
 		mDescEditor->setText(parcel_data.desc);
 	}
+	else
+	{
+		mDescEditor->setText(getString("not_available"));
+	}
 
 	S32 region_x;
 	S32 region_y;
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index d892e2885b4358e2714e6dd0ecab9034ec01f7a5..3c798639d4ecac574bef5f9868b3db1c206fc44f 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -42,6 +42,8 @@
 #include "lltextbox.h"
 #include "lltexteditor.h"
 
+#include "lltrans.h"
+
 #include "llaccordionctrl.h"
 #include "llaccordionctrltab.h"
 #include "llagent.h"
@@ -163,45 +165,45 @@ void LLPanelPlaceProfile::resetLocation()
 	mForSalePanel->setVisible(FALSE);
 	mYouAreHerePanel->setVisible(FALSE);
 
-	std::string not_available = getString("not_available");
-	mParcelOwner->setValue(not_available);
-
-	mParcelRatingIcon->setValue(not_available);
-	mParcelRatingText->setText(not_available);
-	mVoiceIcon->setValue(not_available);
-	mVoiceText->setText(not_available);
-	mFlyIcon->setValue(not_available);
-	mFlyText->setText(not_available);
-	mPushIcon->setValue(not_available);
-	mPushText->setText(not_available);
-	mBuildIcon->setValue(not_available);
-	mBuildText->setText(not_available);
-	mScriptsIcon->setValue(not_available);
-	mScriptsText->setText(not_available);
-	mDamageIcon->setValue(not_available);
-	mDamageText->setText(not_available);
-
-	mRegionNameText->setValue(not_available);
-	mRegionTypeText->setValue(not_available);
-	mRegionRatingIcon->setValue(not_available);
-	mRegionRatingText->setValue(not_available);
-	mRegionOwnerText->setValue(not_available);
-	mRegionGroupText->setValue(not_available);
-
-	mEstateNameText->setValue(not_available);
-	mEstateRatingText->setValue(not_available);
-	mEstateOwnerText->setValue(not_available);
-	mCovenantText->setValue(not_available);
-
-	mSalesPriceText->setValue(not_available);
-	mAreaText->setValue(not_available);
-	mTrafficText->setValue(not_available);
-	mPrimitivesText->setValue(not_available);
-	mParcelScriptsText->setValue(not_available);
-	mTerraformLimitsText->setValue(not_available);
-	mSubdivideText->setValue(not_available);
-	mResaleText->setValue(not_available);
-	mSaleToText->setValue(not_available);
+	std::string loading = LLTrans::getString("LoadingData");
+	mParcelOwner->setValue(loading);
+
+	mParcelRatingIcon->setValue(loading);
+	mParcelRatingText->setText(loading);
+	mVoiceIcon->setValue(loading);
+	mVoiceText->setText(loading);
+	mFlyIcon->setValue(loading);
+	mFlyText->setText(loading);
+	mPushIcon->setValue(loading);
+	mPushText->setText(loading);
+	mBuildIcon->setValue(loading);
+	mBuildText->setText(loading);
+	mScriptsIcon->setValue(loading);
+	mScriptsText->setText(loading);
+	mDamageIcon->setValue(loading);
+	mDamageText->setText(loading);
+
+	mRegionNameText->setValue(loading);
+	mRegionTypeText->setValue(loading);
+	mRegionRatingIcon->setValue(loading);
+	mRegionRatingText->setValue(loading);
+	mRegionOwnerText->setValue(loading);
+	mRegionGroupText->setValue(loading);
+
+	mEstateNameText->setValue(loading);
+	mEstateRatingText->setValue(loading);
+	mEstateOwnerText->setValue(loading);
+	mCovenantText->setValue(loading);
+
+	mSalesPriceText->setValue(loading);
+	mAreaText->setValue(loading);
+	mTrafficText->setValue(loading);
+	mPrimitivesText->setValue(loading);
+	mParcelScriptsText->setValue(loading);
+	mTerraformLimitsText->setValue(loading);
+	mSubdivideText->setValue(loading);
+	mResaleText->setValue(loading);
+	mSaleToText->setValue(loading);
 }
 
 // virtual
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index a4f0e55a93258b36d1f0427ed823d844356e27aa..7272a8a652c6acf2b202712a23fae11a6f4ff329 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -34,7 +34,7 @@
 #include "llpanelplaces.h"
 
 #include "llassettype.h"
-#include "llwindow.h"
+#include "lltimer.h"
 
 #include "llinventory.h"
 #include "lllandmark.h"
@@ -49,6 +49,8 @@
 #include "lltrans.h"
 #include "lluictrlfactory.h"
 
+#include "llwindow.h"
+
 #include "llagent.h"
 #include "llagentpicksinfo.h"
 #include "llavatarpropertiesprocessor.h"
@@ -73,6 +75,7 @@
 #include "llviewerwindow.h"
 
 static const S32 LANDMARK_FOLDERS_MENU_WIDTH = 250;
+static const F32 PLACE_INFO_UPDATE_INTERVAL = 3.0;
 static const std::string AGENT_INFO_TYPE			= "agent";
 static const std::string CREATE_LANDMARK_INFO_TYPE	= "create_landmark";
 static const std::string LANDMARK_INFO_TYPE			= "landmark";
@@ -384,6 +387,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());
 	}
@@ -826,6 +833,10 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
 		{
 			mPlaceProfile->resetLocation();
 
+			// Do not reset location info until mResetInfoTimer has expired
+			// to avoid text blinking.
+			mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL);
+
 			LLRect rect = getRect();
 			LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom);
 			mPlaceProfile->reshape(new_rect.getWidth(), new_rect.getHeight());
@@ -898,6 +909,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 +927,14 @@ void LLPanelPlaces::changedParcelSelection()
 		}
 	}
 
-	mPlaceProfile->resetLocation();
+	// Reset location info only if global position has changed
+	// and update timer has expired to reduce unnecessary text and icons updates.
+	if (prev_pos_global != mPosGlobal && mResetInfoTimer.hasExpired())
+	{
+		mPlaceProfile->resetLocation();
+		mResetInfoTimer.setTimerExpirySec(PLACE_INFO_UPDATE_INTERVAL);
+	}
+
 	mPlaceProfile->displaySelectedParcelInfo(parcel, region, mPosGlobal, is_current_parcel);
 
 	updateVerbs();
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 0eba7f3afc1b8af8e73fcc6cbe480dc44c10652a..a0989746599ec0726ca52f5fa4d9c011a05c4707 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -34,6 +34,8 @@
 
 #include "llpanel.h"
 
+class LLTimer;
+
 class LLInventoryItem;
 class LLFilterEditor;
 class LLLandmark;
@@ -132,6 +134,10 @@ class LLPanelPlaces : public LLPanel
 	// be available (hence zero)
 	LLVector3d					mPosGlobal;
 
+	// Sets a period of time during which the requested place information
+	// is expected to be updated and doesn't need to be reset.
+	LLTimer						mResetInfoTimer;
+
 	// Information type currently shown in Place Information panel
 	std::string					mPlaceInfoType;
 
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..d54cbfe20317458cfc313fc2a3df8559fd567c3a 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -433,6 +433,12 @@ LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
 	LLContextMenu* main_menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
 		"menu_participant_list.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
 
+	// AD *TODO: This is workaround for EXT-4725- way to properly enable/disable "Call" menu item in
+	// enableContextMenuItem() should be found.
+	bool not_agent = mUUIDs.front() != gAgentID;
+	bool can_call = not_agent && LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
+	main_menu->setItemEnabled("Call", can_call);
+
 	// Don't show sort options for P2P chat
 	bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1);
 	main_menu->setItemVisible("SortByName", is_sort_visible);
@@ -628,7 +634,9 @@ bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD&
 	}
 	else if (item == "can_call")
 	{
-		return LLVoiceClient::voiceEnabled();
+		bool not_agent = mUUIDs.front() != gAgentID;
+		bool can_call = not_agent && LLVoiceClient::voiceEnabled() && gVoiceClient->voiceWorking();
+		return can_call;
 	}
 
 	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/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index a08e77e3d88911b6e87b617c3cf00b4514b83ecd..c79a66892d56be16a425262b83e2dc32165e829f 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -68,7 +68,6 @@
 #include "llviewermedia.h"
 #include "llvoavatarself.h"
 #include "llviewermediafocus.h"
-#include "llvovolume.h"
 #include "llworld.h"
 #include "llui.h"
 #include "llweb.h"
@@ -630,14 +629,12 @@ static bool needs_tooltip(LLSelectNode* nodep)
 		return false;
 
 	LLViewerObject* object = nodep->getObject();
-	LLVOVolume* vovolume = dynamic_cast<LLVOVolume*>(object);
 	LLViewerObject *parent = (LLViewerObject *)object->getParent();
 	if (object->flagHandleTouch()
 		|| (parent && parent->flagHandleTouch())
 		|| object->flagTakesMoney()
 		|| (parent && parent->flagTakesMoney())
 		|| object->flagAllowInventoryAdd()
-		|| (vovolume && vovolume->hasMedia())
 		)
 	{
 		return true;
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/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index f650bdbbd13f8a88e45a024786b5f2b424930dd6..2d9e2ef7c9cfb26a9bfe920eb543ddd414c32358 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -208,6 +208,7 @@ void LLViewerFloaterReg::registerFloaters()
 
 	LLFloaterReg::add("openobject", "floater_openobject.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterOpenObject>);
 	LLFloaterReg::add("outgoing_call", "floater_outgoing_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLOutgoingCallDialog>);
+	LLFloaterReg::add("call_info", "floater_call_info.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallInfoDialog>);
 	LLFloaterReg::add("parcel_info", "floater_preview_url.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterParcelInfo>);
 	LLFloaterPayUtil::registerFloater();
 
diff --git a/indra/newview/llviewerhelp.cpp b/indra/newview/llviewerhelp.cpp
index 5af79b4fd32a3f40224534b57acd85109f591c05..b82538dacba001639f06ae59b505be4c7f946474 100644
--- a/indra/newview/llviewerhelp.cpp
+++ b/indra/newview/llviewerhelp.cpp
@@ -33,6 +33,7 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llcommandhandler.h"
 #include "llfloaterhelpbrowser.h"
 #include "llfloaterreg.h"
 #include "llfocusmgr.h"
@@ -43,6 +44,33 @@
 #include "llviewerhelputil.h"
 #include "llviewerhelp.h"
 
+// support for secondlife:///app/help/{TOPIC} SLapps
+class LLHelpHandler : public LLCommandHandler
+{
+public:
+	// requests will be throttled from a non-trusted browser
+	LLHelpHandler() : LLCommandHandler("help", UNTRUSTED_THROTTLE) {}
+
+	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
+	{
+		LLViewerHelp* vhelp = LLViewerHelp::getInstance();
+		if (! vhelp)
+		{
+			return false;
+		}
+
+		// get the requested help topic name, or use the fallback if none
+		std::string help_topic = vhelp->defaultTopic();
+		if (params.size() >= 1)
+		{
+			help_topic = params[0].asString();
+		}
+
+		vhelp->showTopic(help_topic);
+		return true;
+	}
+};
+LLHelpHandler gHelpHandler;
 
 //////////////////////////////
 // implement LLHelp interface
@@ -65,18 +93,16 @@ void LLViewerHelp::showTopic(const std::string &topic)
 		help_topic = defaultTopic();
 	}
 
-	// f1 help topic means: if user not logged in yet, show the
-	// pre-login topic, otherwise show help for the focused item
+	// f1 help topic means: if the user is not logged in yet, show
+	// the pre-login topic instead of the default fallback topic,
+	// otherwise show help for the focused item
 	if (help_topic == f1HelpTopic())
 	{
-		if (! LLLoginInstance::getInstance()->authSuccess())
+		help_topic = getTopicFromFocus();
+		if (help_topic == defaultTopic() && ! LLLoginInstance::getInstance()->authSuccess())
 		{
 			help_topic = preLoginTopic();
 		}
-		else
-		{
-			help_topic = getTopicFromFocus();
-		}
 	}
 
 	// work out the URL for this topic and display it 
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 917b8747eaab195df6c244bb02263ec5a3ad074e..7f3f019b070314587563c05e092cfb79812da11c 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -58,7 +58,6 @@ class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::tr
 protected:
 	~LLViewerInventoryItem( void ); // ref counted
 	BOOL extractSortFieldAndDisplayName(S32* sortField, std::string* displayName) const { return extractSortFieldAndDisplayName(mName, sortField, displayName); }
-	static char getSeparator() { return '@'; }
 	mutable std::string mDisplayName;
 	
 public:
@@ -67,6 +66,7 @@ class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::tr
 	virtual const std::string& getName() const;
 	virtual const std::string& getDisplayName() const;
 	static std::string getDisplayName(const std::string& name);
+	static char getSeparator() { return '@'; }
 	virtual S32 getSortField() const;
 	virtual void setSortField(S32 sortField);
 	virtual void rename(const std::string& new_name);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index d712446d836ac9f1feb704f09cb8852387bb0c9c..98d8780b3432754801c7545e303e595895946b87 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -940,7 +940,6 @@ bool LLViewerMedia::firstRunCallback(const LLSD& notification, const LLSD& respo
 	{
 		// user has elected to automatically play media.
 		gSavedSettings.setBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING, TRUE);
-		gSavedSettings.setBOOL("AudioStreamingVideo", TRUE);
 		gSavedSettings.setBOOL("AudioStreamingMusic", TRUE);
 		gSavedSettings.setBOOL("AudioStreamingMedia", TRUE);
 
@@ -961,7 +960,6 @@ bool LLViewerMedia::firstRunCallback(const LLSD& notification, const LLSD& respo
 	{
 		gSavedSettings.setBOOL(LLViewerMedia::AUTO_PLAY_MEDIA_SETTING, FALSE);
 		gSavedSettings.setBOOL("AudioStreamingMedia", FALSE);
-		gSavedSettings.setBOOL("AudioStreamingVideo", FALSE);
 		gSavedSettings.setBOOL("AudioStreamingMusic", FALSE);
 	}
 	return false;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 79aae9463b0e25583369582db1a3a151076905c1..0801e53fbfcd5df47df6a61c24b83b4cd93975a2 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -6389,10 +6389,9 @@ void handle_selected_texture_info(void*)
    		msg.assign("Texture info for: ");
    		msg.append(node->mName);
 
-		//TODO* CHAT: how to show this?
-		//LLSD args;
-		//args["MESSAGE"] = msg;
-		//LLNotificationsUtil::add("SystemMessage", args);
+		LLSD args;
+		args["MESSAGE"] = msg;
+		LLNotificationsUtil::add("SystemMessage", args);
 	   
    		U8 te_count = node->getObject()->getNumTEs();
    		// map from texture ID to list of faces using it
@@ -6425,10 +6424,9 @@ void handle_selected_texture_info(void*)
    				msg.append( llformat("%d ", (S32)(it->second[i])));
    			}
 
-			//TODO* CHAT: how to show this?
-			//LLSD args;
-			//args["MESSAGE"] = msg;
-			//LLNotificationsUtil::add("SystemMessage", args);
+			LLSD args;
+			args["MESSAGE"] = msg;
+			LLNotificationsUtil::add("SystemMessage", args);
    		}
 	}
 }
@@ -7959,6 +7957,7 @@ void initialize_menus()
 	commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD()));
 	view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM");
 	view_listener_t::addMenu(new LLAvatarCall(), "Avatar.Call");
+	enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));
 	view_listener_t::addMenu(new LLAvatarReportAbuse(), "Avatar.ReportAbuse");
 	
 	view_listener_t::addMenu(new LLAvatarEnableAddFriend(), "Avatar.EnableAddFriend");
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index c463beb3757c0a71c880313d726c557ad65d5f92..79c887844afdb3fc67bcd4c70e9fcb38b0e6a4e5 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1365,10 +1365,9 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 			if (check_offer_throttle(mFromName, true))
 			{
 				log_message = chatHistory_string + " " + LLTrans::getString("InvOfferGaveYou") + " " + mDesc + LLTrans::getString(".");
-				//TODO* CHAT: how to show this?
-				//LLSD args;
-				//args["MESSAGE"] = log_message;
-				//LLNotificationsUtil::add("SystemMessage", args);
+				LLSD args;
+				args["MESSAGE"] = log_message;
+				LLNotificationsUtil::add("SystemMessage", args);
 			}
 			
 			// we will want to open this item when it comes back.
@@ -1410,11 +1409,10 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 			// send the message
 			msg->sendReliable(mHost);
 			
-			//TODO* CHAT: how to show this?
-			//log_message = LLTrans::getString("InvOfferYouDecline") + " " + mDesc + " " + LLTrans::getString("InvOfferFrom") + " " + mFromName +".";
-			//LLSD args;
-			//args["MESSAGE"] = log_message;
-			//LLNotificationsUtil::add("SystemMessage", args);
+			log_message = LLTrans::getString("InvOfferYouDecline") + " " + mDesc + " " + LLTrans::getString("InvOfferFrom") + " " + mFromName +".";
+			LLSD args;
+			args["MESSAGE"] = log_message;
+			LLNotificationsUtil::add("SystemMessage", args);
 			
 			if (busy &&	(!mFromGroup && !mFromObject))
 			{
@@ -1436,6 +1434,31 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 	return false;
 }
 
+std::string get_display_name(const std::string& name)
+{
+	// We receive landmark name as \'<n>@name\' where <n> is a number
+	// LLViewerInventoryItem::getDisplayName will remove \'<n>@ though we need the \'
+	// Lets save all chars preceding @ and insert them back after <n>@ was removed
+
+	std::string saved;
+
+	if(std::string::npos != name.find(LLViewerInventoryItem::getSeparator()))
+	{
+		int n = 0;
+		while(!isdigit(name[n]) && LLViewerInventoryItem::getSeparator() != name[n])
+		{
+			++n;
+		}
+		saved = name.substr(0, n);
+	}
+
+	std::string d_name = LLViewerInventoryItem::getDisplayName(name);
+	d_name.insert(0, saved);
+	LLStringUtil::trim(d_name);
+
+	return d_name;
+}
+
 void inventory_offer_handler(LLOfferInfo* info)
 {
 	//Until throttling is implmented, busy mode should reject inventory instead of silently
@@ -1475,7 +1498,7 @@ void inventory_offer_handler(LLOfferInfo* info)
 
 	if(LLAssetType::AT_LANDMARK == info->mType)
 	{
-		msg = LLViewerInventoryItem::getDisplayName(msg);
+		msg = get_display_name(msg);
 	}
 
 	LLSD args;
@@ -1843,11 +1866,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				// history.  Pretend the chat is from a local agent,
 				// so it will go into the history but not be shown on screen.
 
-				//TODO* CHAT: how to show this?
-				//and this is not system message...
-				//LLSD args;
-				//args["MESSAGE"] = buffer;
-				//LLNotificationsUtil::add("SystemMessage", args);
+				LLSD args;
+				args["MESSAGE"] = buffer;
+				LLNotificationsUtil::add("SystemMessageTip", args);
 			}
 		}
 		break;
@@ -3078,10 +3099,9 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 		{
 			// Chat the "back" SLURL. (DEV-4907)
 
-			//TODO* CHAT: how to show this?
-			//LLSD args;
-			//args["MESSAGE"] = message;
-			//LLNotificationsUtil::add("SystemMessage", args);
+			LLSD args;
+			args["MESSAGE"] = "Teleport completed from " + gAgent.getTeleportSourceSLURL();
+			LLNotificationsUtil::add("SystemMessageTip", args);
 
 			// Set the new position
 			avatarp->setPositionAgent(agent_pos);
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index e87dbe5c07fafceb28f0d223bc25ef66db4de43c..c4fc2e5cabf73e7abb8ad58ba5e172c2d5a72317 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -179,7 +179,7 @@ void LLViewerParcelMedia::play(LLParcel* parcel)
 
 	if (!parcel) return;
 
-	if (!gSavedSettings.getBOOL("AudioStreamingMedia") || !gSavedSettings.getBOOL("AudioStreamingVideo"))
+	if (!gSavedSettings.getBOOL("AudioStreamingMedia"))
 		return;
 
 	std::string media_url = parcel->getMediaURL();
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 73dc9745cbb3845a4b85a7e04216542c12f875fc..7e6a4c00c6151f39f591b8f4724ce743c2e8ccb2 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -2777,7 +2777,6 @@ void LLViewerMediaTexture::updateClass()
 #if 0
 	//force to play media.
 	gSavedSettings.setBOOL("AudioStreamingMedia", true) ;
-	gSavedSettings.setBOOL("AudioStreamingVideo", true) ;
 #endif
 
 	for(media_map_t::iterator iter = sMediaMap.begin() ; iter != sMediaMap.end(); )
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index 917d69fe16d7dd828ea38c3a073a926cb2e1c580..589999c0264fa7b0688d90e1d62bb68bebc0e2fd 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -389,13 +389,13 @@ void LLVoiceChannel::setState(EState state)
 	switch(state)
 	{
 	case STATE_RINGING:
-		gIMMgr->addSystemMessage(mSessionID, "ringing", mNotifyArgs);
+		LLCallInfoDialog::show("ringing", mNotifyArgs);
 		break;
 	case STATE_CONNECTED:
-		gIMMgr->addSystemMessage(mSessionID, "connected", mNotifyArgs);
+		LLCallInfoDialog::show("connected", mNotifyArgs);
 		break;
 	case STATE_HUNG_UP:
-		gIMMgr->addSystemMessage(mSessionID, "hang_up", mNotifyArgs);
+		LLCallInfoDialog::show("hang_up", mNotifyArgs);
 		break;
 	default:
 		break;
@@ -635,7 +635,7 @@ void LLVoiceChannelGroup::setState(EState state)
 	case STATE_RINGING:
 		if ( !mIsRetrying )
 		{
-			gIMMgr->addSystemMessage(mSessionID, "ringing", mNotifyArgs);
+			LLCallInfoDialog::show("ringing", mNotifyArgs);
 		}
 
 		doSetState(state);
@@ -698,7 +698,7 @@ void LLVoiceChannelProximal::handleStatusChange(EStatusType status)
 		// do not notify user when leaving proximal channel
 		return;
 	case STATUS_VOICE_DISABLED:
-		 gIMMgr->addSystemMessage(LLUUID::null, "unavailable", mNotifyArgs);
+		LLCallInfoDialog::show("unavailable", mNotifyArgs);
 		return;
 	default:
 		break;
@@ -897,7 +897,7 @@ void LLVoiceChannelP2P::setState(EState state)
 		// so provide a special purpose message here
 		if (mReceivedCall && state == STATE_RINGING)
 		{
-			gIMMgr->addSystemMessage(mSessionID, "answering", mNotifyArgs);
+			LLCallInfoDialog::show("answering", mNotifyArgs);
 			doSetState(state);
 			return;
 		}
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_aaa.xml b/indra/newview/skins/default/xui/en/floater_aaa.xml
index 0b48ba9321a9ddfd88eb1a585a6e19b34d917ab2..b4d2dabc5c81f896724f5678e4f7e796fc4c7fb8 100644
--- a/indra/newview/skins/default/xui/en/floater_aaa.xml
+++ b/indra/newview/skins/default/xui/en/floater_aaa.xml
@@ -18,7 +18,8 @@
  single_instance="true" 
  width="320">
   <string name="nudge_parabuild">Nudge 1</string>
-  <string name="test_the_vlt">This string CHANGE is extracted.</string>
+  <string name="test_the_vlt">This string CHANGE2 is extracted.</string>
+  <string name="testing_eli">Just a test. change here. more change.</string>
   <chat_history
    allow_html="true"
    bg_readonly_color="ChatHistoryBgColor"
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_search.xml b/indra/newview/skins/default/xui/en/floater_search.xml
index b0bb282abd42e715672c9a396f4b271d898dfc2f..775e7d66f791ca5af92a55016a3d1d2568dd15db 100644
--- a/indra/newview/skins/default/xui/en/floater_search.xml
+++ b/indra/newview/skins/default/xui/en/floater_search.xml
@@ -2,9 +2,9 @@
 <floater
  legacy_header_height="13"
  can_resize="true"
- height="646"
+ height="546"
  layout="topleft"
- min_height="646"
+ min_height="546"
  min_width="670"
  name="floater_search"
  help_topic="floater_search"
@@ -21,7 +21,7 @@
         Done
     </floater.string>
     <layout_stack
-     bottom="641"
+     bottom="541"
      follows="left|right|top|bottom"
      layout="topleft"
      left="10"
@@ -42,7 +42,7 @@
              left="0"
              name="browser"
              top="0"
-             height="600"
+             height="500"
              width="650" />
             <text
              follows="bottom|left"
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/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index 5b94645b603af76db3d12c70a6dadb88e5c00be6..c5b31c7f631a8190b175c5c6291208404ea7db6c 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -30,6 +30,8 @@
      name="Call">
         <menu_item_call.on_click
          function="Avatar.Call" />
+        <menu_item_call.on_enable
+         function="Avatar.EnableCall" />
     </menu_item_call>
       <menu_item_call
          label="Invite to Group"
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
index 0ad41546d204575e0eb369304c55a3f76a1b8c9b..ac9101cfd907befa6e12d2031c0c9e0b6793f4ab 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -30,6 +30,8 @@
      name="Call">
         <menu_item_call.on_click
          function="Avatar.Call" />
+        <menu_item_call.on_enable
+         function="Avatar.EnableCall" />
     </menu_item_call>
       <menu_item_call
          label="Invite to Group"
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
index dde92f23b6b5d94b89c9ae0ce3b88c0174e771c7..85ec174829104e66108e4bb2fa25fa72a65501be 100644
--- a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
@@ -32,6 +32,8 @@
    name="call">
     <menu_item_call.on_click
      function="InspectAvatar.Call"/>
+    <menu_item_call.on_enable
+     function="InspectAvatar.Gear.EnableCall"/>
   </menu_item_call>
   <menu_item_call
    label="Teleport"
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index a0dec346a4fd4eb5aea8bbfedb02aebe19a1727f..5f38522758161132b29cd73a13ea8412ae559b95 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -10,6 +10,7 @@
     <menu
      create_jump_keys="true"
      label="Me"
+     tear_off="true"
      name="File">
         <menu_item_call
          label="Preferences"
@@ -39,6 +40,7 @@
     <menu
      create_jump_keys="true"
      label="Help"
+     tear_off="true"
      name="Help">
         <menu_item_call
          label="[SECOND_LIFE] Help"
diff --git a/indra/newview/skins/default/xui/en/menu_participant_list.xml b/indra/newview/skins/default/xui/en/menu_participant_list.xml
index 805ffbae6688f1a0f6622e5fdeca6224c9d02829..04e02d0f6cc6e3500a322f572f46b5423720952f 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_list.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_list.xml
@@ -57,9 +57,6 @@
      name="Call">
          <menu_item_call.on_click
          function="Avatar.Call" />
-        <menu_item_call.on_enable
-         function="ParticipantList.EnableItem"
-         parameter="can_call" />
     </menu_item_call>
     <menu_item_call
      enabled="true"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 4279097f6205f4a241216973823d7234f6e420fc..0fe4e19bf1ec5aff1ef0b6ab51ddf1e2410a162b 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>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index a8e24366f270110a018252dbd1719e6f5186f7da..0aaeb6114ee89f2b1d81713f9631f51f7c8552b5 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -78,19 +78,19 @@
      top_pad="10"
      width="350" />
 	<check_box
-     control_name="MediaEnabled"
+     name="media_enabled"
+     control_name="AudioStreamingMedia"
      height="16"
      label="Media Enabled"
      layout="topleft"
      left="30"
-     name="media_enabled"
      top_pad="10"
      width="350">
        <check_box.commit_callback
           function="Pref.MediaEnabled" />
     </check_box>
 	<check_box
-	 enabled_control="MediaEnabled"
+	 enabled_control="AudioStreamingMedia"
      control_name="ParcelMediaAutoPlayEnable"
      height="16"
      label="Allow Media to auto-play"
@@ -102,7 +102,19 @@
        <check_box.commit_callback
           function="Pref.ParcelMediaAutoPlayEnable" />
     </check_box>
-   <text
+	<check_box
+     control_name="AudioStreamingMusic"
+     height="16"
+     label="Music Enabled"
+     layout="topleft"
+     left="30"
+     name="music_enabled"
+     top_pad="10"
+     width="350">
+       <check_box.commit_callback
+          function="Pref.MusicEnabled" />
+    </check_box>
+	<text
       type="string"
     length="1"
     follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 17ababe8548752b44fa3c762c8f132adf1eaec49..8723e0a832728d72c254ff57ef21bb58b2102457 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -279,7 +279,7 @@
       width="480" />
     <radio_item
       height="20"
-      label="Use my browser (IE, Firefox)"
+      label="Use my browser (IE, Firefox, Safari)"
       layout="topleft"
       left_delta="0"
       name="external"
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
index 4f40e008156540420154556f992c4eaf6fc47e86..c5f3fcc27df8db88e51b7c96d022ec3928865ab4 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history_item.xml
@@ -41,6 +41,7 @@
      height="20"
      layout="topleft"
      left_pad="5"
+     allow_html="false"
      use_ellipses="true"
      name="region"
      text_color="white"
diff --git a/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml b/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
index ad3872587cd174c4061aaa72e51951965c799476..0552cd3108079355ef007f6d950c9d2382d5927b 100644
--- a/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/fr/floater_bulk_perms.xml
@@ -33,7 +33,7 @@
 	<button label="√ Tout" label_selected="Tout" name="check_all"/>
 	<button label="Effacer" label_selected="Aucun" name="check_none"/>
 	<text name="newperms">
-		Nouvelles permissions relatives au contenu
+		Nouvelles permissions
 	</text>
 	<text name="GroupLabel">
 		Groupe :
diff --git a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
index 5d3a2e6312f2772ecfc8017724cbe95e88f47257..4ca251f3d9386310f40eb28ad90da8a5b224691a 100644
--- a/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/fr/floater_buy_currency.xml
@@ -28,7 +28,7 @@
 		1234
 	</line_editor>
 	<text name="buying_label">
-		Pour le prix
+		Pour
 	</text>
 	<text left_delta="68" name="currency_est" width="138">
 		environ [LOCALAMOUNT]
@@ -57,7 +57,7 @@
 	<text bottom_delta="16" name="purchase_warning_notenough">
 		Vous n&apos;achetez pas assez de L$. Veuillez augmenter le montant.
 	</text>
-	<button label="Acheter maintenant" name="buy_btn"/>
+	<button label="Acheter" name="buy_btn"/>
 	<button label="Annuler" name="cancel_btn"/>
 	<text left="5" name="info_cannot_buy" right="-5">
 		Achat impossible
diff --git a/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml b/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
index 7727e1b65724325ef7d0e48671be379e2e35fe3c..52f8597dc27984cb1b0435c6aad96c98d581945b 100644
--- a/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
+++ b/indra/newview/skins/default/xui/fr/floater_inventory_view_finder.xml
@@ -13,8 +13,7 @@
 	<check_box label="Photos" name="check_snapshot"/>
 	<button label="Tout" label_selected="Tout" name="All" width="70"/>
 	<button bottom_delta="0" label="Aucun" label_selected="Aucun" left="83" name="None" width="70"/>
-	<check_box bottom_delta="-20" label="Toujours montrer 
-les dossiers" name="check_show_empty"/>
+	<check_box bottom_delta="-20" label="Toujours montrer  les dossiers" name="check_show_empty"/>
 	<check_box bottom_delta="-36" label="Depuis la déconnexion" name="check_since_logoff"/>
 	<text name="- OR -">
 		Ou il y a...
diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml
index 2d5def55f3a812b0ae3fb01b729465b40b16ad90..9639e8415d9c62207a4fe60536ff4a287ea7c1d9 100644
--- a/indra/newview/skins/default/xui/fr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml
@@ -49,7 +49,7 @@
 		<menu_item_check label="Mini-carte" name="Mini-Map"/>
 		<menu_item_check label="Carte du monde" name="World Map"/>
 		<menu_item_call label="Photo" name="Take Snapshot"/>
-		<menu label="Soleil" name="Environment Settings">
+		<menu label="Luminosité" name="Environment Settings">
 			<menu_item_call label="Aube" name="Sunrise"/>
 			<menu_item_call label="Milieu de journée" name="Noon"/>
 			<menu_item_call label="Coucher de soleil" name="Sunset"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_skin.xml b/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
index 5f9f49c9e86af283f57d481cdc21fd6aca2cd2ed..649b91d66de5edb37650c48ee1a2ec48472f189d 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_skin.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_skin_panel">
 	<panel name="avatar_skin_color_panel">
-		<texture_picker label="Tatouages tête" name="Head Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
-		<texture_picker label="Tatouages haut" name="Upper Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
-		<texture_picker label="Tatouages bas" name="Lower Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Tatouage tête" name="Head Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Tatouage haut" name="Upper Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Tatouage bas" name="Lower Tattoos" tool_tip="Cliquez pour sélectionner une image"/>
 	</panel>
 	<accordion name="wearable_accordion">
 		<accordion_tab name="skin_color_tab" title="Couleur de peau"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
index ea6cee1da5c637345994b9b875811dd523579735..9a98581cb4c5ac95417b36f388df2b6ee41d1e7a 100644
--- a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
@@ -15,7 +15,7 @@
 	</panel>
 	<menu_bar name="Inventory Menu">
 		<menu label="Fichier" name="File">
-			<menu_item_call label="Ouvert" name="Open"/>
+			<menu_item_call label="Ouvrir" name="Open"/>
 			<menu label="Charger" name="upload">
 				<menu_item_call label="Image ([COST] L$)..." name="Upload Image"/>
 				<menu_item_call label="Son ([COST] L$)..." name="Upload Sound"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_notes.xml b/indra/newview/skins/default/xui/fr/panel_notes.xml
index 7fa583c32bd39e8375fb83c7f158bebc4bacc308..0195118fd8082c643b6cd3d8a2b3ee63ea0a46b8 100644
--- a/indra/newview/skins/default/xui/fr/panel_notes.xml
+++ b/indra/newview/skins/default/xui/fr/panel_notes.xml
@@ -1,10 +1,10 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel label="Notes et vie privée" name="panel_notes">
+<panel label="Notes/Perso" name="panel_notes">
 	<layout_stack name="layout">
 		<panel name="notes_stack">
 			<scroll_container name="profile_scroll">
 				<panel name="profile_scroll_panel">
-					<text name="status_message" value="Mes notes privées :"/>
+					<text name="status_message" value="Mes notes perso :"/>
 					<text name="status_message2" value="Autoriser cette personne à :"/>
 					<check_box label="Afficher mon statut en ligne" name="status_check"/>
 					<check_box label="Me situer sur la carte" name="map_check"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_people.xml b/indra/newview/skins/default/xui/fr/panel_people.xml
index fb669f129bc1eb6edc968e7c23e3d21dbcee364a..ae2b96da3c3058e79ba06e304497bdc23bc2155d 100644
--- a/indra/newview/skins/default/xui/fr/panel_people.xml
+++ b/indra/newview/skins/default/xui/fr/panel_people.xml
@@ -10,7 +10,7 @@
 	<string name="groups_filter_label" value="Filtrer les groupes"/>
 	<filter_editor label="Filtre" name="filter_input"/>
 	<tab_container name="tabs">
-		<panel label="PROCHES" name="nearby_panel">
+		<panel label="PRÈS DE VOUS" name="nearby_panel">
 			<panel label="bottom_panel" name="bottom_panel">
 				<button name="nearby_view_sort_btn" tool_tip="Options"/>
 				<button name="add_friend_btn" tool_tip="Ajouter le résident sélectionné à votre liste d&apos;amis"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_picks.xml b/indra/newview/skins/default/xui/fr/panel_picks.xml
index 63a518f8a60aa73d274ddb1d195a0c037e6a2e37..cf110c27b5e444b0f0d061b2e96b7df574973a9f 100644
--- a/indra/newview/skins/default/xui/fr/panel_picks.xml
+++ b/indra/newview/skins/default/xui/fr/panel_picks.xml
@@ -10,7 +10,7 @@
 		<accordion_tab name="tab_classifieds" title="Petites annonces"/>
 	</accordion>
 	<panel label="bottom_panel" name="edit_panel">
-		<button name="new_btn" tool_tip="Ajouter cet endroit à mes Favoris"/>
+		<button name="new_btn" tool_tip="Ajouter cet endroit à mes Préférences"/>
 	</panel>
 	<panel name="buttons_cucks">
 		<button label="Infos" name="info_btn"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
index 13b467d2059faed388e769c6ea3458e8d87d1116..d292b002f65293cdbf4abc053c72a124d1860778 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Chat écrit" name="chat">
 	<radio_group name="chat_font_size">
-		<radio_item label="Petite" name="radio"/>
+		<radio_item label="Moins" name="radio"/>
 		<radio_item label="Moyenne" name="radio2"/>
-		<radio_item label="Grande" name="radio3"/>
+		<radio_item label="Plus" name="radio3"/>
 	</radio_group>
 	<color_swatch label="Vous" name="user"/>
 	<text name="text_box1">
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
index 783bd3bcbad95b0ad758d41381d1de82eb6527ce..6d331704eace4aba57debe82fcf08e60a53ea00d 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
@@ -38,15 +38,15 @@
 	</combo_box>
 	<check_box initial_value="true" label="Afficher à la connexion" name="show_location_checkbox"/>
 	<text name="name_tags_textbox">
-		Étiquettes :
+		Affichage des noms :
 	</text>
 	<radio_group name="Name_Tag_Preference">
-		<radio_item label="Désactivée" name="radio"/>
-		<radio_item label="Activée" name="radio2"/>
+		<radio_item label="Désactivé" name="radio"/>
+		<radio_item label="Activé" name="radio2"/>
 		<radio_item label="Afficher brièvement" name="radio3"/>
 	</radio_group>
 	<check_box label="Afficher mon nom" name="show_my_name_checkbox1"/>
-	<check_box initial_value="true" label="Étiquettes courtes" name="small_avatar_names_checkbox"/>
+	<check_box initial_value="true" label="Affichage en petit" name="small_avatar_names_checkbox"/>
 	<check_box label="Afficher les titres de groupe" name="show_all_title_checkbox1"/>
 	<text name="effects_color_textbox">
 		Mes effets :
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
index b4b178319039293d2be6add639c2a8634347075c..445924439557ee4d455c4125733106ff3076a9f1 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
@@ -12,7 +12,7 @@
 		<combo_box.item label="1024 x 768" name="1024x768"/>
 	</combo_box>
 	<text name="UI Size:">
-		Taille de l&apos;UI :
+		Taille de l&apos;interface :
 	</text>
 	<text name="QualitySpeed">
 		Qualité et vitesse :
@@ -21,7 +21,7 @@
 		Plus rapide
 	</text>
 	<text name="BetterText">
-		Mieux
+		Meilleur
 	</text>
 	<text name="ShadersPrefText">
 		Faible
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
index c86a6da037abf79019beddd5ddf6119a5faa7838..4bb6c766173bafb22ac1c45814a603cdebae63a4 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
@@ -21,7 +21,7 @@
 	<check_box label="Inclure les heures" name="show_timestamps_check_im"/>
 	<line_editor left="308" name="log_path_string" right="-20"/>
 	<text name="log_path_desc">
-		Emplacement des journaux
+		Emplacement
 	</text>
 	<button label="Parcourir" label_selected="Parcourir" name="log_path_button" width="150"/>
 	<button label="Liste des ignorés" name="block_list"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_profile_view.xml b/indra/newview/skins/default/xui/fr/panel_profile_view.xml
index 146095a25f216ab03da9e022b07a70fc3fe77ef6..8f57dd89c7c7a88908b768e223d8e7ebf20c3c07 100644
--- a/indra/newview/skins/default/xui/fr/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/fr/panel_profile_view.xml
@@ -11,6 +11,6 @@
 	<tab_container name="tabs">
 		<panel label="PROFIL" name="panel_profile"/>
 		<panel label="FAVORIS" name="panel_picks"/>
-		<panel label="NOTES ET VIE PRIVÉE" name="panel_notes"/>
+		<panel label="NOTES/PERSO" name="panel_notes"/>
 	</tab_container>
 </panel>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index a8e3ff1442e86eb60c1f7d4462844bfa17784673..b45a016822c380f15103e9d2f35329b23bbf19a9 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -1729,7 +1729,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Taille du ventre
 	</string>
 	<string name="Big">
-		Maxi
+		Plus
 	</string>
 	<string name="Big Butt">
 		Grosses fesses
@@ -1858,7 +1858,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Favoris
 	</string>
 	<string name="Chin Depth">
-		Profondeur du menton
+		Profondeur
 	</string>
 	<string name="Chin Heavy">
 		Menton lourd
@@ -1873,7 +1873,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Menton-cou
 	</string>
 	<string name="Clear">
-		Effacer
+		Clair
 	</string>
 	<string name="Cleft">
 		Fendu
@@ -1987,7 +1987,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Arc
 	</string>
 	<string name="Eyebrow Density">
-		Épaisseur
+		Épaisseur sourcils
 	</string>
 	<string name="Eyebrow Height">
 		Hauteur
@@ -2041,7 +2041,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Jambes larges
 	</string>
 	<string name="Flat">
-		Plates
+		Plat
 	</string>
 	<string name="Flat Butt">
 		Fesses plates
@@ -2107,13 +2107,13 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Sens de la coiffure
 	</string>
 	<string name="Hair Thickess">
-		Épaisseur
+		Épaisseur cheveux
 	</string>
 	<string name="Hair Thickness">
-		Épaisseur
+		Épaisseur cheveux
 	</string>
 	<string name="Hair Tilt">
-		Inclinaison des cheveux
+		Inclinaison
 	</string>
 	<string name="Hair Tilted Left">
 		Vers la gauche
@@ -2200,7 +2200,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Plis de la veste
 	</string>
 	<string name="Jaw Angle">
-		Angle de la mâchoire
+		Angle mâchoire
 	</string>
 	<string name="Jaw Jut">
 		Saillie de la mâchoire
@@ -2221,7 +2221,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Genoux rapprochés
 	</string>
 	<string name="Large">
-		Grand
+		Plus
 	</string>
 	<string name="Large Hands">
 		Grandes mains
@@ -2230,16 +2230,16 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Raie à gauche
 	</string>
 	<string name="Leg Length">
-		Longueur de la jambe
+		Longueur
 	</string>
 	<string name="Leg Muscles">
-		Muscles de la jambe
+		Muscles
 	</string>
 	<string name="Less">
 		Moins
 	</string>
 	<string name="Less Body Fat">
-		Moins de graisse
+		Moins
 	</string>
 	<string name="Less Curtains">
 		Moins
@@ -2266,13 +2266,13 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Moins
 	</string>
 	<string name="Less Round">
-		Moins
+		Moins ronde
 	</string>
 	<string name="Less Saddle">
 		Moins
 	</string>
 	<string name="Less Square">
-		Moins
+		Moins carrée
 	</string>
 	<string name="Less Volume">
 		Moins
@@ -2299,10 +2299,10 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Proportion des lèvres
 	</string>
 	<string name="Lip Thickness">
-		Épaisseur des lèvres
+		Épaisseur
 	</string>
 	<string name="Lip Width">
-		Largeur des lèvres
+		Largeur
 	</string>
 	<string name="Lipgloss">
 		Brillant à lèvres
@@ -2545,7 +2545,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Épaisseur du nez
 	</string>
 	<string name="Nose Tip Angle">
-		Angle du bout du nez
+		Bout du nez
 	</string>
 	<string name="Nose Tip Shape">
 		Bout du nez
@@ -2629,7 +2629,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Raie
 	</string>
 	<string name="Part Bangs">
-		Séparation de la frange
+		Séparation frange
 	</string>
 	<string name="Pectorals">
 		Pectoraux
@@ -2677,7 +2677,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Paupières
 	</string>
 	<string name="Rainbow Color">
-		Couleur de l&apos;arc en ciel
+		Couleur arc en ciel
 	</string>
 	<string name="Red Hair">
 		Cheveux roux
@@ -2725,10 +2725,10 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Front
 	</string>
 	<string name="Shear Left Up">
-		Haut gauche dégagé
+		Haut gauche décalé
 	</string>
 	<string name="Shear Right Up">
-		Haut droit dégagé
+		Haut droit décalé
 	</string>
 	<string name="Sheared Back">
 		Dégagé derrière
@@ -2758,7 +2758,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Hauteur
 	</string>
 	<string name="Short">
-		Mini
+		Moins
 	</string>
 	<string name="Short Arms">
 		Bras courts
@@ -2833,7 +2833,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Fente : Droite
 	</string>
 	<string name="Small">
-		Mini
+		Moins
 	</string>
 	<string name="Small Hands">
 		Petites mains
@@ -2842,7 +2842,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Petite tête
 	</string>
 	<string name="Smooth">
-		Lisse
+		Lisses
 	</string>
 	<string name="Smooth Hair">
 		Cheveux lisses
@@ -2887,13 +2887,13 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Vers l&apos;avant
 	</string>
 	<string name="Tall">
-		Maxi
+		Plus
 	</string>
 	<string name="Taper Back">
-		Biseauter à l&apos;arrière
+		Arrière
 	</string>
 	<string name="Taper Front">
-		Biseauter à l&apos;avant
+		Avant
 	</string>
 	<string name="Thick Heels">
 		Talons épais
@@ -2980,7 +2980,7 @@ Si ce message persiste, veuillez aller sur la page [SUPPORT_SITE].
 		Très rouge
 	</string>
 	<string name="Waist Height">
-		Hauteur de la taille
+		Hauteur taille
 	</string>
 	<string name="Well-Fed">
 		Ronde