diff --git a/autobuild.xml b/autobuild.xml
index e4e7bf3d579db0f15dc576b6ab7ee45715d4f1e3..84fa31bde473962fe094a7f5b0d19e728cfbd645 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -580,9 +580,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>cc26af2ebfa241891caca829a6e46b88</string>
+              <string>856ba0e5b7be4bf683cf2849bce845e0</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65005/607316/dullahan-1.7.0.202008031101_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-546064.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72458/699860/dullahan-1.7.0.202011160759_81.3.10_gb223419_chromium-81.0.4044.138-darwin64-552313.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -592,9 +592,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>4e5b9e2fe65d94e30a4f3d831c767199</string>
+              <string>515950c911a53ff910b18c7c417ea984</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65004/607304/dullahan-1.7.0.202008031759_81.3.10_gb223419_chromium-81.0.4044.138-windows-546064.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72460/699870/dullahan-1.7.0.202011161603_81.3.10_gb223419_chromium-81.0.4044.138-windows-552313.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -604,16 +604,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6f7bf7f915f3d75dbdad08a2d41ca74e</string>
+              <string>f1dccbdfe0603f488eeee4c8f518c959</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/65003/607308/dullahan-1.7.0.202008031800_81.3.10_gb223419_chromium-81.0.4044.138-windows64-546064.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/72459/699874/dullahan-1.7.0.202011161603_81.3.10_gb223419_chromium-81.0.4044.138-windows64-552313.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.7.0.202008031800_81.3.10_gb223419_chromium-81.0.4044.138</string>
+        <string>1.7.0.202011161603_81.3.10_gb223419_chromium-81.0.4044.138</string>
       </map>
       <key>elfio</key>
       <map>
@@ -2187,18 +2187,18 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c541838a933e0714a954e9ef6c89345d</string>
+              <string>40a87f5d505a141b2ec79513a6197c35</string>
               <key>hash_algorithm</key>
               <string>md5</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/73387/708088/llca-202012011600.553112-common-553112.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/76516/728250/llca-202102021657.555615-common-555615.tar.bz2</string>
             </map>
             <key>name</key>
             <string>common</string>
           </map>
         </map>
         <key>version</key>
-        <string>202012011600.553112</string>
+        <string>202102021657.555615</string>
       </map>
       <key>llphysicsextensions_source</key>
       <map>
@@ -3128,9 +3128,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>d463360491b6b5cb7a57cd67a90ececb</string>
+              <string>60f008c5fd31641ad4e61ac751ce15d1</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54838/510050/uriparser-0.8.0.1-darwin64-538968.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/75748/723495/uriparser-0.9.4-darwin64-555117.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3164,9 +3164,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>57a88be57694de6cf9f516125af2c4c9</string>
+              <string>00aff37a6f5e1fe08456702d28706cf6</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54963/511746/uriparser-0.8.0.1-windows-538968.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/75751/723507/uriparser-0.9.4-windows-555117.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3176,16 +3176,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>f39cc91f2a5dad13790ec18269844ae4</string>
+              <string>ff27a91f3941c7bef5e1613a064cb048</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/54962/511739/uriparser-0.8.0.1-windows64-538968.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/75750/723506/uriparser-0.9.4-windows64-555117.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>0.8.0.1</string>
+        <string>0.9.4</string>
       </map>
       <key>viewer-manager</key>
       <map>
@@ -3206,9 +3206,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c5ab9d9d7482e48cd76f4bf391900a8c</string>
+              <string>6989053898b8e81e904e75553e378820</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/43369/385585/viewer_manager-2.0.531000-darwin64-531000.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77523/735051/viewer_manager-2.0.556340-darwin64-556340.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -3230,9 +3230,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>6b10d7407686d9e12e63576256581e3e</string>
+              <string>3446c1e54bb32542677caad0ec0d42ac</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/43370/385592/viewer_manager-2.0.531000-windows-531000.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/77525/735058/viewer_manager-2.0.556340-windows-556340.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -3243,7 +3243,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>2.0.531000</string>
+        <string>2.0.556340</string>
       </map>
       <key>vlc-bin</key>
       <map>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index bbdfaf655ddc2df6d526703581e98cf9a4fbd175..8ae828e7385e18ca31bd4f3e4f0ca6081ef7f8fc 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -226,6 +226,7 @@ Ansariel Hiller
 	SL-13364
 	SL-13858
 	SL-13697
+	SL-3136
 Aralara Rajal
 Arare Chantilly
 	CHUIBUG-191
@@ -263,10 +264,11 @@ Benja Kepler
 Benjamin Bigdipper
 Beq Janus
 	BUG-227094
-Beth Walcher
-Beq Janus
 	SL-10288
+    SL-11300
 	SL-13583
+	SL-14766
+Beth Walcher
 Bezilon Kasei
 Biancaluce Robbiani
 	CT-225
@@ -358,6 +360,8 @@ Chaser Zaks
     BUG-227485
 Cherry Cheevers
 ChickyBabes Zuzu
+Chorazin Allen
+    BUG-229753
 Christopher  Organiser
 Ciaran Laval
 Cinder Roxley
@@ -1353,6 +1357,12 @@ Sovereign Engineer
     SL-11079
     OPEN-343
 	SL-11625
+	SL-14705
+	SL-14706
+	SL-14707
+	SL-14731
+	SL-14732
+	SL-15096
 SpacedOut Frye
 	VWR-34
 	VWR-45
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 3090e2ebc680bf7a32db094e8563fafc49c0c331..e93900e37e330fb711a01a5d7833fe25e2209499 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -61,6 +61,7 @@ if(WINDOWS)
         nghttp2.dll
         glod.dll
         libhunspell.dll
+        uriparser.dll
         )
 
     # Filenames are different for 32/64 bit BugSplat file and we don't
@@ -94,7 +95,7 @@ if(WINDOWS)
         MESSAGE(STATUS "MSVC_VERSION ${MSVC_VERSION}")
     elseif (MSVC_VERSION EQUAL 1800) # VisualStudio 2013, which is (sigh) VS 12
         set(MSVC_VER 120)
-    elseif (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1930) # Visual Studio 2017 + 2019
+    elseif (MSVC_VERSION GREATER_EQUAL 1910 AND MSVC_VERSION LESS 1940) # Visual Studio 2017 through 2022
         set(MSVC_VER 140)
     else (MSVC80)
         MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake")
@@ -165,6 +166,9 @@ elseif(DARWIN)
         libnghttp2.dylib
         libnghttp2.14.dylib
         libnghttp2.14.19.0.dylib
+        liburiparser.dylib
+        liburiparser.1.dylib
+        liburiparser.1.0.27.dylib
        )
 
     if (FMODSTUDIO)
diff --git a/indra/cmake/URIPARSER.cmake b/indra/cmake/URIPARSER.cmake
index de146885a07aad57a77e1c81c8a83d24b4234197..ecc5b74ef10eb07deec5ea1b88bab5e6d0238303 100644
--- a/indra/cmake/URIPARSER.cmake
+++ b/indra/cmake/URIPARSER.cmake
@@ -29,7 +29,7 @@ else (USESYSTEMLIBS)
     set(URIPARSER_PRELOAD_ARCHIVES -Wl,--whole-archive uriparser -Wl,--no-whole-archive)
     set(URIPARSER_LIBRARIES uriparser)
   elseif (DARWIN)
-    set(URIPARSER_LIBRARIES uriparser)
+    set(URIPARSER_LIBRARIES liburiparser.dylib)
   endif (WINDOWS)
   set(URIPARSER_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/uriparser)
 endif (USESYSTEMLIBS)
diff --git a/indra/edit-me-to-trigger-new-build.txt b/indra/edit-me-to-trigger-new-build.txt
index 48082f72f087ce7e6fa75b9c41d7387daecd447b..5366987cff8af097af8af87892cfa26ba97f3ddf 100644
--- a/indra/edit-me-to-trigger-new-build.txt
+++ b/indra/edit-me-to-trigger-new-build.txt
@@ -1 +1,3 @@
-12
+euclid 5/29/2020
+euclid 7/23/2020
+euclid 4/29/2021
\ No newline at end of file
diff --git a/indra/llappearance/llavatarappearancedefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp
index 9398ce38221ef83cde77421487601e4177af3347..2bcfd06c402b7d9e99315f32443f5032dee61ac4 100644
--- a/indra/llappearance/llavatarappearancedefines.cpp
+++ b/indra/llappearance/llavatarappearancedefines.cpp
@@ -30,7 +30,6 @@
 
 const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 1024;
 const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 1024;
-const S32 LLAvatarAppearanceDefines::IMPOSTOR_PERIOD = 2;
 
 using namespace LLAvatarAppearanceDefines;
 
diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h
index 8968187531042e56280c692ab0eff171455b6980..49dfbebeeab96cb67c9072e7511719ee258e401b 100644
--- a/indra/llappearance/llavatarappearancedefines.h
+++ b/indra/llappearance/llavatarappearancedefines.h
@@ -39,7 +39,6 @@ namespace LLAvatarAppearanceDefines
 
 extern const S32 SCRATCH_TEX_WIDTH;
 extern const S32 SCRATCH_TEX_HEIGHT;
-extern const S32 IMPOSTOR_PERIOD;
 
 static const U32 AVATAR_HOVER = 11001;
 
diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp
index 80b3e42b52904b7a32d2b63097d24b441a3cc7d8..a1d4fe6423e222e59f62dcab8b86964179579e56 100644
--- a/indra/llappearance/llavatarjoint.cpp
+++ b/indra/llappearance/llavatarjoint.cpp
@@ -103,7 +103,7 @@ void LLAvatarJoint::setValid( BOOL valid, BOOL recursive )
 		for (joints_t::iterator iter = mChildren.begin();
 			 iter != mChildren.end(); ++iter)
 		{
-			LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
+			LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*iter);
 			joint->setValid(valid, TRUE);
 		}
 	}
@@ -136,7 +136,7 @@ void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive)
 		for (joints_t::iterator iter = mChildren.begin();
 			 iter != mChildren.end(); ++iter)
 		{
-			LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
+			LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*iter);
 			joint->setVisible(visible, recursive);
 		}
 	}
@@ -167,7 +167,7 @@ void LLAvatarJoint::updateJointGeometry()
 	for (joints_t::iterator iter = mChildren.begin();
 		 iter != mChildren.end(); ++iter)
 	{
-		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+		LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(*iter);
 		joint->updateJointGeometry();
 	}
 }
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index eeb315ead69608d8d5623990d84081d14d6a8e38..cecfadcd91f0c22a727d4c59884684a9e292ede9 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -71,6 +71,7 @@ set(llcommon_SOURCE_FILES
     llinitparam.cpp
     llinitdestroyclass.cpp
     llinstancetracker.cpp
+    llkeybind.cpp
     llleap.cpp
     llleaplistener.cpp
     llliveappconfig.cpp
@@ -182,6 +183,7 @@ set(llcommon_HEADER_FILES
     llinitdestroyclass.h
     llinitparam.h
     llinstancetracker.h
+    llkeybind.h
     llkeythrottle.h
     llleap.h
     llleaplistener.h
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index e7b0e0ef8e9f3c962f71c94bfe77a9af04c7d893..10b98f49aaf32956e9cf59f4f3014df0062c36d6 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -54,6 +54,17 @@ enum ETerrainBrushType
 	E_LANDBRUSH_INVALID = 6
 };
 
+enum EMouseClickType{
+    CLICK_NONE = -1,
+    CLICK_LEFT = 0,
+    CLICK_MIDDLE,
+    CLICK_RIGHT,
+    CLICK_BUTTON4,
+    CLICK_BUTTON5,
+    CLICK_DOUBLELEFT,
+    CLICK_COUNT // 'size', CLICK_NONE does not counts
+};
+
 // keys
 // Bit masks for various keyboard modifier keys.
 const MASK MASK_NONE =			0x0000;
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index 255b50c8d04516d3e3da19c77c2dd4766346639a..565d7cfb6372246b569aa6b1013e55c8940813f7 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -29,7 +29,7 @@
 #ifndef LL_LLAPR_H
 #define LL_LLAPR_H
 
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
 #include <sys/param.h>  // Need PATH_MAX in APR headers...
 #endif
 
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index 262929006dda157334c02e076abe19cffdb973c5..23419a52a757a020808e454e315cd3185948b6a7 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -56,10 +56,6 @@
 #include "stringize.h"
 #include "llexception.h"
 
-#if LL_WINDOWS
-#include <excpt.h>
-#endif
-
 // static
 LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller)
 {
@@ -253,29 +249,13 @@ std::string LLCoros::launch(const std::string& prefix, const callable_t& callabl
 
 #if LL_WINDOWS
 
-static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
-
-U32 exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
-{
-    if (code == STATUS_MSC_EXCEPTION)
-    {
-        // C++ exception, go on
-        return EXCEPTION_CONTINUE_SEARCH;
-    }
-    else
-    {
-        // handle it
-        return EXCEPTION_EXECUTE_HANDLER;
-    }
-}
-
 void LLCoros::winlevel(const callable_t& callable)
 {
     __try
     {
         callable();
     }
-    __except (exception_filter(GetExceptionCode(), GetExceptionInformation()))
+    __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))
     {
         // convert to C++ styled exception
         // Note: it might be better to use _se_set_translator
diff --git a/indra/llcommon/llexception.cpp b/indra/llcommon/llexception.cpp
index 5ce895868798336dc4dfa5ef8dea3ebdfbc2e0b7..b584b0ff8b53c2a4efb58e40f4d4aef210fb1466 100644
--- a/indra/llcommon/llexception.cpp
+++ b/indra/llcommon/llexception.cpp
@@ -24,11 +24,14 @@
 // `_GNU_SOURCE` macro or `BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED` if
 // _Unwind_Backtrace is available without `_GNU_SOURCE`."
 #define BOOST_STACKTRACE_GNU_SOURCE_NOT_REQUIRED
+
 #if LL_WINDOWS
 // On Windows, header-only implementation causes macro collisions -- use
 // prebuilt library
 #define BOOST_STACKTRACE_LINK
+#include <excpt.h>
 #endif // LL_WINDOWS
+
 #include <boost/stacktrace.hpp>
 // other Linden headers
 #include "llerror.h"
@@ -85,3 +88,25 @@ void annotate_exception_(boost::exception& exc)
     // Anyway, which of us is really going to examine more than 100 frames?
     exc << errinfo_stacktrace(boost::stacktrace::stacktrace(1, 100));
 }
+
+#if LL_WINDOWS
+
+// For windows SEH exception handling we sometimes need a filter that will
+// separate C++ exceptions from C SEH exceptions
+static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
+
+U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
+{
+    if (code == STATUS_MSC_EXCEPTION)
+    {
+        // C++ exception, go on
+        return EXCEPTION_CONTINUE_SEARCH;
+    }
+    else
+    {
+        // handle it
+        return EXCEPTION_EXECUTE_HANDLER;
+    }
+}
+
+#endif //LL_WINDOWS
diff --git a/indra/llcommon/llexception.h b/indra/llcommon/llexception.h
index 422dd8810a3228ab6b2005e8a497f6fc52d36086..375bea4a5739577cfcc90097b855a3566a83434b 100644
--- a/indra/llcommon/llexception.h
+++ b/indra/llcommon/llexception.h
@@ -102,4 +102,14 @@ void crash_on_unhandled_exception_(const char*, int, const char*, const std::str
      log_unhandled_exception_(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, CONTEXT)
 void log_unhandled_exception_(const char*, int, const char*, const std::string&);
 
+
+#if LL_WINDOWS
+
+// SEH exception filtering for use in __try __except
+// Separates C++ exceptions from C SEH exceptions
+// Todo: might be good idea to do some kind of seh_to_msc_wrapper(function, ARGS&&);
+U32 msc_exception_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop);
+
+#endif //LL_WINDOWS
+
 #endif /* ! defined(LL_LLEXCEPTION_H) */
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 08ea668964eec0e1fb18e1e8f22405dd37c7f429..5b6a7b82f803bf35b455d4b37ffcb83b7b326b41 100644
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -43,7 +43,7 @@
 
 #if LL_WINDOWS
 #include "lltimer.h"
-#elif LL_LINUX || LL_SOLARIS
+#elif LL_LINUX
 #include <sys/time.h>
 #include <sched.h>
 #include "lltimer.h"
@@ -64,7 +64,7 @@ bool        BlockTimer::sLog		     = false;
 std::string BlockTimer::sLogName         = "";
 bool        BlockTimer::sMetricLog       = false;
 
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
 U64         BlockTimer::sClockResolution = 1000000000; // Nanosecond resolution
 #else
 U64         BlockTimer::sClockResolution = 1000000; // Microsecond resolution
@@ -151,12 +151,12 @@ void BlockTimer::setLogLock(LLMutex* lock)
 
 
 //static
-#if (LL_DARWIN || LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
+#if (LL_DARWIN || LL_LINUX) && !(defined(__i386__) || defined(__amd64__))
 U64 BlockTimer::countsPerSecond()
 {
 	return sClockResolution;
 }
-#else // windows or x86-mac or x86-linux or x86-solaris
+#else // windows or x86-mac or x86-linux
 U64 BlockTimer::countsPerSecond()
 {
 #if LL_FASTTIMER_USE_RDTSC || !LL_WINDOWS
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index 5628a05b00d1d94f407192a39644d5d61aee6c98..dfc63d08a2979203866b0cf6ff7647e66867853e 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -125,9 +125,9 @@ class BlockTimer
 #endif
 
 
-#if (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
+#if (LL_LINUX) && !(defined(__i386__) || defined(__amd64__))
 	//
-	// Linux and Solaris implementation of CPU clock - non-x86.
+	// Linux implementation of CPU clock - non-x86.
 	// This is accurate but SLOW!  Only use out of desperation.
 	//
 	// Try to use the MONOTONIC clock if available, this is a constant time counter
@@ -153,12 +153,12 @@ class BlockTimer
 		return (U32)(getCPUClockCount64() >> 8);
 	}
 
-#endif // (LL_LINUX || LL_SOLARIS) && !(defined(__i386__) || defined(__amd64__))
+#endif // (LL_LINUX) && !(defined(__i386__) || defined(__amd64__))
 
 
-#if (LL_LINUX || LL_SOLARIS || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
+#if (LL_LINUX || LL_DARWIN) && (defined(__i386__) || defined(__amd64__))
 	//
-	// Mac+Linux+Solaris FAST x86 implementation of CPU clock
+	// Mac+Linux FAST x86 implementation of CPU clock
 	static U32 getCPUClockCount32()
 	{
 		U32 low(0),high(0);
diff --git a/indra/llcommon/llkeybind.cpp b/indra/llcommon/llkeybind.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..38696c2258b7d4de12ff1ad8d0a8f5603ff47ea5
--- /dev/null
+++ b/indra/llcommon/llkeybind.cpp
@@ -0,0 +1,395 @@
+/** 
+ * @file llkeybind.cpp
+ * @brief Information about key combinations.
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2019, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llkeybind.h"
+
+#include "llsd.h"
+#include "llsdutil.h"
+
+LLKeyData::LLKeyData()
+    :
+    mMouse(CLICK_NONE),
+    mKey(KEY_NONE),
+    mMask(MASK_NONE),
+    mIgnoreMasks(false)
+{
+}
+
+LLKeyData::LLKeyData(EMouseClickType mouse, KEY key, MASK mask)
+    :
+    mMouse(mouse),
+    mKey(key),
+    mMask(mask),
+    mIgnoreMasks(false)
+{
+}
+
+LLKeyData::LLKeyData(EMouseClickType mouse, KEY key, bool ignore_mask)
+    :
+    mMouse(mouse),
+    mKey(key),
+    mMask(MASK_NONE),
+    mIgnoreMasks(ignore_mask)
+{
+}
+
+LLKeyData::LLKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask)
+    :
+    mMouse(mouse),
+    mKey(key),
+    mMask(mask),
+    mIgnoreMasks(ignore_mask)
+{
+}
+
+LLKeyData::LLKeyData(const LLSD &key_data)
+{
+    if (key_data.has("mouse"))
+    {
+        mMouse = (EMouseClickType)key_data["mouse"].asInteger();
+    }
+    if (key_data.has("key"))
+    {
+        mKey = key_data["key"].asInteger();
+    }
+    if (key_data.has("ignore_accelerators"))
+    {
+        mIgnoreMasks = key_data["ignore_accelerators"];
+    }
+    if (key_data.has("mask"))
+    {
+        mMask = key_data["mask"].asInteger();
+    }
+}
+
+LLSD LLKeyData::asLLSD() const
+{
+    LLSD data;
+    data["mouse"] = (LLSD::Integer)mMouse;
+    data["key"] = (LLSD::Integer)mKey;
+    data["mask"] = (LLSD::Integer)mMask;
+    if (mIgnoreMasks)
+    {
+        data["ignore_accelerators"] = (LLSD::Boolean)mIgnoreMasks;
+    }
+    return data;
+}
+
+bool LLKeyData::isEmpty() const
+{
+    return mMouse == CLICK_NONE && mKey == KEY_NONE;
+}
+
+void LLKeyData::reset()
+{
+    mMouse = CLICK_NONE;
+    mKey = KEY_NONE;
+    mMask = MASK_NONE;
+    mIgnoreMasks = false;
+}
+
+LLKeyData& LLKeyData::operator=(const LLKeyData& rhs)
+{
+    mMouse = rhs.mMouse;
+    mKey = rhs.mKey;
+    mMask = rhs.mMask;
+    mIgnoreMasks = rhs.mIgnoreMasks;
+    return *this;
+}
+
+bool LLKeyData::operator==(const LLKeyData& rhs)
+{
+    if (mMouse != rhs.mMouse) return false;
+    if (mKey != rhs.mKey) return false;
+    if (mMask != rhs.mMask) return false;
+    if (mIgnoreMasks != rhs.mIgnoreMasks) return false;
+    return true;
+}
+
+bool LLKeyData::operator!=(const LLKeyData& rhs)
+{
+    if (mMouse != rhs.mMouse) return true;
+    if (mKey != rhs.mKey) return true;
+    if (mMask != rhs.mMask) return true;
+    if (mIgnoreMasks != rhs.mIgnoreMasks) return true;
+    return false;
+}
+
+bool LLKeyData::canHandle(const LLKeyData& data) const
+{
+    if (data.mKey == mKey
+        && data.mMouse == mMouse
+        && ((mIgnoreMasks && (data.mMask & mMask) == mMask) || data.mMask == mMask))
+    {
+        return true;
+    }
+    return false;
+}
+
+bool LLKeyData::canHandle(EMouseClickType mouse, KEY key, MASK mask) const
+{
+    if (mouse == mMouse
+        && key == mKey
+        && ((mIgnoreMasks && (mask & mMask) == mMask) || mask == mMask))
+    {
+        return true;
+    }
+    return false;
+}
+
+// LLKeyBind
+
+LLKeyBind::LLKeyBind(const LLSD &key_bind)
+{
+    if (key_bind.isArray())
+    {
+        for (LLSD::array_const_iterator data = key_bind.beginArray(), endLists = key_bind.endArray();
+            data != endLists;
+            data++
+            )
+        {
+            mData.push_back(LLKeyData(*data));
+        }
+    }
+}
+
+bool LLKeyBind::operator==(const LLKeyBind& rhs)
+{
+    U32 size = mData.size();
+    if (size != rhs.mData.size()) return false;
+
+    for (U32 i = 0; i < size; i++)
+    {
+        if (mData[i] != rhs.mData[i]) return false;
+    }
+
+    return true;
+}
+
+bool LLKeyBind::operator!=(const LLKeyBind& rhs)
+{
+    U32 size = mData.size();
+    if (size != rhs.mData.size()) return true;
+
+    for (U32 i = 0; i < size; i++)
+    {
+        if (mData[i] != rhs.mData[i]) return true;
+    }
+
+    return false;
+}
+
+bool LLKeyBind::isEmpty() const
+{
+    for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++)
+    {
+        if (!iter->isEmpty()) return false;
+    }
+    return true;
+}
+
+LLSD LLKeyBind::asLLSD() const
+{
+    S32 last = mData.size() - 1;
+    while (mData[last].empty())
+    {
+        last--;
+    }
+
+    LLSD data;
+    for (S32 i = 0; i <= last; ++i)
+    {
+        // append even if empty to not affect visual representation
+        data.append(mData[i].asLLSD());
+    }
+    return data;
+}
+
+bool LLKeyBind::canHandle(EMouseClickType mouse, KEY key, MASK mask) const
+{
+    if (mouse == CLICK_NONE && key == KEY_NONE)
+    {
+        // assume placeholder
+        return false;
+    }
+
+    for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++)
+    {
+        if (iter->canHandle(mouse, key, mask))
+        {
+            return true;
+        }
+    }
+    return false;
+}
+
+bool LLKeyBind::canHandleKey(KEY key, MASK mask) const
+{
+    return canHandle(CLICK_NONE, key, mask);
+}
+
+bool LLKeyBind::canHandleMouse(EMouseClickType mouse, MASK mask) const
+{
+    return canHandle(mouse, KEY_NONE, mask);
+}
+
+bool LLKeyBind::hasKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const
+{
+    if (mouse != CLICK_NONE || key != KEY_NONE)
+    {
+        for (data_vector_t::const_iterator iter = mData.begin(); iter != mData.end(); iter++)
+        {
+            if (iter->mKey == key
+                && iter->mMask == mask
+                && iter->mMouse == mouse
+                && iter->mIgnoreMasks == ignore)
+            {
+                return true;
+            }
+        }
+    }
+    return false;
+}
+
+bool LLKeyBind::hasKeyData(const LLKeyData& data) const
+{
+    return hasKeyData(data.mMouse, data.mKey, data.mMask, data.mIgnoreMasks);
+}
+
+bool LLKeyBind::hasKeyData(U32 index) const
+{
+    return mData.size() > index;
+}
+
+S32 LLKeyBind::findKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const
+{
+    if (mouse != CLICK_NONE || key != KEY_NONE)
+    {
+        for (S32 i = 0; i < mData.size(); ++i)
+        {
+            if (mData[i].mKey == key
+                && mData[i].mMask == mask
+                && mData[i].mMouse == mouse
+                && mData[i].mIgnoreMasks == ignore)
+            {
+                return i;
+            }
+        }
+    }
+    return -1;
+}
+
+S32 LLKeyBind::findKeyData(const LLKeyData& data) const
+{
+    return findKeyData(data.mMouse, data.mKey, data.mMask, data.mIgnoreMasks);
+}
+
+LLKeyData LLKeyBind::getKeyData(U32 index) const
+{
+    if (mData.size() > index)
+    {
+        return mData[index];
+    }
+    return LLKeyData();
+}
+
+bool LLKeyBind::addKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore)
+{
+    if (!hasKeyData(mouse, key, mask, ignore))
+    {
+        mData.push_back(LLKeyData(mouse, key, mask, ignore));
+        return true;
+    }
+    return false;
+}
+
+bool LLKeyBind::addKeyData(const LLKeyData& data)
+{
+    if (!hasKeyData(data))
+    {
+        mData.push_back(data);
+        return true;
+    }
+    return false;
+}
+
+void LLKeyBind::replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore, U32 index)
+{
+    replaceKeyData(LLKeyData(mouse, key, mask, ignore), index);
+}
+
+void LLKeyBind::replaceKeyData(const LLKeyData& data, U32 index)
+{
+    if (!data.isEmpty())
+    {
+        // if both click and key are none (isEmpty()), we are inserting a placeholder, we don't want to reset anything
+        // otherwise reset identical key
+        for (data_vector_t::iterator iter = mData.begin(); iter != mData.end(); iter++)
+        {
+            if (iter->mKey == data.mKey
+                && iter->mMouse == data.mMouse
+                && iter->mIgnoreMasks == data.mIgnoreMasks
+                && iter->mMask == data.mMask)
+            {
+                // Replacing only fully equal combinations even in case 'ignore' is set
+                // Reason: Simplicity and user might decide to do a 'move' command as W and Shift+Ctrl+W, and 'run' as Shift+W
+                iter->reset();
+                break;
+            }
+        }
+    }
+    if (mData.size() <= index)
+    {
+        mData.resize(index + 1);
+    }
+    mData[index] = data;
+}
+
+void LLKeyBind::resetKeyData(S32 index)
+{
+    if (mData.size() > index)
+    {
+        mData[index].reset();
+    }
+}
+
+void LLKeyBind::trimEmpty()
+{
+    S32 last = mData.size() - 1;
+    while (last >= 0 && mData[last].empty())
+    {
+        mData.erase(mData.begin() + last);
+        last--;
+    }
+}
+
+U32 LLKeyBind::getDataCount()
+{
+    return mData.size();
+}
+
diff --git a/indra/llcommon/llkeybind.h b/indra/llcommon/llkeybind.h
new file mode 100644
index 0000000000000000000000000000000000000000..c6b4bd970f43c716bab9e0d6061e7e5d79df5d4e
--- /dev/null
+++ b/indra/llcommon/llkeybind.h
@@ -0,0 +1,106 @@
+/** 
+ * @file llkeybind.h
+ * @brief Information about key combinations.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_KEYBIND_H
+#define LL_KEYBIND_H
+
+#include "indra_constants.h"
+
+// KeyData - single key combination (mouse/mask/keyboard)
+class LL_COMMON_API LLKeyData
+{
+public:
+    LLKeyData();
+    LLKeyData(EMouseClickType mouse, KEY key, MASK mask);
+    LLKeyData(EMouseClickType mouse, KEY key, bool ignore_mask);
+    LLKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask);
+    LLKeyData(const LLSD &key_data);
+
+    LLSD asLLSD() const;
+    bool isEmpty() const;
+    bool empty() const { return isEmpty(); };
+    void reset();
+    LLKeyData& operator=(const LLKeyData& rhs);
+    bool operator==(const LLKeyData& rhs);
+    bool operator!=(const LLKeyData& rhs);
+
+    bool canHandle(const LLKeyData& data) const;
+    bool canHandle(EMouseClickType mouse, KEY key, MASK mask) const;
+
+    EMouseClickType mMouse;
+    KEY mKey;
+    MASK mMask;
+    // Either to expect exact match or ignore not expected masks as long as expected mask-bit is present
+    bool mIgnoreMasks; 
+};
+
+// One function can bind to multiple Key options
+class LLKeyBind
+{
+public:
+    LLKeyBind() {}
+    LLKeyBind(const LLSD &key_bind);
+
+    bool operator==(const LLKeyBind& rhs);
+    bool operator!=(const LLKeyBind& rhs);
+    bool isEmpty() const;
+    bool empty() const { return isEmpty(); };
+
+    LLSD asLLSD() const;
+
+    bool canHandle(EMouseClickType mouse, KEY key, MASK mask) const;
+    bool canHandleKey(KEY key, MASK mask) const;
+    bool canHandleMouse(EMouseClickType mouse, MASK mask) const;
+
+    // contains specified combination
+    bool hasKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const;
+    bool hasKeyData(const LLKeyData& data) const;
+    bool hasKeyData(U32 index) const;
+
+    // index of contained LLKeyData
+    S32 findKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore) const;
+    S32 findKeyData(const LLKeyData& data) const;
+
+    LLKeyData getKeyData(U32 index) const;
+
+    // these methods enshure there will be no repeats
+    bool addKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore);
+    bool addKeyData(const LLKeyData& data);
+    void replaceKeyData(EMouseClickType mouse, KEY key, MASK mask, bool ignore, U32 index);
+    void replaceKeyData(const LLKeyData& data, U32 index);
+    void resetKeyData(S32 index);
+    void clear() { mData.clear(); }
+    // if there any empty LLKeyData in the end of the array, remove them
+    void trimEmpty();
+    U32 getDataCount();
+
+private:
+    typedef std::vector<LLKeyData> data_vector_t;
+    data_vector_t mData;
+};
+
+
+#endif // LL_KEYBIND_H
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 1884d6f04fbdab37acae68de43c5eccc9f873860..ea84e4c1ea1baf971233db28fed511180828ca80 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -35,7 +35,7 @@
 # include <sys/types.h>
 # include <mach/task.h>
 # include <mach/mach_init.h>
-#elif LL_LINUX || LL_SOLARIS
+#elif LL_LINUX
 # include <unistd.h>
 #endif
 
@@ -55,7 +55,6 @@ static LLTrace::SampleStatHandle<F64Megabytes> sVirtualMem("virtual_mem", "virtu
 U32Kilobytes LLMemory::sAllocatedMemInKB(0);
 U32Kilobytes LLMemory::sAllocatedPageSizeInKB(0);
 U32Kilobytes LLMemory::sMaxHeapSizeInKB(U32_MAX);
-BOOL LLMemory::sEnableMemoryFailurePrevention = FALSE;
 
 void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
 {
@@ -75,10 +74,9 @@ void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
 }
 
 //static 
-void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure)
+void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size)
 {
 	sMaxHeapSizeInKB = U32Kilobytes::convert(max_heap_size);
-	sEnableMemoryFailurePrevention = prevent_heap_failure ;
 }
 
 //static 
@@ -158,56 +156,6 @@ void LLMemory::logMemoryInfo(BOOL update)
 	LL_INFOS() << "Current max usable memory(KB): " << sMaxPhysicalMemInKB << LL_ENDL ;
 }
 
-//return 0: everything is normal;
-//return 1: the memory pool is low, but not in danger;
-//return -1: the memory pool is in danger, is about to crash.
-//static 
-bool LLMemory::isMemoryPoolLow()
-{
-	static const U32Megabytes LOW_MEMORY_POOL_THRESHOLD(64);
-	const static U32Megabytes MAX_SIZE_CHECKED_MEMORY_BLOCK(64);
-	static void* last_reserved_address = NULL ;
-
-	if(!sEnableMemoryFailurePrevention)
-	{
-		return false ; //no memory failure prevention.
-	}
-
-	if(sAvailPhysicalMemInKB < (LOW_MEMORY_POOL_THRESHOLD / 4)) //out of physical memory
-	{
-		return true ;
-	}
-
-	if(sAllocatedPageSizeInKB + (LOW_MEMORY_POOL_THRESHOLD / 4) > sMaxHeapSizeInKB) //out of virtual address space.
-	{
-		return true ;
-	}
-
-	bool is_low = (S32)(sAvailPhysicalMemInKB < LOW_MEMORY_POOL_THRESHOLD 
-						|| sAllocatedPageSizeInKB + LOW_MEMORY_POOL_THRESHOLD > sMaxHeapSizeInKB) ;
-
-	//check the virtual address space fragmentation
-	if(!is_low)
-	{
-		if(!last_reserved_address)
-		{
-			last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK.value()) ;
-		}
-		else
-		{
-			last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK.value()) ;
-			if(!last_reserved_address) //failed, try once more
-			{
-				last_reserved_address = LLMemory::tryToAlloc(last_reserved_address, MAX_SIZE_CHECKED_MEMORY_BLOCK.value()) ;
-			}
-		}
-
-		is_low = !last_reserved_address ; //allocation failed
-	}
-
-	return is_low ;
-}
-
 //static 
 U32Kilobytes LLMemory::getAvailableMemKB() 
 {
@@ -309,35 +257,6 @@ U64 LLMemory::getCurrentRSS()
 	return rss;
 }
 
-#elif LL_SOLARIS
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#define _STRUCTURED_PROC 1
-#include <sys/procfs.h>
-
-U64 LLMemory::getCurrentRSS()
-{
-	char path [LL_MAX_PATH];	/* Flawfinder: ignore */ 
-
-	sprintf(path, "/proc/%d/psinfo", (int)getpid());
-	int proc_fd = -1;
-	if((proc_fd = open(path, O_RDONLY)) == -1){
-		LL_WARNS() << "LLmemory::getCurrentRSS() unable to open " << path << ". Returning 0 RSS!" << LL_ENDL;
-		return 0;
-	}
-	psinfo_t proc_psinfo;
-	if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
-		LL_WARNS() << "LLmemory::getCurrentRSS() Unable to read from " << path << ". Returning 0 RSS!" << LL_ENDL;
-		close(proc_fd);
-		return 0;
-	}
-
-	close(proc_fd);
-
-	return((U64)proc_psinfo.pr_rssize * 1024);
-}
-
 #else
 
 U64 LLMemory::getCurrentRSS()
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index f04ae5f5cbe8b7419a789e090b7cdaed49cc5e5b..24f86cc11ee3a7b5c9d0b567e2907539b8fee015 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -344,10 +344,9 @@ class LL_COMMON_API LLMemory
 	// Return value is zero if not known.
 	static U64 getCurrentRSS();
 	static void* tryToAlloc(void* address, U32 size);
-	static void initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure);
+	static void initMaxHeapSizeGB(F32Gigabytes max_heap_size);
 	static void updateMemoryInfo() ;
 	static void logMemoryInfo(BOOL update = FALSE);
-	static bool isMemoryPoolLow();
 
 	static U32Kilobytes getAvailableMemKB() ;
 	static U32Kilobytes getMaxMemKB() ;
@@ -359,7 +358,6 @@ class LL_COMMON_API LLMemory
 	static U32Kilobytes sAllocatedPageSizeInKB ;
 
 	static U32Kilobytes sMaxHeapSizeInKB;
-	static BOOL sEnableMemoryFailurePrevention;
 };
 
 // LLRefCount moved to llrefcount.h
diff --git a/indra/llcommon/llpreprocessor.h b/indra/llcommon/llpreprocessor.h
index bae402110aa3f8326ccdc5674681aff97650fadc..b17a8e761a1f5b6dd50fa9c803185c3ed15abf21 100644
--- a/indra/llcommon/llpreprocessor.h
+++ b/indra/llcommon/llpreprocessor.h
@@ -34,16 +34,7 @@
 #include <endian.h>
 #endif	//	LL_LINUX
 
-#if LL_SOLARIS
-#   ifdef  __sparc     // Since we're talking Solaris 10 and up, only 64 bit is supported.
-#      define LL_BIG_ENDIAN 1
-#      define LL_SOLARIS_ALIGNED_CPU 1     //  used to designate issues where SPARC alignment is addressed
-#      define LL_SOLARIS_NON_MESA_GL 1      //  The SPARC GL does not provide a MESA-based GL API
-#   endif
-#   include <sys/isa_defs.h> // ensure we know which end is up
-#endif // LL_SOLARIS
-
-#if (defined(LL_WINDOWS) || (defined(LL_LINUX) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || (defined(LL_DARWIN) && defined(__LITTLE_ENDIAN__)) || (defined(LL_SOLARIS) && defined(__i386)))
+#if (defined(LL_WINDOWS) || (defined(LL_LINUX) && (__BYTE_ORDER == __LITTLE_ENDIAN)) || (defined(LL_DARWIN) && defined(__LITTLE_ENDIAN__)))
 #define LL_LITTLE_ENDIAN 1
 #else
 #define LL_BIG_ENDIAN 1
diff --git a/indra/llcommon/llsdutil.cpp b/indra/llcommon/llsdutil.cpp
index 3f3edb661fdc1183d91f3e7e21cfefca93d6e300..eb3a96b1333d6d6902ea277b5c46ed60905f5829 100644
--- a/indra/llcommon/llsdutil.cpp
+++ b/indra/llcommon/llsdutil.cpp
@@ -33,7 +33,7 @@
 #if LL_WINDOWS
 #	define WIN32_LEAN_AND_MEAN
 #	include <winsock2.h>	// for htonl
-#elif LL_LINUX || LL_SOLARIS
+#elif LL_LINUX
 #	include <netinet/in.h>
 #elif LL_DARWIN
 #	include <arpa/inet.h>
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index 83a4b64e8f8591a7b7d686fb46149e26950b31bf..ad933154c21196503f7ed13d2cd66eb947e926a4 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -388,7 +388,7 @@ LLSingletonBase::vec_t LLSingletonBase::dep_sort()
     // extracts just the first (key) element from each sorted_iterator, then
     // uses vec_t's range constructor... but frankly this is more
     // straightforward, as long as we remember the above reserve() call!
-    for (const SingletonDeps::sorted_iterator::value_type& pair : sdeps.sort())
+    for (const SingletonDeps::sorted_iterator::value_type pair : sdeps.sort())
     {
         ret.push_back(pair.first);
     }
diff --git a/indra/llcommon/llstring.h b/indra/llcommon/llstring.h
index c3064017008ced46c35c0d520075ef6cd14f2f40..98da4289cd24b29d1859820b85f61d95c45fc8f6 100644
--- a/indra/llcommon/llstring.h
+++ b/indra/llcommon/llstring.h
@@ -40,7 +40,7 @@
 #include <list>
 // [/RLVa:KB]
 
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
 #include <wctype.h>
 #include <wchar.h>
 #endif
@@ -48,16 +48,10 @@
 #include <string.h>
 #include <boost/scoped_ptr.hpp>
 
-#if LL_SOLARIS
-// stricmp and strnicmp do not exist on Solaris:
-#define stricmp strcasecmp
-#define strnicmp strncasecmp
-#endif
-
 const char LL_UNKNOWN_CHAR = '?';
 class LLSD;
 
-#if LL_DARWIN || LL_LINUX || LL_SOLARIS
+#if LL_DARWIN || LL_LINUX
 // Template specialization of char_traits for U16s. Only necessary on Mac and Linux (exists on Windows already)
 #include <cstring>
 
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 1f8d558fbeb0c068c41b7183a667f685703f82b1..4e61fb8a5805bce07f583e958675da0b33756a64 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -55,6 +55,7 @@
 #include <boost/utility/enable_if.hpp>
 #include <boost/type_traits/is_integral.hpp>
 #include <boost/type_traits/is_float.hpp>
+#include "llfasttimer.h"
 
 using namespace llsd;
 
@@ -87,17 +88,6 @@ using namespace llsd;
 #   include <stdexcept>
 const char MEMINFO_FILE[] = "/proc/meminfo";
 #   include <gnu/libc-version.h>
-#elif LL_SOLARIS
-#	include <stdio.h>
-#	include <unistd.h>
-#	include <sys/utsname.h>
-#	define _STRUCTURED_PROC 1
-#	include <sys/procfs.h>
-#	include <sys/types.h>
-#	include <sys/stat.h>
-#	include <fcntl.h>
-#	include <errno.h>
-extern int errno;
 #endif
 
 LLCPUInfo gSysCPU;
@@ -543,8 +533,6 @@ const std::string& LLOSInfo::getOSVersionString() const
 U32 LLOSInfo::getProcessVirtualSizeKB()
 {
 	U32 virtual_size = 0;
-#if LL_WINDOWS
-#endif
 #if LL_LINUX
 #   define STATUS_SIZE 2048	
 	LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb");
@@ -564,24 +552,6 @@ U32 LLOSInfo::getProcessVirtualSizeKB()
 		}
 		fclose(status_filep);
 	}
-#elif LL_SOLARIS
-	char proc_ps[LL_MAX_PATH];
-	sprintf(proc_ps, "/proc/%d/psinfo", (int)getpid());
-	int proc_fd = -1;
-	if((proc_fd = open(proc_ps, O_RDONLY)) == -1){
-		LL_WARNS() << "unable to open " << proc_ps << LL_ENDL;
-		return 0;
-	}
-	psinfo_t proc_psinfo;
-	if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
-		LL_WARNS() << "Unable to read " << proc_ps << LL_ENDL;
-		close(proc_fd);
-		return 0;
-	}
-
-	close(proc_fd);
-
-	virtual_size = proc_psinfo.pr_size;
 #endif
 	return virtual_size;
 }
@@ -590,8 +560,6 @@ U32 LLOSInfo::getProcessVirtualSizeKB()
 U32 LLOSInfo::getProcessResidentSizeKB()
 {
 	U32 resident_size = 0;
-#if LL_WINDOWS
-#endif
 #if LL_LINUX
 	LLFILE* status_filep = LLFile::fopen("/proc/self/status", "rb");
 	if (status_filep != NULL)
@@ -610,24 +578,6 @@ U32 LLOSInfo::getProcessResidentSizeKB()
 		}
 		fclose(status_filep);
 	}
-#elif LL_SOLARIS
-	char proc_ps[LL_MAX_PATH];
-	sprintf(proc_ps, "/proc/%d/psinfo", (int)getpid());
-	int proc_fd = -1;
-	if((proc_fd = open(proc_ps, O_RDONLY)) == -1){
-		LL_WARNS() << "unable to open " << proc_ps << LL_ENDL;
-		return 0;
-	}
-	psinfo_t proc_psinfo;
-	if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
-		LL_WARNS() << "Unable to read " << proc_ps << LL_ENDL;
-		close(proc_fd);
-		return 0;
-	}
-
-	close(proc_fd);
-
-	resident_size = proc_psinfo.pr_rssize;
 #endif
 	return resident_size;
 }
@@ -772,11 +722,6 @@ U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
 	phys = (U64)(getpagesize()) * (U64)(get_phys_pages());
 	return U64Bytes(phys);
 
-#elif LL_SOLARIS
-	U64 phys = 0;
-	phys = (U64)(getpagesize()) * (U64)(sysconf(_SC_PHYS_PAGES));
-	return U64Bytes(phys);
-
 #else
 	return 0;
 
@@ -925,8 +870,12 @@ LLMemoryInfo& LLMemoryInfo::refresh()
 	return *this;
 }
 
+static LLTrace::BlockTimerStatHandle FTM_MEMINFO_LOAD_STATS("MemInfo Load Stats");
+
 LLSD LLMemoryInfo::loadStatsMap()
 {
+	LL_RECORD_BLOCK_TIME(FTM_MEMINFO_LOAD_STATS);
+
 	// This implementation is derived from stream() code (as of 2011-06-29).
 	Stats stats;
 
@@ -948,24 +897,11 @@ LLSD LLMemoryInfo::loadStatsMap()
 	stats.add("Total Virtual KB",   state.ullTotalVirtual/div);
 	stats.add("Avail Virtual KB",   state.ullAvailVirtual/div);
 
-	PERFORMANCE_INFORMATION perf;
-	perf.cb = sizeof(perf);
-	GetPerformanceInfo(&perf, sizeof(perf));
-
-	SIZE_T pagekb(perf.PageSize/1024);
-	stats.add("CommitTotal KB",     perf.CommitTotal * pagekb);
-	stats.add("CommitLimit KB",     perf.CommitLimit * pagekb);
-	stats.add("CommitPeak KB",      perf.CommitPeak * pagekb);
-	stats.add("PhysicalTotal KB",   perf.PhysicalTotal * pagekb);
-	stats.add("PhysicalAvail KB",   perf.PhysicalAvailable * pagekb);
-	stats.add("SystemCache KB",     perf.SystemCache * pagekb);
-	stats.add("KernelTotal KB",     perf.KernelTotal * pagekb);
-	stats.add("KernelPaged KB",     perf.KernelPaged * pagekb);
-	stats.add("KernelNonpaged KB",  perf.KernelNonpaged * pagekb);
-	stats.add("PageSize KB",        pagekb);
-	stats.add("HandleCount",        perf.HandleCount);
-	stats.add("ProcessCount",       perf.ProcessCount);
-	stats.add("ThreadCount",        perf.ThreadCount);
+	// SL-12122 - Call to GetPerformanceInfo() was removed here. Took
+	// on order of 10 ms, causing unacceptable frame time spike every
+	// second, and results were never used. If this is needed in the
+	// future, must find a way to avoid frame time impact (e.g. move
+	// to another thread, call much less often).
 
 	PROCESS_MEMORY_COUNTERS_EX pmem;
 	pmem.cb = sizeof(pmem);
@@ -1074,13 +1010,6 @@ LLSD LLMemoryInfo::loadStatsMap()
 			}
 	}
 
-#elif LL_SOLARIS
-	U64 phys = 0;
-
-	phys = (U64)(sysconf(_SC_PHYS_PAGES)) * (U64)(sysconf(_SC_PAGESIZE)/1024);
-
-	stats.add("Total Physical KB", phys);
-
 #elif LL_LINUX
 	std::ifstream meminfo(MEMINFO_FILE);
 	if (meminfo.is_open())
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index 0b9dec969ce0f738684346dc7312018677670360..98905f3b7193dfbc5ba9b97cfee2a25ef59d7541 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -36,7 +36,7 @@
 #include "lltracethreadrecorder.h"
 #include "llexception.h"
 
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
 #include <sched.h>
 #endif
 
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 76e892212a75721639951178f96d971c5fc888f8..aaa6df325cb741060c7b66c0ee2c0c5a0462760b 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -32,7 +32,7 @@
 
 #if LL_WINDOWS
 #	include "llwin32headerslean.h"
-#elif LL_LINUX || LL_SOLARIS || LL_DARWIN
+#elif LL_LINUX || LL_DARWIN
 #   include <errno.h>
 #	include <sys/time.h>
 #else 
@@ -74,7 +74,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
 	ms_sleep((U32)(us / 1000));
     return 0;
 }
-#elif LL_LINUX || LL_SOLARIS || LL_DARWIN
+#elif LL_LINUX || LL_DARWIN
 static void _sleep_loop(struct timespec& thiswait)
 {
 	struct timespec nextwait;
@@ -187,7 +187,7 @@ F64 calc_clock_frequency()
 #endif // LL_WINDOWS
 
 
-#if LL_LINUX || LL_DARWIN || LL_SOLARIS
+#if LL_LINUX || LL_DARWIN
 // Both Linux and Mac use gettimeofday for accurate time
 F64 calc_clock_frequency()
 {
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index ec70213447cfd3079f599abe3b69befc0837e091..010f290b24780db7f3fabe7ef5af00b644698fe1 100644
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
@@ -27,7 +27,7 @@
 #ifndef LL_TIMER_H					
 #define LL_TIMER_H
 
-#if LL_LINUX || LL_DARWIN || LL_SOLARIS
+#if LL_LINUX || LL_DARWIN
 #include <sys/time.h>
 #endif
 #include <limits.h>
diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp
index c275b90120d976123822300688aa568dbeda0efa..e4f229dd163f05bd22608c4d9b3ff2b158ce1804 100644
--- a/indra/llcommon/lluriparser.cpp
+++ b/indra/llcommon/lluriparser.cpp
@@ -29,10 +29,13 @@
 #include "linden_common.h"
 #include "lluriparser.h"
 
+#if LL_DARWIN
+#include <signal.h>
+#include <setjmp.h>
+#endif
+
 LLUriParser::LLUriParser(const std::string& u) : mTmpScheme(false), mNormalizedTmp(false), mRes(0)
 {
-	mState.uri = &mUri;
-
 	if (u.find("://") == std::string::npos)
 	{
 		mNormalizedUri = "http://";
@@ -51,7 +54,7 @@ LLUriParser::~LLUriParser()
 
 S32 LLUriParser::parse()
 {
-	mRes = uriParseUriA(&mState, mNormalizedUri.c_str());
+	mRes = uriParseSingleUriA(&mUri, mNormalizedUri.c_str(), NULL);
 	return mRes;
 }
 
@@ -158,31 +161,69 @@ void LLUriParser::extractParts()
 	}
 }
 
+#if LL_DARWIN
+typedef void(*sighandler_t)(int);
+jmp_buf return_to_normalize;
+void uri_signal_handler(int signal)
+{
+    // Apparently signal handler throwing an exception doesn't work.
+    // This is ugly and unsafe due to not unwinding content of uriparser library,
+    // but unless we have a way to catch this as NSexception, jump appears to be the only option.
+    longjmp(return_to_normalize, 1 /*setjmp will return this value*/);
+}
+#endif
+
 S32 LLUriParser::normalize()
 {
 	mNormalizedTmp = mTmpScheme;
 	if (!mRes)
 	{
-		mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
-
-		if (!mRes)
-		{
-			S32 chars_required;
-			mRes = uriToStringCharsRequiredA(&mUri, &chars_required);
-
-			if (!mRes)
-			{
-				chars_required++;
-				std::vector<char> label_buf(chars_required);
-				mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL);
-
-				if (!mRes)
-				{
-					mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0];
-					mTmpScheme = false;
-				}
-			}
-		}
+#if LL_DARWIN
+        sighandler_t last_handler;
+        last_handler = signal(SIGILL, &uri_signal_handler);		// illegal instruction
+        if (setjmp(return_to_normalize))
+        {
+            // Issue: external library crashed via signal
+            // If you encountered this, please try to figure out what's wrong:
+            // 1. Verify that library's input is 'sane'
+            // 2. Check if we have an NSexception to work with (unlikely)
+            // 3. See if passing same string causes exception to repeat
+            //
+            // Crash happens at uriNormalizeSyntaxExA
+            // Warning!!! This does not properly unwind stack,
+            // if this can be handled by NSexception, it needs to be remade
+            llassert(0);
+
+            LL_WARNS() << "Uriparser crashed with SIGILL, while processing: " << mNormalizedUri << LL_ENDL;
+            signal(SIGILL, last_handler);
+            return 1;
+        }
+#endif
+
+        mRes = uriNormalizeSyntaxExA(&mUri, URI_NORMALIZE_SCHEME | URI_NORMALIZE_HOST);
+
+#if LL_DARWIN
+        signal(SIGILL, last_handler);
+#endif
+
+        if (!mRes)
+        {
+            S32 chars_required;
+            mRes = uriToStringCharsRequiredA(&mUri, &chars_required);
+
+            if (!mRes)
+            {
+                chars_required++;
+                std::vector<char> label_buf(chars_required);
+                mRes = uriToStringA(&label_buf[0], &mUri, chars_required, NULL);
+
+                if (!mRes)
+                {
+                    mNormalizedUri = &label_buf[mTmpScheme ? 7 : 0];
+                    mTmpScheme = false;
+                }
+            }
+        }
 	}
 
 	if(mTmpScheme)
diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h
index cfbf54f3c8592fb597a1c297988b67ff8d7ad96e..92626b90540232c3cc4d2e9d7ddef58fd6af0f6c 100644
--- a/indra/llcommon/lluriparser.h
+++ b/indra/llcommon/lluriparser.h
@@ -76,7 +76,6 @@ class LL_COMMON_API LLUriParser
 	std::string mFragment;
 	std::string mNormalizedUri;
 
-	UriParserStateA mState;
 	UriUriA mUri;
 
 	S32 mRes;
diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp
index b05630c6b59fbc17a248077f529ac33c6c35d7df..e3b293e465c050031e9d30f272d44017ac4be065 100644
--- a/indra/llcommon/lluuid.cpp
+++ b/indra/llcommon/lluuid.cpp
@@ -601,9 +601,7 @@ S32 LLUUID::getNodeID(unsigned char *node_id)
 #define HAVE_NETINET_IN_H
 #ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
-#if LL_SOLARIS
-#include <sys/sockio.h>
-#elif !LL_DARWIN
+#if !LL_DARWIN
 #include <linux/sockios.h>
 #endif
 #endif
diff --git a/indra/llcommon/stdtypes.h b/indra/llcommon/stdtypes.h
index 6c9871e76c9fd5ed45a9435b1faaf52f89bb877a..887f6ab7332413fcd2a8bc043636935c516729e1 100644
--- a/indra/llcommon/stdtypes.h
+++ b/indra/llcommon/stdtypes.h
@@ -57,7 +57,7 @@ typedef unsigned __int64		U64;
 #else
 typedef long long int			S64;
 typedef long long unsigned int		U64;
-#if LL_DARWIN || LL_LINUX || LL_SOLARIS
+#if LL_DARWIN || LL_LINUX
 #define S64L(a)				(a##LL)
 #define U64L(a)				(a##ULL)
 #endif
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index 11b2e3e929f591d16867315584bde4e9c3fe914f..240ea2da839ee0bc56054208c811eef23bf02ae8 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -178,6 +178,7 @@ if (DARWIN)
     libaprutil-1.0.dylib
     libexception_handler.dylib
     libnghttp2*.dylib
+    liburiparser*.dylib
     ${EXPAT_COPY}
     )
 
diff --git a/indra/llinventory/llparcel.h b/indra/llinventory/llparcel.h
index 3b39aeb56b3a6503fc932e4ed1020afc30539713..5d08c1f4c69a24249fbb7c20290ffe3cc820f98b 100644
--- a/indra/llinventory/llparcel.h
+++ b/indra/llinventory/llparcel.h
@@ -295,7 +295,6 @@ class LLParcel
 	void	setAllowTerraform(BOOL b){setParcelFlag(PF_ALLOW_TERRAFORM, b); }
 	void	setAllowDamage(BOOL b)	{ setParcelFlag(PF_ALLOW_DAMAGE, b); }
 	void	setAllowFly(BOOL b)		{ setParcelFlag(PF_ALLOW_FLY, b); }
-	void	setAllowLandmark(BOOL b){ setParcelFlag(PF_ALLOW_LANDMARK, b); }
 	void	setAllowGroupScripts(BOOL b)	{ setParcelFlag(PF_ALLOW_GROUP_SCRIPTS, b); }
 	void	setAllowOtherScripts(BOOL b)	{ setParcelFlag(PF_ALLOW_OTHER_SCRIPTS, b); }
 	void	setAllowDeedToGroup(BOOL b) { setParcelFlag(PF_ALLOW_DEED_TO_GROUP, b); }
@@ -476,11 +475,6 @@ class LLParcel
 	BOOL	getAllowFly() const
 					{ return (mParcelFlags & PF_ALLOW_FLY) ? TRUE : FALSE; }
 
-	// Remove permission restrictions for creating landmarks.
-	// We should eventually remove this flag completely.
-	BOOL	getAllowLandmark() const
-					{ return TRUE; }
-
 	BOOL	getAllowGroupScripts() const
 					{ return (mParcelFlags & PF_ALLOW_GROUP_SCRIPTS) ? TRUE : FALSE; }
 
diff --git a/indra/llinventory/llparcelflags.h b/indra/llinventory/llparcelflags.h
index 25b27a281af89dfd3f01891d2a42103f01714247..4cffa83cc1c2446bcc0d64fab432fa8cb0ff1f38 100644
--- a/indra/llinventory/llparcelflags.h
+++ b/indra/llinventory/llparcelflags.h
@@ -33,7 +33,7 @@ const U32 PF_ALLOW_FLY			= 1 << 0;// Can start flying
 const U32 PF_ALLOW_OTHER_SCRIPTS= 1 << 1;// Scripts by others can run.
 const U32 PF_FOR_SALE			= 1 << 2;// Can buy this land
 const U32 PF_FOR_SALE_OBJECTS	= 1 << 7;// Can buy all objects on this land
-const U32 PF_ALLOW_LANDMARK		= 1 << 3;
+const U32 PF_ALLOW_LANDMARK		= 1 << 3;// Always true/deprecated
 const U32 PF_ALLOW_TERRAFORM	= 1 << 4;
 const U32 PF_ALLOW_DAMAGE		= 1 << 5;
 const U32 PF_CREATE_OBJECTS		= 1 << 6;
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index 8f01ad6c1cad3f02a79c14b928327ba62bd43a61..e4ccd81faf444a0d7e2532a83f12640a50676768 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -47,9 +47,6 @@
 #elif (LL_LINUX && __GNUC__ <= 2)
 #define llisnan(val)	isnan(val)
 #define llfinite(val)	isfinite(val)
-#elif LL_SOLARIS
-#define llisnan(val)    isnan(val)
-#define llfinite(val)   (val <= std::numeric_limits<double>::max())
 #else
 #define llisnan(val)	std::isnan(val)
 #define llfinite(val)	std::isfinite(val)
diff --git a/indra/llmath/llsdutil_math.cpp b/indra/llmath/llsdutil_math.cpp
index 591f7fde360896bfe5846e71f771afff4975863e..51e5e3764f4192375bb47f22f2048679a817f3c6 100644
--- a/indra/llmath/llsdutil_math.cpp
+++ b/indra/llmath/llsdutil_math.cpp
@@ -40,7 +40,7 @@
 #if LL_WINDOWS
 #	define WIN32_LEAN_AND_MEAN
 #	include <winsock2.h>	// for htonl
-#elif LL_LINUX || LL_SOLARIS
+#elif LL_LINUX
 #	include <netinet/in.h>
 #elif LL_DARWIN
 #	include <arpa/inet.h>
diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h
index c799d8eefc5b147f6acfd55d8e7296ea0564f301..7e4572f50fc81b9cdf8242c040af2e924147ba6b 100644
--- a/indra/llmessage/llassetstorage.h
+++ b/indra/llmessage/llassetstorage.h
@@ -262,7 +262,7 @@ class LLAssetStorage
 
     virtual void logAssetStorageInfo() = 0;
     
-	void checkForTimeouts();
+	virtual void checkForTimeouts();
 
 	void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id,
 									const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype,
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 2d8e994d33e8f23cc3ee74b63a20ec74d9c6b2f4..f6cb0d97005713e871140d94f6a07ec02df61404 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -144,10 +144,10 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
     }
 
     LLSD httpResults;
+    bool success = true;
 
     try
     {
-        bool success = true;
 
         LLCoreHttpUtil::HttpCoroutineAdapter httpAdapter("NameCache", sHttpPolicy);
         LLSD results = httpAdapter.getAndSuspend(sHttpRequest, url);
@@ -162,35 +162,47 @@ void LLAvatarNameCache::requestAvatarNameCache_(std::string url, std::vector<LLU
         else
         {
             httpResults = results["http_result"];
-            success = httpResults["success"].asBoolean();
-            if (!success)
+            if (!httpResults.isMap())
             {
-                LL_WARNS("AvNameCache") << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
-                    << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL;
+                success = false;
+                LL_WARNS("AvNameCache") << " Invalid http_result returned from LLCoreHttpUtil::HttpCoroHandler." << LL_ENDL;
             }
-        }
-
-        if (!success)
-        {   // on any sort of failure add dummy records for any agent IDs 
-            // in this request that we do not have cached already
-            std::vector<LLUUID>::const_iterator it = agentIds.begin();
-            for ( ; it != agentIds.end(); ++it)
+            else
             {
-                const LLUUID& agent_id = *it;
-                LLAvatarNameCache::getInstance()->handleAgentError(agent_id);
+                success = httpResults["success"].asBoolean();
+                if (!success)
+                {
+                    LL_WARNS("AvNameCache") << "Error result from LLCoreHttpUtil::HttpCoroHandler. Code "
+                        << httpResults["status"] << ": '" << httpResults["message"] << "'" << LL_ENDL;
+                }
             }
-            return;
         }
 
-        LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults);
+        if (LLAvatarNameCache::instanceExists())
+        {
+            if (!success)
+            {   // on any sort of failure add dummy records for any agent IDs 
+                // in this request that we do not have cached already
+                std::vector<LLUUID>::const_iterator it = agentIds.begin();
+                for (; it != agentIds.end(); ++it)
+                {
+                    const LLUUID& agent_id = *it;
+                    LLAvatarNameCache::getInstance()->handleAgentError(agent_id);
+                }
+                return;
+            }
 
+            LLAvatarNameCache::getInstance()->handleAvNameCacheSuccess(results, httpResults);
+        }
     }
     catch (...)
     {
         LOG_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << LLCoros::getName()
-                                          << "('" << url << "', " << agentIds.size()
-                                          << " http result: " << httpResults.asString()
-                                          << " Agent Ids)"));
+                                          << "('" << url << "', "
+                                          << agentIds.size() << "Agent Ids,"
+                                          << " http result: " << S32(success)
+                                          << " has response: " << S32(httpResults.size())
+                                          << ")"));
         throw;
     }
 }
diff --git a/indra/llmessage/llcoproceduremanager.cpp b/indra/llmessage/llcoproceduremanager.cpp
index a4fe3a2a8e1aba0aeff1b5cd7b936e06bef68504..4d76dacdf7204b23437c479d5d87f284ca2dc4f0 100644
--- a/indra/llmessage/llcoproceduremanager.cpp
+++ b/indra/llmessage/llcoproceduremanager.cpp
@@ -47,7 +47,7 @@ static const std::map<std::string, U32> DefaultPoolSizes{
 };
 
 static const U32 DEFAULT_POOL_SIZE = 5;
-static const U32 DEFAULT_QUEUE_SIZE = 4096;
+const U32 LLCoprocedureManager::DEFAULT_QUEUE_SIZE = 4096;
 
 //=========================================================================
 class LLCoprocedurePool: private boost::noncopyable
@@ -194,7 +194,7 @@ void LLCoprocedureManager::setPropertyMethods(SettingQuery_t queryfn, SettingUpd
     mPropertyDefineFn = updatefn;
 
     // workaround until we get mutex into initializePool
-    initializePool("VAssetStorage");
+    initializePool("AssetStorage");
     initializePool("Upload");
 }
 
@@ -281,7 +281,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
     mPoolSize(size),
     mActiveCoprocsCount(0),
     mPending(0),
-    mPendingCoprocs(boost::make_shared<CoprocQueue_t>(DEFAULT_QUEUE_SIZE)),
+    mPendingCoprocs(boost::make_shared<CoprocQueue_t>(LLCoprocedureManager::DEFAULT_QUEUE_SIZE)),
     mHTTPPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID),
     mCoroMapping()
 {
@@ -332,7 +332,7 @@ LLCoprocedurePool::LLCoprocedurePool(const std::string &poolName, size_t size):
         mCoroMapping.insert(CoroAdapterMap_t::value_type(pooledCoro, httpAdapter));
     }
 
-    LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << DEFAULT_QUEUE_SIZE << LL_ENDL;
+    LL_INFOS("CoProcMgr") << "Created coprocedure pool named \"" << mPoolName << "\" with " << size << " items, queue max " << LLCoprocedureManager::DEFAULT_QUEUE_SIZE << LL_ENDL;
 }
 
 LLCoprocedurePool::~LLCoprocedurePool() 
diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h
index 70204ba02b53b9d28b693595e47378a76d60700e..d5557c129f2a9c55350074dc89c40edb6aa801d9 100644
--- a/indra/llmessage/llcoproceduremanager.h
+++ b/indra/llmessage/llcoproceduremanager.h
@@ -91,6 +91,9 @@ class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager >
 
     SettingQuery_t mPropertyQueryFn;
     SettingUpdate_t mPropertyDefineFn;
+
+public:
+    static const U32 DEFAULT_QUEUE_SIZE;
 };
 
 #endif
diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
index 52dbf871dbc963be38a38b4bbf597946b4a3b7ef..e25a9ea7efdeb4cf1f9a0cbef0777638b02641d8 100644
--- a/indra/llmessage/message.h
+++ b/indra/llmessage/message.h
@@ -35,10 +35,6 @@
 #include <netinet/in.h>
 #endif
 
-#if LL_SOLARIS
-#include <netinet/in.h>
-#endif
-
 #if LL_WINDOWS
 #include "winsock2.h" // htons etc.
 #endif
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index a2d9b4cd9b54e9c236669448d77b08a2d5e67516..702a1b523843864d24d1f88690aed0cabfe5008d 100644
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -434,7 +434,7 @@ void LLModel::generateNormals(F32 angle_cutoff)
 
 		if (vol_face.mNumIndices > 65535)
 		{
-			LL_WARNS() << "Too many vertices for normal generation to work." << LL_ENDL;
+			LL_WARNS("MESHSKININFO") << "Too many vertices for normal generation to work." << LL_ENDL;
 			continue;
 		}
 
@@ -1100,7 +1100,7 @@ bool LLModel::loadModel(std::istream& is)
 	{
 		if (!LLSDSerialize::fromBinary(header, is, 1024*1024*1024))
 		{
-			LL_WARNS() << "Mesh header parse error.  Not a valid mesh asset!" << LL_ENDL;
+			LL_WARNS("MESHSKININFO") << "Mesh header parse error.  Not a valid mesh asset!" << LL_ENDL;
 			return false;
 		}
 	}
@@ -1132,7 +1132,7 @@ bool LLModel::loadModel(std::istream& is)
 	if (header[lod_name[lod]]["offset"].asInteger() == -1 || 
 		header[lod_name[lod]]["size"].asInteger() == 0 )
 	{ //cannot load requested LOD
-		LL_WARNS() << "LoD data is invalid!" << LL_ENDL;
+		LL_WARNS("MESHSKININFO") << "LoD data is invalid!" << LL_ENDL;
 		return false;
 	}
 
@@ -1195,7 +1195,7 @@ bool LLModel::loadModel(std::istream& is)
 	}
 	else
 	{
-		LL_WARNS() << "unpackVolumeFaces failed!" << LL_ENDL;
+		LL_WARNS("MESHSKININFO") << "unpackVolumeFaces failed!" << LL_ENDL;
 	}
 
 	return false;
@@ -1223,7 +1223,7 @@ bool LLModel::isMaterialListSubset( LLModel* ref )
 
 		if (!foundRef)
 		{
-            LL_INFOS() << "Could not find material " << mMaterialList[src] << " in reference model " << ref->mLabel << LL_ENDL;
+            LL_INFOS("MESHSKININFO") << "Could not find material " << mMaterialList[src] << " in reference model " << ref->mLabel << LL_ENDL;
 			return false;
 		}
 	}
@@ -1259,7 +1259,7 @@ bool LLModel::matchMaterialOrder(LLModel* ref, int& refFaceCnt, int& modelFaceCn
 	bool isASubset = isMaterialListSubset( ref );
 	if ( !isASubset )
 	{
-		LL_INFOS()<<"Material of model is not a subset of reference."<<LL_ENDL;
+		LL_INFOS("MESHSKININFO")<<"Material of model is not a subset of reference."<<LL_ENDL;
 		return false;
 	}
 	
@@ -1398,6 +1398,14 @@ void LLMeshSkinInfo::fromLLSD(LLSD& skin)
 
 			mInvBindMatrix.push_back(mat);
 		}
+
+        if (mJointNames.size() != mInvBindMatrix.size())
+        {
+            LL_WARNS("MESHSKININFO") << "Joints vs bind matrix count mismatch. Dropping joint bindings." << LL_ENDL;
+            mJointNames.clear();
+            mJointNums.clear();
+            mInvBindMatrix.clear();
+        }
 	}
 
 	if (skin.has("bind_shape_matrix"))
@@ -1842,14 +1850,14 @@ bool validate_face(const LLVolumeFace& face)
 	{
 		if (face.mIndices[i] >= face.mNumVertices)
 		{
-			LL_WARNS() << "Face has invalid index." << LL_ENDL;
+			LL_WARNS("MESHSKININFO") << "Face has invalid index." << LL_ENDL;
 			return false;
 		}
 	}
 
 	if (face.mNumIndices % 3 != 0 || face.mNumIndices == 0)
 	{
-		LL_WARNS() << "Face has invalid number of indices." << LL_ENDL;
+		LL_WARNS("MESHSKININFO") << "Face has invalid number of indices." << LL_ENDL;
 		return false;
 	}
 
@@ -1879,7 +1887,7 @@ bool validate_model(const LLModel* mdl)
 {
 	if (mdl->getNumVolumeFaces() == 0)
 	{
-		LL_WARNS() << "Model has no faces!" << LL_ENDL;
+		LL_WARNS("MESHSKININFO") << "Model has no faces!" << LL_ENDL;
 		return false;
 	}
 
@@ -1887,13 +1895,13 @@ bool validate_model(const LLModel* mdl)
 	{
 		if (mdl->getVolumeFace(i).mNumVertices == 0)
 		{
-			LL_WARNS() << "Face has no vertices." << LL_ENDL;
+			LL_WARNS("MESHSKININFO") << "Face has no vertices." << LL_ENDL;
 			return false;
 		}
 
 		if (mdl->getVolumeFace(i).mNumIndices == 0)
 		{
-			LL_WARNS() << "Face has no indices." << LL_ENDL;
+			LL_WARNS("MESHSKININFO") << "Face has no indices." << LL_ENDL;
 			return false;
 		}
 
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index ee02a90b54cedb67d18120d7c83f367675dfa0bb..43fedeca64053ddc78a3d202c0170baec33b35c8 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -151,7 +151,7 @@ LLMatrix4 gGLObliqueProjectionInverse;
 
 std::list<LLGLUpdate*> LLGLUpdate::sGLQ;
 
-#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS)  && !LL_MESA_HEADLESS
+#if (LL_WINDOWS || LL_LINUX)  && !LL_MESA_HEADLESS
 // ATI prototypes
 
 #if LL_WINDOWS
@@ -328,7 +328,7 @@ PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL;
 #endif
 
 // vertex shader prototypes
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
 PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB = NULL;
 PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB = NULL;
 PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB = NULL;
@@ -347,7 +347,7 @@ PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB = NULL;
 PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB = NULL;
 PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB = NULL;
 PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB = NULL;
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
 PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4nbvARB = NULL;
 PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4nivARB = NULL;
 PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4nsvARB = NULL;
@@ -355,7 +355,7 @@ PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4nubARB = NULL;
 PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4nubvARB = NULL;
 PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4nuivARB = NULL;
 PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4nusvARB = NULL;
-#if LL_LINUX  || LL_SOLARIS
+#if LL_LINUX
 PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB = NULL;
 PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB = NULL;
 PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB = NULL;
@@ -393,7 +393,7 @@ PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB = NULL;
 PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB = NULL;
 PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB = NULL;
 PFNGLISPROGRAMARBPROC glIsProgramARB = NULL;
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
 PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB = NULL;
 PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB = NULL;
 PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB = NULL;
@@ -471,8 +471,6 @@ LLGLManager::LLGLManager() :
 
 	mHasSeparateSpecularColor(FALSE),
 
-	mDebugGPU(FALSE),
-
 	mDriverVersionMajor(1),
 	mDriverVersionMinor(0),
 	mDriverVersionRelease(0),
@@ -854,10 +852,6 @@ bool LLGLManager::initGL()
 
 	stop_glerror();
 	
-	setToDebugGPU();
-
-	stop_glerror();
-
 	initGLStates();
 
 	stop_glerror();
@@ -865,17 +859,6 @@ bool LLGLManager::initGL()
 	return true;
 }
 
-void LLGLManager::setToDebugGPU()
-{
-	//"MOBILE INTEL(R) 965 EXPRESS CHIP", 
-	if (mGLRenderer.find("INTEL") != std::string::npos && mGLRenderer.find("965") != std::string::npos)
-	{
-		mDebugGPU = TRUE ;
-	}
-
-	return ;
-}
-
 void LLGLManager::getGLInfo(LLSD& info)
 {
 	if (gHeadlessClient)
@@ -1032,7 +1015,6 @@ void LLGLManager::asLLSD(LLSD& info)
 	// Other fields
 	info["has_requirements"] = mHasRequirements;
 	info["has_separate_specular_color"] = mHasSeparateSpecularColor;
-	info["debug_gpu"] = mDebugGPU;
 	info["max_vertex_range"] = mGLMaxVertexRange;
 	info["max_index_range"] = mGLMaxIndexRange;
 	info["max_texture_size"] = mGLMaxTextureSize;
@@ -1167,7 +1149,7 @@ void LLGLManager::initExtensions()
 	mHasFragmentShader = ExtensionExists("GL_ARB_fragment_shader", gGLHExts.mSysExts) && (LLRender::sGLCoreProfile || ExtensionExists("GL_ARB_shading_language_100", gGLHExts.mSysExts));
 #endif
 
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
 	LL_INFOS() << "initExtensions() checking shell variables to adjust features..." << LL_ENDL;
 	// Our extension support for the Linux Client is very young with some
 	// potential driver gotchas, so offer a semi-secret way to turn it off.
@@ -1237,7 +1219,7 @@ void LLGLManager::initExtensions()
 		if (strchr(blacklist,'u')) mHasDepthClamp = FALSE;
 		
 	}
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
 	
 	if (!mHasMultitexture)
 	{
@@ -1315,7 +1297,7 @@ void LLGLManager::initExtensions()
 	glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
 	glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
 
-#if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
+#if (LL_WINDOWS || LL_LINUX) && !LL_MESA_HEADLESS
 	LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
 	if (mHasVertexBufferObject)
 	{
@@ -1414,7 +1396,7 @@ void LLGLManager::initExtensions()
 		glDebugMessageCallbackARB = (PFNGLDEBUGMESSAGECALLBACKARBPROC) GLH_EXT_GET_PROC_ADDRESS("glDebugMessageCallbackARB");
 		glGetDebugMessageLogARB = (PFNGLGETDEBUGMESSAGELOGARBPROC) GLH_EXT_GET_PROC_ADDRESS("glGetDebugMessageLogARB");
 	}
-#if (!LL_LINUX && !LL_SOLARIS) || LL_LINUX_NV_GL_HEADERS
+#if (!LL_LINUX) || LL_LINUX_NV_GL_HEADERS
 	// This is expected to be a static symbol on Linux GL implementations, except if we use the nvidia headers - bah
 	glDrawRangeElements = (PFNGLDRAWRANGEELEMENTSPROC)GLH_EXT_GET_PROC_ADDRESS("glDrawRangeElements");
 	if (!glDrawRangeElements)
@@ -2775,8 +2757,9 @@ LLGLSPipelineBlendSkyBox::LLGLSPipelineBlendSkyBox(bool depth_test, bool depth_w
 
 #if LL_WINDOWS
 // Expose desired use of high-performance graphics processor to Optimus driver and to AMD driver
+// https://docs.nvidia.com/gameworks/content/technologies/desktop/optimus.htm
 extern "C" 
-{
+{ 
     __declspec(dllexport) DWORD NvOptimusEnablement = 0x00000001;
     __declspec(dllexport) int AmdPowerXpressRequestHighPerformance = 1;
 }
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 966c4b3c77139de1ef4591cc83b12006d80df733..a07e2d9bb02871a8a724fa00c0d46ebd00fb1335 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -142,9 +142,6 @@ class LLGLManager
 	// Misc extensions
 	BOOL mHasSeparateSpecularColor;
 
-	//whether this GPU is in the debug list.
-	BOOL mDebugGPU;
-	
 	S32 mDriverVersionMajor;
 	S32 mDriverVersionMinor;
 	S32 mDriverVersionRelease;
@@ -178,7 +175,6 @@ class LLGLManager
 	void initExtensions();
 	void initGLStates();
 	void initGLImages();
-	void setToDebugGPU();
 };
 
 extern LLGLManager gGLManager;
diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h
index 36fbb381bb13425096a5713b1e692298f96d6879..6bca3623e09c101b01656bd505355062a6acbff2 100644
--- a/indra/llrender/llglheaders.h
+++ b/indra/llrender/llglheaders.h
@@ -27,242 +27,7 @@
 #ifndef LL_LLGLHEADERS_H
 #define LL_LLGLHEADERS_H
 
-#if LL_SOLARIS
-#   if defined(__sparc)
-#      define I_NEED_OS2_H 	//  avoiding BOOL conflicts
-#   endif
-#   include "GL/gl.h"
-#   if defined(__sparc)
-#      undef I_NEED_OS2_H
-#      ifdef BOOL
-#         undef BOOL		// now get rid of Xmd.h crap
-#      endif
-#   endif
-#   include "GL/glx.h"
-#   define  GL_GLEXT_PROTOTYPES 1
-#   include "GL/glext.h"
-#   include "GL/glu.h"
-#   include "GL/glx.h"
-#   define  GLX_GLXEXT_PROTOTYPES 1
-#   include "GL/glxext.h"
-//#   define  GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddressARB((const GLubyte*)(p))
-#   define  GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddress((const GLubyte*)(p))
-
-// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly
-// This header is distributed with SL.  You'll find it in linden/libraries/include/GL/
-# define __APPLE__
-# include "GL/glh_extensions.h"
-# undef __APPLE__
-
-
-// GL_ARB_vertex_buffer_object
-extern PFNGLBINDBUFFERARBPROC		glBindBufferARB;
-extern PFNGLDELETEBUFFERSARBPROC	glDeleteBuffersARB;
-extern PFNGLGENBUFFERSARBPROC		glGenBuffersARB;
-extern PFNGLISBUFFERARBPROC			glIsBufferARB;
-extern PFNGLBUFFERDATAARBPROC		glBufferDataARB;
-extern PFNGLBUFFERSUBDATAARBPROC	glBufferSubDataARB;
-extern PFNGLGETBUFFERSUBDATAARBPROC glGetBufferSubDataARB;
-extern PFNGLMAPBUFFERARBPROC		glMapBufferARB;
-extern PFNGLUNMAPBUFFERARBPROC		glUnmapBufferARB;
-extern PFNGLGETBUFFERPARAMETERIVARBPROC	glGetBufferParameterivARB;
-extern PFNGLGETBUFFERPOINTERVARBPROC	glGetBufferPointervARB;
-
-// GL_ARB_vertex_array_object
-extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray;
-extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays;
-extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays;
-extern PFNGLISVERTEXARRAYPROC glIsVertexArray;
-
-// GL_ARB_sync
-extern PFNGLFENCESYNCPROC				glFenceSync;
-extern PFNGLISSYNCPROC					glIsSync;
-extern PFNGLDELETESYNCPROC				glDeleteSync;
-extern PFNGLCLIENTWAITSYNCPROC			glClientWaitSync;
-extern PFNGLWAITSYNCPROC				glWaitSync;
-extern PFNGLGETINTEGER64VPROC			glGetInteger64v;
-extern PFNGLGETSYNCIVPROC				glGetSynciv;
-
-// GL_APPLE_flush_buffer_range
-extern PFNGLBUFFERPARAMETERIAPPLEPROC	glBufferParameteriAPPLE;
-extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE;
-
-// GL_ARB_map_buffer_range
-extern PFNGLMAPBUFFERRANGEPROC			glMapBufferRange;
-extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC	glFlushMappedBufferRange;
-
-// GL_ATI_vertex_array_object
-extern PFNGLNEWOBJECTBUFFERATIPROC			glNewObjectBufferATI;
-extern PFNGLISOBJECTBUFFERATIPROC			glIsObjectBufferATI;
-extern PFNGLUPDATEOBJECTBUFFERATIPROC		glUpdateObjectBufferATI;
-extern PFNGLGETOBJECTBUFFERFVATIPROC		glGetObjectBufferfvATI;
-extern PFNGLGETOBJECTBUFFERIVATIPROC		glGetObjectBufferivATI;
-extern PFNGLFREEOBJECTBUFFERATIPROC		    glFreeObjectBufferATI;
-extern PFNGLARRAYOBJECTATIPROC				glArrayObjectATI;
-extern PFNGLVERTEXATTRIBARRAYOBJECTATIPROC	glVertexAttribArrayObjectATI;
-extern PFNGLGETARRAYOBJECTFVATIPROC			glGetArrayObjectfvATI;
-extern PFNGLGETARRAYOBJECTIVATIPROC			glGetArrayObjectivATI;
-extern PFNGLVARIANTARRAYOBJECTATIPROC		glVariantObjectArrayATI;
-extern PFNGLGETVARIANTARRAYOBJECTFVATIPROC	glGetVariantArrayObjectfvATI;
-extern PFNGLGETVARIANTARRAYOBJECTIVATIPROC	glGetVariantArrayObjectivATI;
-
-// GL_ARB_occlusion_query
-extern PFNGLGENQUERIESARBPROC glGenQueriesARB;
-extern PFNGLDELETEQUERIESARBPROC glDeleteQueriesARB;
-extern PFNGLISQUERYARBPROC glIsQueryARB;
-extern PFNGLBEGINQUERYARBPROC glBeginQueryARB;
-extern PFNGLENDQUERYARBPROC glEndQueryARB;
-extern PFNGLGETQUERYIVARBPROC glGetQueryivARB;
-extern PFNGLGETQUERYOBJECTIVARBPROC glGetQueryObjectivARB;
-extern PFNGLGETQUERYOBJECTUIVARBPROC glGetQueryObjectuivARB;
-
-// GL_ARB_timer_query
-extern PFNGLQUERYCOUNTERPROC glQueryCounter;
-extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v;
-extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v;
-
-// GL_ARB_point_parameters
-extern PFNGLPOINTPARAMETERFARBPROC glPointParameterfARB;
-extern PFNGLPOINTPARAMETERFVARBPROC glPointParameterfvARB;
-
-// GL_ARB_shader_objects
-extern PFNGLDELETEOBJECTARBPROC glDeleteObjectARB;
-extern PFNGLGETHANDLEARBPROC glGetHandleARB;
-extern PFNGLDETACHOBJECTARBPROC glDetachObjectARB;
-extern PFNGLCREATESHADEROBJECTARBPROC glCreateShaderObjectARB;
-extern PFNGLSHADERSOURCEARBPROC glShaderSourceARB;
-extern PFNGLCOMPILESHADERARBPROC glCompileShaderARB;
-extern PFNGLCREATEPROGRAMOBJECTARBPROC glCreateProgramObjectARB;
-extern PFNGLATTACHOBJECTARBPROC glAttachObjectARB;
-extern PFNGLLINKPROGRAMARBPROC glLinkProgramARB;
-extern PFNGLUSEPROGRAMOBJECTARBPROC glUseProgramObjectARB;
-extern PFNGLVALIDATEPROGRAMARBPROC glValidateProgramARB;
-extern PFNGLUNIFORM1FARBPROC glUniform1fARB;
-extern PFNGLUNIFORM2FARBPROC glUniform2fARB;
-extern PFNGLUNIFORM3FARBPROC glUniform3fARB;
-extern PFNGLUNIFORM4FARBPROC glUniform4fARB;
-extern PFNGLUNIFORM1IARBPROC glUniform1iARB;
-extern PFNGLUNIFORM2IARBPROC glUniform2iARB;
-extern PFNGLUNIFORM3IARBPROC glUniform3iARB;
-extern PFNGLUNIFORM4IARBPROC glUniform4iARB;
-extern PFNGLUNIFORM1FVARBPROC glUniform1fvARB;
-extern PFNGLUNIFORM2FVARBPROC glUniform2fvARB;
-extern PFNGLUNIFORM3FVARBPROC glUniform3fvARB;
-extern PFNGLUNIFORM4FVARBPROC glUniform4fvARB;
-extern PFNGLUNIFORM1IVARBPROC glUniform1ivARB;
-extern PFNGLUNIFORM2IVARBPROC glUniform2ivARB;
-extern PFNGLUNIFORM3IVARBPROC glUniform3ivARB;
-extern PFNGLUNIFORM4IVARBPROC glUniform4ivARB;
-extern PFNGLUNIFORMMATRIX2FVARBPROC glUniformMatrix2fvARB;
-extern PFNGLUNIFORMMATRIX3FVARBPROC glUniformMatrix3fvARB;
-extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv;
-extern PFNGLUNIFORMMATRIX4FVARBPROC glUniformMatrix4fvARB;
-extern PFNGLGETOBJECTPARAMETERFVARBPROC glGetObjectParameterfvARB;
-extern PFNGLGETOBJECTPARAMETERIVARBPROC glGetObjectParameterivARB;
-extern PFNGLGETINFOLOGARBPROC glGetInfoLogARB;
-extern PFNGLGETATTACHEDOBJECTSARBPROC glGetAttachedObjectsARB;
-extern PFNGLGETUNIFORMLOCATIONARBPROC glGetUniformLocationARB;
-extern PFNGLGETACTIVEUNIFORMARBPROC glGetActiveUniformARB;
-extern PFNGLGETUNIFORMFVARBPROC glGetUniformfvARB;
-extern PFNGLGETUNIFORMIVARBPROC glGetUniformivARB;
-extern PFNGLGETSHADERSOURCEARBPROC glGetShaderSourceARB;
-
-// GL_ARB_vertex_shader
-extern PFNGLVERTEXATTRIB1DARBPROC glVertexAttrib1dARB;
-extern PFNGLVERTEXATTRIB1DVARBPROC glVertexAttrib1dvARB;
-extern PFNGLVERTEXATTRIB1FARBPROC glVertexAttrib1fARB;
-extern PFNGLVERTEXATTRIB1FVARBPROC glVertexAttrib1fvARB;
-extern PFNGLVERTEXATTRIB1SARBPROC glVertexAttrib1sARB;
-extern PFNGLVERTEXATTRIB1SVARBPROC glVertexAttrib1svARB;
-extern PFNGLVERTEXATTRIB2DARBPROC glVertexAttrib2dARB;
-extern PFNGLVERTEXATTRIB2DVARBPROC glVertexAttrib2dvARB;
-extern PFNGLVERTEXATTRIB2FARBPROC glVertexAttrib2fARB;
-extern PFNGLVERTEXATTRIB2FVARBPROC glVertexAttrib2fvARB;
-extern PFNGLVERTEXATTRIB2SARBPROC glVertexAttrib2sARB;
-extern PFNGLVERTEXATTRIB2SVARBPROC glVertexAttrib2svARB;
-extern PFNGLVERTEXATTRIB3DARBPROC glVertexAttrib3dARB;
-extern PFNGLVERTEXATTRIB3DVARBPROC glVertexAttrib3dvARB;
-extern PFNGLVERTEXATTRIB3FARBPROC glVertexAttrib3fARB;
-extern PFNGLVERTEXATTRIB3FVARBPROC glVertexAttrib3fvARB;
-extern PFNGLVERTEXATTRIB3SARBPROC glVertexAttrib3sARB;
-extern PFNGLVERTEXATTRIB3SVARBPROC glVertexAttrib3svARB;
-extern PFNGLVERTEXATTRIB4NBVARBPROC glVertexAttrib4nbvARB;
-extern PFNGLVERTEXATTRIB4NIVARBPROC glVertexAttrib4nivARB;
-extern PFNGLVERTEXATTRIB4NSVARBPROC glVertexAttrib4nsvARB;
-extern PFNGLVERTEXATTRIB4NUBARBPROC glVertexAttrib4nubARB;
-extern PFNGLVERTEXATTRIB4NUBVARBPROC glVertexAttrib4nubvARB;
-extern PFNGLVERTEXATTRIB4NUIVARBPROC glVertexAttrib4nuivARB;
-extern PFNGLVERTEXATTRIB4NUSVARBPROC glVertexAttrib4nusvARB;
-extern PFNGLVERTEXATTRIB4BVARBPROC glVertexAttrib4bvARB;
-extern PFNGLVERTEXATTRIB4DARBPROC glVertexAttrib4dARB;
-extern PFNGLVERTEXATTRIB4DVARBPROC glVertexAttrib4dvARB;
-extern PFNGLVERTEXATTRIB4FARBPROC glVertexAttrib4fARB;
-extern PFNGLVERTEXATTRIB4FVARBPROC glVertexAttrib4fvARB;
-extern PFNGLVERTEXATTRIB4IVARBPROC glVertexAttrib4ivARB;
-extern PFNGLVERTEXATTRIB4SARBPROC glVertexAttrib4sARB;
-extern PFNGLVERTEXATTRIB4SVARBPROC glVertexAttrib4svARB;
-extern PFNGLVERTEXATTRIB4UBVARBPROC glVertexAttrib4ubvARB;
-extern PFNGLVERTEXATTRIB4UIVARBPROC glVertexAttrib4uivARB;
-extern PFNGLVERTEXATTRIB4USVARBPROC glVertexAttrib4usvARB;
-extern PFNGLVERTEXATTRIBPOINTERARBPROC glVertexAttribPointerARB;
-extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer;
-extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC glEnableVertexAttribArrayARB;
-extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC glDisableVertexAttribArrayARB;
-extern PFNGLPROGRAMSTRINGARBPROC glProgramStringARB;
-extern PFNGLBINDPROGRAMARBPROC glBindProgramARB;
-extern PFNGLDELETEPROGRAMSARBPROC glDeleteProgramsARB;
-extern PFNGLGENPROGRAMSARBPROC glGenProgramsARB;
-extern PFNGLPROGRAMENVPARAMETER4DARBPROC glProgramEnvParameter4dARB;
-extern PFNGLPROGRAMENVPARAMETER4DVARBPROC glProgramEnvParameter4dvARB;
-extern PFNGLPROGRAMENVPARAMETER4FARBPROC glProgramEnvParameter4fARB;
-extern PFNGLPROGRAMENVPARAMETER4FVARBPROC glProgramEnvParameter4fvARB;
-extern PFNGLPROGRAMLOCALPARAMETER4DARBPROC glProgramLocalParameter4dARB;
-extern PFNGLPROGRAMLOCALPARAMETER4DVARBPROC glProgramLocalParameter4dvARB;
-extern PFNGLPROGRAMLOCALPARAMETER4FARBPROC glProgramLocalParameter4fARB;
-extern PFNGLPROGRAMLOCALPARAMETER4FVARBPROC glProgramLocalParameter4fvARB;
-extern PFNGLGETPROGRAMENVPARAMETERDVARBPROC glGetProgramEnvParameterdvARB;
-extern PFNGLGETPROGRAMENVPARAMETERFVARBPROC glGetProgramEnvParameterfvARB;
-extern PFNGLGETPROGRAMLOCALPARAMETERDVARBPROC glGetProgramLocalParameterdvARB;
-extern PFNGLGETPROGRAMLOCALPARAMETERFVARBPROC glGetProgramLocalParameterfvARB;
-extern PFNGLGETPROGRAMIVARBPROC glGetProgramivARB;
-extern PFNGLGETPROGRAMSTRINGARBPROC glGetProgramStringARB;
-extern PFNGLGETVERTEXATTRIBDVARBPROC glGetVertexAttribdvARB;
-extern PFNGLGETVERTEXATTRIBFVARBPROC glGetVertexAttribfvARB;
-extern PFNGLGETVERTEXATTRIBIVARBPROC glGetVertexAttribivARB;
-extern PFNGLGETVERTEXATTRIBPOINTERVARBPROC glGetVertexAttribPointervARB;
-extern PFNGLISPROGRAMARBPROC glIsProgramARB;
-extern PFNGLBINDATTRIBLOCATIONARBPROC glBindAttribLocationARB;
-extern PFNGLGETACTIVEATTRIBARBPROC glGetActiveAttribARB;
-extern PFNGLGETATTRIBLOCATIONARBPROC glGetAttribLocationARB;
-
-extern PFNGLCOMPRESSEDTEXIMAGE2DARBPROC glCompressedTexImage2DARB;
-extern PFNGLGETCOMPRESSEDTEXIMAGEARBPROC glGetCompressedTexImageARB;
-
-extern PFNGLCOLORTABLEEXTPROC glColorTableEXT;
-
-//GL_EXT_blend_func_separate
-extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT;
-
-//GL_EXT_framebuffer_object
-extern PFNGLISRENDERBUFFEREXTPROC glIsRenderbufferEXT;
-extern PFNGLBINDRENDERBUFFEREXTPROC glBindRenderbufferEXT;
-extern PFNGLDELETERENDERBUFFERSEXTPROC glDeleteRenderbuffersEXT;
-extern PFNGLGENRENDERBUFFERSEXTPROC glGenRenderbuffersEXT;
-extern PFNGLRENDERBUFFERSTORAGEEXTPROC glRenderbufferStorageEXT;
-extern PFNGLGETRENDERBUFFERPARAMETERIVEXTPROC glGetRenderbufferParameterivEXT;
-extern PFNGLISFRAMEBUFFEREXTPROC glIsFramebufferEXT;
-extern PFNGLBINDFRAMEBUFFEREXTPROC glBindFramebufferEXT;
-extern PFNGLDELETEFRAMEBUFFERSEXTPROC glDeleteFramebuffersEXT;
-extern PFNGLGENFRAMEBUFFERSEXTPROC glGenFramebuffersEXT;
-extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC glCheckFramebufferStatusEXT;
-extern PFNGLFRAMEBUFFERTEXTURE1DEXTPROC glFramebufferTexture1DEXT;
-extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC glFramebufferTexture2DEXT;
-extern PFNGLFRAMEBUFFERTEXTURE3DEXTPROC glFramebufferTexture3DEXT;
-extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC glFramebufferRenderbufferEXT;
-extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVEXTPROC glGetFramebufferAttachmentParameterivEXT;
-extern PFNGLGENERATEMIPMAPEXTPROC glGenerateMipmapEXT;
-
-#elif LL_MESA
+#if LL_MESA
 //----------------------------------------------------------------------------
 // MESA headers
 // quotes so we get libraries/.../GL/ version
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 384e5bf99fe3e87c45134d3e7771871ef4884dcf..4351f6e2c86cdde783f128c835c95f4f6f4e4604 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -37,6 +37,10 @@
 #include "OpenGL/OpenGL.h"
 #endif
 
+// Print-print list of shader included source files that are linked together via glAttachObjectARB()
+// i.e. On macOS / OSX the AMD GLSL linker will display an error if a varying is left in an undefined state.
+#define DEBUG_SHADER_INCLUDES 0
+
 // Lots of STL stuff in here, using namespace std to keep things more readable
 using std::vector;
 using std::pair;
@@ -392,16 +396,28 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
     mLightHash = 0xFFFFFFFF;
 
     llassert_always(!mShaderFiles.empty());
-    BOOL success = TRUE;
 
     // Create program
     mProgramObject = glCreateProgramObjectARB();
+    if (mProgramObject == 0)
+    {
+        // Shouldn't happen if shader related extensions, like ARB_vertex_shader, exist.
+        LL_SHADER_LOADING_WARNS() << "Failed to create handle for shader: " << mName << LL_ENDL;
+        unloadInternal();
+        return FALSE;
+    }
+
+    BOOL success = TRUE;
     
 #if LL_DARWIN
     // work-around missing mix(vec3,vec3,bvec3)
     mDefines["OLD_SELECT"] = "1";
 #endif
     
+#if DEBUG_SHADER_INCLUDES
+    fprintf(stderr, "--- %s ---\n", mName.c_str());
+#endif // DEBUG_SHADER_INCLUDES
+
     //compile new source
     vector< pair<string,GLenum> >::iterator fileIter = mShaderFiles.begin();
     for ( ; fileIter != mShaderFiles.end(); fileIter++ )
@@ -485,11 +501,36 @@ BOOL LLGLSLShader::createShader(std::vector<LLStaticHashedString> * attributes,
     return success;
 }
 
-BOOL LLGLSLShader::attachVertexObject(std::string object_path) {
+#if DEBUG_SHADER_INCLUDES
+void dumpAttachObject( const char *func_name, GLhandleARB program_object, const std::string &object_path )
+{
+    GLcharARB* info_log;
+    GLint      info_len_expect = 0;
+    GLint      info_len_actual = 0;
+
+    glGetObjectParameterivARB(program_object, GL_OBJECT_INFO_LOG_LENGTH_ARB, &info_len_expect);
+    fprintf(stderr, " * %-20s(), log size: %d, %s\n", func_name, info_len_expect, object_path.c_str());
+
+    if (info_len_expect > 0)
+    {
+        fprintf(stderr, " ========== %s() ========== \n", func_name);
+        info_log = new GLcharARB [ info_len_expect ];
+        glGetInfoLogARB(program_object, info_len_expect, &info_len_actual, info_log);
+        fprintf(stderr, "%s\n",  info_log);
+        delete [] info_log;
+    }
+}
+#endif // DEBUG_SHADER_INCLUDES
+
+BOOL LLGLSLShader::attachVertexObject(std::string object_path)
+{
     if (LLShaderMgr::instance()->mVertexShaderObjects.count(object_path) > 0)
     {
         stop_glerror();
         glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mVertexShaderObjects[object_path]);
+#if DEBUG_SHADER_INCLUDES
+        dumpAttachObject("attachVertexObject", mProgramObject, object_path);
+#endif // DEBUG_SHADER_INCLUDES
         stop_glerror();
         return TRUE;
     }
@@ -506,6 +547,9 @@ BOOL LLGLSLShader::attachFragmentObject(std::string object_path)
     {
         stop_glerror();
         glAttachObjectARB(mProgramObject, LLShaderMgr::instance()->mFragmentShaderObjects[object_path]);
+#if DEBUG_SHADER_INCLUDES
+        dumpAttachObject("attachFragmentObject", mProgramObject, object_path);
+#endif // DEBUG_SHADER_INCLUDES
         stop_glerror();
         return TRUE;
     }
@@ -522,6 +566,10 @@ void LLGLSLShader::attachObject(GLhandleARB object)
     {
         stop_glerror();
         glAttachObjectARB(mProgramObject, object);
+#if DEBUG_SHADER_INCLUDES
+        std::string object_path("???");
+        dumpAttachObject("attachObject", mProgramObject, object_path);
+#endif // DEBUG_SHADER_INCLUDES
         stop_glerror();
     }
     else
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 11d9ef3f57fdd42633124929011b1b8b1bdd31fe..d515fc707aa6a6aa9b22b717bf60e923aa4ccaac 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -871,10 +871,10 @@ void LLTexUnit::setTextureColorSpace(eTextureColorSpace space)
         }
     }
     else
-#endif
     {
         glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT);
     }
+#endif
 }
 
 LLLightState::LLLightState(S32 index)
diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp
index 8881d25c97239afaf44eea1682c7cd77e964dd32..dba257fc3aea340c1ad4fcb911c9a0b5eb6653dd 100644
--- a/indra/llrender/llshadermgr.cpp
+++ b/indra/llrender/llshadermgr.cpp
@@ -611,13 +611,11 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 #endif
 
 	GLenum error = GL_NO_ERROR;
-	if (gDebugGL)
+
+	error = glGetError();
+	if (error != GL_NO_ERROR)
 	{
-		error = glGetError();
-		if (error != GL_NO_ERROR)
-		{
-			LL_SHADER_LOADING_WARNS() << "GL ERROR entering loadShaderFile(): " << error << LL_ENDL;
-		}
+		LL_SHADER_LOADING_WARNS() << "GL ERROR entering loadShaderFile(): " << error << " for file: " << filename << LL_ENDL;
 	}
 	
 	if (filename.empty()) 
@@ -966,55 +964,45 @@ GLhandleARB LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shade
 
 	//create shader object
 	GLhandleARB ret = glCreateShaderObjectARB(type);
-	if (gDebugGL)
+
+	error = glGetError();
+	if (error != GL_NO_ERROR)
 	{
-		error = glGetError();
-		if (error != GL_NO_ERROR)
-		{
-			LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << LL_ENDL;
-		}
+		LL_WARNS("ShaderLoading") << "GL ERROR in glCreateShaderObjectARB: " << error << " for file: " << open_file_name << LL_ENDL;
 	}
-	
+
 	//load source
 	glShaderSourceARB(ret, shader_code_count, (const GLcharARB**) shader_code_text, NULL);
 
-	if (gDebugGL)
+	error = glGetError();
+	if (error != GL_NO_ERROR)
 	{
-		error = glGetError();
-		if (error != GL_NO_ERROR)
-		{
-			LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << LL_ENDL;
-		}
+		LL_WARNS("ShaderLoading") << "GL ERROR in glShaderSourceARB: " << error << " for file: " << open_file_name << LL_ENDL;
 	}
 
 	//compile source
 	glCompileShaderARB(ret);
 
-	if (gDebugGL)
+	error = glGetError();
+	if (error != GL_NO_ERROR)
 	{
-		error = glGetError();
-		if (error != GL_NO_ERROR)
-		{
-			LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << LL_ENDL;
-		}
+		LL_WARNS("ShaderLoading") << "GL ERROR in glCompileShaderARB: " << error << " for file: " << open_file_name << LL_ENDL;
 	}
-		
+
 	if (error == GL_NO_ERROR)
 	{
 		//check for errors
 		GLint success = GL_TRUE;
 		glGetObjectParameterivARB(ret, GL_OBJECT_COMPILE_STATUS_ARB, &success);
-		if (gDebugGL || success == GL_FALSE)
+
+		error = glGetError();
+		if (error != GL_NO_ERROR || success == GL_FALSE) 
 		{
-			error = glGetError();
-			if (error != GL_NO_ERROR || success == GL_FALSE) 
-			{
-				//an error occured, print log
-				LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL;
-				dumpObjectLog(ret, TRUE, open_file_name);
-                dumpShaderSource(shader_code_count, shader_code_text);
-				ret = 0;
-			}
+			//an error occured, print log
+			LL_WARNS("ShaderLoading") << "GLSL Compilation Error:" << LL_ENDL;
+			dumpObjectLog(ret, TRUE, open_file_name);
+			dumpShaderSource(shader_code_count, shader_code_text);
+			ret = 0;
 		}
 	}
 	else
diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h
index cf77b3ce596d298374affde62231372e6cc0bb7f..254190dca23b16ed92a6180d8f3a7ef7ac1c124b 100644
--- a/indra/llrender/llshadermgr.h
+++ b/indra/llrender/llshadermgr.h
@@ -36,175 +36,176 @@ class LLShaderMgr
 	LLShaderMgr();
 	virtual ~LLShaderMgr();
 
-	typedef enum
-	{
-		MODELVIEW_MATRIX = 0,
-		PROJECTION_MATRIX,
-		INVERSE_PROJECTION_MATRIX,
-		MODELVIEW_PROJECTION_MATRIX,
-        INVERSE_MODELVIEW_MATRIX,
-		NORMAL_MATRIX,
-		TEXTURE_MATRIX0,
-		TEXTURE_MATRIX1,
-		TEXTURE_MATRIX2,
-		TEXTURE_MATRIX3,
-		OBJECT_PLANE_S,
-		OBJECT_PLANE_T,
-		VIEWPORT,
-		LIGHT_POSITION,
-		LIGHT_DIRECTION,
-		LIGHT_ATTENUATION,
-		LIGHT_DIFFUSE,
-		LIGHT_AMBIENT,
-		MULTI_LIGHT_COUNT,
-		MULTI_LIGHT,
-		MULTI_LIGHT_COL,
-		MULTI_LIGHT_FAR_Z,
-		PROJECTOR_MATRIX,
-		PROJECTOR_NEAR,
-		PROJECTOR_P,
-		PROJECTOR_N,
-		PROJECTOR_ORIGIN,
-		PROJECTOR_RANGE,
-		PROJECTOR_AMBIANCE,
-		PROJECTOR_SHADOW_INDEX,
-		PROJECTOR_SHADOW_FADE,
-		PROJECTOR_FOCUS,
-		PROJECTOR_LOD,
-		PROJECTOR_AMBIENT_LOD,
-		DIFFUSE_COLOR,
-		DIFFUSE_MAP,
-        ALTERNATE_DIFFUSE_MAP,
-		SPECULAR_MAP,
-		BUMP_MAP,
-        BUMP_MAP2,
-		ENVIRONMENT_MAP,
-		CLOUD_NOISE_MAP,
-        CLOUD_NOISE_MAP_NEXT,
-		FULLBRIGHT,
-		LIGHTNORM,
-		SUNLIGHT_COLOR,
-		AMBIENT,
-		BLUE_HORIZON,
-		BLUE_DENSITY,
-		HAZE_HORIZON,
-		HAZE_DENSITY,
-		CLOUD_SHADOW,
-		DENSITY_MULTIPLIER,
-		DISTANCE_MULTIPLIER,
-		MAX_Y,
-		GLOW,
-		CLOUD_COLOR,
-		CLOUD_POS_DENSITY1,
-		CLOUD_POS_DENSITY2,
-		CLOUD_SCALE,
-		GAMMA,
-		SCENE_LIGHT_STRENGTH,
-		LIGHT_CENTER,
-		LIGHT_SIZE,
-		LIGHT_FALLOFF,
-		BOX_CENTER,
-		BOX_SIZE,
-
-		GLOW_MIN_LUMINANCE,
-		GLOW_MAX_EXTRACT_ALPHA,
-		GLOW_LUM_WEIGHTS,
-		GLOW_WARMTH_WEIGHTS,
-		GLOW_WARMTH_AMOUNT,
-		GLOW_STRENGTH,
-		GLOW_DELTA,
-
-		MINIMUM_ALPHA,
-		EMISSIVE_BRIGHTNESS,
-
-		DEFERRED_SHADOW_MATRIX,
-		DEFERRED_ENV_MAT,
-		DEFERRED_SHADOW_CLIP,
-		DEFERRED_SUN_WASH,
-		DEFERRED_SHADOW_NOISE,
-		DEFERRED_BLUR_SIZE,
-		DEFERRED_SSAO_RADIUS,
-		DEFERRED_SSAO_MAX_RADIUS,
-		DEFERRED_SSAO_FACTOR,
-		DEFERRED_SSAO_FACTOR_INV,
-		DEFERRED_SSAO_EFFECT_MAT,
-		DEFERRED_SCREEN_RES,
-		DEFERRED_NEAR_CLIP,
-		DEFERRED_SHADOW_OFFSET,
-		DEFERRED_SHADOW_BIAS,
-		DEFERRED_SPOT_SHADOW_BIAS,
-		DEFERRED_SPOT_SHADOW_OFFSET,
-		DEFERRED_SUN_DIR,
-        DEFERRED_MOON_DIR,
-		DEFERRED_SHADOW_RES,
-		DEFERRED_PROJ_SHADOW_RES,
-		DEFERRED_DEPTH_CUTOFF,
-		DEFERRED_NORM_CUTOFF,
-		DEFERRED_SHADOW_TARGET_WIDTH,
-
-		FXAA_TC_SCALE,
-		FXAA_RCP_SCREEN_RES,
-		FXAA_RCP_FRAME_OPT,
-		FXAA_RCP_FRAME_OPT2,
-
-		DOF_FOCAL_DISTANCE,
-		DOF_BLUR_CONSTANT,
-		DOF_TAN_PIXEL_ANGLE,
-		DOF_MAGNIFICATION,
-		DOF_MAX_COF,
-		DOF_RES_SCALE,
-		DOF_WIDTH,
-		DOF_HEIGHT,
-
-		DEFERRED_DEPTH,
-		DEFERRED_SHADOW0,
-		DEFERRED_SHADOW1,
-		DEFERRED_SHADOW2,
-		DEFERRED_SHADOW3,
-		DEFERRED_SHADOW4,
-		DEFERRED_SHADOW5,
-		DEFERRED_NORMAL,
-		DEFERRED_POSITION,
-		DEFERRED_DIFFUSE,
-		DEFERRED_SPECULAR,
-		DEFERRED_NOISE,
-		DEFERRED_LIGHTFUNC,
-		DEFERRED_LIGHT,
-		DEFERRED_BLOOM,
-		DEFERRED_PROJECTION,
-		DEFERRED_NORM_MATRIX,
-		TEXTURE_GAMMA,		
-		SPECULAR_COLOR,
-		ENVIRONMENT_INTENSITY,
-		
-		AVATAR_MATRIX,
-		AVATAR_TRANSLATION,
-
-		WATER_SCREENTEX,
-		WATER_SCREENDEPTH,
-		WATER_REFTEX,
-		WATER_EYEVEC,
-		WATER_TIME,
-		WATER_WAVE_DIR1,
-		WATER_WAVE_DIR2,
-		WATER_LIGHT_DIR,
-		WATER_SPECULAR,
-		WATER_SPECULAR_EXP,
-		WATER_FOGCOLOR,
-		WATER_FOGDENSITY,
-		WATER_FOGKS,
-		WATER_REFSCALE,
-		WATER_WATERHEIGHT,
-		WATER_WATERPLANE,
-		WATER_NORM_SCALE,
-		WATER_FRESNEL_SCALE,
-		WATER_FRESNEL_OFFSET,
-		WATER_BLUR_MULTIPLIER,
-		WATER_SUN_ANGLE,
-		WATER_SCALED_ANGLE,
-		WATER_SUN_ANGLE2,
-		
-		WL_CAMPOSLOCAL,
+    // clang-format off
+    typedef enum
+    {                                       // Shader uniform name, set in LLShaderMgr::initAttribsAndUniforms()
+        MODELVIEW_MATRIX = 0,               //  "modelview_matrix"
+        PROJECTION_MATRIX,                  //  "projection_matrix"
+        INVERSE_PROJECTION_MATRIX,          //  "inv_proj"
+        MODELVIEW_PROJECTION_MATRIX,        //  "modelview_projection_matrix"
+        INVERSE_MODELVIEW_MATRIX,           //  "inv_modelview"
+        NORMAL_MATRIX,                      //  "normal_matrix"
+        TEXTURE_MATRIX0,                    //  "texture_matrix0"
+        TEXTURE_MATRIX1,                    //  "texture_matrix1"
+        TEXTURE_MATRIX2,                    //  "texture_matrix2"
+        TEXTURE_MATRIX3,                    //  "texture_matrix3"
+        OBJECT_PLANE_S,                     //  "object_plane_s"
+        OBJECT_PLANE_T,                     //  "object_plane_t"
+        VIEWPORT,                           //  "viewport"
+        LIGHT_POSITION,                     //  "light_position"
+        LIGHT_DIRECTION,                    //  "light_direction"
+        LIGHT_ATTENUATION,                  //  "light_attenuation"
+        LIGHT_DIFFUSE,                      //  "light_diffuse"
+        LIGHT_AMBIENT,                      //  "light_ambient"
+        MULTI_LIGHT_COUNT,                  //  "light_count"
+        MULTI_LIGHT,                        //  "light"
+        MULTI_LIGHT_COL,                    //  "light_col"
+        MULTI_LIGHT_FAR_Z,                  //  "far_z"
+        PROJECTOR_MATRIX,                   //  "proj_mat"
+        PROJECTOR_NEAR,                     //  "proj_near"
+        PROJECTOR_P,                        //  "proj_p"
+        PROJECTOR_N,                        //  "proj_n"
+        PROJECTOR_ORIGIN,                   //  "proj_origin"
+        PROJECTOR_RANGE,                    //  "proj_range"
+        PROJECTOR_AMBIANCE,                 //  "proj_ambiance"
+        PROJECTOR_SHADOW_INDEX,             //  "proj_shadow_idx"
+        PROJECTOR_SHADOW_FADE,              //  "shadow_fade"
+        PROJECTOR_FOCUS,                    //  "proj_focus"
+        PROJECTOR_LOD,                      //  "proj_lod"
+        PROJECTOR_AMBIENT_LOD,              //  "proj_ambient_lod"
+        DIFFUSE_COLOR,                      //  "color"
+        DIFFUSE_MAP,                        //  "diffuseMap"
+        ALTERNATE_DIFFUSE_MAP,              //  "altDiffuseMap"
+        SPECULAR_MAP,                       //  "specularMap"
+        BUMP_MAP,                           //  "bumpMap"
+        BUMP_MAP2,                          //  "bumpMap2"
+        ENVIRONMENT_MAP,                    //  "environmentMap"
+        CLOUD_NOISE_MAP,                    //  "cloud_noise_texture"
+        CLOUD_NOISE_MAP_NEXT,               //  "cloud_noise_texture_next"
+        FULLBRIGHT,                         //  "fullbright"
+        LIGHTNORM,                          //  "lightnorm"
+        SUNLIGHT_COLOR,                     //  "sunlight_color"
+        AMBIENT,                            //  "ambient_color"
+        BLUE_HORIZON,                       //  "blue_horizon"
+        BLUE_DENSITY,                       //  "blue_density"
+        HAZE_HORIZON,                       //  "haze_horizon"
+        HAZE_DENSITY,                       //  "haze_density"
+        CLOUD_SHADOW,                       //  "cloud_shadow"
+        DENSITY_MULTIPLIER,                 //  "density_multiplier"
+        DISTANCE_MULTIPLIER,                //  "distance_multiplier"
+        MAX_Y,                              //  "max_y"
+        GLOW,                               //  "glow"
+        CLOUD_COLOR,                        //  "cloud_color"
+        CLOUD_POS_DENSITY1,                 //  "cloud_pos_density1"
+        CLOUD_POS_DENSITY2,                 //  "cloud_pos_density2"
+        CLOUD_SCALE,                        //  "cloud_scale"
+        GAMMA,                              //  "gamma"
+        SCENE_LIGHT_STRENGTH,               //  "scene_light_strength"
+        LIGHT_CENTER,                       //  "center"
+        LIGHT_SIZE,                         //  "size"
+        LIGHT_FALLOFF,                      //  "falloff"
+        BOX_CENTER,                         //  "box_center"
+        BOX_SIZE,                           //  "box_size"
+
+        GLOW_MIN_LUMINANCE,                 //  "minLuminance"
+        GLOW_MAX_EXTRACT_ALPHA,             //  "maxExtractAlpha"
+        GLOW_LUM_WEIGHTS,                   //  "lumWeights"
+        GLOW_WARMTH_WEIGHTS,                //  "warmthWeights"
+        GLOW_WARMTH_AMOUNT,                 //  "warmthAmount"
+        GLOW_STRENGTH,                      //  "glowStrength"
+        GLOW_DELTA,                         //  "glowDelta"
+
+        MINIMUM_ALPHA,                      //  "minimum_alpha"
+        EMISSIVE_BRIGHTNESS,                //  "emissive_brightness"
+
+        DEFERRED_SHADOW_MATRIX,             //  "shadow_matrix"
+        DEFERRED_ENV_MAT,                   //  "env_mat"
+        DEFERRED_SHADOW_CLIP,               //  "shadow_clip"
+        DEFERRED_SUN_WASH,                  //  "sun_wash"
+        DEFERRED_SHADOW_NOISE,              //  "shadow_noise"
+        DEFERRED_BLUR_SIZE,                 //  "blur_size"
+        DEFERRED_SSAO_RADIUS,               //  "ssao_radius"
+        DEFERRED_SSAO_MAX_RADIUS,           //  "ssao_max_radius"
+        DEFERRED_SSAO_FACTOR,               //  "ssao_factor"
+        DEFERRED_SSAO_FACTOR_INV,           //  "ssao_factor_inv"
+        DEFERRED_SSAO_EFFECT_MAT,           //  "ssao_effect_mat"
+        DEFERRED_SCREEN_RES,                //  "screen_res"
+        DEFERRED_NEAR_CLIP,                 //  "near_clip"
+        DEFERRED_SHADOW_OFFSET,             //  "shadow_offset"
+        DEFERRED_SHADOW_BIAS,               //  "shadow_bias"
+        DEFERRED_SPOT_SHADOW_BIAS,          //  "spot_shadow_bias"
+        DEFERRED_SPOT_SHADOW_OFFSET,        //  "spot_shadow_offset"
+        DEFERRED_SUN_DIR,                   //  "sun_dir"
+        DEFERRED_MOON_DIR,                  //  "moon_dir"
+        DEFERRED_SHADOW_RES,                //  "shadow_res"
+        DEFERRED_PROJ_SHADOW_RES,           //  "proj_shadow_res"
+        DEFERRED_DEPTH_CUTOFF,              //  "depth_cutoff"
+        DEFERRED_NORM_CUTOFF,               //  "norm_cutoff"
+        DEFERRED_SHADOW_TARGET_WIDTH,       //  "shadow_target_width"
+
+        FXAA_TC_SCALE,                      //  "tc_scale"
+        FXAA_RCP_SCREEN_RES,                //  "rcp_screen_res"
+        FXAA_RCP_FRAME_OPT,                 //  "rcp_frame_opt"
+        FXAA_RCP_FRAME_OPT2,                //  "rcp_frame_opt2"
+
+        DOF_FOCAL_DISTANCE,                 //  "focal_distance"
+        DOF_BLUR_CONSTANT,                  //  "blur_constant"
+        DOF_TAN_PIXEL_ANGLE,                //  "tan_pixel_angle"
+        DOF_MAGNIFICATION,                  //  "magnification"
+        DOF_MAX_COF,                        //  "max_cof"
+        DOF_RES_SCALE,                      //  "res_scale"
+        DOF_WIDTH,                          //  "dof_width"
+        DOF_HEIGHT,                         //  "dof_height"
+
+        DEFERRED_DEPTH,                     //  "depthMap"
+        DEFERRED_SHADOW0,                   //  "shadowMap0"
+        DEFERRED_SHADOW1,                   //  "shadowMap1"
+        DEFERRED_SHADOW2,                   //  "shadowMap2"
+        DEFERRED_SHADOW3,                   //  "shadowMap3"
+        DEFERRED_SHADOW4,                   //  "shadowMap4"
+        DEFERRED_SHADOW5,                   //  "shadowMap5"
+        DEFERRED_NORMAL,                    //  "normalMap"
+        DEFERRED_POSITION,                  //  "positionMap"
+        DEFERRED_DIFFUSE,                   //  "diffuseRect"
+        DEFERRED_SPECULAR,                  //  "specularRect"
+        DEFERRED_NOISE,                     //  "noiseMap"
+        DEFERRED_LIGHTFUNC,                 //  "lightFunc"
+        DEFERRED_LIGHT,                     //  "lightMap"
+        DEFERRED_BLOOM,                     //  "bloomMap"
+        DEFERRED_PROJECTION,                //  "projectionMap"
+        DEFERRED_NORM_MATRIX,               //  "norm_mat"
+        TEXTURE_GAMMA,                      //  "texture_gamma"
+        SPECULAR_COLOR,                     //  "specular_color"
+        ENVIRONMENT_INTENSITY,              //  "env_intensity"
+
+        AVATAR_MATRIX,                      //  "matrixPalette"
+        AVATAR_TRANSLATION,                 //  "translationPalette"
+
+        WATER_SCREENTEX,                    //  "screenTex"
+        WATER_SCREENDEPTH,                  //  "screenDepth"
+        WATER_REFTEX,                       //  "refTex"
+        WATER_EYEVEC,                       //  "eyeVec"
+        WATER_TIME,                         //  "time"
+        WATER_WAVE_DIR1,                    //  "waveDir1"
+        WATER_WAVE_DIR2,                    //  "waveDir2"
+        WATER_LIGHT_DIR,                    //  "lightDir"
+        WATER_SPECULAR,                     //  "specular"
+        WATER_SPECULAR_EXP,                 //  "lightExp"
+        WATER_FOGCOLOR,                     //  "waterFogColor"
+        WATER_FOGDENSITY,                   //  "waterFogDensity"
+        WATER_FOGKS,                        //  "waterFogKS"
+        WATER_REFSCALE,                     //  "refScale"
+        WATER_WATERHEIGHT,                  //  "waterHeight"
+        WATER_WATERPLANE,                   //  "waterPlane"
+        WATER_NORM_SCALE,                   //  "normScale"
+        WATER_FRESNEL_SCALE,                //  "fresnelScale"
+        WATER_FRESNEL_OFFSET,               //  "fresnelOffset"
+        WATER_BLUR_MULTIPLIER,              //  "blurMultiplier"
+        WATER_SUN_ANGLE,                    //  "sunAngle"
+        WATER_SCALED_ANGLE,                 //  "scaledAngle"
+        WATER_SUN_ANGLE2,                   //  "sunAngle2"
+
+        WL_CAMPOSLOCAL,                     //  "camPosLocal"
 // [RLVa:KB] - @setsphere
 		RLV_EFFECT_MODE,
 		RLV_EFFECT_PARAM1,
@@ -214,51 +215,52 @@ class LLShaderMgr
 		RLV_EFFECT_PARAM5,
 // [/RLVa:KB]
 
-		AVATAR_WIND,
-		AVATAR_SINWAVE,
-		AVATAR_GRAVITY,
+        AVATAR_WIND,                        //  "gWindDir"
+        AVATAR_SINWAVE,                     //  "gSinWaveParams"
+        AVATAR_GRAVITY,                     //  "gGravity"
 
-		TERRAIN_DETAIL0,
-		TERRAIN_DETAIL1,
-		TERRAIN_DETAIL2,
-		TERRAIN_DETAIL3,
-		TERRAIN_ALPHARAMP,
-		
-		SHINY_ORIGIN,
-        DISPLAY_GAMMA,
+        TERRAIN_DETAIL0,                    //  "detail_0"
+        TERRAIN_DETAIL1,                    //  "detail_1"
+        TERRAIN_DETAIL2,                    //  "detail_2"
+        TERRAIN_DETAIL3,                    //  "detail_3"
+        TERRAIN_ALPHARAMP,                  //  "alpha_ramp"
 
-        INSCATTER_RT,
-        SUN_SIZE,
-        FOG_COLOR,
+        SHINY_ORIGIN,                       //  "origin"
+        DISPLAY_GAMMA,                      //  "display_gamma"
+
+        INSCATTER_RT,                       //  "inscatter"
+        SUN_SIZE,                           //  "sun_size"
+        FOG_COLOR,                          //  "fog_color"
 
         // precomputed textures
-        TRANSMITTANCE_TEX,
-        SCATTER_TEX,
-        SINGLE_MIE_SCATTER_TEX,
-        ILLUMINANCE_TEX,
-        BLEND_FACTOR,
-
-        NO_ATMO,
-        MOISTURE_LEVEL,
-        DROPLET_RADIUS,
-        ICE_LEVEL,
-        RAINBOW_MAP,
-        HALO_MAP,
-
-        MOON_BRIGHTNESS,
-
-        CLOUD_VARIANCE,
-
-        SH_INPUT_L1R,
-        SH_INPUT_L1G,
-        SH_INPUT_L1B,
-
-        SUN_MOON_GLOW_FACTOR,
-        WATER_EDGE_FACTOR,
-        SUN_UP_FACTOR,
-        MOONLIGHT_COLOR,
-		END_RESERVED_UNIFORMS
-	} eGLSLReservedUniforms;
+        TRANSMITTANCE_TEX,                  //  "transmittance_texture"
+        SCATTER_TEX,                        //  "scattering_texture"
+        SINGLE_MIE_SCATTER_TEX,             //  "single_mie_scattering_texture"
+        ILLUMINANCE_TEX,                    //  "irradiance_texture"
+        BLEND_FACTOR,                       //  "blend_factor"
+
+        NO_ATMO,                            //  "no_atmo"
+        MOISTURE_LEVEL,                     //  "moisture_level"
+        DROPLET_RADIUS,                     //  "droplet_radius"
+        ICE_LEVEL,                          //  "ice_level"
+        RAINBOW_MAP,                        //  "rainbow_map"
+        HALO_MAP,                           //  "halo_map"
+
+        MOON_BRIGHTNESS,                    //  "moon_brightness"
+
+        CLOUD_VARIANCE,                     //  "cloud_variance"
+
+        SH_INPUT_L1R,                       //  "sh_input_r"
+        SH_INPUT_L1G,                       //  "sh_input_g"
+        SH_INPUT_L1B,                       //  "sh_input_b"
+
+        SUN_MOON_GLOW_FACTOR,               //  "sun_moon_glow_factor"
+        WATER_EDGE_FACTOR,                  //  "water_edge"
+        SUN_UP_FACTOR,                      //  "sun_up_factor"
+        MOONLIGHT_COLOR,                    //  "moonlight_color"
+        END_RESERVED_UNIFORMS
+    } eGLSLReservedUniforms;
+    // clang-format on
 
 	// singleton pattern implementation
 	static LLShaderMgr * instance();
diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h
index 9867bd16d6394d6982271afdefc2527108cfa83d..dbe1a3687f12c06056d901ba01c1ca455f5252ec 100644
--- a/indra/llrender/llvertexbuffer.h
+++ b/indra/llrender/llvertexbuffer.h
@@ -155,9 +155,8 @@ class LLVertexBuffer : public LLRefCount, public LLTrace::MemTrackable<LLVertexB
 	//get the size of a buffer with the given typemask and vertex count
 	//fill offsets with the offset of each vertex component array into the buffer
 	// indexed by the following enum
-	static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);		
+	static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices);
 
-	
 	//WARNING -- when updating these enums you MUST 
 	// 1 - update LLVertexBuffer::sTypeSize
 	// 2 - add a strider accessor
@@ -165,24 +164,28 @@ class LLVertexBuffer : public LLRefCount, public LLTrace::MemTrackable<LLVertexB
 	// 4 - modify LLVertexBuffer::setupClientArray
 	// 5 - modify LLViewerShaderMgr::mReservedAttribs
 	// 6 - update LLVertexBuffer::setupVertexArray
-	enum {
-		TYPE_VERTEX = 0,
-		TYPE_NORMAL,
-		TYPE_TEXCOORD0,
-		TYPE_TEXCOORD1,
-		TYPE_TEXCOORD2,
-		TYPE_TEXCOORD3,
-		TYPE_COLOR,
-		TYPE_EMISSIVE,
-		TYPE_TANGENT,
-		TYPE_WEIGHT,
-		TYPE_WEIGHT4,
-		TYPE_CLOTHWEIGHT,
-		TYPE_TEXTURE_INDEX,
-		TYPE_MAX,   // TYPE_MAX is the size/boundary marker for attributes that go in the vertex buffer
-		TYPE_INDEX,	// TYPE_INDEX is beyond _MAX because it lives in a separate (index) buffer	
-	};
-	enum {
+
+    // clang-format off
+    enum {                      // Shader attribute name, set in LLShaderMgr::initAttribsAndUniforms()
+        TYPE_VERTEX = 0,        //  "position"
+        TYPE_NORMAL,            //  "normal"
+        TYPE_TEXCOORD0,         //  "texcoord0"
+        TYPE_TEXCOORD1,         //  "texcoord1"
+        TYPE_TEXCOORD2,         //  "texcoord2"
+        TYPE_TEXCOORD3,         //  "texcoord3"
+        TYPE_COLOR,             //  "diffuse_color"
+        TYPE_EMISSIVE,          //  "emissive"
+        TYPE_TANGENT,           //  "tangent"
+        TYPE_WEIGHT,            //  "weight"
+        TYPE_WEIGHT4,           //  "weight4"
+        TYPE_CLOTHWEIGHT,       //  "clothing"
+        TYPE_TEXTURE_INDEX,     //  "texture_index"
+        TYPE_MAX,   // TYPE_MAX is the size/boundary marker for attributes that go in the vertex buffer
+        TYPE_INDEX,	// TYPE_INDEX is beyond _MAX because it lives in a separate (index) buffer	
+    };
+    // clang-format on
+
+    enum {
 		MAP_VERTEX = (1<<TYPE_VERTEX),
 		MAP_NORMAL = (1<<TYPE_NORMAL),
 		MAP_TEXCOORD0 = (1<<TYPE_TEXCOORD0),
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index cce618487b08f2c8bda030f732ec8be3e1b17302..f781ff4110824663e105dcc8c8088b4c89cd8366 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -122,6 +122,7 @@ set(llui_SOURCE_FILES
     lluictrl.cpp
     lluictrlfactory.cpp
     lluistring.cpp
+    lluiusage.cpp
     llundo.cpp
     llurlaction.cpp
     llurlentry.cpp
@@ -241,6 +242,7 @@ set(llui_HEADER_FILES
     llui.h
     lluicolor.h
     lluistring.h
+    lluiusage.h
     llundo.h
     llurlaction.h
     llurlentry.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 9682c3bc1077fbc5289ece6061e5e9452ef39e6e..0e59fdf51936e4c302cbcb66a8e2c5684ebf818e 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -47,6 +47,7 @@
 #include "llnotificationsutil.h"
 #include "llrender.h"
 #include "lluictrlfactory.h"
+#include "lluiusage.h"
 #include "llhelp.h"
 #include "lldockablefloater.h"
 #include "llviewereventrecorder.h"
@@ -437,6 +438,13 @@ BOOL LLButton::handleMouseDown(S32 x, S32 y, MASK mask)
 			setFocus(TRUE);
 		}
 
+		if (!mFunctionName.empty())
+		{
+			LL_DEBUGS("UIUsage") << "calling mouse down function " << mFunctionName << LL_ENDL;
+			LLUIUsage::instance().logCommand(mFunctionName);
+			LLUIUsage::instance().logControl(getPathname());
+		}
+
 		/*
 		 * ATTENTION! This call fires another mouse down callback.
 		 * If you wish to remove this call emit that signal directly
diff --git a/indra/llui/llchat.h b/indra/llui/llchat.h
index 746103b9115590a9cc9400931457848ee79f57f1..435b5d2f1458a4cd8426d7e65eef7c99c47d3868 100644
--- a/indra/llui/llchat.h
+++ b/indra/llui/llchat.h
@@ -37,7 +37,8 @@ typedef enum e_chat_source_type
 	CHAT_SOURCE_SYSTEM = 0,
 	CHAT_SOURCE_AGENT = 1,
 	CHAT_SOURCE_OBJECT = 2,
-	CHAT_SOURCE_UNKNOWN = 3
+	CHAT_SOURCE_TELEPORT = 3,
+	CHAT_SOURCE_UNKNOWN = 4
 } EChatSourceType;
 
 typedef enum e_chat_type
@@ -64,7 +65,8 @@ typedef enum e_chat_style
 {
 	CHAT_STYLE_NORMAL,
 	CHAT_STYLE_IRC,
-	CHAT_STYLE_HISTORY
+	CHAT_STYLE_HISTORY,
+	CHAT_STYLE_TELEPORT_SEP
 }EChatStyle;
 
 // A piece of chat
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index 6a51c4240b5864ae3fa5bd9503e054e9402b0e32..08da599ef24c480aa94461e64e1361184540ccff 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -187,10 +187,32 @@ void LLCheckBoxCtrl::clear()
 
 void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	S32 label_top = mLabel->getRect().mTop;
-	mLabel->reshapeToFitText();
+    LLRect rect = getRect();
+    S32 delta_width = width - rect.getWidth();
+    S32 delta_height = height - rect.getHeight();
 
-	LLRect label_rect = mLabel->getRect();
+    if (delta_width || delta_height)
+    {
+        // adjust our rectangle
+        rect.mRight = getRect().mLeft + width;
+        rect.mTop = getRect().mBottom + height;
+        setRect(rect);
+    }
+
+    // reshapeToFitText reshapes label to minimal size according to last bounding box
+    // it will work fine in case of decrease of space, but if we get more space or text
+    // becomes longer, label will fail to grow so reinit label's dimentions.
+    
+    static LLUICachedControl<S32> llcheckboxctrl_hpad("UICheckboxctrlHPad", 0);
+    LLRect label_rect = mLabel->getRect();
+    S32 new_width = getRect().getWidth() - label_rect.mLeft - llcheckboxctrl_hpad;
+    label_rect.mRight = label_rect.mLeft + new_width;
+    mLabel->setRect(label_rect);
+
+	S32 label_top = label_rect.mTop;
+	mLabel->reshapeToFitText(TRUE);
+
+    label_rect = mLabel->getRect();
 	if (label_top != label_rect.mTop && mWordWrap == WRAP_DOWN)
 	{
 		// reshapeToFitText uses LLView::reshape() which always reshapes
@@ -210,6 +232,8 @@ void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
 		llmax(btn_rect.getWidth(), label_rect.mRight - btn_rect.mLeft),
 		llmax(label_rect.mTop - btn_rect.mBottom, btn_rect.getHeight()));
 	mButton->setShape(btn_rect);
+
+    updateBoundingRect();
 }
 
 //virtual
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index e9c980ad9a1eb63ec516bf82255a9a2ffd827f48..8ceb411ede76dcb8c44abf82a7db959ee524a46a 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -58,6 +58,7 @@
 #include "llhelp.h"
 #include "llmultifloater.h"
 #include "llsdutil.h"
+#include "lluiusage.h"
 #include <boost/foreach.hpp>
 
 
@@ -198,7 +199,9 @@ LLFloater::Params::Params()
 	help_pressed_image("help_pressed_image"),
 	open_callback("open_callback"),
 	close_callback("close_callback"),
-	follows("follows")
+	follows("follows"),
+	rel_x("rel_x", 0),
+	rel_y("rel_y", 0)
 {
 	changeDefault(visible, false);
 }
@@ -267,6 +270,8 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
 	mHasBeenDraggedWhileMinimized(FALSE),
 	mPreviousMinimizedBottom(0),
 	mPreviousMinimizedLeft(0),
+	mDefaultRelativeX(p.rel_x),
+	mDefaultRelativeY(p.rel_y),
 	mMinimizeSignal(NULL)
 //	mNotificationContext(NULL)
 {
@@ -505,7 +510,12 @@ void LLFloater::destroy()
 // virtual
 LLFloater::~LLFloater()
 {
-	LLFloaterReg::removeInstance(mInstanceName, mKey);
+    if (!isDead())
+    {
+        // If it's dead, instance is supposed to be already removed, and
+        // in case of single instance we can remove new one by accident
+        LLFloaterReg::removeInstance(mInstanceName, mKey);
+    }
 	
 	if( gFocusMgr.childHasKeyboardFocus(this))
 	{
@@ -934,6 +944,15 @@ bool LLFloater::applyRectControl()
 
 			saved_rect = true;
 		}
+		else if ((mDefaultRelativeX != 0) && (mDefaultRelativeY != 0))
+		{
+			mPosition.mX = mDefaultRelativeX;
+			mPosition.mY = mDefaultRelativeY;
+			mPositioning = LLFloaterEnums::POSITIONING_RELATIVE;
+			applyRelativePosition();
+
+			saved_rect = true;
+		}
 
 		// remember updated position
 		if (rect_specified)
@@ -1631,6 +1650,7 @@ void LLFloater::bringToFront( S32 x, S32 y )
 // virtual
 void LLFloater::setVisibleAndFrontmost(BOOL take_focus,const LLSD& key)
 {
+	LLUIUsage::instance().logFloater(getInstanceName());
 	LLMultiFloater* hostp = getHost();
 	if (hostp)
 	{
@@ -3198,6 +3218,9 @@ void LLFloater::initFromParams(const LLFloater::Params& p)
 	mSingleInstance = p.single_instance;
 	mReuseInstance = p.reuse_instance.isProvided() ? p.reuse_instance : p.single_instance;
 
+	mDefaultRelativeX = p.rel_x;
+	mDefaultRelativeY = p.rel_y;
+
 	mPositioning = p.positioning;
 
 	mSaveRect = p.save_rect;
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index f8c04e8a2fc18c5e1a5d462c5edccfda12d2006c..2672d600c6236f828fbc3b822962b6f94b485279 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -172,6 +172,9 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 		Optional<S32>			header_height,
 								legacy_header_height; // HACK see initFromXML()
 
+		Optional<F32>			rel_x,
+								rel_y;
+
 		// Images for top-right controls
 		Optional<LLUIImage*>	close_image,
 								restore_image,
@@ -521,6 +524,9 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 	BOOL			mHasBeenDraggedWhileMinimized;
 	S32				mPreviousMinimizedBottom;
 	S32				mPreviousMinimizedLeft;
+
+	F32				mDefaultRelativeX;
+	F32				mDefaultRelativeY;
 };
 
 
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index b7dea9439760b1a355a989740573b7cef40d4451..35ecac6b93c5f343f23ab8a7a67f85ab00ff150b 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -32,6 +32,7 @@
 #include "llfloater.h"
 #include "llmultifloater.h"
 #include "llfloaterreglistener.h"
+#include "lluiusage.h"
 
 //*******************************************************
 
@@ -60,6 +61,12 @@ void LLFloaterReg::add(const std::string& name, const std::string& filename, con
 	sGroupMap[groupname] = groupname; // for referencing directly by group name
 }
 
+//static
+bool LLFloaterReg::isRegistered(const std::string& name)
+{
+    return sBuildMap.find(name) != sBuildMap.end();
+}
+
 //static
 LLFloater* LLFloaterReg::getLastFloaterInGroup(const std::string& name)
 {
@@ -487,7 +494,6 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
 	std::string name = sdname.asString();
 	LLFloater* instance = getInstance(name, key); 
 	
-
 	if (!instance)
 	{
 		LL_DEBUGS() << "Unable to get instance of floater '" << name << "'" << LL_ENDL;
diff --git a/indra/llui/llfloaterreg.h b/indra/llui/llfloaterreg.h
index 5bafe6466473634237af880d650eb3e1e85e5a8a..97dec2b6017cfe55e3ca9446a271cecc4413fbe5 100644
--- a/indra/llui/llfloaterreg.h
+++ b/indra/llui/llfloaterreg.h
@@ -98,6 +98,7 @@ class LLFloaterReg
 	
 	static void add(const std::string& name, const std::string& file, const LLFloaterBuildFunc& func,
 					const std::string& groupname = LLStringUtil::null);
+	static bool isRegistered(const std::string& name);
 
 	// Helpers
 	static LLFloater* getLastFloaterInGroup(const std::string& name);
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index f4ddfa8f18f8cf7b8a112bde85d65a12ee9123ee..e62b2779ddbb34c724f71f00dfaedcaa4d9ca024 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -204,6 +204,7 @@ class LLFolderViewModelItem : public LLRefCount, public LLTrace::MemTrackable<LL
 	virtual bool hasChildren() const = 0;
 	virtual void addChild(LLFolderViewModelItem* child) = 0;
 	virtual void removeChild(LLFolderViewModelItem* child) = 0;
+	virtual void clearChildren() = 0;
 
 	// This method will be called to determine if a drop can be
 	// performed, and will set drop to TRUE if a drop is
@@ -301,9 +302,8 @@ class LLFolderViewModelItemCommon : public LLFolderViewModelItem
 	
 	virtual void clearChildren()
 	{
-		// As this is cleaning the whole list of children wholesale, we do need to delete the pointed objects
-		// This is different and not equivalent to calling removeChild() on each child
-		std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
+		// We are working with models that belong to views as LLPointers, clean the list, let poiters handle the rest
+		std::for_each(mChildren.begin(), mChildren.end(), [](LLFolderViewModelItem* c) {c->setParent(NULL); });
 		mChildren.clear();
 		dirtyDescendantsFilter();
 		dirtyFilter();
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 4aae1e374b796b4f63d0735f3c725e34794365b9..29a156e93300951c62e4f457a8b8dc7d8b26ac6c 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -166,7 +166,7 @@ void LLLayoutPanel::setVisible( BOOL visible )
 
 void LLLayoutPanel::reshape( S32 width, S32 height, BOOL called_from_parent /*= TRUE*/ )
 {
-	if (width == getRect().getWidth() && height == getRect().getHeight()) return;
+	if (width == getRect().getWidth() && height == getRect().getHeight() && !LLView::sForceReshape) return;
 
 	if (!mIgnoreReshape && mAutoResize == false)
 	{
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index aa5779d45f64838e16cbc0fae86a3fab8e6ad1e2..f84625bea7a680467dbe2cce4e0d2f86499221bf 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -283,6 +283,9 @@ class LLLineEditor
 
 	void			resetContextMenu() { setContextMenu(NULL); };
 
+	void			setBgImage(LLPointer<LLUIImage> image) { mBgImage = image; }
+	void			setBgImageFocused(LLPointer<LLUIImage> image) { mBgImageFocused = image; }
+
 private:
 	// private helper methods
 
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 5568a844943737f7d8542875efd4d7c417f1445d..cdaf03ebde411a0d48bd896f4368bb36dfa7b65b 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -79,7 +79,7 @@ const U32 LEFT_PAD_PIXELS = 3;
 const U32 LEFT_WIDTH_PIXELS = 15;
 const U32 LEFT_PLAIN_PIXELS = LEFT_PAD_PIXELS + LEFT_WIDTH_PIXELS;
 
-const U32 RIGHT_PAD_PIXELS = 2;
+const U32 RIGHT_PAD_PIXELS = 7;
 const U32 RIGHT_WIDTH_PIXELS = 15;
 const U32 RIGHT_PLAIN_PIXELS = RIGHT_PAD_PIXELS + RIGHT_WIDTH_PIXELS;
 
@@ -95,7 +95,7 @@ const std::string SEPARATOR_NAME("separator");
 const std::string VERTICAL_SEPARATOR_LABEL( "|" );
 
 const std::string LLMenuGL::BOOLEAN_TRUE_PREFIX( "\xE2\x9C\x94" ); // U+2714 HEAVY CHECK MARK
-const std::string LLMenuGL::BRANCH_SUFFIX( "\xE2\x96\xB6" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE
+const std::string LLMenuGL::BRANCH_SUFFIX( "\xe2\x96\xb8" ); // U+25B6 BLACK RIGHT-POINTING TRIANGLE
 const std::string LLMenuGL::ARROW_UP  ("^^^^^^^");
 const std::string LLMenuGL::ARROW_DOWN("vvvvvvv");
 
@@ -212,6 +212,12 @@ LLSD LLMenuItemGL::getValue() const
 	return getLabel();
 }
 
+//virtual
+bool LLMenuItemGL::hasAccelerator(const KEY &key, const MASK &mask) const
+{
+	return (mAcceleratorKey == key) && (mAcceleratorMask == mask);
+}
+
 //virtual
 BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)
 {
@@ -263,13 +269,13 @@ BOOL LLMenuItemGL::handleRightMouseUp(S32 x, S32 y, MASK mask)
 
 // This function checks to see if the accelerator key is already in use;
 // if not, it will be added to the list
-BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp)
+BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLMenuKeyboardBinding*> *listp)
 {
-	LLKeyBinding *accelerator = NULL;
+	LLMenuKeyboardBinding *accelerator = NULL;
 
 	if (mAcceleratorKey != KEY_NONE)
 	{
-		std::list<LLKeyBinding*>::iterator list_it;
+		std::list<LLMenuKeyboardBinding*>::iterator list_it;
 		for (list_it = listp->begin(); list_it != listp->end(); ++list_it)
 		{
 			accelerator = *list_it;
@@ -293,7 +299,7 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp)
 		}
 		if (!accelerator)
 		{				
-			accelerator = new LLKeyBinding;
+			accelerator = new LLMenuKeyboardBinding;
 			if (accelerator)
 			{
 				accelerator->mKey = mAcceleratorKey;
@@ -1017,6 +1023,11 @@ BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
+bool LLMenuItemBranchGL::hasAccelerator(const KEY &key, const MASK &mask) const
+{
+	return getBranch() && getBranch()->hasAccelerator(key, mask);
+}
+
 BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask)
 {
 	return getBranch() && getBranch()->handleAcceleratorKey(key, mask);
@@ -1024,7 +1035,7 @@ BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask)
 
 // This function checks to see if the accelerator key is already in use;
 // if not, it will be added to the list
-BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLKeyBinding*> *listp)
+BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLMenuKeyboardBinding*> *listp)
 {
 	LLMenuGL* branch = getBranch();
 	if (!branch)
@@ -3023,6 +3034,27 @@ void LLMenuGL::updateParent(LLView* parentp)
 	}
 }
 
+bool LLMenuGL::hasAccelerator(const KEY &key, const MASK &mask) const
+{
+	if (key == KEY_NONE)
+	{
+		return false;
+	}
+	// Note: checking this way because mAccelerators seems to be broken
+	// mAccelerators probably needs to be cleaned up or fixed
+	// It was used for dupplicate accelerator avoidance.
+	item_list_t::const_iterator item_iter;
+	for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
+	{
+		LLMenuItemGL* itemp = *item_iter;
+		if (itemp->hasAccelerator(key, mask))
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
 BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask)
 {
 	// don't handle if not enabled
@@ -3244,7 +3276,7 @@ void hide_top_view( LLView* view )
 // x and y are the desired location for the popup, in the spawning_view's
 // coordinate frame, NOT necessarily the mouse location
 // static
-void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
+void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S32 mouse_x, S32 mouse_y)
 {
 	const S32 CURSOR_HEIGHT = 22;		// Approximate "normal" cursor size
 	const S32 CURSOR_WIDTH = 12;
@@ -3275,12 +3307,6 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
 		}
 	}
 
-	// Save click point for detecting cursor moves before mouse-up.
-	// Must be in local coords to compare with mouseUp events.
-	// If the mouse doesn't move, the menu will stay open ala the Mac.
-	// See also LLContextMenu::show()
-	S32 mouse_x, mouse_y;
-
 	// Resetting scrolling position
 	if (menu->isScrollable() && menu->isScrollPositionOnShowReset())
 	{
@@ -3291,7 +3317,18 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
 	menu->needsArrange();
 	menu->arrangeAndClear();
 
-	LLUI::getInstance()->getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y);
+	if ((mouse_x == 0) || (mouse_y == 0))
+
+	{
+		// Save click point for detecting cursor moves before mouse-up.
+		// Must be in local coords to compare with mouseUp events.
+		// If the mouse doesn't move, the menu will stay open ala the Mac.
+		// See also LLContextMenu::show()
+
+		LLUI::getInstance()->getMousePositionLocal(menu->getParent(), &mouse_x, &mouse_y);
+	}
+	
+	
 	LLMenuHolderGL::sContextMenuSpawnPos.set(mouse_x,mouse_y);
 
 	const LLRect menu_region_rect = LLMenuGL::sMenuContainer->getRect();
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 1f11f26192b232da83c956076dd8df1ed22b9ee4..273bd789c44796b1a76740b2a5c6b002ffb7e0b1 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -42,6 +42,13 @@
 extern S32 MENU_BAR_HEIGHT;
 extern S32 MENU_BAR_WIDTH;
 
+class LLMenuKeyboardBinding
+{
+public:
+    KEY				mKey;
+    MASK			mMask;
+};
+
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLMenuItemGL
 //
@@ -91,6 +98,7 @@ class LLMenuItemGL: public LLUICtrl, public ll::ui::SearchableControl
 	/*virtual*/ void setValue(const LLSD& value);
 	/*virtual*/ LLSD getValue() const;
 
+	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;
 	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
 
 	LLColor4 getHighlightBgColor() { return mHighlightBackground.get(); }
@@ -109,7 +117,7 @@ class LLMenuItemGL: public LLUICtrl, public ll::ui::SearchableControl
 	virtual void setBriefItem(BOOL brief);
 	virtual BOOL isBriefItem() const;
 
-	virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *listp);
+	virtual BOOL addToAcceleratorList(std::list<LLMenuKeyboardBinding*> *listp);
 	void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; }
 	BOOL getAllowKeyRepeat() const { return mAllowKeyRepeat; }
 
@@ -436,7 +444,8 @@ class LLMenuGL
 	/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
 	/*virtual*/ void removeChild( LLView* ctrl);
 	/*virtual*/ BOOL postBuild();
-
+	
+	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;
 	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
 
 	LLMenuGL* findChildMenuByName(const std::string& name, BOOL recurse) const;
@@ -510,7 +519,7 @@ class LLMenuGL
 	void createJumpKeys();
 
 	// Show popup at a specific location, in the spawn_view's coordinate frame
-	static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y);
+	static void showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y, S32 mouse_x = 0, S32 mouse_y = 0);
 
 	// Whether to drop shadow menu bar 
 	void setDropShadowed( const BOOL shadowed );
@@ -628,10 +637,11 @@ class LLMenuItemBranchGL : public LLMenuItemGL
 	
 	virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
 
+	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;
 	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
 
 	// check if we've used these accelerators already
-	virtual BOOL addToAcceleratorList(std::list <LLKeyBinding*> *listp);
+	virtual BOOL addToAcceleratorList(std::list <LLMenuKeyboardBinding*> *listp);
 
 	// called to rebuild the draw label
 	virtual void buildDrawLabel( void );
@@ -797,7 +807,7 @@ class LLMenuBarGL : public LLMenuGL
 
 	void checkMenuTrigger();
 
-	std::list <LLKeyBinding*>	mAccelerators;
+	std::list <LLMenuKeyboardBinding*>	mAccelerators;
 	BOOL						mAltKeyTrigger;
 };
 
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index eb404c82294e3e7fa335be0c674b0b71cdd15a43..e8424aaf1d45bcf8fcfda39d7544124c21c8fdb1 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -77,6 +77,7 @@ LLNotificationForm::FormButton::FormButton()
 	text("text"),
 	ignore("ignore"),
 	is_default("default"),
+	width("width", 0),
 	type("type")
 {
 	// set type here so it gets serialized
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index c326902ea4d92de40f792fda60435ed134714649..57d1be4497957449646c2c54252f30556f7edf68 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -191,6 +191,7 @@ class LLNotificationForm
 		Mandatory<std::string>	text;
 		Optional<std::string>	ignore;
 		Optional<bool>			is_default;
+		Optional<S32>			width;
 
 		Mandatory<std::string>	type;
 
diff --git a/indra/llui/llresmgr.cpp b/indra/llui/llresmgr.cpp
index 6e924c1f19f91125ba382bc06cf54d6dfd0dbc0f..d65c220974222928d444e967c863cea9d27b6357 100644
--- a/indra/llui/llresmgr.cpp
+++ b/indra/llui/llresmgr.cpp
@@ -295,9 +295,6 @@ const std::string LLLocale::SYSTEM_LOCALE("English_United States.1252");
 #elif LL_DARWIN
 const std::string LLLocale::USER_LOCALE("en_US.iso8859-1");// = LLStringUtil::null;
 const std::string LLLocale::SYSTEM_LOCALE("en_US.iso8859-1");
-#elif LL_SOLARIS
-const std::string LLLocale::USER_LOCALE("en_US.ISO8859-1");
-const std::string LLLocale::SYSTEM_LOCALE("C");
 #else // LL_LINUX likes this
 const std::string LLLocale::USER_LOCALE("en_US.utf8");
 const std::string LLLocale::SYSTEM_LOCALE("C");
diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index 8000efad0e2c31927092168f7c90e283707b66bf..13839da400e504f3e369d034cf916e9d6c163eec 100644
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
@@ -50,6 +50,10 @@ LLScrollListCell* LLScrollListCell::create(const LLScrollListCell::Params& cell_
 	{
 		cell = new LLScrollListDate(cell_p);
 	}
+	else if (cell_p.type() == "icontext")
+	{
+		cell = new LLScrollListIconText(cell_p);
+	}
 	else	// default is "text"
 	{
 		cell = new LLScrollListText(cell_p);
@@ -168,7 +172,7 @@ U32 LLScrollListText::sCount = 0;
 
 LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
 :	LLScrollListCell(p),
-	mText(p.value().asString()),
+	mText(p.label.isProvided() ? p.label() : p.value().asString()),
 	mFont(p.font),
 	mColor(p.color),
 	mUseColor(p.color.isProvided()),
@@ -192,7 +196,7 @@ LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
 void LLScrollListText::highlightText(S32 offset, S32 num_chars)
 {
 	mHighlightOffset = offset;
-	mHighlightCount = num_chars;
+	mHighlightCount = llmax(0, num_chars);
 }
 
 //virtual 
@@ -292,11 +296,12 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
 
 	if (mHighlightCount > 0)
 	{
+		// Highlight text
 		S32 left = 0;
 		switch(mFontAlignment)
 		{
 		case LLFontGL::LEFT:
-			left = mFont->getWidth(mText.getString(), 0, mHighlightOffset);
+			left = mFont->getWidth(mText.getString(), 1, mHighlightOffset);
 			break;
 		case LLFontGL::RIGHT:
 			left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX);
@@ -319,7 +324,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
 	switch(mFontAlignment)
 	{
 	case LLFontGL::LEFT:
-		start_x = 0.f;
+		start_x = 1.f;
 		break;
 	case LLFontGL::RIGHT:
 		start_x = (F32)getWidth();
@@ -435,3 +440,139 @@ const LLSD LLScrollListDate::getValue() const
 {
 	return mDate;
 }
+
+//
+// LLScrollListIconText
+//
+LLScrollListIconText::LLScrollListIconText(const LLScrollListCell::Params& p)
+    : LLScrollListText(p),
+    mIcon(p.value().isUUID() ? LLUI::getUIImageByID(p.value().asUUID()) : LLUI::getUIImage(p.value().asString())),
+    mPad(4)
+{
+    mTextWidth = getWidth() - mPad /*padding*/ - mFont->getLineHeight();
+}
+
+LLScrollListIconText::~LLScrollListIconText()
+{
+}
+
+const LLSD LLScrollListIconText::getValue() const
+{
+    if (mIcon.isNull())
+    {
+        return LLStringUtil::null;
+    }
+    return mIcon->getName();
+}
+
+void LLScrollListIconText::setValue(const LLSD& value)
+{
+    if (value.isUUID())
+    {
+        // don't use default image specified by LLUUID::null, use no image in that case
+        LLUUID image_id = value.asUUID();
+        mIcon = image_id.notNull() ? LLUI::getUIImageByID(image_id) : LLUIImagePtr(NULL);
+    }
+    else
+    {
+        std::string value_string = value.asString();
+        if (LLUUID::validate(value_string))
+        {
+            setValue(LLUUID(value_string));
+        }
+        else if (!value_string.empty())
+        {
+            mIcon = LLUI::getUIImage(value.asString());
+        }
+        else
+        {
+            mIcon = NULL;
+        }
+    }
+}
+
+void LLScrollListIconText::setWidth(S32 width)
+{
+    LLScrollListCell::setWidth(width);
+    // Assume that iamge height and width is identical to font height and width
+    mTextWidth = width - mPad /*padding*/ - mFont->getLineHeight();
+}
+
+
+void LLScrollListIconText::draw(const LLColor4& color, const LLColor4& highlight_color)	 const
+{
+    LLColor4 display_color;
+    if (mUseColor)
+    {
+        display_color = mColor;
+    }
+    else
+    {
+        display_color = color;
+    }
+
+    S32 icon_height = mFont->getLineHeight();
+    S32 icon_space = mIcon ? (icon_height + mPad) : 0;
+
+    if (mHighlightCount > 0)
+    {
+        S32 left = 0;
+        switch (mFontAlignment)
+        {
+        case LLFontGL::LEFT:
+            left = mFont->getWidth(mText.getString(), icon_space + 1, mHighlightOffset);
+            break;
+        case LLFontGL::RIGHT:
+            left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX) - icon_space;
+            break;
+        case LLFontGL::HCENTER:
+            left = (getWidth() - mFont->getWidth(mText.getString()) - icon_space) / 2;
+            break;
+        }
+        LLRect highlight_rect(left - 2,
+            mFont->getLineHeight() + 1,
+            left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1,
+            1);
+        mRoundedRectImage->draw(highlight_rect, highlight_color);
+    }
+
+    // Try to draw the entire string
+    F32 right_x;
+    U32 string_chars = mText.length();
+    F32 start_text_x = 0.f;
+    S32 start_icon_x = 0;
+    switch (mFontAlignment)
+    {
+    case LLFontGL::LEFT:
+        start_text_x = icon_space + 1;
+        start_icon_x = 1;
+        break;
+    case LLFontGL::RIGHT:
+        start_text_x = (F32)getWidth();
+        start_icon_x = getWidth() - mFont->getWidth(mText.getString()) - icon_space;
+        break;
+    case LLFontGL::HCENTER:
+        F32 center = (F32)getWidth()* 0.5f;
+        start_text_x = center + ((F32)icon_space * 0.5f);
+        start_icon_x = center - (((F32)icon_space + mFont->getWidth(mText.getString())) * 0.5f);
+        break;
+    }
+    mFont->render(mText.getWString(), 0,
+        start_text_x, 0.f,
+        display_color,
+        mFontAlignment,
+        LLFontGL::BOTTOM,
+        0,
+        LLFontGL::NO_SHADOW,
+        string_chars,
+        getTextWidth(),
+        &right_x,
+        TRUE);
+
+    if (mIcon)
+    {
+        mIcon->draw(start_icon_x, 0, icon_height, icon_height, mColor);
+    }
+}
+
+
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index d625ebddccacc025f33671fe40a765ac32c22b73..19576fb247adf131a06e44c6e34cb06dbf74f368 100644
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
@@ -59,7 +59,8 @@ class LLScrollListCell
 									visible;
 
 		Optional<void*>				userdata;
-		Optional<LLSD>				value;
+		Optional<LLSD>				value; // state of checkbox, icon id/name, date
+		Optional<std::string>		label; // description or text
 		Optional<std::string>		tool_tip;
 
 		Optional<const LLFontGL*>	font;
@@ -75,6 +76,7 @@ class LLScrollListCell
 			enabled("enabled", true),
 			visible("visible", true),
 			value("value"),
+			label("label"),
 			tool_tip("tool_tip", ""),
 			font("font", LLFontGL::getFontSansSerifSmall()),
 			font_color("font_color", LLColor4::black),
@@ -152,11 +154,12 @@ class LLScrollListText : public LLScrollListCell
 	void			setText(const LLStringExplicit& text);
 	void			setFontStyle(const U8 font_style);
 
-private:
+protected:
 	LLUIString		mText;
 	S32				mTextWidth;
 	const LLFontGL*	mFont;
 	LLColor4		mColor;
+	LLColor4		mHighlightColor;
 	U8				mUseColor;
 	LLFontGL::HAlign mFontAlignment;
 	BOOL			mVisible;
@@ -169,7 +172,7 @@ class LLScrollListText : public LLScrollListCell
 };
 
 /*
- * Cell displaying an image.
+ * Cell displaying an image. AT the moment, this is specifically UI image
  */
 class LLScrollListIcon : public LLScrollListCell
 {
@@ -223,4 +226,26 @@ class LLScrollListDate : public LLScrollListText
 	LLDate		mDate;
 };
 
+/*
+* Cell displaying icon and text.
+*/
+
+class LLScrollListIconText : public LLScrollListText
+{
+public:
+    LLScrollListIconText(const LLScrollListCell::Params& p);
+    /*virtual*/ ~LLScrollListIconText();
+    /*virtual*/ void	draw(const LLColor4& color, const LLColor4& highlight_color) const;
+    /*virtual*/ const LLSD		getValue() const;
+    /*virtual*/ void	setValue(const LLSD& value);
+
+
+    S32					getIconWidth() const;
+    /*virtual*/ void	setWidth(S32 width);/* { LLScrollListCell::setWidth(width); mTextWidth = width - ; }*/
+
+private:
+    LLPointer<LLUIImage>	mIcon;
+    S32						mPad;
+};
+
 #endif
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index a6e4f3a2af70baaa5b46d47937a864eeeaf094ea..be85f1cb6a1ec2fb8393d7e328415bd3e3445464 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -115,6 +115,13 @@ struct SortScrollListItem
 // LLScrollListCtrl
 //---------------------------------------------------------------------------
 
+void LLScrollListCtrl::SelectionTypeNames::declareValues()
+{
+    declare("row", LLScrollListCtrl::ROW);
+    declare("cell", LLScrollListCtrl::CELL);
+    declare("header", LLScrollListCtrl::HEADER);
+}
+
 LLScrollListCtrl::Contents::Contents()
 :	columns("column"),
 	rows("row")
@@ -128,8 +135,10 @@ LLScrollListCtrl::Params::Params()
 	has_border("draw_border"),
 	draw_heading("draw_heading"),
 	search_column("search_column", 0),
+	selection_type("selection_type", ROW),
 	sort_column("sort_column", -1),
 	sort_ascending("sort_ascending", true),
+	can_sort("can_sort", true),
 	mouse_wheel_opaque("mouse_wheel_opaque", false),
 	commit_on_keyboard_movement("commit_on_keyboard_movement", true),
 	commit_on_selection_change("commit_on_selection_change", false),
@@ -165,8 +174,10 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 	mCommitOnKeyboardMovement(p.commit_on_keyboard_movement),
 	mCommitOnSelectionChange(p.commit_on_selection_change),
 	mSelectionChanged(false),
+	mSelectionType(p.selection_type),
 	mNeedsScroll(false),
 	mCanSelect(true),
+	mCanSort(p.can_sort),
 	mColumnsDirty(false),
 	mMaxItemCount(INT_MAX), 
 	mBorderThickness( 2 ),
@@ -840,7 +851,15 @@ BOOL LLScrollListCtrl::selectFirstItem()
 		{
 			if (!itemp->getSelected())
 			{
-				selectItem(itemp);
+                switch (mSelectionType)
+                {
+                case CELL:
+                    selectItem(itemp, 0);
+                    break;
+                case HEADER:
+                case ROW:
+                    selectItem(itemp, -1);
+                }
 			}
 			success = TRUE;
 			mOriginalSelection = 0;
@@ -899,7 +918,8 @@ BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index )
 		{
 			if( itemp->getEnabled() )
 			{
-				selectItem(itemp, FALSE);
+				// TODO: support range selection for cells
+				selectItem(itemp, -1, FALSE);
 				success = TRUE;				
 			}
 		}
@@ -1025,10 +1045,14 @@ void LLScrollListCtrl::clearHighlightedItems()
 
 void LLScrollListCtrl::mouseOverHighlightNthItem(S32 target_index)
 {
-	if (mHighlightedItem != target_index)
-	{
-		mHighlightedItem = target_index;
-	}
+    if (mHighlightedItem != target_index)
+    {
+        if (mHighlightedItem >= 0 && mHighlightedItem < mItemList.size())
+        {
+            mItemList[mHighlightedItem]->setHoverCell(-1);
+        }
+        mHighlightedItem = target_index;
+    }
 }
 
 S32	LLScrollListCtrl::selectMultiple( uuid_vec_t ids )
@@ -1043,7 +1067,8 @@ S32	LLScrollListCtrl::selectMultiple( uuid_vec_t ids )
 		{
 			if (item->getEnabled() && (item->getUUID() == (*iditr)))
 			{
-				selectItem(item,FALSE);
+				// TODO: support multiple selection for cells
+				selectItem(item, -1, FALSE);
 				++count;
 				break;
 			}
@@ -1116,7 +1141,7 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection)
 			{
 				if (prev_item)
 				{
-					selectItem(prev_item, !extend_selection);
+					selectItem(prev_item, cur_item->getSelectedCell(), !extend_selection);
 				}
 				else
 				{
@@ -1160,7 +1185,7 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection)
 			{
 				if (next_item)
 				{
-					selectItem(next_item, !extend_selection);
+					selectItem(next_item, cur_item->getSelectedCell(), !extend_selection);
 				}
 				else
 				{
@@ -1231,7 +1256,7 @@ BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sen
 	bool found = NULL != item;
 	if(found)
 	{
-		selectItem(item);
+		selectItem(item, -1);
 	}
 
 	if (mCommitOnSelectionChange)
@@ -1299,7 +1324,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
 			BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE;
 			if (select)
 			{
-				selectItem(item);
+				selectItem(item, -1);
 				found = TRUE;
 				break;
 			}
@@ -1339,7 +1364,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
 				// find offset of matching text (might have leading whitespace)
 				S32 offset = item_label.find(target_trimmed);
 				cellp->highlightText(offset, target_trimmed.size());
-				selectItem(item);
+				selectItem(item, -1);
 				found = TRUE;
 				break;
 			}
@@ -1421,7 +1446,7 @@ BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected)
             {
                 if (selected)
                 {
-                    selectItem(item);
+                    selectItem(item, -1);
                 }
                 else
                 {
@@ -1501,7 +1526,7 @@ void LLScrollListCtrl::drawItems()
 		
 		S32 max_columns = 0;
 
-		LLColor4 highlight_color = LLColor4::white;
+		LLColor4 highlight_color = LLColor4::white; // ex: text inside cells
 		static LLUICachedControl<F32> type_ahead_timeout ("TypeAheadTimeout", 0);
 		highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout(), 0.4f, 0.f);
 
@@ -1527,7 +1552,8 @@ void LLScrollListCtrl::drawItems()
 			max_columns = llmax(max_columns, item->getNumColumns());
 
 			LLColor4 fg_color;
-			LLColor4 bg_color(LLColor4::transparent);
+			LLColor4 hover_color(LLColor4::transparent);
+			LLColor4 select_color(LLColor4::transparent);
 
 			if( mScrollLines <= line && line < mScrollLines + num_page_lines )
 			{
@@ -1536,44 +1562,44 @@ void LLScrollListCtrl::drawItems()
 				{
 					if(item->getHighlighted())	// if it's highlighted, average the colors
 					{
-						bg_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f);
+						select_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f);
 					}
 					else						// otherwise just select-highlight it
 					{
-						bg_color = mBgSelectedColor.get();
+						select_color = mBgSelectedColor.get();
 					}
 
 					fg_color = (item->getEnabled() ? mFgSelectedColor.get() : mFgDisabledColor.get());
 				}
-				else if (mHighlightedItem == line && mCanSelect)
+				if (mHighlightedItem == line && mCanSelect)
 				{
 					if(item->getHighlighted())	// if it's highlighted, average the colors
 					{
-						bg_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f);
+						hover_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f);
 					}
 					else						// otherwise just hover-highlight it
 					{
-						bg_color = mHoveredColor.get();
+						hover_color = mHoveredColor.get();
 					}
 				}
 				else if (item->getHighlighted())
 				{
-					bg_color = mHighlightedColor.get();
+					hover_color = mHighlightedColor.get();
 				}
 				else 
 				{
 					if (mDrawStripes && (line % 2 == 0) && (max_columns > 1))
 					{
-						bg_color = mBgStripeColor.get();
+						hover_color = mBgStripeColor.get();
 					}
 				}
 
 				if (!item->getEnabled())
 				{
-					bg_color = mBgReadOnlyColor.get();
+					hover_color = mBgReadOnlyColor.get();
 				}
 
-				item->draw(item_rect, fg_color % alpha, bg_color% alpha, highlight_color % alpha, mColumnPadding);
+				item->draw(item_rect, fg_color % alpha, hover_color% alpha, select_color% alpha, highlight_color % alpha, mColumnPadding);
 
 				cur_y -= mLineHeight;
 			}
@@ -1725,7 +1751,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
 			{
 				if (mLastSelected == NULL)
 				{
-					selectItem(hit_item);
+					selectItem(hit_item, getColumnIndexFromOffset(x));
 				}
 				else
 				{
@@ -1749,7 +1775,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
 						LLScrollListItem *item = *itor;
                         if (item == hit_item || item == lastSelected)
 						{
-							selectItem(item, FALSE);
+							selectItem(item, getColumnIndexFromOffset(x), FALSE);
 							selecting = !selecting;
 							if (hit_item == lastSelected)
 							{
@@ -1759,7 +1785,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
 						}
 						if (selecting)
 						{
-							selectItem(item, FALSE);
+							selectItem(item, getColumnIndexFromOffset(x), FALSE);
 						}
 					}
 				}
@@ -1774,7 +1800,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
 				{
 					if(!(mMaxSelectable > 0 && getAllSelected().size() >= mMaxSelectable))
 					{
-						selectItem(hit_item, FALSE);
+						selectItem(hit_item, getColumnIndexFromOffset(x), FALSE);
 					}
 					else
 					{
@@ -1788,12 +1814,12 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
 			else
 			{
 				deselectAllItems(TRUE);
-				selectItem(hit_item);
+				selectItem(hit_item, getColumnIndexFromOffset(x));
 			}
 		}
 		else
 		{
-			selectItem(hit_item);
+			selectItem(hit_item, getColumnIndexFromOffset(x));
 		}
 
 		selection_changed = mSelectionChanged;
@@ -2161,8 +2187,29 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask)
 	{
 		LLScrollListItem* item = hitItem(x, y);
 		if (item)
-		{
-			mouseOverHighlightNthItem(getItemIndex(item));
+        {
+            mouseOverHighlightNthItem(getItemIndex(item));
+            switch (mSelectionType)
+            {
+            case CELL:
+                item->setHoverCell(getColumnIndexFromOffset(x));
+                break;
+            case HEADER:
+                {
+                    S32 cell = getColumnIndexFromOffset(x);
+                    if (cell > 0)
+                    {
+                        item->setHoverCell(cell);
+                    }
+                    else
+                    {
+                        item->setHoverCell(-1);
+                    }
+                    break;
+                }
+            case ROW:
+                break;
+            }
 		}
 		else
 		{
@@ -2210,6 +2257,58 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
 					handled = TRUE;
 				}
 				break;
+            case KEY_LEFT:
+                if (mAllowKeyboardMovement || hasFocus())
+                {
+                    // TODO: support multi-select
+                    LLScrollListItem *item = getFirstSelected();
+                    if (item)
+                    {
+                        S32 cell = item->getSelectedCell();
+                        switch (mSelectionType)
+                        {
+                        case CELL:
+                            if (cell < mColumns.size()) cell++;
+                            break;
+                        case HEADER:
+                            if (cell == -1) cell = 1;
+                            else if (cell > 1 && cell < mColumns.size()) cell++; // skip header
+                            break;
+                        case ROW:
+                            cell = -1;
+                            break;
+                        }
+                        item->setSelectedCell(cell);
+                        handled = TRUE;
+                    }
+                }
+                break;
+            case KEY_RIGHT:
+                if (mAllowKeyboardMovement || hasFocus())
+                {
+                    // TODO: support multi-select
+                    LLScrollListItem *item = getFirstSelected();
+                    if (item)
+                    {
+                        S32 cell = item->getSelectedCell();
+                        switch (mSelectionType)
+                        {
+                        case CELL:
+                            if (cell >= 0) cell--;
+                            break;
+                        case HEADER:
+                            if (cell > 1) cell--;
+                            else if (cell == 1) cell = -1; // skip header
+                            break;
+                        case ROW:
+                            cell = -1;
+                            break;
+                        }
+                        item->setSelectedCell(cell);
+                        handled = TRUE;
+                    }
+                }
+                break;
 			case KEY_PAGE_UP:
 				if (mAllowKeyboardMovement || hasFocus())
 				{
@@ -2378,7 +2477,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
 				LLWString item_label = utf8str_to_wstring(cellp->getValue().asString());
 				if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char)
 				{
-					selectItem(item);
+					selectItem(item, -1);
 					mNeedsScroll = true;
 					cellp->highlightText(0, 1);
 					mSearchTimer.reset();
@@ -2430,7 +2529,7 @@ BOOL LLScrollListCtrl::isRepeatedChars(const LLWString& string) const
 	return TRUE;
 }
 
-void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_item)
+void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, S32 cell, BOOL select_single_item)
 {
 	if (!itemp) return;
 
@@ -2449,6 +2548,18 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it
 			deselectAllItems(TRUE);
 		}
 		itemp->setSelected(TRUE);
+        switch (mSelectionType)
+        {
+        case CELL:
+            itemp->setSelectedCell(cell);
+            break;
+        case HEADER:
+            itemp->setSelectedCell(cell <= 0 ? -1 : cell);
+            break;
+        case ROW:
+            itemp->setSelectedCell(-1);
+            break;
+        }
 		mLastSelected = itemp;
 		mSelectionChanged = true;
 	}
@@ -2709,7 +2820,7 @@ void	LLScrollListCtrl::selectAll()
 		LLScrollListItem *itemp = *iter;
 		if( itemp->getEnabled() )
 		{
-			selectItem(itemp, FALSE);
+			selectItem(itemp, -1, FALSE);
 		}
 	}
 
@@ -2838,6 +2949,8 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
 	LLScrollListCtrl *parent = info->mParentCtrl;
 	if (!parent) return;
 
+	if (!parent->mCanSort) return;
+
 	S32 column_index = info->mIndex;
 
 	LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex];
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 8d00296183e9f7ad957dda924ab61a2c426b41b5..0cc481b113be1a82081f9c5ac3042a56c6142e06 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -54,6 +54,18 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	public LLCtrlListInterface, public LLCtrlScrollInterface
 {
 public:
+    typedef enum e_selection_type
+    {
+        ROW, // default
+        CELL, // does not support multi-selection
+        HEADER, // when pointing to cells in column 0 will highlight whole row, otherwise cell, no multi-select
+    } ESelectionType;
+
+    struct SelectionTypeNames : public LLInitParam::TypeValuesHelper<LLScrollListCtrl::ESelectionType, SelectionTypeNames>
+    {
+        static void declareValues();
+    };
+
 	struct Contents : public LLInitParam::Block<Contents>
 	{
 		Multiple<LLScrollListColumn::Params>	columns;
@@ -100,6 +112,8 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 						commit_on_selection_change,
 						mouse_wheel_opaque;
 
+		Optional<ESelectionType, SelectionTypeNames> selection_type;
+
 		// display flags
 		Optional<bool>	has_border,
 						draw_heading,
@@ -116,7 +130,8 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 		// sort and search behavior
 		Optional<S32>	search_column,
 						sort_column;
-		Optional<bool>	sort_ascending;
+		Optional<bool>	sort_ascending,
+						can_sort; // whether user is allowed to sort
 
 		// colors
 		Optional<LLUIColor>	fg_unselected_color,
@@ -433,7 +448,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	void            updateLineHeightInsert(LLScrollListItem* item);
 	void			reportInvalidInput();
 	BOOL			isRepeatedChars(const LLWString& string) const;
-	void			selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE);
+	void			selectItem(LLScrollListItem* itemp, S32 cell, BOOL single_select = TRUE);
 	void			deselectItem(LLScrollListItem* itemp);
 	void			commitIfChanged();
 	BOOL			setSort(S32 column, BOOL ascending);
@@ -458,9 +473,11 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	bool			mCommitOnKeyboardMovement;
 	bool			mCommitOnSelectionChange;
 	bool			mSelectionChanged;
+	ESelectionType	mSelectionType;
 	bool			mNeedsScroll;
 	bool			mMouseWheelOpaque;
 	bool			mCanSelect;
+    bool			mCanSort;		// Whether user is allowed to sort
 	bool			mDisplayColumnHeaders;
 	bool			mColumnsDirty;
 	bool			mColumnWidthsDirty;
diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp
index df22c88afb428ec6c21348825a24ee19adff81df..51c615dd0037e23f0f5620ee07196c8470ce95f2 100644
--- a/indra/llui/llscrolllistitem.cpp
+++ b/indra/llui/llscrolllistitem.cpp
@@ -40,6 +40,8 @@
 LLScrollListItem::LLScrollListItem( const Params& p )
 :	mSelected(FALSE),
 	mHighlighted(FALSE),
+	mHoverIndex(-1),
+	mSelectedIndex(-1),
 	mEnabled(p.enabled),
 	mUserdata(p.userdata),
 	mItemValue(p.value)
@@ -53,6 +55,28 @@ LLScrollListItem::~LLScrollListItem()
 	mColumns.clear();
 }
 
+void LLScrollListItem::setSelected(BOOL b)
+{
+    mSelected = b;
+    mSelectedIndex = -1;
+}
+
+void LLScrollListItem::setHighlighted(BOOL b)
+{
+    mHighlighted = b;
+    mHoverIndex = -1;
+}
+
+void LLScrollListItem::setHoverCell(S32 cell)
+{
+    mHoverIndex = cell;
+}
+
+void LLScrollListItem::setSelectedCell(S32 cell)
+{
+    mSelectedIndex = cell;
+}
+
 void LLScrollListItem::addColumn(const LLScrollListCell::Params& p)
 {
 	mColumns.push_back(LLScrollListCell::create(p));
@@ -120,12 +144,21 @@ std::string LLScrollListItem::getContentsCSV() const
 }
 
 
-void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding)
+void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& hover_color, const LLColor4& select_color, const LLColor4& highlight_color, S32 column_padding)
 {
 	// draw background rect
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLRect bg_rect = rect;
-	gl_rect_2d( bg_rect, bg_color );
+    if (mSelectedIndex < 0 && getSelected())
+    {
+        // Whole item is highlighted/selected
+        gl_rect_2d(bg_rect, select_color);
+    }
+    else if (mHoverIndex < 0)
+    {
+        // Whole item is highlighted/selected
+        gl_rect_2d(bg_rect, hover_color);
+    }
 
 	S32 cur_x = rect.mLeft;
 	S32 num_cols = getNumColumns();
@@ -141,6 +174,25 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const
 		{
 			LLUI::translate((F32) cur_x, (F32) rect.mBottom);
 
+            if (mSelectedIndex == cur_col)
+            {
+                // select specific cell
+                LLRect highlight_rect(0,
+                    cell->getHeight(),
+                    cell->getWidth(),
+                    0);
+                gl_rect_2d(highlight_rect, select_color);
+            }
+            else if (mHoverIndex == cur_col)
+            {
+                // highlight specific cell
+                LLRect highlight_rect(0,
+                    cell->getHeight(),
+                    cell->getWidth() ,
+                    0);
+                gl_rect_2d(highlight_rect, hover_color);
+            }
+
 			cell->draw( fg_color, highlight_color );
 		}
 		LLUI::popMatrix();
diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h
index 13655b5873b9f5cf8e35938e6e0ea92442632f9b..d2c3dd7721b2c54fafd02b48cc0de7b9985f5e27 100644
--- a/indra/llui/llscrolllistitem.h
+++ b/indra/llui/llscrolllistitem.h
@@ -77,15 +77,21 @@ class LLScrollListItem
 
 	virtual ~LLScrollListItem();
 
-	void	setSelected( BOOL b )			{ mSelected = b; }
+	void	setSelected( BOOL b );
 	BOOL	getSelected() const				{ return mSelected; }
 
 	void	setEnabled( BOOL b )			{ mEnabled = b; }
 	BOOL	getEnabled() const 				{ return mEnabled; }
 
-	void	setHighlighted( BOOL b )		{ mHighlighted = b; }
+	void	setHighlighted( BOOL b );
 	BOOL	getHighlighted() const			{ return mHighlighted; }
 
+	void	setSelectedCell( S32 cell );
+	S32		getSelectedCell() const			{ return mSelectedIndex; }
+
+	void	setHoverCell( S32 cell );
+	S32		getHoverCell() const			{ return mHoverIndex; }
+
 	void	setUserdata( void* userdata )	{ mUserdata = userdata; }
 	void*	getUserdata() const 			{ return mUserdata; }
 
@@ -107,14 +113,21 @@ class LLScrollListItem
 
 	std::string getContentsCSV() const;
 
-	virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding);
+	virtual void draw(const LLRect& rect,
+					  const LLColor4& fg_color,
+					  const LLColor4& hover_color, // highlight/hover selection of whole item or cell
+					  const LLColor4& select_color, // highlight/hover selection of whole item or cell
+					  const LLColor4& highlight_color, // highlights contents of cells (ex: text)
+					  S32 column_padding);
 
 protected:
 	LLScrollListItem( const Params& );
 
 private:
 	BOOL	mSelected;
-	BOOL	mHighlighted;
+    BOOL	mHighlighted;
+    S32		mHoverIndex;
+	S32		mSelectedIndex;
 	BOOL	mEnabled;
 	void*	mUserdata;
 	LLSD	mItemValue;
diff --git a/indra/llui/llsearcheditor.cpp b/indra/llui/llsearcheditor.cpp
index 1fdd05a11cae67ccaeefeb50ab295a51d4b25071..bafeef41fb512172c0e5221774104589722d7d71 100644
--- a/indra/llui/llsearcheditor.cpp
+++ b/indra/llui/llsearcheditor.cpp
@@ -34,7 +34,11 @@
 LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
 :	LLUICtrl(p),
 	mSearchButton(NULL),
-	mClearButton(NULL)
+	mClearButton(NULL),
+	mEditorImage(p.background_image),
+	mEditorImageFocused(p.background_image_focused),
+	mEditorSearchImage(p.background_image_highlight),
+	mHighlightTextField(p.highlight_text_field)
 {
 	S32 srch_btn_top = p.search_button.top_pad + p.search_button.rect.height;
 	S32 srch_btn_right = p.search_button.rect.width + p.search_button.left_pad;
@@ -57,6 +61,8 @@ LLSearchEditor::LLSearchEditor(const LLSearchEditor::Params& p)
 	// Set up line editor.
 	LLLineEditor::Params line_editor_params(p);
 	line_editor_params.name("filter edit box");
+	line_editor_params.background_image(p.background_image);
+	line_editor_params.background_image_focused(p.background_image_focused);
 	line_editor_params.rect(getLocalRect());
 	line_editor_params.follows.flags(FOLLOWS_ALL);
 	line_editor_params.text_pad_left(text_pad_left);
@@ -104,6 +110,20 @@ void LLSearchEditor::draw()
 	if (mClearButton)
 		mClearButton->setVisible(!mSearchEditor->getWText().empty());
 
+	if (mHighlightTextField)
+	{	
+		if (!mSearchEditor->getWText().empty())
+		{
+			mSearchEditor->setBgImage(mEditorSearchImage);
+			mSearchEditor->setBgImageFocused(mEditorSearchImage);
+		}
+		else
+		{
+			mSearchEditor->setBgImage(mEditorImage);
+			mSearchEditor->setBgImageFocused(mEditorImageFocused);
+		}
+	}
+
 	LLUICtrl::draw();
 }
 
diff --git a/indra/llui/llsearcheditor.h b/indra/llui/llsearcheditor.h
index 3b128682256f624d78b07857dacd5a4b7f911bb9..c0f3c1d60cbb3edc9c0758a672cade3c8f3c35f8 100644
--- a/indra/llui/llsearcheditor.h
+++ b/indra/llui/llsearcheditor.h
@@ -47,14 +47,23 @@ class LLSearchEditor : public LLUICtrl
 		Optional<LLButton::Params>	search_button, 
 									clear_button;
 		Optional<bool>				search_button_visible, 
-									clear_button_visible;
+									clear_button_visible,
+									highlight_text_field;
 		Optional<commit_callback_t> keystroke_callback;
 
+		Optional<LLUIImage*>		background_image,
+									background_image_focused,
+									background_image_highlight;
+
 		Params()
 		:	search_button("search_button"),
 			search_button_visible("search_button_visible"),
 			clear_button("clear_button"), 
-			clear_button_visible("clear_button_visible")
+			clear_button_visible("clear_button_visible"),
+			highlight_text_field("highlight_text_field"),
+			background_image("background_image"),
+			background_image_focused("background_image_focused"),
+			background_image_highlight("background_image_highlight")
 		{}
 	};
 
@@ -93,6 +102,13 @@ class LLSearchEditor : public LLUICtrl
 	LLLineEditor* mSearchEditor;
 	LLButton* mSearchButton;
 	LLButton* mClearButton;
+
+	LLPointer<LLUIImage> mEditorImage;
+	LLPointer<LLUIImage> mEditorImageFocused;
+	LLPointer<LLUIImage> mEditorSearchImage;
+	LLPointer<LLUIImage> mEditorSearchImageFocused;
+
+	bool mHighlightTextField;
 };
 
 #endif  // LL_SEARCHEDITOR_H
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index e6b43da8e59a3a37a98663288cd098f9bbb174d7..459fdcf2aec61d0dd82630fc3159708641761641 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -38,6 +38,7 @@
 #include "llrender.h"
 #include "llfloater.h"
 #include "lltrans.h"
+#include "lluiusage.h"
 
 //----------------------------------------------------------------------------
 
@@ -1556,6 +1557,8 @@ BOOL LLTabContainer::setTab(S32 which)
 			
 			if (is_selected)
 			{
+				LLUIUsage::instance().logPanel(tuple->mTabPanel->getName());
+
 				// Make sure selected tab is within scroll region
 				if (mIsVertical)
 				{
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index ff724178679008495b321bcdf550ab6fa316a366..20bea7fe243df33586a94f872862111a0b7dd09d 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1179,7 +1179,7 @@ BOOL LLTextBase::handleToolTip(S32 x, S32 y, MASK mask)
 
 void LLTextBase::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	if (width != getRect().getWidth() || height != getRect().getHeight())
+	if (width != getRect().getWidth() || height != getRect().getHeight() || LLView::sForceReshape)
 	{
 		bool scrolled_to_bottom = mScroller ? mScroller->isAtBottom() : false;
 
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index 0afd32f33279bde6fbbe67ea9d2e21e39951eaec..134afc005b324baa1fb7a82143b0c2d581707c45 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -163,13 +163,13 @@ BOOL LLTextBox::setTextArg( const std::string& key, const LLStringExplicit& text
 }
 
 
-void LLTextBox::reshapeToFitText()
+void LLTextBox::reshapeToFitText(BOOL called_from_parent)
 {
 	reflow();
 
 	S32 width = getTextPixelWidth();
 	S32 height = getTextPixelHeight();
-	reshape( width + 2 * mHPad, height + 2 * mVPad, FALSE );
+	reshape( width + 2 * mHPad, height + 2 * mVPad, called_from_parent );
 }
 
 
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index 061d2dd23db285388d2b2584be123cf402f4f1e1..c3e3b619125dee01c70be3dff1cab5b43c13b336 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -60,7 +60,7 @@ class LLTextBox :
 	void			setHAlign( LLFontGL::HAlign align )		{ mHAlign = align; }
 	void			setClickedCallback( boost::function<void (void*)> cb, void* userdata = NULL );
 
-	void			reshapeToFitText();
+	void			reshapeToFitText(BOOL called_from_parent = FALSE);
 
 	S32				getTextPixelWidth();
 	S32				getTextPixelHeight();
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 47bfdae0a0e185ced43e5e2dcd3f9c0021e16763..94e5a338bdbaf2885aa34f16b21ac05678c6c88a 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -967,6 +967,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
 			executeStopParam.function_name = executeStopFunction;
 			executeStopParam.parameter = commandp->executeStopParameters();
 			LLUICtrl::commit_callback_t execute_func = initCommitCallback(executeParam);
+			button->setFunctionName(commandp->executeFunctionName());
+			LL_DEBUGS("UIUsage") << "button function name a -> " << commandp->executeFunctionName() << LL_ENDL;
 			LLUICtrl::commit_callback_t stop_func = initCommitCallback(executeStopParam);
 			
 			button->setMouseDownCallback(boost::bind(&LLToolBarButton::callIfEnabled, button, execute_func, _1, _2));
@@ -974,6 +976,8 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
 		}
 		else
 		{
+			button->setFunctionName(commandp->executeFunctionName());
+			LL_DEBUGS("UIUsage") << "button function name b -> " << commandp->executeFunctionName() << LL_ENDL;
 			button->setCommitCallback(executeParam);
 		}
 
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 544a76e8d583443a51d4898c8b07fa7dbc9fc05e..5924542a19e34f00fca1dcf90e7f29736f3fe873 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -35,6 +35,7 @@
 #include "lluictrlfactory.h"
 #include "lltabcontainer.h"
 #include "llaccordionctrltab.h"
+#include "lluiusage.h"
 
 static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl");
 
@@ -282,6 +283,7 @@ LLUICtrl::commit_signal_t::slot_type LLUICtrl::initCommitCallback(const CommitCa
 	else
 	{
 		std::string function_name = cb.function_name;
+		setFunctionName(function_name);
 		commit_callback_t* func = (CommitCallbackRegistry::getValue(function_name));
 		if (func)
 		{
@@ -422,7 +424,19 @@ BOOL LLUICtrl::canFocusChildren() const
 void LLUICtrl::onCommit()
 {
 	if (mCommitSignal)
-	(*mCommitSignal)(this, getValue());
+	{
+		if (!mFunctionName.empty())
+		{
+			LL_DEBUGS("UIUsage") << "calling commit function " << mFunctionName << LL_ENDL;
+			LLUIUsage::instance().logCommand(mFunctionName);
+			LLUIUsage::instance().logControl(getPathname());
+		}
+		else
+		{
+			//LL_DEBUGS("UIUsage") << "calling commit function " << "UNKNOWN" << LL_ENDL;
+		}
+		(*mCommitSignal)(this, getValue());
+	}
 }
 
 //virtual
@@ -597,6 +611,12 @@ void LLUICtrl::setMakeInvisibleControlVariable(LLControlVariable* control)
 		setVisible(!(mMakeInvisibleControlVariable->getValue().asBoolean()));
 	}
 }
+
+void LLUICtrl::setFunctionName(const std::string& function_name)
+{
+	mFunctionName = function_name;
+}
+
 // static
 bool LLUICtrl::controlListener(const LLSD& newvalue, LLHandle<LLUICtrl> handle, std::string type)
 {
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 7360bd76598799dc17e90fc46f2539c694ee8fe2..67dd24341cde6babcb0a7ff806b3ff881b7be2a8 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -183,6 +183,8 @@ class LLUICtrl
 	void setMakeVisibleControlVariable(LLControlVariable* control);
 	void setMakeInvisibleControlVariable(LLControlVariable* control);
 
+	void setFunctionName(const std::string& function_name);
+	
 	virtual void	setTentative(BOOL b);
 	virtual BOOL	getTentative() const;
 	virtual void	setValue(const LLSD& value);
@@ -310,6 +312,8 @@ class LLUICtrl
 	LLControlVariable* mMakeInvisibleControlVariable;
 	boost::signals2::connection mMakeInvisibleControlConnection;
 
+	std::string mFunctionName;
+
 	static F32 sActiveControlTransparency;
 	static F32 sInactiveControlTransparency;
 	
diff --git a/indra/llui/lluiusage.cpp b/indra/llui/lluiusage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ccae6643b916680b4cc8442275e420e861d900d7
--- /dev/null
+++ b/indra/llui/lluiusage.cpp
@@ -0,0 +1,146 @@
+/**
+* @file lluiuisage.cpp
+* @brief Source file for LLUIUsage
+*
+* $LicenseInfo:firstyear=2021&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2021, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#include "linden_common.h"
+#include "lluiusage.h"
+#include <boost/algorithm/string.hpp>
+
+LLUIUsage::LLUIUsage()
+{
+}
+
+LLUIUsage::~LLUIUsage()
+{
+}
+
+// static
+std::string LLUIUsage::sanitized(const std::string& s)
+{
+	// Remove characters that make the ViewerStats db unhappy
+	std::string result(s);
+	std::replace(result.begin(), result.end(), '.', '_');
+	std::replace(result.begin(), result.end(), ' ', '_');
+	return result;
+}
+
+// static
+void LLUIUsage::setLLSDPath(LLSD& sd, const std::string& path, S32 max_elts, const LLSD& val)
+{
+	// Keep the last max_elts components of the specified path
+	std::vector<std::string> fields;
+	boost::split(fields, path, boost::is_any_of("/"));
+	auto first_pos = std::max(fields.begin(), fields.end() - max_elts);
+	auto end_pos = fields.end();
+	std::vector<std::string> last_fields(first_pos,end_pos);
+
+	setLLSDNested(sd, last_fields, val);
+}
+
+// setLLSDNested()
+// Accomplish the equivalent of 
+//   sd[fields[0]][fields[1]]... = val;
+// for an arbitrary number of fields.
+// This might be useful as an LLSD utility function; is not specific to LLUIUsage
+// 
+// static
+void LLUIUsage::setLLSDNested(LLSD& sd, const std::vector<std::string>& fields, const LLSD& val)
+{
+	LLSD* fsd = &sd;
+	for (auto it=fields.begin(); it!=fields.end(); ++it)
+	{
+		if (it == fields.end()-1)
+		{
+			(*fsd)[*it] = val;
+		}
+		else
+		{
+			if (!(*fsd)[*it].isMap())
+			{
+				(*fsd)[*it] = LLSD::emptyMap();
+			}
+			fsd = &(*fsd)[*it];
+		}
+	}
+}
+
+void LLUIUsage::logCommand(const std::string& command)
+{
+	mCommandCounts[sanitized(command)]++;
+	LL_DEBUGS("UIUsage") << "command " << command << LL_ENDL;
+}
+
+void LLUIUsage::logControl(const std::string& control)
+{
+	mControlCounts[sanitized(control)]++;
+	LL_DEBUGS("UIUsage") << "control " << control << LL_ENDL;
+}
+
+
+void LLUIUsage::logFloater(const std::string& floater)
+{
+	mFloaterCounts[sanitized(floater)]++;
+	LL_DEBUGS("UIUsage") << "floater " << floater << LL_ENDL;
+}
+
+void LLUIUsage::logPanel(const std::string& p)
+{
+	mPanelCounts[sanitized(p)]++;
+	LL_DEBUGS("UIUsage") << "panel " << p << LL_ENDL;
+}
+
+LLSD LLUIUsage::asLLSD() const
+{
+	LLSD result;
+	for (auto const& it : mCommandCounts)
+	{
+		result["commands"][it.first] = LLSD::Integer(it.second);
+	}
+	for (auto const& it : mControlCounts)
+	{
+		setLLSDPath(result["controls"], it.first, 2, LLSD::Integer(it.second));
+	}
+	for (auto const& it : mFloaterCounts)
+	{
+		result["floaters"][it.first] = LLSD::Integer(it.second);
+	}
+	for (auto const& it : mPanelCounts)
+	{
+		result["panels"][it.first] = LLSD::Integer(it.second);
+	}
+	return result;
+}
+
+// Clear up some junk content generated during initial login/UI initialization
+void LLUIUsage::clear()
+{
+
+	LL_DEBUGS("UIUsage") << "clear" << LL_ENDL;
+	mCommandCounts.clear();
+	mControlCounts.clear();
+	mFloaterCounts.clear();
+	mPanelCounts.clear();
+}
+
diff --git a/indra/llui/lluiusage.h b/indra/llui/lluiusage.h
new file mode 100644
index 0000000000000000000000000000000000000000..a30cd80db34990962f470ed9bc10c28edc30fc4d
--- /dev/null
+++ b/indra/llui/lluiusage.h
@@ -0,0 +1,57 @@
+/**
+* @file lluiuisage.h
+* @brief Header file for LLUIUsage
+*
+* $LicenseInfo:firstyear=2021&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2021, Linden Research, Inc.
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+*
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+*
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_LLUIUSAGE_H
+#define LL_LLUIUSAGE_H
+
+#include <map>
+#include "llsd.h"
+#include "llsingleton.h"
+
+// UIUsage tracking to see which operations and UI elements are most popular in a session
+class LLUIUsage : public LLSingleton<LLUIUsage>
+{
+public:
+	LLSINGLETON(LLUIUsage);
+	~LLUIUsage();
+public:
+	static std::string sanitized(const std::string& s);
+	static void setLLSDPath(LLSD& sd, const std::string& path, S32 max_elts, const LLSD& val);
+	static void setLLSDNested(LLSD& sd, const std::vector<std::string>& fields, const LLSD& val);
+	void logCommand(const std::string& command);
+	void logControl(const std::string& control);
+	void logFloater(const std::string& floater);
+	void logPanel(const std::string& p);
+	LLSD asLLSD() const;
+	void clear();
+private:
+	std::map<std::string,U32> mCommandCounts;
+	std::map<std::string,U32> mControlCounts;
+	std::map<std::string,U32> mFloaterCounts;
+	std::map<std::string,U32> mPanelCounts;
+};
+
+#endif // LLUIUIUSAGE.h
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 3dbe550a21f48b5353ef792e25a0e7665a405938..cb65bac84c563384aff1543e49fb9e89d3fa709b 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -517,8 +517,7 @@ LLUrlEntrySimpleSecondlifeURL::LLUrlEntrySimpleSecondlifeURL()
 // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
 // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
 //
-LLUrlEntryAgent::LLUrlEntryAgent() :
-	mAvatarNameCacheConnection()
+LLUrlEntryAgent::LLUrlEntryAgent()
 {
 	mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/\\w+",
 							boost::regex::perl|boost::regex::icase);
@@ -549,7 +548,15 @@ void LLUrlEntryAgent::callObservers(const std::string &id,
 void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id,
 										const LLAvatarName& av_name)
 {
-	mAvatarNameCacheConnection.disconnect();
+	avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id);
+	if (it != mAvatarNameCacheConnections.end())
+	{
+		if (it->second.connected())
+		{
+			it->second.disconnect();
+		}
+		mAvatarNameCacheConnections.erase(it);
+	}
 	
  	std::string label = av_name.getCompleteName();
 
@@ -636,11 +643,17 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
 	}
 	else
 	{
-		if (mAvatarNameCacheConnection.connected())
+		avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id);
+		if (it != mAvatarNameCacheConnections.end())
 		{
-			mAvatarNameCacheConnection.disconnect();
+			if (it->second.connected())
+			{
+				it->second.disconnect();
+			}
+			mAvatarNameCacheConnections.erase(it);
 		}
-		mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2));
+		mAvatarNameCacheConnections[agent_id] = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2));
+
 		addObserver(agent_id_string, url, cb);
 		return LLTrans::getString("LoadingData");
 	}
@@ -701,14 +714,21 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url)
 // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
 // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
 //
-LLUrlEntryAgentName::LLUrlEntryAgentName() :
-	mAvatarNameCacheConnection()
+LLUrlEntryAgentName::LLUrlEntryAgentName()
 {}
 
 void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id,
 										const LLAvatarName& av_name)
 {
-	mAvatarNameCacheConnection.disconnect();
+	avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(id);
+	if (it != mAvatarNameCacheConnections.end())
+	{
+		if (it->second.connected())
+		{
+			it->second.disconnect();
+		}
+		mAvatarNameCacheConnections.erase(it);
+	}
 
 	std::string label = getName(av_name);
 	// received the agent name from the server - tell our observers
@@ -743,11 +763,17 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab
 	}
 	else
 	{
-		if (mAvatarNameCacheConnection.connected())
+		avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.find(agent_id);
+		if (it != mAvatarNameCacheConnections.end())
 		{
-			mAvatarNameCacheConnection.disconnect();
+			if (it->second.connected())
+			{
+				it->second.disconnect();
+			}
+			mAvatarNameCacheConnections.erase(it);
 		}
-		mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2));
+		mAvatarNameCacheConnections[agent_id] = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2));
+
 		addObserver(agent_id_string, url, cb);
 		return LLTrans::getString("LoadingData");
 	}
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 2cfaf8904b499a8b7685b9e5d6cbad3f497da1d5..84575acbc4f02dbd6569dd646c1e03f7d35023cd 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -212,10 +212,14 @@ class LLUrlEntryAgent : public LLUrlEntryBase
 	LLUrlEntryAgent();
 	~LLUrlEntryAgent()
 	{
-		if (mAvatarNameCacheConnection.connected())
+		for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it)
 		{
-			mAvatarNameCacheConnection.disconnect();
+			if (it->second.connected())
+			{
+				it->second.disconnect();
+			}
 		}
+		mAvatarNameCacheConnections.clear();
 	}
 	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
 	/*virtual*/ std::string getIcon(const std::string &url);
@@ -227,7 +231,9 @@ class LLUrlEntryAgent : public LLUrlEntryBase
 	/*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon);
 private:
 	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
-	boost::signals2::connection mAvatarNameCacheConnection;
+
+	typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
+	avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
 };
 
 ///
@@ -241,10 +247,14 @@ class LLUrlEntryAgentName : public LLUrlEntryBase, public boost::signals2::track
 	LLUrlEntryAgentName();
 	~LLUrlEntryAgentName()
 	{
-		if (mAvatarNameCacheConnection.connected())
+		for (avatar_name_cache_connection_map_t::iterator it = mAvatarNameCacheConnections.begin(); it != mAvatarNameCacheConnections.end(); ++it)
 		{
-			mAvatarNameCacheConnection.disconnect();
+			if (it->second.connected())
+			{
+				it->second.disconnect();
+			}
 		}
+		mAvatarNameCacheConnections.clear();
 	}
 	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
 	/*virtual*/ LLStyle::Params getStyle() const;
@@ -253,7 +263,9 @@ class LLUrlEntryAgentName : public LLUrlEntryBase, public boost::signals2::track
 	virtual std::string getName(const LLAvatarName& avatar_name) = 0;
 private:
 	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
-	boost::signals2::connection mAvatarNameCacheConnection;
+
+	typedef std::map<LLUUID, boost::signals2::connection> avatar_name_cache_connection_map_t;
+	avatar_name_cache_connection_map_t mAvatarNameCacheConnections;
 };
 
 
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index e3a6a98a9f80749068745906ec58e169e64b4961..cd47e2eceaa299967a50f90149f47fae07879436 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1402,7 +1402,9 @@ void LLView::reshape(S32 width, S32 height, BOOL called_from_parent)
 			S32 delta_x = child_rect.mLeft - viewp->getRect().mLeft;
 			S32 delta_y = child_rect.mBottom - viewp->getRect().mBottom;
 			viewp->translate( delta_x, delta_y );
-			if (child_rect.getWidth() != viewp->getRect().getWidth() || child_rect.getHeight() != viewp->getRect().getHeight())
+			if (child_rect.getWidth() != viewp->getRect().getWidth()
+                || child_rect.getHeight() != viewp->getRect().getHeight()
+                || sForceReshape)
 			{
 				viewp->reshape(child_rect.getWidth(), child_rect.getHeight());
 			}
diff --git a/indra/llui/llvirtualtrackball.cpp b/indra/llui/llvirtualtrackball.cpp
index 723643dd251e9213bdfa2991440f9c01e17b8e9d..6e0aef740d5a06d40f7018e34e43c720c4043256 100644
--- a/indra/llui/llvirtualtrackball.cpp
+++ b/indra/llui/llvirtualtrackball.cpp
@@ -348,6 +348,42 @@ LLQuaternion LLVirtualTrackball::getRotation() const
 	return mValue;
 }
 
+// static
+void LLVirtualTrackball::getAzimuthAndElevation(const LLQuaternion &quat, F32 &azimuth, F32 &elevation)
+{
+    // LLQuaternion has own function to get azimuth, but it doesn't appear to return correct values (meant for 2d?)
+    LLVector3 point = VectorZero * quat;
+
+    if (!is_approx_zero(point.mV[VX]) || !is_approx_zero(point.mV[VY]))
+    {
+        azimuth = atan2f(point.mV[VX], point.mV[VY]);
+    }
+    else
+    {
+        azimuth = 0;
+    }
+
+    azimuth -= F_PI_BY_TWO;
+
+    if (azimuth < 0)
+    {
+        azimuth += F_PI * 2;
+    }
+
+    // while vector is '1', F32 is not sufficiently precise and we can get
+    // values like 1.0000012 which will result in -90deg angle instead of 90deg
+    F32 z = llclamp(point.mV[VZ], -1.f, 1.f);
+    elevation = asin(z); // because VectorZero's length is '1'
+}
+
+// static
+void LLVirtualTrackball::getAzimuthAndElevationDeg(const LLQuaternion &quat, F32 &azimuth, F32 &elevation)
+{
+    getAzimuthAndElevation(quat, azimuth, elevation);
+    azimuth *= RAD_TO_DEG;
+    elevation *= RAD_TO_DEG;
+}
+
 BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask)
 {
     if (hasMouseCapture())
@@ -409,6 +445,10 @@ BOOL LLVirtualTrackball::handleHover(S32 x, S32 y, MASK mask)
             mValue *= az_quat;
         }
 
+        // we are doing a lot of F32 mathematical operations with loss of precision,
+        // re-normalize to compensate
+        mValue.normalize();
+
         mPrevX = x;
         mPrevY = y;
         onCommit();
diff --git a/indra/llui/llvirtualtrackball.h b/indra/llui/llvirtualtrackball.h
index 2d4b1ece17623018bbe5b1bcaf46831351e93659..c7a893877b9c032cc113f58b42f912613b824141 100644
--- a/indra/llui/llvirtualtrackball.h
+++ b/indra/llui/llvirtualtrackball.h
@@ -96,6 +96,9 @@ class LLVirtualTrackball
     void            setRotation(const LLQuaternion &value);
     LLQuaternion    getRotation() const;
 
+    static void             getAzimuthAndElevation(const LLQuaternion &quat, F32 &azimuth, F32 &elevation);
+    static void             getAzimuthAndElevationDeg(const LLQuaternion &quat, F32 &azimuth, F32 &elevation);
+
 protected:
     friend class LLUICtrlFactory;
     LLVirtualTrackball(const Params&);
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 10fbc06c61cbe96fecfd5ca486e543db6eb2da9d..9e9abbadff8f31b4c94102cce7e4affd030a481a 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -61,9 +61,6 @@ LLDir_Win32 gDirUtil;
 #elif LL_DARWIN
 #include "lldir_mac.h"
 LLDir_Mac gDirUtil;
-#elif LL_SOLARIS
-#include "lldir_solaris.h"
-LLDir_Solaris gDirUtil;
 #else
 #include "lldir_linux.h"
 LLDir_Linux gDirUtil;
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 38e204ef04729a9657a74f45a8540ae4a3083ce0..4988b9c6e39d1b817c9cc91d3b14e11b0c491c05 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -27,11 +27,6 @@
 #ifndef LL_LLDIR_H
 #define LL_LLDIR_H
 
-#if LL_SOLARIS
-#include <sys/param.h>
-#define MAX_PATH MAXPATHLEN
-#endif
-
 // these numbers are read from settings_files.xml, so we need to be explicit
 typedef enum ELLPath
 {
diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp
deleted file mode 100644
index f18560ff20256f6c9dcd1b4d2c24cf6811beff83..0000000000000000000000000000000000000000
--- a/indra/llvfs/lldir_solaris.cpp
+++ /dev/null
@@ -1,266 +0,0 @@
-/** 
- * @file fmodwrapper.cpp
- * @brief dummy source file for building a shared library to wrap libfmod.a
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-
-#include "lldir_solaris.h"
-#include "llerror.h"
-#include "llrand.h"
-#include "llstring.h"
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <glob.h>
-#include <pwd.h>
-#include <sys/utsname.h>
-#define _STRUCTURED_PROC 1
-#include <sys/procfs.h>
-#include <fcntl.h>
-
-static std::string getCurrentUserHome(char* fallback)
-{
-	// fwiw this exactly duplicates getCurrentUserHome() in lldir_linux.cpp...
-	// we should either derive both from LLDir_Posix or just axe Solaris.
-	const uid_t uid = getuid();
-	struct passwd *pw;
-
-	pw = getpwuid(uid);
-	if ((pw != NULL) && (pw->pw_dir != NULL))
-	{
-		return pw->pw_dir;
-	}
-
-	LL_INFOS() << "Couldn't detect home directory from passwd - trying $HOME" << LL_ENDL;
-	auto home_env = LLStringUtil::getoptenv("HOME");
-	if (home_env)
-	{
-		return *home_env;
-	}
-	else
-	{
-		LL_WARNS() << "Couldn't detect home directory!  Falling back to " << fallback << LL_ENDL;
-		return fallback;
-	}
-}
-
-
-LLDir_Solaris::LLDir_Solaris()
-{
-	mDirDelimiter = "/";
-	mCurrentDirIndex = -1;
-	mCurrentDirCount = -1;
-	mDirp = NULL;
-
-	char tmp_str[LL_MAX_PATH];	/* Flawfinder: ignore */ 
-	if (getcwd(tmp_str, LL_MAX_PATH) == NULL)
-	{
-		strcpy(tmp_str, "/tmp");
-		LL_WARNS() << "Could not get current directory; changing to "
-				<< tmp_str << LL_ENDL;
-		if (chdir(tmp_str) == -1)
-		{
-			LL_ERRS() << "Could not change directory to " << tmp_str << LL_ENDL;
-		}
-	}
-
-	mExecutableFilename = "";
-	mExecutablePathAndName = "";
-	mExecutableDir = strdup(tmp_str);
-	mWorkingDir = strdup(tmp_str);
-	mAppRODataDir = strdup(tmp_str);
-	mOSUserDir = getCurrentUserHome(tmp_str);
-	mOSUserAppDir = "";
-	mLindenUserDir = "";
-
-	char path [LL_MAX_PATH];	/* Flawfinder: ignore */ 
-
-	sprintf(path, "/proc/%d/psinfo", (int)getpid());
-	int proc_fd = -1;
-	if((proc_fd = open(path, O_RDONLY)) == -1){
-		LL_WARNS() << "unable to open " << path << LL_ENDL;
-		return;
-	}
-	psinfo_t proc_psinfo;
-	if(read(proc_fd, &proc_psinfo, sizeof(psinfo_t)) != sizeof(psinfo_t)){
-		LL_WARNS() << "Unable to read " << path << LL_ENDL;
-		close(proc_fd);
-		return;
-	}
-
-	close(proc_fd);
-
-	mExecutableFilename = strdup(proc_psinfo.pr_fname);
-	LL_INFOS() << "mExecutableFilename = [" << mExecutableFilename << "]" << LL_ENDL;
-
-	sprintf(path, "/proc/%d/path/a.out", (int)getpid());
-
-	char execpath[LL_MAX_PATH];
-	if(readlink(path, execpath, LL_MAX_PATH) == -1){
-		LL_WARNS() << "Unable to read link from " << path << LL_ENDL;
-		return;
-	}
-
-	char *p = execpath;			// nuke trash in link, if any exists
-	int i = 0;
-	while(*p != NULL && ++i < LL_MAX_PATH && isprint((int)(*p++)));
-	*p = NULL;
-
-	mExecutablePathAndName = strdup(execpath);
-	LL_INFOS() << "mExecutablePathAndName = [" << mExecutablePathAndName << "]" << LL_ENDL;
-
-	//NOTE: Why force people to cd into the package directory?
-	//      Look for SECONDLIFE env variable and use it, if set.
-
-	auto SECONDLIFE(LLDirUtil::getoptenv("SECONDLIFE"));
-	if(SECONDLIFE){
-		mExecutableDir = add(*SECONDLIFE, "bin"); //NOTE:  make sure we point at the bin
-	}else{
-		mExecutableDir = getDirName(execpath);
-		LL_INFOS() << "mExecutableDir = [" << mExecutableDir << "]" << LL_ENDL;
-	}
-
-	mLLPluginDir = add(mExecutableDir, "llplugin");
-
-	// *TODO: don't use /tmp, use $HOME/.secondlife/tmp or something.
-	mTempDir = "/tmp";
-}
-
-LLDir_Solaris::~LLDir_Solaris()
-{
-}
-
-// Implementation
-
-
-void LLDir_Solaris::initAppDirs(const std::string &app_name,
-								const std::string& app_read_only_data_dir)
-{
-	// Allow override so test apps can read newview directory
-	if (!app_read_only_data_dir.empty())
-	{
-		mAppRODataDir = app_read_only_data_dir;
-		mSkinBaseDir = add(mAppRODataDir, "skins");
-	}
-	mAppName = app_name;
-
-	std::string upper_app_name(app_name);
-	LLStringUtil::toUpper(upper_app_name);
-
-	auto app_home_env(LLStringUtil::getoptenv(upper_app_name + "_USER_DIR"));
-	if (app_home_env)
-	{
-		// user has specified own userappdir i.e. $SECONDLIFE_USER_DIR
-		mOSUserAppDir = *app_home_env;
-	}
-	else
-	{
-		// traditionally on unixoids, MyApp gets ~/.myapp dir for data
-		mOSUserAppDir = mOSUserDir;
-		mOSUserAppDir += "/";
-		mOSUserAppDir += ".";
-		std::string lower_app_name(app_name);
-		LLStringUtil::toLower(lower_app_name);
-		mOSUserAppDir += lower_app_name;
-	}
-
-	// create any directories we expect to write to.
-
-	int res = LLFile::mkdir(mOSUserAppDir);
-	if (res == -1)
-	{
-		LL_WARNS() << "Couldn't create app user dir " << mOSUserAppDir << LL_ENDL;
-		LL_WARNS() << "Default to base dir" << mOSUserDir << LL_ENDL;
-		mOSUserAppDir = mOSUserDir;
-	}
-
-	res = LLFile::mkdir(getExpandedFilename(LL_PATH_LOGS,""));
-	if (res == -1)
-	{
-		LL_WARNS() << "Couldn't create LL_PATH_LOGS dir " << getExpandedFilename(LL_PATH_LOGS,"") << LL_ENDL;
-	}
-	
-	res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SETTINGS,""));
-	if (res == -1)
-	{
-		LL_WARNS() << "Couldn't create LL_PATH_USER_SETTINGS dir " << getExpandedFilename(LL_PATH_USER_SETTINGS,"") << LL_ENDL;
-	}
-
-	res = LLFile::mkdir(getExpandedFilename(LL_PATH_CACHE,""));
-	if (res == -1)
-	{
-		LL_WARNS() << "Couldn't create LL_PATH_CACHE dir " << getExpandedFilename(LL_PATH_CACHE,"") << LL_ENDL;
-	}
-
-	mCAFile = getExpandedFilename(LL_PATH_EXECUTABLE, "ca-bundle.crt");
-}
-
-U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string &mask)
-{
-	U32 file_count = 0;
-	glob_t g;
-
-	std::string tmp_str;
-	tmp_str = dirname;
-	tmp_str += mask;
-	
-	if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
-	{
-		file_count = g.gl_pathc;
-
-		globfree(&g);
-	}
-
-	return (file_count);
-}
-
-std::string LLDir_Solaris::getCurPath()
-{
-	char tmp_str[LL_MAX_PATH];	/* Flawfinder: ignore */ 
-	if (getcwd(tmp_str, LL_MAX_PATH) == NULL)
-	{
-		LL_WARNS() << "Could not get current directory" << LL_ENDL;
-		tmp_str[0] = '\0';
-	}
-	return tmp_str;
-}
-
-
-bool LLDir_Solaris::fileExists(const std::string &filename) const
-{
-	struct stat stat_data;
-	// Check the age of the file
-	// Now, we see if the files we've gathered are recent...
-	int res = stat(filename.c_str(), &stat_data);
-	if (!res)
-	{
-		return TRUE;
-	}
-	else
-	{
-		return FALSE;
-	}
-}
-
diff --git a/indra/llvfs/lldir_solaris.h b/indra/llvfs/lldir_solaris.h
deleted file mode 100644
index c6dac57e1445795c6da708360e65f3ef46181da8..0000000000000000000000000000000000000000
--- a/indra/llvfs/lldir_solaris.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/** 
- * @file fmodwrapper.cpp
- * @brief dummy source file for building a shared library to wrap libfmod.a
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#if !LL_SOLARIS
-#error This header must not be included when compiling for any target other than Solaris. Consider including lldir.h instead.
-#endif // !LL_SOLARIS
-
-#ifndef LL_LLDIR_SOLARIS_H
-#define LL_LLDIR_SOLARIS_H
-
-#include "lldir.h"
-
-#include <dirent.h>
-#include <errno.h>
-
-class LLDir_Solaris : public LLDir
-{
-public:
-	LLDir_Solaris();
-	virtual ~LLDir_Solaris();
-
-	/*virtual*/ void initAppDirs(const std::string &app_name,
-		const std::string& app_read_only_data_dir);
-
-	virtual std::string getCurPath();
-	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
-	/*virtual*/ bool fileExists(const std::string &filename) const;
-
-private:
-	DIR *mDirp;
-	int mCurrentDirIndex;
-	int mCurrentDirCount;
-	std::string mCurrentDir;
-};
-
-#endif // LL_LLDIR_SOLARIS_H
-
-
diff --git a/indra/llvfs/llvfs.cpp b/indra/llvfs/llvfs.cpp
index 617056d94d224eeea3d89b26b45063fe469811e4..2c64bf563eff395e27f7e344a424b1c0d93dff4e 100644
--- a/indra/llvfs/llvfs.cpp
+++ b/indra/llvfs/llvfs.cpp
@@ -33,10 +33,6 @@
 #include <map>
 #if LL_WINDOWS
 #include <share.h>
-#elif LL_SOLARIS
-#include <sys/types.h>
-#include <unistd.h>
-#include <fcntl.h>
 #else
 #include <sys/file.h>
 #endif
@@ -2146,12 +2142,6 @@ LLFILE *LLVFS::openAndLock(const std::string& filename, const char* mode, BOOL r
 	int fd;
 	
 	// first test the lock in a non-destructive way
-#if LL_SOLARIS
-        struct flock fl;
-        fl.l_whence = SEEK_SET;
-        fl.l_start = 0;
-        fl.l_len = 1;
-#else // !LL_SOLARIS
 	if (strchr(mode, 'w') != NULL)
 	{
 		fp = LLFile::fopen(filename, "rb");	/* Flawfinder: ignore */
@@ -2167,19 +2157,13 @@ LLFILE *LLVFS::openAndLock(const std::string& filename, const char* mode, BOOL r
 			fclose(fp);
 		}
 	}
-#endif // !LL_SOLARIS
 
 	// now actually open the file for use
 	fp = LLFile::fopen(filename, mode);	/* Flawfinder: ignore */
 	if (fp)
 	{
 		fd = fileno(fp);
-#if LL_SOLARIS
-                fl.l_type = read_lock ? F_RDLCK : F_WRLCK;
-                if (fcntl(fd, F_SETLK, &fl) == -1)
-#else
 		if (flock(fd, (read_lock ? LOCK_SH : LOCK_EX) | LOCK_NB) == -1)
-#endif
 		{
 			fclose(fp);
 			fp = NULL;
@@ -2207,14 +2191,6 @@ void LLVFS::unlockAndClose(LLFILE *fp)
 	  flock(fd, LOCK_UN);
 	  #endif
     */
-#if LL_SOLARIS
-	        struct flock fl;
-		fl.l_whence = SEEK_SET;
-		fl.l_start = 0;
-		fl.l_len = 1;
-		fl.l_type = F_UNLCK;
-		fcntl(fileno(fp), F_SETLK, &fl);
-#endif
 		fclose(fp);
 	}
 }
diff --git a/indra/llwindow/llkeyboard.cpp b/indra/llwindow/llkeyboard.cpp
index f6f6c3931cb16073b2c43ffb1fa9773fa2cbd404..5404ac50e5c5baefe53ec7e2f65bf6b5d0604388 100644
--- a/indra/llwindow/llkeyboard.cpp
+++ b/indra/llwindow/llkeyboard.cpp
@@ -327,7 +327,7 @@ BOOL LLKeyboard::keyFromString(const std::string& str, KEY *key)
 
 
 // static
-std::string LLKeyboard::stringFromKey(KEY key)
+std::string LLKeyboard::stringFromKey(KEY key, bool translate)
 {
 	std::string res = get_if_there(sKeysToNames, key, std::string());
 	if (res.empty())
@@ -338,16 +338,60 @@ std::string LLKeyboard::stringFromKey(KEY key)
 		res = std::string(buffer);
 	}
 
-	LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator;
-	if (trans != NULL)
+	if (translate)
 	{
-		res = trans(res.c_str());
+		LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator;
+		if (trans != NULL)
+		{
+			res = trans(res.c_str());
+		}
 	}
 
 	return res;
 }
 
+//static
+std::string LLKeyboard::stringFromAccelerator(MASK accel_mask)
+{
+    std::string res;
+
+    LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator;
+
+    if (trans == NULL)
+    {
+        LL_ERRS() << "No mKeyStringTranslator" << LL_ENDL;
+        return res;
+    }
 
+    // Append any masks
+#ifdef LL_DARWIN
+    // Standard Mac names for modifier keys in menu equivalents
+    // We could use the symbol characters, but they only exist in certain fonts.
+    if (accel_mask & MASK_CONTROL)
+    {
+        if (accel_mask & MASK_MAC_CONTROL)
+        {
+            res.append(trans("accel-mac-control"));
+        }
+        else
+        {
+            res.append(trans("accel-mac-command"));		// Symbol would be "\xE2\x8C\x98"
+        }
+    }
+    if (accel_mask & MASK_ALT)
+        res.append(trans("accel-mac-option"));		// Symbol would be "\xE2\x8C\xA5"
+    if (accel_mask & MASK_SHIFT)
+        res.append(trans("accel-mac-shift"));		// Symbol would be "\xE2\x8C\xA7"
+#else
+    if (accel_mask & MASK_CONTROL)
+        res.append(trans("accel-win-control"));
+    if (accel_mask & MASK_ALT)
+        res.append(trans("accel-win-alt"));
+    if (accel_mask & MASK_SHIFT)
+        res.append(trans("accel-win-shift"));
+#endif
+    return res;
+}
 //static
 std::string LLKeyboard::stringFromAccelerator( MASK accel_mask, KEY key )
 {
@@ -359,41 +403,7 @@ std::string LLKeyboard::stringFromAccelerator( MASK accel_mask, KEY key )
 		return res;
 	}
 	
-	LLKeyStringTranslatorFunc *trans = gKeyboard->mStringTranslator;
-	
-	if( trans == NULL )
-	{
-		LL_ERRS() << "No mKeyStringTranslator" << LL_ENDL;
-		return res;
-	}
-	
-	// Append any masks
-#ifdef LL_DARWIN
-	// Standard Mac names for modifier keys in menu equivalents
-	// We could use the symbol characters, but they only exist in certain fonts.
-	if( accel_mask & MASK_CONTROL )
-	{
-		if ( accel_mask & MASK_MAC_CONTROL )
-		{
-			res.append( trans("accel-mac-control") );
-		}
-		else
-		{
-			res.append( trans("accel-mac-command") );		// Symbol would be "\xE2\x8C\x98"
-		}
-	}
-	if( accel_mask & MASK_ALT )
-		res.append( trans("accel-mac-option") );		// Symbol would be "\xE2\x8C\xA5"
-	if( accel_mask & MASK_SHIFT )
-		res.append( trans("accel-mac-shift") );		// Symbol would be "\xE2\x8C\xA7"
-#else
-	if( accel_mask & MASK_CONTROL )
-		res.append( trans("accel-win-control") );
-	if( accel_mask & MASK_ALT )
-		res.append( trans("accel-win-alt") );
-	if( accel_mask & MASK_SHIFT )
-		res.append( trans("accel-win-shift") );
-#endif
+	res.append(stringFromAccelerator(accel_mask));
 	std::string key_string = LLKeyboard::stringFromKey(key);
 	if ((accel_mask & MASK_NORMALKEYS) &&
 		(key_string[0] == '-' || key_string[0] == '=' || key_string[0] == '+'))
diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index 6f2dc87317a0ed62768475182883efd347b0c625..36bd8bcbed54784c4721f793f8e05dc19aeb2313 100644
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -38,10 +38,10 @@ enum EKeystate
 {
 	KEYSTATE_DOWN,
 	KEYSTATE_LEVEL,
-	KEYSTATE_UP 
+	KEYSTATE_UP
 };
 
-typedef boost::function<void(EKeystate keystate)> LLKeyFunc;
+typedef boost::function<bool(EKeystate keystate)> LLKeyFunc;
 typedef std::string (LLKeyStringTranslatorFunc)(const char *label);
 	
 enum EKeyboardInsertMode
@@ -50,15 +50,6 @@ enum EKeyboardInsertMode
 	LL_KIM_OVERWRITE
 };
 
-class LLKeyBinding
-{
-public:
-	KEY				mKey;
-	MASK			mMask;
-// 	const char		*mName; // unused
-	LLKeyFunc		mFunction;
-};
-
 class LLWindowCallbacks;
 
 class LLKeyboard
@@ -103,7 +94,8 @@ class LLKeyboard
 
 	static BOOL		maskFromString(const std::string& str, MASK *mask);		// False on failure
 	static BOOL		keyFromString(const std::string& str, KEY *key);			// False on failure
-	static std::string stringFromKey(KEY key);
+	static std::string stringFromKey(KEY key, bool translate = true);
+	static std::string stringFromAccelerator( MASK accel_mask ); // separated for convinience, returns with "+": "Shift+" or "Shift+Alt+"...
 	static std::string stringFromAccelerator( MASK accel_mask, KEY key );
 
 	void setCallbacks(LLWindowCallbacks *cbs) { mCallbacks = cbs; }
diff --git a/indra/llwindow/llmousehandler.cpp b/indra/llwindow/llmousehandler.cpp
index d5fa65fe4b09a58b92ce8a37ed2be61c2f8b2de0..e41ebd42f352ea11dc0b7022c1715ffc4112b86d 100644
--- a/indra/llwindow/llmousehandler.cpp
+++ b/indra/llwindow/llmousehandler.cpp
@@ -27,7 +27,7 @@
 #include "llmousehandler.h"
 
 //virtual
-BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
+BOOL LLMouseHandler::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)
 {
 	BOOL handled = FALSE;
 	if (down)
diff --git a/indra/llwindow/llmousehandler.h b/indra/llwindow/llmousehandler.h
index 1dcd0348d8bcd65414916024d3d2305fc8aeda18..d221dd117c89ff9c4183bc6193f7b69b19d0892d 100644
--- a/indra/llwindow/llmousehandler.h
+++ b/indra/llwindow/llmousehandler.h
@@ -29,6 +29,7 @@
 
 #include "linden_common.h"
 #include "llrect.h"
+#include "indra_constants.h"
 
 // Mostly-abstract interface.
 // Intended for use via multiple inheritance. 
@@ -46,16 +47,7 @@ class LLMouseHandler
 		SHOW_ALWAYS,
 	} EShowToolTip;
 
-	typedef enum {
-		CLICK_LEFT,
-		CLICK_MIDDLE,
-		CLICK_RIGHT,
-		CLICK_BUTTON4,
-		CLICK_BUTTON5,
-		CLICK_DOUBLELEFT
-	} EClickType;
-
-	virtual BOOL	handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down);
+	virtual BOOL	handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down);
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask) = 0;
 	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask) = 0;
 	virtual BOOL	handleMiddleMouseDown(S32 x, S32 y, MASK mask) = 0;
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index d77997a928000b1a152f174268818d3d71022aef..30bc743e72fbf31b5efb889dd4995beaeecea8e0 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -263,6 +263,18 @@ std::vector<std::string> LLWindow::getDynamicFallbackFontList()
 #endif
 }
 
+// static
+std::vector<std::string> LLWindow::getDisplaysResolutionList()
+{
+#if LL_WINDOWS
+	return LLWindowWin32::getDisplaysResolutionList();
+#elif LL_DARWIN
+	return LLWindowMacOSX::getDisplaysResolutionList();
+#else
+	return std::vector<std::string>();
+#endif
+}
+
 #define UTF16_IS_HIGH_SURROGATE(U) ((U16)((U) - 0xD800) < 0x0400)
 #define UTF16_IS_LOW_SURROGATE(U)  ((U16)((U) - 0xDC00) < 0x0400)
 #define UTF16_SURROGATE_PAIR_TO_UTF32(H,L) (((H) << 10) + (L) - (0xD800 << 10) - 0xDC00 + 0x00010000)
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index f1113acd5f9c55928901cad27d10e96cc64cf05e..d4d5b769376d1e4ae70e9333c0ee86adfcadf992 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -169,6 +169,8 @@ class LLWindow : public LLInstanceTracker<LLWindow>
 	// Get system UI size based on DPI (for 96 DPI UI size should be 1.0)
 	virtual F32 getSystemUISize() { return 1.0; }
 
+	static std::vector<std::string> getDisplaysResolutionList();
+
     // windows only DirectInput8 for joysticks
     virtual void* getDirectInput8() { return NULL; };
     virtual bool getInputDevices(U32 device_type_filter, void * devices_callback, void* userdata) { return false; };
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 2604a23c85107a5aaffa11373938ec4c547e4275..0d0607a0bb1e195fa3e651575f3a35ef8abb122f 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -41,6 +41,7 @@
 #include <OpenGL/OpenGL.h>
 #include <Carbon/Carbon.h>
 #include <CoreServices/CoreServices.h>
+#include <CoreGraphics/CGDisplayConfiguration.h>
 
 extern BOOL gDebugWindowProc;
 BOOL gHiDPISupport = TRUE;
@@ -1911,6 +1912,35 @@ void LLWindowMacOSX::interruptLanguageTextInput()
 	commitCurrentPreedit(mGLView);
 }
 
+std::vector<std::string> LLWindowMacOSX::getDisplaysResolutionList()
+{
+	std::vector<std::string> resolution_list;
+	
+	CGDirectDisplayID display_ids[10];
+	uint32_t found_displays = 0;
+	CGError err = CGGetActiveDisplayList(10, display_ids, &found_displays);
+	
+	if (kCGErrorSuccess != err)
+	{
+		LL_WARNS() << "Couldn't get a list of active displays" << LL_ENDL;
+		return std::vector<std::string>();
+	}
+	
+	for (uint32_t i = 0; i < found_displays; i++)
+	{
+		S32 monitor_width = CGDisplayPixelsWide(display_ids[i]);
+		S32 monitor_height = CGDisplayPixelsHigh(display_ids[i]);
+		
+		std::ostringstream sstream;
+		sstream << monitor_width << "x" << monitor_height;;
+		std::string res = sstream.str();
+		
+		resolution_list.push_back(res);
+	}
+	
+	return resolution_list;
+}
+
 //static
 std::vector<std::string> LLWindowMacOSX::getDynamicFallbackFontList()
 {
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 24651027e8385f29ff13fe908173d9588fb29694..bf45238c8d91bd1150108ee16e88d86faefd0506 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -114,6 +114,8 @@ class LLWindowMacOSX : public LLWindow
 	/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
 	/*virtual*/ F32 getSystemUISize();
 
+	static std::vector<std::string> getDisplaysResolutionList();
+
 	static std::vector<std::string> getDynamicFallbackFontList();
 
 	// Provide native key event data
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index c20e639fc74917d1204fe6044cec39eb7e5f690d..85eb9d6d1b17e47eda95d9e7c6e0225a5ef54538 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -51,13 +51,13 @@ extern "C" {
 # include "fontconfig/fontconfig.h"
 }
 
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
 // not necessarily available on random SDL platforms, so #if LL_LINUX
 // for execv(), waitpid(), fork()
 # include <unistd.h>
 # include <sys/types.h>
 # include <sys/wait.h>
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
 
 extern BOOL gDebugWindowProc;
 
@@ -323,12 +323,6 @@ static int x11_detect_VRAM_kb_fp(FILE *fp, const char *prefix_str)
 
 static int x11_detect_VRAM_kb()
 {
-#if LL_SOLARIS && defined(__sparc)
-      //  NOTE: there's no Xorg server on SPARC so just return 0
-      //        and allow SDL to attempt to get the amount of VRAM
-      return(0);
-#else
-
 	std::string x_log_location("/var/log/");
 	std::string fname;
 	int rtn = 0; // 'could not detect'
@@ -409,7 +403,6 @@ static int x11_detect_VRAM_kb()
 		}
 	}
 	return rtn;
-#endif // LL_SOLARIS
 }
 #endif // LL_X11
 
@@ -484,27 +477,10 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B
 	SDL_GL_SetAttribute(SDL_GL_RED_SIZE,  8);
 	SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE,8);
 	SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
-#if !LL_SOLARIS
-        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24);
+    SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, (bits <= 16) ? 16 : 24);
 	// We need stencil support for a few (minor) things.
 	if (!getenv("LL_GL_NO_STENCIL"))
 		SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
-#else
-	// NOTE- use smaller Z-buffer to enable more graphics cards
-        //     - This should not affect better GPUs and has been proven
-        //	 to provide 24-bit z-buffers when available.
-	//
-        // As the API states: 
-	//
-        // GLX_DEPTH_SIZE    Must be followed by a nonnegative
-        //                   minimum size specification.  If this
-        //                   value is zero, visuals with no depth
-        //                   buffer are preferred.  Otherwise, the
-        //                   largest available depth buffer of at
-        //                   least the minimum size is preferred.
-
-        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
-#endif
         SDL_GL_SetAttribute(SDL_GL_ALPHA_SIZE, (bits <= 16) ? 1 : 8);
 
         // *FIX: try to toggle vsync here?
@@ -682,25 +658,13 @@ BOOL LLWindowSDL::createContext(int x, int y, int width, int height, int bits, B
 	// fixme: actually, it's REALLY important for picking that we get at
 	// least 8 bits each of red,green,blue.  Alpha we can be a bit more
 	// relaxed about if we have to.
-#if LL_SOLARIS && defined(__sparc)
-//  again the __sparc required because Xsun support, 32bit are very pricey on SPARC
-	if(colorBits < 24)		//HACK:  on SPARC allow 24-bit color
-#else
 	if (colorBits < 32)
-#endif
 	{
 		close();
 		setupFailure(
-#if LL_SOLARIS && defined(__sparc)
-			"Second Life requires at least 24-bit color on SPARC to run in a window.\n"
-			"Please use fbconfig to set your default color depth to 24 bits.\n"
-			"You may also need to adjust the X11 setting in SMF.  To do so use\n"
-			"  'svccfg -s svc:/application/x11/x11-server setprop options/default_depth=24'\n"
-#else
 			"Second Life requires True Color (32-bit) to run in a window.\n"
 			"Please go to Control Panels -> Display -> Settings and\n"
 			"set the screen to 32-bit color.\n"
-#endif
 			"Alternately, if you choose to run fullscreen, Second Life\n"
 			"will automatically adjust the screen each time it runs.",
 			"Error",
@@ -2503,7 +2467,7 @@ BOOL LLWindowSDL::dialogColorPicker( F32 *r, F32 *g, F32 *b)
 }
 #endif // LL_GTK
 
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
 // extracted from spawnWebBrowser for clarity and to eliminate
 //  compiler confusion regarding close(int fd) vs. LLWindow::close()
 void exec_cmd(const std::string& cmd, const std::string& arg)
@@ -2559,7 +2523,7 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async)
 
 	LL_INFOS() << "spawn_web_browser: " << escaped_url << LL_ENDL;
 	
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
 # if LL_X11
 	if (mSDL_Display)
 	{
@@ -2578,7 +2542,7 @@ void LLWindowSDL::spawnWebBrowser(const std::string& escaped_url, bool async)
 	cmd += "launch_url.sh";
 	arg = escaped_url;
 	exec_cmd(cmd, arg);
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
 
 	LL_INFOS() << "spawn_web_browser returning." << LL_ENDL;
 }
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index e8abb9f31ab9be63852058626b286088382da98c..b2b123f0da0764e297b46ac67d82bcac22ba9044 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -38,6 +38,7 @@
 
 // Linden library includes
 #include "llerror.h"
+#include "llexception.h"
 #include "llfasttimer.h"
 #include "llgl.h"
 #include "llstring.h"
@@ -121,7 +122,7 @@ void show_window_creation_error(const std::string& title)
 	LL_WARNS("Window") << title << LL_ENDL;
 }
 
-HGLRC SafeCreateContext(HDC hdc)
+HGLRC SafeCreateContext(HDC &hdc)
 {
 	__try 
 	{
@@ -133,6 +134,22 @@ HGLRC SafeCreateContext(HDC hdc)
 	}
 }
 
+GLuint SafeChoosePixelFormat(HDC &hdc, const PIXELFORMATDESCRIPTOR *ppfd)
+{
+    __try
+    {
+        return ChoosePixelFormat(hdc, ppfd);
+    }
+    __except (EXCEPTION_EXECUTE_HANDLER)
+    {
+        // convert to C++ styled exception
+        // C exception don't allow classes, so it's a regular char array
+        char integer_string[32];
+        sprintf(integer_string, "SEH, code: %lu\n", GetExceptionCode());
+        throw std::exception(integer_string);
+    }
+}
+
 //static
 BOOL LLWindowWin32::sIsClassRegistered = FALSE;
 
@@ -404,6 +421,39 @@ LLWinImm::~LLWinImm()
 }
 
 
+class LLMonitorInfo
+{
+public:
+
+	std::vector<std::string> getResolutionsList() { return mResList; }
+
+	LLMonitorInfo()
+	{
+		EnumDisplayMonitors(0, 0, MonitorEnum, (LPARAM)this);
+	}
+
+private:
+
+	static BOOL CALLBACK MonitorEnum(HMONITOR hMon, HDC hdc, LPRECT lprcMonitor, LPARAM pData)
+	{
+		int monitor_width = lprcMonitor->right - lprcMonitor->left;
+		int monitor_height = lprcMonitor->bottom - lprcMonitor->top;
+		
+		std::ostringstream sstream;
+		sstream << monitor_width << "x" << monitor_height;;
+		std::string res = sstream.str();
+
+		LLMonitorInfo* pThis = reinterpret_cast<LLMonitorInfo*>(pData);
+		pThis->mResList.push_back(res);
+
+		return TRUE;
+	}
+
+	std::vector<std::string> mResList;
+};
+
+static LLMonitorInfo sMonitorInfo;
+
 LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
 							 const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
 							 S32 height, U32 flags, 
@@ -432,6 +482,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
 	memset(mCurrentGammaRamp, 0, sizeof(mCurrentGammaRamp));
 	memset(mPrevGammaRamp, 0, sizeof(mPrevGammaRamp));
 	mCustomGammaSet = FALSE;
+	mWindowHandle = NULL;
 	
 	if (!SystemParametersInfo(SPI_GETMOUSEVANISH, 0, &mMouseVanish, 0))
 	{
@@ -695,6 +746,37 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
 	//		TrackMouseEvent( &track_mouse_event ); 
 	//	}
 
+    // SL-12971 dual GPU display
+    DISPLAY_DEVICEA display_device;
+    int             display_index = -1;
+    DWORD           display_flags = 0; // EDD_GET_DEVICE_INTERFACE_NAME ?
+    const size_t    display_bytes = sizeof(display_device);
+
+    do
+    {
+        if (display_index >= 0)
+        {
+            // CHAR DeviceName  [ 32] Adapter name
+            // CHAR DeviceString[128]
+            CHAR text[256];
+
+            size_t name_len = strlen(display_device.DeviceName  );
+            size_t desc_len = strlen(display_device.DeviceString);
+
+            CHAR *name = name_len ? display_device.DeviceName   : "???";
+            CHAR *desc = desc_len ? display_device.DeviceString : "???";
+
+            sprintf(text, "Display Device %d: %s, %s", display_index, name, desc);
+            LL_INFOS("Window") << text << LL_ENDL;
+        }
+
+        ::ZeroMemory(&display_device,display_bytes);
+        display_device.cb = display_bytes;
+
+        display_index++;
+    }  while( EnumDisplayDevicesA(NULL, display_index, &display_device, display_flags ));
+
+    LL_INFOS("Window") << "Total Display Devices: " << display_index << LL_ENDL;
 
 	//-----------------------------------------------------------------------
 	// Create GL drawing context
@@ -1157,7 +1239,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
         << " Height: " << (window_rect.bottom - window_rect.top)
         << " Fullscreen: " << mFullscreen
         << LL_ENDL;
-    if (!destroy_window_handler(mWindowHandle))
+    if (mWindowHandle && !destroy_window_handler(mWindowHandle))
     {
         LL_WARNS("Window") << "Failed to properly close window before recreating it!" << LL_ENDL;
     }	
@@ -1216,11 +1298,24 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 
 	LL_INFOS("Window") << "Device context retrieved." << LL_ENDL ;
 
-	if (!(pixel_format = ChoosePixelFormat(mhDC, &pfd)))
+    try
+    {
+        // Looks like ChoosePixelFormat can crash in case of faulty driver
+        if (!(pixel_format = SafeChoosePixelFormat(mhDC, &pfd)))
 	{
+            LL_WARNS("Window") << "ChoosePixelFormat failed, code: " << GetLastError() << LL_ENDL;
+            OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"),
+                mCallbacks->translateString("MBError"), OSMB_OK);
 		close();
+            return FALSE;
+        }
+    }
+    catch (...)
+    {
+        LOG_UNHANDLED_EXCEPTION("ChoosePixelFormat");
 		OSMessageBox(mCallbacks->translateString("MBPixelFmtErr"),
 			mCallbacks->translateString("MBError"), OSMB_OK);
+        close();
 		return FALSE;
 	}
 
@@ -1449,21 +1544,27 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 		LL_INFOS("Window") << "pixel formats done." << LL_ENDL ;
 
 		S32 swap_method = 0;
-		S32 cur_format = num_formats-1;
+		S32   cur_format  = 0;
+const	S32   max_format  = (S32)num_formats - 1;
 		GLint swap_query = WGL_SWAP_METHOD_ARB;
 
-		BOOL found_format = FALSE;
-
-		while (!found_format && wglGetPixelFormatAttribivARB(mhDC, pixel_format, 0, 1, &swap_query, &swap_method))
+		// SL-14705 Fix name tags showing in front of objects with AMD GPUs.
+		// On AMD hardware we need to iterate from the first pixel format to the end.
+		// Spec:
+		//     https://www.khronos.org/registry/OpenGL/extensions/ARB/WGL_ARB_pixel_format.txt
+		while (wglGetPixelFormatAttribivARB(mhDC, pixel_formats[cur_format], 0, 1, &swap_query, &swap_method))
 		{
-			if (swap_method == WGL_SWAP_UNDEFINED_ARB || cur_format <= 0)
+			if (swap_method == WGL_SWAP_UNDEFINED_ARB)
 			{
-				found_format = TRUE;
+				break;
 			}
-			else
+			else if (cur_format >= max_format)
 			{
-				--cur_format;
+				cur_format = 0;
+				break;
 			}
+
+			++cur_format;
 		}
 		
 		pixel_format = pixel_formats[cur_format];
@@ -1482,7 +1583,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen &size, BO
 		}
 
         // Destroy The Window
-        if (!destroy_window_handler(mWindowHandle))
+        if (mWindowHandle && !destroy_window_handler(mWindowHandle))
         {
             LL_WARNS("Window") << "Failed to properly close window!" << LL_ENDL;
         }		
@@ -4287,6 +4388,12 @@ F32 LLWindowWin32::getSystemUISize()
 	return scale_value;
 }
 
+//static
+std::vector<std::string> LLWindowWin32::getDisplaysResolutionList()
+{ 
+	return sMonitorInfo.getResolutionsList();
+}
+
 //static
 std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
 {
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index ee0df570e90f62bcbb8c788afded3f9f97c29e40..0b3d14fb166917375c73deba7608f18bcbf7edf5 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -114,6 +114,7 @@ class LLWindowWin32 : public LLWindow
 
 	LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url );
 
+	static std::vector<std::string> getDisplaysResolutionList();
 	static std::vector<std::string> getDynamicFallbackFontList();
 	static void setDPIAwareness();
 
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 873e62900eb9a0de7fe41495700d4ae2cbdfdc1a..0e2dff9cf068c47b0d0a034a14bf46df8a3b489d 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -209,6 +209,7 @@ set(viewer_SOURCE_FILES
     llflexibleobject.cpp
     llfloaterabout.cpp
     llfloaterbvhpreview.cpp
+    llfloateraddpaymentmethod.cpp
     llfloaterauction.cpp
     llfloaterautoreplacesettings.cpp
     llfloateravatar.cpp
@@ -232,8 +233,10 @@ set(viewer_SOURCE_FILES
     llfloatercolorpicker.cpp
     llfloaterconversationlog.cpp
     llfloaterconversationpreview.cpp
+    llfloatercreatelandmark.cpp
     llfloaterdeleteprefpreset.cpp
     llfloaterdestinations.cpp
+    llfloatereditenvironmentbase.cpp
     llfloatereditextdaycycle.cpp
     llfloaterenvironmentadjust.cpp
     llfloaterevent.cpp
@@ -253,6 +256,7 @@ set(viewer_SOURCE_FILES
     llfloaterhandler.cpp
     llfloaterhelpbrowser.cpp
     llfloaterhoverheight.cpp
+    llfloaterhowto.cpp
     llfloaterhud.cpp
     llfloaterimagepreview.cpp
     llfloaterimsessiontab.cpp
@@ -375,6 +379,7 @@ set(viewer_SOURCE_FILES
     llinventoryobserver.cpp
     llinventorypanel.cpp
     lljoystickbutton.cpp
+    llkeyconflict.cpp
     lllandmarkactions.cpp
     lllandmarklist.cpp
     lllegacyatmospherics.cpp
@@ -556,6 +561,7 @@ set(viewer_SOURCE_FILES
     llsecapi.cpp
     llsechandler_basic.cpp
     llselectmgr.cpp
+    llsetkeybinddialog.cpp
     llsettingspicker.cpp
     llsettingsvo.cpp
     llshareavatarhandler.cpp
@@ -583,6 +589,7 @@ set(viewer_SOURCE_FILES
     llsyntaxid.cpp
     llsyswellitem.cpp
     llsyswellwindow.cpp
+    lltelemetry.cpp
     llteleporthistory.cpp
     llteleporthistorystorage.cpp
     lltextureatlas.cpp
@@ -632,6 +639,7 @@ set(viewer_SOURCE_FILES
     llurl.cpp
     llurldispatcher.cpp
     llurldispatcherlistener.cpp
+    llurlfloaterdispatchhandler.cpp
     llurlhistory.cpp
     llurllineeditorctrl.cpp
     llurlwhitelist.cpp
@@ -661,7 +669,7 @@ set(viewer_SOURCE_FILES
     llviewerjointattachment.cpp
     llviewerjointmesh.cpp
     llviewerjoystick.cpp
-    llviewerkeyboard.cpp
+    llviewerinput.cpp
     llviewerlayer.cpp
     llviewermedia.cpp
     llviewermedia_streamingaudio.cpp
@@ -852,6 +860,7 @@ set(viewer_HEADER_FILES
     llflexibleobject.h
     llfloaterabout.h
     llfloaterbvhpreview.h
+    llfloateraddpaymentmethod.h
     llfloaterauction.h
     llfloaterautoreplacesettings.h
     llfloateravatar.h
@@ -875,8 +884,10 @@ set(viewer_HEADER_FILES
     llfloatercolorpicker.h
     llfloaterconversationlog.h
     llfloaterconversationpreview.h
+    llfloatercreatelandmark.h
     llfloaterdeleteprefpreset.h
     llfloaterdestinations.h
+    llfloatereditenvironmentbase.h
     llfloatereditextdaycycle.h
     llfloaterenvironmentadjust.h
     llfloaterevent.h
@@ -896,6 +907,7 @@ set(viewer_HEADER_FILES
     llfloaterhandler.h
     llfloaterhelpbrowser.h
     llfloaterhoverheight.h
+    llfloaterhowto.h
     llfloaterhud.h
     llfloaterimagepreview.h
     llfloaterimnearbychat.h
@@ -1019,6 +1031,7 @@ set(viewer_HEADER_FILES
     llinventoryobserver.h
     llinventorypanel.h
     lljoystickbutton.h
+    llkeyconflict.h
     lllandmarkactions.h
     lllandmarklist.h
     lllightconstants.h
@@ -1190,6 +1203,7 @@ set(viewer_HEADER_FILES
     llsecapi.h
     llsechandler_basic.h
     llselectmgr.h
+    llsetkeybinddialog.h
     llsettingspicker.h
     llsettingsvo.h
     llsidepanelappearance.h
@@ -1269,6 +1283,7 @@ set(viewer_HEADER_FILES
     llurl.h
     llurldispatcher.h
     llurldispatcherlistener.h
+    llurlfloaterdispatchhandler.h
     llurlhistory.h
     llurllineeditorctrl.h
     llurlwhitelist.h
@@ -1297,7 +1312,7 @@ set(viewer_HEADER_FILES
     llviewerjointattachment.h
     llviewerjointmesh.h
     llviewerjoystick.h
-    llviewerkeyboard.h
+    llviewerinput.h
     llviewerlayer.h
     llviewermedia.h
     llviewermediafocus.h
@@ -1688,7 +1703,7 @@ set(viewer_APPSETTINGS_FILES
     app_settings/grass.xml
     app_settings/high_graphics.xml
     app_settings/ignorable_dialogs.xml
-    app_settings/keys.xml
+    app_settings/key_bindings.xml
     app_settings/keywords_lsl_default.xml
     app_settings/logcontrol.xml
     app_settings/low_graphics.xml
@@ -1842,10 +1857,12 @@ if (WINDOWS)
       ${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll
       ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll
       #${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll
-      ${LIBS_PREBUILT_DIR}/bin/release/SLVoice.exe
+      ${SHARED_LIB_STAGING_DIR}/Release/uriparser.dll
+      ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/uriparser.dll
+      ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe
       #${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libsndfile-1.dll
       #${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxoal.dll
-      ${LIBS_PREBUILT_DIR}/ca-bundle.crt
+      ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ca-bundle.crt
       ${GOOGLE_PERF_TOOLS_SOURCE}
       ${CMAKE_CURRENT_SOURCE_DIR}/licenses-win32.txt
       #${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index d613169e8896c11271275886f09efa7954d4589f..e786022da5d4f75c8734f90965b20f1e132ce6cd 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-6.4.12
+6.4.20
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 6d367955689c65c73d1c12987e7c585eea2b62b2..b1f6e2fb100afff61f5a68ec7b0f1d03f7fe7b2f 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -90,8 +90,10 @@
            icon="Command_HowTo_Icon"
            label_ref="Command_HowTo_Label"
            tooltip_ref="Command_HowTo_Tooltip"
-           execute_function="Help.ToggleHowTo"
-           is_running_function="Help.HowToVisible"
+           execute_function="Floater.ToggleOrBringToFront"
+           execute_parameters="guidebook"
+           is_running_function="Floater.IsOpen"
+           is_running_parameters="guidebook"
            />
   <command name="inventory"
            available_in_toybox="true"
diff --git a/indra/newview/app_settings/keys.xml b/indra/newview/app_settings/key_bindings.xml
similarity index 64%
rename from indra/newview/app_settings/keys.xml
rename to indra/newview/app_settings/key_bindings.xml
index a8037fec05a663e610807aaafb8ea214754d7e3f..4f6deb1f9853c968b0552d4bd21a20a9a171baf6 100644
--- a/indra/newview/app_settings/keys.xml
+++ b/indra/newview/app_settings/key_bindings.xml
@@ -28,34 +28,11 @@
     <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
     <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
 
-    <binding key="A" mask="SHIFT" command="slide_left"/>
-    <binding key="D" mask="SHIFT" command="slide_right"/>
-    <binding key="W" mask="SHIFT" command="push_forward"/>
-    <binding key="S" mask="SHIFT" command="push_backward"/>
-    <binding key="E" mask="SHIFT" command="jump"/>
-    <binding key="C" mask="SHIFT" command="push_down"/>
-    <binding key="F" mask="SHIFT" command="toggle_fly"/>
-
     <binding key="SPACE" mask="NONE" command="stop_moving"/>
     <binding key="ENTER" mask="NONE" command="start_chat"/>
     <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
 
-    <binding key="LEFT" mask="SHIFT" command="slide_left"/>
-    <binding key="RIGHT" mask="SHIFT" command="slide_right"/>
-    <binding key="UP" mask="SHIFT" command="push_forward"/>
-    <binding key="DOWN" mask="SHIFT" command="push_backward"/>
-    <binding key="PGUP" mask="SHIFT" command="jump"/>
-    <binding key="PGDN" mask="SHIFT" command="push_down"/>
-
-    <binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
-    <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
-    <binding key="PAD_UP" mask="SHIFT" command="push_forward"/>
-    <binding key="PAD_DOWN" mask="SHIFT" command="push_backward"/>
-    <binding key="PAD_PGUP" mask="SHIFT" command="jump"/>
-    <binding key="PAD_PGDN" mask="SHIFT" command="push_down"/>
-    <binding key="PAD_HOME" mask="SHIFT" command="toggle_fly"/>
-    <binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
+    <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
   </first_person>
   <third_person>
     <binding key="A" mask="NONE" command="turn_left"/>
@@ -64,15 +41,10 @@
     <binding key="D" mask="SHIFT" command="slide_right"/>
     <binding key="W" mask="NONE" command="push_forward"/>
     <binding key="S" mask="NONE" command="push_backward"/>
-    <binding key="W" mask="SHIFT" command="push_forward"/>
-    <binding key="S" mask="SHIFT" command="push_backward"/>
     <binding key="E" mask="NONE" command="jump"/>
     <binding key="C" mask="NONE" command="push_down"/>
-    <binding key="E" mask="SHIFT" command="jump"/>
-    <binding key="C" mask="SHIFT" command="push_down"/>
 
     <binding key="F" mask="NONE" command="toggle_fly"/>
-    <binding key="F" mask="SHIFT" command="toggle_fly"/>
 
     <binding key="SPACE" mask="NONE" command="stop_moving"/>
     <binding key="ENTER" mask="NONE" command="start_chat"/>
@@ -84,13 +56,8 @@
     <binding key="RIGHT" mask="SHIFT" command="slide_right"/>
     <binding key="UP" mask="NONE" command="push_forward"/>
     <binding key="DOWN" mask="NONE" command="push_backward"/>
-    <binding key="UP" mask="SHIFT" command="push_forward"/>
-    <binding key="DOWN" mask="SHIFT" command="push_backward"/>
     <binding key="PGUP" mask="NONE" command="jump"/>
     <binding key="PGDN" mask="NONE" command="push_down"/>
-    <binding key="PGUP" mask="SHIFT" command="jump"/>
-    <binding key="PGDN" mask="SHIFT" command="push_down"/>
-    <binding key="HOME" mask="SHIFT" command="toggle_fly"/>
     <binding key="HOME" mask="NONE" command="toggle_fly"/>
 
     <binding key="PAD_LEFT" mask="NONE" command="turn_left"/>
@@ -99,20 +66,12 @@
     <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
     <binding key="PAD_UP" mask="NONE" command="push_forward"/>
     <binding key="PAD_DOWN" mask="NONE" command="push_backward"/>
-    <binding key="PAD_UP" mask="SHIFT" command="push_forward"/>
-    <binding key="PAD_DOWN" mask="SHIFT" command="push_backward"/>
     <binding key="PAD_PGUP" mask="NONE" command="jump"/>
     <binding key="PAD_PGDN" mask="NONE" command="push_down"/>
-    <binding key="PAD_PGUP" mask="SHIFT" command="jump"/>
-    <binding key="PAD_PGDN" mask="SHIFT" command="push_down"/>
     <binding key="PAD_HOME" mask="NONE" command="toggle_fly"/>
-    <binding key="PAD_HOME" mask="SHIFT" command="toggle_fly"/>
     <binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
-    <binding key="PAD_CENTER" mask="SHIFT" command="stop_moving"/>
     <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
-    <binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
     <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
-    <binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
 
     <!--Camera controls in third person on Alt-->
     <binding key="LEFT" mask="ALT" command="spin_around_cw"/>
@@ -139,28 +98,14 @@
     <binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/>
 
     <!--mimic alt zoom behavior with keyboard only-->
-    <binding key="A" mask="CTL_ALT" command="spin_around_cw"/>
-    <binding key="D" mask="CTL_ALT" command="spin_around_ccw"/>
     <binding key="W" mask="CTL_ALT" command="spin_over"/>
     <binding key="S" mask="CTL_ALT" command="spin_under"/>
-    <binding key="E" mask="CTL_ALT" command="spin_over"/>
-    <binding key="C" mask="CTL_ALT" command="spin_under"/>
 
-    <binding key="LEFT" mask="CTL_ALT" command="spin_around_cw"/>
-    <binding key="RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
     <binding key="UP" mask="CTL_ALT" command="spin_over"/>
     <binding key="DOWN" mask="CTL_ALT" command="spin_under"/>
-    <binding key="PGUP" mask="CTL_ALT" command="spin_over"/>
-    <binding key="PGDN" mask="CTL_ALT" command="spin_under"/>
 
-    <binding key="PAD_LEFT" mask="CTL_ALT" command="spin_around_cw"/>
-    <binding key="PAD_RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
     <binding key="PAD_UP" mask="CTL_ALT" command="spin_over"/>
     <binding key="PAD_DOWN" mask="CTL_ALT" command="spin_under"/>
-    <binding key="PAD_PGUP" mask="CTL_ALT" command="spin_over"/>
-    <binding key="PAD_PGDN" mask="CTL_ALT" command="spin_under"/>
-    <binding key="PAD_ENTER" mask="CTL_ALT" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="CTL_ALT" command="start_gesture"/>
 
     <!--Therefore pan on Alt-Shift-->
     <binding key="A" mask="CTL_ALT_SHIFT" command="pan_left"/>
@@ -179,63 +124,10 @@
     <binding key="PAD_DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
     <binding key="PAD_ENTER" mask="CTL_ALT_SHIFT" command="start_chat"/>
     <binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/>
-  </third_person>
 
-  <!-- Basic editing camera control -->
-  <edit>
-    <binding key="A" mask="NONE" command="spin_around_cw"/>
-    <binding key="D" mask="NONE" command="spin_around_ccw"/>
-    <binding key="W" mask="NONE" command="move_forward"/>
-    <binding key="S" mask="NONE" command="move_backward"/>
-    <binding key="E" mask="NONE" command="spin_over"/>
-    <binding key="C" mask="NONE" command="spin_under"/>
-    <binding key="ENTER" mask="NONE" command="start_chat"/>
-    <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
-    <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
-
-    <binding key="LEFT" mask="NONE" command="spin_around_cw"/>
-    <binding key="RIGHT" mask="NONE" command="spin_around_ccw"/>
-    <binding key="UP" mask="NONE" command="move_forward"/>
-    <binding key="DOWN" mask="NONE" command="move_backward"/>
-    <binding key="PGUP" mask="NONE" command="spin_over"/>
-    <binding key="PGDN" mask="NONE" command="spin_under"/>
-
-    <binding key="A" mask="SHIFT" command="pan_left"/>
-    <binding key="D" mask="SHIFT" command="pan_right"/>
-    <binding key="W" mask="SHIFT" command="pan_up"/>
-    <binding key="S" mask="SHIFT" command="pan_down"/>
-
-    <binding key="LEFT" mask="SHIFT" command="pan_left"/>
-    <binding key="RIGHT" mask="SHIFT" command="pan_right"/>
-    <binding key="UP" mask="SHIFT" command="pan_up"/>
-    <binding key="DOWN" mask="SHIFT" command="pan_down"/>
-
-    <!--Walking works with ALT held down.-->
-    <binding key="A" mask="ALT" command="slide_left"/>
-    <binding key="D" mask="ALT" command="slide_right"/>
-    <binding key="W" mask="ALT" command="push_forward"/>
-    <binding key="S" mask="ALT" command="push_backward"/>
-    <binding key="E" mask="ALT" command="jump"/>
-    <binding key="C" mask="ALT" command="push_down"/>
-
-    <binding key="LEFT" mask="ALT" command="slide_left"/>
-    <binding key="RIGHT" mask="ALT" command="slide_right"/>
-    <binding key="UP" mask="ALT" command="push_forward"/>
-    <binding key="DOWN" mask="ALT" command="push_backward"/>
-    <binding key="PGUP" mask="ALT" command="jump"/>
-    <binding key="PGDN" mask="ALT" command="push_down"/>
-    <binding key="HOME" mask="ALT" command="toggle_fly"/>
-
-    <binding key="PAD_LEFT" mask="ALT" command="slide_left"/>
-    <binding key="PAD_RIGHT" mask="ALT" command="slide_right"/>
-    <binding key="PAD_UP" mask="ALT" command="push_forward"/>
-    <binding key="PAD_DOWN" mask="ALT" command="push_backward"/>
-    <binding key="PAD_PGUP" mask="ALT" command="jump"/>
-    <binding key="PAD_PGDN" mask="ALT" command="push_down"/>
-    <binding key="PAD_ENTER" mask="ALT" command="start_chat"/>
-    <binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/>
-  </edit>
+    <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
+    <binding key="" mask="NONE" mouse="LMB" command="walk_to"/>
+  </third_person>
   <sitting>
     <binding key="A" mask="ALT" command="spin_around_cw"/>
     <binding key="D" mask="ALT" command="spin_around_ccw"/>
@@ -251,15 +143,11 @@
     <binding key="PGUP" mask="ALT" command="spin_over"/>
     <binding key="PGDN" mask="ALT" command="spin_under"/>
 
-    <binding key="A" mask="CTL_ALT" command="spin_around_cw"/>
-    <binding key="D" mask="CTL_ALT" command="spin_around_ccw"/>
     <binding key="W" mask="CTL_ALT" command="spin_over"/>
     <binding key="S" mask="CTL_ALT" command="spin_under"/>
     <binding key="E" mask="CTL_ALT" command="spin_over"/>
     <binding key="C" mask="CTL_ALT" command="spin_under"/>
 
-    <binding key="LEFT" mask="CTL_ALT" command="spin_around_cw"/>
-    <binding key="RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
     <binding key="UP" mask="CTL_ALT" command="spin_over"/>
     <binding key="DOWN" mask="CTL_ALT" command="spin_under"/>
     <binding key="PGUP" mask="CTL_ALT" command="spin_over"/>
@@ -294,23 +182,23 @@
     <binding key="A" mask="SHIFT" command="slide_left"/>
     <binding key="D" mask="SHIFT" command="slide_right"/>
     <binding key="W" mask="SHIFT" command="move_forward_sitting"/>
-	<binding key="S" mask="SHIFT" command="move_backward_sitting"/>
-	<binding key="E" mask="SHIFT" command="spin_over_sitting"/>
-	<binding key="C" mask="SHIFT" command="spin_under_sitting"/>
+    <binding key="S" mask="SHIFT" command="move_backward_sitting"/>
+    <binding key="E" mask="SHIFT" command="spin_over_sitting"/>
+    <binding key="C" mask="SHIFT" command="spin_under_sitting"/>
 
     <binding key="LEFT" mask="SHIFT" command="slide_left"/>
     <binding key="RIGHT" mask="SHIFT" command="slide_right"/>
     <binding key="UP" mask="SHIFT" command="move_forward_sitting"/>
-	<binding key="DOWN" mask="SHIFT" command="move_backward_sitting"/>
-	<binding key="PGUP" mask="SHIFT" command="spin_over_sitting"/>
-	<binding key="PGDN" mask="SHIFT" command="spin_under_sitting"/>
+    <binding key="DOWN" mask="SHIFT" command="move_backward_sitting"/>
+    <binding key="PGUP" mask="SHIFT" command="spin_over_sitting"/>
+    <binding key="PGDN" mask="SHIFT" command="spin_under_sitting"/>
 
     <binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
     <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
     <binding key="PAD_UP" mask="SHIFT" command="move_forward_sitting"/>
-	<binding key="PAD_DOWN" mask="SHIFT" command="move_backward_sitting"/>
-	<binding key="PAD_PGUP" mask="SHIFT" command="spin_over_sitting"/>
-	<binding key="PAD_PGDN" mask="SHIFT" command="spin_under_sitting"/> 
+    <binding key="PAD_DOWN" mask="SHIFT" command="move_backward_sitting"/>
+    <binding key="PAD_PGUP" mask="SHIFT" command="spin_over_sitting"/>
+    <binding key="PAD_PGDN" mask="SHIFT" command="spin_under_sitting"/> 
     <binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
     <binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
 
@@ -334,6 +222,8 @@
 
     <binding key="ENTER" mask="NONE" command="start_chat"/>
     <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
+
+    <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
   </sitting>
   <edit_avatar>
     <!--Avatar editing camera controls-->
@@ -359,5 +249,7 @@
     <binding key="PAD_PGDN" mask="NONE" command="edit_avatar_spin_under"/>
     <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
     <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
+
+    <binding key="" mask="NONE" mouse="MMB" command="toggle_voice"/>
   </edit_avatar>
-</keys>
\ No newline at end of file
+</keys>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 3416c72c7326ee94dbd92d724721ad7505e7fdc3..8deee2db4c81325aee030d46bc63ed1e15ff7c6e 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -3861,7 +3861,7 @@
     <key>DoubleClickAutoPilot</key>
     <map>
       <key>Comment</key>
-      <string>Enable double-click auto pilot</string>
+      <string>(Obsolete)Enable double-click auto pilot</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -3869,10 +3869,10 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
-    <key>DoubleClickTeleport</key>
+    <key>DoubleClickTeleport</key> 
     <map>
       <key>Comment</key>
-      <string>Enable double-click to teleport where allowed</string>
+      <string>Enable double-click to teleport where allowed (afects minimap and people panel)</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -5055,6 +5055,17 @@
       <key>Value</key>
       <string>https://search.[GRID]/viewer/[CATEGORY]/?q=[QUERY]&amp;p=[AUTH_TOKEN]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
     </map>
+    <key>GuidebookURL</key>
+    <map>
+      <key>Comment</key>
+      <string>URL for Guidebook content</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>http://guidebooks.secondlife.io/welcome/index.html</string>
+    </map>
     <key>HighResSnapshot</key>
     <map>
       <key>Comment</key>
@@ -6265,7 +6276,7 @@
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
-      <string>http://map.secondlife.com.s3.amazonaws.com/</string>
+      <string>https://map.secondlife.com/</string>
     </map>
     <key>CurrentMapServerURL</key>
     <map>
@@ -6916,7 +6927,7 @@
     <key>Value</key>
     <integer>1</integer>
   </map>
-  <key>MemoryFailurePreventionEnabled</key>
+  <key>MemoryFailurePreventionEnabled</key> <!-- deprecated, only used for obsolete-in-2020 Intel 965 Express GPU -->
   <map>
     <key>Comment</key>
     <string>If set, the viewer will quit to avoid crash when memory failure happens</string>
@@ -8623,7 +8634,7 @@
     <key>PushToTalkButton</key>
     <map>
       <key>Comment</key>
-      <string>Which button or keyboard key is used for push-to-talk</string>
+      <string>(Obsolete)Which button or keyboard key is used for push-to-talk</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -9454,7 +9465,7 @@
     <key>Type</key>
     <string>F32</string>
     <key>Value</key>
-    <real>0.03</real>
+    <real>0.1</real>
   </map>
   <key>RenderDebugPipeline</key>
     <map>
@@ -14777,7 +14788,53 @@
       <key>Value</key>
       <integer>44125</integer>
     </map>
-    <key>VoiceCallsFriendsOnly</key>
+    
+  <key>VivoxVadAuto</key>
+  <map>
+    <key>Comment</key>
+    <string>A flag indicating if the automatic VAD is enabled (1) or disabled (0). The individual settings are ignored if the auto-mode is enabled</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+  <key>VivoxVadHangover</key>
+  <map>
+    <key>Comment</key>
+    <string>The time (in milliseconds) that it takes or the VAD to switch back to silence from speech mode after the last speech frame has been detected</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>2000</integer>
+  </map>
+  <key>VivoxVadNoiseFloor</key>
+  <map>
+    <key>Comment</key>
+    <string>A dimensionless value between 0 and 20000 (default 576) that controls the maximum level at which the noise floor may be set at by the VAD's noise tracking</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>576</integer>
+  </map>
+  <key>VivoxVadSensitivity</key>
+  <map>
+    <key>Comment</key>
+    <string>
+      A dimensionless value between 0 and 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds to decreasing the sensitivity of the VAD and 0 is turned off altogether</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+  <key>VoiceCallsFriendsOnly</key>
     <map>
       <key>Comment</key>
       <string>(Deprecated) Only accept voice calls from residents on your friends list</string>
@@ -15521,7 +15578,7 @@
         <key>Value</key>
             <real>1</real>
         </map>
-    <key>PoolSizeVAssetStorage</key>
+    <key>PoolSizeAssetStorage</key>
         <map>
         <key>Comment</key>
             <string>Coroutine Pool size for AssetStorage requests</string>
@@ -15919,7 +15976,7 @@
     <key>ClickToWalk</key>
     <map>
       <key>Comment</key>
-      <string>Click in world to walk to location</string>
+      <string>(obsolete)Click in world to walk to location</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
diff --git a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
index b7036e02cfcc8f169dcdad32f858f334c79159c5..8e0a0014038514208f6772cccd09b38b8925172c 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/cloudsV.glsl
@@ -1,24 +1,24 @@
-/**
+/** 
  * @file WLCloudsV.glsl
  *
  * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2005, Linden Research, Inc.
- *
+ * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- *
+ * 
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- *
+ * 
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
+ * 
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -33,26 +33,26 @@ ATTRIBUTE vec2 texcoord0;
 ///////////////////////////////////////////////////////////////////////////////
 
 // Output parameters
-VARYING vec4  vary_CloudColorSun;
-VARYING vec4  vary_CloudColorAmbient;
+VARYING vec4 vary_CloudColorSun;
+VARYING vec4 vary_CloudColorAmbient;
 VARYING float vary_CloudDensity;
 
-VARYING vec2  vary_texcoord0;
-VARYING vec2  vary_texcoord1;
-VARYING vec2  vary_texcoord2;
-VARYING vec2  vary_texcoord3;
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec2 vary_texcoord3;
 VARYING float altitude_blend_factor;
 
 // Inputs
 uniform vec3 camPosLocal;
 
-uniform vec4  lightnorm;
-uniform vec4  sunlight_color;
-uniform vec4  moonlight_color;
-uniform int   sun_up_factor;
-uniform vec4  ambient_color;
-uniform vec4  blue_horizon;
-uniform vec4  blue_density;
+uniform vec4 lightnorm;
+uniform vec4 sunlight_color;
+uniform vec4 moonlight_color;
+uniform int sun_up_factor;
+uniform vec4 ambient_color;
+uniform vec4 blue_horizon;
+uniform vec4 blue_density;
 uniform float haze_horizon;
 uniform float haze_density;
 
@@ -60,7 +60,7 @@ uniform float cloud_shadow;
 uniform float density_multiplier;
 uniform float max_y;
 
-uniform vec4  glow;
+uniform vec4 glow;
 uniform float sun_moon_glow_factor;
 
 uniform vec4 cloud_color;
@@ -75,53 +75,53 @@ uniform float cloud_scale;
 //       indra\newview\llsettingsvo.cpp
 void main()
 {
-    // World / view / projection
-    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	// World / view / projection
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
 
-    // Texture coords
+	// Texture coords
     // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
     vary_texcoord0 = vec2(-texcoord0.x, texcoord0.y);  // See: LLSettingsVOSky::applySpecial
 
-    vary_texcoord0.xy -= 0.5;
-    vary_texcoord0.xy /= cloud_scale;
-    vary_texcoord0.xy += 0.5;
+	vary_texcoord0.xy -= 0.5;
+	vary_texcoord0.xy /= cloud_scale;
+	vary_texcoord0.xy += 0.5;
 
-    vary_texcoord1 = vary_texcoord0;
-    vary_texcoord1.x += lightnorm.x * 0.0125;
-    vary_texcoord1.y += lightnorm.z * 0.0125;
+	vary_texcoord1 = vary_texcoord0;
+	vary_texcoord1.x += lightnorm.x * 0.0125;
+	vary_texcoord1.y += lightnorm.z * 0.0125;
 
-    vary_texcoord2 = vary_texcoord0 * 16.;
-    vary_texcoord3 = vary_texcoord1 * 16.;
+	vary_texcoord2 = vary_texcoord0 * 16.;
+	vary_texcoord3 = vary_texcoord1 * 16.;
 
-    // Get relative position
+	// Get relative position
     vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
 
     altitude_blend_factor = clamp((rel_pos.y + 512.0) / max_y, 0.0, 1.0);
 
-    // Set altitude
+	// Set altitude
     if (rel_pos.y > 0)
-    {
+	{
         rel_pos *= (max_y / rel_pos.y);
-    }
+	}
     if (rel_pos.y < 0)
-    {
-        altitude_blend_factor = 0;  // SL-11589 Fix clouds drooping below horizon
+	{
+		altitude_blend_factor = 0; // SL-11589 Fix clouds drooping below horizon
         rel_pos *= (-32000. / rel_pos.y);
-    }
+	}
 
-    // Can normalize then
+	// Can normalize then
     vec3  rel_pos_norm = normalize(rel_pos);
     float rel_pos_len  = length(rel_pos);
 
-    // Initialize temp variables
-    vec4 sunlight = sunlight_color;
-    vec4 light_atten;
+	// Initialize temp variables
+	vec4 sunlight = sunlight_color;
+	vec4 light_atten;
 
-    // Sunlight attenuation effect (hue and brightness) due to atmosphere
-    // this is used later for sunlight modulation at various altitudes
+	// Sunlight attenuation effect (hue and brightness) due to atmosphere
+	// this is used later for sunlight modulation at various altitudes
     light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
 
-    // Calculate relative weights
+	// Calculate relative weights
     vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
     vec4 blue_weight   = blue_density / combined_haze;
     vec4 haze_weight   = haze_density / combined_haze;
@@ -130,63 +130,64 @@ void main()
     float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
     sunlight *= exp(-light_atten * off_axis);
 
-    // Distance
+	// Distance
     float density_dist = rel_pos_len * density_multiplier;
 
     // Transparency (-> combined_haze)
     // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
-    // compiler gets confused.
+	// compiler gets confused.
     combined_haze = exp(-combined_haze * density_dist);
 
-    // Compute haze glow
+	// Compute haze glow
     float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
     // haze_glow is 0 at the sun and increases away from sun
     haze_glow = max(haze_glow, .001);
-    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
     haze_glow *= glow.x;
-    // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+		// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
     haze_glow = pow(haze_glow, glow.z);
-    // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+		// glow.z should be negative, so we're doing a sort of (1 / "angle") function
 
     haze_glow *= sun_moon_glow_factor;
 
-    // Add "minimum anti-solar illumination"
+	// Add "minimum anti-solar illumination"
     // For sun, add to glow.  For moon, remove glow entirely. SL-13768
     haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
 
-    // Increase ambient when there are more clouds
-    vec4 tmpAmbient = ambient_color;
-    tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
+	// Increase ambient when there are more clouds
+	vec4 tmpAmbient = ambient_color;
+	tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; 
 
-    // Dim sunlight by cloud shadow percentage
-    sunlight *= (1. - cloud_shadow);
+	// Dim sunlight by cloud shadow percentage
+	sunlight *= (1. - cloud_shadow);
 
-    // Haze color below cloud
+	// Haze color below cloud
     vec4 additiveColorBelowCloud =
         (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
 
-    // CLOUDS
+	// CLOUDS
+    sunlight = sunlight_color;  // SL-14707 reset color -- Clouds are unusually dim in EEP
     off_axis = 1.0 / max(1e-6, lightnorm.y * 2.);
     sunlight *= exp(-light_atten * off_axis);
 
-    // Cloud color out
+	// Cloud color out
     vary_CloudColorSun     = (sunlight * haze_glow) * cloud_color;
-    vary_CloudColorAmbient = tmpAmbient * cloud_color;
-
-    // Attenuate cloud color by atmosphere
+	vary_CloudColorAmbient = tmpAmbient * cloud_color;
+	
+	// Attenuate cloud color by atmosphere
     combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds
     vary_CloudColorSun *= combined_haze;
     vary_CloudColorAmbient *= combined_haze;
     vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
 
-    // Make a nice cloud density based on the cloud_shadow value that was passed in.
-    vary_CloudDensity = 2. * (cloud_shadow - 0.25);
+	// Make a nice cloud density based on the cloud_shadow value that was passed in.
+	vary_CloudDensity = 2. * (cloud_shadow - 0.25);
 
-    // Combine these to minimize register use
-    vary_CloudColorAmbient += oHazeColorBelowCloud;
+	// Combine these to minimize register use
+	vary_CloudColorAmbient += oHazeColorBelowCloud;
 
-    // needs this to compile on mac
-    // vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
+	// needs this to compile on mac
+	//vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
 
-    // END CLOUDS
+	// END CLOUDS
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
index 6b36d00f97e504b57a33e0b9f7c31b3bccfbab89..9fcee04c3254d1dca6152348cda08107112f5118 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightShinyF.glsl
@@ -64,28 +64,27 @@ void main()
 #else
 	vec4 color = texture2D(diffuseMap, vary_texcoord0.xy);
 #endif
-
+	
 	color.rgb *= vertex_color.rgb;
 
 	// SL-9632 HUDs are affected by Atmosphere
 	if (no_atmo == 0)
 	{
-		vec3 sunlit;
-		vec3 amblit;
-		vec3 additive;
-		vec3 atten;
+	vec3 sunlit;
+	vec3 amblit;
+	vec3 additive;
+	vec3 atten;
 		vec3 pos = vary_position.xyz/vary_position.w;
 
-		calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false);
-
-		vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
-		float env_intensity = vertex_color.a;
+	calcAtmosphericVars(pos.xyz, vec3(0), 1.0, sunlit, amblit, additive, atten, false);
+	
+	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
+	float env_intensity = vertex_color.a;
 
 	//color.rgb = srgb_to_linear(color.rgb);
 		color.rgb = mix(color.rgb, envColor.rgb, env_intensity);
-
-		color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten);
-		color.rgb = fullbrightScaleSoftClip(color.rgb);
+	color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten);
+	color.rgb = fullbrightScaleSoftClip(color.rgb);
 	}
 
 /*
diff --git a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
index d29e8a9423ab73f3b058c0a323251cfe3499bd04..eb6e56e718cf3da79584bcc5792b972e25f2e2e8 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/impostorF.glsl
@@ -40,6 +40,8 @@ uniform sampler2D specularMap;
 
 VARYING vec2 vary_texcoord0;
 
+vec3 linear_to_srgb(vec3 c);
+
 void main() 
 {
 	vec4 col = texture2D(diffuseMap, vary_texcoord0.xy);
@@ -52,6 +54,7 @@ void main()
 	vec4 norm = texture2D(normalMap,   vary_texcoord0.xy);
 	vec4 spec = texture2D(specularMap, vary_texcoord0.xy);
 
+	col.rgb = linear_to_srgb(col.rgb);
 	frag_data[0] = vec4(col.rgb, 0.0);
 	frag_data[1] = spec;
 	frag_data[2] = vec4(norm.xy,0,0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
index 80d19102b6ce957d0e8defa72d93bbcd77617322..e1f7031af6ad587650665da70158588d8cf16da0 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/materialF.glsl
@@ -406,6 +406,8 @@ void main()
 
     vec3 light = vec3(0, 0, 0);
     
+    final_specular.rgb = srgb_to_linear(final_specular.rgb); // SL-14035
+
 #define LIGHT_LOOP(i) light.rgb += calcPointLightOrSpotLight(light_diffuse[i].rgb, npos, diffuse.rgb, final_specular, pos.xyz, norm.xyz, light_position[i], light_direction[i].xyz, light_attenuation[i].x, light_attenuation[i].y, light_attenuation[i].z, glare, light_attenuation[i].w );
 
     LIGHT_LOOP(1)
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
index 8c402fcb5466f54b229074e4498326d370085c67..09c47165ddcd7dd4e2e89ddc1e6051e609d37f14 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiPointLightF.glsl
@@ -73,9 +73,7 @@ void main()
     vec3 norm = getNorm(frag.xy);
 
     vec4 spec = texture2DRect(specularRect, frag.xy);
-    spec.rgb  = srgb_to_linear(spec.rgb);
     vec3 diff = texture2DRect(diffuseRect, frag.xy).rgb;
-    diff.rgb  = srgb_to_linear(diff.rgb);
 
     float noise = texture2D(noiseMap, frag.xy / 128.0).b;
     vec3  npos  = normalize(-pos);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
index 9bba45bc4ea1f7163724d264430efcd1d3f19c20..ec3fb9c54316dc16e398142484eb338bb58d1246 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/multiSpotLightF.glsl
@@ -182,10 +182,6 @@ void main()
 		
 		
 	vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-    // SL-12005 Projector light pops as we get closer, more objectionable than being in wrong color space.
-    //          We can't switch to linear here unless we do it everywhere*
-	// *gbuffer is sRGB, convert to linear whenever sampling from it
-    diff_tex.rgb = srgb_to_linear(diff_tex.rgb);
 
 	vec3 dlit = vec3(0, 0, 0);
 	
diff --git a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
index d805c9ea48a97436011da003cfcf343a34883595..18616a9bb36c8bc6e6019304f164bf66f6d3f0dd 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/pointLightF.glsl
@@ -90,7 +90,6 @@ void main()
     float noise = texture2D(noiseMap, frag.xy/128.0).b;
     
     vec3 col = texture2DRect(diffuseRect, frag.xy).rgb;
-    col.rgb = srgb_to_linear(col.rgb);
 
     float fa = falloff+1.0;
     float dist_atten = clamp(1.0-(dist-1.0*(1.0-fa))/fa, 0.0, 1.0);
@@ -127,7 +126,7 @@ void main()
     {
         discard;
     }
-//col.rgb = vec3(0);        
+
     frag_color.rgb = col;   
     frag_color.a = 0.0;
 }
diff --git a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
index f80f1a985a31a9ea796e2d47d3fef08939831e03..7f2c603f87a7f867cfebc2377bdd61a2a409fc95 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/softenLightF.glsl
@@ -90,7 +90,7 @@ void main()
     vec4 diffuse = texture2DRect(diffuseRect, tc);
 
     //convert to gamma space
-    //diffuse.rgb = linear_to_srgb(diffuse.rgb);
+    diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14035
 
     vec4 spec = texture2DRect(specularRect, vary_fragcoord.xy);
     vec3 color = vec3(0);
diff --git a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
index 454af2a9bcee478fbe107402a564d52a32a5328c..b2fa5d8a2567edd65462194e2fbc94d637cd8496 100644
--- a/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
+++ b/indra/newview/app_settings/shaders/class1/deferred/sunDiscF.glsl
@@ -49,10 +49,6 @@ void main()
     vec4 sunDiscB = texture2D(altDiffuseMap, vary_texcoord0.xy);
     vec4 c     = mix(sunDiscA, sunDiscB, blend_factor);
 
-    c.rgb = srgb_to_linear(c.rgb);
-    c.rgb = clamp(c.rgb, vec3(0), vec3(1));
-    c.rgb = pow(c.rgb, vec3(0.7f));
-
     //c.rgb = fullbrightAtmosTransport(c.rgb);
     c.rgb = fullbrightScaleSoftClip(c.rgb);
 
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
index 6f7e777d23f6e16abc6324afe0cbbc0b1ec35054..5e966293c6fed83e1332dcaa5647ec8d99c4d8fe 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightShinyF.glsl
@@ -48,15 +48,15 @@ void fullbright_shiny_lighting()
 {
 	vec4 color = diffuseLookup(vary_texcoord0.xy);
 	color.rgb *= vertex_color.rgb;
-
+	
 	// SL-9632 HUDs are affected by Atmosphere
 	if (no_atmo == 0)
 	{
-		vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;
-		color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
+	vec3 envColor = textureCube(environmentMap, vary_texcoord1.xyz).rgb;	
+	color.rgb = mix(color.rgb, envColor.rgb, vertex_color.a*0.75); // MAGIC NUMBER SL-12574; ALM: Off, Quality > Low
 
-		color.rgb = fullbrightShinyAtmosTransport(color.rgb);
-		color.rgb = fullbrightScaleSoftClip(color.rgb);
+	color.rgb = fullbrightShinyAtmosTransport(color.rgb);
+	color.rgb = fullbrightScaleSoftClip(color.rgb);
 	}
 /*
 	// NOTE: HUD objects will be full bright. Uncomment if you want "some" environment lighting effecting these HUD objects.
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
index a0699affbf078c73ad0d3c7b26817cc9b379bddf..3b4d358cfab8fad00916f07ce815a8f8fcde884d 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsF.glsl
@@ -1,30 +1,37 @@
-/** 
+/**
  * @file class1\windlight\atmosphericVarsF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2007, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
-vec3 getPositionEye()
-{
-	return vec3(0,0,0);
-}
+VARYING vec3 vary_AdditiveColor;
+VARYING vec3 vary_AtmosAttenuation;
+
+vec3 getAmblitColor() { return vec3(0, 0, 0); }
+
+vec3 getAdditiveColor() { return vary_AdditiveColor; }
+
+vec3 getAtmosAttenuation() { return vec3(vary_AtmosAttenuation); }
+
+vec3 getSunlitColor() { return vec3(0, 0, 0); }
+
+vec3 getPositionEye() { return vec3(0, 0, 0); }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
index bd1d150fc81956fdcb110ede0ccafa552be0f8e9..1fea2c362898f6b74b22461ca5f736e8b2fa58a7 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsV.glsl
@@ -1,36 +1,56 @@
-/** 
+/**
  * @file class1\windlight\atmosphericVarsV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2007, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
+VARYING vec3 vary_AdditiveColor;
+VARYING vec3 vary_AtmosAttenuation;
 
-vec3 getPositionEye()
+vec3 additive_color;
+vec3 atmos_attenuation;
+vec3 sunlit_color;
+vec3 amblit_color;
+vec3 position_eye;
+
+vec3 getSunlitColor() { return sunlit_color; }
+void setSunlitColor(vec3 v) { sunlit_color = v; }
+
+vec3 getAdditiveColor() { return additive_color; }
+void setAdditiveColor(vec3 v)
 {
-	return vec3(0,0,0);
+    additive_color     = v;
+    vary_AdditiveColor = v;
 }
 
-void setPositionEye(vec3 v)
+vec3 getAmblitColor() { return amblit_color; }
+void setAmblitColor(vec3 v) { amblit_color = v; }
+
+vec3 getAtmosAttenuation() { return atmos_attenuation; }
+void setAtmosAttenuation(vec3 v)
 {
-	
+    atmos_attenuation     = v;
+    vary_AtmosAttenuation = v;
 }
+
+vec3 getPositionEye() { return position_eye; }
+void setPositionEye(vec3 v) { position_eye = v; }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
index 5dc086ab1e05d38241db5d7bebe8711a603e05cb..f83434b7ec907a6d69b6b28bad2c5066846eae55 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterF.glsl
@@ -1,33 +1,38 @@
-/** 
+/**
  * @file class1\windlight\atmosphericVarsWaterF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2007, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
 
 VARYING vec3 vary_PositionEye;
+VARYING vec3 vary_AdditiveColor;
+VARYING vec3 vary_AtmosAttenuation;
+
+vec3 getSunlitColor() { return vec3(0, 0, 0); }
+
+vec3 getAmblitColor() { return vec3(0, 0, 0); }
+
+vec3 getAdditiveColor() { return vary_AdditiveColor; }
 
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
+vec3 getAtmosAttenuation() { return vary_AtmosAttenuation; }
 
+vec3 getPositionEye() { return vary_PositionEye; }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
index e59eca265a80d85810e27f2c4e5e6475e77d1607..65d117677787019eec5c6cae8392b3c7230be47a 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/atmosphericsVarsWaterV.glsl
@@ -1,37 +1,51 @@
-/** 
+/**
  * @file class1\windlight\atmosphericVarsWaterV.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2007, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
- 
- 
+
 VARYING vec3 vary_PositionEye;
+VARYING vec3 vary_AdditiveColor;
+VARYING vec3 vary_AtmosAttenuation;
 
-vec3 getPositionEye()
-{
-	return vary_PositionEye;
-}
+vec3 atmos_attenuation;
+vec3 sunlit_color;
+vec3 amblit_color;
+
+vec3 getSunlitColor() { return sunlit_color; }
+void setSunlitColor(vec3 v) { sunlit_color = v; }
+
+vec3 getAmblitColor() { return amblit_color; }
+void setAmblitColor(vec3 v) { amblit_color = v; }
 
-void setPositionEye(vec3 v)
+vec3 getAdditiveColor() { return vary_AdditiveColor; }
+void setAdditiveColor(vec3 v) { vary_AdditiveColor = v; }
+
+vec3 getAtmosAttenuation() { return atmos_attenuation; }
+void setAtmosAttenuation(vec3 v)
 {
-	vary_PositionEye = v;
+    atmos_attenuation     = v;
+    vary_AtmosAttenuation = v;
 }
+
+vec3 getPositionEye() { return vary_PositionEye; }
+void setPositionEye(vec3 v) { vary_PositionEye = v; }
diff --git a/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl b/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
index b9ae7a02262b01cc62aa485f142168418cc10aa9..5a41dc644a55fa321bcfc964fcf70d48280c7160 100644
--- a/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
+++ b/indra/newview/app_settings/shaders/class1/windlight/sunDiscF.glsl
@@ -51,7 +51,6 @@ void main()
 // SL-9806 stars poke through
 //    c.a *= sun_fade;
 
-    c.rgb = pow(c.rgb, vec3(0.7f));
     c.rgb = fullbrightAtmosTransport(c.rgb);
     c.rgb = fullbrightScaleSoftClip(c.rgb);
     frag_color = c;
diff --git a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
index 5d7a28c359284de7a8836e313c7c987123e85f4c..1b7a1cc6ecc70a0874acded92d8c7b1ba0446840 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/multiSpotLightF.glsl
@@ -191,10 +191,6 @@ void main()
     float da = dot(norm, lv);
         
     vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
-    // SL-12005 Projector light pops as we get closer, more objectionable than being in wrong color space.
-    //          We can't switch to linear here unless we do it everywhere*
-    // *gbuffer IS sRGB, convert to linear since this shader outputs linear
-    diff_tex.rgb = srgb_to_linear(diff_tex.rgb);
  
     vec4 spec = texture2DRect(specularRect, frag.xy);
 
diff --git a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
index 1485c515a4d27863e5a4f64a26accd235de57933..6841a8194f6c27ebe4f84c48e82f9608d6e9e84d 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/skyF.glsl
@@ -73,7 +73,21 @@ uniform float ice_level;
 
 vec3 rainbow(float d)
 {
-    d         = clamp(d, -1.0, 0.0);
+    // d is the dot product of view and sun directions, so ranging -1.0..1.0
+    // 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec
+    // Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175.
+
+    // SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted.
+    // Rather than replace the texture, we mirror and translate the y tc to keep the colors within the
+    // interesting range, but in reversed order:  i.e. d = (1 - d) - 1.575
+    d = clamp(-0.575 - d, 0.0, 1.0);
+
+    // With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
+    // So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
+    // space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
+    float interior_coord = max(0.0, d - 0.25) * 4.2857;
+    d = clamp(d, 0.0, 0.25) + interior_coord;
+
     float rad = (droplet_radius - 5.0f) / 1024.0f;
     return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
 }
diff --git a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
index f4db53e0b7816815fff8323758940e17283a2322..7700d16007a4a68d5cf37665c5bd3e9a5a479d9c 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/softenLightF.glsl
@@ -87,8 +87,9 @@ void main()
     float light_gamma = 1.0 / 1.3;
     da                = pow(da, light_gamma);
 
-    vec4 diffuse = texture2DRect(diffuseRect, tc);
-    vec4 spec    = texture2DRect(specularRect, vary_fragcoord.xy);
+    vec4 diffuse     = texture2DRect(diffuseRect, tc);
+         diffuse.rgb = linear_to_srgb(diffuse.rgb); // SL-14025
+    vec4 spec        = texture2DRect(specularRect, vary_fragcoord.xy);
 
     vec2 scol_ambocc = texture2DRect(lightMap, vary_fragcoord.xy).rg;
     scol_ambocc      = pow(scol_ambocc, vec2(light_gamma));
diff --git a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
index 5ab0b5c5b4d9ff0ccca3c74d77eab178f4dd52b5..774f537821c8ee6692cbc10eae5f6beb2a5daad4 100644
--- a/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
+++ b/indra/newview/app_settings/shaders/class2/deferred/spotLightF.glsl
@@ -189,7 +189,7 @@ void main()
 	lv = normalize(lv);
 	float da = dot(norm, lv);
 		
-	vec3 diff_tex = srgb_to_linear(texture2DRect(diffuseRect, frag.xy).rgb);
+	vec3 diff_tex = texture2DRect(diffuseRect, frag.xy).rgb;
 	vec4 spec = texture2DRect(specularRect, frag.xy);
 	vec3 dlit = vec3(0, 0, 0);
 
diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
index d758f85d713eafb34643c126c6212f17ef6fa136..07733bda18b43fdbd162db6d8be2df87962bfe14 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsVarsF.glsl
@@ -1,5 +1,5 @@
 /** 
- * @file class2\wl\atmosphericVars.glsl
+ * @file class2\wl\atmosphericVarsF.glsl
  *
  * $LicenseInfo:firstyear=2007&license=viewerlgpl$
  * Second Life Viewer Source Code
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
index 75bf8730df46e3efcdff262cc488f1518a564a2e..fa928d993ef4fea39635cdecb2551200a155147a 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsF.glsl
@@ -26,9 +26,9 @@
 /*[EXTRA_CODE_HERE]*/ 
 
 #ifdef DEFINE_GL_FRAGCOLOR
-out vec4 frag_data[3];
+out vec4 frag_color;
 #else
-#define frag_data gl_FragData
+#define frag_color gl_FragColor
 #endif
 
 /////////////////////////////////////////////////////////////////////////
@@ -126,8 +126,6 @@ void main()
     color.rgb = scaleSoftClip(color.rgb);
 
     /// Gamma correct for WL (soft clip effect).
-    frag_data[0] = vec4(color.rgb, alpha1);
-    frag_data[1] = vec4(0.0,0.0,0.0,0.0);
-    frag_data[2] = vec4(0,0,0,1);
+    frag_color = vec4(color.rgb, alpha1);
 }
 
diff --git a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
index 1f881eb44b5fcb4f94b1e72ddd4136dac7d9bfc1..97ffa9feef9418f77dc4843a95a82471f0a6bee1 100644
--- a/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
+++ b/indra/newview/app_settings/shaders/class2/windlight/cloudsV.glsl
@@ -1,24 +1,24 @@
-/**
+/** 
  * @file class2\wl\cloudsV.glsl
  *
  * $LicenseInfo:firstyear=2005&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2005, Linden Research, Inc.
- *
+ * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- *
+ * 
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- *
+ * 
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- *
+ * 
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -33,26 +33,26 @@ ATTRIBUTE vec2 texcoord0;
 ///////////////////////////////////////////////////////////////////////////////
 
 // Output parameters
-VARYING vec4  vary_CloudColorSun;
-VARYING vec4  vary_CloudColorAmbient;
+VARYING vec4 vary_CloudColorSun;
+VARYING vec4 vary_CloudColorAmbient;
 VARYING float vary_CloudDensity;
 
-VARYING vec2  vary_texcoord0;
-VARYING vec2  vary_texcoord1;
-VARYING vec2  vary_texcoord2;
-VARYING vec2  vary_texcoord3;
+VARYING vec2 vary_texcoord0;
+VARYING vec2 vary_texcoord1;
+VARYING vec2 vary_texcoord2;
+VARYING vec2 vary_texcoord3;
 VARYING float altitude_blend_factor;
 
 // Inputs
 uniform vec3 camPosLocal;
 
-uniform vec4  lightnorm;
-uniform vec4  sunlight_color;
-uniform vec4  moonlight_color;
-uniform int   sun_up_factor;
-uniform vec4  ambient_color;
-uniform vec4  blue_horizon;
-uniform vec4  blue_density;
+uniform vec4 lightnorm;
+uniform vec4 sunlight_color;
+uniform vec4 moonlight_color;
+uniform int sun_up_factor;
+uniform vec4 ambient_color;
+uniform vec4 blue_horizon;
+uniform vec4 blue_density;
 uniform float haze_horizon;
 uniform float haze_density;
 
@@ -60,7 +60,7 @@ uniform float cloud_shadow;
 uniform float density_multiplier;
 uniform float max_y;
 
-uniform vec4  glow;
+uniform vec4 glow;
 uniform float sun_moon_glow_factor;
 
 uniform vec4 cloud_color;
@@ -75,8 +75,8 @@ uniform float cloud_scale;
 //       indra\newview\llsettingsvo.cpp
 void main()
 {
-    // World / view / projection
-    gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
+	// World / view / projection
+	gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0);
 
     // Texture coords
     // SL-13084 EEP added support for custom cloud textures -- flip them horizontally to match the preview of Clouds > Cloud Scroll
@@ -93,7 +93,7 @@ void main()
     vary_texcoord2 = vary_texcoord0 * 16.;
     vary_texcoord3 = vary_texcoord1 * 16.;
 
-    // Get relative position
+	// Get relative position
     vec3 rel_pos = position.xyz - camPosLocal.xyz + vec3(0, 50, 0);
 
     // fade clouds beyond a certain point so the bottom of the sky dome doesn't look silly at high altitude
@@ -101,27 +101,27 @@ void main()
 
     // Adj position vector to clamp altitude
     if (rel_pos.y > 0.)
-    {
+	{
         rel_pos *= (max_y / rel_pos.y);
-    }
+	}
     if (rel_pos.y < 0.)
-    {
+	{
         rel_pos *= (-32000. / rel_pos.y);
-    }
+	}
 
-    // Can normalize then
+	// Can normalize then
     vec3  rel_pos_norm = normalize(rel_pos);
     float rel_pos_len  = length(rel_pos);
 
-    // Initialize temp variables
-    vec4 sunlight = sunlight_color;
-    vec4 light_atten;
+	// Initialize temp variables
+	vec4 sunlight = sunlight_color;
+	vec4 light_atten;
 
-    // Sunlight attenuation effect (hue and brightness) due to atmosphere
-    // this is used later for sunlight modulation at various altitudes
+	// Sunlight attenuation effect (hue and brightness) due to atmosphere
+	// this is used later for sunlight modulation at various altitudes
     light_atten = (blue_density + vec4(haze_density * 0.25)) * (density_multiplier * max_y);
 
-    // Calculate relative weights
+	// Calculate relative weights
     vec4 combined_haze = abs(blue_density) + vec4(abs(haze_density));
     vec4 blue_weight   = blue_density / combined_haze;
     vec4 haze_weight   = haze_density / combined_haze;
@@ -130,63 +130,64 @@ void main()
     float off_axis = 1.0 / max(1e-6, max(0., rel_pos_norm.y) + lightnorm.y);
     sunlight *= exp(-light_atten * off_axis);
 
-    // Distance
+	// Distance
     float density_dist = rel_pos_len * density_multiplier;
 
     // Transparency (-> combined_haze)
     // ATI Bugfix -- can't store combined_haze*density_dist in a variable because the ati
-    // compiler gets confused.
+	// compiler gets confused.
     combined_haze = exp(-combined_haze * density_dist);
 
-    // Compute haze glow
+	// Compute haze glow
     float haze_glow = 1.0 - dot(rel_pos_norm, lightnorm.xyz);
     // haze_glow is 0 at the sun and increases away from sun
     haze_glow = max(haze_glow, .001);
-    // Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
+		// Set a minimum "angle" (smaller glow.y allows tighter, brighter hotspot)
     haze_glow *= glow.x;
-    // Higher glow.x gives dimmer glow (because next step is 1 / "angle")
+		// Higher glow.x gives dimmer glow (because next step is 1 / "angle")
     haze_glow = pow(haze_glow, glow.z);
-    // glow.z should be negative, so we're doing a sort of (1 / "angle") function
+		// glow.z should be negative, so we're doing a sort of (1 / "angle") function
 
     haze_glow *= sun_moon_glow_factor;
 
-    // Add "minimum anti-solar illumination"
+	// Add "minimum anti-solar illumination"
     // For sun, add to glow.  For moon, remove glow entirely. SL-13768
     haze_glow = (sun_moon_glow_factor < 1.0) ? 0.0 : (haze_glow + 0.25);
 
-    // Increase ambient when there are more clouds
-    vec4 tmpAmbient = ambient_color;
-    tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5;
+	// Increase ambient when there are more clouds
+	vec4 tmpAmbient = ambient_color;
+	tmpAmbient += (1. - tmpAmbient) * cloud_shadow * 0.5; 
 
-    // Dim sunlight by cloud shadow percentage
-    sunlight *= (1. - cloud_shadow);
+	// Dim sunlight by cloud shadow percentage
+	sunlight *= (1. - cloud_shadow);
 
-    // Haze color below cloud
+	// Haze color below cloud
     vec4 additiveColorBelowCloud =
         (blue_horizon * blue_weight * (sunlight + tmpAmbient) + (haze_horizon * haze_weight) * (sunlight * haze_glow + tmpAmbient));
 
-    // CLOUDS
+	// CLOUDS
+    sunlight = sunlight_color;  // SL-14707 reset color -- Clouds are unusually dim in EEP
     off_axis = 1.0 / max(1e-6, lightnorm.y * 2.);
     sunlight *= exp(-light_atten * off_axis);
 
-    // Cloud color out
+	// Cloud color out
     vary_CloudColorSun     = (sunlight * haze_glow) * cloud_color;
-    vary_CloudColorAmbient = tmpAmbient * cloud_color;
-
-    // Attenuate cloud color by atmosphere
+	vary_CloudColorAmbient = tmpAmbient * cloud_color;
+	
+	// Attenuate cloud color by atmosphere
     combined_haze = sqrt(combined_haze);  // less atmos opacity (more transparency) below clouds
     vary_CloudColorSun *= combined_haze;
     vary_CloudColorAmbient *= combined_haze;
     vec4 oHazeColorBelowCloud = additiveColorBelowCloud * (1. - combined_haze);
 
-    // Make a nice cloud density based on the cloud_shadow value that was passed in.
-    vary_CloudDensity = 2. * (cloud_shadow - 0.25);
+	// Make a nice cloud density based on the cloud_shadow value that was passed in.
+	vary_CloudDensity = 2. * (cloud_shadow - 0.25);
 
-    // Combine these to minimize register use
-    vary_CloudColorAmbient += oHazeColorBelowCloud;
+	// Combine these to minimize register use
+	vary_CloudColorAmbient += oHazeColorBelowCloud;
 
-    // needs this to compile on mac
-    // vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
+	// needs this to compile on mac
+	//vary_AtmosAttenuation = vec3(0.0,0.0,0.0);
 
-    // END CLOUDS
+	// END CLOUDS
 }
diff --git a/indra/newview/app_settings/shaders/class3/deferred/lightUtil.glsl b/indra/newview/app_settings/shaders/class3/deferred/lightUtil.glsl
deleted file mode 100644
index 8bb3f07fc6450457928e4123bf57525fb70a9d9d..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/shaders/class3/deferred/lightUtil.glsl
+++ /dev/null
@@ -1,117 +0,0 @@
-/** 
- * @file lightInfo.glsl
- *
- * $LicenseInfo:firstyear=2007&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2007, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-struct DirectionalLightInfo
-{
-    vec4 pos;
-    float depth;
-    vec4 normal;
-    vec3 normalizedLightDirection;
-    vec3 normalizedToLight;
-    float lightIntensity;
-    vec3 lightDiffuseColor;
-    float specExponent;
-    float shadow;
-};
-
-struct SpotLightInfo
-{
-    vec4 pos;
-    float depth;
-    vec4 normal;
-    vec3 normalizedLightDirection;
-    vec3 normalizedToLight;
-    float lightIntensity;
-    float attenuation;
-    float distanceToLight;
-    vec3 lightDiffuseColor;
-    float innerHalfAngleCos;
-    float outerHalfAngleCos;
-    float spotExponent;
-    float specExponent;
-    float shadow;
-};
-
-struct PointLightInfo
-{
-    vec4 pos;
-    float depth;
-    vec4 normal;
-    vec3 normalizedToLight;
-    float lightIntensity;
-    float attenuation;
-    float distanceToLight;
-    vec3 lightDiffuseColor;
-    float lightRadius;
-    float specExponent;
-    vec3 worldspaceLightDirection;
-    float shadow;
-};
-
-float attenuate(float attenuationSelection, float distanceToLight)
-{
-// LLRENDER_REVIEW
-// sh/could eventually consume attenuation func defined in texture
-    return (attenuationSelection == 0.0f) ? 1.0f : // none
-           (attenuationSelection <  1.0f) ? (1.0f / distanceToLight) : // linear atten 
-           (attenuationSelection <  2.0f) ? (1.0f / (distanceToLight*distanceToLight)) // quadratic atten
-										  : (1.0f / (distanceToLight*distanceToLight*distanceToLight));	// cubic atten    
-}
-
-
-vec3 lightDirectional(struct DirectionalLightInfo dli)
-{
-    float lightIntensity = dli.lightIntensity;
-	lightIntensity *= dot(dli.normal.xyz, dli.normalizedLightDirection);
-    //lightIntensity *= directionalShadowSample(vec4(dli.pos.xyz, 1.0f), dli.depth, dli.directionalShadowMap, dli.directionalShadowMatrix);
-	return lightIntensity * dli.lightDiffuseColor;
-}
-
-
-vec3 lightSpot(struct SpotLightInfo sli)    
-{
-	float penumbraRange = (sli.outerHalfAngleCos - sli.innerHalfAngleCos);
-    float coneAngleCos = max(dot(sli.normalizedLightDirection, sli.normalizedToLight), 0.0);
-	float coneAttenFactor = (coneAngleCos <= sli.outerHalfAngleCos) ? 1.0f : pow(smoothstep(1,0, sli.outerHalfAngleCos / penumbraRange), sli.spotExponent);
-    float distanceAttenuation = attenuate(sli.attenuation, sli.distanceToLight);
-    float lightIntensity = sli.lightIntensity;
-    lightIntensity *= distanceAttenuation;
-	lightIntensity *= max(dot(sli.normal.xyz, sli.normalizedLightDirection), 0.0);
-	lightIntensity *= coneAttenFactor;
-    lightIntensity *= sli.shadow;
-	return lightIntensity * sli.lightDiffuseColor;
-}
-
-vec3 lightPoint(struct PointLightInfo pli)
-{
-    float padRadius = pli.lightRadius * 0.1; // distance for which to perform smoothed dropoff past light radius
-	float distanceAttenuation =	attenuate(pli.attenuation, pli.distanceToLight);
-    float lightIntensity = pli.lightIntensity;
-    lightIntensity*= distanceAttenuation;    
-	lightIntensity *= clamp((padRadius - pli.distanceToLight + pli.lightRadius) / padRadius, 0.0, 1.0);
-    lightIntensity *= pli.shadow;
-    lightIntensity *= max(dot(pli.normal.xyz, pli.normalizedToLight), 0.0);
-	return lightIntensity * pli.lightDiffuseColor;
-}
diff --git a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
index 6de01cb667c3e6bc9f55a1d96493a5d84ea51420..a0b082ed7ccb7f5e44931f7fbd9410392e903ad2 100644
--- a/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
+++ b/indra/newview/app_settings/shaders/class3/deferred/skyF.glsl
@@ -56,8 +56,23 @@ vec3 GetSkyLuminanceToPoint(vec3 camPos, vec3 pos, float shadow_length, vec3 dir
 vec3 ColorFromRadiance(vec3 radiance);
 vec3 rainbow(float d)
 {
-   float rad = (droplet_radius - 5.0f) / 1024.0f;
-   return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
+    // d is the dot product of view and sun directions, so ranging -1.0..1.0
+    // 'interesting' values of d are the range -0.75..-0.825, when view is nearly opposite of sun vec
+    // Rainbox texture mode is GL_REPEAT, so tc of -.75 is equiv to 0.25, -0.825 equiv to 0.175.
+
+    // SL-13629 Rainbow texture has colors within the correct .175...250 range, but order is inverted.
+    // Rather than replace the texture, we mirror and translate the y tc to keep the colors within the
+    // interesting range, but in reversed order:  i.e. d = (1 - d) - 1.575
+    d = clamp(-0.575 - d, 0.0, 1.0);
+
+    // With the colors in the lower 1/4 of the texture, inverting the coords leaves most of it inaccessible.
+    // So, we can stretch the texcoord above the colors (ie > 0.25) to fill the entire remaining coordinate
+    // space. This improves gradation, reduces banding within the rainbow interior. (1-0.25) / (0.425/0.25) = 4.2857
+    float interior_coord = max(0.0, d - 0.25) * 4.2857;
+    d = clamp(d, 0.0, 0.25) + interior_coord;
+
+    float rad = (droplet_radius - 5.0f) / 1024.0f;
+    return pow(texture2D(rainbow_map, vec2(rad, d)).rgb, vec3(1.8)) * moisture_level;
 }
 
 vec3 halo22(float d)
diff --git a/indra/newview/icons/release/secondlife.icns b/indra/newview/icons/release/secondlife.icns
index e15e34140dd43a66ade1e71feff9455da24f560f..a30b51b67aa15e409291f059f6a82007351e2f4b 100644
Binary files a/indra/newview/icons/release/secondlife.icns and b/indra/newview/icons/release/secondlife.icns differ
diff --git a/indra/newview/icons/release/secondlife.ico b/indra/newview/icons/release/secondlife.ico
index 28bf1e766456b441605e090568cd042709a2bd7b..93d4fa54bae9e26c236cc432dceb5a27467031cc 100644
Binary files a/indra/newview/icons/release/secondlife.ico and b/indra/newview/icons/release/secondlife.ico differ
diff --git a/indra/newview/icons/release/secondlife_128.png b/indra/newview/icons/release/secondlife_128.png
index 4c9544f49837be4dec00a426239a9191f9612f92..2f21c1c7fc80466fd4ee0075ca8ad2a5f0418126 100644
Binary files a/indra/newview/icons/release/secondlife_128.png and b/indra/newview/icons/release/secondlife_128.png differ
diff --git a/indra/newview/icons/release/secondlife_16.png b/indra/newview/icons/release/secondlife_16.png
index bb3168b8be416de728cf281814b56592a030d064..68f14273093133861dee474628c6845ada0f4278 100644
Binary files a/indra/newview/icons/release/secondlife_16.png and b/indra/newview/icons/release/secondlife_16.png differ
diff --git a/indra/newview/icons/release/secondlife_256.BMP b/indra/newview/icons/release/secondlife_256.BMP
index 74deedd7d31a7f01587ef926889abf5f258e6a46..dba26368031df55ba84d2c07a7e955c748e031d9 100644
Binary files a/indra/newview/icons/release/secondlife_256.BMP and b/indra/newview/icons/release/secondlife_256.BMP differ
diff --git a/indra/newview/icons/release/secondlife_256.png b/indra/newview/icons/release/secondlife_256.png
index bece338a909ad32f782943ef7441fee930809191..8f324910e7c3dfa803b74aa412db2e6684216648 100644
Binary files a/indra/newview/icons/release/secondlife_256.png and b/indra/newview/icons/release/secondlife_256.png differ
diff --git a/indra/newview/icons/release/secondlife_32.png b/indra/newview/icons/release/secondlife_32.png
index 736359c1475427ce71ef5e9fd9baa2de433fdf00..2b7cdef03d57dcd57eff53b8c88a4187d8d67735 100644
Binary files a/indra/newview/icons/release/secondlife_32.png and b/indra/newview/icons/release/secondlife_32.png differ
diff --git a/indra/newview/icons/release/secondlife_48.png b/indra/newview/icons/release/secondlife_48.png
index 07d39ae5854c4d6d9a67b85d21abed1c4d2353bb..c2ef372dd7c2eb62582653432585487c4bfaab5a 100644
Binary files a/indra/newview/icons/release/secondlife_48.png and b/indra/newview/icons/release/secondlife_48.png differ
diff --git a/indra/newview/icons/release/secondlife_512.png b/indra/newview/icons/release/secondlife_512.png
index 53d1643f45b8f276f661798ee7acd87871cbd7d3..d8a0c2924d1adb68f97c79f28e9e337d43d5ce80 100644
Binary files a/indra/newview/icons/release/secondlife_512.png and b/indra/newview/icons/release/secondlife_512.png differ
diff --git a/indra/newview/installers/windows/install_icon.BMP b/indra/newview/installers/windows/install_icon.BMP
index 09df573870e6aac8b5ea331fd143fd0ae4cd095e..dba26368031df55ba84d2c07a7e955c748e031d9 100644
Binary files a/indra/newview/installers/windows/install_icon.BMP and b/indra/newview/installers/windows/install_icon.BMP differ
diff --git a/indra/newview/installers/windows/install_icon.ico b/indra/newview/installers/windows/install_icon.ico
index efe6c4f323d216cdced45fdcf0d67ac217440841..93d4fa54bae9e26c236cc432dceb5a27467031cc 100644
Binary files a/indra/newview/installers/windows/install_icon.ico and b/indra/newview/installers/windows/install_icon.ico differ
diff --git a/indra/newview/installers/windows/uninstall_icon.BMP b/indra/newview/installers/windows/uninstall_icon.BMP
index 562b56676a9a87037f773cdd4ce2f2f1ba66b9d3..dba26368031df55ba84d2c07a7e955c748e031d9 100644
Binary files a/indra/newview/installers/windows/uninstall_icon.BMP and b/indra/newview/installers/windows/uninstall_icon.BMP differ
diff --git a/indra/newview/installers/windows/uninstall_icon.ico b/indra/newview/installers/windows/uninstall_icon.ico
index 05e154686092d89fec551319a8ab9ffd906cdd44..93d4fa54bae9e26c236cc432dceb5a27467031cc 100644
Binary files a/indra/newview/installers/windows/uninstall_icon.ico and b/indra/newview/installers/windows/uninstall_icon.ico differ
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 1209b8c041261a26de0556c751396d3869ec0fb1..0c8a160e60f8b937fd20c1690f15b1d9f9000369 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -405,6 +405,7 @@ LLAgent::LLAgent() :
 	mTeleportFinishedSlot(),
 	mTeleportFailedSlot(),
 	mIsMaturityRatingChangingDuringTeleport(false),
+	mTPNeedsNeabyChatSeparator(false),
 	mMaturityRatingChange(0U),
 	mIsDoSendMaturityPreferenceToServer(false),
 	mMaturityPreferenceRequestId(0U),
@@ -4036,6 +4037,7 @@ void LLAgent::clearTeleportRequest()
         LLVoiceClient::getInstance()->setHidden(FALSE);
     }
 	mTeleportRequest.reset();
+    mTPNeedsNeabyChatSeparator = false;
 }
 
 void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
@@ -4044,6 +4046,12 @@ void LLAgent::setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange)
 	mMaturityRatingChange = pMaturityRatingChange;
 }
 
+void LLAgent::sheduleTeleportIM()
+{
+    // is supposed to be called during teleport so we are still waiting for parcel
+    mTPNeedsNeabyChatSeparator = true;
+}
+
 bool LLAgent::hasPendingTeleportRequest()
 {
 	return ((mTeleportRequest != NULL) &&
@@ -4091,6 +4099,12 @@ void LLAgent::startTeleportRequest()
 void LLAgent::handleTeleportFinished()
 {
     LL_INFOS("Teleport") << "Agent handling teleport finished." << LL_ENDL;
+    if (mTPNeedsNeabyChatSeparator)
+    {
+        // parcel is ready at this point
+        addTPNearbyChatSeparator();
+        mTPNeedsNeabyChatSeparator = false;
+    }
 	clearTeleportRequest();
     mTeleportCanceled.reset();
 	if (mIsMaturityRatingChangingDuringTeleport)
@@ -4153,6 +4167,44 @@ void LLAgent::handleTeleportFailed()
 		LLNotificationsUtil::add("PreferredMaturityChanged", args);
 		mIsMaturityRatingChangingDuringTeleport = false;
 	}
+
+    mTPNeedsNeabyChatSeparator = false;
+}
+
+/*static*/
+void LLAgent::addTPNearbyChatSeparator()
+{
+    LLViewerRegion* agent_region = gAgent.getRegion();
+    LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
+    if (!agent_region || !agent_parcel)
+    {
+        return;
+    }
+
+    LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+    if (nearby_chat)
+    {
+        std::string location_name;
+        LLAgentUI::ELocationFormat format = LLAgentUI::LOCATION_FORMAT_NO_MATURITY;
+
+        // Might be better to provide slurl to chat
+        if (!LLAgentUI::buildLocationString(location_name, format))
+        {
+            location_name = "Teleport to new region"; // Shouldn't happen
+        }
+
+        LLChat chat;
+        chat.mFromName = location_name;
+        chat.mMuted = FALSE;
+        chat.mFromID = LLUUID::null;
+        chat.mSourceType = CHAT_SOURCE_TELEPORT;
+        chat.mChatStyle = CHAT_STYLE_TELEPORT_SEP;
+        chat.mText = "";
+
+        LLSD args;
+        args["do_not_log"] = TRUE;
+        nearby_chat->addMessage(chat, true, args);
+    }
 }
 
 /*static*/
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 72d5f31f4d9b75728aab41b100b25f60bb78681d..972ed81f243ddb875f6856528aba5b2577b55644 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -668,6 +668,7 @@ class LLAgent : public LLOldEvents::LLObservable
 	void            restartFailedTeleportRequest();
 	void            clearTeleportRequest();
 	void            setMaturityRatingChangeDuringTeleport(U8 pMaturityRatingChange);
+	void            sheduleTeleportIM();
 
 private:
 
@@ -684,6 +685,7 @@ class LLAgent : public LLOldEvents::LLObservable
 	boost::signals2::connection mTeleportFailedSlot;
 
 	bool            mIsMaturityRatingChangingDuringTeleport;
+	bool            mTPNeedsNeabyChatSeparator;
 	U8              mMaturityRatingChange;
 
 	bool            hasPendingTeleportRequest();
@@ -706,6 +708,7 @@ class LLAgent : public LLOldEvents::LLObservable
 	void            handleTeleportFinished();
 	void            handleTeleportFailed();
 
+    static void     addTPNearbyChatSeparator();
     static void     onCapabilitiesReceivedAfterTeleport();
 
 	//--------------------------------------------------------------------
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 7ea09e6d0c5e27c789e0472cb279b92675d4cbf5..39bac6b4b2614485084f0cb303c9b7f98077ed73 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -2891,10 +2891,19 @@ void LLAgentCamera::setFocusOnAvatar(BOOL focus_on_avatar, BOOL animate, BOOL re
 			LLVector3 at_axis;
 			if (!isAgentAvatarValid() || !gAgentAvatarp->getParent())
 			{
-				at_axis = LLViewerCamera::getInstance()->getAtAxis();
-				at_axis.mV[VZ] = 0.f;
-				at_axis.normalize();
-				gAgent.resetAxes(at_axis);
+                // In case of front view rotate agent to look into direction opposite to camera
+                // In case of rear view rotate agent into diraction same as camera, e t c
+                LLVector3 vect = getCameraOffsetInitial();
+                F32 rotxy = F32(atan2(vect.mV[VY], vect.mV[VX]));
+
+                LLCoordFrame frameCamera = *((LLCoordFrame*)LLViewerCamera::getInstance());
+                // front view angle rotxy is zero, rear view rotxy angle is 180, compensate
+                frameCamera.yaw((180 * DEG_TO_RAD) - rotxy);
+                at_axis = frameCamera.getAtAxis();
+                at_axis.mV[VZ] = 0.f;
+                at_axis.normalize();
+                gAgent.resetAxes(at_axis);
+                gAgent.yaw(0);
 			}
 		}
 	}
diff --git a/indra/newview/llappdelegate-objc.mm b/indra/newview/llappdelegate-objc.mm
index a2b7362608d38c822cf4d5fd28a31b338e5883a7..3f1b5139c5c98693a355c77723bdc3bd8614fdba 100644
--- a/indra/newview/llappdelegate-objc.mm
+++ b/indra/newview/llappdelegate-objc.mm
@@ -134,6 +134,7 @@
 		// called again. Since it returned false, do not yet cancel
 		// frameTimer.
 		handleQuit();
+		[[NSApplication sharedApplication] stopModal];
 		return NSTerminateCancel;
 	} else {
 		// pumpMainLoop() returned true: it's done. Okay, done with frameTimer.
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index cba4b49613bdbdde2f894cfa7c9742a8e3bd7cf9..42f9c707be69f90ed319d113934dca13f5e70123 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -49,6 +49,7 @@
 #include "llwindow.h"
 #include "llviewerstats.h"
 #include "llviewerstatsrecorder.h"
+#include "llkeyconflict.h" // for legacy keybinding support, remove later
 #include "llmarketplacefunctions.h"
 #include "llmarketplacenotifications.h"
 #include "llmd5.h"
@@ -58,6 +59,7 @@
 #include "llslurl.h"
 #include "llstartup.h"
 #include "llfocusmgr.h"
+#include "llurlfloaterdispatchhandler.h"
 #include "llviewerjoystick.h"
 #include "llallocator.h"
 #include "llcalc.h"
@@ -89,6 +91,7 @@
 #include "llsdutil_math.h"
 #include "lllocationhistory.h"
 #include "llfasttimerview.h"
+#include "lltelemetry.h"
 #include "llvector4a.h"
 #include "llviewermenufile.h"
 #include "llvoicechannel.h"
@@ -158,7 +161,7 @@
 #include "llapr.h"
 #include <boost/lexical_cast.hpp>
 
-#include "llviewerkeyboard.h"
+#include "llviewerinput.h"
 #include "lllfsthread.h"
 #include "llworkerthread.h"
 #include "lltexturecache.h"
@@ -263,9 +266,9 @@
 // define a self-registering event API object
 #include "llappviewerlistener.h"
 
-#if (LL_LINUX || LL_SOLARIS) && LL_GTK
+#if LL_LINUX && LL_GTK
 #include "glib.h"
-#endif // (LL_LINUX || LL_SOLARIS) && LL_GTK
+#endif // (LL_LINUX) && LL_GTK
 
 #if LL_MSVC
 // disable boost::lexical_cast warning
@@ -934,6 +937,7 @@ bool LLAppViewer::init()
 
 	// Load translations for tooltips
 	LLFloater::initClass();
+	LLUrlFloaterDispatchHandler::registerInDispatcher();
 
 	/////////////////////////////////////////////////
 
@@ -1024,23 +1028,6 @@ bool LLAppViewer::init()
 	gGLManager.getGLInfo(gDebugInfo);
 	gGLManager.printGLInfoString();
 
-	// Load Default bindings
-	std::string key_bindings_file = gDirUtilp->findFile("keys.xml",
-														gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
-														gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
-
-
-	if (!gViewerKeyboard.loadBindingsXML(key_bindings_file))
-	{
-		std::string key_bindings_file = gDirUtilp->findFile("keys.ini",
-															gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
-															gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
-		if (!gViewerKeyboard.loadBindings(key_bindings_file))
-		{
-			LL_ERRS("InitInfo") << "Unable to open keys.ini" << LL_ENDL;
-		}
-	}
-
 	// If we don't have the right GL requirements, exit.
 	if (!gGLManager.mHasRequirements)
 	{
@@ -1132,6 +1119,46 @@ bool LLAppViewer::init()
 		}
 	}
 
+#if LL_WINDOWS && ADDRESS_SIZE == 64
+    if (gGLManager.mIsIntel)
+    {
+        // Check intel driver's version
+        // Ex: "3.1.0 - Build 8.15.10.2559";
+        std::string version = ll_safe_string((const char *)glGetString(GL_VERSION));
+
+        const boost::regex is_intel_string("[0-9].[0-9].[0-9] - Build [0-9]{1,2}.[0-9]{2}.[0-9]{2}.[0-9]{4}");
+
+        if (boost::regex_search(version, is_intel_string))
+        {
+            // Valid string, extract driver version
+            std::size_t found = version.find("Build ");
+            std::string driver = version.substr(found + 6);
+            S32 v1, v2, v3, v4;
+            S32 count = sscanf(driver.c_str(), "%d.%d.%d.%d", &v1, &v2, &v3, &v4);
+            if (count > 0 && v1 <= 10)
+            {
+                LL_INFOS("AppInit") << "Detected obsolete intel driver: " << driver << LL_ENDL;
+                LLUIString details = LLNotifications::instance().getGlobalString("UnsupportedIntelDriver");
+                std::string gpu_name = ll_safe_string((const char *)glGetString(GL_RENDERER));
+                details.setArg("[VERSION]", driver);
+                details.setArg("[GPUNAME]", gpu_name);
+                S32 button = OSMessageBox(details.getString(),
+                                          LLStringUtil::null,
+                                          OSMB_YESNO);
+                if (OSBTN_YES == button && gViewerWindow)
+                {
+                    std::string url = LLWeb::escapeURL(LLTrans::getString("IntelDriverPage"));
+                    if (gViewerWindow->getWindow())
+                    {
+                        gViewerWindow->getWindow()->spawnWebBrowser(url, false);
+                    }
+                }
+            }
+        }
+    }
+#endif
+
+    // Obsolete? mExpectedGLVersion is always zero
 #if LL_WINDOWS
 	if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
 	{
@@ -1206,7 +1233,16 @@ bool LLAppViewer::init()
 	// add LEAP mode command-line argument to whichever of these we selected
 	updater.args.add("leap");
 	// UpdaterServiceSettings
-	updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
+    if (gSavedSettings.getBOOL("FirstLoginThisInstall"))
+    {
+        // Befor first login, treat this as 'manual' updates,
+        // updater won't install anything, but required updates
+        updater.args.add("0");
+    }
+    else
+    {
+        updater.args.add(stringize(gSavedSettings.getU32("UpdaterServiceSetting")));
+    }
 	// channel
 	updater.args.add(LLVersionInfo::instance().getChannel());
 	// testok
@@ -1324,6 +1360,9 @@ bool LLAppViewer::init()
 	gSavedSettings.getControl("FramePerSecondLimit")->getSignal()->connect(boost::bind(&LLAppViewer::onChangeFrameLimit, this, _2));
 	onChangeFrameLimit(gSavedSettings.getLLSD("FramePerSecondLimit"));
 
+	// Load User's bindings
+	loadKeyBindings();
+
 	return true;
 }
 
@@ -1344,39 +1383,8 @@ void LLAppViewer::initMaxHeapSize()
 
 	//F32 max_heap_size_gb = llmin(1.6f, (F32)gSavedSettings.getF32("MaxHeapSize")) ;
 	F32Gigabytes max_heap_size_gb = (F32Gigabytes)gSavedSettings.getF32("MaxHeapSize") ;
-	BOOL enable_mem_failure_prevention = (BOOL)gSavedSettings.getBOOL("MemoryFailurePreventionEnabled") ;
-
-	LLMemory::initMaxHeapSizeGB(max_heap_size_gb, enable_mem_failure_prevention) ;
-}
-
-void LLAppViewer::checkMemory()
-{
-	const static F32 MEMORY_CHECK_INTERVAL = 1.0f ; //second
-	//const static F32 MAX_QUIT_WAIT_TIME = 30.0f ; //seconds
-	//static F32 force_quit_timer = MAX_QUIT_WAIT_TIME + MEMORY_CHECK_INTERVAL ;
-
-	if(!gGLManager.mDebugGPU)
-	{
-		return ;
-	}
-
-	if(MEMORY_CHECK_INTERVAL > mMemCheckTimer.getElapsedTimeF32())
-	{
-		return ;
-	}
-	mMemCheckTimer.reset() ;
-
-		//update the availability of memory
-		LLMemory::updateMemoryInfo() ;
 
-	bool is_low = LLMemory::isMemoryPoolLow() ;
-
-	LLPipeline::throttleNewMemoryAllocation(is_low) ;
-
-	if(is_low)
-	{
-		LLMemory::logMemoryInfo() ;
-	}
+	LLMemory::initMaxHeapSizeGB(max_heap_size_gb);
 }
 
 static LLTrace::BlockTimerStatHandle FTM_MESSAGES("System Messages");
@@ -1455,9 +1463,6 @@ bool LLAppViewer::doFrame()
 	//clear call stack records
 	LL_CLEAR_CALLSTACKS();
 
-	//check memory availability information
-	checkMemory() ;
-
 	{
 		pingMainloopTimeout("Main:MiscNativeWindowEvents");
 
@@ -1513,6 +1518,7 @@ bool LLAppViewer::doFrame()
 			{
 				joystick->scanJoystick();
 				gKeyboard->scanKeyboard();
+                gViewerInput.scanMouse();
 			}
 
 			// Update state based on messages, user input, object idle.
@@ -1684,12 +1690,15 @@ bool LLAppViewer::doFrame()
 		}
 
 		delete gServicePump;
+		gServicePump = NULL;
 
 		destroyMainloopTimeout();
 
 		LL_INFOS() << "Exiting main_loop" << LL_ENDL;
 	}
 
+    LLPROFILE_UPDATE();
+
 	return ! LLApp::isRunning();
 }
 
@@ -1741,7 +1750,11 @@ bool LLAppViewer::cleanup()
 	//dump scene loading monitor results
 	if (LLSceneMonitor::instanceExists())
 	{
-		LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+		if (!isSecondInstance())
+		{
+			LLSceneMonitor::instance().dumpToFile(gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "scene_monitor_results.csv"));
+		}
+		LLSceneMonitor::deleteSingleton();
 	}
 
 	// There used to be an 'if (LLFastTimerView::sAnalyzePerformance)' block
@@ -3575,6 +3588,12 @@ void LLAppViewer::writeSystemInfo()
 	gDebugInfo["FirstRunThisInstall"] = gSavedSettings.getBOOL("FirstRunThisInstall");
     gDebugInfo["StartupState"] = LLStartUp::getStartupStateString();
 
+	std::vector<std::string> resolutions = gViewerWindow->getWindow()->getDisplaysResolutionList();
+	for (auto res_iter : resolutions)
+	{
+		gDebugInfo["DisplayInfo"].append(res_iter);
+	}
+
 	writeDebugInfo(); // Save out debug_info.log early, in case of crash.
 }
 
@@ -4495,6 +4514,134 @@ void LLAppViewer::addOnIdleCallback(const boost::function<void()>& cb)
 	LLDeferredTaskList::instance().addTask(cb);
 }
 
+void LLAppViewer::loadKeyBindings()
+{
+	std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "key_bindings.xml");
+#if 1
+	// Legacy support
+	// Remove #if-#endif section half a year after DRTVWR-501 releases.
+	// Mouse actions are part of keybinding file since DRTVWR-501 instead of being stored in
+	// settings.xml. To support legacy viewers that were storing in  settings.xml we need to
+	// transfer old variables to new format.
+	// Also part of backward compatibility is present in LLKeyConflictHandler to modify
+	// legacy variables on changes in new system (to make sure we won't enforce
+	// legacy values again if user dropped to defaults in new system)
+	if (LLVersionInfo::getInstance()->getChannelAndVersion() != gLastRunVersion
+		|| !gDirUtilp->fileExists(key_bindings_file)) // if file is missing, assume that there were no changes by user yet
+	{
+		// copy mouse actions and voice key changes to new file
+		LL_INFOS("InitInfo") << "Converting legacy mouse bindings to new format" << LL_ENDL;
+		// Load settings from file
+		LLKeyConflictHandler third_person_view(LLKeyConflictHandler::MODE_THIRD_PERSON);
+		LLKeyConflictHandler sitting_view(LLKeyConflictHandler::MODE_SITTING);
+
+		// Since we are only modifying keybindings if personal file doesn't exist yet,
+		// it should be safe to just overwrite the value
+		// If key is already in use somewhere by default, LLKeyConflictHandler should resolve it.
+		BOOL value = gSavedSettings.getBOOL("DoubleClickAutoPilot");
+		third_person_view.registerControl("walk_to",
+			0,
+			value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE,
+			KEY_NONE,
+			MASK_NONE,
+			value);
+
+		U32 index = value ? 1 : 0; // we can store multiple combinations per action, so if first is in use by doubleclick, go to second
+		value = gSavedSettings.getBOOL("ClickToWalk");
+		third_person_view.registerControl("walk_to",
+			index,
+			value ? EMouseClickType::CLICK_LEFT : EMouseClickType::CLICK_NONE,
+			KEY_NONE,
+			MASK_NONE,
+			value);
+
+		value = gSavedSettings.getBOOL("DoubleClickTeleport");
+		third_person_view.registerControl("teleport_to",
+			0,
+			value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE,
+			KEY_NONE,
+			MASK_NONE,
+			value);
+
+		// sitting also supports teleport
+		sitting_view.registerControl("teleport_to",
+			0,
+			value ? EMouseClickType::CLICK_DOUBLELEFT : EMouseClickType::CLICK_NONE,
+			KEY_NONE,
+			MASK_NONE,
+			value);
+
+		std::string key_string = gSavedSettings.getString("PushToTalkButton");
+		EMouseClickType mouse = EMouseClickType::CLICK_NONE;
+		KEY key = KEY_NONE;
+		if (key_string == "MiddleMouse")
+		{
+			mouse = EMouseClickType::CLICK_MIDDLE;
+		}
+		else if (key_string == "MouseButton4")
+		{
+			mouse = EMouseClickType::CLICK_BUTTON4;
+		}
+		else if (key_string == "MouseButton5")
+		{
+			mouse = EMouseClickType::CLICK_BUTTON5;
+		}
+		else
+		{
+			LLKeyboard::keyFromString(key_string, &key);
+		}
+
+		value = gSavedSettings.getBOOL("PushToTalkToggle");
+		std::string control_name = value ? "toggle_voice" : "voice_follow_key";
+		third_person_view.registerControl(control_name, 0, mouse, key, MASK_NONE, true);
+		sitting_view.registerControl(control_name, 0, mouse, key, MASK_NONE, true);
+
+		if (third_person_view.hasUnsavedChanges())
+		{
+			// calls loadBindingsXML()
+			third_person_view.saveToSettings();
+		}
+
+		if (sitting_view.hasUnsavedChanges())
+		{
+			// calls loadBindingsXML()
+			sitting_view.saveToSettings();
+		}
+
+		// in case of voice we need to repeat this in other modes
+
+		for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+		{
+			// edit and first person modes; MODE_SAVED_SETTINGS not in use at the moment
+			if (i != LLKeyConflictHandler::MODE_THIRD_PERSON && i != LLKeyConflictHandler::MODE_SITTING)
+			{
+				LLKeyConflictHandler handler((LLKeyConflictHandler::ESourceMode)i);
+
+				handler.registerControl(control_name, 0, mouse, key, MASK_NONE, true);
+
+				if (handler.hasUnsavedChanges())
+				{
+					// calls loadBindingsXML()
+					handler.saveToSettings();
+				}
+			}
+		}
+	}
+	// since something might have gone wrong or there might have been nothing to save
+	// (and because otherwise following code will have to be encased in else{}),
+	// load everything one last time
+#endif
+	if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file))
+	{
+		// Failed to load custom bindings, try default ones
+		key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "key_bindings.xml");
+		if (!gViewerInput.loadBindingsXML(key_bindings_file))
+		{
+			LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL;
+		}
+	}
+}
+
 void LLAppViewer::purgeCache()
 {
 	LL_INFOS("AppCache") << "Purging Cache and Texture Cache..." << LL_ENDL;
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 5332fe2deba5111e2a71cdcd248865b0cb5472e2..5ceb54078430cf286c2b3428273b85e1a4e5c6b4 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -195,6 +195,8 @@ class LLAppViewer : public LLApp
 	void purgeCache(); // Clear the local cache. 
 	void purgeCacheImmediate(); //clear local cache immediately.
 	S32  updateTextureThreads(F32 max_time);
+
+	void loadKeyBindings();
 	
 	// mute/unmute the system's master audio
 	virtual void setMasterSystemAudioMute(bool mute);
@@ -233,7 +235,6 @@ class LLAppViewer : public LLApp
 	bool initConfiguration(); // Initialize settings from the command line/config file.
 	void initStrings();       // Initialize LLTrans machinery
 	bool initCache(); // Initialize local client cache.
-	void checkMemory() ;
 
 	// We have switched locations of both Mac and Windows cache, make sure
 	// files migrate and old cache is cleared out.
@@ -312,8 +313,6 @@ class LLAppViewer : public LLApp
 
     LLAllocator mAlloc;
 
-	LLFrameTimer mMemCheckTimer;
-
 	// llcorehttp library init/shutdown helper
 	LLAppCoreHttp mAppCoreHttp;
 
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 6f32aab851ebb2c451490f037ce80637faf0185b..dc487967fc695a3a7993a744a6e8690d93570fc1 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -73,10 +73,6 @@ static void exceptionTerminateHandler()
 
 int main( int argc, char **argv ) 
 {
-#if LL_SOLARIS && defined(__sparc)
-	asm ("ta\t6");		 // NOTE:  Make sure memory alignment is enforced on SPARC
-#endif
-
 	gArgC = argc;
 	gArgV = argv;
 
@@ -336,8 +332,6 @@ void LLAppViewerLinux::initCrashReporting(bool reportFreeze)
 	cmd += gDirUtilp->getDirDelimiter();
 #if LL_LINUX
 	cmd += "linux-crash-logger.bin";
-#elif LL_SOLARIS
-	cmd += "solaris-crash-logger";
 #else
 # error Unknown platform
 #endif
@@ -394,9 +388,6 @@ bool LLAppViewerLinux::beingDebugged()
 {
 	static enum {unknown, no, yes} debugged = unknown;
 
-#if LL_SOLARIS
-	return debugged == no;	// BUG: fix this for Solaris
-#else
 	if (debugged == unknown)
 	{
 		pid_t ppid = getppid();
@@ -431,7 +422,6 @@ bool LLAppViewerLinux::beingDebugged()
 	}
 
 	return debugged == yes;
-#endif
 }
 
 void LLAppViewerLinux::initLoggingAndGetLastDuration()
diff --git a/indra/newview/llattachmentsmgr.cpp b/indra/newview/llattachmentsmgr.cpp
index 0d51d581dbbb507b906e4acad94316ad46295116..174447fb44aa0b093fe00d1c30f9a62ca8ba32bb 100644
--- a/indra/newview/llattachmentsmgr.cpp
+++ b/indra/newview/llattachmentsmgr.cpp
@@ -310,6 +310,7 @@ void LLAttachmentsMgr::linkRecentlyArrivedAttachments()
         {
             if (isAgentAvatarValid() &&
                 gAgentAvatarp->isWearingAttachment(*it) &&
+                !gAgentAvatarp->getWornAttachment(*it)->isTempAttachment() && // Don't link temp attachments in COF!
                 !LLAppearanceMgr::instance().isLinkedInCOF(*it))
             {
                 LLUUID item_id = *it;
diff --git a/indra/newview/llavatarpropertiesprocessor.cpp b/indra/newview/llavatarpropertiesprocessor.cpp
index 856eb3414ed998d27be6f2b95a850ecd59057b75..f41eb3daf4286369ca565c4649ecbb8192ca7ff3 100644
--- a/indra/newview/llavatarpropertiesprocessor.cpp
+++ b/indra/newview/llavatarpropertiesprocessor.cpp
@@ -253,6 +253,19 @@ std::string LLAvatarPropertiesProcessor::paymentInfo(const LLAvatarData* avatar_
 	return LLTrans::getString(payment_text);
 }
 
+//static
+bool LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(const LLAvatarData* avatar_data)
+{
+	// Special accounts like M Linden don't have payment info revealed.
+	if (!avatar_data->caption_text.empty()) return true;
+
+	// Linden employees don't have payment info revealed
+	const S32 LINDEN_EMPLOYEE_INDEX = 3;
+	if (avatar_data->caption_index == LINDEN_EMPLOYEE_INDEX) return true;
+
+	return ((avatar_data->flags & AVATAR_TRANSACTED) || (avatar_data->flags & AVATAR_IDENTIFIED));
+}
+
 void LLAvatarPropertiesProcessor::processAvatarPropertiesReply(LLMessageSystem* msg, void**)
 {
 	LLAvatarData avatar_data;
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index d5c5c75c6914d7a8942a5da13470af7a5ea0c0a8..b063048c26c25241385df9e93fb207bdc0f7b2af 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -232,6 +232,8 @@ class LLAvatarPropertiesProcessor
 	// Used for profiles, inspectors.
 	static std::string paymentInfo(const LLAvatarData* avatar_data);
 
+	static bool hasPaymentInfoOnFile(const LLAvatarData* avatar_data);
+
 	static void processAvatarPropertiesReply(LLMessageSystem* msg, void**);
 
 	static void processAvatarInterestsReply(LLMessageSystem* msg, void**);
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 2f503fc57ddde20ecd5f7edddb7acd4ba418361e..83e54be4a27fc171751ccd97eb8da65faa4a4ca9 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -58,6 +58,7 @@
 #include "llmultigesture.h"
 #include "llui.h"
 #include "lluictrlfactory.h"
+#include "lluiusage.h"
 // [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0b)
 #include "rlvactions.h"
 #include "rlvcommon.h"
@@ -573,6 +574,8 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
 	// as soon as we say something, we no longer care about teaching the user
 	// how to chat
 	gWarningSettings.setBOOL("FirstOtherChatBeforeUser", FALSE);
+
+	LLUIUsage::instance().logCommand("Chat.Send"); // Pseudo-command
 	
 	// Look for "/20 foo" channel chats.
 	S32 channel = 0;
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 252acecd3e5c4ef883334b3f3ad388371ed0ea8c..a5e212a14138e4229032d810f0455e835db4b079 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -134,6 +134,7 @@ class LLChatHistoryHeader: public LLPanel
 		mUserNameFont(NULL),
 		mUserNameTextBox(NULL),
 		mTimeBoxTextBox(NULL),
+		mNeedsTimeBox(true),
 		mAvatarNameCacheConnection()
 	{}
 
@@ -665,8 +666,19 @@ class LLChatHistoryHeader: public LLPanel
 		user_name->setReadOnlyColor(style_params.readonly_color());
 		user_name->setColor(style_params.color());
 
-		if (chat.mFromName.empty()
-			|| mSourceType == CHAT_SOURCE_SYSTEM)
+        if (mSourceType == CHAT_SOURCE_TELEPORT
+            && chat.mChatStyle == CHAT_STYLE_TELEPORT_SEP)
+        {
+            mFrom = chat.mFromName;
+            mNeedsTimeBox = false;
+            user_name->setValue(mFrom);
+            updateMinUserNameWidth();
+            LLColor4 sep_color = LLUIColorTable::instance().getColor("ChatTeleportSeparatorColor");
+            setTransparentColor(sep_color);
+            mTimeBoxTextBox->setVisible(FALSE);
+        }
+        else if (chat.mFromName.empty()
+                 || mSourceType == CHAT_SOURCE_SYSTEM)
 		{
 			mFrom = LLTrans::getString("SECOND_LIFE");
 			if(!chat.mFromName.empty() && (mFrom != chat.mFromName))
@@ -775,6 +787,9 @@ class LLChatHistoryHeader: public LLPanel
 			case CHAT_SOURCE_SYSTEM:
 				icon->setValue(LLSD("SL_Logo"));
 				break;
+			case CHAT_SOURCE_TELEPORT:
+				icon->setValue(LLSD("Command_Destinations_Icon"));
+				break;
 			case CHAT_SOURCE_UNKNOWN: 
 				icon->setValue(LLSD("Unknown_Icon"));
 		}
@@ -813,7 +828,7 @@ class LLChatHistoryHeader: public LLPanel
 		S32 user_name_width = user_name_rect.getWidth();
 		S32 time_box_width = time_box->getRect().getWidth();
 
-		if (!time_box->getVisible() && user_name_width > mMinUserNameWidth)
+		if (mNeedsTimeBox && !time_box->getVisible() && user_name_width > mMinUserNameWidth)
 		{
 			user_name_rect.mRight -= time_box_width;
 			user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight());
@@ -1026,6 +1041,8 @@ class LLChatHistoryHeader: public LLPanel
 	LLTextBox*			mUserNameTextBox;
 	LLTextBox*			mTimeBoxTextBox; 
 
+    bool				mNeedsTimeBox;
+
 private:
 	boost::signals2::connection mAvatarNameCacheConnection;
 };
@@ -1260,6 +1277,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	}
 
 	bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY;
+	bool teleport_separator = chat.mSourceType == CHAT_SOURCE_TELEPORT;
 	// We graying out chat history by graying out messages that contains full date in a time string
 	if (message_from_log)
 	{
@@ -1280,14 +1298,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		LLStyle::Params timestamp_style(body_message_params);
 
 		// out of the timestamp
-		if (args["show_time"].asBoolean())
-		{
-		if (!message_from_log)
+		if (args["show_time"].asBoolean() && !teleport_separator)
 		{
-			LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
-			timestamp_style.color(timestamp_color);
-			timestamp_style.readonly_color(timestamp_color);
-		}
+			if (!message_from_log)
+			{
+				LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
+				timestamp_style.color(timestamp_color);
+				timestamp_style.readonly_color(timestamp_color);
+			}
 			mEditor->appendText("[" + chat.mTimeStr + "] ", prependNewLineState, timestamp_style);
 			prependNewLineState = false;
 		}
@@ -1343,6 +1361,13 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 					prependNewLineState, link_params);
 				prependNewLineState = false;
 			}
+            else if (teleport_separator)
+            {
+                std::string tp_text = LLTrans::getString("teleport_preamble_compact_chat");
+                mEditor->appendText(tp_text + " <nolink>" + chat.mFromName + "</nolink>",
+                    prependNewLineState, body_message_params);
+                                prependNewLineState = false;
+            }
 			else
 			{
 				mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter,
@@ -1361,8 +1386,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		p.right_pad = mRightWidgetPad;
 
 		LLDate new_message_time = LLDate::now();
-
-		if (mLastFromName == chat.mFromName 
+		if (!teleport_separator
+			&& mLastFromName == chat.mFromName
 			&& mLastFromID == chat.mFromID
 			&& mLastMessageTime.notNull() 
 			&& (new_message_time.secondsSinceEpoch() - mLastMessageTime.secondsSinceEpoch()) < 60.0
@@ -1385,7 +1410,14 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 				p.top_pad = 0;
 			else
 				p.top_pad = mTopHeaderPad;
-            p.bottom_pad = mBottomHeaderPad;
+            if (teleport_separator)
+            {
+                p.bottom_pad = mBottomSeparatorPad;
+            }
+            else
+            {
+                p.bottom_pad = mBottomHeaderPad;
+            }
             if (!view)
             {
                 LL_WARNS() << "Failed to create header from " << mMessageHeaderFilename << ": can't append to history" << LL_ENDL;
@@ -1463,9 +1495,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			}
 		}
 	}
-
 	// usual messages showing
-	else
+	else if(!teleport_separator)
 	{
 		std::string message = irc_me ? chat.mText.substr(3) : chat.mText;
 
@@ -1498,7 +1529,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		if (square_brackets)
 		{
 			message += "]";
-	}
+		}
 
 		mEditor->appendText(message, prependNewLineState, body_message_params);
 		prependNewLineState = false;
diff --git a/indra/newview/llcontrolavatar.cpp b/indra/newview/llcontrolavatar.cpp
index 5a6b66df52b0213e17a35829d88ec919e3f8b4ff..fab249f98807a865b7d4c21732eecd4c5443b440 100644
--- a/indra/newview/llcontrolavatar.cpp
+++ b/indra/newview/llcontrolavatar.cpp
@@ -78,6 +78,24 @@ void LLControlAvatar::initInstance()
     mInitFlags |= 1<<4;
 }
 
+const LLVOAvatar *LLControlAvatar::getAttachedAvatar() const
+{
+	if (mRootVolp && mRootVolp->isAttachment())
+	{
+		return mRootVolp->getAvatarAncestor();
+	}
+	return NULL;
+}
+
+LLVOAvatar *LLControlAvatar::getAttachedAvatar()
+{
+	if (mRootVolp && mRootVolp->isAttachment())
+	{
+		return mRootVolp->getAvatarAncestor();
+	}
+	return NULL;
+}
+
 void LLControlAvatar::getNewConstraintFixups(LLVector3& new_pos_fixup, F32& new_scale_fixup) const
 {
 
@@ -165,7 +183,7 @@ void LLControlAvatar::matchVolumeTransform()
 
         if (mRootVolp->isAttachment())
         {
-            LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor();
+            LLVOAvatar *attached_av = getAttachedAvatar();
             if (attached_av)
             {
                 LLViewerJointAttachment *attach = attached_av->getTargetAttachmentPoint(mRootVolp);
@@ -360,7 +378,34 @@ void LLControlAvatar::idleUpdate(LLAgent &agent, const F64 &time)
     }
 }
 
-BOOL LLControlAvatar::updateCharacter(LLAgent &agent)
+bool LLControlAvatar::computeNeedsUpdate()
+{
+	computeUpdatePeriod();
+
+	// Animesh attachments are a special case. Should have the same update cadence as their attached parent avatar.
+	LLVOAvatar *attached_av = getAttachedAvatar();
+	if (attached_av)
+	{
+		// Have to run computeNeedsUpdate() for attached av in
+		// case it hasn't run updateCharacter() already this
+		// frame.  Note this means that the attached av will
+		// run computeNeedsUpdate() multiple times per frame
+		// if it has animesh attachments. Results will be
+		// consistent except for the corner case of exceeding
+		// MAX_IMPOSTOR_INTERVAL in one call but not another,
+		// which should be rare.
+		attached_av->computeNeedsUpdate();
+		mNeedsImpostorUpdate = attached_av->mNeedsImpostorUpdate;
+		if (mNeedsImpostorUpdate)
+		{
+			mLastImpostorUpdateReason = 12;
+		}
+		return mNeedsImpostorUpdate;
+	}
+	return LLVOAvatar::computeNeedsUpdate();
+}
+
+bool LLControlAvatar::updateCharacter(LLAgent &agent)
 {
     return LLVOAvatar::updateCharacter(agent);
 }
@@ -634,29 +679,23 @@ std::string LLControlAvatar::getFullname() const
 // virtual
 bool LLControlAvatar::shouldRenderRigged() const
 {
-    if (mRootVolp && mRootVolp->isAttachment())
-    {
-        LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor();
-        if (attached_av)
-        {
-            return attached_av->shouldRenderRigged();
-        }
-    }
+	const LLVOAvatar *attached_av = getAttachedAvatar();
+	if (attached_av)
+	{
+		return attached_av->shouldRenderRigged();
+	}
     return true;
 }
 
 // virtual
 BOOL LLControlAvatar::isImpostor()
 {
-    if (mRootVolp && mRootVolp->isAttachment())
-    {
-		// Attached animated objects should match state of their attached av.
-        LLVOAvatar *attached_av = mRootVolp->getAvatarAncestor();
-		if (attached_av)
-		{
-			return attached_av->isImpostor();
-		}
-    }
+	// Attached animated objects should match state of their attached av.
+	LLVOAvatar *attached_av = getAttachedAvatar();
+	if (attached_av)
+	{
+		return attached_av->isImpostor();
+	}
 	return LLVOAvatar::isImpostor();
 }
 
diff --git a/indra/newview/llcontrolavatar.h b/indra/newview/llcontrolavatar.h
index 288d07cd48aed31bbd261558ff66da4b6db9eb15..8e87299f3ee7302867b64ee27b83c47ea5677216 100644
--- a/indra/newview/llcontrolavatar.h
+++ b/indra/newview/llcontrolavatar.h
@@ -40,6 +40,10 @@ class LLControlAvatar:
 	virtual void 			initInstance(); // Called after construction to initialize the class.
 	virtual	~LLControlAvatar();
 
+	// If this is an attachment, return the avatar it is attached to. Otherwise NULL.
+	virtual const LLVOAvatar *getAttachedAvatar() const;
+	virtual LLVOAvatar *getAttachedAvatar();
+	
     void getNewConstraintFixups(LLVector3& new_pos_constraint, F32& new_scale_constraint) const;
     void matchVolumeTransform();
     void updateVolumeGeom();
@@ -53,7 +57,8 @@ class LLControlAvatar:
     void markForDeath();
 
     virtual void idleUpdate(LLAgent &agent, const F64 &time);
-	virtual BOOL updateCharacter(LLAgent &agent);
+	virtual bool computeNeedsUpdate();
+	virtual bool updateCharacter(LLAgent &agent);
 
     void getAnimatedVolumes(std::vector<LLVOVolume*>& volumes);
     void updateAnimations();  
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 9430bb3ca331dc7ede43576a23275a9a5084a51e..a696c99a82060c922b4c438d240a777ddf298882 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -398,6 +398,24 @@ void LLConversationLog::deleteBackupLogs()
 	}
 }
 
+void LLConversationLog::verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name)
+{
+    conversations_vec_t::iterator conv_it = mConversations.begin();
+    for (; conv_it != mConversations.end(); ++conv_it)
+    {
+        if (conv_it->getSessionID() == session_id)
+        {
+            if (conv_it->getHistoryFileName() != expected_filename)
+            {
+                LLLogChat::renameLogFile(conv_it->getHistoryFileName(), expected_filename);
+                conv_it->updateHistoryFileName(expected_filename);
+                conv_it->setConversationName(new_session_name);
+            }
+            break;
+        }
+    }
+}
+
 bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory)
 {
 
@@ -518,7 +536,9 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 	}
 	bool purge_required = false;
 
-	char buffer[MAX_STRING];
+	static constexpr int UTF_BUFFER{ 1024 }; // long enough to handle the most extreme Unicode nonsense and some to spare
+
+	char buffer[UTF_BUFFER];
 	char conv_name_buffer[MAX_STRING];
 	char part_id_buffer[MAX_STRING];
 	char conv_id_buffer[MAX_STRING];
@@ -529,11 +549,14 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 	// before CHUI-348 it was a flag of conversation voice state
 	int prereserved_unused;
 
-	while (!feof(fp) && fgets(buffer, MAX_STRING, fp))
+	memset(buffer, '\0', UTF_BUFFER);
+	while (!feof(fp) && fgets(buffer, UTF_BUFFER, fp))
 	{
-		conv_name_buffer[0] = '\0';
-		part_id_buffer[0]	= '\0';
-		conv_id_buffer[0]	= '\0';
+        // force blank for added safety
+        memset(conv_name_buffer, '\0', MAX_STRING);
+        memset(part_id_buffer, '\0', MAX_STRING);
+        memset(conv_id_buffer, '\0', MAX_STRING);
+        memset(history_file_name, '\0', MAX_STRING);
 
 		sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|",
 				&time,
@@ -570,6 +593,7 @@ bool LLConversationLog::loadFromFile(const std::string& filename)
 		}
 
 		mConversations.push_back(conversation);
+		memset(buffer, '\0', UTF_BUFFER);
 	}
 	fclose(fp);
 
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 46e46a3278b6c4c843b286054f56e21bf071bf3a..820a5db49143c77ea49c549b12f7d85416bf7728 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -59,7 +59,7 @@ class LLConversation
 						getTime()				const	{ return mTime; }
 	bool				hasOfflineMessages()	const	{ return mHasOfflineIMs; }
 
-	void setConversationName(std::string conv_name) { mConversationName = conv_name; }
+	void setConversationName(const std::string &conv_name) { mConversationName = conv_name; }
 	void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; }
 	bool isOlderThan(U32Days days) const;
 
@@ -68,6 +68,8 @@ class LLConversation
 	 */
 	void updateTimestamp();
 
+    void updateHistoryFileName(const std::string &new_name) { mHistoryFileName = new_name; }
+
 	/*
 	 * Resets flag of unread offline message to false when im floater with this conversation is opened.
 	 */
@@ -137,6 +139,8 @@ class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObse
 	 * public method which is called on viewer exit to save conversation log
 	 */
 	void cache();
+    // will check if current name is edentical with the one on disk and will rename the one on disk if it isn't
+	void verifyFilename(const LLUUID& session_id, const std::string &expected_filename, const std::string &new_session_name);
 	bool moveLog(const std::string &originDirectory, const std::string &targetDirectory);
 	void getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs);
 	void deleteBackupLogs();
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 4aa74a550cb65ee2ae14b9e9d52490dca16d7a7a..e2b2cb8cc911dc2d169400fd43e4743227a925a8 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -36,6 +36,9 @@
 #include "llconversationmodel.h"
 #include "llimview.h" //For LLIMModel
 #include "lltrans.h"
+// [RLVa:KB] - @shownames
+#include "rlvactions.h"
+// [/RLVa:KB]
 
 #include <boost/foreach.hpp>
 
@@ -341,11 +344,36 @@ void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
 
 void LLConversationItemSession::clearParticipants()
 {
+    // clearParticipants function potentially is malfunctioning since it only cleans children of models,
+    // it does nothing to views that own those models (listeners)
+    // probably needs to post some kind of 'remove all participants' event
 	clearChildren();
 	mIsLoaded = false;
 	mNeedsRefresh = true;
 }
 
+
+void LLConversationItemSession::clearAndDeparentModels()
+{
+    std::for_each(mChildren.begin(), mChildren.end(),
+        [](LLFolderViewModelItem* c)
+        {
+            if (c->getNumRefs() == 0)
+            {
+                // LLConversationItemParticipant can be created but not assigned to any view,
+                // it was waiting for an "add_participant" event to be processed
+                delete c;
+            }
+            else
+            {
+                // Model is still assigned to some view/widget
+                c->setParent(NULL);
+            }
+        }
+    );
+    mChildren.clear();
+}
+
 LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id)
 {
 	// This is *not* a general tree parsing algorithm. It assumes that a session contains only 
@@ -355,7 +383,7 @@ LLConversationItemParticipant* LLConversationItemSession::findParticipant(const
 	for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
 	{
 		participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
-		if (participant->hasSameValue(participant_id))
+		if (participant && participant->hasSameValue(participant_id))
 		{
 			break;
 		}
@@ -466,7 +494,7 @@ const bool LLConversationItemSession::getTime(F64& time) const
 	{
 		participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
 		F64 participant_time;
-		if (participant->getTime(participant_time))
+		if (participant && participant->getTime(participant_time))
 		{
 			has_time = true;
 			most_recent_time = llmax(most_recent_time,participant_time);
@@ -559,8 +587,13 @@ void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_nam
 
 void LLConversationItemParticipant::updateName(const LLAvatarName& av_name)
 {
-	mName = av_name.getUserName();
-	mDisplayName = av_name.getDisplayName();
+// [RLVa:KB] - @shownames
+	bool fRlvCanShowName = (!mRlvCheckShowNames) || (RlvActions::canShowName(RlvActions::SNC_DEFAULT, mUUID));
+	mName = (fRlvCanShowName) ? av_name.getUserName() : LLStringUtil::null;
+	mDisplayName = (fRlvCanShowName) ? av_name.getDisplayName() : RlvStrings::getAnonym(av_name);
+// [/RLVa:KB]
+//	mName = av_name.getUserName();
+//	mDisplayName = av_name.getDisplayName();
 	
 	if (mDisplayModeratorLabel)
 	{
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
index 30c74818648a1dc83a21453f2c35ec06e43b349b..4c9d51d77c4656af53df20aa0a199264e7e7bf3f 100644
--- a/indra/newview/llconversationmodel.h
+++ b/indra/newview/llconversationmodel.h
@@ -165,6 +165,7 @@ class LLConversationItemSession : public LLConversationItem
 	void removeParticipant(LLConversationItemParticipant* participant);
 	void removeParticipant(const LLUUID& participant_id);
 	void clearParticipants();
+	void clearAndDeparentModels(); // will delete unowned models and deparent owned ones
 	LLConversationItemParticipant* findParticipant(const LLUUID& participant_id);
 
 	void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted);
@@ -213,6 +214,10 @@ class LLConversationItemParticipant : public LLConversationItem
 	void setModeratorOptionsVisible(bool visible) { mDisplayModeratorOptions = visible; }
 	void setDisplayModeratorRole(bool displayRole);
 	void setGroupBanVisible(bool visible) { mDisplayGroupBanOptions = visible; }
+// [RLVa:KB] - @shownames
+	void setRlvCheckShowNames(bool fRlvCheckShowNames) { mRlvCheckShowNames = fRlvCheckShowNames; }
+// [/RLVa:KB]
+
 
 private:
 	void onAvatarNameCache(const LLAvatarName& av_name);	// callback used by fetchAvatarName
@@ -221,6 +226,9 @@ class LLConversationItemParticipant : public LLConversationItem
 	bool mIsModeratorMuted;	         // default is false
 	bool mIsModerator;	         // default is false
 	bool mDisplayModeratorLabel; // default is false
+// [RLVa:KB] - @shownames
+	bool mRlvCheckShowNames;
+// [/RLVa:KB]
 	std::string mDisplayName;
 	F64  mDistToAgent;  // Distance to the agent. A negative (meaningless) value means the distance has not been set.
 	boost::signals2::connection mAvatarNameCacheConnection;
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
index 093e772abecbd7e85505005ef6de1d8bf3d66261..65cec68884da0a1a7a2ce35c2bdd37ad89ca35b0 100644
--- a/indra/newview/llconversationview.cpp
+++ b/indra/newview/llconversationview.cpp
@@ -31,6 +31,7 @@
 
 #include <boost/bind.hpp>
 #include "llagentdata.h"
+#include "llavataractions.h"
 #include "llconversationmodel.h"
 #include "llfloaterimsession.h"
 #include "llfloaterimnearbychat.h"
@@ -102,6 +103,56 @@ LLConversationViewSession::~LLConversationViewSession()
 	mFlashTimer->unset();
 }
 
+void LLConversationViewSession::destroyView()
+{
+    // Chat can create and parent models(listeners) to session's model before creating
+    // coresponding views, such participant's models normally will wait for idle cycles
+    // but since we are deleting session and won't be processing any more events, make
+    // sure unowned LLConversationItemParticipant models are removed as well.
+
+    LLConversationItemSession* vmi = dynamic_cast<LLConversationItemSession*>(getViewModelItem());
+
+    // CONV_SESSION_1_ON_1 stores participants as two models that belong to views independent
+    // from session (nasty! These views are widgets in LLFloaterIMSessionTab, see buildConversationViewParticipant)
+    if (vmi && vmi->getType() != LLConversationItem::CONV_SESSION_1_ON_1)
+    {
+        // Destroy existing views
+        while (!mItems.empty())
+        {
+            LLFolderViewItem *itemp = mItems.back();
+            mItems.pop_back();
+
+            LLFolderViewModelItem* item_vmi = itemp->getViewModelItem();
+            if (item_vmi) // supposed to exist
+            {
+                // unparent to remove from child list
+                vmi->removeChild(item_vmi);
+            }
+            itemp->destroyView();
+        }
+
+        // Not needed in scope of sessions, but just in case
+        while (!mFolders.empty())
+        {
+            LLFolderViewFolder *folderp = mFolders.back();
+            mFolders.pop_back();
+
+            LLFolderViewModelItem* folder_vmi = folderp->getViewModelItem();
+            if (folder_vmi)
+            {
+                vmi->removeChild(folder_vmi);
+            }
+            folderp->destroyView();
+        }
+
+        // Now everything that is left in model(listener) is not owned by views,
+        // only by sessions, deparent so it won't point to soon to be dead model
+        vmi->clearAndDeparentModels();
+    }
+
+    LLFolderViewFolder::destroyView();
+}
+
 void LLConversationViewSession::setFlashState(bool flash_state)
 {
 	if (flash_state && !mFlashStateOn)
@@ -432,8 +483,13 @@ void LLConversationViewSession::refresh()
 	vmi->resetRefresh();
 
 	if (mSessionTitle)
-	{
-		mSessionTitle->setText(vmi->getDisplayName());
+	{		
+		if (!highlightFriendTitle(vmi))
+		{
+			LLStyle::Params title_style;
+			title_style.color = LLUIColorTable::instance().getColor("LabelTextColor");
+			mSessionTitle->setText(vmi->getDisplayName(), title_style);
+		}
 	}
 
 	// Update all speaking indicators
@@ -478,6 +534,22 @@ void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& sessi
 	}
 }
 
+bool LLConversationViewSession::highlightFriendTitle(LLConversationItem* vmi)
+{
+	if(vmi->getType() == LLConversationItem::CONV_PARTICIPANT || vmi->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+	{
+		LLIMModel::LLIMSession* session=  LLIMModel::instance().findIMSession(vmi->getUUID());
+		if (session && LLAvatarActions::isFriend(session->mOtherParticipantID))
+		{
+			LLStyle::Params title_style;
+			title_style.color = LLUIColorTable::instance().getColor("ConversationFriendColor");
+			mSessionTitle->setText(vmi->getDisplayName(), title_style);
+			return true;
+		}
+	}
+	return false;
+}
+
 //
 // Implementation of conversations list participant (avatar) widgets
 //
@@ -578,7 +650,14 @@ void LLConversationViewParticipant::draw()
 	}
 	else
 	{
-		color = mIsSelected ? sHighlightFgColor : sFgColor;
+		if (LLAvatarActions::isFriend(mUUID))
+		{
+			color = LLUIColorTable::instance().getColor("ConversationFriendColor");
+		}
+		else
+		{
+			color = mIsSelected ? sHighlightFgColor : sFgColor;
+		}
 	}
 
 	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
@@ -617,10 +696,13 @@ void LLConversationViewParticipant::refresh()
 {
 	// Refresh the participant view from its model data
 	LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(getViewModelItem());
-	participant_model->resetRefresh();
-	
-	// *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
-	mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
+    if (participant_model)
+    {
+        participant_model->resetRefresh();
+
+        // *TODO: We should also do something with vmi->isModerator() to echo that state in the UI somewhat
+        mSpeakingIndicator->setIsModeratorMuted(participant_model->isModeratorMuted());
+    }
 
 	// Do the regular upstream refresh
 	LLFolderViewItem::refresh();
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
index c5930c8a293aa2e6f761b6d8880173b7008ba1a6..0932d24dfe22abcceb3cab1d9a54fd12ba81e36e 100644
--- a/indra/newview/llconversationview.h
+++ b/indra/newview/llconversationview.h
@@ -36,6 +36,7 @@
 class LLTextBox;
 class LLFloater;
 class LLFloaterIMContainer;
+class LLConversationItem;
 class LLConversationViewSession;
 class LLConversationViewParticipant;
 
@@ -66,6 +67,8 @@ class LLConversationViewSession : public LLFolderViewFolder
 public:
 	virtual ~LLConversationViewSession();
 
+	/*virtual*/ void destroyView();
+
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
 	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
@@ -93,6 +96,8 @@ class LLConversationViewSession : public LLFolderViewFolder
 	LLFloater* getSessionFloater();
 	bool isInActiveVoiceChannel() { return mIsInActiveVoiceChannel; }
 
+	bool highlightFriendTitle(LLConversationItem* vmi);
+
 private:
 
 	void onCurrentVoiceSessionChanged(const LLUUID& session_id);
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index d4fc1fe64d28b6186559a583ead0e5573de8d96a..232e461fd0fa076dbfea12378248455e842e80d6 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -454,7 +454,7 @@ void LLCurrencyUIManager::Impl::updateUI()
 		
 		if (!mUserEnteredCurrencyBuy)
 		{
-			if (!mZeroMessage.empty() && mUserCurrencyBuy == 0)
+			if (mUserCurrencyBuy == 0)
 			{
 				lindenAmount->setText(LLStringUtil::null);
 			}
@@ -467,8 +467,9 @@ void LLCurrencyUIManager::Impl::updateUI()
 		}
 	}
 
-	mPanel.getChild<LLUICtrl>("currency_est")->setTextArg("[LOCALAMOUNT]", getLocalEstimate());
-	mPanel.getChildView("currency_est")->setVisible( hasEstimate() && mUserCurrencyBuy > 0);
+	std::string estimated = (mUserCurrencyBuy == 0) ? mPanel.getString("estimated_zero") : getLocalEstimate();
+	mPanel.getChild<LLUICtrl>("currency_est")->setTextArg("[LOCALAMOUNT]", estimated);
+	mPanel.getChildView("currency_est")->setVisible( hasEstimate() || mUserCurrencyBuy == 0);
 
 	mPanel.getChildView("currency_links")->setVisible( mSupportsInternationalBilling);
 	mPanel.getChildView("exchange_rate_note")->setVisible( mSupportsInternationalBilling);
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index b8e6e81ee6695c92f5239d0d1d3f1c118226e652..01790ad19e480d31c3a9a9f8bf75e34974e1c90f 100644
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -37,7 +37,7 @@
 #include "llviewercontrol.h"
 #include "llwin32headerslean.h"
 
-#if LL_LINUX || LL_SOLARIS || LL_DARWIN
+#if LL_LINUX || LL_DARWIN
 # include "llfilepicker.h"
 #endif
 
@@ -187,7 +187,7 @@ std::string LLDirPicker::getDirName()
 	return mFilePicker->getFirstFile();
 }
 
-#elif LL_LINUX || LL_SOLARIS
+#elif LL_LINUX
 
 LLDirPicker::LLDirPicker() :
 	mFileName(NULL),
diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h
index c7dba12130b9e26c8d8490823ff21a9a71701207..52febe45235920d2d76974671d5b42bb6fe7fe5a 100644
--- a/indra/newview/lldirpicker.h
+++ b/indra/newview/lldirpicker.h
@@ -78,7 +78,7 @@ class LLDirPicker
 	void buildDirname( void );
 	bool check_local_file_access_enabled();
 
-#if LL_LINUX || LL_SOLARIS || LL_DARWIN
+#if LL_LINUX || LL_DARWIN
 	// On Linux we just implement LLDirPicker on top of LLFilePicker
 	LLFilePicker *mFilePicker;
 #endif
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 2219f202729317542ffb88067528ad23101377aa..507af56cb0d2b8be0a0068a03c1276191a1cf7da 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -912,22 +912,18 @@ void LLDrawable::updateDistance(LLCamera& camera, bool force_update)
             if (volume->getAvatar())
             {
                 const LLVector3* av_box = volume->getAvatar()->getLastAnimExtents();
-                LLVector3d cam_pos = gAgent.getPosGlobalFromAgent(LLViewerCamera::getInstance()->getOrigin());
-                LLVector3 cam_region_pos = LLVector3(cam_pos - volume->getRegion()->getOriginGlobal());
-                
-                LLVector3 cam_to_box_offset = point_to_box_offset(cam_region_pos, av_box);
+                LLVector3 cam_pos_from_agent = LLViewerCamera::getInstance()->getOrigin();
+                LLVector3 cam_to_box_offset = point_to_box_offset(cam_pos_from_agent, av_box);
                 mDistanceWRTCamera = llmax(0.01f, ll_round(cam_to_box_offset.magVec(), 0.01f));
                 LL_DEBUGS("DynamicBox") << volume->getAvatar()->getFullname() 
                                         << " pos (ignored) " << pos
-                                        << " cam pos " << cam_pos
-                                        << " cam region pos " << cam_region_pos
+                                        << " cam pos " << cam_pos_from_agent
                                         << " box " << av_box[0] << "," << av_box[1] 
                                         << " -> dist " << mDistanceWRTCamera
                                         << LL_ENDL;
                 mVObjp->updateLOD();
                 return;
             }
-            
 		}
 		else
 		{
@@ -1485,7 +1481,7 @@ void LLSpatialBridge::setVisible(LLCamera& camera_in, std::vector<LLDrawable*>*
 				LLVOAvatar* avatarp = (LLVOAvatar*) objparent;
 				if (avatarp->isVisible())
 				{
-					impostor = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isImpostor();
+					impostor = objparent->isAvatar() && !LLPipeline::sImpostorRender && ((LLVOAvatar*) objparent)->isImpostor();
 					loaded   = objparent->isAvatar() && ((LLVOAvatar*) objparent)->isFullyLoaded();
 				}
 				else
@@ -1569,7 +1565,8 @@ void LLSpatialBridge::updateDistance(LLCamera& camera_in, bool force_update)
 
 	if (mDrawable->getVObj())
 	{
-		if (mDrawable->getVObj()->isAttachment())
+		// Don't update if we are part of impostor, unles it's an impostor pass
+		if (!LLPipeline::sImpostorRender && mDrawable->getVObj()->isAttachment())
 		{
 			LLDrawable* parent = mDrawable->getParent();
 			if (parent && parent->getVObj())
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 87772d9eb689163efee6e8a9f0e25cca522c8170..687b13d2c8366d46496f27495ebbdb6709bac068 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -572,12 +572,12 @@ void LLDrawPoolAvatar::renderShadow(S32 pass)
 	{
 		return;
 	}
-
-	BOOL impostor = avatarp->isImpostor();
-	if (impostor 
-		&& LLVOAvatar::AV_DO_NOT_RENDER != avatarp->getVisualMuteSettings()
-		&& LLVOAvatar::AV_ALWAYS_RENDER != avatarp->getVisualMuteSettings())
+	LLVOAvatar::AvatarOverallAppearance oa = avatarp->getOverallAppearance();
+	BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor();
+	if (oa == LLVOAvatar::AOA_INVISIBLE ||
+		(impostor && oa == LLVOAvatar::AOA_JELLYDOLL))
 	{
+		// No shadows for jellydolled or invisible avs.
 		return;
 	}
 	
@@ -1464,7 +1464,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 		return;
 	}
 
-	LLVOAvatar *avatarp;
+	LLVOAvatar *avatarp = NULL;
 
 	if (single_avatar)
 	{
@@ -1510,11 +1510,12 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 		return;
 	}
 
-	BOOL impostor = avatarp->isImpostor() && !single_avatar;
+	BOOL impostor = !LLPipeline::sImpostorRender && avatarp->isImpostor() && !single_avatar;
 
 	if (( avatarp->isInMuteList() 
 		  || impostor 
-		  || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
+		  || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
+//		  || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()) ) && pass != 0)
 	{ //don't draw anything but the impostor for impostored avatars
 		return;
 	}
@@ -1524,6 +1525,13 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 		return;
 	}
 
+	LLVOAvatar *attached_av = avatarp->getAttachedAvatar();
+	if (attached_av && LLVOAvatar::AOA_NORMAL != attached_av->getOverallAppearance())
+	{
+		// Animesh attachment of a jellydolled or invisible parent - don't show
+		return;
+	}
+
 	if (pass == 0)
 	{
 		if (!LLPipeline::sReflectionRender)
@@ -1531,7 +1539,8 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 			LLVOAvatar::sNumVisibleAvatars++;
 		}
 
-		if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()))
+//		if (impostor || (LLVOAvatar::AV_DO_NOT_RENDER == avatarp->getVisualMuteSettings() && !avatarp->needsImpostorUpdate()))
+		if (impostor || (LLVOAvatar::AOA_NORMAL != avatarp->getOverallAppearance() && !avatarp->needsImpostorUpdate()))
 		{
 			if (LLPipeline::sRenderDeferred && !LLPipeline::sReflectionRender && avatarp->mImpostor.isComplete()) 
 			{
diff --git a/indra/newview/lldrawpoolwlsky.cpp b/indra/newview/lldrawpoolwlsky.cpp
index d4e7f1600e7637b025c41ab05fe94f0ddbfd2934..0c3d8f3098fa334bd0ef8a4c1325a3766c0b93b8 100644
--- a/indra/newview/lldrawpoolwlsky.cpp
+++ b/indra/newview/lldrawpoolwlsky.cpp
@@ -226,7 +226,7 @@ void LLDrawPoolWLSky::renderSkyHaze(const LLVector3& camPosLocal, F32 camHeightL
     }
 }
 
-void LLDrawPoolWLSky::renderStars(void) const
+void LLDrawPoolWLSky::renderStars(const LLVector3& camPosLocal) const
 {
     LLGLSPipelineBlendSkyBox gls_skybox(true, false);
 	
@@ -266,6 +266,7 @@ void LLDrawPoolWLSky::renderStars(void) const
     }
 
 	gGL.pushMatrix();
+	gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
 	gGL.rotatef(gFrameTimeSeconds*0.01f, 0.f, 0.f, 1.f);
 	if (LLGLSLShader::sNoFixedFunction)
 	{
@@ -296,7 +297,7 @@ void LLDrawPoolWLSky::renderStars(void) const
 	}
 }
 
-void LLDrawPoolWLSky::renderStarsDeferred(void) const
+void LLDrawPoolWLSky::renderStarsDeferred(const LLVector3& camPosLocal) const
 {
 	LLGLSPipelineBlendSkyBox gls_sky(true, false);
 
@@ -337,6 +338,8 @@ void LLDrawPoolWLSky::renderStarsDeferred(void) const
         gGL.getTexUnit(1)->bind(tex_b);
     }
 
+	gGL.pushMatrix();
+	gGL.translatef(camPosLocal.mV[0], camPosLocal.mV[1], camPosLocal.mV[2]);
     gDeferredStarProgram.uniform1f(LLShaderMgr::BLEND_FACTOR, blend_factor);
 
     if (LLPipeline::sReflectionRender)
@@ -355,6 +358,8 @@ void LLDrawPoolWLSky::renderStarsDeferred(void) const
     gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE);
 
     gDeferredStarProgram.unbind();
+
+	gGL.popMatrix();
 }
 
 void LLDrawPoolWLSky::renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const
@@ -601,7 +606,7 @@ void LLDrawPoolWLSky::renderDeferred(S32 pass)
     if (gPipeline.canUseWindLightShaders())
     {
         renderSkyHazeDeferred(origin, camHeightLocal);
-        renderStarsDeferred();
+        renderStarsDeferred(origin);
         renderHeavenlyBodies();
         renderSkyCloudsDeferred(origin, camHeightLocal, cloud_shader);
     }
@@ -620,7 +625,7 @@ void LLDrawPoolWLSky::render(S32 pass)
     LLVector3 const & origin = LLViewerCamera::getInstance()->getOrigin();
     
 	renderSkyHaze(origin, camHeightLocal);    
-    renderStars();
+    renderStars(origin);
     renderHeavenlyBodies();	
 	renderSkyClouds(origin, camHeightLocal, cloud_shader);
 
diff --git a/indra/newview/lldrawpoolwlsky.h b/indra/newview/lldrawpoolwlsky.h
index a4f176d6db7f3247e3bbeef48c355096c5683111..324886ed42f3db5854036094b72f2bf71ef6c731 100644
--- a/indra/newview/lldrawpoolwlsky.h
+++ b/indra/newview/lldrawpoolwlsky.h
@@ -78,8 +78,8 @@ class LLDrawPoolWLSky : public LLDrawPool {
 	void renderSkyHazeDeferred(const LLVector3& camPosLocal, F32 camHeightLocal) const;
     void renderSkyCloudsDeferred(const LLVector3& camPosLocal, F32 camHeightLocal, LLGLSLShader* cloudshader) const;
 
-    void renderStarsDeferred(void) const;
-	void renderStars(void) const;
+    void renderStarsDeferred(const LLVector3& camPosLocal) const;
+	void renderStars(const LLVector3& camPosLocal) const;
 	void renderHeavenlyBodies();    
 };
 
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index 89c20904c1143beef560abccfc0c4f49900a2990..8b8273d18304d4b259cfa477228d0680dc341389 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -56,13 +56,6 @@ LLViewerDynamicTexture::LLViewerDynamicTexture(S32 width, S32 height, S32 compon
 {
 	llassert((1 <= components) && (components <= 4));
 
-	if(gGLManager.mDebugGPU)
-	{
-		if(components == 3)
-		{
-			mComponents = 4 ; //convert to 32bits.
-		}
-	}
 	generateGLTexture();
 
 	llassert( 0 <= order && order < ORDER_COUNT );
@@ -211,7 +204,7 @@ void LLViewerDynamicTexture::postRender(BOOL success)
 BOOL LLViewerDynamicTexture::updateAllInstances()
 {
 	sNumRenders = 0;
-	if (gGLManager.mIsDisabled || LLPipeline::sMemAllocationThrottled)
+	if (gGLManager.mIsDisabled)
 	{
 		return TRUE;
 	}
diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp
index 9270bc6e9b9a9a7be40ddbc4892cfbf9ba178271..e9bf22b6fe9e0c468d1856b319453c3fc3e0244f 100644
--- a/indra/newview/llenvironment.cpp
+++ b/indra/newview/llenvironment.cpp
@@ -331,7 +331,7 @@ namespace
                 std::istringstream llsdData(llsdRaw);
                 if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length()))
                 {
-                    LL_WARNS() << "LLExperienceLogDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
+                    LL_WARNS() << "LLEnvironmentPushDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
                 }
             }
 
@@ -789,11 +789,11 @@ namespace
 }
 
 //=========================================================================
-const F32Seconds LLEnvironment::TRANSITION_INSTANT(0.0f);
-const F32Seconds LLEnvironment::TRANSITION_FAST(1.0f);
-const F32Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f);
-const F32Seconds LLEnvironment::TRANSITION_SLOW(10.0f);
-const F32Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);
+const F64Seconds LLEnvironment::TRANSITION_INSTANT(0.0f);
+const F64Seconds LLEnvironment::TRANSITION_FAST(1.0f);
+const F64Seconds LLEnvironment::TRANSITION_DEFAULT(5.0f);
+const F64Seconds LLEnvironment::TRANSITION_SLOW(10.0f);
+const F64Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f);
 
 const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb");
 const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("6c83e853-e7f8-cad7-8ee6-5f31c453721c");
@@ -1228,28 +1228,24 @@ void LLEnvironment::setEnvironment(LLEnvironment::EnvSelection_t env, const LLSe
 
 void LLEnvironment::setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version)
 {
-    setEnvironment(env, assetId, LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET);
+    setEnvironment(env, assetId, TRANSITION_DEFAULT, env_version);
 }
 
-
 void LLEnvironment::setEnvironment(EnvSelection_t env,
                                    const LLUUID &assetId,
-                                   LLSettingsDay::Seconds daylength,
-                                   LLSettingsDay::Seconds dayoffset,
+                                   LLSettingsBase::Seconds transition,
                                    S32 env_version)
 {
     LLSettingsVOBase::getSettingsAsset(assetId,
-        [this, env, daylength, dayoffset, env_version](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
+        [this, env, env_version, transition](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
         {
-            onSetEnvAssetLoaded(env, asset_id, settings, daylength, dayoffset, TRANSITION_DEFAULT, status, env_version);
+            onSetEnvAssetLoaded(env, asset_id, settings, transition, status, env_version);
         });
 }
 
 void LLEnvironment::onSetEnvAssetLoaded(EnvSelection_t env,
                                         LLUUID asset_id,
                                         LLSettingsBase::ptr_t settings,
-                                        LLSettingsDay::Seconds daylength,
-                                        LLSettingsDay::Seconds dayoffset,
                                         LLSettingsBase::Seconds transition,
                                         S32 status,
                                         S32 env_version)
@@ -1696,7 +1692,7 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI
         if (!envinfo->mDayCycle)
         {
             clearEnvironment(ENV_PARCEL);
-            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion);
+            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), TRANSITION_DEFAULT, envinfo->mEnvVersion);
             updateEnvironment();
         }
         else if (envinfo->mDayCycle->isTrackEmpty(LLSettingsDay::TRACK_WATER)
@@ -1704,7 +1700,7 @@ void LLEnvironment::recordEnvironment(S32 parcel_id, LLEnvironment::EnvironmentI
         {
             LL_WARNS("ENVIRONMENT") << "Invalid day cycle for region" << LL_ENDL;
             clearEnvironment(ENV_PARCEL);
-            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), LLSettingsDay::DEFAULT_DAYLENGTH, LLSettingsDay::DEFAULT_DAYOFFSET, envinfo->mEnvVersion);
+            setEnvironment(ENV_REGION, LLSettingsDay::GetDefaultAssetId(), TRANSITION_DEFAULT, envinfo->mEnvVersion);
             updateEnvironment();
         }
         else
@@ -2950,17 +2946,15 @@ bool LLEnvironment::loadFromSettings()
 
     if (env_data.has("day_id"))
     {
-        LLSettingsDay::Seconds length = LLSettingsDay::Seconds(env_data["day_length"].asInteger());
-        LLSettingsDay::Seconds offset = LLSettingsDay::Seconds(env_data["day_offset"].asInteger());
         LLUUID assetId = env_data["day_id"].asUUID();
 
         LLSettingsVOBase::getSettingsAsset(assetId,
-            [this, length, offset, env_data](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
+            [this, env_data](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat)
         {
             // Day should be always applied first,
             // otherwise it will override sky or water that was set earlier
             // so wait for asset to load before applying sky/water
-            onSetEnvAssetLoaded(ENV_LOCAL, asset_id, settings, length, offset, TRANSITION_DEFAULT, status, NO_VERSION);
+            onSetEnvAssetLoaded(ENV_LOCAL, asset_id, settings, TRANSITION_DEFAULT, status, NO_VERSION);
             bool valid = false, has_assets = false;
             loadSkyWaterFromSettings(env_data, valid, has_assets);
             if (!has_assets && valid)
diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h
index 080262aba1b233653bf53f2e280af16f2dff7d03..afe1c32150018bb804aac97c9f6d24d06857d92c 100644
--- a/indra/newview/llenvironment.h
+++ b/indra/newview/llenvironment.h
@@ -52,11 +52,11 @@ class LLEnvironment : public LLSingleton<LLEnvironment>
     LOG_CLASS(LLEnvironment);
 
 public:
-    static const F32Seconds     TRANSITION_INSTANT;
-    static const F32Seconds     TRANSITION_FAST;
-    static const F32Seconds     TRANSITION_DEFAULT;
-    static const F32Seconds     TRANSITION_SLOW;
-    static const F32Seconds     TRANSITION_ALTITUDE;
+    static const F64Seconds     TRANSITION_INSTANT;
+    static const F64Seconds     TRANSITION_FAST;
+    static const F64Seconds     TRANSITION_DEFAULT;
+    static const F64Seconds     TRANSITION_SLOW;
+    static const F64Seconds     TRANSITION_ALTITUDE;
 
     static const LLUUID         KNOWN_SKY_SUNRISE;
     static const LLUUID         KNOWN_SKY_MIDDAY;
@@ -144,8 +144,8 @@ class LLEnvironment : public LLSingleton<LLEnvironment>
     void                        setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixed, LLSettingsWater::ptr_t()), env_version); }
     void                        setEnvironment(EnvSelection_t env, const LLSettingsWater::ptr_t & fixed, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(LLSettingsSky::ptr_t(), fixed), env_version); }
     void                        setEnvironment(EnvSelection_t env, const LLSettingsSky::ptr_t & fixeds, const LLSettingsWater::ptr_t & fixedw, S32 env_version = NO_VERSION) { setEnvironment(env, fixedEnvironment_t(fixeds, fixedw), env_version); }
-    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, S32 env_version = NO_VERSION);
-    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version = NO_VERSION);
+    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, S32 env_version);
+    void                        setEnvironment(EnvSelection_t env, const LLUUID &assetId, LLSettingsBase::Seconds transition = TRANSITION_DEFAULT, S32 env_version = NO_VERSION);
 
     void                        setSharedEnvironment();
     void                        clearEnvironment(EnvSelection_t env);
@@ -443,7 +443,7 @@ class LLEnvironment : public LLSingleton<LLEnvironment>
 
     void                        onAgentPositionHasChanged(const LLVector3 &localpos);
 
-    void                        onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsDay::Seconds daylength, LLSettingsDay::Seconds dayoffset, LLSettingsBase::Seconds transition, S32 status, S32 env_version);
+    void                        onSetEnvAssetLoaded(EnvSelection_t env, LLUUID asset_id, LLSettingsBase::ptr_t settings, LLSettingsBase::Seconds transition, S32 status, S32 env_version);
     void                        onUpdateParcelAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, S32 parcel_id, S32 day_length, S32 day_offset, altitudes_vect_t altitudes);
 
     void                        handleEnvironmentPushClear(LLUUID experience_id, LLSD &message, F32 transition);
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 9a80313a6db831c13edc69d6d75aa5ff569dc5c9..529d5494deee01f12918166851ba69f9fcc6eace 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -38,6 +38,7 @@
 #include "lltooltip.h"
 
 #include "llagent.h"
+#include "llagentpicksinfo.h"
 #include "llavatarnamecache.h"
 #include "llclipboard.h"
 #include "llinventorybridge.h"
@@ -384,6 +385,8 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
 	mUpdateDropDownItems(true),
 	mRestoreOverflowMenu(false),
 	mGetPrevItems(true),
+	mMouseX(0),
+	mMouseY(0),
 	mItemsChangedTimer()
 {
 	// Register callback for menus with current registrar (will be parent panel's registrar)
@@ -399,8 +402,10 @@ LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
 	//make chevron button                                                                                                                               
 	LLTextBox::Params more_button_params(p.more_button);
 	mMoreTextBox = LLUICtrlFactory::create<LLTextBox> (more_button_params);
-	mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::showDropDownMenu, this));
+	mMoreTextBox->setClickedCallback(boost::bind(&LLFavoritesBarCtrl::onMoreTextBoxClicked, this));
 	addChild(mMoreTextBox);
+	LLRect rect = mMoreTextBox->getRect();
+	mMoreTextBox->setRect(LLRect(rect.mLeft - rect.getWidth(), rect.mTop, rect.mRight, rect.mBottom));
 
 	mDropDownItemsCount = 0;
 
@@ -978,6 +983,12 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it
 	return TRUE;
 }
 
+void LLFavoritesBarCtrl::onMoreTextBoxClicked()
+{
+	LLUI::getInstance()->getMousePositionScreen(&mMouseX, &mMouseY);
+	showDropDownMenu();
+}
+
 void LLFavoritesBarCtrl::showDropDownMenu()
 {
 	if (mOverflowMenuHandle.isDead())
@@ -1133,7 +1144,7 @@ void LLFavoritesBarCtrl::positionAndShowMenu(LLToggleableMenu* menu)
 		}
 	}
 
-	LLMenuGL::showPopup(this, menu, menu_x, menu_y);
+	LLMenuGL::showPopup(this, menu, menu_x, menu_y, mMouseX, mMouseY);
 }
 
 void LLFavoritesBarCtrl::onButtonClick(LLUUID item_id)
@@ -1197,6 +1208,10 @@ bool LLFavoritesBarCtrl::enableSelected(const LLSD& userdata)
     {
         return isClipboardPasteable();
     }
+    else if (param == "create_pick")
+    {
+        return !LLAgentPicksInfo::getInstance()->isPickLimitReached();
+    }
 
     return false;
 }
@@ -1245,6 +1260,13 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
 			LLFloaterReg::showInstance("world_map", "center");
 		}
 	}
+    else if (action == "create_pick")
+    {
+        LLSD args;
+        args["type"] = "create_pick";
+        args["item_id"] = item->getUUID();
+        LLFloaterSidePanelContainer::showPanel("places", args);
+    }
 	else if (action == "cut")
 	{
 	}
@@ -1260,6 +1282,20 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
 	{
 		gInventory.removeItem(mSelectedItemID);
 	}
+    else if (action == "rename")
+    {
+        LLSD args;
+        args["NAME"] = item->getName();
+
+        LLSD payload;
+        payload["id"] = mSelectedItemID;
+
+        LLNotificationsUtil::add("RenameLandmark", args, payload, boost::bind(onRenameCommit, _1, _2));
+    }
+	else if (action == "move_to_landmarks")
+	{
+		change_item_parent(mSelectedItemID, gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
+	}
 
 	// Pop-up the overflow menu again (it gets hidden whenever the user clicks a context menu item).
 	// See EXT-4217 and STORM-207.
@@ -1272,6 +1308,28 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
 	}
 }
 
+bool LLFavoritesBarCtrl::onRenameCommit(const LLSD& notification, const LLSD& response)
+{
+    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+    if (0 == option)
+    {
+        LLUUID id = notification["payload"]["id"].asUUID();
+        LLInventoryItem *item = gInventory.getItem(id);
+        std::string landmark_name = response["new_name"].asString();
+        LLStringUtil::trim(landmark_name);
+
+        if (!landmark_name.empty() && item && item->getName() != landmark_name)
+        {
+            LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
+            new_item->rename(landmark_name);
+            new_item->updateServer(FALSE);
+            gInventory.updateItem(new_item);
+        }
+    }
+
+    return false;
+}
+
 BOOL LLFavoritesBarCtrl::isClipboardPasteable() const
 {
 	if (!LLClipboard::instance().hasContents())
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 571208aa31b201f1c42e73c8cbf63668daa7eec7..3bb940948b8b291da7791a0145a40042c8d1b777 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -91,11 +91,14 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 
 	bool enableSelected(const LLSD& userdata);
 	void doToSelected(const LLSD& userdata);
+	static bool onRenameCommit(const LLSD& notification, const LLSD& response);
 	BOOL isClipboardPasteable() const;
 	void pasteFromClipboard() const;
 	
 	void showDropDownMenu();
 
+	void onMoreTextBoxClicked();
+
 	LLHandle<LLView> mOverflowMenuHandle;
 	LLHandle<LLView> mContextMenuHandle;
 
@@ -163,6 +166,9 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 
 	BOOL mTabsHighlightEnabled;
 
+	S32 mMouseX;
+	S32 mMouseY;
+
 	boost::signals2::connection mEndDragConnection;
 };
 
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index d915a9fd2695a7aeeff74afb75ba8a5612382c53..e6bbe234b3e56f93aca526375adecaa83c3f78d1 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -379,22 +379,6 @@ F32 gpu_benchmark();
 
 #if LL_WINDOWS
 
-static const U32 STATUS_MSC_EXCEPTION = 0xE06D7363; // compiler specific
-
-U32 exception_benchmark_filter(U32 code, struct _EXCEPTION_POINTERS *exception_infop)
-{
-    if (code == STATUS_MSC_EXCEPTION)
-    {
-        // C++ exception, go on
-        return EXCEPTION_CONTINUE_SEARCH;
-    }
-    else
-    {
-        // handle it
-        return EXCEPTION_EXECUTE_HANDLER;
-    }
-}
-
 F32 logExceptionBenchmark()
 {
     // Todo: make a wrapper/class for SEH exceptions
@@ -403,7 +387,7 @@ F32 logExceptionBenchmark()
     {
         gbps = gpu_benchmark();
     }
-    __except (exception_benchmark_filter(GetExceptionCode(), GetExceptionInformation()))
+    __except (msc_exception_filter(GetExceptionCode(), GetExceptionInformation()))
     {
         // convert to C++ styled exception
         char integer_string[32];
@@ -771,12 +755,7 @@ void LLFeatureManager::applyBaseMasks()
 		maskFeatures("RAM256MB");
 	}
 	
-#if LL_SOLARIS && defined(__sparc) 	//  even low MHz SPARCs are fast
-#error The 800 is hinky. Would something like a LL_MIN_MHZ make more sense here?
-	if (gSysCPU.getMHz() < 800)
-#else
 	if (gSysCPU.getMHz() < 1100)
-#endif
 	{
 		maskFeatures("CPUSlow");
 	}
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index b6fd70452e7dfee28f5b4a843c13ce3e6aea91fd..3669fb1eeb000e103e5a2187ac829b901d39a810 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -40,7 +40,7 @@
 #include "llwindowsdl.h" // for some X/GTK utils to help with filepickers
 #endif // LL_SDL
 
-#if LL_LINUX || LL_SOLARIS
+#if LL_LINUX
 #include "llhttpconstants.h"    // file picker uses some of thes constants on Linux
 #endif
 
@@ -939,7 +939,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename,
 }
 //END LL_DARWIN
 
-#elif LL_LINUX || LL_SOLARIS
+#elif LL_LINUX
 
 # if LL_GTK
 
@@ -1504,4 +1504,4 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
 	return FALSE;
 }
 
-#endif // LL_LINUX || LL_SOLARIS
+#endif // LL_LINUX
diff --git a/indra/newview/llfloateraddpaymentmethod.cpp b/indra/newview/llfloateraddpaymentmethod.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3952b482290ab42420aaff72777b3858624da0a8
--- /dev/null
+++ b/indra/newview/llfloateraddpaymentmethod.cpp
@@ -0,0 +1,81 @@
+/** 
+ * @file llfloateraddpaymentmethod.cpp
+ * @brief LLFloaterAddPaymentMethod class implementation
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloateraddpaymentmethod.h"
+#include "llnotificationsutil.h"
+#include "lluictrlfactory.h"
+#include "llweb.h"
+
+
+LLFloaterAddPaymentMethod::LLFloaterAddPaymentMethod(const LLSD& key)
+	:	LLFloater(key)
+{
+}
+
+LLFloaterAddPaymentMethod::~LLFloaterAddPaymentMethod()
+{
+}
+
+BOOL LLFloaterAddPaymentMethod::postBuild()
+{
+	setCanDrag(FALSE);
+	getChild<LLButton>("continue_btn")->setCommitCallback(boost::bind(&LLFloaterAddPaymentMethod::onContinueBtn, this));
+	getChild<LLButton>("close_btn")->setCommitCallback(boost::bind(&LLFloaterAddPaymentMethod::onCloseBtn, this));
+	return TRUE;
+}
+
+void LLFloaterAddPaymentMethod::onOpen(const LLSD& key)
+{
+	centerOnScreen();
+}
+
+void LLFloaterAddPaymentMethod::onContinueBtn()
+{
+	closeFloater();
+	LLNotificationsUtil::add("AddPaymentMethod", LLSD(), LLSD(),
+		[this](const LLSD&notif, const LLSD&resp)
+	{
+		S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+		if (opt == 0)
+		{
+			LLWeb::loadURL(this->getString("continue_url"));
+		}
+	}); 
+}
+
+void LLFloaterAddPaymentMethod::onCloseBtn()
+{
+	closeFloater();
+}
+
+void LLFloaterAddPaymentMethod::centerOnScreen()
+{
+	LLVector2 window_size = LLUI::getInstance()->getWindowSize();
+	centerWithin(LLRect(0, 0, ll_round(window_size.mV[VX]), ll_round(window_size.mV[VY])));
+}
+
diff --git a/indra/newview/llfloateraddpaymentmethod.h b/indra/newview/llfloateraddpaymentmethod.h
new file mode 100644
index 0000000000000000000000000000000000000000..b3bb624484370dd2e7386848989b374a8c8650e9
--- /dev/null
+++ b/indra/newview/llfloateraddpaymentmethod.h
@@ -0,0 +1,52 @@
+/** 
+ * @file llfloateraddpaymentmethod.h
+ * @brief LLFloaterAddPaymentMethod class definition
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FLOATER_ADDPAYMENTMETHOD_H
+#define LL_FLOATER_ADDPAYMENTMETHOD_H
+
+#include "llfloater.h"
+
+class LLFloaterAddPaymentMethod:
+	public LLFloater
+{
+	friend class LLFloaterReg;
+public:
+	/*virtual*/	BOOL postBuild();
+	/*virtual*/ void onOpen(const LLSD& key);
+
+private:
+	LLFloaterAddPaymentMethod(const LLSD& key);
+
+	void centerOnScreen();
+
+	void onCloseBtn();
+	void onContinueBtn();
+	
+	/*virtual*/	~LLFloaterAddPaymentMethod();
+
+};
+
+#endif
diff --git a/indra/newview/llfloaterbuy.cpp b/indra/newview/llfloaterbuy.cpp
index e530eb4bbff473f82ec65593a11c2196b10eb346..8ca1a7f0295f512fac5c912288dd14a5d878b353 100644
--- a/indra/newview/llfloaterbuy.cpp
+++ b/indra/newview/llfloaterbuy.cpp
@@ -49,7 +49,8 @@
 #include "lltrans.h"
 
 LLFloaterBuy::LLFloaterBuy(const LLSD& key)
-:	LLFloater(key)
+:	LLFloater(key),
+	mSelectionUpdateSlot()
 {
 }
 
@@ -182,12 +183,19 @@ void LLFloaterBuy::show(const LLSaleInfo& sale_info)
 	floater->getChild<LLUICtrl>("buy_text")->setTextArg("[AMOUNT]", llformat("%d", sale_info.getSalePrice()));
 	floater->getChild<LLUICtrl>("buy_name_text")->setTextArg("[NAME]", owner_name);
 
+	floater->showViews(true);
+
 	// Must do this after the floater is created, because
 	// sometimes the inventory is already there and 
 	// the callback is called immediately.
 	LLViewerObject* obj = selection->getFirstRootObject();
 	floater->registerVOInventoryListener(obj,NULL);
 	floater->requestVOInventory();
+
+	if (!floater->mSelectionUpdateSlot.connected())
+	{
+		floater->mSelectionUpdateSlot = LLSelectMgr::getInstance()->mUpdateSignal.connect(boost::bind(&LLFloaterBuy::onSelectionChanged, floater));
+	}
 }
 
 void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
@@ -283,6 +291,30 @@ void LLFloaterBuy::inventoryChanged(LLViewerObject* obj,
 	removeVOInventoryListener();
 }
 
+void LLFloaterBuy::onSelectionChanged()
+{
+	
+	if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() == 0)
+	{
+		removeVOInventoryListener();
+		closeFloater();
+	}
+	else if (LLSelectMgr::getInstance()->getEditSelection()->getRootObjectCount() > 1)
+	{
+		removeVOInventoryListener();
+		showViews(false);
+		reset();
+		setTitle(getString("mupliple_selected"));
+	}
+}
+
+void LLFloaterBuy::showViews(bool show)
+{
+	getChild<LLUICtrl>("buy_btn")->setEnabled(show);
+	getChild<LLUICtrl>("buy_text")->setVisible(show);
+	getChild<LLUICtrl>("buy_name_text")->setVisible(show);
+}
+
 void LLFloaterBuy::onClickBuy()
 {
 	// Put the items where we put new folders.
@@ -306,5 +338,10 @@ void LLFloaterBuy::onClickCancel()
 // virtual
 void LLFloaterBuy::onClose(bool app_quitting)
 {
+	if (mSelectionUpdateSlot.connected())
+	{
+		mSelectionUpdateSlot.disconnect();
+	}
+
 	mObjectSelection.clear();
 }
diff --git a/indra/newview/llfloaterbuy.h b/indra/newview/llfloaterbuy.h
index 3ec642dee1652db7334df71716e6c2eb38be0932..e83b3c6ba614469033ad36b1213947294281b9b3 100644
--- a/indra/newview/llfloaterbuy.h
+++ b/indra/newview/llfloaterbuy.h
@@ -63,12 +63,17 @@ class LLFloaterBuy
 								 S32 serial_num,
 								 void* data);
 
+	void onSelectionChanged();
+	void showViews(bool show);
+
 	void onClickBuy();
 	void onClickCancel();
 
 private:
 	LLSafeHandle<LLObjectSelection>	mObjectSelection;
 	LLSaleInfo mSaleInfo;
+
+	boost::signals2::connection mSelectionUpdateSlot;
 };
 
 #endif
diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index 1751d54b5a7ad2d8a874d08b685d212aa2193b44..0cfac166c7885dca115d1c7ecf2cf5e96f975bae 100644
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
@@ -32,6 +32,8 @@
 #include "llcurrencyuimanager.h"
 #include "llfloater.h"
 #include "llfloaterreg.h"
+#include "lllayoutstack.h"
+#include "lliconctrl.h"
 #include "llnotificationsutil.h"
 #include "llstatusbar.h"
 #include "lltextbox.h"
@@ -42,7 +44,6 @@
 #include "llwindow.h"
 #include "llappviewer.h"
 
-static const S32 STANDARD_BUY_AMOUNT = 2000;
 static const S32 MINIMUM_BALANCE_AMOUNT = 0;
 
 class LLFloaterBuyCurrencyUI
@@ -58,8 +59,8 @@ class LLFloaterBuyCurrencyUI
 	LLCurrencyUIManager	mManager;
 	
 	bool		mHasTarget;
-	std::string	mTargetName;
 	S32			mTargetPrice;
+	S32			mRequiredAmount;
 	
 public:
 	void noTarget();
@@ -68,6 +69,7 @@ class LLFloaterBuyCurrencyUI
 	virtual BOOL postBuild();
 	
 	void updateUI();
+	void collapsePanels(bool collapse);
 
 	virtual void draw();
 	virtual BOOL canClose();
@@ -92,7 +94,9 @@ LLFloater* LLFloaterBuyCurrency::buildFloater(const LLSD& key)
 LLFloaterBuyCurrencyUI::LLFloaterBuyCurrencyUI(const LLSD& key)
 :	LLFloater(key),
 	mChildren(*this),
-	mManager(*this)
+	mManager(*this),
+	mHasTarget(false),
+	mTargetPrice(0)
 {
 }
 
@@ -104,15 +108,20 @@ LLFloaterBuyCurrencyUI::~LLFloaterBuyCurrencyUI()
 void LLFloaterBuyCurrencyUI::noTarget()
 {
 	mHasTarget = false;
-	mManager.setAmount(STANDARD_BUY_AMOUNT);
+	mTargetPrice = 0;
+	mManager.setAmount(0);
 }
 
 void LLFloaterBuyCurrencyUI::target(const std::string& name, S32 price)
 {
 	mHasTarget = true;
-	mTargetName = name;
 	mTargetPrice = price;
 	
+	if (!name.empty())
+	{
+		getChild<LLUICtrl>("target_price_label")->setValue(name);
+	}
+
 	S32 balance = gStatusBar->getBalance();
 	S32 need = price - balance;
 	if (need < 0)
@@ -120,7 +129,8 @@ void LLFloaterBuyCurrencyUI::target(const std::string& name, S32 price)
 		need = 0;
 	}
 	
-	mManager.setAmount(need + MINIMUM_BALANCE_AMOUNT);
+	mRequiredAmount = need + MINIMUM_BALANCE_AMOUNT;
+	mManager.setAmount(0);
 }
 
 
@@ -175,7 +185,6 @@ void LLFloaterBuyCurrencyUI::updateUI()
 	getChildView("purchase_warning_repurchase")->setVisible(FALSE);
 	getChildView("purchase_warning_notenough")->setVisible(FALSE);
 	getChildView("contacting")->setVisible(FALSE);
-	getChildView("buy_action")->setVisible(FALSE);
 
 	if (hasError)
 	{
@@ -209,8 +218,8 @@ void LLFloaterBuyCurrencyUI::updateUI()
 		{
 			if (mHasTarget)
 			{
-				getChildView("buy_action")->setVisible( true);
-				getChild<LLUICtrl>("buy_action")->setTextArg("[ACTION]", mTargetName);
+				getChild<LLUICtrl>("target_price")->setTextArg("[AMT]", llformat("%d", mTargetPrice));
+				getChild<LLUICtrl>("required_amount")->setTextArg("[AMT]", llformat("%d", mRequiredAmount));
 			}
 		}
 		
@@ -231,18 +240,40 @@ void LLFloaterBuyCurrencyUI::updateUI()
 
 		if (mHasTarget)
 		{
-			if (total >= mTargetPrice)
-			{
-				getChildView("purchase_warning_repurchase")->setVisible( true);
-			}
-			else
-			{
-				getChildView("purchase_warning_notenough")->setVisible( true);
-			}
+			getChildView("purchase_warning_repurchase")->setVisible( !getChildView("currency_links")->getVisible());
 		}
 	}
 
-	getChildView("getting_data")->setVisible( !mManager.canBuy() && !hasError);
+	getChildView("getting_data")->setVisible( !mManager.canBuy() && !hasError && !getChildView("currency_est")->getVisible());
+}
+
+void LLFloaterBuyCurrencyUI::collapsePanels(bool collapse)
+{
+	LLLayoutPanel* price_panel = getChild<LLLayoutPanel>("layout_panel_price");
+	
+	if (price_panel->isCollapsed() == collapse)
+		return;
+	
+	LLLayoutStack* outer_stack = getChild<LLLayoutStack>("outer_stack");	
+	LLLayoutPanel* required_panel = getChild<LLLayoutPanel>("layout_panel_required");
+	LLLayoutPanel* msg_panel = getChild<LLLayoutPanel>("layout_panel_msg");
+
+	S32 delta_height = price_panel->getRect().getHeight() + required_panel->getRect().getHeight() + msg_panel->getRect().getHeight();
+	delta_height *= (collapse ? -1 : 1);
+
+	LLIconCtrl* icon = getChild<LLIconCtrl>("normal_background");
+	LLRect rect = icon->getRect();
+	icon->setRect(rect.setOriginAndSize(rect.mLeft, rect.mBottom - delta_height, rect.getWidth(), rect.getHeight() + delta_height));
+
+	outer_stack->collapsePanel(price_panel, collapse);
+	outer_stack->collapsePanel(required_panel, collapse);
+	outer_stack->collapsePanel(msg_panel, collapse);
+
+	outer_stack->updateLayout();
+
+	LLRect floater_rect = getRect();
+	floater_rect.mBottom -= delta_height;
+	setShape(floater_rect, false);
 }
 
 void LLFloaterBuyCurrencyUI::onClickBuy()
@@ -260,20 +291,72 @@ void LLFloaterBuyCurrencyUI::onClickCancel()
 	LLStatusBar::sendMoneyBalanceRequest();
 }
 
+LLFetchAvatarPaymentInfo* LLFloaterBuyCurrency::sPropertiesRequest = NULL;
+
 // static
 void LLFloaterBuyCurrency::buyCurrency()
 {
-	LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
-	ui->noTarget();
-	ui->updateUI();
+	delete sPropertiesRequest;
+	sPropertiesRequest = new LLFetchAvatarPaymentInfo(false);
 }
 
 // static
 void LLFloaterBuyCurrency::buyCurrency(const std::string& name, S32 price)
 {
-	LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
-	ui->target(name, price);
-	ui->updateUI();
+	delete sPropertiesRequest;
+	sPropertiesRequest = new LLFetchAvatarPaymentInfo(true, name, price);
+}
+
+// static
+void LLFloaterBuyCurrency::handleBuyCurrency(bool has_piof, bool has_target, const std::string name, S32 price)
+{
+	delete sPropertiesRequest;
+	sPropertiesRequest = NULL;
+
+	if (has_piof)
+	{
+		LLFloaterBuyCurrencyUI* ui = LLFloaterReg::showTypedInstance<LLFloaterBuyCurrencyUI>("buy_currency");
+		if (has_target)
+		{
+			ui->target(name, price);
+		}
+		else
+		{
+			ui->noTarget();			
+		}
+		ui->updateUI();
+		ui->collapsePanels(!has_target);
+	}
+	else
+	{
+		LLFloaterReg::showInstance("add_payment_method");
+	}
 }
 
+LLFetchAvatarPaymentInfo::LLFetchAvatarPaymentInfo(bool has_target, const std::string& name, S32 price)
+:	mAvatarID(gAgent.getID()),
+	mHasTarget(has_target),
+	mPrice(price),
+	mName(name)
+{
+	LLAvatarPropertiesProcessor* processor = LLAvatarPropertiesProcessor::getInstance();
+	// register ourselves as an observer
+	processor->addObserver(mAvatarID, this);
+	// send a request (duplicates will be suppressed inside the avatar
+	// properties processor)
+	processor->sendAvatarPropertiesRequest(mAvatarID);
+}
+
+LLFetchAvatarPaymentInfo::~LLFetchAvatarPaymentInfo()
+{
+	LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarID, this);
+}
 
+void LLFetchAvatarPaymentInfo::processProperties(void* data, EAvatarProcessorType type)
+{
+	if (data && type == APT_PROPERTIES)
+	{
+		LLAvatarData* avatar_data = static_cast<LLAvatarData*>(data);
+		LLFloaterBuyCurrency::handleBuyCurrency(LLAvatarPropertiesProcessor::hasPaymentInfoOnFile(avatar_data), mHasTarget, mName, mPrice);
+	}
+}
diff --git a/indra/newview/llfloaterbuycurrency.h b/indra/newview/llfloaterbuycurrency.h
index 7ff6c42384194141e32e777785522d5bae65a725..88d3d17cd6ac7c55087ba10574d75f3e64df152c 100644
--- a/indra/newview/llfloaterbuycurrency.h
+++ b/indra/newview/llfloaterbuycurrency.h
@@ -27,15 +27,34 @@
 #ifndef LL_LLFLOATERBUYCURRENCY_H
 #define LL_LLFLOATERBUYCURRENCY_H
 
+#include "llavatarpropertiesprocessor.h"
 #include "stdtypes.h"
-
+#include "llagent.h"
 class LLFloater;
 
+class LLFetchAvatarPaymentInfo : public LLAvatarPropertiesObserver
+{
+public:
+	LLFetchAvatarPaymentInfo(bool has_target, const std::string& name = std::string(), S32 price = 0);
+	~LLFetchAvatarPaymentInfo();
+
+	void processProperties(void* data, EAvatarProcessorType type);
+
+private:
+	LLUUID mAvatarID;
+	bool mHasTarget;
+	std::string mName;
+    S32 mPrice;
+};
+
+
 class LLFloaterBuyCurrency
 {
 public:
 	static void buyCurrency();
 	static void buyCurrency(const std::string& name, S32 price);
+
+		static void handleBuyCurrency(bool has_piof, bool has_target, const std::string name, S32 price);
 		/* name should be a noun phrase of the object or service being bought:
 				"That object costs"
 				"Trying to give"
@@ -44,7 +63,8 @@ class LLFloaterBuyCurrency
 		*/
 	
 	static LLFloater* buildFloater(const LLSD& key);
-};
 
+	static LLFetchAvatarPaymentInfo* sPropertiesRequest;
+};
 
 #endif
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index 941902c1faf91c5befee220b48895a81723aeb85..db7e6abe97ed95d40bad9bfd6419ecbb06491fbc 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -460,6 +460,7 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode)
 
 	switch (mode)
 	{
+	case CAMERA_CTRL_MODE_PRESETS:
 	case CAMERA_CTRL_MODE_PAN:
 		sFreeCamera = false;
 		clear_camera_tool();
@@ -470,13 +471,6 @@ void LLFloaterCamera::switchMode(ECameraControlMode mode)
 		activate_camera_tool();
 		break;
 
-	case CAMERA_CTRL_MODE_PRESETS:
-		if(sFreeCamera)
-		{
-			switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
-		}
-		break;
-
 	default:
 		//normally we won't occur here
 		llassert_always(FALSE);
@@ -531,7 +525,6 @@ void LLFloaterCamera::onClickCameraItem(const LLSD& param)
 		{
 			camera_floater->switchMode(CAMERA_CTRL_MODE_FREE_CAMERA);
 			camera_floater->updateItemsSelection();
-			camera_floater->fromFreeToPresets();
 		}
 	}
 	else
@@ -596,15 +589,7 @@ void LLFloaterCamera::switchToPreset(const std::string& name)
 	if (camera_floater)
 	{
 		camera_floater->updateItemsSelection();
-		camera_floater->fromFreeToPresets();
-	}
-}
-
-void LLFloaterCamera::fromFreeToPresets()
-{
-	if (!sFreeCamera && mCurrMode == CAMERA_CTRL_MODE_FREE_CAMERA && mPrevMode == CAMERA_CTRL_MODE_PRESETS)
-	{
-		switchMode(CAMERA_CTRL_MODE_PRESETS);
+		camera_floater->switchMode(CAMERA_CTRL_MODE_PRESETS);
 	}
 }
 
diff --git a/indra/newview/llfloatercamera.h b/indra/newview/llfloatercamera.h
index 9440f50c3fd15b6d8787702e6273d0b102f670b7..a69b87ad1626a6ffa1b72b8d413f072e824d5bd7 100644
--- a/indra/newview/llfloatercamera.h
+++ b/indra/newview/llfloatercamera.h
@@ -69,10 +69,6 @@ class LLFloaterCamera : public LLFloater
 	/*switch to one of the camera presets (front, rear, side)*/
 	static void switchToPreset(const std::string& name);
 
-	/* move to CAMERA_CTRL_MODE_PRESETS from CAMERA_CTRL_MODE_FREE_CAMERA if we are on presets panel and
-	   are not in free camera mode*/
-	void fromFreeToPresets();
-
 	virtual void onOpen(const LLSD& key);
 	virtual void onClose(bool app_quitting);
 
diff --git a/indra/newview/llfloatercreatelandmark.cpp b/indra/newview/llfloatercreatelandmark.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..eb93a6a75addf102481b68cc4df44b2b8895d1b0
--- /dev/null
+++ b/indra/newview/llfloatercreatelandmark.cpp
@@ -0,0 +1,323 @@
+/** 
+ * @file llfloatercreatelandmark.cpp
+ * @brief LLFloaterCreateLandmark class implementation
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatercreatelandmark.h"
+
+#include "llagent.h"
+#include "llagentui.h"
+#include "llcombobox.h"
+#include "llinventoryfunctions.h"
+#include "llinventoryobserver.h"
+#include "lllandmarkactions.h"
+#include "llnotificationsutil.h"
+#include "llpanellandmarkinfo.h"
+#include "llparcel.h"
+#include "lltextbox.h"
+#include "lltexteditor.h"
+#include "lluictrlfactory.h"
+#include "llviewermessage.h"
+#include "llviewerparcelmgr.h"
+#include "llviewerregion.h"
+
+typedef std::pair<LLUUID, std::string> folder_pair_t;
+
+class LLLandmarksInventoryObserver : public LLInventoryAddedObserver
+{
+public:
+	LLLandmarksInventoryObserver(LLFloaterCreateLandmark* create_landmark_floater) :
+		mFloater(create_landmark_floater)
+	{}
+
+protected:
+	/*virtual*/ void done()
+	{
+		mFloater->setItem(gInventory.getAddedIDs());
+	}
+
+private:
+	LLFloaterCreateLandmark* mFloater;
+};
+
+LLFloaterCreateLandmark::LLFloaterCreateLandmark(const LLSD& key)
+	:	LLFloater("add_landmark"),
+		mItem(NULL)
+{
+	mInventoryObserver = new LLLandmarksInventoryObserver(this);
+}
+
+LLFloaterCreateLandmark::~LLFloaterCreateLandmark()
+{
+	removeObserver();
+}
+
+BOOL LLFloaterCreateLandmark::postBuild()
+{
+	mFolderCombo = getChild<LLComboBox>("folder_combo");
+	mLandmarkTitleEditor = getChild<LLLineEditor>("title_editor");
+	mNotesEditor = getChild<LLTextEditor>("notes_editor");
+
+	getChild<LLTextBox>("new_folder_textbox")->setURLClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCreateFolderClicked, this));
+	getChild<LLButton>("ok_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onSaveClicked, this));
+	getChild<LLButton>("cancel_btn")->setClickedCallback(boost::bind(&LLFloaterCreateLandmark::onCancelClicked, this));
+
+	mLandmarksID = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
+
+	return TRUE;
+}
+
+void LLFloaterCreateLandmark::removeObserver()
+{
+	if (gInventory.containsObserver(mInventoryObserver))
+		gInventory.removeObserver(mInventoryObserver);
+}
+
+void LLFloaterCreateLandmark::onOpen(const LLSD& key)
+{
+	LLUUID dest_folder = LLUUID();
+	if (key.has("dest_folder"))
+	{
+		dest_folder = key["dest_folder"].asUUID();
+	}
+	mItem = NULL;
+	gInventory.addObserver(mInventoryObserver);
+	setLandmarkInfo(dest_folder);
+	populateFoldersList(dest_folder);
+}
+
+void LLFloaterCreateLandmark::setLandmarkInfo(const LLUUID &folder_id)
+{
+	LLViewerParcelMgr* parcel_mgr = LLViewerParcelMgr::getInstance();
+	LLParcel* parcel = parcel_mgr->getAgentParcel();
+	std::string name = parcel->getName();
+	LLVector3 agent_pos = gAgent.getPositionAgent();
+
+	if (name.empty())
+	{
+		S32 region_x = ll_round(agent_pos.mV[VX]);
+		S32 region_y = ll_round(agent_pos.mV[VY]);
+		S32 region_z = ll_round(agent_pos.mV[VZ]);
+
+		std::string region_name;
+		LLViewerRegion* region = parcel_mgr->getSelectionRegion();
+		if (region)
+		{
+			region_name = region->getName();
+		}
+		else
+		{
+			std::string desc;
+			LLAgentUI::buildLocationString(desc, LLAgentUI::LOCATION_FORMAT_NORMAL, agent_pos);
+			region_name = desc;
+		}
+
+		mLandmarkTitleEditor->setText(llformat("%s (%d, %d, %d)",
+			region_name.c_str(), region_x, region_y, region_z));
+	}
+	else
+	{
+		mLandmarkTitleEditor->setText(name);
+	}
+
+	LLLandmarkActions::createLandmarkHere(name, "", folder_id.notNull() ? folder_id : gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE));
+}
+
+bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
+{
+	return left.second < right.second;
+}
+
+void LLFloaterCreateLandmark::populateFoldersList(const LLUUID &folder_id)
+{
+	// Collect all folders that can contain landmarks.
+	LLInventoryModel::cat_array_t cats;
+	LLPanelLandmarkInfo::collectLandmarkFolders(cats);
+
+	mFolderCombo->removeall();
+
+	// Put the "My Favorites" folder first in list.
+	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+	LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
+	if (!favorites_cat)
+	{
+		LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL;
+	}
+	else
+	{
+		mFolderCombo->add(getString("favorites_bar"), favorites_cat->getUUID());
+	}
+
+	// Add the "Landmarks" category. 
+	const LLViewerInventoryCategory* lmcat = gInventory.getCategory(mLandmarksID);
+	if (!lmcat)
+	{
+		LL_WARNS() << "Cannot find the landmarks folder" << LL_ENDL;
+	}
+	else
+	{
+		std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(lmcat);
+		mFolderCombo->add(cat_full_name, lmcat->getUUID());
+	}
+
+	typedef std::vector<folder_pair_t> folder_vec_t;
+	folder_vec_t folders;
+	// Sort the folders by their full name.
+	for (S32 i = 0; i < cats.size(); i++)
+	{
+		const LLViewerInventoryCategory* cat = cats.at(i);
+		std::string cat_full_name = LLPanelLandmarkInfo::getFullFolderName(cat);
+		folders.push_back(folder_pair_t(cat->getUUID(), cat_full_name));
+	}
+	sort(folders.begin(), folders.end(), cmp_folders);
+
+	// Finally, populate the combobox.
+	for (folder_vec_t::const_iterator it = folders.begin(); it != folders.end(); it++)
+		mFolderCombo->add(it->second, LLSD(it->first));
+
+	if (folder_id.notNull())
+	{
+		mFolderCombo->setCurrentByID(folder_id);
+	}
+}
+
+void LLFloaterCreateLandmark::onCreateFolderClicked()
+{
+	LLNotificationsUtil::add("CreateLandmarkFolder", LLSD(), LLSD(),
+		[this](const LLSD&notif, const LLSD&resp)
+	{
+		S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+		if (opt == 0)
+		{
+			std::string folder_name = resp["message"].asString();
+			if (!folder_name.empty())
+			{
+				inventory_func_type func = boost::bind(&LLFloaterCreateLandmark::folderCreatedCallback, this, _1);
+				gInventory.createNewCategory(mLandmarksID, LLFolderType::FT_NONE, folder_name, func);
+				gInventory.notifyObservers();
+			}
+		}
+	}); 
+}
+
+void LLFloaterCreateLandmark::folderCreatedCallback(LLUUID folder_id)
+{
+	populateFoldersList(folder_id);
+}
+
+void LLFloaterCreateLandmark::onSaveClicked()
+{
+	if (mItem.isNull())
+	{
+		closeFloater();
+		return;
+	}
+		
+
+	std::string current_title_value = mLandmarkTitleEditor->getText();
+	std::string item_title_value = mItem->getName();
+	std::string current_notes_value = mNotesEditor->getText();
+	std::string item_notes_value = mItem->getDescription();
+
+	LLStringUtil::trim(current_title_value);
+	LLStringUtil::trim(current_notes_value);
+
+	LLUUID item_id = mItem->getUUID();
+	LLUUID folder_id = mFolderCombo->getValue().asUUID();
+	bool change_parent = folder_id != mItem->getParentUUID();
+
+	LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(mItem);
+
+	if (!current_title_value.empty() &&
+		(item_title_value != current_title_value || item_notes_value != current_notes_value))
+	{
+		new_item->rename(current_title_value);
+		new_item->setDescription(current_notes_value);
+		LLPointer<LLInventoryCallback> cb;
+		if (change_parent)
+		{
+			cb = new LLUpdateLandmarkParent(new_item, folder_id);
+		}
+		LLInventoryModel::LLCategoryUpdate up(mItem->getParentUUID(), 0);
+		gInventory.accountForUpdate(up);
+		update_inventory_item(new_item, cb);
+	}
+	else if (change_parent)
+	{
+		LLInventoryModel::update_list_t update;
+		LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(),-1);
+		update.push_back(old_folder);
+		LLInventoryModel::LLCategoryUpdate new_folder(folder_id, 1);
+		update.push_back(new_folder);
+		gInventory.accountForUpdate(update);
+
+		new_item->setParent(folder_id);
+		new_item->updateParentOnServer(FALSE);
+	}
+
+	gInventory.updateItem(new_item);
+	gInventory.notifyObservers();
+
+	closeFloater();
+}
+
+void LLFloaterCreateLandmark::onCancelClicked()
+{
+	if (!mItem.isNull())
+	{
+		LLUUID item_id = mItem->getUUID();
+		remove_inventory_item(item_id, NULL);
+	}
+	closeFloater();
+}
+
+
+void LLFloaterCreateLandmark::setItem(const uuid_set_t& items)
+{
+	for (uuid_set_t::const_iterator item_iter = items.begin();
+		item_iter != items.end();
+		++item_iter)
+	{
+		const LLUUID& item_id = (*item_iter);
+		if(!highlight_offered_object(item_id))
+		{
+			continue;
+		}
+
+		LLInventoryItem* item = gInventory.getItem(item_id);
+
+		llassert(item);
+		if (item && (LLAssetType::AT_LANDMARK == item->getType()) )
+		{
+			if(!getItem())
+			{
+				removeObserver();
+				mItem = item;
+				break;
+			}
+		}
+	}
+}
\ No newline at end of file
diff --git a/indra/newview/llfloatercreatelandmark.h b/indra/newview/llfloatercreatelandmark.h
new file mode 100644
index 0000000000000000000000000000000000000000..74ac5e651c1a21bc3599089ee45de27170b4ccb1
--- /dev/null
+++ b/indra/newview/llfloatercreatelandmark.h
@@ -0,0 +1,74 @@
+/** 
+ * @file llfloatercreatelandmark.h
+ * @brief LLFloaterCreateLandmark class definition
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERCREATELANDMARK_H
+#define LL_LLFLOATERCREATELANDMARK_H
+
+#include "llfloater.h"
+
+class LLComboBox;
+class LLInventoryItem;
+class LLLineEditor;
+class LLTextEditor;
+class LLLandmarksInventoryObserver;
+
+class LLFloaterCreateLandmark:
+	public LLFloater
+{
+	friend class LLFloaterReg;
+
+public:
+
+	LLFloaterCreateLandmark(const LLSD& key);
+	~LLFloaterCreateLandmark();
+
+	BOOL postBuild();
+	void onOpen(const LLSD& key);
+
+	void setItem(const uuid_set_t& items);
+
+	LLInventoryItem* getItem() { return mItem; }
+
+private:
+	void setLandmarkInfo(const LLUUID &folder_id);
+	void removeObserver();
+	void populateFoldersList(const LLUUID &folder_id = LLUUID::null);
+	void onCreateFolderClicked();
+	void onSaveClicked();
+	void onCancelClicked();
+
+	void folderCreatedCallback(LLUUID folder_id);
+
+	LLComboBox*		mFolderCombo;
+	LLLineEditor*	mLandmarkTitleEditor;
+	LLTextEditor*	mNotesEditor;
+	LLUUID			mLandmarksID;
+
+	LLLandmarksInventoryObserver*	mInventoryObserver;
+	LLPointer<LLInventoryItem>		mItem;
+};
+
+#endif
diff --git a/indra/newview/llfloatereditenvironmentbase.cpp b/indra/newview/llfloatereditenvironmentbase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e888144b6aa104f5a5cd0ebebd02d8f1a3204d0e
--- /dev/null
+++ b/indra/newview/llfloatereditenvironmentbase.cpp
@@ -0,0 +1,479 @@
+/** 
+ * @file llfloatereditenvironmentbase.cpp
+ * @brief Floaters to create and edit fixed settings for sky and water.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloatereditenvironmentbase.h"
+
+#include <boost/make_shared.hpp>
+
+// libs
+#include "llnotifications.h"
+#include "llnotificationsutil.h"
+#include "llfilepicker.h"
+#include "llsettingspicker.h"
+#include "llviewerparcelmgr.h"
+
+// newview
+#include "llsettingssky.h"
+#include "llsettingswater.h"
+
+#include "llenvironment.h"
+#include "llagent.h"
+#include "llparcel.h"
+
+#include "llsettingsvo.h"
+#include "llinventorymodel.h"
+
+namespace
+{
+    const std::string ACTION_APPLY_LOCAL("apply_local");
+    const std::string ACTION_APPLY_PARCEL("apply_parcel");
+    const std::string ACTION_APPLY_REGION("apply_region");
+}
+
+//=========================================================================
+const std::string LLFloaterEditEnvironmentBase::KEY_INVENTORY_ID("inventory_id");
+
+
+//=========================================================================
+
+class LLFixedSettingCopiedCallback : public LLInventoryCallback
+{
+public:
+    LLFixedSettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {}
+
+    virtual void fire(const LLUUID& inv_item_id)
+    {
+        if (!mHandle.isDead())
+        {
+            LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
+            if (item)
+            {
+                LLFloaterEditEnvironmentBase* floater = (LLFloaterEditEnvironmentBase*)mHandle.get();
+                floater->onInventoryCreated(item->getAssetUUID(), inv_item_id);
+            }
+        }
+    }
+
+private:
+    LLHandle<LLFloater> mHandle;
+};
+
+//=========================================================================
+LLFloaterEditEnvironmentBase::LLFloaterEditEnvironmentBase(const LLSD &key) :
+    LLFloater(key),
+    mInventoryId(),
+    mInventoryItem(nullptr),
+    mIsDirty(false),
+    mCanCopy(false),
+    mCanMod(false),
+    mCanTrans(false),
+    mCanSave(false)
+{
+}
+
+LLFloaterEditEnvironmentBase::~LLFloaterEditEnvironmentBase()
+{
+}
+
+void LLFloaterEditEnvironmentBase::onFocusReceived()
+{
+    if (isInVisibleChain())
+    {
+        updateEditEnvironment();
+        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
+    }
+}
+
+void LLFloaterEditEnvironmentBase::onFocusLost()
+{
+}
+
+void LLFloaterEditEnvironmentBase::loadInventoryItem(const LLUUID  &inventoryId, bool can_trans)
+{
+    if (inventoryId.isNull())
+    {
+        mInventoryItem = nullptr;
+        mInventoryId.setNull();
+        mCanMod = true;
+        mCanCopy = true;
+        mCanTrans = true;
+        return;
+    }
+
+    mInventoryId = inventoryId;
+    LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL;
+    mInventoryItem = gInventory.getItem(mInventoryId);
+
+    if (!mInventoryItem)
+    {
+        LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL;
+        LLNotificationsUtil::add("CantFindInvItem");
+        closeFloater();
+
+        mInventoryId.setNull();
+        mInventoryItem = nullptr;
+        return;
+    }
+
+    if (mInventoryItem->getAssetUUID().isNull())
+    {
+        LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL;
+        LLNotificationsUtil::add("UnableEditItem");
+        closeFloater();
+
+        mInventoryId.setNull();
+        mInventoryItem = nullptr;
+        return;
+    }
+
+    mCanSave = true;
+    mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
+    mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
+    mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
+
+    mExpectingAssetId = mInventoryItem->getAssetUUID();
+    LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
+        [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
+}
+
+
+void LLFloaterEditEnvironmentBase::checkAndConfirmSettingsLoss(LLFloaterEditEnvironmentBase::on_confirm_fn cb)
+{
+    if (isDirty())
+    {
+        LLSD args(LLSDMap("TYPE", getEditSettings()->getSettingsType())
+            ("NAME", getEditSettings()->getName()));
+
+        // create and show confirmation textbox
+        LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(),
+            [cb](const LLSD&notif, const LLSD&resp)
+            {
+                S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
+                if (opt == 0)
+                    cb();
+            });
+    }
+    else if (cb)
+    {
+        cb();
+    }
+}
+
+void LLFloaterEditEnvironmentBase::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status)
+{
+    if (asset_id != mExpectingAssetId)
+    {
+        LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL;
+        return;
+    }
+    mExpectingAssetId.setNull();
+    clearDirtyFlag();
+
+    if (!settings || status)
+    {
+        LLSD args;
+        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString();
+        LLNotificationsUtil::add("FailedToFindSettings", args);
+        closeFloater();
+        return;
+    }
+
+    if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE))
+    {
+        mCanSave = false;
+        mCanCopy = false;
+        mCanMod = false;
+        mCanTrans = false;
+    }
+    else
+    {
+        if (mInventoryItem)
+            settings->setName(mInventoryItem->getName());
+
+        if (mCanCopy)
+            settings->clearFlag(LLSettingsBase::FLAG_NOCOPY);
+        else
+            settings->setFlag(LLSettingsBase::FLAG_NOCOPY);
+
+        if (mCanMod)
+            settings->clearFlag(LLSettingsBase::FLAG_NOMOD);
+        else
+            settings->setFlag(LLSettingsBase::FLAG_NOMOD);
+
+        if (mCanTrans)
+            settings->clearFlag(LLSettingsBase::FLAG_NOTRANS);
+        else
+            settings->setFlag(LLSettingsBase::FLAG_NOTRANS);
+    }
+
+    setEditSettingsAndUpdate(settings);
+}
+
+void LLFloaterEditEnvironmentBase::onButtonImport()
+{
+    checkAndConfirmSettingsLoss([this](){ doImportFromDisk(); });
+}
+
+void LLFloaterEditEnvironmentBase::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings)
+{
+    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+    if (0 == option)
+    {
+        std::string settings_name = response["message"].asString();
+
+        LLInventoryObject::correctInventoryName(settings_name);
+        if (settings_name.empty())
+        {
+            // Ideally notification should disable 'OK' button if name won't fit our requirements,
+            // for now either display notification, or use some default name
+            settings_name = "Unnamed";
+        }
+
+        if (mCanMod)
+        {
+            doApplyCreateNewInventory(settings_name, settings);
+        }
+        else if (mInventoryItem)
+        {
+            const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
+            LLUUID parent_id = mInventoryItem->getParentUUID();
+            if (marketplacelistings_id == parent_id)
+            {
+                parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+            }
+
+            LLPointer<LLInventoryCallback> cb = new LLFixedSettingCopiedCallback(getHandle());
+            copy_inventory_item(
+                gAgent.getID(),
+                mInventoryItem->getPermissions().getOwner(),
+                mInventoryItem->getUUID(),
+                parent_id,
+                settings_name,
+                cb);
+        }
+        else
+        {
+            LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL;
+        }
+    }
+}
+
+void LLFloaterEditEnvironmentBase::onClickCloseBtn(bool app_quitting)
+{
+    if (!app_quitting)
+        checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); });
+    else
+        closeFloater();
+}
+
+void LLFloaterEditEnvironmentBase::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings)
+{
+    if (mInventoryItem)
+    {
+        LLUUID parent_id = mInventoryItem->getParentUUID();
+        U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner();
+        LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name,
+            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+    }
+    else
+    {
+        LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
+        // This method knows what sort of settings object to create.
+        LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name,
+            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+    }
+}
+
+void LLFloaterEditEnvironmentBase::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings)
+{
+    LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL;
+    if (mInventoryId.isNull())
+    {
+        LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(),
+            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
+    }
+    else
+    {
+        LLSettingsVOBase::updateInventoryItem(settings, mInventoryId,
+            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); });
+    }
+}
+
+void LLFloaterEditEnvironmentBase::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings)
+{
+    U32 flags(0);
+
+    if (mInventoryItem)
+    {
+        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
+            flags |= LLSettingsBase::FLAG_NOMOD;
+        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+            flags |= LLSettingsBase::FLAG_NOTRANS;
+    }
+
+    flags |= settings->getFlags();
+    settings->setFlag(flags);
+
+    if (where == ACTION_APPLY_LOCAL)
+    {
+        settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy.
+        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings);
+    }
+    else if (where == ACTION_APPLY_PARCEL)
+    {
+        LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel());
+
+        if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID))
+        {
+            LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL;
+            LLNotificationsUtil::add("WLParcelApplyFail");
+            return;
+        }
+
+        if (mInventoryItem && !isDirty())
+        {
+            LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
+        }
+        else if (settings->getSettingsType() == "sky")
+        {
+            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(settings), -1, -1);
+        }
+        else if (settings->getSettingsType() == "water")
+        {
+            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(settings), -1, -1);
+        }
+        else if (settings->getSettingsType() == "day")
+        {
+            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsDay>(settings), -1, -1);
+        }
+    }
+    else if (where == ACTION_APPLY_REGION)
+    {
+        if (mInventoryItem && !isDirty())
+        {
+            LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
+        }
+        else if (settings->getSettingsType() == "sky")
+        {
+            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(settings), -1, -1);
+        }
+        else if (settings->getSettingsType() == "water")
+        {
+            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(settings), -1, -1);
+        }
+        else if (settings->getSettingsType() == "day")
+        {
+            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsDay>(settings), -1, -1);
+        }
+    }
+    else
+    {
+        LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL;
+        return;
+    }
+
+}
+
+void LLFloaterEditEnvironmentBase::doCloseInventoryFloater(bool quitting)
+{
+    LLFloater* floaterp = mInventoryFloater.get();
+
+    if (floaterp)
+    {
+        floaterp->closeFloater(quitting);
+    }
+}
+
+void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+    LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL;
+
+    if (inventory_id.isNull() || !results["success"].asBoolean())
+    {
+        LLNotificationsUtil::add("CantCreateInventory");
+        return;
+    }
+    onInventoryCreated(asset_id, inventory_id);
+}
+
+void LLFloaterEditEnvironmentBase::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id)
+{
+    bool can_trans = true;
+    if (mInventoryItem)
+    {
+        LLPermissions perms = mInventoryItem->getPermissions();
+
+        LLInventoryItem *created_item = gInventory.getItem(mInventoryId);
+
+        if (created_item)
+        {
+            can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID());
+            created_item->setPermissions(perms);
+            created_item->updateServer(false);
+        }
+    }
+
+    clearDirtyFlag();
+    setFocus(TRUE);                 // Call back the focus...
+    loadInventoryItem(inventory_id, can_trans);
+}
+
+void LLFloaterEditEnvironmentBase::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
+{
+    LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL;
+
+    clearDirtyFlag();
+    if (inventory_id != mInventoryId)
+    {
+        loadInventoryItem(inventory_id);
+    }
+}
+
+void LLFloaterEditEnvironmentBase::onPanelDirtyFlagChanged(bool value)
+{
+    if (value)
+        setDirtyFlag();
+}
+
+//-------------------------------------------------------------------------
+bool LLFloaterEditEnvironmentBase::canUseInventory() const
+{
+    return LLEnvironment::instance().isInventoryEnabled();
+}
+
+bool LLFloaterEditEnvironmentBase::canApplyRegion() const
+{
+    return gAgent.canManageEstate();
+}
+
+bool LLFloaterEditEnvironmentBase::canApplyParcel() const
+{
+    return LLEnvironment::instance().canAgentUpdateParcelEnvironment();
+}
+
+//=========================================================================
diff --git a/indra/newview/llfloatereditenvironmentbase.h b/indra/newview/llfloatereditenvironmentbase.h
new file mode 100644
index 0000000000000000000000000000000000000000..7c7cf5bdcd7d1a3e524e2ac59d37297ba249faf7
--- /dev/null
+++ b/indra/newview/llfloatereditenvironmentbase.h
@@ -0,0 +1,148 @@
+/** 
+ * @file llfloatereditenvironmentbase.h
+ * @brief Floaters to create and edit fixed settings for sky and water.
+ *
+ * $LicenseInfo:firstyear=2011&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_FLOATEREDITENVIRONMENTBASE_H
+#define LL_FLOATEREDITENVIRONMENTBASE_H
+
+#include "llfloater.h"
+#include "llsettingsbase.h"
+#include "llflyoutcombobtn.h"
+#include "llinventory.h"
+
+#include "boost/signals2.hpp"
+
+class LLTabContainer;
+class LLButton;
+class LLLineEditor;
+class LLFloaterSettingsPicker;
+class LLFixedSettingCopiedCallback;
+
+class LLFloaterEditEnvironmentBase : public LLFloater
+{
+    LOG_CLASS(LLFloaterEditEnvironmentBase);
+
+    friend class LLFixedSettingCopiedCallback;
+
+public:
+    static const std::string    KEY_INVENTORY_ID;
+
+                            LLFloaterEditEnvironmentBase(const LLSD &key);
+                            ~LLFloaterEditEnvironmentBase();
+
+    virtual void            onFocusReceived()           override;
+    virtual void            onFocusLost()               override;
+    
+    virtual LLSettingsBase::ptr_t   getEditSettings()   const = 0;
+
+    virtual BOOL            isDirty() const override            { return getIsDirty(); }
+
+protected:
+    typedef std::function<void()> on_confirm_fn;
+
+    virtual void            setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) = 0;
+    virtual void            updateEditEnvironment() = 0;
+
+    virtual LLFloaterSettingsPicker *getSettingsPicker() = 0;
+
+    void                    loadInventoryItem(const LLUUID  &inventoryId, bool can_trans = true);
+
+    void                    checkAndConfirmSettingsLoss(on_confirm_fn cb);
+
+    virtual void            doImportFromDisk() = 0;
+    virtual void            doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings);
+    virtual void            doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings);
+    virtual void            doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings);
+    void                    doCloseInventoryFloater(bool quitting = false);
+
+    bool                    canUseInventory() const;
+    bool                    canApplyRegion() const;
+    bool                    canApplyParcel() const;
+
+    LLUUID                  mInventoryId;
+    LLInventoryItem *       mInventoryItem;
+    LLHandle<LLFloater>     mInventoryFloater;
+    bool                    mCanCopy;
+    bool                    mCanMod;
+    bool                    mCanTrans;
+    bool                    mCanSave;
+
+    bool                    mIsDirty;
+
+    void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
+    void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+    void                    onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
+
+    bool                    getIsDirty() const  { return mIsDirty; }
+    void                    setDirtyFlag()      { mIsDirty = true; }
+    virtual void            clearDirtyFlag() = 0;
+
+    void                    onPanelDirtyFlagChanged(bool);
+
+    virtual void            onClickCloseBtn(bool app_quitting = false) override;
+    void                    onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings);
+    void                    onButtonImport();
+
+    void                    onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status);
+
+private:
+    LLUUID                  mExpectingAssetId; // for asset load confirmation
+};
+
+class LLSettingsEditPanel : public LLPanel
+{
+public:
+    virtual void setSettings(const LLSettingsBase::ptr_t &) = 0;
+
+    typedef boost::signals2::signal<void(LLPanel *, bool)> on_dirty_charged_sg;
+    typedef boost::signals2::connection connection_t;
+
+    inline bool         getIsDirty() const      { return mIsDirty; }
+    inline void         setIsDirty()            { mIsDirty = true; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); }
+    inline void         clearIsDirty()          { mIsDirty = false; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); }
+
+    inline bool        getCanChangeSettings() const    { return mCanEdit; }
+    inline void        setCanChangeSettings(bool flag) { mCanEdit = flag; }
+
+    inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb)    { return mOnDirtyChanged.connect(cb); }
+
+
+protected:
+    LLSettingsEditPanel() :
+        LLPanel(),
+        mIsDirty(false),
+        mOnDirtyChanged()
+    {}
+
+private:
+    void onTextureChanged(LLUUID &inventory_item_id);
+
+    bool                mIsDirty;
+    bool                mCanEdit;
+    
+    on_dirty_charged_sg mOnDirtyChanged;
+};
+
+#endif // LL_FLOATERENVIRONMENTBASE_H
diff --git a/indra/newview/llfloatereditextdaycycle.cpp b/indra/newview/llfloatereditextdaycycle.cpp
index a7c2cbbeaa2d5e2f3c4948e63eb35821f97bff71..0501c287ad96605235339968a20d9e036752816e 100644
--- a/indra/newview/llfloatereditextdaycycle.cpp
+++ b/indra/newview/llfloatereditextdaycycle.cpp
@@ -125,7 +125,6 @@ namespace {
 }
 
 //=========================================================================
-const std::string LLFloaterEditExtDayCycle::KEY_INVENTORY_ID("inventory_id");
 const std::string LLFloaterEditExtDayCycle::KEY_EDIT_CONTEXT("edit_context");
 const std::string LLFloaterEditExtDayCycle::KEY_DAY_LENGTH("day_length");
 const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod");
@@ -133,7 +132,7 @@ const std::string LLFloaterEditExtDayCycle::KEY_CANMOD("canmod");
 const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_INVENTORY("inventory");
 const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_PARCEL("parcel");
 const std::string LLFloaterEditExtDayCycle::VALUE_CONTEXT_REGION("region");
-
+/*
 //=========================================================================
 
 class LLDaySettingCopiedCallback : public LLInventoryCallback
@@ -156,12 +155,12 @@ class LLDaySettingCopiedCallback : public LLInventoryCallback
 
 private:
     LLHandle<LLFloater> mHandle;
-};
+};*/
 
 //=========================================================================
 
 LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :
-    LLFloater(key),
+    LLFloaterEditEnvironmentBase(key),
     mFlyoutControl(nullptr),
     mDayLength(0),
     mCurrentTrack(1),
@@ -170,19 +169,12 @@ LLFloaterEditExtDayCycle::LLFloaterEditExtDayCycle(const LLSD &key) :
     mFramesSlider(nullptr),
     mCurrentTimeLabel(nullptr),
     mImportButton(nullptr),
-    mInventoryId(),
-    mInventoryItem(nullptr),
     mLoadFrame(nullptr),
     mSkyBlender(),
     mWaterBlender(),
     mScratchSky(),
     mScratchWater(),
     mIsPlaying(false),
-    mIsDirty(false),
-    mCanSave(false),
-    mCanCopy(false),
-    mCanMod(false),
-    mCanTrans(false),
     mCloneTrack(nullptr),
     mLoadTrack(nullptr),
     mClearTrack(nullptr)
@@ -425,19 +417,6 @@ void LLFloaterEditExtDayCycle::onClose(bool app_quitting)
     }
 }
 
-void LLFloaterEditExtDayCycle::onFocusReceived()
-{
-    if (isInVisibleChain())
-    {
-        updateEditEnvironment();
-        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
-    }
-}
-
-void LLFloaterEditExtDayCycle::onFocusLost()
-{
-}
-
 
 void LLFloaterEditExtDayCycle::onVisibilityChange(BOOL new_visibility)
 {
@@ -488,6 +467,10 @@ void LLFloaterEditExtDayCycle::refresh()
     LLFloater::refresh();
 }
 
+void LLFloaterEditExtDayCycle::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings)
+{
+    setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings));
+}
 
 void LLFloaterEditExtDayCycle::setEditDayCycle(const LLSettingsDay::ptr_t &pday)
 {
@@ -700,63 +683,6 @@ void LLFloaterEditExtDayCycle::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
     }
 }
 
-void LLFloaterEditExtDayCycle::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day)
-{
-    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-    if (0 == option)
-    {
-        std::string settings_name = response["message"].asString();
-
-        LLInventoryObject::correctInventoryName(settings_name);
-        if (settings_name.empty())
-        {
-            // Ideally notification should disable 'OK' button if name won't fit our requirements,
-            // for now either display notification, or use some default name
-            settings_name = "Unnamed";
-        }
-
-        if (mCanMod)
-        {
-            doApplyCreateNewInventory(day, settings_name);
-        }
-        else if (mInventoryItem)
-        {
-            const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
-            LLUUID parent_id = mInventoryItem->getParentUUID();
-            if (marketplacelistings_id == parent_id)
-            {
-                parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
-            }
-
-            LLPointer<LLInventoryCallback> cb = new LLDaySettingCopiedCallback(getHandle());
-            copy_inventory_item(
-                gAgent.getID(),
-                mInventoryItem->getPermissions().getOwner(),
-                mInventoryItem->getUUID(),
-                parent_id,
-                settings_name,
-                cb);
-        }
-        else
-        {
-            LL_WARNS() << "Failed to copy day setting" << LL_ENDL;
-        }
-    }
-}
-
-void LLFloaterEditExtDayCycle::onClickCloseBtn(bool app_quitting /*= false*/)
-{
-    if (!app_quitting)
-        checkAndConfirmSettingsLoss([this](){ closeFloater(); clearDirtyFlag(); });
-    else
-        closeFloater();
-}
-
-void LLFloaterEditExtDayCycle::onButtonImport()
-{
-    checkAndConfirmSettingsLoss([this]() { doImportFromDisk(); });
-}
-
 void LLFloaterEditExtDayCycle::onButtonLoadFrame()
 {
     doOpenInventoryFloater((mCurrentTrack == LLSettingsDay::TRACK_WATER) ? LLSettingsType::ST_WATER : LLSettingsType::ST_SKY, LLUUID::null);
@@ -1053,35 +979,6 @@ void LLFloaterEditExtDayCycle::onFrameSliderMouseUp(S32 x, S32 y, MASK mask)
     selectFrame(sliderpos, LLSettingsDay::DEFAULT_FRAME_SLOP_FACTOR);
 }
 
-
-void LLFloaterEditExtDayCycle::onPanelDirtyFlagChanged(bool value)
-{
-    if (value)
-        setDirtyFlag();
-}
-
-void LLFloaterEditExtDayCycle::checkAndConfirmSettingsLoss(on_confirm_fn cb)
-{
-    if (isDirty())
-    {
-        LLSD args(LLSDMap("TYPE", mEditDay->getSettingsType())
-            ("NAME", mEditDay->getName()));
-
-        // create and show confirmation textbox
-        LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(),
-            [cb](const LLSD&notif, const LLSD&resp)
-            {
-                S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
-                if (opt == 0)
-                    cb();
-            });
-    }
-    else if (cb)
-    {
-        cb();
-    }
-}
-
 void LLFloaterEditExtDayCycle::onTimeSliderCallback()
 {
     stopPlay();
@@ -1435,106 +1332,6 @@ LLFloaterEditExtDayCycle::connection_t LLFloaterEditExtDayCycle::setEditCommitSi
     return mCommitSignal.connect(cb);
 }
 
-void LLFloaterEditExtDayCycle::loadInventoryItem(const LLUUID  &inventoryId, bool can_trans)
-{
-    if (inventoryId.isNull())
-    {
-        mInventoryItem = nullptr;
-        mInventoryId.setNull();
-        mCanSave = true;
-        mCanCopy = true;
-        mCanMod = true;
-        mCanTrans = true;
-        return;
-    }
-
-    mInventoryId = inventoryId;
-    LL_INFOS("ENVDAYEDIT") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL;
-    mInventoryItem = gInventory.getItem(mInventoryId);
-
-    if (!mInventoryItem)
-    {
-        LL_WARNS("ENVDAYEDIT") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL;
-
-        LLNotificationsUtil::add("CantFindInvItem");
-        closeFloater();
-        mInventoryId.setNull();
-        mInventoryItem = nullptr;
-        return;
-    }
-
-    if (mInventoryItem->getAssetUUID().isNull())
-    {
-        LL_WARNS("ENVDAYEDIT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" <<  LL_ENDL;
-
-        LLNotificationsUtil::add("UnableEditItem");
-        closeFloater();
-
-        mInventoryId.setNull();
-        mInventoryItem = nullptr;
-        return;
-    }
-
-    mCanSave = true;
-    mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
-    mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
-    mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
-
-    mExpectingAssetId = mInventoryItem->getAssetUUID();
-    LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
-        [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
-}
-
-void LLFloaterEditExtDayCycle::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status)
-{
-    if (asset_id != mExpectingAssetId)
-    {
-        LL_WARNS("ENVDAYEDIT") << "Expecting {" << mExpectingAssetId << "} got {" << asset_id << "} - throwing away." << LL_ENDL;
-        return;
-    }
-    mExpectingAssetId.setNull();
-    clearDirtyFlag();
-
-    if (!settings || status)
-    {
-        LLSD args;
-        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString();
-        LLNotificationsUtil::add("FailedToFindSettings", args);
-        closeFloater();
-        return;
-    }
-
-    if (settings->getFlag(LLSettingsBase::FLAG_NOSAVE))
-    {
-        mCanSave = false;
-        mCanCopy = false;
-        mCanMod = false;
-        mCanTrans = false;
-    }
-    else
-    {
-        if (mCanCopy)
-            settings->clearFlag(LLSettingsBase::FLAG_NOCOPY);
-        else
-            settings->setFlag(LLSettingsBase::FLAG_NOCOPY);
-
-        if (mCanMod)
-            settings->clearFlag(LLSettingsBase::FLAG_NOMOD);
-        else
-            settings->setFlag(LLSettingsBase::FLAG_NOMOD);
-
-        if (mCanTrans)
-            settings->clearFlag(LLSettingsBase::FLAG_NOTRANS);
-        else
-            settings->setFlag(LLSettingsBase::FLAG_NOTRANS);
-
-        if (mInventoryItem)
-            settings->setName(mInventoryItem->getName());
-    }
-
-    setEditDayCycle(std::dynamic_pointer_cast<LLSettingsDay>(settings));
-}
-
 void LLFloaterEditExtDayCycle::updateEditEnvironment(void)
 {
     if (!mEditDay)
@@ -1670,93 +1467,6 @@ void LLFloaterEditExtDayCycle::reblendSettings()
     mWaterBlender->setPosition(position);    
 }
 
-void LLFloaterEditExtDayCycle::doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name)
-{
-    if (mInventoryItem)
-    {
-        LLUUID parent_id = mInventoryItem->getParentUUID();
-        U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner();
-        LLSettingsVOBase::createInventoryItem(day, next_owner_perm, parent_id, settings_name,
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    }
-    else
-    {
-        LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
-        // This method knows what sort of settings object to create.
-        LLSettingsVOBase::createInventoryItem(day, parent_id, settings_name,
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    }
-}
-
-void LLFloaterEditExtDayCycle::doApplyUpdateInventory(const LLSettingsDay::ptr_t &day)
-{
-    if (mInventoryId.isNull())
-        LLSettingsVOBase::createInventoryItem(day, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(),
-                [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    else
-        LLSettingsVOBase::updateInventoryItem(day, mInventoryId,
-                [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); });
-}
-
-void LLFloaterEditExtDayCycle::doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day)
-{
-    U32 flags(0);
-
-    if (mInventoryItem)
-    {
-        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
-            flags |= LLSettingsBase::FLAG_NOMOD;
-        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
-            flags |= LLSettingsBase::FLAG_NOTRANS;
-    }
-
-    flags |= day->getFlags();
-    day->setFlag(flags);
-
-    if (where == ACTION_APPLY_LOCAL)
-    {
-        day->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy.
-        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, day);
-    }
-    else if (where == ACTION_APPLY_PARCEL)
-    {
-        LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel());
-
-        if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID))
-        {
-            LL_WARNS("ENVDAYEDIT") << "Can not identify parcel. Not applying." << LL_ENDL;
-            LLNotificationsUtil::add("WLParcelApplyFail");
-            return;
-        }
-
-        if (mInventoryItem && !isDirty())
-        {
-            LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
-        }
-        else
-        {
-            LLEnvironment::instance().updateParcel(parcel->getLocalID(), day, -1, -1);
-        }
-    }
-    else if (where == ACTION_APPLY_REGION)
-    {
-        if (mInventoryItem && !isDirty())
-        {
-            LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
-        }
-        else
-        {
-            LLEnvironment::instance().updateRegion(day, -1, -1);
-        }
-    }
-    else
-    {
-        LL_WARNS("ENVDAYEDIT") << "Unknown apply '" << where << "'" << LL_ENDL;
-        return;
-    }
-
-}
-
 void LLFloaterEditExtDayCycle::doApplyCommit(LLSettingsDay::ptr_t day)
 {
     if (!mCommitSignal.empty())
@@ -1793,51 +1503,6 @@ bool LLFloaterEditExtDayCycle::isAddingFrameAllowed()
     return mFramesSlider->canAddSliders();
 }
 
-void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
-{
-    LL_INFOS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL;
-
-    if (inventory_id.isNull() || !results["success"].asBoolean())
-    {
-        LLNotificationsUtil::add("CantCreateInventory");
-        return;
-    }
-    onInventoryCreated(asset_id, inventory_id);
-}
-
-void LLFloaterEditExtDayCycle::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id)
-{
-    bool can_trans = true;
-    if (mInventoryItem)
-    {
-        LLPermissions perms = mInventoryItem->getPermissions();
-
-        LLInventoryItem *created_item = gInventory.getItem(mInventoryId);
-        
-        if (created_item)
-        {
-            can_trans = perms.allowOperationBy(PERM_TRANSFER, gAgent.getID());
-            created_item->setPermissions(perms);
-            created_item->updateServer(false);
-        }
-    }
-
-    clearDirtyFlag();
-    setFocus(TRUE);                 // Call back the focus...
-    loadInventoryItem(inventory_id, can_trans);
-}
-
-void LLFloaterEditExtDayCycle::onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
-{
-    LL_WARNS("ENVDAYEDIT") << "Inventory item " << inventory_id << " has been updated with asset " << asset_id << " results are:" << results << LL_ENDL;
-
-    clearDirtyFlag();
-    if (inventory_id != mInventoryId)
-    {
-        loadInventoryItem(inventory_id);
-    }
-}
-
 void LLFloaterEditExtDayCycle::doImportFromDisk()
 {   // Load a a legacy Windlight XML from disk.
     (new LLFilePickerReplyThread(boost::bind(&LLFloaterEditExtDayCycle::loadSettingFromFile, this, _1), LLFilePicker::FFLOAD_XML, false))->getFile();
@@ -1864,21 +1529,6 @@ void LLFloaterEditExtDayCycle::loadSettingFromFile(const std::vector<std::string
     setEditDayCycle(legacyday);
 }
 
-bool LLFloaterEditExtDayCycle::canUseInventory() const
-{
-    return LLEnvironment::instance().isInventoryEnabled();
-}
-
-bool LLFloaterEditExtDayCycle::canApplyRegion() const
-{
-    return gAgent.canManageEstate();
-}
-
-bool LLFloaterEditExtDayCycle::canApplyParcel() const
-{
-    return LLEnvironment::instance().canAgentUpdateParcelEnvironment();
-}
-
 void LLFloaterEditExtDayCycle::startPlay()
 {
     doCloseInventoryFloater();
@@ -1983,14 +1633,8 @@ void LLFloaterEditExtDayCycle::doCloseTrackFloater(bool quitting)
     }
 }
 
-void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id)
+LLFloaterSettingsPicker * LLFloaterEditExtDayCycle::getSettingsPicker()
 {
-    cloneTrack(track_id, mCurrentTrack);
-}
-
-void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem)
-{
-//  LLUI::sWindow->setCursor(UI_CURSOR_WAIT);
     LLFloaterSettingsPicker *picker = static_cast<LLFloaterSettingsPicker *>(mInventoryFloater.get());
 
     // Show the dialog
@@ -2003,7 +1647,17 @@ void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e typ
 
         picker->setCommitCallback([this](LLUICtrl *, const LLSD &data){ onPickerCommitSetting(data["ItemId"].asUUID(), data["Track"].asInteger()); });
     }
+    return picker;
+}
+
+void LLFloaterEditExtDayCycle::onPickerCommitTrackId(U32 track_id)
+{
+    cloneTrack(track_id, mCurrentTrack);
+}
 
+void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem)
+{
+    LLFloaterSettingsPicker *picker = getSettingsPicker();
     picker->setSettingsFilter(type);
     picker->setSettingsItemId(curritem);
     if (type == LLSettingsType::ST_DAYCYCLE)
@@ -2018,16 +1672,6 @@ void LLFloaterEditExtDayCycle::doOpenInventoryFloater(LLSettingsType::type_e typ
     picker->setFocus(TRUE);
 }
 
-void LLFloaterEditExtDayCycle::doCloseInventoryFloater(bool quitting)
-{
-    LLFloater* floaterp = mInventoryFloater.get();
-
-    if (floaterp)
-    {
-        floaterp->closeFloater(quitting);
-    }
-}
-
 void LLFloaterEditExtDayCycle::onPickerCommitSetting(LLUUID item_id, S32 track)
 {
     LLSettingsBase::TrackPosition frame(mTimeSlider->getCurSliderValue());
@@ -2118,7 +1762,9 @@ void LLFloaterEditExtDayCycle::onAssetLoadedForInsertion(LLUUID item_id, LLUUID
 
     LLInventoryItem *inv_item = gInventory.getItem(item_id);
 
-    if (inv_item && !inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
+    if (inv_item
+        && (!inv_item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID())
+            || !inv_item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())))
     {
         // Need to check if item is already no-transfer, otherwise make it no-transfer
         bool no_transfer = false;
diff --git a/indra/newview/llfloatereditextdaycycle.h b/indra/newview/llfloatereditextdaycycle.h
index b6e9fdb14f8a635757c954ed20b7da7d34fa2acd..9a30fb199f2c82562ddca325fcce6d8ade3e3828 100644
--- a/indra/newview/llfloatereditextdaycycle.h
+++ b/indra/newview/llfloatereditextdaycycle.h
@@ -32,6 +32,7 @@
 #include <boost/signals2.hpp>
 
 #include "llenvironment.h"
+#include "llfloatereditenvironmentbase.h"
 
 class LLCheckBoxCtrl;
 class LLComboBox;
@@ -50,14 +51,13 @@ typedef std::shared_ptr<LLSettingsBase> LLSettingsBasePtr_t;
 /**
  * Floater for creating or editing a day cycle.
  */
-class LLFloaterEditExtDayCycle : public LLFloater
+class LLFloaterEditExtDayCycle : public LLFloaterEditEnvironmentBase
 {
 	LOG_CLASS(LLFloaterEditExtDayCycle);
 
     friend class LLDaySettingCopiedCallback;
 
 public:
-    static const std::string    KEY_INVENTORY_ID;
     static const std::string    KEY_EDIT_CONTEXT;
     static const std::string    KEY_DAY_LENGTH;
     static const std::string    KEY_CANMOD;
@@ -82,8 +82,8 @@ class LLFloaterEditExtDayCycle : public LLFloater
     virtual BOOL                postBuild() override;
     virtual void                onOpen(const LLSD& key) override;
     virtual void                onClose(bool app_quitting) override;
-    virtual void                onFocusReceived() override;
-    virtual void                onFocusLost() override;
+    //virtual void                onFocusReceived() override;
+    //virtual void                onFocusLost() override;
     virtual void                onVisibilityChange(BOOL new_visibility) override;
 
     connection_t                setEditCommitSignal(edit_commit_signal_t::slot_type cb);
@@ -97,10 +97,13 @@ class LLFloaterEditExtDayCycle : public LLFloater
     LLUUID                      getEditingAssetId() { return mEditDay ? mEditDay->getAssetId() : LLUUID::null; }
     LLUUID                      getEditingInventoryId() { return mInventoryId; }
 
+    virtual LLSettingsBase::ptr_t getEditSettings()   const override { return mEditDay; }
+
 
     BOOL			            handleKeyUp(KEY key, MASK mask, BOOL called_from_parent) override;
 
-    BOOL                        isDirty() const override { return getIsDirty(); } 
+protected:
+    virtual void                setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override;
 
 private:
     typedef std::function<void()> on_confirm_fn;
@@ -108,8 +111,8 @@ class LLFloaterEditExtDayCycle : public LLFloater
 
 	// flyout response/click
 	void                        onButtonApply(LLUICtrl *ctrl, const LLSD &data);
-    virtual void                onClickCloseBtn(bool app_quitting = false) override;
-    void                        onButtonImport();
+    //virtual void                onClickCloseBtn(bool app_quitting = false) override;
+    //void                        onButtonImport();
     void                        onButtonLoadFrame();
     void                        onAddFrame();
 	void                        onRemoveFrame();
@@ -119,7 +122,6 @@ class LLFloaterEditExtDayCycle : public LLFloater
 	void                        onCommitName(class LLLineEditor* caller, void* user_data);
 	void                        onTrackSelectionCallback(const LLSD& user_data);
 	void                        onPlayActionCallback(const LLSD& user_data);
-	void                        onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsDay::ptr_t &day);
 	// time slider clicked
 	void                        onTimeSliderCallback();
 	// a frame moved or frame selection changed
@@ -128,10 +130,6 @@ class LLFloaterEditExtDayCycle : public LLFloater
     void                        onFrameSliderMouseDown(S32 x, S32 y, MASK mask);
     void                        onFrameSliderMouseUp(S32 x, S32 y, MASK mask);
 
-    void                        onPanelDirtyFlagChanged(bool);
-
-    void                        checkAndConfirmSettingsLoss(on_confirm_fn cb);
-
     void                        cloneTrack(U32 source_index, U32 dest_index);
     void                        cloneTrack(const LLSettingsDay::ptr_t &source_day, U32 source_index, U32 dest_index);
 	void                        selectTrack(U32 track_index, bool force = false);
@@ -148,25 +146,21 @@ class LLFloaterEditExtDayCycle : public LLFloater
     void                        removeCurrentSliderFrame();
     void                        removeSliderFrame(F32 frame);
 
-    void                        loadInventoryItem(const LLUUID  &inventoryId, bool can_trans = true);
-    void                        onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status);
-
-    void                        doImportFromDisk();
+    virtual void                doImportFromDisk() override;
     void                        loadSettingFromFile(const std::vector<std::string>& filenames);
-    void                        doApplyCreateNewInventory(const LLSettingsDay::ptr_t &day, std::string settings_name);
-    void                        doApplyUpdateInventory(const LLSettingsDay::ptr_t &day);
-    void                        doApplyEnvironment(const std::string &where, const LLSettingsDay::ptr_t &day);
     void                        doApplyCommit(LLSettingsDay::ptr_t day);
     void                        onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
     void                        onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
     void                        onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
 
+
     void                        doOpenTrackFloater(const LLSD &args);
     void                        doCloseTrackFloater(bool quitting = false);
+    virtual LLFloaterSettingsPicker* getSettingsPicker() override;
     void                        onPickerCommitTrackId(U32 track_id);
 
     void                        doOpenInventoryFloater(LLSettingsType::type_e type, LLUUID curritem);
-    void                        doCloseInventoryFloater(bool quitting = false);
+    //void                        doCloseInventoryFloater(bool quitting = false);
     void                        onPickerCommitSetting(LLUUID item_id, S32 track);
     void                        onAssetLoadedForInsertion(LLUUID item_id,
                                                           LLUUID asset_id,
@@ -176,11 +170,7 @@ class LLFloaterEditExtDayCycle : public LLFloater
                                                           S32 dest_track,
                                                           LLSettingsBase::TrackPosition dest_frame);
 
-    bool                        canUseInventory() const;
-    bool                        canApplyRegion() const;
-    bool                        canApplyParcel() const;
-
-    void                        updateEditEnvironment();
+    virtual void                updateEditEnvironment() override;
     void                        synchronizeTabs();
     void                        reblendSettings();
 
@@ -193,7 +183,7 @@ class LLFloaterEditExtDayCycle : public LLFloater
 
     bool                        getIsDirty() const  { return mIsDirty; }
     void                        setDirtyFlag()      { mIsDirty = true; }
-    virtual void                clearDirtyFlag();
+    virtual void                clearDirtyFlag() override;
 
     bool                        isRemovingFrameAllowed();
     bool                        isAddingFrameAllowed();
@@ -218,11 +208,8 @@ class LLFloaterEditExtDayCycle : public LLFloater
     LLView*                     mSkyTabLayoutContainer;
     LLView*                     mWaterTabLayoutContainer;
     LLTextBox*                  mCurrentTimeLabel;
-    LLUUID                      mInventoryId;
-    LLInventoryItem *           mInventoryItem;
     LLFlyoutComboBtnCtrl *      mFlyoutControl;
 
-    LLHandle<LLFloater>         mInventoryFloater;
     LLHandle<LLFloater>         mTrackFloater;
 
     LLTrackBlenderLoopingManual::ptr_t  mSkyBlender;
@@ -236,11 +223,6 @@ class LLFloaterEditExtDayCycle : public LLFloater
     LLFrameTimer                mPlayTimer;
     F32                         mPlayStartFrame; // an env frame
     bool                        mIsPlaying;
-    bool                        mIsDirty;
-    bool                        mCanCopy;
-    bool                        mCanMod;
-    bool                        mCanTrans;
-    bool                        mCanSave;
 
     edit_commit_signal_t        mCommitSignal;
 
diff --git a/indra/newview/llfloaterenvironmentadjust.cpp b/indra/newview/llfloaterenvironmentadjust.cpp
index 4eb5e03603513202e1005a318ee29188329c66eb..95d6a2d65299a2623e2451739818cc83ae58d486 100644
--- a/indra/newview/llfloaterenvironmentadjust.cpp
+++ b/indra/newview/llfloaterenvironmentadjust.cpp
@@ -53,11 +53,15 @@ namespace
     const std::string FIELD_SKY_CLOUD_SCALE("cloud_scale");
     const std::string FIELD_SKY_SCENE_GAMMA("scene_gamma");
     const std::string FIELD_SKY_SUN_ROTATION("sun_rotation");
+    const std::string FIELD_SKY_SUN_AZIMUTH("sun_azimuth");
+    const std::string FIELD_SKY_SUN_ELEVATION("sun_elevation");
     const std::string FIELD_SKY_SUN_SCALE("sun_scale");
     const std::string FIELD_SKY_GLOW_FOCUS("glow_focus");
     const std::string FIELD_SKY_GLOW_SIZE("glow_size");
     const std::string FIELD_SKY_STAR_BRIGHTNESS("star_brightness");
     const std::string FIELD_SKY_MOON_ROTATION("moon_rotation");
+    const std::string FIELD_SKY_MOON_AZIMUTH("moon_azimuth");
+    const std::string FIELD_SKY_MOON_ELEVATION("moon_elevation");
     const std::string BTN_RESET("btn_reset");
 
     const F32 SLIDER_SCALE_SUN_AMBIENT(3.0f);
@@ -96,9 +100,13 @@ BOOL LLFloaterEnvironmentAdjust::postBuild()
     getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); });
     getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onStarBrightnessChanged(); });
     getChild<LLUICtrl>(FIELD_SKY_SUN_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunRotationChanged(); });
+    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
+    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
     getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunScaleChanged(); });
 
     getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); });
+    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
+    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
     getChild<LLUICtrl>(BTN_RESET)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onButtonReset(); });
 
     getChild<LLTextureCtrl>(FIELD_SKY_CLOUD_MAP)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onCloudMapChanged(); });
@@ -169,10 +177,25 @@ void LLFloaterEnvironmentAdjust::refresh()
     getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setValue(2.0 - (glow.mV[0] / SLIDER_SCALE_GLOW_R));
     getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setValue(glow.mV[2] / SLIDER_SCALE_GLOW_B);
     getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setValue(mLiveSky->getStarBrightness());
-    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(mLiveSky->getSunRotation());
     getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setValue(mLiveSky->getSunScale());
-    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(mLiveSky->getMoonRotation());
 
+    // Sun rotation
+    LLQuaternion quat = mLiveSky->getSunRotation();
+    F32 azimuth;
+    F32 elevation;
+    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+
+    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
+    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
+    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
+
+    // Moon rotation
+    quat = mLiveSky->getMoonRotation();
+    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+
+    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
+    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
+    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
 }
 
 
@@ -325,10 +348,45 @@ void LLFloaterEnvironmentAdjust::onStarBrightnessChanged()
 
 void LLFloaterEnvironmentAdjust::onSunRotationChanged()
 {
-    if (!mLiveSky)
-        return;
-    mLiveSky->setSunRotation(getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation());
-    mLiveSky->update();
+    LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation();
+    F32 azimuth;
+    F32 elevation;
+    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
+    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
+    if (mLiveSky)
+    {
+        mLiveSky->setSunRotation(quat);
+        mLiveSky->update();
+    }
+}
+
+void LLFloaterEnvironmentAdjust::onSunAzimElevChanged()
+{
+    F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->getValue().asReal();
+    F32 elevation = getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->getValue().asReal();
+    LLQuaternion quat;
+
+    azimuth *= DEG_TO_RAD;
+    elevation *= DEG_TO_RAD;
+
+    if (is_approx_zero(elevation))
+    {
+        elevation = F_APPROXIMATELY_ZERO;
+    }
+
+    quat.setAngleAxis(-elevation, 0, 1, 0);
+    LLQuaternion az_quat;
+    az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1);
+    quat *= az_quat;
+
+    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
+
+    if (mLiveSky)
+    {
+        mLiveSky->setSunRotation(quat);
+        mLiveSky->update();
+    }
 }
 
 void LLFloaterEnvironmentAdjust::onSunScaleChanged()
@@ -341,10 +399,45 @@ void LLFloaterEnvironmentAdjust::onSunScaleChanged()
 
 void LLFloaterEnvironmentAdjust::onMoonRotationChanged()
 {
-    if (!mLiveSky)
-        return;
-    mLiveSky->setMoonRotation(getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation());
-    mLiveSky->update();
+    LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation();
+    F32 azimuth;
+    F32 elevation;
+    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
+    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
+    if (mLiveSky)
+    {
+        mLiveSky->setMoonRotation(quat);
+        mLiveSky->update();
+    }
+}
+
+void LLFloaterEnvironmentAdjust::onMoonAzimElevChanged()
+{
+    F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->getValue().asReal();
+    F32 elevation = getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->getValue().asReal();
+    LLQuaternion quat;
+
+    azimuth *= DEG_TO_RAD;
+    elevation *= DEG_TO_RAD;
+
+    if (is_approx_zero(elevation))
+    {
+        elevation = F_APPROXIMATELY_ZERO;
+    }
+
+    quat.setAngleAxis(-elevation, 0, 1, 0);
+    LLQuaternion az_quat;
+    az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1);
+    quat *= az_quat;
+
+    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
+
+    if (mLiveSky)
+    {
+        mLiveSky->setMoonRotation(quat);
+        mLiveSky->update();
+    }
 }
 
 void LLFloaterEnvironmentAdjust::onCloudMapChanged()
diff --git a/indra/newview/llfloaterenvironmentadjust.h b/indra/newview/llfloaterenvironmentadjust.h
index cb38dbcfa80e3362e4b754b38669be734d0e6696..05ff011be5d14400c30d6a2306fe4ccb37640fc9 100644
--- a/indra/newview/llfloaterenvironmentadjust.h
+++ b/indra/newview/llfloaterenvironmentadjust.h
@@ -73,9 +73,11 @@ class LLFloaterEnvironmentAdjust : public LLFloater
     void                        onGlowChanged();
     void                        onStarBrightnessChanged();
     void                        onSunRotationChanged();
+    void                        onSunAzimElevChanged();
     void                        onSunScaleChanged();
 
     void                        onMoonRotationChanged();
+    void                        onMoonAzimElevChanged();
 
     void                        onCloudMapChanged();
     void                        onWaterMapChanged();
diff --git a/indra/newview/llfloaterfixedenvironment.cpp b/indra/newview/llfloaterfixedenvironment.cpp
index cd8e0a48e7c170f185be2ad12ce9839f1c2d97c1..4f2c36f45b6217ae609cd8ef2b3dc5f190191add 100644
--- a/indra/newview/llfloaterfixedenvironment.cpp
+++ b/indra/newview/llfloaterfixedenvironment.cpp
@@ -81,44 +81,11 @@ namespace
     const std::string XML_FLYOUTMENU_FILE("menu_save_settings.xml");
 }
 
-//=========================================================================
-const std::string LLFloaterFixedEnvironment::KEY_INVENTORY_ID("inventory_id");
-
-
-//=========================================================================
-
-class LLFixedSettingCopiedCallback : public LLInventoryCallback
-{
-public:
-    LLFixedSettingCopiedCallback(LLHandle<LLFloater> handle) : mHandle(handle) {}
-
-    virtual void fire(const LLUUID& inv_item_id)
-    {
-        if (!mHandle.isDead())
-        {
-            LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
-            if (item)
-            {
-                LLFloaterFixedEnvironment* floater = (LLFloaterFixedEnvironment*)mHandle.get();
-                floater->onInventoryCreated(item->getAssetUUID(), inv_item_id);
-            }
-        }
-    }
-
-private:
-    LLHandle<LLFloater> mHandle;
-};
 
 //=========================================================================
 LLFloaterFixedEnvironment::LLFloaterFixedEnvironment(const LLSD &key) :
-    LLFloater(key),
-    mFlyoutControl(nullptr),
-    mInventoryId(),
-    mInventoryItem(nullptr),
-    mIsDirty(false),
-    mCanCopy(false),
-    mCanMod(false),
-    mCanTrans(false)
+    LLFloaterEditEnvironmentBase(key),
+    mFlyoutControl(nullptr)
 {
 }
 
@@ -161,7 +128,7 @@ void LLFloaterFixedEnvironment::onOpen(const LLSD& key)
     updateEditEnvironment();
     syncronizeTabs();
     refresh();
-    LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
+    LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_INSTANT);
 
 }
 
@@ -176,19 +143,6 @@ void LLFloaterFixedEnvironment::onClose(bool app_quitting)
     syncronizeTabs();
 }
 
-void LLFloaterFixedEnvironment::onFocusReceived()
-{
-    if (isInVisibleChain())
-    {
-        updateEditEnvironment();
-        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_EDIT, LLEnvironment::TRANSITION_FAST);
-    }
-}
-
-void LLFloaterFixedEnvironment::onFocusLost()
-{
-}
-
 void LLFloaterFixedEnvironment::refresh()
 {
     if (!mSettings)
@@ -220,6 +174,15 @@ void LLFloaterFixedEnvironment::refresh()
     }
 }
 
+void LLFloaterFixedEnvironment::setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings)
+{
+    mSettings = settings; // shouldn't this do buildDeepCloneAndUncompress() ?
+    updateEditEnvironment();
+    syncronizeTabs();
+    refresh();
+    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT);
+}
+
 void LLFloaterFixedEnvironment::syncronizeTabs()
 {
     S32 count = mTab->getTabCount();
@@ -250,131 +213,9 @@ LLFloaterSettingsPicker * LLFloaterFixedEnvironment::getSettingsPicker()
     return picker;
 }
 
-void LLFloaterFixedEnvironment::loadInventoryItem(const LLUUID  &inventoryId, bool can_trans)
-{
-    if (inventoryId.isNull())
-    {
-        mInventoryItem = nullptr;
-        mInventoryId.setNull();
-        mCanMod = true;
-        mCanCopy = true;
-        mCanTrans = true;
-        return;
-    }
-
-    mInventoryId = inventoryId;
-    LL_INFOS("SETTINGS") << "Setting edit inventory item to " << mInventoryId << "." << LL_ENDL;
-    mInventoryItem = gInventory.getItem(mInventoryId);
-
-    if (!mInventoryItem)
-    {
-        LL_WARNS("SETTINGS") << "Could not find inventory item with Id = " << mInventoryId << LL_ENDL;
-        LLNotificationsUtil::add("CantFindInvItem");
-        closeFloater();
-
-        mInventoryId.setNull();
-        mInventoryItem = nullptr;
-        return;
-    }
-
-    if (mInventoryItem->getAssetUUID().isNull())
-    {
-        LL_WARNS("ENVIRONMENT") << "Asset ID in inventory item is NULL (" << mInventoryId << ")" << LL_ENDL;
-        LLNotificationsUtil::add("UnableEditItem");
-        closeFloater();
-
-        mInventoryId.setNull();
-        mInventoryItem = nullptr;
-        return;
-    }
-
-    mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
-    mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
-    mCanTrans = can_trans && mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
-
-    LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
-        [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
-}
-
-
-void LLFloaterFixedEnvironment::checkAndConfirmSettingsLoss(LLFloaterFixedEnvironment::on_confirm_fn cb)
-{
-    if (isDirty())
-    {
-        LLSD args(LLSDMap("TYPE", mSettings->getSettingsType())
-            ("NAME", mSettings->getName()));
-
-        // create and show confirmation textbox
-        LLNotificationsUtil::add("SettingsConfirmLoss", args, LLSD(),
-            [cb](const LLSD&notif, const LLSD&resp)
-            {
-                S32 opt = LLNotificationsUtil::getSelectedOption(notif, resp);
-                if (opt == 0)
-                    cb();
-            });
-    }
-    else if (cb)
-    {
-        cb();
-    }
-}
-
 void LLFloaterFixedEnvironment::onPickerCommitSetting(LLUUID item_id)
 {
     loadInventoryItem(item_id);
-//     mInventoryId = item_id;
-//     mInventoryItem = gInventory.getItem(mInventoryId);
-// 
-//     mCanCopy = mInventoryItem->getPermissions().allowCopyBy(gAgent.getID());
-//     mCanMod = mInventoryItem->getPermissions().allowModifyBy(gAgent.getID());
-//     mCanTrans = mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID());
-// 
-//     LLSettingsVOBase::getSettingsAsset(mInventoryItem->getAssetUUID(),
-//         [this](LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status, LLExtStat) { onAssetLoaded(asset_id, settings, status); });
-}
-
-void LLFloaterFixedEnvironment::onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settings, S32 status)
-{
-    if (mInventoryItem && mInventoryItem->getAssetUUID() != asset_id)
-    {
-        LL_WARNS("ENVIRONMENT") << "Discarding obsolete asset callback" << LL_ENDL;
-        return;
-    }
-
-    clearDirtyFlag();
-
-    if (!settings || status)
-    {
-        LLSD args;
-        args["NAME"] = (mInventoryItem) ? mInventoryItem->getName() : asset_id.asString();
-        LLNotificationsUtil::add("FailedToFindSettings", args);
-        closeFloater();
-        return;
-    }
-
-    mSettings = settings;
-    if (mInventoryItem)
-        mSettings->setName(mInventoryItem->getName());
-
-    if (mCanCopy)
-        settings->clearFlag(LLSettingsBase::FLAG_NOCOPY);
-    else
-        settings->setFlag(LLSettingsBase::FLAG_NOCOPY);
-
-    if (mCanMod)
-        settings->clearFlag(LLSettingsBase::FLAG_NOMOD);
-    else
-        settings->setFlag(LLSettingsBase::FLAG_NOMOD);
-
-    if (mCanTrans)
-        settings->clearFlag(LLSettingsBase::FLAG_NOTRANS);
-    else
-        settings->setFlag(LLSettingsBase::FLAG_NOTRANS);
-
-    updateEditEnvironment();
-    syncronizeTabs();
-    refresh();
-    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST);
 }
 
 void LLFloaterFixedEnvironment::onNameChanged(const std::string &name)
@@ -473,50 +314,6 @@ void LLFloaterFixedEnvironment::onButtonApply(LLUICtrl *ctrl, const LLSD &data)
     }
 }
 
-void LLFloaterFixedEnvironment::onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings)
-{
-    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-    if (0 == option)
-    {
-        std::string settings_name = response["message"].asString();
-
-        LLInventoryObject::correctInventoryName(settings_name);
-        if (settings_name.empty())
-        {
-            // Ideally notification should disable 'OK' button if name won't fit our requirements,
-            // for now either display notification, or use some default name
-            settings_name = "Unnamed";
-        }
-
-        if (mCanMod)
-        {
-            doApplyCreateNewInventory(settings_name, settings);
-        }
-        else if (mInventoryItem)
-        {
-            const LLUUID &marketplacelistings_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
-            LLUUID parent_id = mInventoryItem->getParentUUID();
-            if (marketplacelistings_id == parent_id)
-            {
-                parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
-            }
-
-            LLPointer<LLInventoryCallback> cb = new LLFixedSettingCopiedCallback(getHandle());
-            copy_inventory_item(
-                gAgent.getID(),
-                mInventoryItem->getPermissions().getOwner(),
-                mInventoryItem->getUUID(),
-                parent_id,
-                settings_name,
-                cb);
-        }
-        else
-        {
-            LL_WARNS() << "Failed to copy fixed env setting" << LL_ENDL;
-        }
-    }
-}
-
 void LLFloaterFixedEnvironment::onClickCloseBtn(bool app_quitting)
 {
     if (!app_quitting)
@@ -530,116 +327,6 @@ void LLFloaterFixedEnvironment::onButtonLoad()
     checkAndConfirmSettingsLoss([this](){ doSelectFromInventory(); });
 }
 
-void LLFloaterFixedEnvironment::doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings)
-{
-    if (mInventoryItem)
-    {
-        LLUUID parent_id = mInventoryItem->getParentUUID();
-        U32 next_owner_perm = mInventoryItem->getPermissions().getMaskNextOwner();
-        LLSettingsVOBase::createInventoryItem(settings, next_owner_perm, parent_id, settings_name,
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    }
-    else
-    {
-        LLUUID parent_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS);
-        // This method knows what sort of settings object to create.
-        LLSettingsVOBase::createInventoryItem(settings, parent_id, settings_name,
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    }
-}
-
-void LLFloaterFixedEnvironment::doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings)
-{
-    LL_DEBUGS("ENVEDIT") << "Update inventory for " << mInventoryId << LL_ENDL;
-    if (mInventoryId.isNull())
-    {
-        LLSettingsVOBase::createInventoryItem(settings, gInventory.findCategoryUUIDForType(LLFolderType::FT_SETTINGS), std::string(),
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryCreated(asset_id, inventory_id, results); });
-    }
-    else
-    {
-        LLSettingsVOBase::updateInventoryItem(settings, mInventoryId,
-            [this](LLUUID asset_id, LLUUID inventory_id, LLUUID, LLSD results) { onInventoryUpdated(asset_id, inventory_id, results); });
-    }
-}
-
-void LLFloaterFixedEnvironment::doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings)
-{
-    U32 flags(0);
-
-    if (mInventoryItem)
-    {
-        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()))
-            flags |= LLSettingsBase::FLAG_NOMOD;
-        if (!mInventoryItem->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()))
-            flags |= LLSettingsBase::FLAG_NOTRANS;
-    }
-
-    flags |= settings->getFlags();
-    settings->setFlag(flags);
-
-    if (where == ACTION_APPLY_LOCAL)
-    {
-        settings->setName("Local"); // To distinguish and make sure there is a name. Safe, because this is a copy.
-        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, settings);
-    }
-    else if (where == ACTION_APPLY_PARCEL)
-    {
-        LLParcel *parcel(LLViewerParcelMgr::instance().getAgentOrSelectedParcel());
-
-        if ((!parcel) || (parcel->getLocalID() == INVALID_PARCEL_ID))
-        {
-            LL_WARNS("ENVIRONMENT") << "Can not identify parcel. Not applying." << LL_ENDL;
-            LLNotificationsUtil::add("WLParcelApplyFail");
-            return;
-        }
-
-        if (mInventoryItem && !isDirty())
-        {
-            LLEnvironment::instance().updateParcel(parcel->getLocalID(), mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
-        }
-        else if (settings->getSettingsType() == "sky")
-        {
-            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsSky>(settings), -1, -1);
-        }
-        else if (settings->getSettingsType() == "water")
-        {
-            LLEnvironment::instance().updateParcel(parcel->getLocalID(), std::static_pointer_cast<LLSettingsWater>(settings), -1, -1);
-        }
-    }
-    else if (where == ACTION_APPLY_REGION)
-    {
-        if (mInventoryItem && !isDirty())
-        {
-            LLEnvironment::instance().updateRegion(mInventoryItem->getAssetUUID(), mInventoryItem->getName(), LLEnvironment::NO_TRACK, -1, -1, flags);
-        }
-        else if (settings->getSettingsType() == "sky")
-        {
-            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsSky>(settings), -1, -1);
-        }
-        else if (settings->getSettingsType() == "water")
-        {
-            LLEnvironment::instance().updateRegion(std::static_pointer_cast<LLSettingsWater>(settings), -1, -1);
-        }
-    }
-    else
-    {
-        LL_WARNS("ENVIRONMENT") << "Unknown apply '" << where << "'" << LL_ENDL;
-        return;
-    }
-
-}
-
-void LLFloaterFixedEnvironment::doCloseInventoryFloater(bool quitting)
-{
-    LLFloater* floaterp = mInventoryFloater.get();
-
-    if (floaterp)
-    {
-        floaterp->closeFloater(quitting);
-    }
-}
-
 void LLFloaterFixedEnvironment::onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results)
 {
     LL_WARNS("ENVIRONMENT") << "Inventory item " << inventory_id << " has been created with asset " << asset_id << " results are:" << results << LL_ENDL;
@@ -709,28 +396,6 @@ void LLFloaterFixedEnvironment::doSelectFromInventory()
     picker->setFocus(TRUE);
 }
 
-void LLFloaterFixedEnvironment::onPanelDirtyFlagChanged(bool value)
-{
-    if (value)
-        setDirtyFlag();
-}
-
-//-------------------------------------------------------------------------
-bool LLFloaterFixedEnvironment::canUseInventory() const
-{
-    return LLEnvironment::instance().isInventoryEnabled();
-}
-
-bool LLFloaterFixedEnvironment::canApplyRegion() const
-{
-    return gAgent.canManageEstate();
-}
-
-bool LLFloaterFixedEnvironment::canApplyParcel() const
-{
-    return LLEnvironment::instance().canAgentUpdateParcelEnvironment();
-}
-
 //=========================================================================
 LLFloaterFixedEnvironmentWater::LLFloaterFixedEnvironmentWater(const LLSD &key):
     LLFloaterFixedEnvironment(key)
@@ -795,7 +460,7 @@ void LLFloaterFixedEnvironmentWater::loadWaterSettingFromFile(const std::vector<
     setDirtyFlag();
     LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacywater);
     setEditSettings(legacywater);
-    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true);
+    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true);
 }
 
 //=========================================================================
@@ -883,7 +548,7 @@ void LLFloaterFixedEnvironmentSky::loadSkySettingFromFile(const std::vector<std:
     setDirtyFlag();
     LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_EDIT, legacysky);
     setEditSettings(legacysky);
-    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_FAST, true);
+    LLEnvironment::instance().updateEnvironment(LLEnvironment::TRANSITION_INSTANT, true);
 }
 
 //=========================================================================
diff --git a/indra/newview/llfloaterfixedenvironment.h b/indra/newview/llfloaterfixedenvironment.h
index 513996c4a393e6f9f6c4c65b8b4fbb4cc7495991..f35f4a436841c6bdf6202a3b577d1533a0eb5469 100644
--- a/indra/newview/llfloaterfixedenvironment.h
+++ b/indra/newview/llfloaterfixedenvironment.h
@@ -27,7 +27,7 @@
 #ifndef LL_FLOATERFIXEDENVIRONMENT_H
 #define LL_FLOATERFIXEDENVIRONMENT_H
 
-#include "llfloater.h"
+#include "llfloatereditenvironmentbase.h"
 #include "llsettingsbase.h"
 #include "llflyoutcombobtn.h"
 #include "llinventory.h"
@@ -43,15 +43,10 @@ class LLFixedSettingCopiedCallback;
 /**
  * Floater container for creating and editing fixed environment settings.
  */
-class LLFloaterFixedEnvironment : public LLFloater
+class LLFloaterFixedEnvironment : public LLFloaterEditEnvironmentBase
 {
     LOG_CLASS(LLFloaterFixedEnvironment);
-
-    friend class LLFixedSettingCopiedCallback;
-
 public:
-    static const std::string    KEY_INVENTORY_ID;
-
                             LLFloaterFixedEnvironment(const LLSD &key);
                             ~LLFloaterFixedEnvironment();
 
@@ -59,64 +54,35 @@ class LLFloaterFixedEnvironment : public LLFloater
     virtual void            onOpen(const LLSD& key)     override;
     virtual void            onClose(bool app_quitting)  override;
 
-    virtual void            onFocusReceived()           override;
-    virtual void            onFocusLost()               override;
-
     void                    setEditSettings(const LLSettingsBase::ptr_t &settings)  { mSettings = settings; clearDirtyFlag(); syncronizeTabs(); refresh(); }
-    LLSettingsBase::ptr_t   getEditSettings()   const                           { return mSettings; }
-
-    virtual BOOL            isDirty() const override            { return getIsDirty(); }
+    virtual LLSettingsBase::ptr_t getEditSettings()   const override                { return mSettings; }
 
 protected:
     typedef std::function<void()> on_confirm_fn;
 
-    virtual void            updateEditEnvironment() = 0;
     virtual void            refresh()                   override;
+    void                    setEditSettingsAndUpdate(const LLSettingsBase::ptr_t &settings) override;
     virtual void            syncronizeTabs();
 
-    LLFloaterSettingsPicker *getSettingsPicker();
-
-    void                    loadInventoryItem(const LLUUID  &inventoryId, bool can_trans = true);
-
-    void                    checkAndConfirmSettingsLoss(on_confirm_fn cb);
+    virtual LLFloaterSettingsPicker *getSettingsPicker() override;
 
     LLTabContainer *        mTab;
     LLLineEditor *          mTxtName;
 
     LLSettingsBase::ptr_t   mSettings;
 
-    virtual void            doImportFromDisk() = 0;
-    virtual void            doApplyCreateNewInventory(std::string settings_name, const LLSettingsBase::ptr_t &settings);
-    virtual void            doApplyUpdateInventory(const LLSettingsBase::ptr_t &settings);
-    virtual void            doApplyEnvironment(const std::string &where, const LLSettingsBase::ptr_t &settings);
-    void                    doCloseInventoryFloater(bool quitting = false);
-
-    bool                    canUseInventory() const;
-    bool                    canApplyRegion() const;
-    bool                    canApplyParcel() const;
-
     LLFlyoutComboBtnCtrl *      mFlyoutControl;
 
-    LLUUID                  mInventoryId;
-    LLInventoryItem *       mInventoryItem;
-    LLHandle<LLFloater>     mInventoryFloater;
-    bool                    mCanCopy;
-    bool                    mCanMod;
-    bool                    mCanTrans;
-
     void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id);
     void                    onInventoryCreated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
     void                    onInventoryUpdated(LLUUID asset_id, LLUUID inventory_id, LLSD results);
 
-    bool                    getIsDirty() const  { return mIsDirty; }
-    void                    setDirtyFlag()      { mIsDirty = true; }
-    virtual void            clearDirtyFlag();
+    virtual void            clearDirtyFlag() override;
+    void                    updatePermissionFlags();
 
     void                    doSelectFromInventory();
-    void                    onPanelDirtyFlagChanged(bool);
 
     virtual void            onClickCloseBtn(bool app_quitting = false) override;
-    void                    onSaveAsCommit(const LLSD& notification, const LLSD& response, const LLSettingsBase::ptr_t &settings);
 
 private:
     void                    onNameChanged(const std::string &name);
@@ -126,9 +92,6 @@ class LLFloaterFixedEnvironment : public LLFloater
     void                    onButtonLoad();
 
     void                    onPickerCommitSetting(LLUUID item_id);
-    void                    onAssetLoaded(LLUUID asset_id, LLSettingsBase::ptr_t settins, S32 status);
-
-    bool                    mIsDirty;
 };
 
 class LLFloaterFixedEnvironmentWater : public LLFloaterFixedEnvironment
@@ -172,36 +135,4 @@ class LLFloaterFixedEnvironmentSky : public LLFloaterFixedEnvironment
 private:
 };
 
-class LLSettingsEditPanel : public LLPanel
-{
-public:
-    virtual void setSettings(const LLSettingsBase::ptr_t &) = 0;
-
-    typedef boost::signals2::signal<void(LLPanel *, bool)> on_dirty_charged_sg;
-    typedef boost::signals2::connection connection_t;
-
-    inline bool         getIsDirty() const      { return mIsDirty; }
-    inline void         setIsDirty()            { mIsDirty = true; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); }
-    inline void         clearIsDirty()          { mIsDirty = false; if (!mOnDirtyChanged.empty()) mOnDirtyChanged(this, mIsDirty); }
-
-    inline bool        getCanChangeSettings() const    { return mCanEdit; }
-    inline void        setCanChangeSettings(bool flag) { mCanEdit = flag; }
-
-    inline connection_t setOnDirtyFlagChanged(on_dirty_charged_sg::slot_type cb)    { return mOnDirtyChanged.connect(cb); }
-
-
-protected:
-    LLSettingsEditPanel() :
-        LLPanel(),
-        mIsDirty(false),
-        mOnDirtyChanged()
-    {}
-
-private:
-    bool                mIsDirty;
-    bool                mCanEdit;
-    
-    on_dirty_charged_sg mOnDirtyChanged;
-};
-
 #endif // LL_FLOATERFIXEDENVIRONMENT_H
diff --git a/indra/newview/llfloaterhandler.cpp b/indra/newview/llfloaterhandler.cpp
index e2160498e93c338ecd756c3407389fb7bd0f1c3a..8ebb14149c96240ef13aa990ca37f2bd7900805e 100644
--- a/indra/newview/llfloaterhandler.cpp
+++ b/indra/newview/llfloaterhandler.cpp
@@ -26,6 +26,7 @@
 
 #include "llfloater.h"
 #include "llmediactrl.h"
+#include "llfloaterreg.h"
 
 // register with dispatch via global object
 LLFloaterHandler gFloaterHandler;
@@ -50,9 +51,15 @@ LLFloater* get_parent_floater(LLView* view)
 
 bool LLFloaterHandler::handle(const LLSD &params, const LLSD &query_map, LLMediaCtrl *web)
 {
-	if (params.size() < 2) return false;
+	if (params.size() < 1) return false;
 	LLFloater* floater = NULL;
 	// *TODO: implement floater lookup by name
+
+	if (params[0].asString() == "destinations")
+	{
+		LLFloaterReg::toggleInstanceOrBringToFront("destinations");
+		return true;
+	}
 	if (params[0].asString() == "self")
 	{
 		if (web)
diff --git a/indra/newview/llfloaterhowto.cpp b/indra/newview/llfloaterhowto.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a359fb7c7dcedc7cf86d52ec402d3313c986dcd3
--- /dev/null
+++ b/indra/newview/llfloaterhowto.cpp
@@ -0,0 +1,92 @@
+/** 
+ * @file llfloaterhowto.cpp
+ * @brief A variant of web floater meant to open guidebook
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterhowto.h"
+
+#include "llfloaterreg.h"
+#include "llviewercontrol.h"
+#include "llweb.h"
+
+
+const S32 STACK_WIDTH = 300;
+const S32 STACK_HEIGHT = 505; // content will be 500
+
+LLFloaterHowTo::LLFloaterHowTo(const Params& key) :
+    LLFloaterWebContent(key)
+{
+    mShowPageTitle = false;
+}
+
+BOOL LLFloaterHowTo::postBuild()
+{
+    LLFloaterWebContent::postBuild();
+
+    return TRUE;
+}
+
+void LLFloaterHowTo::onOpen(const LLSD& key)
+{
+    LLFloaterWebContent::Params p(key);
+    if (!p.url.isProvided() || p.url.getValue().empty())
+    {
+        std::string url = gSavedSettings.getString("GuidebookURL");
+        p.url = LLWeb::expandURLSubstitutions(url, LLSD());
+    }
+    p.show_chrome = false;
+
+    LLFloaterWebContent::onOpen(p);
+
+    if (p.preferred_media_size().isEmpty())
+    {
+        // Elements from LLFloaterWebContent did not pick up restored size (save_rect) of LLFloaterHowTo
+        // set the stack size and position (alternative to preferred_media_size)
+        LLLayoutStack *stack = getChild<LLLayoutStack>("stack1");
+        LLRect stack_rect = stack->getRect();
+        stack->reshape(STACK_WIDTH, STACK_HEIGHT);
+        stack->setOrigin(stack_rect.mLeft, stack_rect.mTop - STACK_HEIGHT);
+        stack->updateLayout();
+    }
+}
+
+LLFloaterHowTo* LLFloaterHowTo::getInstance()
+{
+    return LLFloaterReg::getTypedInstance<LLFloaterHowTo>("guidebook");
+}
+
+BOOL LLFloaterHowTo::handleKeyHere(KEY key, MASK mask)
+{
+	BOOL handled = FALSE;
+
+	if (KEY_F1 == key )
+	{
+		closeFloater();
+		handled = TRUE;
+	}
+
+	return handled;
+}
diff --git a/indra/newview/llfloaterhowto.h b/indra/newview/llfloaterhowto.h
new file mode 100644
index 0000000000000000000000000000000000000000..d8da355600e16cb12388ac113f158e09dbf27e64
--- /dev/null
+++ b/indra/newview/llfloaterhowto.h
@@ -0,0 +1,58 @@
+/** 
+ * @file llfloaterhowto.h
+ * @brief A variant of web floater meant to open guidebook
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERHOWTO_H
+#define LL_LLFLOATERHOWTO_H
+
+#include "llfloaterwebcontent.h"
+
+class LLMediaCtrl;
+
+
+class LLFloaterHowTo :
+    public LLFloaterWebContent
+{
+public:
+    LOG_CLASS(LLFloaterHowTo);
+
+    typedef LLFloaterWebContent::Params Params;
+
+    LLFloaterHowTo(const Params& key);
+
+    void onOpen(const LLSD& key) override;
+
+    BOOL handleKeyHere(KEY key, MASK mask) override;
+
+    static LLFloaterHowTo* getInstance();
+
+    bool matchesKey(const LLSD& key) override { return true; /*single instance*/ };
+
+private:
+    BOOL postBuild() override;
+};
+
+#endif  // LL_LLFLOATERHOWTO_H
+
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index c174b4d197b54584b82487fc925ef709fb91ebb0..1aa29cbb41620b26f0ab5f280fbc9726d06af79d 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -62,7 +62,9 @@
 #include "boost/foreach.hpp"
 
 
-const S32 EVENTS_PER_IDLE_LOOP = 100;
+const S32 EVENTS_PER_IDLE_LOOP_CURRENT_SESSION = 80;
+const S32 EVENTS_PER_IDLE_LOOP_BACKGROUND = 40;
+const F32 EVENTS_PER_IDLE_LOOP_MIN_PERCENTAGE = 0.01f; // process a minimum of 1% of total events per frame
 
 //
 // LLFloaterIMContainer
@@ -312,12 +314,15 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
 
 	
 	LLIconCtrl* icon = 0;
+	bool is_in_group = gAgent.isInGroup(session_id, TRUE);
+	LLUUID icon_id;
 
-	if(gAgent.isInGroup(session_id, TRUE))
+	if (is_in_group)
 	{
 		LLGroupIconCtrl::Params icon_params;
 		icon_params.group_id = session_id;
 		icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
+		icon_id = session_id;
 
 		mSessions[session_id] = floaterp;
 		floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
@@ -329,11 +334,18 @@ void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
 		LLAvatarIconCtrl::Params icon_params;
 		icon_params.avatar_id = avatar_id;
 		icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
+		icon_id = avatar_id;
 
 		mSessions[session_id] = floaterp;
 		floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
 	}
 
+	LLFloaterIMSessionTab* floater = LLFloaterIMSessionTab::getConversation(session_id);
+	if (floater)
+	{
+		floater->updateChatIcon(icon_id);
+	}
+
 	// forced resize of the floater
 	LLRect wrapper_rect = this->mTabContainer->getLocalRect();
 	floaterp->setRect(wrapper_rect);
@@ -419,8 +431,11 @@ void LLFloaterIMContainer::processParticipantsStyleUpdate()
 		while (current_participant_model != end_participant_model)
 		{
 			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
-			// Get the avatar name for this participant id from the cache and update the model
-			participant_model->updateName();
+            if (participant_model)
+            {
+                // Get the avatar name for this participant id from the cache and update the model
+                participant_model->updateName();
+            }
 			// Next participant
 			current_participant_model++;
 		}
@@ -467,8 +482,11 @@ void LLFloaterIMContainer::idleUpdate()
                 while (current_participant_model != end_participant_model)
                 {
                     LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
-                    participant_model->setModeratorOptionsVisible(is_moderator);
-                    participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
+                    if (participant_model)
+                    {
+                        participant_model->setModeratorOptionsVisible(is_moderator);
+                        participant_model->setGroupBanVisible(can_ban && participant_model->getUUID() != gAgentID);
+                    }
 
                     current_participant_model++;
                 }
@@ -501,20 +519,49 @@ void LLFloaterIMContainer::idleUpdate()
 
 void LLFloaterIMContainer::idleProcessEvents()
 {
-	if (!mConversationEventQueue.empty())
-	{
-		S32 events_to_handle = llmin((S32)mConversationEventQueue.size(), EVENTS_PER_IDLE_LOOP);
-		for (S32 i = 0; i < events_to_handle; i++)
-		{
-			handleConversationModelEvent(mConversationEventQueue.back());
-			mConversationEventQueue.pop_back();
-		}
-	}
+    LLUUID current_session_id = getSelectedSession();
+    conversations_items_deque::iterator iter = mConversationEventQueue.begin();
+    conversations_items_deque::iterator end = mConversationEventQueue.end();
+    while (iter != end)
+    {
+        std::deque<LLSD> &events = iter->second;
+        if (!events.empty())
+        {
+            S32 events_to_handle;
+            S32 query_size = (S32)events.size();
+            if (current_session_id == iter->first)
+            {
+                events_to_handle = EVENTS_PER_IDLE_LOOP_CURRENT_SESSION;
+            }
+            else
+            {
+                events_to_handle = EVENTS_PER_IDLE_LOOP_BACKGROUND;
+            }
+
+            if (events_to_handle <= query_size)
+            {
+                // Some groups can be very large and can generate huge amount of updates, scale processing up to keep up
+                events_to_handle = llmax(events_to_handle, (S32)(query_size * EVENTS_PER_IDLE_LOOP_MIN_PERCENTAGE));
+            }
+            else
+            {
+                events_to_handle = query_size;
+            }
+
+            for (S32 i = 0; i < events_to_handle; i++)
+            {
+                handleConversationModelEvent(events.back());
+                events.pop_back();
+            }
+        }
+        iter++;
+    }
 }
 
 bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
 {
-	mConversationEventQueue.push_front(event);
+	LLUUID id = event.get("session_uuid").asUUID();
+	mConversationEventQueue[id].push_front(event);
 	return true;
 }
 
@@ -1311,6 +1358,23 @@ void LLFloaterIMContainer::doToSelected(const LLSD& userdata)
     const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
     uuid_vec_t selected_uuids;
 
+// [RLVa:KB] - @shownames
+	// Bulldozer block of all actions but both Catznip and Firestorm have no need for CHUI
+	if (!RlvActions::canShowName(RlvActions::SNC_DEFAULT))
+	{
+		if (LLConversationItemParticipant* pParticipantItem = dynamic_cast<LLConversationItemParticipant*>(const_cast<LLConversationItem*>(conversationItem)))
+		{
+			if (LLConversationItemSession* pParentSession = pParticipantItem->getParentSession())
+			{
+				if ( (pParentSession->getUUID().isNull()) && (selected_uuids.size() != 1 || !RlvActions::canShowName(RlvActions::SNC_DEFAULT, selected_uuids.front())) )
+				{
+					return;
+				}
+			}
+		}
+	}
+// [/RLVa:KB]
+
     if(conversationItem != NULL)
     {
     	getParticipantUUIDs(selected_uuids);
@@ -1828,12 +1892,16 @@ bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool c
 		{
 			new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
 		}
+
+		// Will destroy views and delete models that are not assigned to any views
 		widget->destroyView();
 	}
 	
 	// Suppress the conversation items and widgets from their respective maps
 	mConversationsItems.erase(uuid);
 	mConversationsWidgets.erase(uuid);
+	// Clear event query (otherwise reopening session in some way can bombard session with stale data)
+	mConversationEventQueue.erase(uuid);
 	
 	// Don't let the focus fall IW, select and refocus on the first conversation in the list
 	if (change_focus)
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 468b47f1f1b457037b013c1f3a9da46975ff5f8f..b4a9d377ab9b61cf794c52ed1e26f201b8eb0eea 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -229,9 +229,10 @@ class LLFloaterIMContainer
 	conversations_widgets_map mConversationsWidgets;
 	LLConversationViewModel mConversationViewModel;
 	LLFolderView* mConversationsRoot;
-	LLEventStream mConversationsEventStream; 
+	LLEventStream mConversationsEventStream;
 
-	std::deque<LLSD> mConversationEventQueue;
+	typedef std::map<LLUUID, std::deque<LLSD> > conversations_items_deque;
+	conversations_items_deque mConversationEventQueue;
 
 	LLTimer mParticipantRefreshTimer;
 };
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 655276af0bf3e40093efe8a7b2860b8fcd32e00a..4e415f0c1ba3e5ac426d0976410277778ada217d 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -67,6 +67,7 @@
 #include "llviewerchat.h"
 #include "lltranslate.h"
 #include "llautoreplace.h"
+#include "lluiusage.h"
 // [RLVa:KB] - Checked: 2010-02-27 (RLVa-1.2.0b)
 #include "rlvactions.h"
 #include "rlvcommon.h"
@@ -705,6 +706,7 @@ void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, ECha
 
 void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
 {
+	LLUIUsage::instance().logCommand("Chat.Send"); // pseuo-command
 	// Look for "/20 foo" channel chats.
 	S32 channel = 0;
 	LLWString out_text = stripChannelNumber(wtext, &channel);
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
index d604d0a789f66804b2cd48fb4c02e711b1efa554..7541bb5efefa1662962652e610f85a58907600fa 100644
--- a/indra/newview/llfloaterimsessiontab.cpp
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -32,6 +32,8 @@
 #include "llagent.h"
 #include "llagentcamera.h"
 #include "llavataractions.h"
+#include "llavatariconctrl.h"
+#include "llgroupiconctrl.h"
 #include "llchatentry.h"
 #include "llchathistory.h"
 #include "llchiclet.h"
@@ -45,6 +47,9 @@
 #include "llfloaterimnearbychat.h"
 
 const F32 REFRESH_INTERVAL = 1.0f;
+const std::string ICN_GROUP("group_chat_icon");
+const std::string ICN_NEARBY("nearby_chat_icon");
+const std::string ICN_AVATAR("avatar_icon");
 
 void cb_group_do_nothing()
 {
@@ -492,7 +497,10 @@ void LLFloaterIMSessionTab::buildConversationViewParticipant()
 	while (current_participant_model != end_participant_model)
 	{
 		LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
-		addConversationViewParticipant(participant_model);
+        if (participant_model)
+        {
+            addConversationViewParticipant(participant_model);
+        }
 		current_participant_model++;
 	}
 }
@@ -529,8 +537,7 @@ void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& part
 	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
 	if (widget)
 	{
-		mConversationsRoot->extractItem(widget);
-		delete widget;
+		widget->destroyView();
 	}
 	mConversationsWidgets.erase(participant_id);
 }
@@ -700,6 +707,39 @@ void LLFloaterIMSessionTab::updateSessionName(const std::string& name)
 	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name);
 }
 
+void LLFloaterIMSessionTab::updateChatIcon(const LLUUID& id)
+{
+	if (mSession)
+	{
+		if (mSession->isP2PSessionType())
+		{
+			LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>(ICN_AVATAR);
+			icon->setVisible(true);
+			icon->setValue(id);
+		}
+		if (mSession->isAdHocSessionType())
+		{
+			LLGroupIconCtrl* icon = getChild<LLGroupIconCtrl>(ICN_GROUP);
+			icon->setVisible(true);
+		}
+		if (mSession->isGroupSessionType())
+		{
+			LLGroupIconCtrl* icon = getChild<LLGroupIconCtrl>(ICN_GROUP);
+			icon->setVisible(true);
+			icon->setValue(id);
+		}
+	}
+	else
+	{
+		if (mIsNearbyChat)
+		{
+			LLIconCtrl* icon = getChild<LLIconCtrl>(ICN_NEARBY);
+			icon->setVisible(true);
+		}
+	}
+
+}
+
 void LLFloaterIMSessionTab::hideAllStandardButtons()
 {
 	for (S32 i = 0; i < BUTTON_COUNT; i++)
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
index 5357a14ab9aee12b169eb40f26d7c96ce5b43d55..e954fa2e9cb013acdb1879a8798b2969d90f7638 100644
--- a/indra/newview/llfloaterimsessiontab.h
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -37,6 +37,9 @@
 #include "llconversationmodel.h"
 #include "llconversationview.h"
 #include "lltexteditor.h"
+// [RLVa:KB] - @shownames
+#include "rlvhelper.h"
+// [/RLVa:KB]
 
 class LLPanelChatControlPanel;
 class LLChatEntry;
@@ -45,6 +48,10 @@ class LLChatHistory;
 class LLFloaterIMSessionTab
 	: public LLTransientDockableFloater
 {
+// [RLVa:KB] - @shownames
+	friend struct RlvCommandHandler<RLV_TYPE_ADDREM, RLV_BHVR_SHOWNAMES>;
+	friend struct RlvCommandHandler<RLV_TYPE_ADDREM, RLV_BHVR_SHOWNEARBY>;
+// [/RLVa:KB]
 
 public:
 	LOG_CLASS(LLFloaterIMSessionTab);
@@ -103,6 +110,8 @@ class LLFloaterIMSessionTab
 	void restoreFloater();
 	void saveCollapsedState();
 
+	void updateChatIcon(const LLUUID& id);
+
 	LLView* getChatHistory();
 
 protected:
diff --git a/indra/newview/llfloaterlandholdings.cpp b/indra/newview/llfloaterlandholdings.cpp
index f34760a6bf7c38c31ad6138c9205031fed3f5fe5..749a3d26862f9c9c1cbdc4e8fde28f2c6bf006b3 100644
--- a/indra/newview/llfloaterlandholdings.cpp
+++ b/indra/newview/llfloaterlandholdings.cpp
@@ -51,6 +51,9 @@
 
 #include "llgroupactions.h"
 
+const std::string LINDEN_HOMES_SKU = "131";
+bool LLFloaterLandHoldings::sHasLindenHome = false;
+
 // protected
 LLFloaterLandHoldings::LLFloaterLandHoldings(const LLSD& key)
 :	LLFloater(key),
@@ -148,10 +151,24 @@ void LLFloaterLandHoldings::refresh()
 void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)
 {
 	LLFloaterLandHoldings* self = LLFloaterReg::findTypedInstance<LLFloaterLandHoldings>("land_holdings");
-
-	// Is this packet from an old, closed window?
+	S32 count = msg->getNumberOfBlocks("QueryData");
+	std::string land_sku;
+	sHasLindenHome = false;
 	if (!self)
 	{
+		for (S32 i = 0; i < count; i++)
+		{
+			if ( msg->getSizeFast(_PREHASH_QueryData, i, _PREHASH_ProductSKU) > 0 )
+			{
+				msg->getStringFast(	_PREHASH_QueryData, _PREHASH_ProductSKU, land_sku, i);
+
+				if (LINDEN_HOMES_SKU == land_sku)
+				{
+					sHasLindenHome = true;
+					return;
+				}
+			}
+		}
 		return;
 	}
 
@@ -174,12 +191,9 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)
 	F32		global_x;
 	F32		global_y;
 	std::string	sim_name;
-	std::string land_sku;
 	std::string land_type;
 	
-	S32 i;
-	S32 count = msg->getNumberOfBlocks("QueryData");
-	for (i = 0; i < count; i++)
+	for (S32 i = 0; i < count; i++)
 	{
 		msg->getUUID("QueryData", "OwnerID", owner_id, i);
 		msg->getString("QueryData", "Name", name, i);
@@ -196,6 +210,10 @@ void LLFloaterLandHoldings::processPlacesReply(LLMessageSystem* msg, void**)
 			msg->getStringFast(	_PREHASH_QueryData, _PREHASH_ProductSKU, land_sku, i);
 			LL_INFOS() << "Land sku: " << land_sku << LL_ENDL;
 			land_type = LLProductInfoRequestManager::instance().getDescriptionForSku(land_sku);
+			if (LINDEN_HOMES_SKU == land_sku)
+			{
+				sHasLindenHome = true;
+			}
 		}
 		else
 		{
diff --git a/indra/newview/llfloaterlandholdings.h b/indra/newview/llfloaterlandholdings.h
index d1d510bb40a189007bbbe397b2a366d4d9f8e028..90e75b10627cb20001db37095ba81690c604ed63 100644
--- a/indra/newview/llfloaterlandholdings.h
+++ b/indra/newview/llfloaterlandholdings.h
@@ -57,6 +57,8 @@ class LLFloaterLandHoldings
 
 	static void onGrantList(void* data);
 
+	static bool sHasLindenHome;
+
 protected:
 	void refreshAggregates();
 
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index 889d01738931f4ed4e7eae31c913840b8ecea1bf..524162ba513badb0bf3ff12ee459a2649ba84968 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -103,14 +103,17 @@ void LLPanelMarketplaceListings::buildAllPanels()
     panel = buildInventoryPanel("Active Items", "panel_marketplace_listings_listed.xml");
 	panel->getFilter().setFilterMarketplaceActiveFolders();
 	panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+	panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");
 	panel->getFilter().markDefault();
     panel = buildInventoryPanel("Inactive Items", "panel_marketplace_listings_unlisted.xml");
 	panel->getFilter().setFilterMarketplaceInactiveFolders();
 	panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+	panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");
 	panel->getFilter().markDefault();
     panel = buildInventoryPanel("Unassociated Items", "panel_marketplace_listings_unassociated.xml");
 	panel->getFilter().setFilterMarketplaceUnassociatedFolders();
 	panel->getFilter().setEmptyLookupMessage("MarketplaceNoMatchingItems");
+	panel->getFilter().setDefaultEmptyLookupMessage("MarketplaceNoListing");
 	panel->getFilter().markDefault();
 
     // Set the tab panel
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index b9c03f66a3ee253ee5840de2f6b66e5b22bf6044..d9edd4dc30b16b6a7f3f03431c70e92c7b267edf 100644
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -103,6 +103,11 @@ LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod)
 
 void LLMeshFilePicker::notify(const std::vector<std::string>& filenames)
 {
+	if(LLAppViewer::instance()->quitRequested())
+	{
+		return;
+	}
+	
 	if (filenames.size() > 0)
 	{
 		mMP->loadModel(filenames[0], mLOD);
@@ -906,7 +911,7 @@ BOOL LLFloaterModelPreview::handleScrollWheel(S32 x, S32 y, S32 clicks)
     {
         LLFloaterModelUploadBase::handleScrollWheel(x, y, clicks);
     }
-    return TRUE;
+	return TRUE;
 }
 
 /*virtual*/
@@ -1287,47 +1292,47 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl
 void LLFloaterModelPreview::addStringToLog(const std::string& message, const LLSD& args, bool flash, S32 lod)
 {
     if (sInstance && sInstance->hasString(message))
-    {
+	{
         std::string str;
         switch (lod)
-        {
+{
         case LLModel::LOD_IMPOSTOR: str = "LOD0 "; break;
         case LLModel::LOD_LOW:      str = "LOD1 "; break;
         case LLModel::LOD_MEDIUM:   str = "LOD2 "; break;
         case LLModel::LOD_PHYSICS:  str = "PHYS "; break;
         case LLModel::LOD_HIGH:     str = "LOD3 ";   break;
         default: break;
-        }
-        
+}
+
         LLStringUtil::format_map_t args_msg;
         LLSD::map_const_iterator iter = args.beginMap();
         LLSD::map_const_iterator end = args.endMap();
         for (; iter != end; ++iter)
-        {
+{
             args_msg[iter->first] = iter->second.asString();
-        }
+		}		
         str += sInstance->getString(message, args_msg);
         sInstance->addStringToLogTab(str, flash);
-    }
-}
+	}
+	}
 
 // static
 void LLFloaterModelPreview::addStringToLog(const std::string& str, bool flash)
-{
+	{
     if (sInstance)
-    {
+		{
         sInstance->addStringToLogTab(str, flash);
-    }
-}
+				}
+			}
 
 // static
 void LLFloaterModelPreview::addStringToLog(const std::ostringstream& strm, bool flash)
-{
+			{
     if (sInstance)
-    {
+            {
         sInstance->addStringToLogTab(strm.str(), flash);
-    }
-}
+            }
+		}
 
 void LLFloaterModelPreview::clearAvatarTab()
 {
@@ -1338,9 +1343,9 @@ void LLFloaterModelPreview::clearAvatarTab()
     joints_pos->deleteAllItems();    mSelectedJointName.clear();
 
     for (U32 i = 0; i < LLModel::NUM_LODS; ++i)
-    {
+{
         mJointOverrides[i].clear();
-    }
+	}
 
     LLTextBox *joint_total_descr = panel->getChild<LLTextBox>("conflicts_description");
     joint_total_descr->setTextArg("[CONFLICTS]", llformat("%d", 0));
@@ -1349,34 +1354,34 @@ void LLFloaterModelPreview::clearAvatarTab()
 
     LLTextBox *joint_pos_descr = panel->getChild<LLTextBox>("pos_overrides_descr");
     joint_pos_descr->setTextArg("[JOINT]", std::string("mPelvis")); // Might be better to hide it
-}
+			}
 
 void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
-{
+			{
     S32 display_lod = mModelPreview->mPreviewLOD;
     if (mModelPreview->mModel[display_lod].empty())
-    {
+				{
         mSelectedJointName.clear();
         return;
-    }
+					}
 
     // Joints will be listed as long as they are listed in mAlternateBindMatrix
     // even if they are for some reason identical to defaults.
     // Todo: Are overrides always identical for all lods? They normally are, but there might be situations where they aren't.
     if (mJointOverrides[display_lod].empty())
-    {
+					{
         // populate map
         for (LLModelLoader::scene::iterator iter = mModelPreview->mScene[display_lod].begin(); iter != mModelPreview->mScene[display_lod].end(); ++iter)
-        {
+					{
             for (LLModelLoader::model_instance_list::iterator model_iter = iter->second.begin(); model_iter != iter->second.end(); ++model_iter)
-            {
+					{
                 LLModelInstance& instance = *model_iter;
                 LLModel* model = instance.mModel;
                 const LLMeshSkinInfo *skin = &model->mSkinInfo;
                 U32 joint_count = LLSkinningUtil::getMeshJointCount(skin);
                 U32 bind_count = highlight_overrides ? skin->mAlternateBindMatrix.size() : 0; // simply do not include overrides if data is not needed
                 if (bind_count > 0 && bind_count != joint_count)
-                {
+						{
                     std::ostringstream out;
                     out << "Invalid joint overrides for model " << model->getName();
                     out << ". Amount of joints " << joint_count;
@@ -1385,68 +1390,68 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
                     addStringToLog(out.str(), true);
                     // Disable overrides for this model
                     bind_count = 0;
-                }
+						}
                 if (bind_count > 0)
-                {
+						{
                     for (U32 j = 0; j < joint_count; ++j)
-                    {
+							{
                         const LLVector3& joint_pos = skin->mAlternateBindMatrix[j].getTranslation();
                         LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
 
                         LLJoint* pJoint = LLModelPreview::lookupJointByName(skin->mJointNames[j], mModelPreview);
                         if (pJoint)
-                        {
+							{
                             // see how voavatar uses aboveJointPosThreshold
                             if (pJoint->aboveJointPosThreshold(joint_pos))
-                            {
+				{
                                 // valid override
                                 if (data.mPosOverrides.size() > 0
                                     && (data.mPosOverrides.begin()->second - joint_pos).lengthSquared() > (LL_JOINT_TRESHOLD_POS_OFFSET * LL_JOINT_TRESHOLD_POS_OFFSET))
-                                {
+					{
                                     // File contains multiple meshes with conflicting joint offsets
                                     // preview may be incorrect, upload result might wary (depends onto
                                     // mesh_id that hasn't been generated yet).
                                     data.mHasConflicts = true;
-                                }
+							}
                                 data.mPosOverrides[model->getName()] = joint_pos;
-                            }
-                            else
-                            {
+						}
+						else
+						{
                                 // default value, it won't be accounted for by avatar
                                 data.mModelsNoOverrides.insert(model->getName());
-                            }
-                        }
-                    }
-                }
-                else
-                {
+					}
+					}
+				}
+			}
+			else
+			{
                     for (U32 j = 0; j < joint_count; ++j)
-                    {
+				{				
                         LLJointOverrideData &data = mJointOverrides[display_lod][skin->mJointNames[j]];
                         data.mModelsNoOverrides.insert(model->getName());
                     }
                 }
-            }
-        }
-    }
+			}
+		}
+	}
 
     LLPanel *panel = mTabContainer->getPanelByName("rigging_panel");
     LLScrollListCtrl *joints_list = panel->getChild<LLScrollListCtrl>("joints_list");
 
     if (joints_list->isEmpty())
-    {
+	{
         // Populate table
 
-        std::map<std::string, std::string> joint_alias_map;
+    std::map<std::string, std::string> joint_alias_map;
         mModelPreview->getJointAliases(joint_alias_map);
-
+    
         S32 conflicts = 0;
         joint_override_data_map_t::iterator joint_iter = mJointOverrides[display_lod].begin();
         joint_override_data_map_t::iterator joint_end = mJointOverrides[display_lod].end();
         while (joint_iter != joint_end)
-        {
+	{
             const std::string& listName = joint_iter->first;
-
+        
             LLScrollListItem::Params item_params;
             item_params.value(listName);
 
@@ -1454,38 +1459,38 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
             cell_params.font = LLFontGL::getFontSansSerif();
             cell_params.value = listName;
             if (joint_alias_map.find(listName) == joint_alias_map.end())
-            {
+	{
                 // Missing names
                 cell_params.color = LLColor4::red;
-            }
+	}
             if (joint_iter->second.mHasConflicts)
-            {
+	{
                 // Conflicts
                 cell_params.color = LLColor4::orange;
                 conflicts++;
-            }
+	}
             if (highlight_overrides && joint_iter->second.mPosOverrides.size() > 0)
-            {
+	{
                 cell_params.font.style = "BOLD";
-            }
+	}
 
             item_params.columns.add(cell_params);
 
             joints_list->addRow(item_params, ADD_BOTTOM);
             joint_iter++;
-        }
+	}
         joints_list->selectFirstItem();
         LLScrollListItem *selected = joints_list->getFirstSelected();
         if (selected)
-        {
+{
             mSelectedJointName = selected->getValue().asString();
-        }
+	}
 
         LLTextBox *joint_conf_descr = panel->getChild<LLTextBox>("conflicts_description");
         joint_conf_descr->setTextArg("[CONFLICTS]", llformat("%d", conflicts));
         joint_conf_descr->setTextArg("[JOINTS_COUNT]", llformat("%d", mJointOverrides[display_lod].size()));
-    }
-}
+		}
+	}
 
 //-----------------------------------------------------------------------------
 // addStringToLogTab()
@@ -1493,52 +1498,52 @@ void LLFloaterModelPreview::updateAvatarTab(bool highlight_overrides)
 void LLFloaterModelPreview::addStringToLogTab(const std::string& str, bool flash)
 {
     if (str.empty())
-    {
-        return;
-    }
+		{
+		return;
+	}
 
     LLWString text = utf8str_to_wstring(str);
     S32 add_text_len = text.length() + 1; // newline
     S32 editor_max_len = mUploadLogText->getMaxTextLength();
     if (add_text_len > editor_max_len)
-    {
-        return;
-    }
+		{
+		return;
+	}
 
     // Make sure we have space for new string
     S32 editor_text_len = mUploadLogText->getLength();
     if (editor_max_len < (editor_text_len + add_text_len)
         && mUploadLogText->getLineCount() <= 0)
-    {
+	{
         mUploadLogText->getTextBoundingRect();// forces a reflow() to fix line count
-    }
+			}
     while (editor_max_len < (editor_text_len + add_text_len))
-    {
+		{
         S32 shift = mUploadLogText->removeFirstLine();
         if (shift > 0)
-        {
+	{
             // removed a line
             editor_text_len -= shift;
-        }
-        else
-        {
+}
+	else
+	{
             //nothing to remove?
             LL_WARNS() << "Failed to clear log lines" << LL_ENDL;
-            break;
-        }
-    }
+					break;
+				}
+			}
 
     mUploadLogText->appendText(str, true);
 
     if (flash)
-    {
+	{
         LLPanel* panel = mTabContainer->getPanelByName("logs_panel");
         if (mTabContainer->getCurrentPanel() != panel)
-        {
+		{
             mTabContainer->setTabPanelFlashing(panel, true);
-        }
-    }
-}
+		}
+	}
+	}
 
 void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost)
 {
@@ -1546,15 +1551,15 @@ void LLFloaterModelPreview::setDetails(F32 x, F32 y, F32 z, F32 streaming_cost,
 	childSetTextArg("import_dimensions", "[X]", llformat("%.3f", x));
 	childSetTextArg("import_dimensions", "[Y]", llformat("%.3f", y));
 	childSetTextArg("import_dimensions", "[Z]", llformat("%.3f", z));
-}
+		}
 
 void LLFloaterModelPreview::setPreviewLOD(S32 lod)
-{
+		{
 	if (mModelPreview)
 	{
 		mModelPreview->setPreviewLOD(lod);
-	}
-}
+								}
+							}
 
 void LLFloaterModelPreview::onBrowseLOD(S32 lod)
 {
@@ -1643,13 +1648,13 @@ void LLFloaterModelPreview::setCtrlLoadFromFile(S32 lod)
         }
     }
     else
-    {
+{
         LLComboBox* lod_combo = findChild<LLComboBox>("lod_source_" + lod_name[lod]);
         if (lod_combo)
-        {
+	{
             lod_combo->setCurrentByIndex(0);
-        }
-    }
+	}
+}
 }
 
 void LLFloaterModelPreview::setStatusMessage(const std::string& msg)
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 746a7743fe2af245b79f6b5f00ea764082b55c52..d837293e4d37d2c2594963c716d4560f8f0853f1 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -71,8 +71,9 @@
 #include "lltrans.h"
 #include "llviewercontrol.h"
 #include "llviewercamera.h"
-#include "llviewerwindow.h"
+#include "llviewereventrecorder.h"
 #include "llviewermessage.h"
+#include "llviewerwindow.h"
 #include "llviewershadermgr.h"
 #include "llviewerthrottle.h"
 #include "llvoavatarself.h"
@@ -162,87 +163,6 @@ struct LabelTable : public LLInitParam::Block<LabelTable>
     {}
 };
 
-class LLVoiceSetKeyDialog : public LLModalDialog
-{
-public:
-	LLVoiceSetKeyDialog(const LLSD& key);
-	~LLVoiceSetKeyDialog();
-	
-	/*virtual*/ BOOL postBuild();
-	
-	void setParent(LLFloaterPreference* parent) { mParent = parent; }
-	
-	BOOL handleKeyHere(KEY key, MASK mask);
-	BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down);
-	static void onCancel(void* user_data);
-		
-private:
-	LLFloaterPreference* mParent;
-};
-
-LLVoiceSetKeyDialog::LLVoiceSetKeyDialog(const LLSD& key)
-  : LLModalDialog(key),
-	mParent(NULL)
-{
-}
-
-//virtual
-BOOL LLVoiceSetKeyDialog::postBuild()
-{
-	childSetAction("Cancel", onCancel, this);
-	getChild<LLUICtrl>("Cancel")->setFocus(TRUE);
-	
-	gFocusMgr.setKeystrokesOnly(TRUE);
-	
-	return TRUE;
-}
-
-LLVoiceSetKeyDialog::~LLVoiceSetKeyDialog()
-{
-}
-
-BOOL LLVoiceSetKeyDialog::handleKeyHere(KEY key, MASK mask)
-{
-	BOOL result = TRUE;
-	
-	if (key == 'Q' && mask == MASK_CONTROL)
-	{
-		result = FALSE;
-	}
-	else if (mParent)
-	{
-		mParent->setKey(key);
-	}
-	closeFloater();
-	return result;
-}
-
-BOOL LLVoiceSetKeyDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
-{
-    BOOL result = FALSE;
-    if (down
-        && (clicktype == LLMouseHandler::CLICK_MIDDLE || clicktype == LLMouseHandler::CLICK_BUTTON4 || clicktype == LLMouseHandler::CLICK_BUTTON5)
-        && mask == 0)
-    {
-        mParent->setMouse(clicktype);
-        result = TRUE;
-        closeFloater();
-    }
-    else
-    {
-        result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
-    }
-
-    return result;
-}
-
-//static
-void LLVoiceSetKeyDialog::onCancel(void* user_data)
-{
-	LLVoiceSetKeyDialog* self = (LLVoiceSetKeyDialog*)user_data;
-	self->closeFloater();
-}
-
 
 // global functions 
 
@@ -322,37 +242,6 @@ void handleAppearanceCameraMovementChanged(const LLSD& newvalue)
 	}
 }
 
-/*bool callback_skip_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	if (0 == option && floater )
-	{
-		if ( floater )
-		{
-			floater->setAllIgnored();
-		//	LLFirstUse::disableFirstUse();
-			floater->buildPopupLists();
-		}
-	}
-	return false;
-}
-
-bool callback_reset_dialogs(const LLSD& notification, const LLSD& response, LLFloaterPreference* floater)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	if ( 0 == option && floater )
-	{
-		if ( floater )
-		{
-			floater->resetAllIgnored();
-			//LLFirstUse::resetFirstUse();
-			floater->buildPopupLists();
-		}
-	}
-	return false;
-}
-*/
-
 void fractionFromDecimal(F32 decimal_val, S32& numerator, S32& denominator)
 {
 	numerator = 0;
@@ -377,8 +266,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mGotPersonalInfo(false),
 	mOriginalIMViaEmail(false),
 	mLanguageChanged(false),
-	mAvatarDataInitialized(false),
-	mClickActionDirty(false)
+	mAvatarDataInitialized(false)
 {
 	LLConversationLog::instance().addObserver(this);
 
@@ -387,7 +275,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	static bool registered_dialog = false;
 	if (!registered_dialog)
 	{
-		LLFloaterReg::add("voice_set_key", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLVoiceSetKeyDialog>);
+		LLFloaterReg::add("keybind_dialog", "floater_select_key.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLSetKeyBindDialog>);
 		registered_dialog = true;
 	}
 	
@@ -400,8 +288,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.ResetCache",				boost::bind(&LLFloaterPreference::onClickResetCache, this));
 	mCommitCallbackRegistrar.add("Pref.ClickSkin",				boost::bind(&LLFloaterPreference::onClickSkin, this,_1, _2));
 	mCommitCallbackRegistrar.add("Pref.SelectSkin",				boost::bind(&LLFloaterPreference::onSelectSkin, this));
-	mCommitCallbackRegistrar.add("Pref.VoiceSetKey",			boost::bind(&LLFloaterPreference::onClickSetKey, this));
-	mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse",	boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this));
 	mCommitCallbackRegistrar.add("Pref.SetSounds",				boost::bind(&LLFloaterPreference::onClickSetSounds, this));
 	mCommitCallbackRegistrar.add("Pref.ClickEnablePopup",		boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
 	mCommitCallbackRegistrar.add("Pref.ClickDisablePopup",		boost::bind(&LLFloaterPreference::onClickDisablePopup, this));	
@@ -696,12 +582,6 @@ void LLFloaterPreference::apply()
 	}
 
 	saveAvatarProperties();
-
-	if (mClickActionDirty)
-	{
-		updateClickActionSettings();
-		mClickActionDirty = false;
-	}
 }
 
 void LLFloaterPreference::cancel()
@@ -734,11 +614,7 @@ void LLFloaterPreference::cancel()
 	// reverts any changes to current skin
 	gSavedSettings.setString("SkinCurrent", sSkin);
 
-	if (mClickActionDirty)
-	{
-		updateClickActionControls();
-		mClickActionDirty = false;
-	}
+	updateClickActionViews();
 
 	LLFloaterPreferenceProxy * advanced_proxy_settings = LLFloaterReg::findTypedInstance<LLFloaterPreferenceProxy>("prefs_proxy");
 	if (advanced_proxy_settings)
@@ -823,7 +699,7 @@ void LLFloaterPreference::onOpen(const LLSD& key)
 	onChangeAnimationFolder();
 
 	// Load (double-)click to walk/teleport settings.
-	updateClickActionControls();
+	updateClickActionViews();
 	
 	// Enabled/disabled popups, might have been changed by user actions
 	// while preferences floater was closed.
@@ -1497,7 +1373,7 @@ void LLAvatarComplexityControls::setIndirectMaxNonImpostors()
 {
 	U32 max_non_impostors = gSavedSettings.getU32("RenderAvatarMaxNonImpostors");
 	// for this one, we just need to make zero, which means off, the max value of the slider
-	U32 indirect_max_non_impostors = (0 == max_non_impostors) ? LLVOAvatar::IMPOSTORS_OFF : max_non_impostors;
+	U32 indirect_max_non_impostors = (0 == max_non_impostors) ? LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER : max_non_impostors;
 	gSavedSettings.setU32("IndirectMaxNonImpostors", indirect_max_non_impostors);
 }
 
@@ -1642,6 +1518,7 @@ void LLFloaterPreference::refresh()
 	{
 		advanced->refresh();
 	}
+    updateClickActionViews();
 }
 
 void LLFloaterPreferenceGraphicsAdvanced::refresh()
@@ -1683,72 +1560,6 @@ void LLFloaterPreference::onChangeQuality(const LLSD& data)
 	refresh();
 }
 
-void LLFloaterPreference::onClickSetKey()
-{
-	LLVoiceSetKeyDialog* dialog = LLFloaterReg::showTypedInstance<LLVoiceSetKeyDialog>("voice_set_key", LLSD(), TRUE);
-	if (dialog)
-	{
-		dialog->setParent(this);
-	}
-}
-
-void LLFloaterPreference::setKey(KEY key)
-{
-	getChild<LLUICtrl>("modifier_combo")->setValue(LLKeyboard::stringFromKey(key));
-	// update the control right away since we no longer wait for apply
-	getChild<LLUICtrl>("modifier_combo")->onCommit();
-}
-
-void LLFloaterPreference::setMouse(LLMouseHandler::EClickType click)
-{
-    std::string bt_name;
-    std::string ctrl_value;
-    switch (click)
-    {
-        case LLMouseHandler::CLICK_MIDDLE:
-            bt_name = "middle_mouse";
-            ctrl_value = MIDDLE_MOUSE_CV;
-            break;
-        case LLMouseHandler::CLICK_BUTTON4:
-            bt_name = "button4_mouse";
-            ctrl_value = MOUSE_BUTTON_4_CV;
-            break;
-        case LLMouseHandler::CLICK_BUTTON5:
-            bt_name = "button5_mouse";
-            ctrl_value = MOUSE_BUTTON_5_CV;
-            break;
-        default:
-            break;
-    }
-
-    if (!ctrl_value.empty())
-    {
-        LLUICtrl* p2t_line_editor = getChild<LLUICtrl>("modifier_combo");
-        // We are using text control names for readability and compatibility with voice
-        p2t_line_editor->setControlValue(ctrl_value);
-        LLPanel* advanced_preferences = dynamic_cast<LLPanel*>(p2t_line_editor->getParent());
-        if (advanced_preferences)
-        {
-            p2t_line_editor->setValue(advanced_preferences->getString(bt_name));
-        }
-    }
-}
-
-void LLFloaterPreference::onClickSetMiddleMouse()
-{
-	LLUICtrl* p2t_line_editor = getChild<LLUICtrl>("modifier_combo");
-
-	// update the control right away since we no longer wait for apply
-	p2t_line_editor->setControlValue(MIDDLE_MOUSE_CV);
-
-	//push2talk button "middle mouse" control value is in English, need to localize it for presentation
-	LLPanel* advanced_preferences = dynamic_cast<LLPanel*>(p2t_line_editor->getParent());
-	if (advanced_preferences)
-	{
-		p2t_line_editor->setValue(advanced_preferences->getString("middle_mouse"));
-	}
-}
-
 void LLFloaterPreference::onClickSetSounds()
 {
 	// Disable Enable gesture sounds checkbox if the master sound is disabled 
@@ -1756,18 +1567,6 @@ void LLFloaterPreference::onClickSetSounds()
 	getChild<LLCheckBoxCtrl>("gesture_audio_play_btn")->setEnabled(!gSavedSettings.getBOOL("MuteSounds"));
 }
 
-/*
-void LLFloaterPreference::onClickSkipDialogs()
-{
-	LLNotificationsUtil::add("SkipShowNextTimeDialogs", LLSD(), LLSD(), boost::bind(&callback_skip_dialogs, _1, _2, this));
-}
-
-void LLFloaterPreference::onClickResetDialogs()
-{
-	LLNotificationsUtil::add("ResetShowNextTimeDialogs", LLSD(), LLSD(), boost::bind(&callback_reset_dialogs, _1, _2, this));
-}
- */
-
 void LLFloaterPreference::onClickEnablePopup()
 {	
 	LLScrollListCtrl& disabled_popups = getChildRef<LLScrollListCtrl>("disabled_popups");
@@ -1997,7 +1796,7 @@ void LLFloaterPreferenceGraphicsAdvanced::updateMaxNonImpostors()
 	LLSliderCtrl* ctrl = getChild<LLSliderCtrl>("IndirectMaxNonImpostors",true);
 	U32 value = ctrl->getValue().asInteger();
 
-	if (0 == value || LLVOAvatar::IMPOSTORS_OFF <= value)
+	if (0 == value || LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER <= value)
 	{
 		value=0;
 	}
@@ -2249,7 +2048,7 @@ void LLFloaterPreference::onClickAdvanced()
 
 void LLFloaterPreference::onClickActionChange()
 {
-	mClickActionDirty = true;
+    updateClickActionControls();
 }
 
 void LLFloaterPreference::onClickPermsDefault()
@@ -2289,21 +2088,81 @@ void LLFloaterPreference::onLogChatHistorySaved()
 	}
 }
 
-void LLFloaterPreference::updateClickActionSettings()
+void LLFloaterPreference::updateClickActionControls()
 {
-	const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
-	const int double_clk_action = getChild<LLComboBox>("double_click_action_combo")->getValue().asInteger();
-
-	gSavedSettings.setBOOL("ClickToWalk",			single_clk_action == 1);
-	gSavedSettings.setBOOL("DoubleClickAutoPilot",	double_clk_action == 1);
-	gSavedSettings.setBOOL("DoubleClickTeleport",	double_clk_action == 2);
+    const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
+    const int double_clk_action = getChild<LLComboBox>("double_click_action_combo")->getValue().asInteger();
+
+    // Todo: This is a very ugly way to get access to keybindings.
+    // Reconsider possible options.
+    // Potential option: make constructor of LLKeyConflictHandler private
+    // but add a getter that will return shared pointer for specific
+    // mode, pointer should only exist so long as there are external users.
+    // In such case we won't need to do this 'dynamic_cast' nightmare.
+    // updateTable() can also be avoided
+    LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+    for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+        iter != tabcontainer->getChildList()->end(); ++iter)
+    {
+        LLView* view = *iter;
+        LLPanelPreferenceControls* panel = dynamic_cast<LLPanelPreferenceControls*>(view);
+        if (panel)
+        {
+            panel->setKeyBind("walk_to",
+                              EMouseClickType::CLICK_LEFT,
+                              KEY_NONE,
+                              MASK_NONE,
+                              single_clk_action == 1);
+            
+            panel->setKeyBind("walk_to",
+                              EMouseClickType::CLICK_DOUBLELEFT,
+                              KEY_NONE,
+                              MASK_NONE,
+                              double_clk_action == 1);
+            
+            panel->setKeyBind("teleport_to",
+                              EMouseClickType::CLICK_DOUBLELEFT,
+                              KEY_NONE,
+                              MASK_NONE,
+                              double_clk_action == 2);
+
+            panel->updateAndApply();
+        }
+    }
 }
 
-void LLFloaterPreference::updateClickActionControls()
+void LLFloaterPreference::updateClickActionViews()
 {
-	const bool click_to_walk = gSavedSettings.getBOOL("ClickToWalk");
-	const bool dbl_click_to_walk = gSavedSettings.getBOOL("DoubleClickAutoPilot");
-	const bool dbl_click_to_teleport = gSavedSettings.getBOOL("DoubleClickTeleport");
+    bool click_to_walk = false;
+    bool dbl_click_to_walk = false;
+    bool dbl_click_to_teleport = false;
+
+    // Todo: This is a very ugly way to get access to keybindings.
+    // Reconsider possible options.
+    LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
+    for (child_list_t::const_iterator iter = tabcontainer->getChildList()->begin();
+        iter != tabcontainer->getChildList()->end(); ++iter)
+    {
+        LLView* view = *iter;
+        LLPanelPreferenceControls* panel = dynamic_cast<LLPanelPreferenceControls*>(view);
+        if (panel)
+        {
+            click_to_walk = panel->canKeyBindHandle("walk_to",
+                EMouseClickType::CLICK_LEFT,
+                KEY_NONE,
+                MASK_NONE);
+
+            dbl_click_to_walk = panel->canKeyBindHandle("walk_to",
+                EMouseClickType::CLICK_DOUBLELEFT,
+                KEY_NONE,
+                MASK_NONE);
+
+            dbl_click_to_teleport = panel->canKeyBindHandle("teleport_to",
+                EMouseClickType::CLICK_DOUBLELEFT,
+                KEY_NONE,
+                MASK_NONE);
+        }
+    }
 
 	getChild<LLComboBox>("single_click_action_combo")->setValue((int)click_to_walk);
 	getChild<LLComboBox>("double_click_action_combo")->setValue(dbl_click_to_teleport ? 2 : (int)dbl_click_to_walk);
@@ -2490,25 +2349,6 @@ BOOL LLPanelPreference::postBuild()
 		getChild<LLTextBox>("mute_chb_label")->setClickedCallback(boost::bind(&toggleMuteWhenMinimized));
 	}
 
-	//////////////////////PanelAdvanced ///////////////////
-	if (hasChild("modifier_combo", TRUE))
-	{
-		//localizing if push2talk button is set to middle mouse
-		std::string modifier_value = getChild<LLUICtrl>("modifier_combo")->getValue().asString();
-		if (MIDDLE_MOUSE_CV == modifier_value)
-		{
-			getChild<LLUICtrl>("modifier_combo")->setValue(getString("middle_mouse"));
-		}
-		else if (MOUSE_BUTTON_4_CV == modifier_value)
-		{
-			getChild<LLUICtrl>("modifier_combo")->setValue(getString("button4_mouse"));
-		}
-		else if (MOUSE_BUTTON_5_CV == modifier_value)
-		{
-			getChild<LLUICtrl>("modifier_combo")->setValue(getString("button5_mouse"));
-		}
-	}
-
 	//////////////////////PanelSetup ///////////////////
 	if (hasChild("max_bandwidth"), TRUE)
 	{
@@ -2789,7 +2629,7 @@ void LLPanelPreferenceGraphics::setPresetText()
 		}
 	}
 
-	if (hasDirtyChilds() && !preset_graphic_active.empty())
+    if (hasDirtyChilds() && !preset_graphic_active.empty())
 	{
 		gSavedSettings.setString("PresetGraphicActive", "");
 		preset_graphic_active.clear();
@@ -2909,6 +2749,585 @@ void LLPanelPreferenceGraphics::setHardwareDefaults()
 	resetDirtyChilds();
 }
 
+//------------------------LLPanelPreferenceControls--------------------------------
+static LLPanelInjector<LLPanelPreferenceControls> t_pref_contrls("panel_preference_controls");
+
+LLPanelPreferenceControls::LLPanelPreferenceControls()
+    :LLPanelPreference(),
+    mEditingColumn(-1),
+    mEditingMode(0)
+{
+    // MODE_COUNT - 1 because there are currently no settings assigned to 'saved settings'.
+    for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+    {
+        mConflictHandler[i].setLoadMode((LLKeyConflictHandler::ESourceMode)i);
+    }
+}
+
+LLPanelPreferenceControls::~LLPanelPreferenceControls()
+{
+}
+
+BOOL LLPanelPreferenceControls::postBuild()
+{
+    // populate list of controls
+    pControlsTable = getChild<LLScrollListCtrl>("controls_list");
+    pKeyModeBox = getChild<LLComboBox>("key_mode");
+
+    pControlsTable->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onListCommit, this));
+    pKeyModeBox->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onModeCommit, this));
+    getChild<LLButton>("restore_defaults")->setCommitCallback(boost::bind(&LLPanelPreferenceControls::onRestoreDefaultsBtn, this));
+
+    return TRUE;
+}
+
+void LLPanelPreferenceControls::regenerateControls()
+{
+    mEditingMode = pKeyModeBox->getValue().asInteger();
+    mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode);
+    populateControlTable();
+}
+
+bool LLPanelPreferenceControls::addControlTableColumns(const std::string &filename)
+{
+    LLXMLNodePtr xmlNode;
+    LLScrollListCtrl::Contents contents;
+    if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
+    {
+        LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+        return false;
+    }
+    LLXUIParser parser;
+    parser.readXUI(xmlNode, contents, filename);
+
+    if (!contents.validateBlock())
+    {
+        return false;
+    }
+
+    for (LLInitParam::ParamIterator<LLScrollListColumn::Params>::const_iterator col_it = contents.columns.begin();
+        col_it != contents.columns.end();
+        ++col_it)
+    {
+        pControlsTable->addColumn(*col_it);
+    }
+
+    return true;
+}
+
+bool LLPanelPreferenceControls::addControlTableRows(const std::string &filename)
+{
+    LLXMLNodePtr xmlNode;
+    LLScrollListCtrl::Contents contents;
+    if (!LLUICtrlFactory::getLayeredXMLNode(filename, xmlNode))
+    {
+        LL_WARNS() << "Failed to load " << filename << LL_ENDL;
+        return false;
+    }
+    LLXUIParser parser;
+    parser.readXUI(xmlNode, contents, filename);
+
+    if (!contents.validateBlock())
+    {
+        return false;
+    }
+
+    LLScrollListCell::Params cell_params;
+    // init basic cell params
+    cell_params.font = LLFontGL::getFontSansSerif();
+    cell_params.font_halign = LLFontGL::LEFT;
+    cell_params.column = "";
+    cell_params.value = "";
+
+
+    for (LLInitParam::ParamIterator<LLScrollListItem::Params>::const_iterator row_it = contents.rows.begin();
+        row_it != contents.rows.end();
+        ++row_it)
+    {
+        std::string control = row_it->value.getValue().asString();
+        if (!control.empty() && control != "menu_separator")
+        {
+            bool show = true;
+            bool enabled = mConflictHandler[mEditingMode].canAssignControl(control);
+            if (!enabled)
+            {
+                // If empty: this is a placeholder to make sure user won't assign
+                // value by accident, don't show it
+                // If not empty: predefined control combination user should see
+                // to know that combination is reserved
+                show = !mConflictHandler[mEditingMode].isControlEmpty(control);
+                // example: teleport_to and walk_to in first person view, and
+                // sitting related functions, see generatePlaceholders()
+            }
+
+            if (show)
+            {
+                // At the moment viewer is hardcoded to assume that columns are named as lst_ctrl%d
+                LLScrollListItem::Params item_params(*row_it);
+                item_params.enabled.setValue(enabled);
+
+                S32 num_columns = pControlsTable->getNumColumns();
+                for (S32 col = 1; col < num_columns; col++)
+                {
+                    cell_params.column = llformat("lst_ctrl%d", col);
+                    cell_params.value = mConflictHandler[mEditingMode].getControlString(control, col - 1);
+                    item_params.columns.add(cell_params);
+                }
+                pControlsTable->addRow(item_params, EAddPosition::ADD_BOTTOM);
+            }
+        }
+        else
+        {
+            // Separator example:
+            // <rows
+            //  enabled = "false">
+            //  <columns
+            //   type = "icon"
+            //   color = "0 0 0 0.7"
+            //   halign = "center"
+            //   value = "menu_separator"
+            //   column = "lst_action" / >
+            //</rows>
+            pControlsTable->addRow(*row_it, EAddPosition::ADD_BOTTOM);
+        }
+    }
+    return true;
+}
+
+void LLPanelPreferenceControls::addControlTableSeparator()
+{
+    LLScrollListItem::Params separator_params;
+    separator_params.enabled(false);
+    LLScrollListCell::Params column_params;
+    column_params.type = "icon";
+    column_params.value = "menu_separator";
+    column_params.column = "lst_action";
+    column_params.color = LLColor4(0.f, 0.f, 0.f, 0.7f);
+    column_params.font_halign = LLFontGL::HCENTER;
+    separator_params.columns.add(column_params);
+    pControlsTable->addRow(separator_params, EAddPosition::ADD_BOTTOM);
+}
+
+void LLPanelPreferenceControls::populateControlTable()
+{
+    pControlsTable->clearRows();
+    pControlsTable->clearColumns();
+
+    // Add columns
+    std::string filename;
+    switch ((LLKeyConflictHandler::ESourceMode)mEditingMode)
+    {
+    case LLKeyConflictHandler::MODE_THIRD_PERSON:
+    case LLKeyConflictHandler::MODE_FIRST_PERSON:
+    case LLKeyConflictHandler::MODE_EDIT_AVATAR:
+    case LLKeyConflictHandler::MODE_SITTING:
+        filename = "control_table_contents_columns_basic.xml";
+        break;
+    default:
+        // Either unknown mode or MODE_SAVED_SETTINGS
+        // It doesn't have UI or actual settings yet
+        LL_INFOS() << "Unimplemented mode" << LL_ENDL;
+        return;
+    }
+    addControlTableColumns(filename);
+
+    // Add rows.
+    // Each file represents individual visual group (movement/camera/media...)
+    if (mEditingMode == LLKeyConflictHandler::MODE_FIRST_PERSON)
+    {
+        // Don't display whole camera and editing groups
+        addControlTableRows("control_table_contents_movement.xml");
+        addControlTableSeparator();
+        addControlTableRows("control_table_contents_media.xml");
+    }
+    // MODE_THIRD_PERSON; MODE_EDIT_AVATAR; MODE_SITTING
+    else if (mEditingMode < LLKeyConflictHandler::MODE_SAVED_SETTINGS)
+    {
+        // In case of 'sitting' mode, movements still apply due to vehicles
+        // but walk_to is not supported and will be hidden by addControlTableRows
+        addControlTableRows("control_table_contents_movement.xml");
+        addControlTableSeparator();
+
+        addControlTableRows("control_table_contents_camera.xml");
+        addControlTableSeparator();
+
+        addControlTableRows("control_table_contents_editing.xml");
+        addControlTableSeparator();
+
+        addControlTableRows("control_table_contents_media.xml");
+    }
+    else
+    {
+        LL_INFOS() << "Unimplemented mode" << LL_ENDL;
+        return;
+    }
+}
+
+void LLPanelPreferenceControls::updateTable()
+{
+    mEditingControl.clear();
+    std::vector<LLScrollListItem*> list = pControlsTable->getAllData();
+    for (S32 i = 0; i < list.size(); ++i)
+    {
+        std::string control = list[i]->getValue();
+        if (!control.empty())
+        {
+            LLScrollListCell* cell = NULL;
+
+            S32 num_columns = pControlsTable->getNumColumns();
+            for (S32 col = 1; col < num_columns; col++)
+            {
+                cell = list[i]->getColumn(col);
+                cell->setValue(mConflictHandler[mEditingMode].getControlString(control, col - 1));
+            }
+        }
+    }
+    pControlsTable->deselectAllItems();
+}
+
+void LLPanelPreferenceControls::apply()
+{
+    for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+    {
+        if (mConflictHandler[i].hasUnsavedChanges())
+        {
+            mConflictHandler[i].saveToSettings();
+        }
+    }
+}
+
+void LLPanelPreferenceControls::cancel()
+{
+    for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+    {
+        if (mConflictHandler[i].hasUnsavedChanges())
+        {
+            mConflictHandler[i].clear();
+        }
+    }
+    pControlsTable->clearRows();
+    pControlsTable->clearColumns();
+}
+
+void LLPanelPreferenceControls::saveSettings()
+{
+    for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+    {
+        if (mConflictHandler[i].hasUnsavedChanges())
+        {
+            mConflictHandler[i].saveToSettings();
+            mConflictHandler[i].clear();
+        }
+    }
+
+    S32 mode = pKeyModeBox->getValue().asInteger();
+    if (mConflictHandler[mode].empty() || pControlsTable->isEmpty())
+    {
+        regenerateControls();
+    }
+}
+
+void LLPanelPreferenceControls::resetDirtyChilds()
+{
+    regenerateControls();
+}
+
+void LLPanelPreferenceControls::onListCommit()
+{
+    LLScrollListItem* item = pControlsTable->getFirstSelected();
+    if (item == NULL)
+    {
+        return;
+    }
+
+    std::string control = item->getValue();
+
+    if (control.empty())
+    {
+        pControlsTable->deselectAllItems();
+        return;
+    }
+
+    if (!mConflictHandler[mEditingMode].canAssignControl(control))
+    {
+        pControlsTable->deselectAllItems();
+        return;
+    }
+
+    S32 cell_ind = item->getSelectedCell();
+    if (cell_ind <= 0)
+    {
+        pControlsTable->deselectAllItems();
+        return;
+    }
+
+    // List does not tell us what cell was clicked, so we have to figure it out manually, but
+    // fresh mouse coordinates are not yet accessible during onCommit() and there are other issues,
+    // so we cheat: remember item user clicked at, trigger 'key dialog' on hover that comes next,
+    // use coordinates from hover to calculate cell
+
+    LLScrollListCell* cell = item->getColumn(cell_ind);
+    if (cell)
+    {
+        LLSetKeyBindDialog* dialog = LLFloaterReg::getTypedInstance<LLSetKeyBindDialog>("keybind_dialog", LLSD());
+        if (dialog)
+        {
+            mEditingControl = control;
+            mEditingColumn = cell_ind;
+            dialog->setParent(this, pControlsTable, DEFAULT_KEY_FILTER);
+
+            LLFloater* root_floater = gFloaterView->getParentFloater(this);
+            if (root_floater)
+                root_floater->addDependentFloater(dialog);
+            dialog->openFloater();
+            dialog->setFocus(TRUE);
+        }
+    }
+    else
+    {
+        pControlsTable->deselectAllItems();
+    }
+}
+
+void LLPanelPreferenceControls::onModeCommit()
+{
+    mEditingMode = pKeyModeBox->getValue().asInteger();
+    if (mConflictHandler[mEditingMode].empty())
+    {
+        // opening for first time
+        mConflictHandler[mEditingMode].loadFromSettings((LLKeyConflictHandler::ESourceMode)mEditingMode);
+    }
+    populateControlTable();
+}
+
+void LLPanelPreferenceControls::onRestoreDefaultsBtn()
+{
+    LLNotificationsUtil::add("PreferenceControlsDefaults", LLSD(), LLSD(), boost::bind(&LLPanelPreferenceControls::onRestoreDefaultsResponse, this, _1, _2));
+}
+
+void LLPanelPreferenceControls::onRestoreDefaultsResponse(const LLSD& notification, const LLSD& response)
+{
+    S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+    switch(option)
+    {
+    case 0: // All
+        for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+        {
+            mConflictHandler[i].resetToDefaults();
+            // Apply changes to viewer as 'temporary'
+            mConflictHandler[i].saveToSettings(true);
+
+            // notify comboboxes in move&view about potential change
+            LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+            if (instance)
+            {
+                instance->updateClickActionViews();
+            }
+        }
+
+        updateTable();
+        break;
+    case 1: // Current
+        mConflictHandler[mEditingMode].resetToDefaults();
+        // Apply changes to viewer as 'temporary'
+        mConflictHandler[mEditingMode].saveToSettings(true);
+
+        if (mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON)
+        {
+            // notify comboboxes in move&view about potential change
+            LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+            if (instance)
+            {
+                instance->updateClickActionViews();
+            }
+        }
+
+        updateTable();
+        break;
+    case 2: // Cancel
+    default:
+        //exit;
+        break;
+    }
+}
+
+// Bypass to let Move & view read values without need to create own key binding handler
+// Assumes third person view
+// Might be better idea to just move whole mConflictHandler into LLFloaterPreference
+bool LLPanelPreferenceControls::canKeyBindHandle(const std::string &control, EMouseClickType click, KEY key, MASK mask)
+{
+    S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
+    if (mConflictHandler[mode].empty())
+    {
+        // opening for first time
+        mConflictHandler[mode].loadFromSettings(LLKeyConflictHandler::MODE_THIRD_PERSON);
+    }
+
+    return mConflictHandler[mode].canHandleControl(control, click, key, mask);
+}
+
+// Bypass to let Move & view modify values without need to create own key binding handler
+// Assumes third person view
+// Might be better idea to just move whole mConflictHandler into LLFloaterPreference
+void LLPanelPreferenceControls::setKeyBind(const std::string &control, EMouseClickType click, KEY key, MASK mask, bool set)
+{
+    S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
+    if (mConflictHandler[mode].empty())
+    {
+        // opening for first time
+        mConflictHandler[mode].loadFromSettings(LLKeyConflictHandler::MODE_THIRD_PERSON);
+    }
+
+    if (!mConflictHandler[mode].canAssignControl(mEditingControl))
+    {
+        return;
+    }
+
+    bool already_recorded = mConflictHandler[mode].canHandleControl(control, click, key, mask);
+    if (set)
+    {
+        if (already_recorded)
+        {
+            // nothing to do
+            return;
+        }
+
+        // find free spot to add data, if no free spot, assign to first
+        S32 index = 0;
+        for (S32 i = 0; i < 3; i++)
+        {
+            if (mConflictHandler[mode].getControl(control, i).isEmpty())
+            {
+                index = i;
+                break;
+            }
+        }
+        mConflictHandler[mode].registerControl(control, index, click, key, mask, true);
+    }
+    else if (!set)
+    {
+        if (!already_recorded)
+        {
+            // nothing to do
+            return;
+        }
+
+        // find specific control and reset it
+        for (S32 i = 0; i < 3; i++)
+        {
+            LLKeyData data = mConflictHandler[mode].getControl(control, i);
+            if (data.mMouse == click && data.mKey == key && data.mMask == mask)
+            {
+                mConflictHandler[mode].clearControl(control, i);
+            }
+        }
+    }
+}
+
+void LLPanelPreferenceControls::updateAndApply()
+{
+    S32 mode = LLKeyConflictHandler::MODE_THIRD_PERSON;
+    mConflictHandler[mode].saveToSettings(true);
+    updateTable();
+}
+
+// from LLSetKeybindDialog's interface
+bool LLPanelPreferenceControls::onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes)
+{
+    if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl))
+    {
+        return true;
+    }
+
+    if ( mEditingColumn > 0)
+    {
+        if (all_modes)
+        {
+            for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+            {
+                if (mConflictHandler[i].empty())
+                {
+                    mConflictHandler[i].loadFromSettings((LLKeyConflictHandler::ESourceMode)i);
+                }
+                mConflictHandler[i].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, true);
+                // Apply changes to viewer as 'temporary'
+                mConflictHandler[i].saveToSettings(true);
+            }
+        }
+        else
+        {
+            mConflictHandler[mEditingMode].registerControl(mEditingControl, mEditingColumn - 1, click, key, mask, true);
+            // Apply changes to viewer as 'temporary'
+            mConflictHandler[mEditingMode].saveToSettings(true);
+        }
+    }
+
+    updateTable();
+
+    if ((mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON || all_modes)
+        && (mEditingControl == "walk_to"
+            || mEditingControl == "teleport_to"
+            || click == CLICK_LEFT
+            || click == CLICK_DOUBLELEFT))
+    {
+        // notify comboboxes in move&view about potential change
+        LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+        if (instance)
+        {
+            instance->updateClickActionViews();
+        }
+    }
+
+    return true;
+}
+
+void LLPanelPreferenceControls::onDefaultKeyBind(bool all_modes)
+{
+    if (!mConflictHandler[mEditingMode].canAssignControl(mEditingControl))
+    {
+        return;
+    }
+    
+    if (mEditingColumn > 0)
+    {
+        if (all_modes)
+        {
+            for (U32 i = 0; i < LLKeyConflictHandler::MODE_COUNT - 1; ++i)
+            {
+                if (mConflictHandler[i].empty())
+                {
+                    mConflictHandler[i].loadFromSettings((LLKeyConflictHandler::ESourceMode)i);
+                }
+                mConflictHandler[i].resetToDefault(mEditingControl, mEditingColumn - 1);
+                // Apply changes to viewer as 'temporary'
+                mConflictHandler[i].saveToSettings(true);
+            }
+        }
+        else
+        {
+            mConflictHandler[mEditingMode].resetToDefault(mEditingControl, mEditingColumn - 1);
+            // Apply changes to viewer as 'temporary'
+            mConflictHandler[mEditingMode].saveToSettings(true);
+        }
+    }
+    updateTable();
+
+    if (mEditingMode == LLKeyConflictHandler::MODE_THIRD_PERSON || all_modes)
+    {
+        // notify comboboxes in move&view about potential change
+        LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
+        if (instance)
+        {
+            instance->updateClickActionViews();
+        }
+    }
+}
+
+void LLPanelPreferenceControls::onCancelKeyBind()
+{
+    pControlsTable->deselectAllItems();
+}
+
 LLFloaterPreferenceGraphicsAdvanced::LLFloaterPreferenceGraphicsAdvanced(const LLSD& key)
 	: LLFloater(key)
 {
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index 526214a617b2af0fa67e434c723aa90af28b8ec9..1268935712d6051663370e236ae2d49cfd8d095f 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -37,13 +37,17 @@
 #include "llavatarpropertiesprocessor.h"
 #include "llconversationlog.h"
 #include "llsearcheditor.h"
+#include "llsetkeybinddialog.h"
+#include "llkeyconflict.h"
 
 class LLConversationLogObserver;
 class LLPanelPreference;
 class LLPanelLCD;
 class LLPanelDebug;
 class LLMessageSystem;
+class LLComboBox;
 class LLScrollListCtrl;
+class LLScrollListCell;
 class LLSliderCtrl;
 class LLSD;
 class LLTextBox;
@@ -102,6 +106,8 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver,
 	void selectPrivacyPanel();
 	void selectChatPanel();
 	void getControlNames(std::vector<std::string>& names);
+	// updates click/double-click action controls depending on values from settings.xml
+	void updateClickActionViews();
 
 protected:	
 	void		onBtnOK(const LLSD& userdata);
@@ -129,9 +135,7 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver,
 
 	// callback for commit in the "Single click on land" and "Double click on land" comboboxes.
 	void onClickActionChange();
-	// updates click/double-click action settings depending on controls values
-	void updateClickActionSettings();
-	// updates click/double-click action controls depending on values from settings.xml
+	// updates click/double-click action keybindngs depending on view values
 	void updateClickActionControls();
 
 public:
@@ -146,10 +150,6 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver,
 	void onClickResetCache();
 	void onClickSkin(LLUICtrl* ctrl,const LLSD& userdata);
 	void onSelectSkin();
-	void onClickSetKey();
-	void setKey(KEY key);
-	void setMouse(LLMouseHandler::EClickType click);
-	void onClickSetMiddleMouse();
 	void onClickSetSounds();
 	void onClickEnablePopup();
 	void onClickDisablePopup();	
@@ -204,7 +204,6 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver,
 
 	static std::string sSkin;
 	notifications_map mNotificationOptions;
-	bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user.
 	bool mGotPersonalInfo;
 	bool mOriginalIMViaEmail;
 	bool mLanguageChanged;
@@ -294,6 +293,60 @@ class LLPanelPreferenceGraphics : public LLPanelPreference
 	LOG_CLASS(LLPanelPreferenceGraphics);
 };
 
+class LLPanelPreferenceControls : public LLPanelPreference, public LLKeyBindResponderInterface
+{
+	LOG_CLASS(LLPanelPreferenceControls);
+public:
+	LLPanelPreferenceControls();
+	virtual ~LLPanelPreferenceControls();
+
+	BOOL postBuild();
+
+	void apply();
+	void cancel();
+	void saveSettings();
+	void resetDirtyChilds();
+
+	void onListCommit();
+	void onModeCommit();
+	void onRestoreDefaultsBtn();
+	void onRestoreDefaultsResponse(const LLSD& notification, const LLSD& response);
+
+    // Bypass to let Move & view read values without need to create own key binding handler
+    // Todo: consider a better way to share access to keybindings
+    bool canKeyBindHandle(const std::string &control, EMouseClickType click, KEY key, MASK mask);
+    // Bypasses to let Move & view modify values without need to create own key binding handler
+    void setKeyBind(const std::string &control, EMouseClickType click, KEY key, MASK mask, bool set /*set or reset*/ );
+    void updateAndApply();
+
+    // from interface
+	/*virtual*/ bool onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes);
+    /*virtual*/ void onDefaultKeyBind(bool all_modes);
+    /*virtual*/ void onCancelKeyBind();
+
+private:
+	// reloads settings, discards current changes, updates table
+	void regenerateControls();
+
+	// These fuctions do not clean previous content
+	bool addControlTableColumns(const std::string &filename);
+	bool addControlTableRows(const std::string &filename);
+	void addControlTableSeparator();
+
+	// Cleans content and then adds content from xml files according to current mEditingMode
+    void populateControlTable();
+
+    // Updates keybindings from storage to table
+    void updateTable();
+
+	LLScrollListCtrl* pControlsTable;
+	LLComboBox *pKeyModeBox;
+	LLKeyConflictHandler mConflictHandler[LLKeyConflictHandler::MODE_COUNT];
+	std::string mEditingControl;
+	S32 mEditingColumn;
+	S32 mEditingMode;
+};
+
 class LLFloaterPreferenceGraphicsAdvanced : public LLFloater
 {
   public: 
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index bfc9b79e877e535e526ba1551399117ef417122b..80ae710b75d57106636f83bf8b1bf1d3f7c5600b 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -754,9 +754,6 @@ LLSD LLFloaterReporter::gatherReport()
 	const char* platform = "Mac";
 #elif LL_LINUX
 	const char* platform = "Lnx";
-#elif LL_SOLARIS
-	const char* platform = "Sol";
-	const char* short_platform = "O:S";
 #else
 	const char* platform = "???";
 #endif
diff --git a/indra/newview/llfolderviewmodelinventory.h b/indra/newview/llfolderviewmodelinventory.h
index 06a908cccc82a9b9a4eee074da122d6a7549ecbc..51b98339c42623ff3565dc5ec684c40e3d5a7599 100644
--- a/indra/newview/llfolderviewmodelinventory.h
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -45,6 +45,7 @@ class LLFolderViewModelItemInventory
 	virtual LLFolderType::EType getPreferredType() const = 0;
 	virtual void showProperties(void) = 0;
 	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make   into pure virtual.
+	virtual BOOL isAgentInventory() const { return FALSE; }
 	virtual BOOL isUpToDate() const = 0;
 	virtual bool hasChildren() const = 0;
 	virtual LLInventoryType::EType getInventoryType() const = 0;
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index c33ff3e709fb64b76847a3dc758b3601edd44987..33bd923b193a93b7784b10f98bb70201844f2fdc 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -39,6 +39,7 @@
 #include "llfloaterimcontainer.h"
 #include "llimview.h" // for gIMMgr
 #include "llnotificationsutil.h"
+#include "llstartup.h"
 #include "llstatusbar.h"	// can_afford_transaction()
 #include "groupchatlistener.h"
 // [RLVa:KB] - Checked: 2011-03-28 (RLVa-1.3.0)
@@ -61,6 +62,11 @@ class LLGroupHandler : public LLCommandHandler
 	bool handle(const LLSD& tokens, const LLSD& query_map,
 				LLMediaCtrl* web)
 	{
+		if (LLStartUp::getStartupState() < STATE_STARTED)
+		{
+			return true;
+		}
+
 		if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableGroupInfo"))
 		{
 			LLNotificationsUtil::add("NoGroupInfo", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index 3cbdb2e9921872d4db21524e1db2529982624352..34eaafc0b8ae92fb85bc3d81136d7308d3286c0e 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -1334,10 +1334,11 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
 // [RLVa:KB] - Checked: RLVa-1.4.9
 				if (rlv_handler_t::isEnabled())
 				{
-					if ( ((IM_LURE_USER == dialog) && (!RlvActions::canAcceptTpOffer(from_id))) ||
-					     ((IM_TELEPORT_REQUEST == dialog) && (!RlvActions::canAcceptTpRequest(from_id))) )
+                    bool fBlockTpLure = (IM_LURE_USER == dialog) && (!RlvActions::canAcceptTpOffer(from_id));
+                    bool fBlockTpRequest = (IM_TELEPORT_REQUEST == dialog) && (!RlvActions::canAcceptTpRequest(from_id));
+					if ( fBlockTpLure || fBlockTpRequest )
 					{
-						RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(RlvStringKeys::Blocked::TpLureRequestRemote));
+						RlvUtil::sendBusyMessage(from_id, RlvStrings::getString(fBlockTpLure ? RlvStringKeys::Blocked::TpLureRemote : RlvStringKeys::Blocked::TpRequestRemote));
 						if (is_do_not_disturb)
 							send_do_not_disturb_message(gMessageSystem, from_id);
 						return;
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e4a2b01c3188fa941c52472cd93cc8853058e1e0..8a62646e0771343d5d0c312e8fc55dc4fe37c4ff 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -972,6 +972,9 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 			// Incoming P2P sessions include a name that we can use to build a history file name
 			mHistoryFileName = LLCacheName::buildUsername(mName);
 		}
+
+        // user's account name can change, but filenames and session names are account name based
+        LLConversationLog::getInstance()->verifyFilename(mSessionID, mHistoryFileName, av_name.getCompleteName());
 	}
 	else if (isGroupChat())
 	{
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index ae9a67bd9b64b7aa70ffe388d225880fad208da2..2ed81728ad50aa57659b9ba39731e1f4dd5bcb8e 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -1855,28 +1855,11 @@ void LLItemBridge::restoreToWorld()
 
 void LLItemBridge::gotoItem()
 {
-	LLInventoryObject *obj = getInventoryObject();
-	if (obj && obj->getIsLinkType())
-	{
-		const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
-		if (gInventory.isObjectDescendentOf(obj->getLinkedUUID(), inbox_id))
-		{
-			LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
-			if (sidepanel_inventory && sidepanel_inventory->getInboxPanel())
-			{
-				sidepanel_inventory->getInboxPanel()->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
-			}
-		}
-		else
-		{
-			LLInventoryPanel *active_panel = LLInventoryPanel::getActiveInventoryPanel();
-			if (active_panel)
-			{
-				active_panel->setSelection(obj->getLinkedUUID(), TAKE_FOCUS_NO);
-			}
-		}
-
-	}
+    LLInventoryObject *obj = getInventoryObject();
+    if (obj && obj->getIsLinkType())
+    {
+        show_item_original(obj->getUUID());
+    }
 }
 
 LLUIImagePtr LLItemBridge::getIcon() const
@@ -4145,6 +4128,12 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
                     items.push_back(std::string("New Body Parts"));
                     items.push_back(std::string("New Settings"));
                     items.push_back(std::string("upload_def"));
+
+                    if (!LLEnvironment::instance().isInventoryEnabled())
+                    {
+                        disabled_items.push_back("New Settings");
+                    }
+
                 }
 			}
 			getClipboardEntries(false, items, disabled_items, flags);
@@ -7209,8 +7198,8 @@ void LLSettingsBridge::performAction(LLInventoryModel* model, std::string action
         if (!item) 
             return;
         LLUUID asset_id = item->getAssetUUID();
-        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id);
-        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
+        LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, asset_id, LLEnvironment::TRANSITION_INSTANT);
+        LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
     }
     else if ("apply_settings_parcel" == action)
     {
@@ -7384,21 +7373,17 @@ void LLLinkFolderBridge::performAction(LLInventoryModel* model, std::string acti
 }
 void LLLinkFolderBridge::gotoItem()
 {
-	const LLUUID &cat_uuid = getFolderID();
-	if (!cat_uuid.isNull())
-	{
-		LLFolderViewItem *base_folder = mInventoryPanel.get()->getItemByID(cat_uuid);
-		if (base_folder)
-		{
-			if (LLInventoryModel* model = getInventoryModel())
-			{
-				model->fetchDescendentsOf(cat_uuid);
-			}
-			base_folder->setOpen(TRUE);
-			mRoot->setSelection(base_folder,TRUE);
-			mRoot->scrollToShowSelection();
-		}
-	}
+    LLItemBridge::gotoItem();
+
+    const LLUUID &cat_uuid = getFolderID();
+    if (!cat_uuid.isNull())
+    {
+        LLFolderViewItem *base_folder = LLInventoryPanel::getActiveInventoryPanel()->getItemByID(cat_uuid);
+        if (base_folder)
+        {
+            base_folder->setOpen(TRUE);
+        }
+    }
 }
 const LLUUID &LLLinkFolderBridge::getFolderID() const
 {
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 72013f739612bc173a117eb7dae66ab6b67075f4..411311bbea82b8f6ef94f29c840c4eb64e1f7fec 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -63,7 +63,8 @@ LLInventoryFilter::FilterOps::FilterOps(const Params& p)
 	mPermissions(p.permissions),
 	mFilterTypes(p.types),
 	mFilterUUID(p.uuid),
-	mFilterLinks(p.links)
+	mFilterLinks(p.links),
+	mSearchVisibility(p.search_visibility)
 {
 }
 
@@ -74,6 +75,7 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
 :	mName(p.name),
 	mFilterModified(FILTER_NONE),
 	mEmptyLookupMessage("InventoryNoMatchingItems"),
+	mDefaultEmptyLookupMessage(""),
 	mFilterOps(p.filter_ops),
 	mBackupFilterOps(mFilterOps),
 	mFilterSubString(p.substring),
@@ -154,6 +156,7 @@ bool LLInventoryFilter::check(const LLFolderViewModelItem* item)
 	passed = passed && checkAgainstPermissions(listener);
 	passed = passed && checkAgainstFilterLinks(listener);
 	passed = passed && checkAgainstCreator(listener);
+	passed = passed && checkAgainstSearchVisibility(listener);
 
 	return passed;
 }
@@ -582,6 +585,27 @@ bool LLInventoryFilter::checkAgainstCreator(const LLFolderViewModelItemInventory
 	}
 }
 
+bool LLInventoryFilter::checkAgainstSearchVisibility(const LLFolderViewModelItemInventory* listener) const
+{
+	if (!listener || !hasFilterString()) return TRUE;
+
+	const LLUUID object_id = listener->getUUID();
+	const LLInventoryObject *object = gInventory.getObject(object_id);
+	if (!object) return TRUE;
+
+	const BOOL is_link = object->getIsLinkType();
+	if (is_link && ((mFilterOps.mSearchVisibility & VISIBILITY_LINKS) == 0))
+		return FALSE;
+
+	if (listener->isItemInTrash() && ((mFilterOps.mSearchVisibility & VISIBILITY_TRASH) == 0))
+		return FALSE;
+
+	if (!listener->isAgentInventory() && ((mFilterOps.mSearchVisibility & VISIBILITY_LIBRARY) == 0))
+		return FALSE;
+
+	return TRUE;
+}
+
 const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
 {
 	return mFilterSubString;
@@ -750,6 +774,61 @@ void LLInventoryFilter::setFilterMarketplaceListingFolders(bool select_only_list
     }
 }
 
+
+void LLInventoryFilter::toggleSearchVisibilityLinks()
+{
+	bool hide_links = mFilterOps.mSearchVisibility & VISIBILITY_LINKS;
+	if (hide_links)
+	{
+		mFilterOps.mSearchVisibility &= ~VISIBILITY_LINKS;
+	}
+	else
+	{
+		mFilterOps.mSearchVisibility |= VISIBILITY_LINKS;
+	}
+
+	if (hasFilterString())
+	{
+		setModified(hide_links ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE);
+	}
+}
+
+void LLInventoryFilter::toggleSearchVisibilityTrash()
+{
+	bool hide_trash = mFilterOps.mSearchVisibility & VISIBILITY_TRASH;
+	if (hide_trash)
+	{
+		mFilterOps.mSearchVisibility &= ~VISIBILITY_TRASH;
+	}
+	else
+	{
+		mFilterOps.mSearchVisibility |= VISIBILITY_TRASH;
+	}
+
+	if (hasFilterString())
+	{
+		setModified(hide_trash ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE);
+	}
+}
+
+void LLInventoryFilter::toggleSearchVisibilityLibrary()
+{
+	bool hide_library = mFilterOps.mSearchVisibility & VISIBILITY_LIBRARY;
+	if (hide_library)
+	{
+		mFilterOps.mSearchVisibility &= ~VISIBILITY_LIBRARY;
+	}
+	else
+	{
+		mFilterOps.mSearchVisibility |= VISIBILITY_LIBRARY;
+	}
+
+	if (hasFilterString())
+	{
+		setModified(hide_library ? FILTER_MORE_RESTRICTIVE : FILTER_LESS_RESTRICTIVE);
+	}
+}
+
 void LLInventoryFilter::setFilterNoMarketplaceFolder()
 {
     mFilterOps.mFilterTypes |= FILTERTYPE_NO_MARKETPLACE_ITEMS;
@@ -861,6 +940,44 @@ void LLInventoryFilter::setFilterSubString(const std::string& string)
 	}
 }
 
+void LLInventoryFilter::setSearchVisibilityTypes(U32 types)
+{
+	if (mFilterOps.mSearchVisibility != types)
+	{
+		// keep current items only if no perm bits getting turned off
+		BOOL fewer_bits_set = (mFilterOps.mSearchVisibility & ~types);
+		BOOL more_bits_set = (~mFilterOps.mSearchVisibility & types);
+		mFilterOps.mSearchVisibility = types;
+
+		if (more_bits_set && fewer_bits_set)
+		{
+			setModified(FILTER_RESTART);
+		}
+		else if (more_bits_set)
+		{
+			// target must have all requested permission bits, so more bits == more restrictive
+			setModified(FILTER_MORE_RESTRICTIVE);
+		}
+		else if (fewer_bits_set)
+		{
+			setModified(FILTER_LESS_RESTRICTIVE);
+		}
+	}
+}
+
+void LLInventoryFilter::setSearchVisibilityTypes(const Params& params)
+{
+	if (!params.validateBlock())
+	{
+		return;
+	}
+
+	if (params.filter_ops.search_visibility.isProvided())
+	{
+		setSearchVisibilityTypes(params.filter_ops.search_visibility);
+	}
+}
+
 void LLInventoryFilter::setFilterPermissions(PermissionMask perms)
 {
 	if (mFilterOps.mPermissions != perms)
@@ -1262,6 +1379,18 @@ const std::string& LLInventoryFilter::getFilterText()
 		filtered_by_all_types = FALSE;
 	}
 
+	if (isFilterObjectTypesWith(LLInventoryType::IT_SETTINGS))
+	{
+		filtered_types +=  LLTrans::getString("Settings");
+		filtered_by_type = TRUE;
+		num_filter_types++;
+	}
+	else
+	{
+		not_filtered_types +=  LLTrans::getString("Settings");
+		filtered_by_all_types = FALSE;
+	}
+
 	if (!LLInventoryModelBackgroundFetch::instance().folderFetchActive()
 		&& filtered_by_type
 		&& !filtered_by_all_types)
@@ -1317,6 +1446,7 @@ void LLInventoryFilter::toParams(Params& params) const
 	params.filter_ops.show_folder_state = getShowFolderState();
 	params.filter_ops.creator_type = getFilterCreatorType();
 	params.filter_ops.permissions = getFilterPermissions();
+	params.filter_ops.search_visibility = getSearchVisibilityTypes();
 	params.substring = getFilterSubString();
 	params.since_logoff = isSinceLogoff();
 }
@@ -1340,6 +1470,7 @@ void LLInventoryFilter::fromParams(const Params& params)
 	setShowFolderState(params.filter_ops.show_folder_state);
 	setFilterCreator(params.filter_ops.creator_type);
 	setFilterPermissions(params.filter_ops.permissions);
+	setSearchVisibilityTypes(params.filter_ops.search_visibility);
 	setFilterSubString(params.substring);
 	setDateRangeLastLogoff(params.since_logoff);
 }
@@ -1369,6 +1500,11 @@ U64 LLInventoryFilter::getFilterSettingsTypes() const
     return mFilterOps.mFilterSettingsTypes;
 }
 
+U64 LLInventoryFilter::getSearchVisibilityTypes() const
+{
+	return mFilterOps.mSearchVisibility;
+}
+
 bool LLInventoryFilter::hasFilterString() const
 {
 	return mFilterSubString.size() > 0;
@@ -1441,12 +1577,24 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
 	mEmptyLookupMessage = message;
 }
 
+void LLInventoryFilter::setDefaultEmptyLookupMessage(const std::string& message)
+{
+	mDefaultEmptyLookupMessage = message;
+}
+
 std::string LLInventoryFilter::getEmptyLookupMessage() const
 {
-	LLStringUtil::format_map_t args;
-	args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig());
+	if (isDefault() && !mDefaultEmptyLookupMessage.empty())
+	{
+		return LLTrans::getString(mDefaultEmptyLookupMessage);
+	}
+	else
+	{
+		LLStringUtil::format_map_t args;
+		args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig());
 
-	return LLTrans::getString(mEmptyLookupMessage, args);
+		return LLTrans::getString(mEmptyLookupMessage, args);
+	}
 
 }
 
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index be02ee3623b2e922eec8dbf12a83c2f3d2dd8231..384de3e8898145a6062e2e4920ea0d2c3c25480e 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -99,6 +99,14 @@ class LLInventoryFilter : public LLFolderViewFilter
 		FILTERCREATOR_OTHERS
 	};
 
+	enum ESearchVisibility
+	{
+		VISIBILITY_NONE = 0,
+		VISIBILITY_TRASH = 0x1 << 0,
+		VISIBILITY_LIBRARY = 0x1 << 1,
+		VISIBILITY_LINKS	= 0x1 << 2
+	};
+
 	struct FilterOps
 	{
 		struct DateRange : public LLInitParam::Block<DateRange>
@@ -116,11 +124,13 @@ class LLInventoryFilter : public LLFolderViewFilter
 
 		struct Params : public LLInitParam::Block<Params>
 		{
-			Optional<U32>				types;
+			Optional<U32>				types,
+										search_visibility;
 			Optional<U64>				object_types,
 										wearable_types,
                                         settings_types,
 										category_types;
+										
 			Optional<EFilterLink>		links;
 			Optional<LLUUID>			uuid;
 			Optional<DateRange>			date_range;
@@ -137,6 +147,7 @@ class LLInventoryFilter : public LLFolderViewFilter
                 settings_types("settings_types", 0xffffFFFFffffFFFFULL),
 				category_types("category_types", 0xffffFFFFffffFFFFULL),
 				links("links", FILTERLINK_INCLUDE_LINKS),
+				search_visibility("search_visibility", 0xFFFFFFFF),
 				uuid("uuid"),
 				date_range("date_range"),
 				hours_ago("hours_ago", 0),
@@ -149,7 +160,8 @@ class LLInventoryFilter : public LLFolderViewFilter
 
 		FilterOps(const Params& = Params());
 
-		U32 			mFilterTypes;
+		U32 			mFilterTypes,
+						mSearchVisibility;
 		U64				mFilterObjectTypes,   // For _OBJECT
 						mFilterWearableTypes,
                         mFilterSettingsTypes, // for _SETTINGS
@@ -193,7 +205,8 @@ class LLInventoryFilter : public LLFolderViewFilter
 	U64 				getFilterObjectTypes() const;
 	U64					getFilterCategoryTypes() const;
 	U64					getFilterWearableTypes() const;
-    U64                 getFilterSettingsTypes() const;
+	U64					getFilterSettingsTypes() const;
+	U64					getSearchVisibilityTypes() const;
 
 	bool 				isFilterObjectTypesWith(LLInventoryType::EType t) const;
 	void 				setFilterObjectTypes(U64 types);
@@ -213,6 +226,12 @@ class LLInventoryFilter : public LLFolderViewFilter
 	ESearchType			getSearchType() { return mSearchType; }
 	void 				setFilterCreator(EFilterCreatorType type);
 
+	void				toggleSearchVisibilityLinks();
+	void				toggleSearchVisibilityTrash();
+	void				toggleSearchVisibilityLibrary();
+	void 				setSearchVisibilityTypes(U32 types);
+	void 				setSearchVisibilityTypes(const Params& params);
+
 	void 				setFilterSubString(const std::string& string);
 	const std::string& 	getFilterSubString(BOOL trim = FALSE) const;
 	const std::string& 	getFilterSubStringOrig() const { return mFilterSubStringOrig; } 
@@ -257,6 +276,7 @@ class LLInventoryFilter : public LLFolderViewFilter
 	EFilterCreatorType		getFilterCreatorType() const;
 
 	void 				setEmptyLookupMessage(const std::string& message);
+	void				setDefaultEmptyLookupMessage(const std::string& message);
 	std::string			getEmptyLookupMessage() const;
 
 	// +-------------------------------------------------------------------+
@@ -309,6 +329,7 @@ class LLInventoryFilter : public LLFolderViewFilter
 	bool 				checkAgainstPermissions(const LLInventoryItem* item) const;
 	bool 				checkAgainstFilterLinks(const class LLFolderViewModelItemInventory* listener) const;
 	bool 				checkAgainstCreator(const class LLFolderViewModelItemInventory* listener) const;
+	bool				checkAgainstSearchVisibility(const class LLFolderViewModelItemInventory* listener) const;
 	bool				checkAgainstClipboard(const LLUUID& object_id) const;
 
 	FilterOps				mFilterOps;
@@ -332,6 +353,7 @@ class LLInventoryFilter : public LLFolderViewFilter
     
 	std::string 			mFilterText;
 	std::string 			mEmptyLookupMessage;
+	std::string				mDefaultEmptyLookupMessage;
 
 	ESearchType 			mSearchType;
 
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 71424491f52940d4d5fc9f7c01f19a39bede7bc8..f0487cbe4a55e721b816066b9f9c7fb35e19f855 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -811,40 +811,45 @@ void show_item_profile(const LLUUID& item_uuid)
 
 void show_item_original(const LLUUID& item_uuid)
 {
-	LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
-	if (!floater_inventory)
-	{
-		LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL;
-		return;
-	}
-
-	//sidetray inventory panel
-	LLSidepanelInventory *sidepanel_inventory =	LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
-
-	bool do_reset_inventory_filter = !floater_inventory->isInVisibleChain();
+    LLFloater* floater_inventory = LLFloaterReg::getInstance("inventory");
+    if (!floater_inventory)
+    {
+        LL_WARNS() << "Could not find My Inventory floater" << LL_ENDL;
+        return;
+    }
+    LLSidepanelInventory *sidepanel_inventory =	LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
+    if (sidepanel_inventory)
+    {
+        LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
+        if (main_inventory)
+        {
+            main_inventory->resetFilters();
+        }
+        reset_inventory_filter();
 
-	LLInventoryPanel* active_panel = LLInventoryPanel::getActiveInventoryPanel();
-	if (!active_panel) 
-	{
-		//this may happen when there is no floatera and other panel is active in inventory tab
+        if (!LLFloaterReg::getTypedInstance<LLFloaterSidePanelContainer>("inventory")->isInVisibleChain())
+        {
+            LLFloaterReg::toggleInstanceOrBringToFront("inventory");
+        }
 
-		if	(sidepanel_inventory)
-		{
-			sidepanel_inventory->showInventoryPanel();
-		}
-	}
-	
-	active_panel = LLInventoryPanel::getActiveInventoryPanel();
-	if (!active_panel) 
-	{
-		return;
-	}
-	active_panel->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES);
-	
-	if(do_reset_inventory_filter)
-	{
-		reset_inventory_filter();
-	}
+        const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
+        if (gInventory.isObjectDescendentOf(gInventory.getLinkedItemID(item_uuid), inbox_id))
+        {
+            if (sidepanel_inventory->getInboxPanel())
+            {
+                sidepanel_inventory->openInbox();
+                sidepanel_inventory->getInboxPanel()->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES);
+            }
+        }
+        else
+        {
+            sidepanel_inventory->selectAllItemsPanel();
+            if (sidepanel_inventory->getActivePanel())
+            {
+                sidepanel_inventory->getActivePanel()->setSelection(gInventory.getLinkedItemID(item_uuid), TAKE_FOCUS_YES);
+            }
+        }
+    }
 }
 
 
@@ -1879,6 +1884,26 @@ bool validate_marketplacelistings(LLInventoryCategory* cat, validation_callback_
     return result && !has_bad_items;
 }
 
+void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id)
+{
+	LLInventoryItem* inv_item = gInventory.getItem(item_id);
+	if (inv_item)
+	{
+		LLInventoryModel::update_list_t update;
+		LLInventoryModel::LLCategoryUpdate old_folder(inv_item->getParentUUID(), -1);
+		update.push_back(old_folder);
+		LLInventoryModel::LLCategoryUpdate new_folder(new_parent_id, 1);
+		update.push_back(new_folder);
+		gInventory.accountForUpdate(update);
+
+		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(inv_item);
+		new_item->setParent(new_parent_id);
+		new_item->updateParentOnServer(FALSE);
+		gInventory.updateItem(new_item);
+		gInventory.notifyObservers();
+	}
+}
+
 ///----------------------------------------------------------------------------
 /// LLInventoryCollectFunctor implementations
 ///----------------------------------------------------------------------------
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index ce82108103c5cd38da6f2f5247acb7c8ad960848..1f1e95a756af87fe0cf9bcbc6ad4b9c320dabbc3 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -95,6 +95,8 @@ S32  depth_nesting_in_marketplace(LLUUID cur_uuid);
 LLUUID nested_parent_id(LLUUID cur_uuid, S32 depth);
 S32 compute_stock_count(LLUUID cat_uuid, bool force_count = false);
 
+void change_item_parent(const LLUUID& item_id, const LLUUID& new_parent_id);
+
 /**                    Miscellaneous global functions
  **                                                                            **
  *******************************************************************************/
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 0782793e1b7ee0aa2ade35652e7c6002da9b3e78..b01c9a568b50583c2e20c01f073649e08950b72f 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -162,7 +162,8 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 	mViewsInitialized(VIEWS_UNINITIALIZED),
 	mInvFVBridgeBuilder(NULL),
 	mInventoryViewModel(p.name),
-	mGroupedItemBridge(new LLFolderViewGroupedItemBridge)
+	mGroupedItemBridge(new LLFolderViewGroupedItemBridge),
+	mFocusSelection(false)
 {
 	mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
 
@@ -1244,6 +1245,7 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::
 void LLInventoryPanel::clearSelection()
 {
 	mSelectThisID.setNull();
+	mFocusSelection = false;
 }
 
 LLInventoryPanel::selected_items_t LLInventoryPanel::getSelectedItems() const
@@ -1757,15 +1759,17 @@ LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id)
 void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL    take_keyboard_focus )
 {
 	LLFolderViewItem* itemp = getItemByID(obj_id);
-	if(itemp && itemp->getViewModelItem())
+	if(itemp && itemp->getViewModelItem() && itemp->passedFilter())
 	{
 		itemp->arrangeAndSet(TRUE, take_keyboard_focus);
 		mSelectThisID.setNull();
+		mFocusSelection = false;
 		return;
 	}
 	else
 	{
 		// save the desired item to be selected later (if/when ready)
+		mFocusSelection = take_keyboard_focus;
 		mSelectThisID = obj_id;
 	}
 }
@@ -1774,7 +1778,7 @@ void LLInventoryPanel::updateSelection()
 {
 	if (mSelectThisID.notNull())
 	{
-		setSelectionByID(mSelectThisID, false);
+		setSelectionByID(mSelectThisID, mFocusSelection);
 	}
 }
 
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index ad6010f09c8705a006853c1b3b82cb705224d734..a019fc2231d994f20e57ce598abc120bd77157d6 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -269,6 +269,7 @@ class LLInventoryPanel : public LLPanel
 	LLInventoryModel*			mInventory;
 	LLInventoryObserver*		mInventoryObserver;
 	LLInvPanelComplObserver*	mCompletionObserver;
+	bool						mFocusSelection;
 	bool						mAcceptsDragAndDrop;
 	bool 						mAllowMultiSelect;
 	bool 						mAllowDrag;
@@ -366,27 +367,6 @@ class LLInventoryPanel : public LLPanel
     EViewsInitializationState	mViewsInitialized; // Whether views have been generated
 };
 
-
-class LLInventoryFavoriteItemsPanel : public LLInventoryPanel
-{
-public:
-    struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
-    {};
-
-    void initFromParams(const Params& p);
-    bool isSelectionRemovable() { return false; }
-    void setSelectCallback(const boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
-
-protected:
-    LLInventoryFavoriteItemsPanel(const Params& params);
-    ~LLInventoryFavoriteItemsPanel() { mFolderChangedSignal.disconnect(); }
-    void updateFavoritesRootFolder();
-
-    boost::signals2::connection mFolderChangedSignal;
-    boost::function<void(const std::deque<LLFolderViewItem*>& items, BOOL user_action)> mSelectionCallback;
-    friend class LLUICtrlFactory;
-};
-
 /************************************************************************/
 /* Asset Pre-Filtered Inventory Panel related class                     */
 /* Exchanges filter's flexibility for speed of generation and           */
diff --git a/indra/newview/llkeyconflict.cpp b/indra/newview/llkeyconflict.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b6107eeedf13ceff9fcdd15aebe4d63883d8bd93
--- /dev/null
+++ b/indra/newview/llkeyconflict.cpp
@@ -0,0 +1,1015 @@
+/** 
+ * @file llkeyconflict.cpp
+ * @brief 
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2019, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+/*
+ * App-wide preferences.  Note that these are not per-user,
+ * because we need to load many preferences before we have
+ * a login name.
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llkeyconflict.h"
+
+#include "llinitparam.h"
+#include "llkeyboard.h"
+#include "lltrans.h"
+#include "llviewercontrol.h"
+#include "llviewerinput.h"
+#include "llviewermenu.h"
+#include "llxuiparser.h"
+
+static const std::string saved_settings_key_controls[] = { "placeholder" }; // add settings from gSavedSettings here
+
+static const std::string filename_default = "key_bindings.xml";
+static const std::string filename_temporary = "key_bindings_tmp.xml"; // used to apply uncommited changes on the go.
+
+// LLKeyboard::stringFromMask is meant for UI and is OS dependent,
+// so this class uses it's own version
+std::string string_from_mask(MASK mask)
+{
+    std::string res;
+    if ((mask & MASK_CONTROL) != 0)
+    {
+        res = "CTL";
+    }
+    if ((mask & MASK_ALT) != 0)
+    {
+        if (!res.empty()) res += "_";
+        res += "ALT";
+    }
+    if ((mask & MASK_SHIFT) != 0)
+    {
+        if (!res.empty()) res += "_";
+        res += "SHIFT";
+    }
+
+    if (mask == MASK_NONE)
+    {
+        res = "NONE";
+    }
+    return res;
+}
+
+std::string string_from_mouse(EMouseClickType click, bool translate)
+{
+    std::string res;
+    switch (click)
+    {
+    case CLICK_LEFT:
+        res = "LMB";
+        break;
+    case CLICK_MIDDLE:
+        res = "MMB";
+        break;
+    case CLICK_RIGHT:
+        res = "RMB";
+        break;
+    case CLICK_BUTTON4:
+        res = "MB4";
+        break;
+    case CLICK_BUTTON5:
+        res = "MB5";
+        break;
+    case CLICK_DOUBLELEFT:
+        res = "Double LMB";
+        break;
+    default:
+        break;
+    }
+
+    if (translate && !res.empty())
+    {
+        res = LLTrans::getString(res);
+    }
+    return res;
+}
+
+// LLKeyConflictHandler
+
+S32 LLKeyConflictHandler::sTemporaryFileUseCount = 0;
+
+LLKeyConflictHandler::LLKeyConflictHandler()
+:   mHasUnsavedChanges(false),
+    mUsesTemporaryFile(false),
+    mLoadMode(MODE_COUNT)
+{
+}
+
+LLKeyConflictHandler::LLKeyConflictHandler(ESourceMode mode)
+:   mHasUnsavedChanges(false),
+    mUsesTemporaryFile(false),
+    mLoadMode(mode)
+{
+    loadFromSettings(mode);
+}
+
+LLKeyConflictHandler::~LLKeyConflictHandler()
+{
+    clearUnsavedChanges();
+    // Note: does not reset bindings if temporary file was used
+}
+
+bool LLKeyConflictHandler::canHandleControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask)
+{
+    return mControlsMap[control_name].canHandle(mouse_ind, key, mask);
+}
+
+bool LLKeyConflictHandler::canHandleKey(const std::string &control_name, KEY key, MASK mask)
+{
+    return canHandleControl(control_name, CLICK_NONE, key, mask);
+}
+
+bool LLKeyConflictHandler::canHandleMouse(const std::string &control_name, EMouseClickType mouse_ind, MASK mask)
+{
+    return canHandleControl(control_name, mouse_ind, KEY_NONE, mask);
+}
+
+bool LLKeyConflictHandler::canHandleMouse(const std::string &control_name, S32 mouse_ind, MASK mask)
+{
+    return canHandleControl(control_name, (EMouseClickType)mouse_ind, KEY_NONE, mask);
+}
+
+bool LLKeyConflictHandler::canAssignControl(const std::string &control_name)
+{
+    control_map_t::iterator iter = mControlsMap.find(control_name);
+    if (iter != mControlsMap.end())
+    {
+        return iter->second.mAssignable;
+    }
+    // If we don't know this control, means it wasn't assigned by user yet and thus is editable
+    return true;
+}
+
+// static
+bool LLKeyConflictHandler::isReservedByMenu(const KEY &key, const MASK &mask)
+{
+    if (key == KEY_NONE)
+    {
+        return false;
+    }
+    return (gMenuBarView && gMenuBarView->hasAccelerator(key, mask))
+           || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(key, mask));
+}
+
+// static
+bool LLKeyConflictHandler::isReservedByMenu(const LLKeyData &data)
+{
+    if (data.mMouse != CLICK_NONE || data.mKey == KEY_NONE)
+    {
+        return false;
+    }
+    return (gMenuBarView && gMenuBarView->hasAccelerator(data.mKey, data.mMask))
+           || (gLoginMenuBarView && gLoginMenuBarView->hasAccelerator(data.mKey, data.mMask));
+}
+
+bool LLKeyConflictHandler::registerControl(const std::string &control_name, U32 index, EMouseClickType mouse, KEY key, MASK mask, bool ignore_mask)
+{
+    if (control_name.empty())
+    {
+        return false;
+    }
+    LLKeyConflict &type_data = mControlsMap[control_name];
+    if (!type_data.mAssignable)
+    {
+        // Example: user tried to assign camera spin to all modes, but first person mode doesn't support it
+        return false;
+    }
+    LLKeyData data(mouse, key, mask, ignore_mask);
+    if (type_data.mKeyBind.getKeyData(index) == data)
+    {
+        return true;
+    }
+    if (isReservedByMenu(data))
+    {
+        return false;
+    }
+    if (removeConflicts(data, type_data.mConflictMask))
+    {
+        type_data.mKeyBind.replaceKeyData(data, index);
+        mHasUnsavedChanges = true;
+        return true;
+    }
+    // control already in use/blocked
+    return false;
+}
+
+bool LLKeyConflictHandler::clearControl(const std::string &control_name, U32 data_index)
+{
+    if (control_name.empty())
+    {
+        return false;
+    }
+    LLKeyConflict &type_data = mControlsMap[control_name];
+    if (!type_data.mAssignable)
+    {
+        // Example: user tried to assign camera spin to all modes, but first person mode doesn't support it
+        return false;
+    }
+    type_data.mKeyBind.resetKeyData(data_index);
+    mHasUnsavedChanges = true;
+    return true;
+}
+
+LLKeyData LLKeyConflictHandler::getControl(const std::string &control_name, U32 index)
+{
+    if (control_name.empty())
+    {
+        return LLKeyData();
+    }
+    return mControlsMap[control_name].getKeyData(index);
+}
+
+bool LLKeyConflictHandler::isControlEmpty(const std::string &control_name)
+{
+    if (control_name.empty())
+    {
+        return true;
+    }
+    return mControlsMap[control_name].mKeyBind.isEmpty();
+}
+
+// static
+std::string LLKeyConflictHandler::getStringFromKeyData(const LLKeyData& keydata)
+{
+    std::string result;
+
+    if (keydata.mMask != MASK_NONE && keydata.mKey != KEY_NONE)
+    {
+        result = LLKeyboard::stringFromAccelerator(keydata.mMask, keydata.mKey);
+    }
+    else if (keydata.mKey != KEY_NONE)
+    {
+        result = LLKeyboard::stringFromKey(keydata.mKey);
+    }
+    else if (keydata.mMask != MASK_NONE)
+    {
+        result = LLKeyboard::stringFromAccelerator(keydata.mMask);
+    }
+
+    result += string_from_mouse(keydata.mMouse, true);
+
+    return result;
+}
+
+std::string LLKeyConflictHandler::getControlString(const std::string &control_name, U32 index)
+{
+    if (control_name.empty())
+    {
+        return "";
+    }
+    return getStringFromKeyData(mControlsMap[control_name].getKeyData(index));
+}
+
+void LLKeyConflictHandler::loadFromControlSettings(const std::string &name)
+{
+    LLControlVariablePtr var = gSavedSettings.getControl(name);
+    if (var)
+    {
+        LLKeyBind bind(var->getValue());
+        LLKeyConflict key(bind, true, 0);
+        mControlsMap[name] = key;
+    }
+}
+
+void LLKeyConflictHandler::loadFromSettings(const LLViewerInput::KeyMode& keymode, control_map_t *destination)
+{
+    for (LLInitParam::ParamIterator<LLViewerInput::KeyBinding>::const_iterator it = keymode.bindings.begin(),
+        end_it = keymode.bindings.end();
+        it != end_it;
+    ++it)
+    {
+        KEY key;
+        MASK mask;
+        EMouseClickType mouse = CLICK_NONE;
+        if (it->mouse.isProvided())
+        {
+            LLViewerInput::mouseFromString(it->mouse.getValue(), &mouse);
+        }
+        if (it->key.getValue().empty())
+        {
+            key = KEY_NONE;
+        }
+        else
+        {
+            LLKeyboard::keyFromString(it->key, &key);
+        }
+        LLKeyboard::maskFromString(it->mask, &mask);
+        // Note: it->command is also the name of UI element, howhever xml we are loading from
+        // might not know all the commands, so UI will have to know what to fill by its own
+        // Assumes U32_MAX conflict mask, and is assignable by default,
+        // but assignability might have been overriden by generatePlaceholders.
+        LLKeyConflict &type_data = (*destination)[it->command];
+        type_data.mKeyBind.addKeyData(mouse, key, mask, true);
+    }
+}
+
+bool LLKeyConflictHandler::loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination)
+{
+    if (filename.empty())
+    {
+        return false;
+    }
+
+    bool res = false;
+
+    LLViewerInput::Keys keys;
+    LLSimpleXUIParser parser;
+
+    if (parser.readXUI(filename, keys)
+        && keys.validateBlock())
+    {
+        switch (load_mode)
+        {
+        case MODE_FIRST_PERSON:
+            if (keys.first_person.isProvided())
+            {
+                loadFromSettings(keys.first_person, destination);
+                res = true;
+            }
+            break;
+        case MODE_THIRD_PERSON:
+            if (keys.third_person.isProvided())
+            {
+                loadFromSettings(keys.third_person, destination);
+                res = true;
+            }
+            break;
+        case MODE_EDIT_AVATAR:
+            if (keys.edit_avatar.isProvided())
+            {
+                loadFromSettings(keys.edit_avatar, destination);
+                res = true;
+            }
+            break;
+        case MODE_SITTING:
+            if (keys.sitting.isProvided())
+            {
+                loadFromSettings(keys.sitting, destination);
+                res = true;
+            }
+            break;
+        default:
+            LL_ERRS() << "Not implememted mode " << load_mode << LL_ENDL;
+            break;
+        }
+    }
+    return res;
+}
+
+void LLKeyConflictHandler::loadFromSettings(ESourceMode load_mode)
+{
+    mControlsMap.clear();
+    mDefaultsMap.clear();
+
+    // E.X. In case we need placeholder keys for conflict resolution.
+    generatePlaceholders(load_mode);
+
+    if (load_mode == MODE_SAVED_SETTINGS)
+    {
+        // load settings clss knows about, but it also possible to load settings by name separately
+        const S32 size = std::extent<decltype(saved_settings_key_controls)>::value;
+        for (U32 i = 0; i < size; i++)
+        {
+            loadFromControlSettings(saved_settings_key_controls[i]);
+        }
+    }
+    else
+    {
+        // load defaults
+        std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename_default);
+        if (!loadFromSettings(load_mode, filename, &mDefaultsMap))
+        {
+            LL_WARNS() << "Failed to load default settings, aborting" << LL_ENDL;
+            return;
+        }
+
+        // load user's
+        filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
+        if (!gDirUtilp->fileExists(filename) || !loadFromSettings(load_mode, filename, &mControlsMap))
+        {
+            // mind placeholders
+            mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end());
+        }
+    }
+    mLoadMode = load_mode;
+}
+
+void LLKeyConflictHandler::saveToSettings(bool temporary)
+{
+    if (mControlsMap.empty())
+    {
+        return;
+    }
+
+    if (mLoadMode == MODE_SAVED_SETTINGS)
+    {
+        // Does not support 'temporary', preferences handle that themself
+        // so in case of saved settings we just do not clear mHasUnsavedChanges
+        control_map_t::iterator iter = mControlsMap.begin();
+        control_map_t::iterator end = mControlsMap.end();
+
+        for (; iter != end; ++iter)
+        {
+            if (iter->first.empty())
+            {
+                continue;
+            }
+
+            LLKeyConflict &key = iter->second;
+            key.mKeyBind.trimEmpty();
+            if (!key.mAssignable)
+            {
+                continue;
+            }
+
+            if (gSavedSettings.controlExists(iter->first))
+            {
+                gSavedSettings.setLLSD(iter->first, key.mKeyBind.asLLSD());
+            }
+            else if (!key.mKeyBind.empty())
+            {
+                // Note: this is currently not in use, might be better for load mechanics to ask for and retain control group
+                // otherwise settings loaded from other control groups will end in gSavedSettings
+                LL_INFOS() << "Creating new keybinding " << iter->first << LL_ENDL;
+                gSavedSettings.declareLLSD(iter->first, key.mKeyBind.asLLSD(), "comment", LLControlVariable::PERSIST_ALWAYS);
+            }
+        }
+    }
+    else
+    {
+        // Determine what file to load and load full copy of that file
+        std::string filename;
+
+        if (temporary)
+        {
+            filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary);
+            if (!gDirUtilp->fileExists(filename))
+            {
+                filename.clear();
+            }
+        }
+
+        if (filename.empty())
+        {
+            filename = gDirUtilp->findFile(filename_default,
+                gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
+                gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+        }
+
+        LLViewerInput::Keys keys;
+        LLSimpleXUIParser parser;
+
+        if (parser.readXUI(filename, keys)
+            && keys.validateBlock())
+        {
+            // replace category we edited
+
+            // mode is a HACK to correctly reset bindings without reparsing whole file and avoid doing
+            // own param container (which will face issues with inasseesible members of LLInitParam)
+            LLViewerInput::KeyMode mode;
+            LLViewerInput::KeyBinding binding;
+
+            control_map_t::iterator iter = mControlsMap.begin();
+            control_map_t::iterator end = mControlsMap.end();
+            for (; iter != end; ++iter)
+            {
+                // By default xml have (had) up to 6 elements per function
+                // eventually it will be cleaned up and UI will only shows 3 per function,
+                // so make sure to cleanup.
+                // Also this helps in keeping file small.
+                iter->second.mKeyBind.trimEmpty();
+                U32 size = iter->second.mKeyBind.getDataCount();
+                for (U32 i = 0; i < size; ++i)
+                {
+                    if (iter->first.empty())
+                    {
+                        continue;
+                    }
+
+                    LLKeyConflict &key = iter->second;
+                    key.mKeyBind.trimEmpty();
+                    if (key.mKeyBind.empty() || !key.mAssignable)
+                    {
+                        continue;
+                    }
+
+                    LLKeyData data = key.mKeyBind.getKeyData(i);
+                    // Still write empty LLKeyData to make sure we will maintain UI position
+                    if (data.mKey == KEY_NONE)
+                    {
+                        // Might be better idea to be consistent and use NONE. LLViewerInput can work with both cases
+                        binding.key = "";
+                    }
+                    else
+                    {
+                        binding.key = LLKeyboard::stringFromKey(data.mKey, false /*Do not localize*/);
+                    }
+                    binding.mask = string_from_mask(data.mMask);
+                    if (data.mMouse == CLICK_NONE)
+                    {
+                        binding.mouse.setProvided(false);
+                    }
+                    else
+                    {
+                        // set() because 'optional', for compatibility purposes
+                        // just copy old keys.xml and rename to key_bindings.xml, it should work
+                        binding.mouse.set(string_from_mouse(data.mMouse, false), true);
+                    }
+                    binding.command = iter->first;
+                    mode.bindings.add(binding);
+                }
+            }
+
+            switch (mLoadMode)
+            {
+            case MODE_FIRST_PERSON:
+                if (keys.first_person.isProvided())
+                {
+                    keys.first_person.bindings.set(mode.bindings, true);
+                }
+                break;
+            case MODE_THIRD_PERSON:
+                if (keys.third_person.isProvided())
+                {
+                    keys.third_person.bindings.set(mode.bindings, true);
+                }
+                break;
+            case MODE_EDIT_AVATAR:
+                if (keys.edit_avatar.isProvided())
+                {
+                    keys.edit_avatar.bindings.set(mode.bindings, true);
+                }
+                break;
+            case MODE_SITTING:
+                if (keys.sitting.isProvided())
+                {
+                    keys.sitting.bindings.set(mode.bindings, true);
+                }
+                break;
+            default:
+                LL_ERRS() << "Not implememted mode " << mLoadMode << LL_ENDL;
+                break;
+            }
+
+            if (temporary)
+            {
+                // write to temporary xml and use it for gViewerInput
+                filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary);
+                if (!mUsesTemporaryFile)
+                {
+                    mUsesTemporaryFile = true;
+                    sTemporaryFileUseCount++;
+                }
+            }
+            else
+            {
+                // write back to user's xml and use it for gViewerInput
+                filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
+                // Don't reset mUsesTemporaryFile, it will be reset at cleanup stage
+            }
+
+            LLXMLNodePtr output_node = new LLXMLNode("keys", false);
+            LLXUIParser parser;
+            parser.writeXUI(output_node, keys);
+
+            // Write the resulting XML to file
+            if (!output_node->isNull())
+            {
+                LLFILE *fp = LLFile::fopen(filename, "w");
+                if (fp != NULL)
+                {
+                    LLXMLNode::writeHeaderToFile(fp);
+                    output_node->writeToFile(fp);
+                    fclose(fp);
+                }
+            }
+            // Now force a rebind for keyboard
+            if (gDirUtilp->fileExists(filename))
+            {
+                // Ideally instead of rebinding immediately we should shedule
+                // the rebind since single file can have multiple handlers,
+                // one per mode, saving simultaneously.
+                // Or whatever uses LLKeyConflictHandler should control the process.
+                gViewerInput.loadBindingsXML(filename);
+            }
+        }
+    }
+
+#if 1
+    // Legacy support
+    // Remove #if-#endif section half a year after DRTVWR-501 releases.
+    // Update legacy settings in settings.xml
+    // We only care for third person view since legacy settings can't store
+    // more than one mode.
+    // We are saving this even if we are in temporary mode - preferences
+    // will restore values on cancel
+    if (mLoadMode == MODE_THIRD_PERSON && mHasUnsavedChanges)
+    {
+        bool value = canHandleMouse("walk_to", CLICK_DOUBLELEFT, MASK_NONE);
+        gSavedSettings.setBOOL("DoubleClickAutoPilot", value);
+
+        value = canHandleMouse("walk_to", CLICK_LEFT, MASK_NONE);
+        gSavedSettings.setBOOL("ClickToWalk", value);
+
+        // new method can save both toggle and push-to-talk values simultaneously,
+        // but legacy one can save only one. It also doesn't support mask.
+        LLKeyData data = getControl("toggle_voice", 0);
+        bool can_toggle = !data.isEmpty();
+        if (!can_toggle)
+        {
+            data = getControl("voice_follow_key", 0);
+        }
+
+        gSavedSettings.setBOOL("PushToTalkToggle", can_toggle);
+        if (data.isEmpty())
+        {
+            // legacy viewer has a bug that might crash it if NONE value is assigned.
+            // just reset to default
+            gSavedSettings.getControl("PushToTalkButton")->resetToDefault(false);
+        }
+        else
+        {
+            if (data.mKey != KEY_NONE)
+            {
+                gSavedSettings.setString("PushToTalkButton", LLKeyboard::stringFromKey(data.mKey));
+            }
+            else
+            {
+                std::string ctrl_value;
+                switch (data.mMouse)
+                {
+                case CLICK_MIDDLE:
+                    ctrl_value = "MiddleMouse";
+                    break;
+                case CLICK_BUTTON4:
+                    ctrl_value = "MouseButton4";
+                    break;
+                case CLICK_BUTTON5:
+                    ctrl_value = "MouseButton5";
+                    break;
+                default:
+                    ctrl_value = "MiddleMouse";
+                    break;
+                }
+                gSavedSettings.setString("PushToTalkButton", ctrl_value);
+            }
+        }
+    }
+#endif
+
+    if (mLoadMode == MODE_THIRD_PERSON && mHasUnsavedChanges)
+    {
+        // Map floater should react to doubleclick if doubleclick for teleport is set
+        // Todo: Seems conterintuitive for map floater to share inworld controls
+        // after these changes release, discuss with UI UX engineer if this should just
+        // be set to 1 by default (before release this also doubles as legacy support)
+        bool value = canHandleMouse("teleport_to", CLICK_DOUBLELEFT, MASK_NONE);
+        gSavedSettings.setBOOL("DoubleClickTeleport", value);
+    }
+
+    if (!temporary)
+    {
+        // will remove any temporary file if there were any
+        clearUnsavedChanges();
+    }
+}
+
+LLKeyData LLKeyConflictHandler::getDefaultControl(const std::string &control_name, U32 index)
+{
+    if (control_name.empty())
+    {
+        return LLKeyData();
+    }
+    if (mLoadMode == MODE_SAVED_SETTINGS)
+    {
+        LLControlVariablePtr var = gSavedSettings.getControl(control_name);
+        if (var)
+        {
+            return LLKeyBind(var->getDefault()).getKeyData(index);
+        }
+        return LLKeyData();
+    }
+    else
+    {
+        control_map_t::iterator iter = mDefaultsMap.find(control_name);
+        if (iter != mDefaultsMap.end())
+        {
+            return iter->second.mKeyBind.getKeyData(index);
+        }
+        return LLKeyData();
+    }
+}
+
+void LLKeyConflictHandler::resetToDefault(const std::string &control_name, U32 index)
+{
+    if (control_name.empty())
+    {
+        return;
+    }
+    LLKeyData data = getDefaultControl(control_name, index);
+
+    if (data != mControlsMap[control_name].getKeyData(index))
+    {
+        // reset controls that might have been switched to our current control
+        removeConflicts(data, mControlsMap[control_name].mConflictMask);
+        mControlsMap[control_name].setKeyData(data, index);
+    }
+}
+
+void LLKeyConflictHandler::resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts)
+{
+    if (control_name.empty())
+    {
+        return;
+    }
+    if (mLoadMode == MODE_SAVED_SETTINGS)
+    {
+        LLControlVariablePtr var = gSavedSettings.getControl(control_name);
+        if (var)
+        {
+            LLKeyBind bind(var->getDefault());
+            if (!ignore_conflicts)
+            {
+                for (S32 i = 0; i < bind.getDataCount(); ++i)
+                {
+                    removeConflicts(bind.getKeyData(i), mControlsMap[control_name].mConflictMask);
+                }
+            }
+            mControlsMap[control_name].mKeyBind = bind;
+        }
+        else
+        {
+            mControlsMap[control_name].mKeyBind.clear();
+        }
+    }
+    else
+    {
+        control_map_t::iterator iter = mDefaultsMap.find(control_name);
+        if (iter != mDefaultsMap.end())
+        {
+            if (!ignore_conflicts)
+            {
+                for (S32 i = 0; i < iter->second.mKeyBind.getDataCount(); ++i)
+                {
+                    removeConflicts(iter->second.mKeyBind.getKeyData(i), mControlsMap[control_name].mConflictMask);
+                }
+            }
+            mControlsMap[control_name].mKeyBind = iter->second.mKeyBind;
+        }
+        else
+        {
+            mControlsMap[control_name].mKeyBind.clear();
+        }
+    }
+}
+
+void LLKeyConflictHandler::resetToDefault(const std::string &control_name)
+{
+    // reset specific binding without ignoring conflicts
+    resetToDefaultAndResolve(control_name, false);
+}
+
+void LLKeyConflictHandler::resetToDefaults(ESourceMode mode)
+{
+    if (mode == MODE_SAVED_SETTINGS)
+    {
+        control_map_t::iterator iter = mControlsMap.begin();
+        control_map_t::iterator end = mControlsMap.end();
+
+        for (; iter != end; ++iter)
+        {
+            resetToDefaultAndResolve(iter->first, true);
+        }
+    }
+    else
+    {
+        mControlsMap.clear();
+        generatePlaceholders(mode);
+        mControlsMap.insert(mDefaultsMap.begin(), mDefaultsMap.end());
+    }
+
+    mHasUnsavedChanges = true;
+}
+
+void LLKeyConflictHandler::resetToDefaults()
+{
+    if (!empty())
+    {
+        resetToDefaults(mLoadMode);
+    }
+    else
+    {
+        // not optimal since:
+        // 1. We are not sure that mLoadMode was set
+        // 2. We are not sure if there are any changes in comparison to default
+        // 3. We are loading 'current' only to replace it
+        // but it is reliable and works Todo: consider optimizing.
+        loadFromSettings(mLoadMode);
+        resetToDefaults(mLoadMode);
+    }
+}
+
+void LLKeyConflictHandler::clear()
+{
+    if (clearUnsavedChanges())
+    {
+        // temporary file was removed, this means we were using it and need to reload keyboard's bindings
+        resetKeyboardBindings();
+    }
+    mControlsMap.clear();
+    mDefaultsMap.clear();
+}
+
+// static
+void LLKeyConflictHandler::resetKeyboardBindings()
+{
+    // Try to load User's bindings first
+    std::string key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_default);
+    if (!gDirUtilp->fileExists(key_bindings_file) || !gViewerInput.loadBindingsXML(key_bindings_file))
+    {
+        // Failed to load custom bindings, try default ones
+        key_bindings_file = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, filename_default);
+        if (!gViewerInput.loadBindingsXML(key_bindings_file))
+        {
+            LL_ERRS("InitInfo") << "Unable to open default key bindings from " << key_bindings_file << LL_ENDL;
+        }
+    }
+}
+
+void LLKeyConflictHandler::generatePlaceholders(ESourceMode load_mode)
+{
+    // These controls are meant to cause conflicts when user tries to assign same control somewhere else
+    // also this can be used to pre-record controls that should not conflict or to assign conflict groups/masks
+
+    if (load_mode == MODE_FIRST_PERSON)
+    {
+        // First person view doesn't support camera controls
+        // Note: might be better idea to just load these from control_table_contents_camera.xml
+        // or to pass from floaterpreferences when it loads said file
+        registerTemporaryControl("look_up");
+        registerTemporaryControl("look_down");
+        registerTemporaryControl("move_forward");
+        registerTemporaryControl("move_backward");
+        registerTemporaryControl("move_forward_fast");
+        registerTemporaryControl("move_backward_fast");
+        registerTemporaryControl("spin_over");
+        registerTemporaryControl("spin_under");
+        registerTemporaryControl("pan_up");
+        registerTemporaryControl("pan_down");
+        registerTemporaryControl("pan_left");
+        registerTemporaryControl("pan_right");
+        registerTemporaryControl("pan_in");
+        registerTemporaryControl("pan_out");
+        registerTemporaryControl("spin_around_ccw");
+        registerTemporaryControl("spin_around_cw");
+
+        // control_table_contents_editing.xml
+        registerTemporaryControl("edit_avatar_spin_ccw");
+        registerTemporaryControl("edit_avatar_spin_cw");
+        registerTemporaryControl("edit_avatar_spin_over");
+        registerTemporaryControl("edit_avatar_spin_under");
+        registerTemporaryControl("edit_avatar_move_forward");
+        registerTemporaryControl("edit_avatar_move_backward");
+
+        // no autopilot or teleport
+        registerTemporaryControl("walk_to");
+        registerTemporaryControl("teleport_to");
+    }
+
+    if (load_mode == MODE_EDIT_AVATAR)
+    {
+        // no autopilot or teleport
+        registerTemporaryControl("walk_to");
+        registerTemporaryControl("teleport_to");
+    }
+
+    if (load_mode == MODE_SITTING)
+    {
+        // no autopilot
+        registerTemporaryControl("walk_to");
+    }
+    else 
+    {
+        // sitting related functions should only be avaliable in sitting mode
+        registerTemporaryControl("move_forward_sitting");
+        registerTemporaryControl("move_backward_sitting");
+        registerTemporaryControl("spin_over_sitting");
+        registerTemporaryControl("spin_under_sitting");
+        registerTemporaryControl("spin_around_ccw_sitting");
+        registerTemporaryControl("spin_around_cw_sitting");
+    }
+}
+
+bool LLKeyConflictHandler::removeConflicts(const LLKeyData &data, const U32 &conlict_mask)
+{
+    if (conlict_mask == CONFLICT_NOTHING)
+    {
+        // Can't conflict
+        return true;
+    }
+    std::map<std::string, S32> conflict_list;
+    control_map_t::iterator cntrl_iter = mControlsMap.begin();
+    control_map_t::iterator cntrl_end = mControlsMap.end();
+    for (; cntrl_iter != cntrl_end; ++cntrl_iter)
+    {
+        S32 index = cntrl_iter->second.mKeyBind.findKeyData(data);
+        if (index >= 0
+            && cntrl_iter->second.mConflictMask != CONFLICT_NOTHING
+            && (cntrl_iter->second.mConflictMask & conlict_mask) != 0)
+        {
+            if (cntrl_iter->second.mAssignable)
+            {
+                // Potentially we can have multiple conflict flags conflicting
+                // including unassignable keys.
+                // So record the conflict and find all others before doing any changes.
+                // Assume that there is only one conflict per bind
+                conflict_list[cntrl_iter->first] = index;
+            }
+            else
+            {
+                return false;
+            }
+        }
+    }
+
+    std::map<std::string, S32>::iterator cnflct_iter = conflict_list.begin();
+    std::map<std::string, S32>::iterator cnflct_end = conflict_list.end();
+    for (; cnflct_iter != cnflct_end; ++cnflct_iter)
+    {
+        mControlsMap[cnflct_iter->first].mKeyBind.resetKeyData(cnflct_iter->second);
+    }
+    return true;
+}
+
+void LLKeyConflictHandler::registerTemporaryControl(const std::string &control_name, EMouseClickType mouse, KEY key, MASK mask, U32 conflict_mask)
+{
+    LLKeyConflict *type_data = &mControlsMap[control_name];
+    type_data->mAssignable = false;
+    type_data->mConflictMask = conflict_mask;
+    type_data->mKeyBind.addKeyData(mouse, key, mask, false);
+}
+
+void LLKeyConflictHandler::registerTemporaryControl(const std::string &control_name, U32 conflict_mask)
+{
+    LLKeyConflict *type_data = &mControlsMap[control_name];
+    type_data->mAssignable = false;
+    type_data->mConflictMask = conflict_mask;
+}
+
+bool LLKeyConflictHandler::clearUnsavedChanges()
+{
+    bool result = false;
+    mHasUnsavedChanges = false;
+
+    if (mUsesTemporaryFile)
+    {
+        mUsesTemporaryFile = false;
+        sTemporaryFileUseCount--;
+        if (!sTemporaryFileUseCount)
+        {
+            result = clearTemporaryFile();
+        }
+        // else: might be usefull to overwrite content of temp file with defaults
+        // but at the moment there is no such need
+    }
+    return result;
+}
+
+//static
+bool LLKeyConflictHandler::clearTemporaryFile()
+{
+    // At the moment single file needs five handlers (one per mode), so doing this
+    // will remove file for all hadlers
+    std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, filename_temporary);
+    if (gDirUtilp->fileExists(filename))
+    {
+        LLFile::remove(filename);
+        return true;
+    }
+    return false;
+}
+
diff --git a/indra/newview/llkeyconflict.h b/indra/newview/llkeyconflict.h
new file mode 100644
index 0000000000000000000000000000000000000000..2926ca3aeb10f33f9ed3b7aaed53e78bf596579b
--- /dev/null
+++ b/indra/newview/llkeyconflict.h
@@ -0,0 +1,175 @@
+/** 
+ * @file llkeyconflict.h
+ * @brief 
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2019, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLKEYCONFLICT_H
+#define LL_LLKEYCONFLICT_H
+
+#include "llkeybind.h"
+#include "llviewerinput.h"
+
+
+class LLKeyConflict
+{
+public:
+    LLKeyConflict() : mAssignable(true), mConflictMask(U32_MAX) {} //temporary assignable, don't forget to change once all keys are recorded
+    LLKeyConflict(bool assignable, U32 conflict_mask)
+        : mAssignable(assignable), mConflictMask(conflict_mask) {}
+    LLKeyConflict(const LLKeyBind &bind, bool assignable, U32 conflict_mask)
+        : mAssignable(assignable), mConflictMask(conflict_mask), mKeyBind(bind) {}
+
+    LLKeyData getPrimaryKeyData() { return mKeyBind.getKeyData(0); }
+    LLKeyData getKeyData(U32 index) { return mKeyBind.getKeyData(index); }
+    void setPrimaryKeyData(const LLKeyData& data) { mKeyBind.replaceKeyData(data, 0); }
+    void setKeyData(const LLKeyData& data, U32 index) { mKeyBind.replaceKeyData(data, index); }
+    bool canHandle(EMouseClickType mouse, KEY key, MASK mask) { return mKeyBind.canHandle(mouse, key, mask); }
+
+    LLKeyBind mKeyBind;
+    bool mAssignable; // whether user can change key or key simply acts as placeholder
+    U32 mConflictMask;
+};
+
+class LLKeyConflictHandler
+{
+public:
+
+    enum ESourceMode // partially repeats e_keyboard_mode
+    {
+        MODE_FIRST_PERSON,
+        MODE_THIRD_PERSON,
+        MODE_EDIT_AVATAR,
+        MODE_SITTING,
+        MODE_SAVED_SETTINGS, // for settings from saved settings
+        MODE_COUNT
+    };
+
+    const U32 CONFLICT_NOTHING = 0;
+    // at the moment this just means that key will conflict with everything that is identical
+    const U32 CONFLICT_ANY = U32_MAX;
+
+    // Note: missed selection and edition commands (would be really nice to go through selection via MB4/5 or wheel)
+
+    LLKeyConflictHandler();
+    LLKeyConflictHandler(ESourceMode mode);
+    ~LLKeyConflictHandler();
+
+    bool canHandleControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask);
+    bool canHandleKey(const std::string &control_name, KEY key, MASK mask);
+    bool canHandleMouse(const std::string &control_name, EMouseClickType mouse_ind, MASK mask);
+    bool canHandleMouse(const std::string &control_name, S32 mouse_ind, MASK mask); //Just for convinience
+    bool canAssignControl(const std::string &control_name);
+    static bool isReservedByMenu(const KEY &key, const MASK &mask);
+    static bool isReservedByMenu(const LLKeyData &data);
+
+    // @control_name - see REGISTER_KEYBOARD_ACTION in llviewerinput for avaliable options,
+    // usually this is just name of the function
+    // @data_index - single control (function) can have multiple key combinations trigering
+    // it, this index indicates combination function will change/add; Note that preferences
+    // floater can only display up to 3 options, but data_index can be bigger than that
+    // @mouse_ind - mouse action (middle click, MB5 etc)
+    // @key - keyboard key action
+    // @mask - shift/ctrl/alt flags
+    // @ignore_mask - Either to expect exact match (ctrl+K will not trigger if ctrl+shift+K
+    // is active) or ignore not expected masks as long as expected mask is present
+    // (ctrl+K will be triggered if ctrl+shift+K is active)
+    bool registerControl(const std::string &control_name, U32 data_index, EMouseClickType mouse_ind, KEY key, MASK mask, bool ignore_mask); //todo: return conflicts?
+    bool clearControl(const std::string &control_name, U32 data_index);
+
+    LLKeyData getControl(const std::string &control_name, U32 data_index);
+    bool isControlEmpty(const std::string &control_name);
+
+    // localized string
+    static std::string getStringFromKeyData(const LLKeyData& keydata);
+    std::string getControlString(const std::string &control_name, U32 data_index);
+
+    // Load single control, overrides existing one if names match
+    void loadFromControlSettings(const std::string &name);
+    // Drops any changes loads controls with ones from 'saved settings' or from xml
+    void loadFromSettings(ESourceMode load_mode);
+
+    // Saves settings to 'saved settings' or to xml
+    // If 'temporary' is set, function will save settings to temporary
+    // file and reload input bindings from temporary file.
+    // 'temporary' does not support gSavedSettings, those are handled
+    // by preferences, so 'temporary' is such case will simply not
+    // reset mHasUnsavedChanges
+    //
+    // 'temporary' exists to support ability of live-editing settings in
+    // preferences: temporary for testing changes 'live' without saving them,
+    // then hitting ok/cancel and save/discard values permanently.
+    void saveToSettings(bool apply_temporary = false);
+
+    LLKeyData getDefaultControl(const std::string &control_name, U32 data_index);
+    // Resets keybinding to default variant from 'saved settings' or xml
+    void resetToDefault(const std::string &control_name, U32 index);
+    void resetToDefault(const std::string &control_name);
+    // resets current mode to defaults
+    void resetToDefaults();
+
+    bool empty() { return mControlsMap.empty(); }
+    void clear();
+
+    // reloads bindings from last valid user's xml or from default xml
+    // to keyboard's handler
+    static void resetKeyboardBindings();
+
+    bool hasUnsavedChanges() { return mHasUnsavedChanges; }
+    void setLoadMode(ESourceMode mode) { mLoadMode = mode; }
+    ESourceMode getLoadMode() { return mLoadMode; }
+
+private:
+    void resetToDefaultAndResolve(const std::string &control_name, bool ignore_conflicts);
+    void resetToDefaults(ESourceMode mode);
+
+    // at the moment these kind of control is not savable, but takes part in conflict resolution
+    void registerTemporaryControl(const std::string &control_name, EMouseClickType mouse_ind, KEY key, MASK mask, U32 conflict_mask);
+    void registerTemporaryControl(const std::string &control_name, U32 conflict_mask = 0);
+
+    typedef std::map<std::string, LLKeyConflict> control_map_t;
+    void loadFromSettings(const LLViewerInput::KeyMode& keymode, control_map_t *destination);
+    bool loadFromSettings(const ESourceMode &load_mode, const std::string &filename, control_map_t *destination);
+    void generatePlaceholders(ESourceMode load_mode); //E.x. non-assignable values
+    // returns false in case user is trying to reuse control that can't be reassigned
+    bool removeConflicts(const LLKeyData &data, const U32 &conlict_mask);
+
+    // removes flags and removes temporary file, returns 'true' if file was removed
+    bool clearUnsavedChanges();
+    // return true if there was a file to remove
+    static bool clearTemporaryFile();
+
+    control_map_t mControlsMap;
+    control_map_t mDefaultsMap;
+    bool mHasUnsavedChanges;
+    ESourceMode mLoadMode;
+
+    // To implement 'apply immediately'+revert on cancel, class applies changes to temporary file
+    // but this only works for settings from keybndings files (key_bindings.xml)
+    // saved setting rely onto external mechanism of preferences floater
+    bool mUsesTemporaryFile;
+    static S32 sTemporaryFileUseCount;
+};
+
+
+#endif  // LL_LLKEYCONFLICT_H
diff --git a/indra/newview/lllandmarkactions.cpp b/indra/newview/lllandmarkactions.cpp
index c243f8b4f0194c8567fbaa6f51dd9f36b1f601cc..a17dc674acb08b460f83af1fa331ff11886eb326 100644
--- a/indra/newview/lllandmarkactions.cpp
+++ b/indra/newview/lllandmarkactions.cpp
@@ -228,23 +228,6 @@ LLViewerInventoryItem* LLLandmarkActions::findLandmarkForAgentPos()
 	return findLandmarkForGlobalPos(gAgent.getPositionGlobal());
 }
 
-bool LLLandmarkActions::canCreateLandmarkHere()
-{
-	LLParcel* agent_parcel = LLViewerParcelMgr::getInstance()->getAgentParcel();
-	if(!agent_parcel)
-	{
-		LL_WARNS() << "No agent region" << LL_ENDL;
-		return false;
-	}
-	if (agent_parcel->getAllowLandmark()
-		|| LLViewerParcelMgr::isParcelOwnedByAgent(agent_parcel, GP_LAND_ALLOW_LANDMARK))
-	{
-		return true;
-	}
-
-	return false;
-}
-
 void LLLandmarkActions::createLandmarkHere(
 	const std::string& name, 
 	const std::string& desc, 
@@ -261,11 +244,6 @@ void LLLandmarkActions::createLandmarkHere(
 		LL_WARNS() << "No agent parcel" << LL_ENDL;
 		return;
 	}
-	if (!canCreateLandmarkHere())
-	{
-		LLNotificationsUtil::add("CannotCreateLandmarkNotOwner");
-		return;
-	}
 
 	create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
 		folder_id, LLTransactionID::tnull,
diff --git a/indra/newview/lllandmarkactions.h b/indra/newview/lllandmarkactions.h
index 870d92811ea2bbac7826d955feec08a272193077..ae7b072fcb381133ad828286f38119e82f2b4d93 100644
--- a/indra/newview/lllandmarkactions.h
+++ b/indra/newview/lllandmarkactions.h
@@ -72,12 +72,6 @@ class LLLandmarkActions
 	 */
 	static LLViewerInventoryItem* findLandmarkForAgentPos();
 
-
-	/**
-	 * @brief Checks whether agent has rights to create landmark for current parcel.
-	 */
-	static bool canCreateLandmarkHere();
-
 	/**
 	 * @brief Creates landmark for current parcel.
 	 */
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index b4236c406b8b79ce85f2d7ecfcce2ee07c3d8430..543d2a087fbebbac7f36f950f3babf131bb7c66b 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -107,11 +107,13 @@ LLLandmark* LLLandmarkList::getAsset(const LLUUID& asset_uuid, loaded_callback_t
             return NULL;
         }
 
+        mRequestedList[asset_uuid] = gFrameTimeSeconds;
+
+        // Note that getAssetData can callback immediately and cleans mRequestedList
 		gAssetStorage->getAssetData(asset_uuid,
 									LLAssetType::AT_LANDMARK,
 									LLLandmarkList::processGetAssetReply,
 									NULL);
-		mRequestedList[asset_uuid] = gFrameTimeSeconds;
 	}
 	return NULL;
 }
@@ -194,11 +196,15 @@ void LLLandmarkList::processGetAssetReply(
             landmark_uuid_list_t::iterator iter = gLandmarkList.mWaitList.begin();
             LLUUID asset_uuid = *iter;
             gLandmarkList.mWaitList.erase(iter);
+
+            // add to mRequestedList before calling getAssetData()
+            gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;
+
+            // Note that getAssetData can callback immediately and cleans mRequestedList
             gAssetStorage->getAssetData(asset_uuid,
                 LLAssetType::AT_LANDMARK,
                 LLLandmarkList::processGetAssetReply,
                 NULL);
-            gLandmarkList.mRequestedList[asset_uuid] = gFrameTimeSeconds;
         }
         scheduling = false;
     }
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 2300bc886232b78212e2cf3910424e99f9cd177d..fa626fb015a0a83634e0cd108b70ffa431b881be 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -44,6 +44,7 @@
 
 // newview includes
 #include "llagent.h"
+#include "llfloaterreg.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llinventoryobserver.h"
 #include "lllandmarkactions.h"
@@ -671,7 +672,7 @@ void LLLocationInputCtrl::onAddLandmarkButtonClicked()
 	}
 	else
 	{
-		LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
+		LLFloaterReg::showInstance("add_landmark");
 	}
 }
 
@@ -1158,7 +1159,7 @@ void LLLocationInputCtrl::onLocationContextMenuItemClicked(const LLSD& userdata)
 			
 			if(!landmark)
 			{
-				LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
+				LLFloaterReg::showInstance("add_landmark");
 			}
 			else
 			{
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 415781bc27fcf0f0d76025883edac8e437c09fa8..eebc2486a234fa0f1c4c37027c9ee63502302fd5 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -281,6 +281,28 @@ std::string LLLogChat::makeLogFileName(std::string filename)
 	return filename;
 }
 
+//static
+void LLLogChat::renameLogFile(const std::string& old_filename, const std::string& new_filename)
+{
+    std::string new_name = cleanFileName(new_filename);
+    std::string old_name = cleanFileName(old_filename);
+    new_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, new_name);
+    old_name = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, old_name);
+
+    if (new_name.empty() || old_name.empty())
+    {
+        return;
+    }
+
+    new_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+    old_name += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+
+    if (!LLFile::isfile(new_name) && LLFile::isfile(old_name))
+    {
+        LLFile::rename(old_name, new_name);
+    }
+}
+
 std::string LLLogChat::cleanFileName(std::string filename)
 {
 	std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 8b7fe14e1684ad4c6c4b7596a09aaa948978f154..c4b61ee716b56e1832e3a0e373a84c30ca559ca7 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -94,6 +94,7 @@ class LLLogChat : public LLSingleton<LLLogChat>
 
 	static std::string timestamp(bool withdate = false);
 	static std::string makeLogFileName(std::string(filename));
+	static void renameLogFile(const std::string& old_filename, const std::string& new_filename);
 	/**
 	*Add functions to get old and non date stamped file names when needed
 	*/
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index fa53a21940c70a139fef1fb7634207b4ad8bb916..e81d2cc0826e83e8b4ff0c4709722590f19d125b 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -58,6 +58,7 @@
 #include "llevents.h"
 #include "llappviewer.h"
 #include "llsdserialize.h"
+#include "lltrans.h"
 
 #include <boost/scoped_ptr.hpp>
 #include <sstream>
@@ -332,7 +333,7 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
         {
             data["certificate"] = response["certificate"];
         }
-        
+
         if (gViewerWindow)
             gViewerWindow->setShowProgress(FALSE);
 
@@ -349,13 +350,36 @@ void LLLoginInstance::handleLoginFailure(const LLSD& event)
         // login.cgi is insisting on a required update. We were called with an
         // event that bundles both the login.cgi 'response' and the
         // synchronization event from the 'updater'.
-        std::string required_version = response["message_args"]["VERSION"];
-        LL_WARNS("LLLogin") << "Login failed because an update to version " << required_version << " is required." << LL_ENDL;
+        std::string login_version = response["message_args"]["VERSION"];
+        std::string vvm_version   = updater["VERSION"];
+        std::string relnotes      = updater["URL"];
+        LL_WARNS("LLLogin") << "Login failed because an update to version " << login_version << " is required." << LL_ENDL;
+        // vvm_version might be empty because we might not have gotten
+        // SLVersionChecker's LoginSync handshake. But if it IS populated, it
+        // should (!) be the same as the version we got from login.cgi.
+        if ((! vvm_version.empty()) && vvm_version != login_version)
+        {
+            LL_WARNS("LLLogin") << "VVM update version " << vvm_version
+                                << " differs from login version " << login_version
+                                << "; presenting VVM version to match release notes URL"
+                                << LL_ENDL;
+            login_version = vvm_version;
+        }
+        if (relnotes.empty() || relnotes.find("://") == std::string::npos)
+        {
+            relnotes = LLTrans::getString("RELEASE_NOTES_BASE_URL");
+            if (!LLStringUtil::endsWith(relnotes, "/"))
+                relnotes += "/";
+            relnotes += LLURI::escape(login_version) + ".html";
+        }
 
         if (gViewerWindow)
             gViewerWindow->setShowProgress(FALSE);
 
-        LLSD args(LLSDMap("VERSION", required_version));
+        LLSD args;
+        args["VERSION"] = login_version;
+        args["URL"] = relnotes;
+
         if (updater.isUndefined())
         {
             // If the updater failed to shake hands, better advise the user to
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 663a6071f733ed344f00b944757866787e5dbcf2..4a8ef53a8ba03be21223eb4dfe777f065068d107 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -726,7 +726,20 @@ void LLMuteList::requestFromServer(const LLUUID& agent_id)
 	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 	msg->nextBlockFast(_PREHASH_MuteData);
 	msg->addU32Fast(_PREHASH_MuteCRC, crc.getCRC());
-	gAgent.sendReliableMessage();
+
+    if (gDisconnected)
+    {
+        LL_WARNS() << "Trying to request mute list when disconnected!" << LL_ENDL;
+        return;
+    }
+    if (!gAgent.getRegion())
+    {
+        LL_WARNS() << "No region for agent yet, skipping mute list request!" << LL_ENDL;
+        return;
+    }
+    // Double amount of retries due to this request happening during busy stage
+    // Ideally this should be turned into a capability
+    gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, TRUE, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);
 }
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index b68baf53a8d82534270c6de2a85195e6bb16ff08..285056300d533c9b934e4cb4c8e183db22fa35d6 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -58,6 +58,7 @@
 #include "llweb.h"
 #include "llhints.h"
 
+#include "llfloatersidepanelcontainer.h"
 #include "llinventorymodel.h"
 #include "lllandmarkactions.h"
 
@@ -290,6 +291,7 @@ BOOL LLNavigationBar::postBuild()
 	mBtnBack	= getChild<LLPullButton>("back_btn");
 	mBtnForward	= getChild<LLPullButton>("forward_btn");
 	mBtnHome	= getChild<LLButton>("home_btn");
+	mBtnLandmarks = getChild<LLButton>("landmarks_btn");
 
 	mCmbLocation= getChild<LLLocationInputCtrl>("location_combo");
 
@@ -305,6 +307,8 @@ BOOL LLNavigationBar::postBuild()
 
 	mBtnHome->setClickedCallback(boost::bind(&LLNavigationBar::onHomeButtonClicked, this));
 
+	mBtnLandmarks->setClickedCallback(boost::bind(&LLNavigationBar::onLandmarksButtonClicked, this));
+
 	mCmbLocation->setCommitCallback(boost::bind(&LLNavigationBar::onLocationSelection, this));
 
 	mTeleportFinishConnection = LLViewerParcelMgr::getInstance()->
@@ -401,6 +405,12 @@ void LLNavigationBar::onHomeButtonClicked()
 	gAgent.teleportHome();
 }
 
+void LLNavigationBar::onLandmarksButtonClicked()
+{
+	LLFloaterReg::toggleInstanceOrBringToFront("places");
+	LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "open_landmark_tab"));
+}
+
 void LLNavigationBar::onTeleportHistoryMenuItemClicked(const LLSD& userdata)
 {
 	int idx = userdata.asInteger();
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
index 997c7677cd05556052fe2941d2bf5796dd2cb7fa..ab624ae0c256f36ed84f6c4dced397a0f6ff5f30 100755
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -122,6 +122,7 @@ class LLNavigationBar
 	void onNavigationButtonHeldUp(LLButton* nav_button);
 	void onForwardButtonClicked();
 	void onHomeButtonClicked();
+	void onLandmarksButtonClicked();
 	void onLocationSelection();
 	void onLocationPrearrange(const LLSD& data);
 	void onTeleportFinished(const LLVector3d& global_agent_pos);
@@ -147,6 +148,7 @@ class LLNavigationBar
 	LLPullButton*				mBtnBack;
 	LLPullButton*				mBtnForward;
 	LLButton*					mBtnHome;
+	LLButton*					mBtnLandmarks;
 	LLLocationInputCtrl*		mCmbLocation;
 	LLRect						mDefaultNbRect;
 	LLRect						mDefaultFpRect;
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index c044c9d696e2c072ed3b2ac8f46ecdcace2bfc6e..6fd9e3267865809177b3f11d94ebb34f281d548b 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -297,6 +297,7 @@ class LLHandlerUtil
 	 * Writes notification message to IM  p2p session.
 	 */
 	static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false);
+	static void logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only = false);
 
 	/**
 	 * Writes group notice notification message to IM  group session.
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 1e1f243653fd8739537ce71ded9e0a5c38b6e03e..cb3086ee702af589fc8947d7202b50c93f7ed18f 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -123,15 +123,13 @@ void log_name_callback(const LLAvatarName& av_name, const std::string& from_name
 }
 
 // static
-void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
+void LLHandlerUtil::logToIMP2P(const LLUUID& from_id, const std::string& message, bool to_file_only)
 {
 	if (!gCacheName)
 	{
 		return;
 	}
 
-	LLUUID from_id = notification->getPayload()["from_id"];
-
 	if (from_id.isNull())
 	{
 		// Normal behavior for system generated messages, don't spam.
@@ -141,14 +139,21 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi
 
 	if(to_file_only)
 	{
-		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
+		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", message, LLUUID()));
 	}
 	else
 	{
-		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
+		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, message, from_id));
 	}
 }
 
+// static
+void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
+{
+	LLUUID from_id = notification->getPayload()["from_id"];
+	logToIMP2P(from_id, notification->getMessage(), to_file_only);	
+}
+
 // static
 void LLHandlerUtil::logGroupNoticeToIMGroup(
 		const LLNotificationPtr& notification)
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index d4898bb497deb97d68579e5f964eefb4110e0001..58ff2b92c2b0d5e934319e5143b79216eef45d01 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -40,6 +40,8 @@
 #include "rlvactions.h"
 // [/RLVa:KB]
 
+#include <boost/regex.hpp>
+
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
@@ -158,7 +160,19 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 		{
 			// log only to file if notif panel can be embedded to IM and IM is opened
 			bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification);
-			LLHandlerUtil::logToIMP2P(notification, file_only);
+			if ((notification->getName() == "TeleportOffered"
+				|| notification->getName() == "TeleportOffered_MaturityExceeded"
+				|| notification->getName() == "TeleportOffered_MaturityBlocked"))
+			{
+				boost::regex r("<icon\\s*>\\s*([^<]*)?\\s*</icon\\s*>( - )?",
+					boost::regex::perl|boost::regex::icase);
+				std::string stripped_msg = boost::regex_replace(notification->getMessage(), r, "");
+				LLHandlerUtil::logToIMP2P(notification->getPayload()["from_id"], stripped_msg,file_only);
+			}
+			else
+			{
+				LLHandlerUtil::logToIMP2P(notification, file_only);
+			}
 		}
 	}
 
diff --git a/indra/newview/llpaneleditsky.cpp b/indra/newview/llpaneleditsky.cpp
index 2e26b691441d0fa439cad061b2a9bd2142d4f061..a169712bd885804a03d1240ec1d81e38268f2dc9 100644
--- a/indra/newview/llpaneleditsky.cpp
+++ b/indra/newview/llpaneleditsky.cpp
@@ -69,11 +69,15 @@ namespace
     const std::string   FIELD_SKY_GLOW_SIZE("glow_size");
     const std::string   FIELD_SKY_STAR_BRIGHTNESS("star_brightness");
     const std::string   FIELD_SKY_SUN_ROTATION("sun_rotation");
+    const std::string   FIELD_SKY_SUN_AZIMUTH("sun_azimuth");
+    const std::string   FIELD_SKY_SUN_ELEVATION("sun_elevation");
     const std::string   FIELD_SKY_SUN_IMAGE("sun_image");
     const std::string   FIELD_SKY_SUN_SCALE("sun_scale");
     const std::string   FIELD_SKY_SUN_BEACON("sunbeacon");
     const std::string   FIELD_SKY_MOON_BEACON("moonbeacon");
     const std::string   FIELD_SKY_MOON_ROTATION("moon_rotation");
+    const std::string   FIELD_SKY_MOON_AZIMUTH("moon_azimuth");
+    const std::string   FIELD_SKY_MOON_ELEVATION("moon_elevation");
     const std::string   FIELD_SKY_MOON_IMAGE("moon_image");
     const std::string   FIELD_SKY_MOON_SCALE("moon_scale");
     const std::string   FIELD_SKY_MOON_BRIGHTNESS("moon_brightness");
@@ -473,12 +477,16 @@ BOOL LLPanelSettingsSkySunMoonTab::postBuild()
     getChild<LLUICtrl>(FIELD_SKY_GLOW_SIZE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onGlowChanged(); });
     getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onStarBrightnessChanged(); });
     getChild<LLUICtrl>(FIELD_SKY_SUN_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunRotationChanged(); });
+    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
+    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunAzimElevChanged(); });
     getChild<LLUICtrl>(FIELD_SKY_SUN_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunImageChanged(); });
     getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onSunScaleChanged(); });
     getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setBlankImageAssetID(LLSettingsSky::GetBlankSunTextureId());
     getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setDefaultImageAssetID(LLSettingsSky::GetBlankSunTextureId());
     getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setAllowNoTexture(TRUE);
     getChild<LLUICtrl>(FIELD_SKY_MOON_ROTATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonRotationChanged(); });
+    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
+    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonAzimElevChanged(); });
     getChild<LLUICtrl>(FIELD_SKY_MOON_IMAGE)->setCommitCallback([this](LLUICtrl *, const LLSD &) { onMoonImageChanged(); });
     getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setDefaultImageAssetID(LLSettingsSky::GetDefaultMoonTextureId());
     getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setBlankImageAssetID(LLSettingsSky::GetDefaultMoonTextureId());
@@ -537,13 +545,29 @@ void LLPanelSettingsSkySunMoonTab::refresh()
     getChild<LLUICtrl>(FIELD_SKY_GLOW_FOCUS)->setValue(glow.mV[2] / SLIDER_SCALE_GLOW_B);
 
     getChild<LLUICtrl>(FIELD_SKY_STAR_BRIGHTNESS)->setValue(mSkySettings->getStarBrightness());
-    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(mSkySettings->getSunRotation());
     getChild<LLTextureCtrl>(FIELD_SKY_SUN_IMAGE)->setValue(mSkySettings->getSunTextureId());
     getChild<LLUICtrl>(FIELD_SKY_SUN_SCALE)->setValue(mSkySettings->getSunScale());
-    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(mSkySettings->getMoonRotation());
     getChild<LLTextureCtrl>(FIELD_SKY_MOON_IMAGE)->setValue(mSkySettings->getMoonTextureId());
     getChild<LLUICtrl>(FIELD_SKY_MOON_SCALE)->setValue(mSkySettings->getMoonScale());
     getChild<LLUICtrl>(FIELD_SKY_MOON_BRIGHTNESS)->setValue(mSkySettings->getMoonBrightness());
+
+    // Sun rotation values
+    F32 azimuth, elevation;
+    LLQuaternion quat = mSkySettings->getSunRotation();
+    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+
+    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
+    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
+    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
+
+    // Moon rotation values
+    quat = mSkySettings->getMoonRotation();
+    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+
+    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
+    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
+    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
+
 }
 
 //-------------------------------------------------------------------------
@@ -583,10 +607,47 @@ void LLPanelSettingsSkySunMoonTab::onStarBrightnessChanged()
 
 void LLPanelSettingsSkySunMoonTab::onSunRotationChanged()
 {
-    if (!mSkySettings) return;
-    mSkySettings->setSunRotation(getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation());
-    mSkySettings->update();
-    setIsDirty();
+    LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->getRotation();
+
+    F32 azimuth, elevation;
+    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+    getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->setValue(azimuth);
+    getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->setValue(elevation);
+    if (mSkySettings)
+    {
+        mSkySettings->setSunRotation(quat);
+        mSkySettings->update();
+        setIsDirty();
+    }
+}
+
+void LLPanelSettingsSkySunMoonTab::onSunAzimElevChanged()
+{
+    F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_SUN_AZIMUTH)->getValue().asReal();
+    F32 elevation = getChild<LLUICtrl>(FIELD_SKY_SUN_ELEVATION)->getValue().asReal();
+    LLQuaternion quat;
+
+    azimuth *= DEG_TO_RAD;
+    elevation *= DEG_TO_RAD;
+
+    if (is_approx_zero(elevation))
+    {
+        elevation = F_APPROXIMATELY_ZERO;
+    }
+
+    quat.setAngleAxis(-elevation, 0, 1, 0);
+    LLQuaternion az_quat;
+    az_quat.setAngleAxis(F_TWO_PI - azimuth, 0, 0, 1);
+    quat *= az_quat;
+
+    getChild<LLVirtualTrackball>(FIELD_SKY_SUN_ROTATION)->setRotation(quat);
+
+    if (mSkySettings)
+    {
+        mSkySettings->setSunRotation(quat);
+        mSkySettings->update();
+        setIsDirty();
+    }
 }
 
 void LLPanelSettingsSkySunMoonTab::onSunScaleChanged()
@@ -607,10 +668,48 @@ void LLPanelSettingsSkySunMoonTab::onSunImageChanged()
 
 void LLPanelSettingsSkySunMoonTab::onMoonRotationChanged()
 {
-    if (!mSkySettings) return;
-    mSkySettings->setMoonRotation(getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation());
-    mSkySettings->update();
-    setIsDirty();
+    LLQuaternion quat = getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->getRotation();
+
+    F32 azimuth, elevation;
+    LLVirtualTrackball::getAzimuthAndElevationDeg(quat, azimuth, elevation);
+    getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->setValue(azimuth);
+    getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->setValue(elevation);
+
+    if (mSkySettings)
+    {
+        mSkySettings->setMoonRotation(quat);
+        mSkySettings->update();
+        setIsDirty();
+    }
+}
+
+void LLPanelSettingsSkySunMoonTab::onMoonAzimElevChanged()
+{
+    F32 azimuth = getChild<LLUICtrl>(FIELD_SKY_MOON_AZIMUTH)->getValue().asReal();
+    F32 elevation = getChild<LLUICtrl>(FIELD_SKY_MOON_ELEVATION)->getValue().asReal();
+    LLQuaternion quat;
+
+    azimuth *= DEG_TO_RAD;
+    elevation *= DEG_TO_RAD;
+
+    if (is_approx_zero(elevation))
+    {
+        elevation = F_APPROXIMATELY_ZERO;
+    }
+
+    quat.setAngleAxis(-elevation, 0, 1, 0);
+    LLQuaternion az_quat;
+    az_quat.setAngleAxis(F_TWO_PI- azimuth, 0, 0, 1);
+    quat *= az_quat;
+
+    getChild<LLVirtualTrackball>(FIELD_SKY_MOON_ROTATION)->setRotation(quat);
+
+    if (mSkySettings)
+    {
+        mSkySettings->setMoonRotation(quat);
+        mSkySettings->update();
+        setIsDirty();
+    }
 }
 
 void LLPanelSettingsSkySunMoonTab::onMoonImageChanged()
diff --git a/indra/newview/llpaneleditsky.h b/indra/newview/llpaneleditsky.h
index c02c9c95a0c2cc8a84c68e7a05a35a67de5cd1c8..cb63d40b0c0c83deb6ba5af26adb3cab1ee7f446 100644
--- a/indra/newview/llpaneleditsky.h
+++ b/indra/newview/llpaneleditsky.h
@@ -29,7 +29,7 @@
 
 #include "llpanel.h"
 #include "llsettingssky.h"
-#include "llfloaterfixedenvironment.h"
+#include "llfloatereditenvironmentbase.h"
 
 //=========================================================================
 class LLSlider;
@@ -124,9 +124,11 @@ class LLPanelSettingsSkySunMoonTab : public LLPanelSettingsSky
     void                    onGlowChanged();
     void                    onStarBrightnessChanged();
     void                    onSunRotationChanged();
+    void                    onSunAzimElevChanged();
     void                    onSunScaleChanged();
     void                    onSunImageChanged();
     void                    onMoonRotationChanged();
+    void                    onMoonAzimElevChanged();
     void                    onMoonScaleChanged();
     void                    onMoonBrightnessChanged();
     void                    onMoonImageChanged();
diff --git a/indra/newview/llpaneleditwater.h b/indra/newview/llpaneleditwater.h
index ab2dc47bccb96ed528c99cb1af3c3d80f8b66fbc..4b7ec903c9d973441c50c3f4a1ff5f8c74f6bad8 100644
--- a/indra/newview/llpaneleditwater.h
+++ b/indra/newview/llpaneleditwater.h
@@ -30,7 +30,7 @@
 #include "llpanel.h"
 #include "llsettingswater.h"
 
-#include "llfloaterfixedenvironment.h"
+#include "llfloatereditenvironmentbase.h"
 
 //=========================================================================
 class LLSlider;
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index 6751c25fb995ded9deb3521996de1f6e132e4b96..880323ce16049154b229c18bd570128d88e0a404 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -52,7 +52,6 @@
 typedef std::pair<LLUUID, std::string> folder_pair_t;
 
 static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right);
-static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
 
 static LLPanelInjector<LLPanelLandmarkInfo> t_landmark_info("panel_landmark_info");
 
@@ -106,6 +105,18 @@ void LLPanelLandmarkInfo::resetLocation()
 
 // virtual
 void LLPanelLandmarkInfo::setInfoType(EInfoType type)
+{
+    LLUUID dest_folder;
+    setInfoType(type, dest_folder);
+}
+
+// Sets CREATE_LANDMARK infotype and creates landmark at desired folder
+void LLPanelLandmarkInfo::setInfoAndCreateLandmark(const LLUUID& fodler_id)
+{
+    setInfoType(CREATE_LANDMARK, fodler_id);
+}
+
+void LLPanelLandmarkInfo::setInfoType(EInfoType type, const LLUUID &folder_id)
 {
 	LLPanel* landmark_info_panel = getChild<LLPanel>("landmark_info_panel");
 
@@ -183,7 +194,7 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
 			// remote parcel request to complete.
 			if (!LLLandmarkActions::landmarkAlreadyExists())
 			{
-				createLandmark(LLUUID());
+				createLandmark(folder_id);
 			}
 		}
 		break;
@@ -504,7 +515,7 @@ static bool cmp_folders(const folder_pair_t& left, const folder_pair_t& right)
 	return left.second < right.second;
 }
 
-static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
+void LLPanelLandmarkInfo::collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
 {
 	LLUUID landmarks_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK);
 
@@ -517,16 +528,20 @@ static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats)
 		items,
 		LLInventoryModel::EXCLUDE_TRASH,
 		is_category);
+}
 
-	// Add the "My Favorites" category.
-	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-	LLViewerInventoryCategory* favorites_cat = gInventory.getCategory(favorites_id);
-	if (!favorites_cat)
-	{
-		LL_WARNS() << "Cannot find the favorites folder" << LL_ENDL;
-	}
-	else
-	{
-		cats.push_back(favorites_cat);
-	}
+/* virtual */ void LLUpdateLandmarkParent::fire(const LLUUID& inv_item_id)
+{
+	LLInventoryModel::update_list_t update;
+	LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1);
+	update.push_back(old_folder);
+	LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1);
+	update.push_back(new_folder);
+	gInventory.accountForUpdate(update);
+
+	mItem->setParent(mNewParentId);
+	mItem->updateParentOnServer(FALSE);
+
+	gInventory.updateItem(mItem);
+	gInventory.notifyObservers();
 }
diff --git a/indra/newview/llpanellandmarkinfo.h b/indra/newview/llpanellandmarkinfo.h
index 9712736182bcfafe46f3ab62104295eb600f970d..f727f286b5704d7564f55aefd136424efffbc9ae 100644
--- a/indra/newview/llpanellandmarkinfo.h
+++ b/indra/newview/llpanellandmarkinfo.h
@@ -28,6 +28,7 @@
 #define LL_LLPANELLANDMARKINFO_H
 
 #include "llpanelplaceinfo.h"
+#include "llinventorymodel.h"
 
 class LLComboBox;
 class LLLineEditor;
@@ -43,8 +44,12 @@ class LLPanelLandmarkInfo : public LLPanelPlaceInfo
 
 	/*virtual*/ void resetLocation();
 
+    // If landmark doesn't exists, will create it at default folder
 	/*virtual*/ void setInfoType(EInfoType type);
 
+    // Sets CREATE_LANDMARK infotype and creates landmark at desired folder
+    void setInfoAndCreateLandmark(const LLUUID& fodler_id);
+
 	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
 
 	// Displays landmark owner, creator and creation date info.
@@ -59,13 +64,19 @@ class LLPanelLandmarkInfo : public LLPanelPlaceInfo
 	// Select current landmark folder in combobox.
 	BOOL setLandmarkFolder(const LLUUID& id);
 
-	// Create a landmark for the current location
-	// in a folder specified by folder_id.
-	void createLandmark(const LLUUID& folder_id);
-
+	typedef std::vector<LLPointer<LLViewerInventoryCategory> > cat_array_t;
 	static std::string getFullFolderName(const LLViewerInventoryCategory* cat);
+	static void collectLandmarkFolders(LLInventoryModel::cat_array_t& cats);
 
 private:
+    // Create a landmark for the current location
+    // in a folder specified by folder_id.
+    // Expects title and description to be initialized
+    void createLandmark(const LLUUID& folder_id);
+
+    // If landmark doesn't exists, will create it at specified folder
+    void setInfoType(EInfoType type, const LLUUID &folder_id);
+
 	void populateFoldersList();
 
 	LLTextBox*			mOwner;
@@ -77,4 +88,17 @@ class LLPanelLandmarkInfo : public LLPanelPlaceInfo
 	LLComboBox*			mFolderCombo;
 };
 
+class LLUpdateLandmarkParent : public LLInventoryCallback
+{
+public:
+	LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) :
+		mItem(item),
+		mNewParentId(new_parent)
+	{};
+	/* virtual */ void fire(const LLUUID& inv_item_id);
+
+private:
+	LLPointer<LLViewerInventoryItem> mItem;
+	LLUUID mNewParentId;
+};
 #endif // LL_LLPANELLANDMARKINFO_H
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index ed0aedf698765da2c94f6c9fcd1394443021e14c..892e3bd4f77cbbd469c4ec0abbc3ad0cc0b532d7 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -36,12 +36,11 @@
 #include "llregionhandle.h"
 
 #include "llaccordionctrl.h"
-#include "llaccordionctrltab.h"
 #include "llagent.h"
 #include "llagentpicksinfo.h"
 #include "llagentui.h"
+#include "llavataractions.h"
 #include "llcallbacklist.h"
-#include "lldndbutton.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfloaterworldmap.h"
 #include "llfolderviewitem.h"
@@ -63,15 +62,8 @@
 // Not yet implemented; need to remove buildPanel() from constructor when we switch
 //static LLRegisterPanelClassWrapper<LLLandmarksPanel> t_landmarks("panel_landmarks");
 
-static const std::string OPTIONS_BUTTON_NAME = "options_gear_btn";
-static const std::string ADD_BUTTON_NAME = "add_btn";
-static const std::string ADD_FOLDER_BUTTON_NAME = "add_folder_btn";
-static const std::string TRASH_BUTTON_NAME = "trash_btn";
-
-
 // helper functions
 static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string);
-static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list);
 static void collapse_all_folders(LLFolderView* root_folder);
 static void expand_all_folders(LLFolderView* root_folder);
 static bool has_expanded_folders(LLFolderView* root_folder);
@@ -152,69 +144,37 @@ void LLOpenFolderByID::doFolder(LLFolderViewFolder* folder)
 	}
 }
 
-/**
- * Bridge to support knowing when the inventory has changed to update Landmarks tab
- * ShowFolderState filter setting to show all folders when the filter string is empty and
- * empty folder message when Landmarks inventory category has no children.
- * Ensures that "Landmarks" folder in the Library is open on strart up.
- */
-class LLLandmarksPanelObserver : public LLInventoryObserver
-{
-public:
-	LLLandmarksPanelObserver(LLLandmarksPanel* lp)
-	:	mLP(lp),
-	 	mIsLibraryLandmarksOpen(false)
-	{}
-	virtual ~LLLandmarksPanelObserver() {}
-	/*virtual*/ void changed(U32 mask);
-
-private:
-	LLLandmarksPanel* mLP;
-	bool mIsLibraryLandmarksOpen;
-};
-
-void LLLandmarksPanelObserver::changed(U32 mask)
+LLLandmarksPanel::LLLandmarksPanel()
+	:	LLPanelPlacesTab()
+	,	mLandmarksInventoryPanel(NULL)
+	,	mCurrentSelectedList(NULL)
+	,	mGearFolderMenu(NULL)
+	,	mGearLandmarkMenu(NULL)
+	,	mSortingMenu(NULL)
+	,	mAddMenu(NULL)
+	,	isLandmarksPanel(true)
 {
-	mLP->updateShowFolderState();
-
-	LLPlacesInventoryPanel* library = mLP->getLibraryInventoryPanel();
-	if (!mIsLibraryLandmarksOpen && library)
-	{
-		// Search for "Landmarks" folder in the Library and open it once on start up. See EXT-4827.
-		const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
-		if (landmarks_cat.notNull())
-		{
-			LLOpenFolderByID opener(landmarks_cat);
-			library->getRootFolder()->applyFunctorRecursively(opener);
-			mIsLibraryLandmarksOpen = opener.isFolderOpen();
-		}
-	}
+	buildFromFile("panel_landmarks.xml");
 }
 
-LLLandmarksPanel::LLLandmarksPanel()
+LLLandmarksPanel::LLLandmarksPanel(bool is_landmark_panel)
 	:	LLPanelPlacesTab()
-	,	mFavoritesInventoryPanel(NULL)
 	,	mLandmarksInventoryPanel(NULL)
-	,	mMyInventoryPanel(NULL)
-	,	mLibraryInventoryPanel(NULL)
 	,	mCurrentSelectedList(NULL)
-	,	mListCommands(NULL)
-	,	mGearButton(NULL)
 	,	mGearFolderMenu(NULL)
 	,	mGearLandmarkMenu(NULL)
+	,	mSortingMenu(NULL)
+	,	mAddMenu(NULL)
+	,	isLandmarksPanel(is_landmark_panel)
 {
-	mInventoryObserver = new LLLandmarksPanelObserver(this);
-	gInventory.addObserver(mInventoryObserver);
-
-	buildFromFile( "panel_landmarks.xml");
+	if (is_landmark_panel)
+	{
+		buildFromFile("panel_landmarks.xml");
+	}
 }
 
 LLLandmarksPanel::~LLLandmarksPanel()
 {
-	if (gInventory.containsObserver(mInventoryObserver))
-	{
-		gInventory.removeObserver(mInventoryObserver);
-	}
 }
 
 BOOL LLLandmarksPanel::postBuild()
@@ -224,17 +184,7 @@ BOOL LLLandmarksPanel::postBuild()
 
 	// mast be called before any other initXXX methods to init Gear menu
 	initListCommandsHandlers();
-
-	initFavoritesInventoryPanel();
 	initLandmarksInventoryPanel();
-	initMyInventoryPanel();
-	initLibraryInventoryPanel();
-
-	LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
-	if (accordion)
-	{
-		accordion->setSkipScrollToChild(true);
-	}
 
 	return TRUE;
 }
@@ -242,30 +192,10 @@ BOOL LLLandmarksPanel::postBuild()
 // virtual
 void LLLandmarksPanel::onSearchEdit(const std::string& string)
 {
-	// give FolderView a chance to be refreshed. So, made all accordions visible
-	for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
-	{
-		LLAccordionCtrlTab* tab = *iter;
-		tab->setVisible(TRUE);
-
-		// expand accordion to see matched items in each one. See EXT-2014.
-		if (string != "")
-		{
-			tab->changeOpenClose(false);
-		}
-
-		LLPlacesInventoryPanel* inventory_list = dynamic_cast<LLPlacesInventoryPanel*>(tab->getAccordionView());
-		if (NULL == inventory_list) continue;
-
-		filter_list(inventory_list, string);
-	}
+	filter_list(mCurrentSelectedList, string);
 
 	if (sFilterSubString != string)
 		sFilterSubString = string;
-
-	// show all folders in Landmarks Accordion for empty filter
-	// only if Landmarks inventory folder is not empty
-	updateShowFolderState();
 }
 
 // virtual
@@ -277,11 +207,6 @@ void LLLandmarksPanel::onShowOnMap()
 		return;
 	}
 
-	// Disable the "Map" button because loading landmark can take some time.
-	// During this time the button is useless. It will be enabled on callback finish
-	// or upon switching to other item.
-	mShowOnMapBtn->setEnabled(FALSE);
-
 	doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doShowOnMap, this, _1));
 }
 
@@ -306,6 +231,12 @@ void LLLandmarksPanel::onTeleport()
 	}
 }
 
+/*virtual*/
+void LLLandmarksPanel::onRemoveSelected()
+{
+    onClipboardAction("delete");
+}
+
 // virtual
 bool LLLandmarksPanel::isSingleItemSelected()
 {
@@ -325,86 +256,55 @@ bool LLLandmarksPanel::isSingleItemSelected()
 }
 
 // virtual
-void LLLandmarksPanel::updateVerbs()
-{
-	if (!isTabVisible()) 
-		return;
-
-	bool landmark_selected = isLandmarkSelected();
-	mTeleportBtn->setEnabled(landmark_selected && isActionEnabled("teleport"));
-	mShowProfile->setEnabled(landmark_selected && isActionEnabled("more_info"));
-	mShowOnMapBtn->setEnabled(landmark_selected && isActionEnabled("show_on_map"));
-
-	// TODO: mantipov: Uncomment when mShareBtn is supported
-	// Share button should be enabled when neither a folder nor a landmark is selected
-	//mShareBtn->setEnabled(NULL != current_item);
-
-	updateListCommands();
+LLToggleableMenu* LLLandmarksPanel::getSelectionMenu()
+{
+    LLToggleableMenu* menu = mGearFolderMenu;
+
+    if (mCurrentSelectedList)
+    {
+        LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem();
+        if (!listenerp)
+            return menu;
+
+        if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
+        {
+            menu = mGearLandmarkMenu;
+        }
+    }
+    return menu;
 }
 
-void LLLandmarksPanel::onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action)
+// virtual
+LLToggleableMenu* LLLandmarksPanel::getSortingMenu()
 {
-	if (user_action && (items.size() > 0))
-	{
-		deselectOtherThan(inventory_list);
-		mCurrentSelectedList = inventory_list;
-	}
-	updateVerbs();
+    return mSortingMenu;
 }
 
-void LLLandmarksPanel::onSelectorButtonClicked()
+// virtual
+LLToggleableMenu* LLLandmarksPanel::getCreateMenu()
 {
-	// TODO: mantipov: update getting of selected item
-	// TODO: bind to "i" button
-	LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem();
-	if (!cur_item) return;
-
-	LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem());
-	if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
-	{
-		LLSD key;
-		key["type"] = "landmark";
-		key["id"] = listenerp->getUUID();
-
-		LLFloaterSidePanelContainer::showPanel("places", key);
-	}
+    return mAddMenu;
 }
 
-void LLLandmarksPanel::updateShowFolderState()
+void LLLandmarksPanel::updateVerbs()
 {
-	bool show_all_folders =   mLandmarksInventoryPanel->getFilterSubString().empty();
-	if (show_all_folders)
+	if (sRemoveBtn)
 	{
-		show_all_folders = category_has_descendents(mLandmarksInventoryPanel);
+		sRemoveBtn->setEnabled(isActionEnabled("delete") && (isFolderSelected() || isLandmarkSelected()));
 	}
-
-	mLandmarksInventoryPanel->setShowFolderState(show_all_folders ?
-		LLInventoryFilter::SHOW_ALL_FOLDERS :
-		LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS
-		);
 }
 
 void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus)
 {
-	if (selectItemInAccordionTab(mFavoritesInventoryPanel, "tab_favorites", obj_id, take_keyboard_focus))
-	{
-		return;
-	}
-
-	if (selectItemInAccordionTab(mLandmarksInventoryPanel, "tab_landmarks", obj_id, take_keyboard_focus))
-	{
+	if (!mCurrentSelectedList)
 		return;
-	}
 
-	if (selectItemInAccordionTab(mMyInventoryPanel, "tab_inventory", obj_id, take_keyboard_focus))
-	{
-		return;
-	}
-
-	if (selectItemInAccordionTab(mLibraryInventoryPanel, "tab_library", obj_id, take_keyboard_focus))
-	{
+	LLFolderView* root = mCurrentSelectedList->getRootFolder();
+	LLFolderViewItem* item = mCurrentSelectedList->getItemByID(obj_id);
+	if (!item)
 		return;
-	}
+	root->setSelection(item, FALSE, take_keyboard_focus);
+	root->scrollToShowSelection();
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -423,18 +323,6 @@ bool LLLandmarksPanel::isFolderSelected() const
 	return current_item && (current_item->getInventoryType() == LLInventoryType::IT_CATEGORY);
 }
 
-bool LLLandmarksPanel::isReceivedFolderSelected() const
-{
-	// Received Folder can be only in Landmarks accordion
-	if (mCurrentSelectedList != mLandmarksInventoryPanel) return false;
-
-	// *TODO: it should be filled with logic when EXT-976 is done.
-
-	LL_WARNS() << "Not implemented yet until EXT-976 is done." << LL_ENDL;
-
-	return false;
-}
-
 void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb)
 {
 	LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
@@ -464,36 +352,6 @@ LLFolderViewModelItemInventory* LLLandmarksPanel::getCurSelectedViewModelItem()
 }
 
 
-LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
-															 const std::string& tab_name,
-															 const LLUUID& obj_id,
-															 BOOL take_keyboard_focus) const
-{
-	if (!inventory_list)
-		return NULL;
-
-	LLFolderView* root = inventory_list->getRootFolder();
-
-	LLFolderViewItem* item = inventory_list->getItemByID(obj_id);
-	if (!item)
-		return NULL;
-
-	LLAccordionCtrlTab* tab = getChild<LLAccordionCtrlTab>(tab_name);
-	if (!tab->isExpanded())
-	{
-		tab->changeOpenClose(false);
-	}
-
-	root->setSelection(item, FALSE, take_keyboard_focus);
-
-	LLAccordionCtrl* accordion = getChild<LLAccordionCtrl>("landmarks_accordion");
-	LLRect screen_rc;
-	localRectToScreen(item->getRect(), &screen_rc);
-	accordion->notifyParent(LLSD().with("scrollToShowRect", screen_rc.getValue()));
-
-	return item;
-}
-
 void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate)
 {
 	if(!panel) return; 
@@ -509,19 +367,29 @@ void LLLandmarksPanel::updateSortOrder(LLInventoryPanel* panel, bool byDate)
 	}
 }
 
+void LLLandmarksPanel::resetSelection()
+{
+}
+
 // virtual
 void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data)
 {
 	//this function will be called after user will try to create a pick for selected landmark.
 	// We have to make request to sever to get parcel_id and snaption_id. 
-	if(isLandmarkSelected())
+	if(mCreatePickItemId.notNull())
 	{
-		LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
-		if (!cur_item) return;
-		LLUUID id = cur_item->getUUID();
-		LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id);
-		doActionOnCurSelectedLandmark(boost::bind(
-				&LLLandmarksPanel::doProcessParcelInfo, this, _1, getCurSelectedItem(), inv_item, parcel_data));
+		LLInventoryItem* inv_item = gInventory.getItem(mCreatePickItemId);
+
+        if (inv_item && inv_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
+        {
+            // we are processing response for doCreatePick, landmark should be already loaded
+            LLLandmark* landmark = LLLandmarkActions::getLandmark(inv_item->getUUID());
+            if (landmark)
+            {
+                doProcessParcelInfo(landmark, inv_item, parcel_data);
+            }
+        }
+        mCreatePickItemId.setNull();
 	}
 }
 
@@ -546,16 +414,6 @@ void LLLandmarksPanel::setErrorStatus(S32 status, const std::string& reason)
 // PRIVATE METHODS
 //////////////////////////////////////////////////////////////////////////
 
-void LLLandmarksPanel::initFavoritesInventoryPanel()
-{
-	mFavoritesInventoryPanel = getChild<LLPlacesInventoryPanel>("favorites_list");
-
-	initLandmarksPanel(mFavoritesInventoryPanel);
-	mFavoritesInventoryPanel->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems");
-
-	initAccordion("tab_favorites", mFavoritesInventoryPanel, true);
-}
-
 void LLLandmarksPanel::initLandmarksInventoryPanel()
 {
 	mLandmarksInventoryPanel = getChild<LLPlacesInventoryPanel>("landmarks_list");
@@ -567,40 +425,14 @@ void LLLandmarksPanel::initLandmarksInventoryPanel()
 	// subscribe to have auto-rename functionality while creating New Folder
 	mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2));
 
-	mMyLandmarksAccordionTab = initAccordion("tab_landmarks", mLandmarksInventoryPanel, true);
-}
-
-void LLLandmarksPanel::initMyInventoryPanel()
-{
-	mMyInventoryPanel= getChild<LLPlacesInventoryPanel>("my_inventory_list");
-
-	initLandmarksPanel(mMyInventoryPanel);
-
-	initAccordion("tab_inventory", mMyInventoryPanel, false);
-}
-
-void LLLandmarksPanel::initLibraryInventoryPanel()
-{
-	mLibraryInventoryPanel = getChild<LLPlacesInventoryPanel>("library_list");
-
-	initLandmarksPanel(mLibraryInventoryPanel);
-
-	// We want to fetch only "Landmarks" category from the library.
-	const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
-	if (landmarks_cat.notNull())
-	{
-		LLInventoryModelBackgroundFetch::instance().start(landmarks_cat);
-	}
-
-	// Expanding "Library" tab for new users who have no landmarks in "My Inventory".
-	initAccordion("tab_library", mLibraryInventoryPanel, true);
+	mCurrentSelectedList = mLandmarksInventoryPanel;
 }
 
 void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list)
 {
 	inventory_list->getFilter().setEmptyLookupMessage("PlacesNoMatchingItems");
 	inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK);
-	inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2));
+	inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::updateVerbs, this));
 
 	inventory_list->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
 	bool sorting_order = gSavedSettings.getBOOL("LandmarksSortedByDate");
@@ -618,86 +450,10 @@ void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list
 	inventory_list->saveFolderState();
 }
 
-LLAccordionCtrlTab* LLLandmarksPanel::initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list,	bool expand_tab)
-{
-	LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>(accordion_tab_name);
-
-	mAccordionTabs.push_back(accordion_tab);
-	accordion_tab->setDropDownStateChangedCallback(
-		boost::bind(&LLLandmarksPanel::onAccordionExpandedCollapsed, this, _2, inventory_list));
-	accordion_tab->setDisplayChildren(expand_tab);
-	return accordion_tab;
-}
-
-void LLLandmarksPanel::onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list)
-{
-	bool expanded = param.asBoolean();
-
-	if(!expanded && (mCurrentSelectedList == inventory_list))
-	{
-		inventory_list->getRootFolder()->clearSelection();
-
-		mCurrentSelectedList = NULL;
-		updateVerbs();
-	}
-
-	// Start background fetch, mostly for My Inventory and Library
-	if (expanded)
-	{
-		const LLUUID &cat_id = inventory_list->getRootFolderID();
-		// Just because the category itself has been fetched, doesn't mean its child folders have.
-		/*
-		  if (!gInventory.isCategoryComplete(cat_id))
-		*/
-		{
-			LLInventoryModelBackgroundFetch::instance().start(cat_id);
-		}
-
-		// Apply filter substring because it might have been changed
-		// while accordion was closed. See EXT-3714.
-		filter_list(inventory_list, sFilterSubString);
-	}
-}
-
-void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory_list)
-{
-	if (inventory_list != mFavoritesInventoryPanel)
-	{
-		mFavoritesInventoryPanel->clearSelection();
-	}
-
-	if (inventory_list != mLandmarksInventoryPanel)
-	{
-		mLandmarksInventoryPanel->clearSelection();
-	}
-	if (inventory_list != mMyInventoryPanel)
-	{
-		mMyInventoryPanel->clearSelection();
-	}
-	if (inventory_list != mLibraryInventoryPanel)
-	{
-		mLibraryInventoryPanel->clearSelection();
-	}
-}
 
 // List Commands Handlers
 void LLLandmarksPanel::initListCommandsHandlers()
 {
-	mListCommands = getChild<LLPanel>("bottom_panel");
-
-	mGearButton = getChild<LLMenuButton>(OPTIONS_BUTTON_NAME);
-	mGearButton->setMouseDownCallback(boost::bind(&LLLandmarksPanel::onActionsButtonClick, this));
-
-	mListCommands->childSetAction(TRASH_BUTTON_NAME, boost::bind(&LLLandmarksPanel::onTrashButtonClick, this));
-
-	LLDragAndDropButton* trash_btn = mListCommands->getChild<LLDragAndDropButton>(TRASH_BUTTON_NAME);
-	trash_btn->setDragAndDropHandler(boost::bind(&LLLandmarksPanel::handleDragAndDropToTrash, this
-			,	_4 // BOOL drop
-			,	_5 // EDragAndDropType cargo_type
-			,	_6 // void* cargo_data
-			,	_7 // EAcceptance* accept
-			));
-
 	mCommitCallbackRegistrar.add("Places.LandmarksGear.Add.Action", boost::bind(&LLLandmarksPanel::onAddAction, this, _2));
 	mCommitCallbackRegistrar.add("Places.LandmarksGear.CopyPaste.Action", boost::bind(&LLLandmarksPanel::onClipboardAction, this, _2));
 	mCommitCallbackRegistrar.add("Places.LandmarksGear.Custom.Action", boost::bind(&LLLandmarksPanel::onCustomAction, this, _2));
@@ -706,23 +462,16 @@ void LLLandmarksPanel::initListCommandsHandlers()
 	mEnableCallbackRegistrar.add("Places.LandmarksGear.Enable", boost::bind(&LLLandmarksPanel::isActionEnabled, this, _2));
 	mGearLandmarkMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_landmark.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 	mGearFolderMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_folder.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	mMenuAdd = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	mSortingMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_places_gear_sorting.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	mAddMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_place_add_button.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 
 	mGearLandmarkMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2));
 	mGearFolderMenu->setVisibilityChangeCallback(boost::bind(&LLLandmarksPanel::onMenuVisibilityChange, this, _1, _2));
 
-	mListCommands->childSetAction(ADD_BUTTON_NAME, boost::bind(&LLLandmarksPanel::showActionMenu, this, mMenuAdd, ADD_BUTTON_NAME));
-}
-
-
-void LLLandmarksPanel::updateListCommands()
-{
-	bool add_folder_enabled = isActionEnabled("category");
-	bool trash_enabled = isActionEnabled("delete") && (isFolderSelected() || isLandmarkSelected());
-
-	// keep Options & Add Landmark buttons always enabled
-	mListCommands->getChildView(ADD_FOLDER_BUTTON_NAME)->setEnabled(add_folder_enabled);
-	mListCommands->getChildView(TRASH_BUTTON_NAME)->setEnabled(trash_enabled);
+	// show menus even if all items are disabled
+	mGearLandmarkMenu->setAlwaysShowMenu(TRUE);
+	mGearFolderMenu->setAlwaysShowMenu(TRUE);
+	mAddMenu->setAlwaysShowMenu(TRUE);
 }
 
 void LLLandmarksPanel::updateMenuVisibility(LLUICtrl* menu)
@@ -730,43 +479,6 @@ void LLLandmarksPanel::updateMenuVisibility(LLUICtrl* menu)
 	onMenuVisibilityChange(menu, LLSD().with("visibility", true));
 }
 
-void LLLandmarksPanel::onActionsButtonClick()
-{
-	LLToggleableMenu* menu = mGearFolderMenu;
-
-	if(mCurrentSelectedList)
-	{
-		LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem();
-		if(!listenerp)
-			return;
-
-		if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
-		{
-			menu = mGearLandmarkMenu;
-		}
-	}
-
-	mGearButton->setMenu(menu);
-}
-
-void LLLandmarksPanel::showActionMenu(LLMenuGL* menu, std::string spawning_view_name)
-{
-	if (menu)
-	{
-		menu->buildDrawLabels();
-		menu->updateParent(LLMenuGL::sMenuContainer);
-		menu->arrangeAndClear();
-
-		LLView* spawning_view = getChild<LLView>(spawning_view_name);
-
-		S32 menu_x, menu_y;
-		//show menu in co-ordinates of panel
-		spawning_view->localPointToOtherView(0, spawning_view->getRect().getHeight(), &menu_x, &menu_y, this);
-		menu_y += menu->getRect().getHeight();
-		LLMenuGL::showPopup(this, menu, menu_x, menu_y);
-	}
-}
-
 void LLLandmarksPanel::onTrashButtonClick() const
 {
 	onClipboardAction("delete");
@@ -778,7 +490,8 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 	LLFolderViewItem* item = getCurSelectedItem();
 
 	std::string command_name = userdata.asString();
-	if("add_landmark" == command_name)
+	if("add_landmark" == command_name
+        || "add_landmark_root" == command_name)
 	{
 // [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5
 		if (!gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
@@ -791,7 +504,20 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 			}
 			else
 			{
-				LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
+            LLSD args;
+            args["type"] = "create_landmark";
+            if ("add_landmark" == command_name
+                && view_model->getInventoryType() == LLInventoryType::IT_CATEGORY)
+            {
+                args["dest_folder"] = view_model->getUUID();
+            }
+            if ("add_landmark_root" == command_name
+                && mCurrentSelectedList == mLandmarksInventoryPanel)
+            {
+                args["dest_folder"] = mLandmarksInventoryPanel->getRootFolderID();
+            }
+            // else will end up in favorites
+			LLFloaterReg::showInstance("add_landmark", args);
 			}
 // [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5
 		}
@@ -826,13 +552,14 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 			//in case My Landmarks tab is completely empty (thus cannot be determined as being selected)
 			menu_create_inventory_item(mLandmarksInventoryPanel, NULL,  LLSD("category"), 
 				gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
-
-			if (mMyLandmarksAccordionTab)
-			{
-				mMyLandmarksAccordionTab->changeOpenClose(false);
-			}
 		}
 	}
+    else if ("category_root" == command_name)
+    {
+        //in case My Landmarks tab is completely empty (thus cannot be determined as being selected)
+        menu_create_inventory_item(mLandmarksInventoryPanel, NULL, LLSD("category"),
+            gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
+    }
 }
 
 void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
@@ -866,27 +593,11 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
 
 	if ("expand_all" == command_name)
 	{
-		expand_all_folders(mFavoritesInventoryPanel->getRootFolder());
-		expand_all_folders(mLandmarksInventoryPanel->getRootFolder());
-		expand_all_folders(mMyInventoryPanel->getRootFolder());
-		expand_all_folders(mLibraryInventoryPanel->getRootFolder());
-
-		for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
-		{
-			(*iter)->changeOpenClose(false);
-		}
+		expand_all_folders(mCurrentSelectedList->getRootFolder());
 	}
 	else if ("collapse_all" == command_name)
 	{
-		collapse_all_folders(mFavoritesInventoryPanel->getRootFolder());
-		collapse_all_folders(mLandmarksInventoryPanel->getRootFolder());
-		collapse_all_folders(mMyInventoryPanel->getRootFolder());
-		collapse_all_folders(mLibraryInventoryPanel->getRootFolder());
-
-		for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
-		{
-			(*iter)->changeOpenClose(true);
-		}
+		collapse_all_folders(mCurrentSelectedList->getRootFolder());
 	}
 	else if ("sort_by_date" == command_name)
 	{
@@ -894,8 +605,6 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
 		sorting_order=!sorting_order;
 		gSavedSettings.setBOOL("LandmarksSortedByDate",sorting_order);
 		updateSortOrder(mLandmarksInventoryPanel, sorting_order);
-		updateSortOrder(mMyInventoryPanel, sorting_order);
-		updateSortOrder(mLibraryInventoryPanel, sorting_order);
 	}
 	else
 	{
@@ -927,51 +636,21 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 		? mCurrentSelectedList->getRootFolder() 
 		: NULL;
 
+	bool is_single_selection = root_folder_view && root_folder_view->getSelectedCount() == 1;
+
 	if ("collapse_all" == command_name)
 	{
-		bool disable_collapse_all =	!has_expanded_folders(mFavoritesInventoryPanel->getRootFolder())
-									&& !has_expanded_folders(mLandmarksInventoryPanel->getRootFolder())
-									&& !has_expanded_folders(mMyInventoryPanel->getRootFolder())
-									&& !has_expanded_folders(mLibraryInventoryPanel->getRootFolder());
-		if (disable_collapse_all)
-		{
-			for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
-			{
-				if ((*iter)->isExpanded())
-				{
-					disable_collapse_all = false;
-					break;
-				}
-			}
-		}
-
-		return !disable_collapse_all;
+		return has_expanded_folders(mCurrentSelectedList->getRootFolder());
 	}
 	else if ("expand_all" == command_name)
 	{
-		bool disable_expand_all = !has_collapsed_folders(mFavoritesInventoryPanel->getRootFolder())
-								  && !has_collapsed_folders(mLandmarksInventoryPanel->getRootFolder())
-								  && !has_collapsed_folders(mMyInventoryPanel->getRootFolder())
-								  && !has_collapsed_folders(mLibraryInventoryPanel->getRootFolder());
-		if (disable_expand_all)
-		{
-			for (accordion_tabs_t::const_iterator iter = mAccordionTabs.begin(); iter != mAccordionTabs.end(); ++iter)
-			{
-				if (!(*iter)->isExpanded())
-				{
-					disable_expand_all = false;
-					break;
-				}
-			}
-		}
-
-		return !disable_expand_all;
+		return has_collapsed_folders(mCurrentSelectedList->getRootFolder());
 	}
 	else if ("sort_by_date"	== command_name)
 	{
-		// disable "sort_by_date" for Favorites accordion because
+		// disable "sort_by_date" for Favorites tab because
 		// it has its own items order. EXT-1758
-		if (mCurrentSelectedList == mFavoritesInventoryPanel)
+		if (!isLandmarksPanel)
 		{
 			return false;
 		}
@@ -988,6 +667,11 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 
 		std::set<LLFolderViewItem*> selected_uuids =    root_folder_view->getSelectionList();
 
+		if (selected_uuids.empty())
+		{
+			return false;
+		}
+		
 		// Allow to execute the command only if it can be applied to all selected items.
 		for (std::set<LLFolderViewItem*>::const_iterator iter =    selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
 		{
@@ -1008,7 +692,6 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 			)
 	{
 		// disable some commands for multi-selection. EXT-1757
-		bool is_single_selection = root_folder_view && root_folder_view->getSelectedCount() == 1;
 		if (!is_single_selection)
 		{
 			return false;
@@ -1027,9 +710,9 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 
 			// Disable "Show on Map" if landmark loading is in progress.
 			return !gLandmarkList.isAssetInLoadedCallbackMap(asset_uuid);
-	}
-	else if ("rename" == command_name)
-	{
+		}
+		else if ("rename" == command_name)
+		{
 			LLFolderViewItem* selected_item = getCurSelectedItem();
 			if (!selected_item) return false;
 
@@ -1038,16 +721,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 
 		return true;
 	}
-	else if("category" == command_name)
-	{
-		// we can add folder only in Landmarks Accordion
-		if (mCurrentSelectedList == mLandmarksInventoryPanel)
-		{
-			// ... but except Received folder
-			return !isReceivedFolderSelected();
-		}
-		//"Add a folder" is enabled by default (case when My Landmarks is empty)
-		else return true;
+    if ("category_root" == command_name || "category" == command_name)
+    {
+		// we can add folder only in Landmarks tab
+		return isLandmarksPanel;
 	}
 	else if("create_pick" == command_name)
 	{
@@ -1061,12 +738,92 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 		}
 		return false;
 	}
+    else if ("add_landmark" == command_name)
+    {
 // [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5
-	else if("add_landmark" == command_name)
+	if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
 	{
-		return !gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC);
+		return false;
+	}
+// [/RLVa:KB]
+
+        if (!is_single_selection)
+        {
+            return false;
+        }
+
+        LLFolderViewModelItemInventory* view_model = getCurSelectedViewModelItem();
+        if (!view_model || view_model->getInventoryType() != LLInventoryType::IT_CATEGORY)
+        {
+            return false;
+        }
+        LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();
+        if (landmark)
+        {
+            //already exists
+            return false;
+        }
+        return true;
+    }
+    else if ("add_landmark_root" == command_name)
+    {
+// [RLVa:KB] - Checked: 2012-02-08 (RLVa-1.4.5) | Added: RLVa-1.4.5
+	if (gRlvHandler.hasBehaviour(RLV_BHVR_SHOWLOC))
+	{
+		return false;
 	}
 // [/RLVa:KB]
+
+        LLViewerInventoryItem* landmark = LLLandmarkActions::findLandmarkForAgentPos();
+        if (landmark)
+        {
+            //already exists
+            return false;
+        }
+        return true;
+    }
+    else if ("share" == command_name)
+    {
+        if (!mCurrentSelectedList)
+        {
+            return false;
+        }
+        if (!LLAvatarActions::canShareSelectedItems(mCurrentSelectedList))
+        {
+            return false;
+        }
+        return true;
+    }
+	else if (command_name == "move_to_landmarks" || command_name == "move_to_favorites")
+	{
+		LLFolderViewModelItemInventory* cur_item_model = getCurSelectedViewModelItem();
+		if (cur_item_model)
+		{
+			LLFolderType::EType folder_type = command_name == "move_to_landmarks" ? LLFolderType::FT_FAVORITE : LLFolderType::FT_LANDMARK;
+			if (!gInventory.isObjectDescendentOf(cur_item_model->getUUID(), gInventory.findCategoryUUIDForType(folder_type)))
+			{
+				return false;
+			}
+
+			if (root_folder_view)
+			{
+				std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList();
+				for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+				{
+					LLFolderViewItem* item = *iter;
+					if (!item) return false;
+
+					cur_item_model = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
+					if (!cur_item_model || cur_item_model->getInventoryType() != LLInventoryType::IT_LANDMARK)
+					{
+						return false;
+					}
+				}
+				return true;
+			}
+		}
+		return false;
+	}
 	else
 	{
 		LL_WARNS() << "Unprocessed command has come: " << command_name << LL_ENDL;
@@ -1092,12 +849,42 @@ void LLLandmarksPanel::onCustomAction(const LLSD& userdata)
 	}
 	else if ("create_pick" == command_name)
 	{
-		doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doCreatePick, this, _1));
+        LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
+        if (cur_item)
+        {
+            doActionOnCurSelectedLandmark(boost::bind(&LLLandmarksPanel::doCreatePick, this, _1, cur_item->getUUID()));
+        }
 	}
+    else if ("share" == command_name && mCurrentSelectedList)
+    {
+        LLAvatarActions::shareWithAvatars(mCurrentSelectedList);
+    }
 	else if ("restore" == command_name && mCurrentSelectedList)
 	{
 		mCurrentSelectedList->doToSelected(userdata);
 	}
+	else if (command_name == "move_to_landmarks" || command_name == "move_to_favorites")
+	{
+		LLFolderView* root_folder_view = mCurrentSelectedList ? mCurrentSelectedList->getRootFolder() : NULL;
+		if (root_folder_view)
+		{
+			LLFolderType::EType folder_type = command_name == "move_to_landmarks" ? LLFolderType::FT_LANDMARK : LLFolderType::FT_FAVORITE;
+			std::set<LLFolderViewItem*> selected_uuids = root_folder_view->getSelectionList();
+			for (std::set<LLFolderViewItem*>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+			{
+				LLFolderViewItem* item = *iter;
+				if (item)
+				{
+					LLFolderViewModelItemInventory* item_model = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
+					if (item_model)
+					{
+						change_item_parent(item_model->getUUID(), gInventory.findCategoryUUIDForType(folder_type));
+					}
+				}
+			}
+		}
+
+	}
 }
 
 void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param)
@@ -1164,29 +951,17 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
 
 	if (!item) return false;
 
-	// nothing can be modified in Library
-	if (mLibraryInventoryPanel == mCurrentSelectedList) return false;
-
 	bool can_be_modified = false;
 
 	// landmarks can be modified in any other accordion...
 	if (static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem())->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		can_be_modified = true;
-
-		// we can modify landmarks anywhere except paste to My Inventory
-		if ("paste" == command_name)
-		{
-			can_be_modified = (mCurrentSelectedList != mMyInventoryPanel);
-		}
 	}
 	else
 	{
 		// ...folders only in the Landmarks accordion...
-		can_be_modified = mLandmarksInventoryPanel == mCurrentSelectedList;
-
-		// ...except "Received" folder
-		can_be_modified &= !isReceivedFolderSelected();
+		can_be_modified = isLandmarksPanel;
 	}
 
 	// then ask LLFolderView permissions
@@ -1303,12 +1078,10 @@ void LLLandmarksPanel::doShowOnMap(LLLandmark* landmark)
 		LLFloaterReg::showInstance("world_map", "center");
 	}
 
-	mShowOnMapBtn->setEnabled(TRUE);
 	mGearLandmarkMenu->setItemEnabled("show_on_map", TRUE);
 }
 
 void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
-										   LLFolderViewItem* cur_item,
 										   LLInventoryItem* inv_item,
 										   const LLParcelData& parcel_data)
 {
@@ -1337,7 +1110,7 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
 
 	LLPickData data;
 	data.pos_global = landmark_global_pos;
-	data.name = cur_item->getName();
+	data.name = inv_item->getName();
 	data.desc = inv_item->getDescription();
 	data.snapshot_id = parcel_data.snapshot_id;
 	data.parcel_id = parcel_data.parcel_id;
@@ -1357,11 +1130,13 @@ void LLLandmarksPanel::doProcessParcelInfo(LLLandmark* landmark,
 					panel_pick, panel_places,params));
 }
 
-void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)
+void LLLandmarksPanel::doCreatePick(LLLandmark* landmark, const LLUUID &item_id)
 {
 	LLViewerRegion* region = gAgent.getRegion();
 	if (!region) return;
 
+    mCreatePickItemId = item_id;
+
 	LLGlobalVec pos_global;
 	LLUUID region_id;
 	landmark->getGlobalPos(pos_global);
@@ -1414,27 +1189,12 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin
 	inventory_list->setFilterSubString(string);
 }
 
-static bool category_has_descendents(LLPlacesInventoryPanel* inventory_list)
-{
-	LLViewerInventoryCategory* category = gInventory.getCategory(inventory_list->getRootFolderID());
-	if (category)
-	{
-		return category->getDescendentCount() > 0;
-	}
-
-	return false;
-}
-
 static void collapse_all_folders(LLFolderView* root_folder)
 {
 	if (!root_folder)
 		return;
 
 	root_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
-
-	// The top level folder is invisible, it must be open to
-	// display its sub-folders.
-	root_folder->openTopLevelFolders();
 	root_folder->arrangeAll();
 }
 
@@ -1501,4 +1261,31 @@ void toggle_restore_menu(LLMenuGL *menu, BOOL visible, BOOL enabled)
 		}
 	}
 }
+
+LLFavoritesPanel::LLFavoritesPanel()
+	:	LLLandmarksPanel(false)
+{
+	buildFromFile("panel_favorites.xml");
+}
+
+BOOL LLFavoritesPanel::postBuild()
+{
+	if (!gInventory.isInventoryUsable())
+		return FALSE;
+
+	// mast be called before any other initXXX methods to init Gear menu
+	LLLandmarksPanel::initListCommandsHandlers();
+
+	initFavoritesInventoryPanel();
+
+	return TRUE;
+}
+
+void LLFavoritesPanel::initFavoritesInventoryPanel()
+{
+	mCurrentSelectedList = getChild<LLPlacesInventoryPanel>("favorites_list");
+
+	LLLandmarksPanel::initLandmarksPanel(mCurrentSelectedList);
+	mCurrentSelectedList->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems");
+}
 // EOF
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index c11cbe05ae655a9599a7157603fbeb85da2a5823..d7408269b5dfb6728dfb928bbb058e26da9031e8 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -50,81 +50,69 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
 {
 public:
 	LLLandmarksPanel();
+	LLLandmarksPanel(bool is_landmark_panel);
 	virtual ~LLLandmarksPanel();
 
-	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void onSearchEdit(const std::string& string);
-	/*virtual*/ void onShowOnMap();
-	/*virtual*/ void onShowProfile();
-	/*virtual*/ void onTeleport();
-	/*virtual*/ void updateVerbs();
-	/*virtual*/ bool isSingleItemSelected();
+	BOOL postBuild() override;
+	void onSearchEdit(const std::string& string) override;
+	void onShowOnMap() override;
+	void onShowProfile() override;
+	void onTeleport() override;
+	void onRemoveSelected() override;
+	void updateVerbs() override;
+	bool isSingleItemSelected() override;
+
+    LLToggleableMenu* getSelectionMenu() override;
+    LLToggleableMenu* getSortingMenu() override;
+    LLToggleableMenu* getCreateMenu() override;
+
+    /**
+     * Processes drag-n-drop of the Landmarks and folders into trash button.
+     */
+    bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) override;
 
-	void onSelectionChange(LLPlacesInventoryPanel* inventory_list, const std::deque<LLFolderViewItem*> &items, BOOL user_action);
-	void onSelectorButtonClicked();
 	void setCurrentSelectedList(LLPlacesInventoryPanel* inventory_list)
 	{
 		mCurrentSelectedList = inventory_list;
 	}
 
-	/**
-	 * 	Update filter ShowFolderState setting to show empty folder message
-	 *  if Landmarks inventory folder is empty.
-	 */
-	void updateShowFolderState();
-
 	/**
 	 * Selects item with "obj_id" in one of accordion tabs.
 	 */
 	void setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_focus);
 
-	LLPlacesInventoryPanel* getLibraryInventoryPanel() { return mLibraryInventoryPanel; }
-
 	void updateMenuVisibility(LLUICtrl* menu);
 
+	void doCreatePick(LLLandmark* landmark, const LLUUID &item_id );
+
+	void resetSelection();
+
 protected:
 	/**
 	 * @return true - if current selected panel is not null and selected item is a landmark
 	 */
 	bool isLandmarkSelected() const;
 	bool isFolderSelected() const;
-	bool isReceivedFolderSelected() const;
 	void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
 	LLFolderViewItem* getCurSelectedItem() const;
 	LLFolderViewModelItemInventory* getCurSelectedViewModelItem() const;
 
-	/**
-	 * Selects item with "obj_id" in "inventory_list" and scrolls accordion
-	 * scrollbar to show the item.
-	 * Returns pointer to the item if it is found in "inventory_list", otherwise NULL.
-	 */
-	LLFolderViewItem* selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
-											   const std::string& tab_name,
-											   const LLUUID& obj_id,
-											   BOOL take_keyboard_focus) const;
-
 	void updateSortOrder(LLInventoryPanel* panel, bool byDate);
 
 	//LLRemoteParcelInfoObserver interface
-	/*virtual*/ void processParcelInfo(const LLParcelData& parcel_data);
-	/*virtual*/ void setParcelID(const LLUUID& parcel_id);
-	/*virtual*/ void setErrorStatus(S32 status, const std::string& reason);
+	void processParcelInfo(const LLParcelData& parcel_data) override;
+	void setParcelID(const LLUUID& parcel_id) override;
+	void setErrorStatus(S32 status, const std::string& reason) override;
+
+	// List Commands Handlers
+	void initListCommandsHandlers();
+	void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list);
+
+	LLPlacesInventoryPanel*		mCurrentSelectedList;
 	
 private:
-	void initFavoritesInventoryPanel();
 	void initLandmarksInventoryPanel();
-	void initMyInventoryPanel();
-	void initLibraryInventoryPanel();
-	void initLandmarksPanel(LLPlacesInventoryPanel* inventory_list);
-	LLAccordionCtrlTab* initAccordion(const std::string& accordion_tab_name, LLPlacesInventoryPanel* inventory_list, bool expand_tab);
-	void onAccordionExpandedCollapsed(const LLSD& param, LLPlacesInventoryPanel* inventory_list);
-	void deselectOtherThan(const LLPlacesInventoryPanel* inventory_list);
 
-	// List Commands Handlers
-	void initListCommandsHandlers();
-	void updateListCommands();
-	void onActionsButtonClick();
-	void showActionMenu(LLMenuGL* menu, std::string spawning_view_name);
 	void onTrashButtonClick() const;
 	void onAddAction(const LLSD& command_name) const;
 	void onClipboardAction(const LLSD& command_name) const;
@@ -150,39 +138,34 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
 	bool canItemBeModified(const std::string& command_name, LLFolderViewItem* item) const;
 	void onPickPanelExit( LLPanelPickEdit* pick_panel, LLView* owner, const LLSD& params);
 
-	/**
-	 * Processes drag-n-drop of the Landmarks and folders into trash button.
-	 */
-	bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept);
-
 	/**
 	 * Landmark actions callbacks. Fire when a landmark is loaded from the list.
 	 */
 	void doShowOnMap(LLLandmark* landmark);
 	void doProcessParcelInfo(LLLandmark* landmark,
-							 LLFolderViewItem* cur_item,
 							 LLInventoryItem* inv_item,
 							 const LLParcelData& parcel_data);
-	void doCreatePick(LLLandmark* landmark);
 
 private:
-	LLPlacesInventoryPanel*		mFavoritesInventoryPanel;
 	LLPlacesInventoryPanel*		mLandmarksInventoryPanel;
-	LLPlacesInventoryPanel*		mMyInventoryPanel;
-	LLPlacesInventoryPanel*		mLibraryInventoryPanel;
-	LLMenuButton*				mGearButton;
 	LLToggleableMenu*			mGearLandmarkMenu;
 	LLToggleableMenu*			mGearFolderMenu;
-	LLMenuGL*					mMenuAdd;
-	LLPlacesInventoryPanel*		mCurrentSelectedList;
-	LLInventoryObserver*		mInventoryObserver;
+	LLToggleableMenu*			mSortingMenu;
+	LLToggleableMenu*			mAddMenu;
 
-	LLPanel*					mListCommands;
+	bool						isLandmarksPanel;
 	
-	typedef	std::vector<LLAccordionCtrlTab*> accordion_tabs_t;
-	accordion_tabs_t			mAccordionTabs;
+    LLUUID                      mCreatePickItemId; // item we requested a pick for
+};
 
-	LLAccordionCtrlTab*			mMyLandmarksAccordionTab;
+
+class LLFavoritesPanel : public LLLandmarksPanel
+{
+public:
+	LLFavoritesPanel();
+
+	BOOL postBuild() override;
+	void initFavoritesInventoryPanel();
 };
 
 #endif //LL_LLPANELLANDMARKS_H
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 4f607034885e6d7e343c73ccf32197b4194215af..3964dc075ca6b046e43d722e9d59884a51591090 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -544,6 +544,16 @@ void LLPanelLogin::show(const LLRect &rect,
 	gFocusMgr.setDefaultKeyboardFocus(sInstance);
 }
 
+//static
+void LLPanelLogin::reshapePanel()
+{
+    if (sInstance)
+    {
+        LLRect rect = sInstance->getRect();
+        sInstance->reshape(rect.getWidth(), rect.getHeight());
+    }
+}
+
 //static
 void LLPanelLogin::populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd)
 {
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index c9b8e1b6fcfdc4bc3ac2344f5eb39e0df7fb9198..788c269ffd98a22b7ffcd9e647e14cd76593a542 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -54,6 +54,7 @@ class LLPanelLogin:
 	static void show(const LLRect &rect,
 		void (*callback)(S32 option, void* user_data), 
 		void* callback_data);
+	static void reshapePanel();
 
 	static void populateFields(LLPointer<LLCredential> credential, bool remember_user, bool remember_psswrd);
 	static void resetFields();
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index fbc1b80857caa912a3a26254a90229578288d9bf..e9c9c451a2456ae26f39ea386ff7614495536431 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -115,6 +115,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
 	  mSavedFolderState(NULL),
 	  mFilterText(""),
 	  mMenuGearDefault(NULL),
+	  mMenuVisibility(NULL),
 	  mMenuAddHandle(),
 	  mNeedUploadCost(true)
 {
@@ -219,6 +220,17 @@ BOOL LLPanelMainInventory::postBuild()
 				recent_items_panel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::RECENTITEMS_SORT_ORDER));
 			}
 		}
+		if(mActivePanel)
+		{
+			if(savedFilterState.has(mActivePanel->getFilter().getName()))
+			{
+				LLSD items = savedFilterState.get(mActivePanel->getFilter().getName());
+				LLInventoryFilter::Params p;
+				LLParamSDParser parser;
+				parser.readSD(items, p);
+				mActivePanel->getFilter().setSearchVisibilityTypes(p);
+			}
+		}
 
 	}
 
@@ -229,6 +241,7 @@ BOOL LLPanelMainInventory::postBuild()
 	}
 
 	mGearMenuButton = getChild<LLMenuButton>("options_gear_btn");
+	mVisibilityMenuButton = getChild<LLMenuButton>("options_visibility_btn");
 
 	initListCommandsHandlers();
 
@@ -254,6 +267,9 @@ BOOL LLPanelMainInventory::postBuild()
 LLPanelMainInventory::~LLPanelMainInventory( void )
 {
 	// Save the filters state.
+	// Some params types cannot be saved this way
+	// for example, LLParamSDParser doesn't know about U64,
+	// so some FilterOps params should be revised.
 	LLSD filterRoot;
 	LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
 	if (all_items_panel)
@@ -1165,6 +1181,10 @@ void LLPanelMainInventory::initListCommandsHandlers()
 	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory_add.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 	mMenuAddHandle = menu->getHandle();
 
+	mMenuVisibility = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_search_visibility.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	mVisibilityMenuButton->setMenu(mMenuVisibility);
+	mVisibilityMenuButton->setMenuPosition(LLMenuButton::MP_BOTTOM_LEFT);
+
 	// Update the trash button when selected item(s) get worn or taken off.
 	LLOutfitObserver::instance().addCOFChangedCallback(boost::bind(&LLPanelMainInventory::updateListCommands, this));
 }
@@ -1354,6 +1374,21 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		}
 		LLFloaterReg::showInstance("linkreplace", params);
 	}
+
+	if (command_name == "toggle_search_trash")
+	{
+		mActivePanel->getFilter().toggleSearchVisibilityTrash();
+	}
+
+	if (command_name == "toggle_search_library")
+	{
+		mActivePanel->getFilter().toggleSearchVisibilityLibrary();
+	}
+
+	if (command_name == "include_links")
+	{
+		mActivePanel->getFilter().toggleSearchVisibilityLinks();
+	}		
 }
 
 void LLPanelMainInventory::onVisibilityChange( BOOL new_visibility )
@@ -1499,6 +1534,21 @@ BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata)
 		return sort_order_mask & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
 	}
 
+	if (command_name == "toggle_search_trash")
+	{
+		return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_TRASH) != 0;
+	}
+
+	if (command_name == "toggle_search_library")
+	{
+		return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LIBRARY) != 0;
+	}
+
+	if (command_name == "include_links")
+	{
+		return (mActivePanel->getFilter().getSearchVisibilityTypes() & LLInventoryFilter::VISIBILITY_LINKS) != 0;	
+	}	
+
 	return FALSE;
 }
 
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index a6bdee233d5f23eac700757a3a824ccf4a8ac139..dfb8db9d122f8eb4d4b51f58f30b2978caecb3ab 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -93,6 +93,8 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver
 
 	void toggleFindOptions();
 
+    void resetFilters();
+
 protected:
 	//
 	// Misc functions
@@ -117,7 +119,6 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver
 	void doToSelected(const LLSD& userdata);
 	void closeAllFolders();
 	void doCreate(const LLSD& userdata);
-	void resetFilters();
 	void setSortBy(const LLSD& userdata);
 	void saveTexture(const LLSD& userdata);
 	bool isSaveTextureEnabled(const LLSD& userdata);
@@ -169,7 +170,9 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver
 private:
 	LLDragAndDropButton*		mTrashButton;
 	LLToggleableMenu*			mMenuGearDefault;
+	LLToggleableMenu*			mMenuVisibility;
 	LLMenuButton*				mGearMenuButton;
+	LLMenuButton*				mVisibilityMenuButton;
 	LLHandle<LLView>			mMenuAddHandle;
 
 	bool						mNeedUploadCost;
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 19a06ca4b42238598596b360800fe3ed4be4ae9d..159d8c7be7e3f18a58a31d00aff5ef45a54a8314 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -58,7 +58,6 @@
 #include "llmenubutton.h"
 #include "llpaneloutfitsinventory.h"
 #include "lluiconstants.h"
-#include "llsaveoutfitcombobtn.h"
 #include "llscrolllistctrl.h"
 #include "lltextbox.h"
 #include "lltoggleablemenu.h"
@@ -83,6 +82,8 @@ const U64 ATTACHMENT_MASK = (1LL << LLInventoryType::IT_ATTACHMENT) | (1LL << LL
 const U64 ALL_ITEMS_MASK = WEARABLE_MASK | ATTACHMENT_MASK;
 
 static const std::string REVERT_BTN("revert_btn");
+static const std::string SAVE_AS_BTN("save_as_btn");
+static const std::string SAVE_BTN("save_btn");
 
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -565,7 +566,8 @@ BOOL LLPanelOutfitEdit::postBuild()
 	mGearMenu = LLPanelOutfitEditGearMenu::create();
 	mGearMenuBtn->setMenu(mGearMenu);
 
-	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this));
+	getChild<LLButton>(SAVE_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitEdit::saveOutfit, this, false));
+	getChild<LLButton>(SAVE_AS_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitEdit::saveOutfit, this, true));
 
 	onOutfitChanging(gAgentWearables.isCOFChangeInProgress());
 	return TRUE;
@@ -1246,11 +1248,9 @@ void LLPanelOutfitEdit::updateVerbs()
 	bool outfit_locked = LLAppearanceMgr::getInstance()->isOutfitLocked();
 	bool has_baseoutfit = LLAppearanceMgr::getInstance()->getBaseOutfitUUID().notNull();
 
-	mSaveComboBtn->setSaveBtnEnabled(!outfit_locked && outfit_is_dirty);
+	getChildView(SAVE_BTN)->setEnabled(!outfit_locked && outfit_is_dirty);
 	getChildView(REVERT_BTN)->setEnabled(outfit_is_dirty && has_baseoutfit);
 
-	mSaveComboBtn->setMenuItemEnabled("save_outfit", !outfit_locked && outfit_is_dirty);
-
 	mStatus->setText(outfit_is_dirty ? getString("unsaved_changes") : getString("now_editing"));
 
 	updateCurrentOutfitName();
@@ -1436,4 +1436,13 @@ void LLPanelOutfitEdit::saveListSelection()
 	}
 }
 
+void LLPanelOutfitEdit::saveOutfit(bool as_new)
+{
+	LLPanelOutfitsInventory* panel_outfits_inventory = LLPanelOutfitsInventory::findInstance();
+	if (panel_outfits_inventory)
+	{
+		panel_outfits_inventory->saveOutfit(as_new);
+	} 	
+}
+
 // EOF
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 034e1a0dacb55699777d145ea6a00a235e937705..d0597fb72bbea41c1a535385c218a327ddf11ebf 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -58,7 +58,6 @@ class LLMenuButton;
 class LLMenuGL;
 class LLFindNonLinksByMask;
 class LLFindWearablesOfType;
-class LLSaveOutfitComboBtn;
 class LLWearableItemTypeNameComparator;
 
 class LLPanelOutfitEdit : public LLPanel
@@ -195,6 +194,7 @@ class LLPanelOutfitEdit : public LLPanel
 	void getSelectedItemsUUID(uuid_vec_t& uuid_list);
 	void getCurrentItemUUID(LLUUID& selected_id);
 	void onCOFChanged();
+	void saveOutfit(bool as_new = false);
 
 	/**
 	 * Method preserves selection while switching between folder/list view modes
@@ -237,10 +237,6 @@ class LLPanelOutfitEdit : public LLPanel
 	LLToggleableMenu*	mGearMenu;
 	LLToggleableMenu*	mAddWearablesGearMenu;
 	bool				mInitialized;
-// [SL:KB] - Patch: Viewer-Build | Checked: Catznip-6.6
-	std::unique_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;
-// [/SL:KB]
-//	std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;
 	LLMenuButton*		mWearablesGearMenuBtn;
 	LLMenuButton*		mGearMenuBtn;
 
diff --git a/indra/newview/llpaneloutfitsinventory.cpp b/indra/newview/llpaneloutfitsinventory.cpp
index 8fff52ca4e0109466aacdb76a53d8c76a0b761e4..531073526bb0c9a5fd8517f74486a5648a0d768a 100644
--- a/indra/newview/llpaneloutfitsinventory.cpp
+++ b/indra/newview/llpaneloutfitsinventory.cpp
@@ -40,7 +40,6 @@
 #include "lloutfitgallery.h"
 #include "lloutfitslist.h"
 #include "llpanelwearing.h"
-#include "llsaveoutfitcombobtn.h"
 #include "llsidepanelappearance.h"
 #include "llviewercontrol.h"
 #include "llviewerfoldertype.h"
@@ -49,6 +48,9 @@ static const std::string OUTFITS_TAB_NAME = "outfitslist_tab";
 static const std::string OUTFIT_GALLERY_TAB_NAME = "outfit_gallery_tab";
 static const std::string COF_TAB_NAME = "cof_tab";
 
+static const std::string SAVE_AS_BTN("save_as_btn");
+static const std::string SAVE_BTN("save_btn");
+
 static LLPanelInjector<LLPanelOutfitsInventory> t_inventory("panel_outfits_inventory");
 
 LLPanelOutfitsInventory::LLPanelOutfitsInventory() :
@@ -90,8 +92,9 @@ BOOL LLPanelOutfitsInventory::postBuild()
 	{
 		LLInventoryModelBackgroundFetch::instance().start(outfits_cat);
 	}
-	
-	mSaveComboBtn.reset(new LLSaveOutfitComboBtn(this, true));
+
+	getChild<LLButton>(SAVE_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, false));
+	getChild<LLButton>(SAVE_AS_BTN)->setCommitCallback(boost::bind(&LLPanelOutfitsInventory::saveOutfit, this, true));
 
 	return TRUE;
 }
@@ -246,6 +249,12 @@ LLPanelOutfitsInventory* LLPanelOutfitsInventory::findInstance()
 	return dynamic_cast<LLPanelOutfitsInventory*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfits_inventory"));
 }
 
+void LLPanelOutfitsInventory::openApearanceTab(const std::string& tab_name)
+{
+    if (!mAppearanceTabs) return;
+    mAppearanceTabs->selectTabByName(tab_name);
+}
+
 //////////////////////////////////////////////////////////////////////////////////
 // List Commands                                                                //
 
@@ -269,7 +278,7 @@ void LLPanelOutfitsInventory::updateListCommands()
 	mOutfitGalleryPanel->childSetEnabled("trash_btn", trash_enabled);
 	wear_btn->setEnabled(wear_enabled);
 	wear_btn->setVisible(wear_visible);
-	mSaveComboBtn->setMenuItemEnabled("save_outfit", make_outfit_enabled);
+	getChild<LLButton>(SAVE_BTN)->setEnabled(make_outfit_enabled);
 	wear_btn->setToolTip(getString((!isOutfitsGalleryPanelActive() && mMyOutfitsPanel->hasItemSelected()) ? "wear_items_tooltip" : "wear_outfit_tooltip"));
 }
 
@@ -368,3 +377,15 @@ LLSidepanelAppearance* LLPanelOutfitsInventory::getAppearanceSP()
 		dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
 	return panel_appearance;
 }
+
+void LLPanelOutfitsInventory::saveOutfit(bool as_new)
+{
+	if (!as_new && LLAppearanceMgr::getInstance()->updateBaseOutfit())
+	{
+		// we don't need to ask for an outfit name, and updateBaseOutfit() successfully saved.
+		// If updateBaseOutfit fails, ask for an outfit name anyways
+		return;
+	}
+
+	onSave();
+}
diff --git a/indra/newview/llpaneloutfitsinventory.h b/indra/newview/llpaneloutfitsinventory.h
index 0bf48834c8c662d9649d532ca99b9e60a0070058..92058a242984146232957a51c293f52673e244e8 100644
--- a/indra/newview/llpaneloutfitsinventory.h
+++ b/indra/newview/llpaneloutfitsinventory.h
@@ -38,7 +38,6 @@ class LLPanelWearing;
 class LLMenuGL;
 class LLSidepanelAppearance;
 class LLTabContainer;
-class LLSaveOutfitComboBtn;
 
 class LLPanelOutfitsInventory : public LLPanel
 {
@@ -52,6 +51,7 @@ class LLPanelOutfitsInventory : public LLPanel
 	
 	void onSearchEdit(const std::string& string);
 	void onSave();
+	void saveOutfit(bool as_new = false);
 	
 	bool onSaveCommit(const LLSD& notification, const LLSD& response);
 
@@ -65,16 +65,14 @@ class LLPanelOutfitsInventory : public LLPanel
 
 	static LLPanelOutfitsInventory* findInstance();
 
+	void openApearanceTab(const std::string& tab_name);
+
 protected:
 	void updateVerbs();
 
 private:
 	LLTabContainer*			mAppearanceTabs;
 	std::string 			mFilterSubString;
-// [SL:KB] - Patch: Viewer-Build | Checked: Catznip-6.6
-	std::unique_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;
-// [/SL:KB]
-//	std::auto_ptr<LLSaveOutfitComboBtn> mSaveComboBtn;
 
 	//////////////////////////////////////////////////////////////////////////////////
 	// tab panels                                                                   //
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 9975119c569f1b92b7c0dd9eefea26d9b19e34eb..3bb7161df9dcb37ab48ecbca9825e5841dd7ef9c 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -668,6 +668,7 @@ BOOL LLPanelPeople::postBuild()
 	mRecentList->setShowIcons("RecentListShowIcons");
 
 	mGroupList = getChild<LLGroupList>("group_list");
+	mGroupList->setNoItemsCommentText(getString("no_groups_msg"));
 	mGroupList->setNoItemsMsg(getString("no_groups_msg"));
 	mGroupList->setNoFilteredItemsMsg(getString("no_filtered_groups_msg"));
 
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index c39df3fe8bbe58a6ffd101afbe975fa883f29ef9..4762e15d8f961306fc64a4ead6338151e1991e6e 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -37,6 +37,7 @@
 #include "llfloatersidepanelcontainer.h"
 #include "llfloaterworldmap.h"
 #include "llnotificationsutil.h"
+#include "llstartup.h"
 #include "lltexturectrl.h"
 #include "lltoggleablemenu.h"
 #include "lltrans.h"
@@ -84,6 +85,11 @@ class LLPickHandler : public LLCommandHandler,
 	bool handle(const LLSD& params, const LLSD& query_map,
 		LLMediaCtrl* web)
 	{
+		if (LLStartUp::getStartupState() < STATE_STARTED)
+		{
+			return true;
+		}
+
 		if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnablePicks"))
 		{
 			LLNotificationsUtil::add("NoPicks", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
@@ -198,6 +204,11 @@ class LLClassifiedHandler :
 	
 	bool handle(const LLSD& params, const LLSD& query_map, LLMediaCtrl* web)
 	{
+		if (LLStartUp::getStartupState() < STATE_STARTED)
+		{
+			return true;
+		}
+
 		if (!LLUI::getInstance()->mSettingGroups["config"]->getBOOL("EnableClassifieds"))
 		{
 			LLNotificationsUtil::add("NoClassifieds", LLSD(), LLSD(), std::string("SwitchToStandardSkinAndQuit"));
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index 53870fb5c74282ec3196a7ead7a13ab1ae234e94..9c67ec40fee1be6baa5480313514e1df407d66dd 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -53,6 +53,7 @@
 #include "llagentpicksinfo.h"
 #include "llavatarpropertiesprocessor.h"
 #include "llcommandhandler.h"
+#include "lldndbutton.h"
 #include "llfloaterworldmap.h"
 #include "llinventorybridge.h"
 #include "llinventoryobserver.h"
@@ -79,6 +80,7 @@
 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 CREATE_PICK_TYPE			= "create_pick";
 static const std::string LANDMARK_INFO_TYPE			= "landmark";
 static const std::string REMOTE_PLACE_INFO_TYPE		= "remote_place";
 static const std::string TELEPORT_HISTORY_INFO_TYPE	= "teleport_history";
@@ -293,8 +295,25 @@ BOOL LLPanelPlaces::postBuild()
 	mOverflowBtn = getChild<LLMenuButton>("overflow_btn");
 	mOverflowBtn->setMouseDownCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this));
 
-	mPlaceInfoBtn = getChild<LLButton>("profile_btn");
-	mPlaceInfoBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onProfileButtonClicked, this));
+    mGearMenuButton = getChild<LLMenuButton>("options_gear_btn");
+    mGearMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onGearMenuClick, this));
+
+    mSortingMenuButton = getChild<LLMenuButton>("sorting_menu_btn");
+    mSortingMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onSortingMenuClick, this));
+
+    mAddMenuButton = getChild<LLMenuButton>("add_menu_btn");
+    mAddMenuButton->setMouseDownCallback(boost::bind(&LLPanelPlaces::onAddMenuClick, this));
+
+    mRemoveSelectedBtn = getChild<LLButton>("trash_btn");
+    mRemoveSelectedBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onRemoveButtonClicked, this));
+
+    LLDragAndDropButton* trash_btn = (LLDragAndDropButton*)mRemoveSelectedBtn;
+    trash_btn->setDragAndDropHandler(boost::bind(&LLPanelPlaces::handleDragAndDropToTrash, this
+        , _4 // BOOL drop
+        , _5 // EDragAndDropType cargo_type
+        , _6 // void* cargo_data
+        , _7 // EAcceptance* accept
+    ));
 
 	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 	registrar.add("Places.OverflowMenu.Action",  boost::bind(&LLPanelPlaces::onOverflowMenuItemClicked, this, _2));
@@ -323,6 +342,10 @@ BOOL LLPanelPlaces::postBuild()
 		mTabContainer->setCommitCallback(boost::bind(&LLPanelPlaces::onTabSelected, this));
 	}
 
+    mButtonsContainer = getChild<LLPanel>("button_layout_panel");
+    mButtonsContainer->setVisible(FALSE);
+    mFilterContainer = getChild<LLLayoutStack>("top_menu_panel");
+
 	mFilterEditor = getChild<LLFilterEditor>("Filter");
 	if (mFilterEditor)
 	{
@@ -388,7 +411,22 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 			// Update the buttons at the bottom of the panel
 			updateVerbs();
 		}
-		else
+        else if (key_type == CREATE_PICK_TYPE)
+        {
+            LLUUID item_id = key["item_id"];
+
+            LLLandmarksPanel* landmarks_panel =
+                dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks"));
+            if (landmarks_panel && item_id.notNull())
+            {
+                LLLandmark* landmark = LLLandmarkActions::getLandmark(item_id, boost::bind(&LLLandmarksPanel::doCreatePick, landmarks_panel, _1, item_id));
+                if (landmark)
+                {
+                    landmarks_panel->doCreatePick(landmark, item_id);
+                }
+            }
+        }
+		else // "create_landmark"
 		{
 			mFilterEditor->clear();
 			onFilterEdit("", false);
@@ -409,7 +447,8 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 			}
 			else if (mPlaceInfoType == CREATE_LANDMARK_INFO_TYPE)
 			{
-				mLandmarkInfo->setInfoType(LLPanelPlaceInfo::CREATE_LANDMARK);
+				LLUUID dest_folder = key["dest_folder"];
+				mLandmarkInfo->setInfoAndCreateLandmark(dest_folder);
 
 				if (key.has("x") && key.has("y") && key.has("z"))
 				{
@@ -612,6 +651,23 @@ void LLPanelPlaces::onTabSelected()
 
 	onFilterEdit(mActivePanel->getFilterSubString(), true);
 	mActivePanel->updateVerbs();
+
+    // History panel does not support deletion nor creation
+    // Hide menus
+    bool supports_create = mActivePanel->getCreateMenu() != NULL;
+    childSetVisible("add_btn_panel", supports_create);
+
+    // favorites and inventory can remove items, history can clear history
+    childSetVisible("trash_btn_panel", TRUE);
+
+    if (supports_create)
+    {
+        mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items"));
+    }
+    else
+    {
+        mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history"));
+    }
 }
 
 void LLPanelPlaces::onTeleportButtonClicked()
@@ -728,34 +784,6 @@ void LLPanelPlaces::onEditButtonClicked()
 	updateVerbs();
 }
 
-class LLUpdateLandmarkParent : public LLInventoryCallback
-{
-public:
-    LLUpdateLandmarkParent(LLPointer<LLViewerInventoryItem> item, LLUUID new_parent) :
-        mItem(item),
-        mNewParentId(new_parent)
-    {};
-    /* virtual */ void fire(const LLUUID& inv_item_id)
-    {
-        LLInventoryModel::update_list_t update;
-        LLInventoryModel::LLCategoryUpdate old_folder(mItem->getParentUUID(), -1);
-        update.push_back(old_folder);
-        LLInventoryModel::LLCategoryUpdate new_folder(mNewParentId, 1);
-        update.push_back(new_folder);
-        gInventory.accountForUpdate(update);
-
-        mItem->setParent(mNewParentId);
-        mItem->updateParentOnServer(FALSE);
-
-        gInventory.updateItem(mItem);
-        gInventory.notifyObservers();
-    }
-
-private:
-    LLPointer<LLViewerInventoryItem> mItem;
-    LLUUID mNewParentId;
-};
-
 void LLPanelPlaces::onSaveButtonClicked()
 {
 	if (!mLandmarkInfo || mItem.isNull())
@@ -885,14 +913,6 @@ void LLPanelPlaces::onOverflowButtonClicked()
 	mOverflowBtn->setMenu(menu, LLMenuButton::MP_TOP_RIGHT);
 }
 
-void LLPanelPlaces::onProfileButtonClicked()
-{
-	if (!mActivePanel)
-		return;
-
-	mActivePanel->onShowProfile();
-}
-
 bool LLPanelPlaces::onOverflowMenuItemEnable(const LLSD& param)
 {
 	std::string value = param.asString();
@@ -981,6 +1001,50 @@ void LLPanelPlaces::onBackButtonClicked()
 	updateVerbs();
 }
 
+void LLPanelPlaces::onGearMenuClick()
+{
+    if (mActivePanel)
+    {
+        LLToggleableMenu* menu = mActivePanel->getSelectionMenu();
+        mGearMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT);
+    }
+}
+
+void LLPanelPlaces::onSortingMenuClick()
+{
+    if (mActivePanel)
+    {
+        LLToggleableMenu* menu = mActivePanel->getSortingMenu();
+        mSortingMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT);
+    }
+}
+
+void LLPanelPlaces::onAddMenuClick()
+{
+    if (mActivePanel)
+    {
+        LLToggleableMenu* menu = mActivePanel->getCreateMenu();
+        mAddMenuButton->setMenu(menu, LLMenuButton::MP_BOTTOM_LEFT);
+    }
+}
+
+void LLPanelPlaces::onRemoveButtonClicked()
+{
+    if (mActivePanel)
+    {
+        mActivePanel->onRemoveSelected();
+    }
+}
+
+bool LLPanelPlaces::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept)
+{
+    if (mActivePanel)
+    {
+        return mActivePanel->handleDragAndDropToTrash(drop, cargo_type, cargo_data, accept);
+    }
+    return false;
+}
+
 void LLPanelPlaces::togglePickPanel(BOOL visible)
 {
 	if (mPickPanel)
@@ -997,8 +1061,9 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
 	if (!mPlaceProfile || !mLandmarkInfo)
 		return;
 
-	mFilterEditor->setVisible(!visible);
 	mTabContainer->setVisible(!visible);
+	mButtonsContainer->setVisible(visible);
+	mFilterContainer->setVisible(!visible);
 
 	if (mPlaceInfoType == AGENT_INFO_TYPE ||
 		mPlaceInfoType == REMOTE_PLACE_INFO_TYPE ||
@@ -1014,10 +1079,6 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
 			// 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());
-
 			mLandmarkInfo->setVisible(FALSE);
 		}
 		else if (mPlaceInfoType == AGENT_INFO_TYPE)
@@ -1038,15 +1099,19 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
 		if (visible)
 		{
 			mLandmarkInfo->resetLocation();
-
-			LLRect rect = getRect();
-			LLRect new_rect = LLRect(rect.mLeft, rect.mTop, rect.mRight, mTabContainer->getRect().mBottom);
-			mLandmarkInfo->reshape(new_rect.getWidth(), new_rect.getHeight());
 		}
 		else
 		{
-			LLLandmarksPanel* landmarks_panel =
-					dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName("Landmarks"));
+			std::string tab_panel_name("Landmarks");
+			if (mItem.notNull())
+			{
+				if (gInventory.isObjectDescendentOf(mItem->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE)))
+				{
+					tab_panel_name = "Favorites";
+				}
+			}
+			
+			LLLandmarksPanel* landmarks_panel = dynamic_cast<LLLandmarksPanel*>(mTabContainer->getPanelByName(tab_panel_name));
 			if (landmarks_panel)
 			{
 				// If a landmark info is being closed we open the landmarks tab
@@ -1056,6 +1121,10 @@ void LLPanelPlaces::togglePlaceInfoPanel(BOOL visible)
 				{
 					landmarks_panel->setItemSelected(mItem->getUUID(), TRUE);
 				}
+				else
+				{
+					landmarks_panel->resetSelection();
+				}
 			}
 		}
 	}
@@ -1123,11 +1192,19 @@ void LLPanelPlaces::createTabs()
 	if (!(gInventory.isInventoryUsable() && LLTeleportHistory::getInstance() && !mTabsCreated))
 		return;
 
+	LLFavoritesPanel* favorites_panel = new LLFavoritesPanel();
+	if (favorites_panel)
+	{
+		mTabContainer->addTabPanel(
+			LLTabContainer::TabPanelParams().
+			panel(favorites_panel).
+			label(getString("favorites_tab_title")).
+			insert_at(LLTabContainer::END));
+	}
+
 	LLLandmarksPanel* landmarks_panel = new LLLandmarksPanel();
 	if (landmarks_panel)
 	{
-		landmarks_panel->setPanelPlacesButtons(this);
-
 		mTabContainer->addTabPanel(
 			LLTabContainer::TabPanelParams().
 			panel(landmarks_panel).
@@ -1138,8 +1215,6 @@ void LLPanelPlaces::createTabs()
 	LLTeleportHistoryPanel* teleport_history_panel = new LLTeleportHistoryPanel();
 	if (teleport_history_panel)
 	{
-		teleport_history_panel->setPanelPlacesButtons(this);
-
 		mTabContainer->addTabPanel(
 			LLTabContainer::TabPanelParams().
 			panel(teleport_history_panel).
@@ -1151,9 +1226,31 @@ void LLPanelPlaces::createTabs()
 
 	mActivePanel = dynamic_cast<LLPanelPlacesTab*>(mTabContainer->getCurrentPanel());
 
-	// Filter applied to show all items.
-	if (mActivePanel)
-		mActivePanel->onSearchEdit(mActivePanel->getFilterSubString());
+    if (mActivePanel)
+    {
+        // Filter applied to show all items.
+        mActivePanel->onSearchEdit(mActivePanel->getFilterSubString());
+
+        // History panel does not support deletion nor creation
+        // Hide menus
+        bool supports_create = mActivePanel->getCreateMenu() != NULL;
+        childSetVisible("add_btn_panel", supports_create);
+
+        // favorites and inventory can remove items, history can clear history
+        childSetVisible("trash_btn_panel", TRUE);
+
+        if (supports_create)
+        {
+            mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_items"));
+        }
+        else
+        {
+            mRemoveSelectedBtn->setToolTip(getString("tooltip_trash_history"));
+        }
+
+        mActivePanel->setRemoveBtn(mRemoveSelectedBtn);
+		mActivePanel->updateVerbs();
+    }
 
 	mTabsCreated = true;
 }
@@ -1219,15 +1316,12 @@ void LLPanelPlaces::updateVerbs()
 	mSaveBtn->setVisible(isLandmarkEditModeOn);
 	mCancelBtn->setVisible(isLandmarkEditModeOn);
 	mCloseBtn->setVisible(is_create_landmark_visible && !isLandmarkEditModeOn);
-	mPlaceInfoBtn->setVisible(!is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn && !is_pick_panel_visible);
 
 	bool show_options_btn = is_place_info_visible && !is_create_landmark_visible && !isLandmarkEditModeOn;
 	mOverflowBtn->setVisible(show_options_btn);
 	getChild<LLLayoutPanel>("lp_options")->setVisible(show_options_btn);
 	getChild<LLLayoutPanel>("lp2")->setVisible(!show_options_btn);
 
-	mPlaceInfoBtn->setEnabled(!is_create_landmark_visible && !isLandmarkEditModeOn && have_3d_pos);
-
 	if (is_place_info_visible)
 	{
 		mShowOnMapBtn->setEnabled(have_3d_pos);
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index 978b030b2e02f7e169ea8b55ba42e8b1cd329b44..3b87eb6cb9521ac15ecfa72d18e534eea1f3bfde 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -48,6 +48,7 @@ class LLRemoteParcelInfoObserver;
 class LLTabContainer;
 class LLToggleableMenu;
 class LLMenuButton;
+class LLLayoutStack;
 
 typedef std::pair<LLUUID, std::string>	folder_pair_t;
 
@@ -96,7 +97,12 @@ class LLPanelPlaces : public LLPanel
 	bool onOverflowMenuItemEnable(const LLSD& param);
 	void onCreateLandmarkButtonClicked(const LLUUID& folder_id);
 	void onBackButtonClicked();
-	void onProfileButtonClicked();
+    void onGearMenuClick();
+    void onSortingMenuClick();
+    void onAddMenuClick();
+    void onRemoveButtonClicked();
+    bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept);
+
 
 	void toggleMediaPanel();
 	void togglePickPanel(BOOL visible);
@@ -111,6 +117,8 @@ class LLPanelPlaces : public LLPanel
 	LLFilterEditor*				mFilterEditor;
 	LLPanelPlacesTab*			mActivePanel;
 	LLTabContainer*				mTabContainer;
+	LLPanel*					mButtonsContainer;
+	LLLayoutStack*				mFilterContainer;
 	LLPanelPlaceProfile*		mPlaceProfile;
 	LLPanelLandmarkInfo*		mLandmarkInfo;
 
@@ -125,7 +133,12 @@ class LLPanelPlaces : public LLPanel
 	LLButton*					mCancelBtn;
 	LLButton*					mCloseBtn;
 	LLMenuButton*				mOverflowBtn;
-	LLButton*					mPlaceInfoBtn;
+
+    // Top menu
+    LLMenuButton*				mGearMenuButton;
+    LLMenuButton*				mSortingMenuButton;
+    LLMenuButton*				mAddMenuButton;
+    LLButton*					mRemoveSelectedBtn;
 
 	LLPlacesInventoryObserver*	mInventoryObserver;
 	LLPlacesParcelObserver*		mParcelObserver;
diff --git a/indra/newview/llpanelplacestab.cpp b/indra/newview/llpanelplacestab.cpp
index 9644b7518e883feead5315f66cd1672431290437..748a91714752ec47e75da9a0cd20b73d2aa523c0 100644
--- a/indra/newview/llpanelplacestab.cpp
+++ b/indra/newview/llpanelplacestab.cpp
@@ -38,6 +38,7 @@
 #include "llworldmap.h"
 
 std::string LLPanelPlacesTab::sFilterSubString = LLStringUtil::null;
+LLButton* LLPanelPlacesTab::sRemoveBtn = NULL;
 
 bool LLPanelPlacesTab::isTabVisible()
 {
@@ -47,13 +48,6 @@ bool LLPanelPlacesTab::isTabVisible()
 	return true;
 }
 
-void LLPanelPlacesTab::setPanelPlacesButtons(LLPanelPlaces* panel)
-{
-	mTeleportBtn = panel->getChild<LLButton>("teleport_btn");
-	mShowOnMapBtn = panel->getChild<LLButton>("map_btn");
-	mShowProfile = panel->getChild<LLButton>("profile_btn");
-}
-
 void LLPanelPlacesTab::onRegionResponse(const LLVector3d& landmark_global_pos,
 										U64 region_handle,
 										const std::string& url,
diff --git a/indra/newview/llpanelplacestab.h b/indra/newview/llpanelplacestab.h
index 367ce46e2e0763d431cf44c8d8ae9b70c0818641..aab1c130c18d6367f7584d0e8b6ca24c40eca0e1 100644
--- a/indra/newview/llpanelplacestab.h
+++ b/indra/newview/llpanelplacestab.h
@@ -30,6 +30,7 @@
 #include "llpanel.h"
 
 class LLPanelPlaces;
+class LLToggleableMenu;
 
 class LLPanelPlacesTab : public LLPanel
 {
@@ -42,11 +43,21 @@ class LLPanelPlacesTab : public LLPanel
 	virtual void onShowOnMap() = 0;
 	virtual void onShowProfile() = 0;
 	virtual void onTeleport() = 0;
+	virtual void onRemoveSelected() = 0;
 	virtual bool isSingleItemSelected() = 0;
 
+    // returns menu for current selection
+    virtual LLToggleableMenu* getSelectionMenu() = 0;
+    virtual LLToggleableMenu* getSortingMenu() = 0;
+    virtual LLToggleableMenu* getCreateMenu() = 0;
+
+    /**
+    * Processes drag-n-drop of the Landmarks and folders into trash button.
+    */
+    virtual bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) = 0;
+
 	bool isTabVisible(); // Check if parent TabContainer is visible.
 
-	void setPanelPlacesButtons(LLPanelPlaces* panel);
 	void onRegionResponse(const LLVector3d& landmark_global_pos,
 										U64 region_handle,
 										const std::string& url,
@@ -56,13 +67,12 @@ class LLPanelPlacesTab : public LLPanel
 	const std::string& getFilterSubString() { return sFilterSubString; }
 	void setFilterSubString(const std::string& string) { sFilterSubString = string; }
 
-protected:
-	LLButton*				mTeleportBtn;
-	LLButton*				mShowOnMapBtn;
-	LLButton*				mShowProfile;
+	void setRemoveBtn(LLButton* trash_btn) { sRemoveBtn = trash_btn; }
 
+protected:
 	// Search string for filtering landmarks and teleport history locations
 	static std::string		sFilterSubString;
+	static LLButton*		sRemoveBtn;
 };
 
 #endif //LL_LLPANELPLACESTAB_H
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index 2bd78f40ba6dafddaaf595199f4a82069201c968..c42cd6c6ba2ba23fa6d064639c920081f2f70134 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -74,6 +74,8 @@ const LLPanelPrimMediaControls::EZoomLevel LLPanelPrimMediaControls::kZoomLevels
 const int LLPanelPrimMediaControls::kNumZoomLevels = 2;
 
 const F32 EXCEEDING_ZOOM_DISTANCE = 0.5f;
+const S32 ADDR_LEFT_PAD = 3;
+
 //
 // LLPanelPrimMediaControls
 //
@@ -156,7 +158,7 @@ BOOL LLPanelPrimMediaControls::postBuild()
 	mMediaProgressPanel		= getChild<LLPanel>("media_progress_indicator");
 	mMediaProgressBar		= getChild<LLProgressBar>("media_progress_bar");
 	mMediaAddressCtrl		= getChild<LLUICtrl>("media_address");
-	mMediaAddress			= getChild<LLUICtrl>("media_address_url");
+	mMediaAddress			= getChild<LLLineEditor>("media_address_url");
 	mMediaPlaySliderPanel	= getChild<LLUICtrl>("media_play_position");
 	mMediaPlaySliderCtrl	= getChild<LLUICtrl>("media_play_slider");
 	mSkipFwdCtrl			= getChild<LLUICtrl>("skip_forward");
@@ -501,8 +503,10 @@ void LLPanelPrimMediaControls::updateShape()
 			std::string test_prefix = mCurrentURL.substr(0, prefix.length());
 			LLStringUtil::toLower(test_prefix);
             mSecureURL = has_focus && (test_prefix == prefix);
-            mCurrentURL = (mSecureURL ? "      " + mCurrentURL : mCurrentURL);
-			
+
+			S32 left_pad = mSecureURL ? mSecureLockIcon->getRect().getWidth() : ADDR_LEFT_PAD;
+			mMediaAddress->setTextPadding(left_pad, 0);
+
 			if(mCurrentURL!=mPreviousURL)
 			{
 				setCurrentURL();
diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h
index 86fc03655389f24e5138dd6345249e735e453661..dd0e4ff095f869eacc6d1f87c78ddc66ab233b4a 100644
--- a/indra/newview/llpanelprimmediacontrols.h
+++ b/indra/newview/llpanelprimmediacontrols.h
@@ -39,6 +39,7 @@ class LLProgressBar;
 class LLSliderCtrl;
 class LLViewerMediaImpl;
 class LLWindowShade;
+class LLLineEditor;
 
 class LLPanelPrimMediaControls : public LLPanel
 {
@@ -164,7 +165,7 @@ class LLPanelPrimMediaControls : public LLPanel
 	LLPanel  *mMediaProgressPanel;
 	LLProgressBar *mMediaProgressBar;
 	LLUICtrl *mMediaAddressCtrl;
-	LLUICtrl *mMediaAddress;
+	LLLineEditor *mMediaAddress;
 	LLUICtrl *mMediaPlaySliderPanel;
 	LLUICtrl *mMediaPlaySliderCtrl;
 	LLUICtrl *mVolumeCtrl;
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index fe0608d5441594e958547554213017c52425502d..b938b304792e1d9bac22cdba389f713b5ed64139 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -56,7 +56,7 @@ static const std::string COLLAPSED_BY_USER = "collapsed_by_user";
 class LLTeleportHistoryFlatItem : public LLPanel
 {
 public:
-	LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name,
+	LLTeleportHistoryFlatItem(S32 index, LLToggleableMenu *menu, const std::string &region_name,
 										 	 LLDate date, const std::string &hl);
 	virtual ~LLTeleportHistoryFlatItem();
 
@@ -86,12 +86,13 @@ class LLTeleportHistoryFlatItem : public LLPanel
 
 private:
 	void onProfileBtnClick();
+    void showMenu(S32 x, S32 y);
 
 	LLButton* mProfileBtn;
 	LLTextBox* mTitle;
 	LLTextBox* mTimeTextBox;
 	
-	LLTeleportHistoryPanel::ContextMenu *mContextMenu;
+	LLToggleableMenu *mMenu;
 
 	S32 mIndex;
 	std::string mRegionName;
@@ -112,7 +113,7 @@ class LLTeleportHistoryFlatItemStorage: public LLSingleton<LLTeleportHistoryFlat
 
 public:
 	LLTeleportHistoryFlatItem* getFlatItemForPersistentItem (
-		LLTeleportHistoryPanel::ContextMenu *context_menu,
+		LLToggleableMenu *menu,
 		const LLTeleportHistoryPersistentItem& persistent_item,
 		const S32 cur_item_index,
 		const std::string &hl);
@@ -130,16 +131,16 @@ class LLTeleportHistoryFlatItemStorage: public LLSingleton<LLTeleportHistoryFlat
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
-LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLTeleportHistoryPanel::ContextMenu *context_menu, const std::string &region_name,
+LLTeleportHistoryFlatItem::LLTeleportHistoryFlatItem(S32 index, LLToggleableMenu *menu, const std::string &region_name,
 																LLDate date, const std::string &hl)
 :	LLPanel(),
 	mIndex(index),
-	mContextMenu(context_menu),
+	mMenu(menu),
 	mRegionName(region_name),
 	mDate(date),
 	mHighlight(hl)
 {
-	buildFromFile( "panel_teleport_history_item.xml");
+	buildFromFile("panel_teleport_history_item.xml");
 }
 
 LLTeleportHistoryFlatItem::~LLTeleportHistoryFlatItem()
@@ -266,10 +267,9 @@ void LLTeleportHistoryFlatItem::onMouseLeave(S32 x, S32 y, MASK mask)
 // virtual
 BOOL LLTeleportHistoryFlatItem::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
-	if (mContextMenu)
-		mContextMenu->show(this, mIndex, x, y);
-
-	return LLPanel::handleRightMouseDown(x, y, mask);
+    LLPanel::handleRightMouseDown(x, y, mask);
+	showMenu(x, y);
+    return TRUE;
 }
 
 void LLTeleportHistoryFlatItem::showPlaceInfoPanel(S32 index)
@@ -286,13 +286,23 @@ void LLTeleportHistoryFlatItem::onProfileBtnClick()
 	LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);
 }
 
+void LLTeleportHistoryFlatItem::showMenu(S32 x, S32 y)
+{
+    mMenu->setButtonRect(this);
+    mMenu->buildDrawLabels();
+    mMenu->arrangeAndClear();
+    mMenu->updateParent(LLMenuGL::sMenuContainer);
+
+    LLMenuGL::showPopup(this, mMenu, x, y);
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
 LLTeleportHistoryFlatItem*
 LLTeleportHistoryFlatItemStorage::getFlatItemForPersistentItem (
-	LLTeleportHistoryPanel::ContextMenu *context_menu,
+	LLToggleableMenu *menu,
 	const LLTeleportHistoryPersistentItem& persistent_item,
 	const S32 cur_item_index,
 	const std::string &hl)
@@ -321,7 +331,7 @@ LLTeleportHistoryFlatItemStorage::getFlatItemForPersistentItem (
 	if ( !item )
 	{
 		item = new LLTeleportHistoryFlatItem(cur_item_index,
-											 context_menu,
+											 menu,
 											 persistent_item.mTitle,
 											 persistent_item.mDate,
 											 hl);
@@ -365,74 +375,6 @@ void LLTeleportHistoryFlatItemStorage::purge()
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
-LLTeleportHistoryPanel::ContextMenu::ContextMenu() :
-	mMenu(NULL), mIndex(0)
-{
-}
-
-void LLTeleportHistoryPanel::ContextMenu::show(LLView* spawning_view, S32 index, S32 x, S32 y)
-{
-	if (mMenu)
-	{
-		//preventing parent (menu holder) from deleting already "dead" context menus on exit
-		LLView* parent = mMenu->getParent();
-		if (parent)
-		{
-			parent->removeChild(mMenu);
-		}
-		delete mMenu;
-	}
-
-	mIndex = index;
-	mMenu = createMenu();
-
-	mMenu->show(x, y);
-	LLMenuGL::showPopup(spawning_view, mMenu, x, y);
-}
-
-LLContextMenu* LLTeleportHistoryPanel::ContextMenu::createMenu()
-{
-	// set up the callbacks for all of the avatar menu items
-	// (N.B. callbacks don't take const refs as mID is local scope)
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
-	registrar.add("TeleportHistory.Teleport",	boost::bind(&LLTeleportHistoryPanel::ContextMenu::onTeleport, this));
-	registrar.add("TeleportHistory.MoreInformation",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onInfo, this));
-	registrar.add("TeleportHistory.CopyToClipboard",boost::bind(&LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard, this));
-
-	// create the context menu from the XUI
-	llassert(LLMenuGL::sMenuContainer != NULL);
-	return LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(
-		"menu_teleport_history_item.xml", LLMenuGL::sMenuContainer, LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLTeleportHistoryPanel::ContextMenu::onTeleport()
-{
-	confirmTeleport(mIndex);
-}
-
-void LLTeleportHistoryPanel::ContextMenu::onInfo()
-{
-	LLTeleportHistoryFlatItem::showPlaceInfoPanel(mIndex);
-}
-
-//static
-void LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback(const std::string& slurl)
-{
-	LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl),0,slurl.size());
-
-	LLSD args;
-	args["SLURL"] = slurl;
-
-	LLNotificationsUtil::add("CopySLURL", args);
-}
-
-void LLTeleportHistoryPanel::ContextMenu::onCopyToClipboard()
-{
-	LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[mIndex].mGlobalPos;
-	LLLandmarkActions::getSLURLfromPosGlobal(globalPos,
-		boost::bind(&LLTeleportHistoryPanel::ContextMenu::gotSLURLCallback, _1));
-}
 
 // Not yet implemented; need to remove buildPanel() from constructor when we switch
 //static LLRegisterPanelClassWrapper<LLTeleportHistoryPanel> t_teleport_history("panel_teleport_history");
@@ -446,7 +388,8 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()
 		mAccordionTabMenu(NULL),
 		mLastSelectedFlatlList(NULL),
 		mLastSelectedItemIndex(-1),
-		mMenuGearButton(NULL)
+		mGearItemMenu(NULL),
+		mSortingMenu(NULL)
 {
 	buildFromFile( "panel_teleport_history.xml");
 }
@@ -454,12 +397,19 @@ LLTeleportHistoryPanel::LLTeleportHistoryPanel()
 LLTeleportHistoryPanel::~LLTeleportHistoryPanel()
 {
 	LLTeleportHistoryFlatItemStorage::instance().purge();
-	if (mGearMenuHandle.get()) mGearMenuHandle.get()->die();
 	mTeleportHistoryChangedConnection.disconnect();
 }
 
 BOOL LLTeleportHistoryPanel::postBuild()
 {
+    mCommitCallbackRegistrar.add("TeleportHistory.GearMenu.Action", boost::bind(&LLTeleportHistoryPanel::onGearMenuAction, this, _2));
+    mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2));
+
+    // init menus before list, since menus are passed to list
+    mGearItemMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_item.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+    mGearItemMenu->setAlwaysShowMenu(TRUE); // all items can be disabled if nothing is selected, show anyway
+    mSortingMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_gear.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+
 	mTeleportHistory = LLTeleportHistoryStorage::getInstance();
 	if (mTeleportHistory)
 	{
@@ -511,22 +461,6 @@ BOOL LLTeleportHistoryPanel::postBuild()
 		}
 	}
 
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-
-	registrar.add("TeleportHistory.ExpandAllFolders",  boost::bind(&LLTeleportHistoryPanel::onExpandAllFolders,  this));
-	registrar.add("TeleportHistory.CollapseAllFolders",  boost::bind(&LLTeleportHistoryPanel::onCollapseAllFolders,  this));
-	registrar.add("TeleportHistory.ClearTeleportHistory",  boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistory,  this));
-	mEnableCallbackRegistrar.add("TeleportHistory.GearMenu.Enable", boost::bind(&LLTeleportHistoryPanel::isActionEnabled, this, _2));
-
-	mMenuGearButton = getChild<LLMenuButton>("gear_btn");
-
-	LLToggleableMenu* gear_menu  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_teleport_history_gear.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());;
-	if(gear_menu)
-	{
-		mGearMenuHandle  = gear_menu->getHandle();
-		mMenuGearButton->setMenu(gear_menu);
-	}
-
 	return TRUE;
 }
 
@@ -600,6 +534,12 @@ void LLTeleportHistoryPanel::onTeleport()
 	confirmTeleport(itemp->getIndex());
 }
 
+// virtual
+void LLTeleportHistoryPanel::onRemoveSelected()
+{
+    LLNotificationsUtil::add("ConfirmClearTeleportHistory", LLSD(), LLSD(), boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistoryDialog, this, _1, _2));
+}
+
 /*
 // virtual
 void LLTeleportHistoryPanel::onCopySLURL()
@@ -630,19 +570,28 @@ void LLTeleportHistoryPanel::updateVerbs()
 	if (!isTabVisible())
 		return;
 
-	if (!mLastSelectedFlatlList)
+	if (sRemoveBtn)
 	{
-		mTeleportBtn->setEnabled(false);
-		mShowProfile->setEnabled(false);
-		mShowOnMapBtn->setEnabled(false);
-		return;
+		sRemoveBtn->setEnabled(true);
 	}
+}
 
-	LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem());
+// virtual
+LLToggleableMenu* LLTeleportHistoryPanel::getSelectionMenu()
+{
+    return mGearItemMenu;
+}
+
+// virtual
+LLToggleableMenu* LLTeleportHistoryPanel::getSortingMenu()
+{
+    return mSortingMenu;
+}
 
-	mTeleportBtn->setEnabled(NULL != itemp);
-	mShowProfile->setEnabled(NULL != itemp);
-	mShowOnMapBtn->setEnabled(NULL != itemp);
+// virtual
+LLToggleableMenu* LLTeleportHistoryPanel::getCreateMenu()
+{
+    return NULL;
 }
 
 void LLTeleportHistoryPanel::getNextTab(const LLDate& item_date, S32& tab_idx, LLDate& tab_date)
@@ -778,7 +727,7 @@ void LLTeleportHistoryPanel::refresh()
 		{
 			LLTeleportHistoryFlatItem* item =
 				LLTeleportHistoryFlatItemStorage::instance()
-				.getFlatItemForPersistentItem(&mContextMenu,
+				.getFlatItemForPersistentItem(mGearItemMenu,
 											  items[mCurrentItem],
 											  mCurrentItem,
 											  filter_string);
@@ -847,7 +796,7 @@ void LLTeleportHistoryPanel::replaceItem(S32 removed_index)
 
 	const LLTeleportHistoryStorage::slurl_list_t& history_items = mTeleportHistory->getItems();
 	LLTeleportHistoryFlatItem* item = LLTeleportHistoryFlatItemStorage::instance()
-		.getFlatItemForPersistentItem(&mContextMenu,
+		.getFlatItemForPersistentItem(mGearItemMenu,
 									  history_items[history_items.size() - 1], // Most recent item, it was added instead of removed
 									  history_items.size(), // index will be decremented inside loop below
 									  sFilterSubString);
@@ -1019,38 +968,6 @@ void LLTeleportHistoryPanel::onAccordionTabClose(LLAccordionCtrlTab *tab)
 	mHistoryAccordion->arrange();
 }
 
-void LLTeleportHistoryPanel::onExpandAllFolders()
-{
-	S32 tabs_cnt = mItemContainers.size();
-
-	for (S32 n = 0; n < tabs_cnt; n++)
-	{
-		mItemContainers.at(n)->setDisplayChildren(true);
-	}
-	mHistoryAccordion->arrange();
-}
-
-void LLTeleportHistoryPanel::onCollapseAllFolders()
-{
-	S32 tabs_cnt = mItemContainers.size();
-
-	for (S32 n = 0; n < tabs_cnt; n++)
-	{
-		mItemContainers.at(n)->setDisplayChildren(false);
-	}
-	mHistoryAccordion->arrange();
-
-	if (mLastSelectedFlatlList)
-	{
-		mLastSelectedFlatlList->resetSelection();
-	}
-}
-
-void LLTeleportHistoryPanel::onClearTeleportHistory()
-{
-	LLNotificationsUtil::add("ConfirmClearTeleportHistory", LLSD(), LLSD(), boost::bind(&LLTeleportHistoryPanel::onClearTeleportHistoryDialog, this, _1, _2));
-}
-
 bool LLTeleportHistoryPanel::onClearTeleportHistoryDialog(const LLSD& notification, const LLSD& response)
 {
 
@@ -1082,45 +999,137 @@ LLFlatListView* LLTeleportHistoryPanel::getFlatListViewFromTab(LLAccordionCtrlTa
 	return NULL;
 }
 
-bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const
+void LLTeleportHistoryPanel::gotSLURLCallback(const std::string& slurl)
 {
-	S32 tabs_cnt = mItemContainers.size();
-
-	bool has_expanded_tabs = false;
-	bool has_collapsed_tabs = false;
-
-	for (S32 n = 0; n < tabs_cnt; n++)
-	{
-		LLAccordionCtrlTab* tab = mItemContainers.at(n);
-		if (!tab->getVisible())
-			continue;
-
-		if (tab->getDisplayChildren())
-		{
-			has_expanded_tabs = true;
-		}
-		else
-		{
-			has_collapsed_tabs = true;
-		}
+    LLClipboard::instance().copyToClipboard(utf8str_to_wstring(slurl), 0, slurl.size());
 
-		if (has_expanded_tabs && has_collapsed_tabs)
-		{
-			break;
-		}
-	}
+    LLSD args;
+    args["SLURL"] = slurl;
 
-	std::string command_name = userdata.asString();
+    LLNotificationsUtil::add("CopySLURL", args);
+}
 
-	if (has_expanded_tabs && command_name == "collapse_all")
-	{
-		return true;
-	}
+void LLTeleportHistoryPanel::onGearMenuAction(const LLSD& userdata)
+{
+    std::string command_name = userdata.asString();
+
+    if ("expand_all" == command_name)
+    {
+        S32 tabs_cnt = mItemContainers.size();
+
+        for (S32 n = 0; n < tabs_cnt; n++)
+        {
+            mItemContainers.at(n)->setDisplayChildren(true);
+        }
+        mHistoryAccordion->arrange();
+    }
+    else if ("collapse_all" == command_name)
+    {
+        S32 tabs_cnt = mItemContainers.size();
+
+        for (S32 n = 0; n < tabs_cnt; n++)
+        {
+            mItemContainers.at(n)->setDisplayChildren(false);
+        }
+        mHistoryAccordion->arrange();
+
+        if (mLastSelectedFlatlList)
+        {
+            mLastSelectedFlatlList->resetSelection();
+        }
+    }
+
+    S32 index = -1;
+    if (mLastSelectedFlatlList)
+    {
+        LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem());
+        if (itemp)
+        {
+            index = itemp->getIndex();
+        }
+    }
+
+    if ("teleport" == command_name)
+    {
+        confirmTeleport(index);
+    }
+    else if ("view" == command_name)
+    {
+        LLTeleportHistoryFlatItem::showPlaceInfoPanel(index);
+    }
+    else if ("show_on_map" == command_name)
+    {
+        LLTeleportHistoryStorage::getInstance()->showItemOnMap(index);
+    }
+    else if ("copy_slurl" == command_name)
+    {
+        LLVector3d globalPos = LLTeleportHistoryStorage::getInstance()->getItems()[index].mGlobalPos;
+        LLLandmarkActions::getSLURLfromPosGlobal(globalPos,
+            boost::bind(&LLTeleportHistoryPanel::gotSLURLCallback, _1));
+    }
+}
 
-	if (has_collapsed_tabs && command_name ==  "expand_all")
-	{
-		return true;
-	}
+bool LLTeleportHistoryPanel::isActionEnabled(const LLSD& userdata) const
+{
+    std::string command_name = userdata.asString();
+
+    if (command_name == "collapse_all"
+        || command_name == "expand_all")
+    {
+        S32 tabs_cnt = mItemContainers.size();
+
+        bool has_expanded_tabs = false;
+        bool has_collapsed_tabs = false;
+
+        for (S32 n = 0; n < tabs_cnt; n++)
+        {
+            LLAccordionCtrlTab* tab = mItemContainers.at(n);
+            if (!tab->getVisible())
+                continue;
+
+            if (tab->getDisplayChildren())
+            {
+                has_expanded_tabs = true;
+            }
+            else
+            {
+                has_collapsed_tabs = true;
+            }
+
+            if (has_expanded_tabs && has_collapsed_tabs)
+            {
+                break;
+            }
+        }
+
+        if (command_name == "collapse_all")
+        {
+            return has_expanded_tabs;
+        }
+
+        if (command_name == "expand_all")
+        {
+            return has_collapsed_tabs;
+        }
+    }
+
+    if (command_name == "clear_history")
+    {
+        return mTeleportHistory->getItems().size() > 0;
+    }
+    
+    if ("teleport" == command_name
+        || "view" == command_name
+        || "show_on_map" == command_name
+        || "copy_slurl" == command_name)
+    {
+        if (!mLastSelectedFlatlList)
+        {
+            return false;
+        }
+        LLTeleportHistoryFlatItem* itemp = dynamic_cast<LLTeleportHistoryFlatItem *> (mLastSelectedFlatlList->getSelectedItem());
+        return itemp != NULL;
+    }
 
 	return false;
 }
diff --git a/indra/newview/llpanelteleporthistory.h b/indra/newview/llpanelteleporthistory.h
index b88861c5c632cb3cd50da65a5cb11015b55a0ec5..058fee01708a86e09674fbb1d6b85ae1e90fe490 100644
--- a/indra/newview/llpanelteleporthistory.h
+++ b/indra/newview/llpanelteleporthistory.h
@@ -43,38 +43,26 @@ class LLMenuButton;
 class LLTeleportHistoryPanel : public LLPanelPlacesTab
 {
 public:
-	// *TODO: derive from LLListContextMenu?
-	class ContextMenu
-	{
-	public:
-		ContextMenu();
-		void show(LLView* spawning_view, S32 index, S32 x, S32 y);
-
-	private:
-		LLContextMenu* createMenu();
-		void onTeleport();
-		void onInfo();
-		void onCopyToClipboard();
-
-		static void gotSLURLCallback(const std::string& slurl);
-
-		LLContextMenu* mMenu;
-		S32 mIndex;
-	};
-
 	LLTeleportHistoryPanel();
 	virtual ~LLTeleportHistoryPanel();
 
-	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void draw();
+    BOOL postBuild() override;
+    void draw() override;
 
-	/*virtual*/ void onSearchEdit(const std::string& string);
-	/*virtual*/ void onShowOnMap();
-	/*virtual*/ void onShowProfile();
-	/*virtual*/ void onTeleport();
-	///*virtual*/ void onCopySLURL();
-	/*virtual*/ void updateVerbs();
-	/*virtual*/ bool isSingleItemSelected();
+    void onSearchEdit(const std::string& string) override;
+    void onShowOnMap() override;
+    void onShowProfile() override;
+    void onTeleport() override;
+    ///*virtual*/ void onCopySLURL();
+    void onRemoveSelected() override;
+    void updateVerbs() override;
+    bool isSingleItemSelected() override;
+
+    LLToggleableMenu* getSelectionMenu() override;
+    LLToggleableMenu* getSortingMenu() override;
+    LLToggleableMenu* getCreateMenu() override;
+
+    bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, void* cargo_data, EAcceptance* accept) override { return false; }
 
 private:
 
@@ -88,13 +76,15 @@ class LLTeleportHistoryPanel : public LLPanelPlacesTab
 	void onClearTeleportHistory();
 	bool onClearTeleportHistoryDialog(const LLSD& notification, const LLSD& response);
 
-	void refresh();
+	void refresh() override;
 	void getNextTab(const LLDate& item_date, S32& curr_tab, LLDate& tab_date);
 	void onTeleportHistoryChange(S32 removed_index);
 	void replaceItem(S32 removed_index);
 	void showTeleportHistory();
 	void handleItemSelect(LLFlatListView* );
 	LLFlatListView* getFlatListViewFromTab(LLAccordionCtrlTab *);
+	static void gotSLURLCallback(const std::string& slurl);
+	void onGearMenuAction(const LLSD& userdata);
 	bool isActionEnabled(const LLSD& userdata) const;
 
 	void setAccordionCollapsedByUser(LLUICtrl* acc_tab, bool collapsed);
@@ -115,10 +105,10 @@ class LLTeleportHistoryPanel : public LLPanelPlacesTab
 	typedef std::vector<LLAccordionCtrlTab*> item_containers_t;
 	item_containers_t mItemContainers;
 
-	ContextMenu mContextMenu;
 	LLContextMenu*			mAccordionTabMenu;
-	LLHandle<LLView>		mGearMenuHandle;
-	LLMenuButton*			mMenuGearButton;
+
+    LLToggleableMenu*			mGearItemMenu;
+    LLToggleableMenu*			mSortingMenu;
 
 	boost::signals2::connection mTeleportHistoryChangedConnection;
 };
diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp
index b0dafe5a1195a396592fcb24bcfbeea7530f414f..e878b20d89fb1159ad5aecaebbe45f4b8dead090 100644
--- a/indra/newview/llpaneltopinfobar.cpp
+++ b/indra/newview/llpaneltopinfobar.cpp
@@ -31,6 +31,7 @@
 #include "llagent.h"
 #include "llagentui.h"
 #include "llclipboard.h"
+#include "llfloaterreg.h"
 #include "llfloatersidepanelcontainer.h"
 #include "lllandmarkactions.h"
 #include "lllocationinputctrl.h"
@@ -463,7 +464,7 @@ void LLPanelTopInfoBar::onContextMenuItemClicked(const LLSD::String& item)
 
 			if(landmark == NULL)
 			{
-				LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
+				LLFloaterReg::showInstance("add_landmark");
 			}
 			else
 			{
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index ee6893907e2af575b38ed185e61d3bd867db1276..1f5ed9b1952ab63c37d3d4362d517595e12abc1c 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -259,11 +259,7 @@ LLParticipantList::~LLParticipantList()
 */
 void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
 {
-	LLConversationItemParticipant* participant = findParticipant(participant_id);
-	if (participant)
-	{
-		removeParticipant(participant);
-	}
+	removeParticipant(participant_id);
 	// re-add avaline caller with a correct class instance.
 	addAvatarIDExceptAgent(participant_id);
 }
@@ -280,6 +276,19 @@ void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t c
 	mValidateSpeakerCallback = cb;
 }
 
+// [RLVa:KB] - @shownames
+void LLParticipantList::refreshNames()
+{
+	for (LLFolderViewModelItem* pChildItem : mChildren)
+	{
+		if (LLConversationItemParticipant* pConversationItem = dynamic_cast<LLConversationItemParticipant*>(pChildItem))
+		{
+			pConversationItem->updateName();
+		}
+	}
+}
+// [/RLVa:KB]
+
 void LLParticipantList::update()
 {
 	mSpeakerMgr->update(true);
@@ -392,11 +401,15 @@ void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 		participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
 		mAvalineUpdater->watchAvalineCaller(avatar_id);
 	}
+// [RLVa:KB] - @shownames
+	participant->setRlvCheckShowNames(mSpeakerMgr->getSessionID().isNull());
+// [/RLVa:KB]
 
 	// *TODO : Need to update the online/offline status of the participant
 	// Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))
 	
 	// Add the participant model to the session's children list
+	// This will post "add_participant" event
 	addParticipant(participant);
 
 	adjustParticipant(avatar_id);
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 3a3ae76604a9c17bc8d0df5629b082bf66f686e9..8e89da37dd7247b5d549b6738393d05e39bb8878 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -51,6 +51,13 @@ class LLParticipantList : public LLConversationItemSession
 	 */
 	void addAvatarIDExceptAgent(const LLUUID& avatar_id);
 
+// [RLVa:KB] - @shownames
+	/**
+	 * Refreshes the name of each (avatar) participant
+	 */
+	void refreshNames();
+// [/RLVa:KB]
+
 	/**
 	 * Refreshes the participant list.
 	 */
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index 70ce275734488e6c7b583a3461a52ef981326cbc..18c2fb5452524ae6014aa2d7aeac8efb0cfd4c9f 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -373,11 +373,11 @@ BOOL LLPreviewGesture::postBuild()
 	mReplaceEditor = edit;
 
 	combo = getChild<LLComboBox>( "modifier_combo");
-	combo->setCommitCallback(onCommitSetDirty, this);
+	combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitKeyorModifier, this));
 	mModifierCombo = combo;
 
 	combo = getChild<LLComboBox>( "key_combo");
-	combo->setCommitCallback(onCommitSetDirty, this);
+	combo->setCommitCallback(boost::bind(&LLPreviewGesture::onCommitKeyorModifier, this));
 	mKeyCombo = combo;
 
 	list = getChild<LLScrollListCtrl>("library_list");
@@ -937,12 +937,16 @@ void LLPreviewGesture::loadUIFromGesture(LLMultiGesture* gesture)
 		break;
 	}
 
+	mModifierCombo->setEnabledByValue(CTRL_LABEL, gesture->mKey != KEY_F10);
+
 	mKeyCombo->setCurrentByIndex(0);
 	if (gesture->mKey != KEY_NONE)
 	{
 		mKeyCombo->setSimple(LLKeyboard::stringFromKey(gesture->mKey));
 	}
 
+	mKeyCombo->setEnabledByValue(LLKeyboard::stringFromKey(KEY_F10), gesture->mMask != MASK_CONTROL);
+
 	// Make UI steps for each gesture step
 	S32 i;
 	S32 count = gesture->mSteps.size();
@@ -1338,6 +1342,17 @@ LLMultiGesture* LLPreviewGesture::createGesture()
 }
 
 
+void LLPreviewGesture::onCommitKeyorModifier()
+{
+	// SL-14139: ctrl-F10 is currently used to access top menu,
+	// so don't allow to bound gestures to this combination.
+
+	mKeyCombo->setEnabledByValue(LLKeyboard::stringFromKey(KEY_F10), mModifierCombo->getSimple() != CTRL_LABEL);
+	mModifierCombo->setEnabledByValue(CTRL_LABEL, mKeyCombo->getSimple() != LLKeyboard::stringFromKey(KEY_F10));
+	mDirty = TRUE;
+	refresh();
+}
+
 // static
 void LLPreviewGesture::updateLabel(LLScrollListItem* item)
 {
diff --git a/indra/newview/llpreviewgesture.h b/indra/newview/llpreviewgesture.h
index 3ba4f562952505e041100a5c23f905d6b920d3b3..ffcada4cc29d136b5f9290434f03595376d4305e 100644
--- a/indra/newview/llpreviewgesture.h
+++ b/indra/newview/llpreviewgesture.h
@@ -103,6 +103,8 @@ class LLPreviewGesture : public LLPreview
 	LLScrollListItem* addStep(const enum EStepType step_type);
 	
 	void onVisibilityChanged ( const LLSD& new_visibility );
+
+	void onCommitKeyorModifier();
 	
 	static std::string getLabel(std::vector<std::string> labels);
 	static void updateLabel(LLScrollListItem* item);
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index de2ae45a4170de25b6f24033d48c777cb260672f..b65430afa9dc70bdc5d2e0fda5953642893e46b1 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -737,7 +737,10 @@ void LLScriptEdCore::updateDynamicHelp(BOOL immediate)
 		}
 		if (immediate || (mLiveHelpTimer.getStarted() && mLiveHelpTimer.getElapsedTimeF32() > LIVE_HELP_REFRESH_TIME))
 		{
-			std::string help_string = mEditor->getText().substr(segment->getStart(), segment->getEnd() - segment->getStart());
+			// Use Wtext since segment's start/end are made for wstring and will
+			// result in a shift for case of multi-byte symbols inside std::string.
+			LLWString segment_text = mEditor->getWText().substr(segment->getStart(), segment->getEnd() - segment->getStart());
+			std::string help_string = wstring_to_utf8str(segment_text);
 			setHelpPage(help_string);
 			mLiveHelpTimer.stop();
 		}
diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp
index 3c9ce6b752a7baf0ca73b326a372f4e6f53919c9..f9baf5fbd30b15fb90a3e353bbe67f858d788cc8 100644
--- a/indra/newview/llscenemonitor.cpp
+++ b/indra/newview/llscenemonitor.cpp
@@ -530,157 +530,163 @@ void LLSceneMonitor::dumpToFile(std::string file_name)
 	if (!hasResults()) return;
 
 	LL_INFOS("SceneMonitor") << "Saving scene load stats to " << file_name << LL_ENDL; 
-
-	llofstream os(file_name.c_str());
-
-	os << std::setprecision(10);
-
-	LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults();
-	const U32 frame_count = scene_load_recording.getNumRecordedPeriods();
-
-	F64Seconds frame_time;
-
-	os << "Stat";
-	for (S32 frame = 1; frame <= frame_count; frame++)
+	try
 	{
-		frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
-		os << ", " << frame_time.value();
-	}
-	os << '\n';
+		llofstream os(file_name.c_str());
 
-	os << "Sample period(s)";
-	for (S32 frame = 1; frame <= frame_count; frame++)
-	{
-		frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
-		os << ", " << frame_time.value();
-	}
-	os << '\n';
+		os << std::setprecision(10);
 
+		LLTrace::PeriodicRecording& scene_load_recording = mSceneLoadRecording.getResults();
+		const U32 frame_count = scene_load_recording.getNumRecordedPeriods();
 
-	typedef LLTrace::StatType<LLTrace::CountAccumulator> trace_count;
-	for (auto& it : trace_count::instance_snapshot())
-	{
-		std::ostringstream row;
-		row << std::setprecision(10);
+		F64Seconds frame_time;
 
-		row << it.getName();
-
-		const char* unit_label = it.getUnitLabel();
-		if(unit_label[0])
+		os << "Stat";
+		for (S32 frame = 1; frame <= frame_count; frame++)
 		{
-			row << "(" << unit_label << ")";
+			frame_time += scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
+			os << ", " << frame_time.value();
 		}
+		os << '\n';
 
-		S32 samples = 0;
-
+		os << "Sample period(s)";
 		for (S32 frame = 1; frame <= frame_count; frame++)
 		{
-			LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
-			samples += recording.getSampleCount(it);
-			row << ", " << recording.getSum(it);
+			frame_time = scene_load_recording.getPrevRecording(frame_count - frame).getDuration();
+			os << ", " << frame_time.value();
 		}
+		os << '\n';
 
-		row << '\n';
 
-		if (samples > 0)
+		typedef LLTrace::StatType<LLTrace::CountAccumulator> trace_count;
+		for (auto& it : trace_count::instance_snapshot())
 		{
-			os << row.str();
-		}
-	}
-
-	typedef LLTrace::StatType<LLTrace::EventAccumulator> trace_event;
+			std::ostringstream row;
+			row << std::setprecision(10);
 
-	for (auto& it : trace_event::instance_snapshot())
-	{
-		std::ostringstream row;
-		row << std::setprecision(10);
-		row << it.getName();
+			row << it.getName();
 
-		const char* unit_label = it.getUnitLabel();
-		if(unit_label[0])
-		{
-			row << "(" << unit_label << ")";
-		}
+			const char* unit_label = it.getUnitLabel();
+			if (unit_label[0])
+			{
+				row << "(" << unit_label << ")";
+			}
 
-		S32 samples = 0;
+			S32 samples = 0;
 
-		for (S32 frame = 1; frame <= frame_count; frame++)
-		{
-			LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
-			samples += recording.getSampleCount(it);
-			F64 mean = recording.getMean(it);
-			if (llisnan(mean))
+			for (S32 frame = 1; frame <= frame_count; frame++)
 			{
-				row << ", n/a";
+				LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+				samples += recording.getSampleCount(it);
+				row << ", " << recording.getSum(it);
 			}
-			else
+
+			row << '\n';
+
+			if (samples > 0)
 			{
-				row << ", " << mean;
+				os << row.str();
 			}
 		}
 
-		row << '\n';
+		typedef LLTrace::StatType<LLTrace::EventAccumulator> trace_event;
 
-		if (samples > 0)
+		for (auto& it : trace_event::instance_snapshot())
 		{
-			os << row.str();
-		}
-	}
+			std::ostringstream row;
+			row << std::setprecision(10);
+			row << it.getName();
 
-	typedef LLTrace::StatType<LLTrace::SampleAccumulator> trace_sample;
+			const char* unit_label = it.getUnitLabel();
+			if (unit_label[0])
+			{
+				row << "(" << unit_label << ")";
+			}
 
-	for (auto& it : trace_sample::instance_snapshot())
-	{
-		std::ostringstream row;
-		row << std::setprecision(10);
-		row << it.getName();
+			S32 samples = 0;
 
-		const char* unit_label = it.getUnitLabel();
-		if(unit_label[0])
-		{
-			row << "(" << unit_label << ")";
+			for (S32 frame = 1; frame <= frame_count; frame++)
+			{
+				LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+				samples += recording.getSampleCount(it);
+				F64 mean = recording.getMean(it);
+				if (llisnan(mean))
+				{
+					row << ", n/a";
+				}
+				else
+				{
+					row << ", " << mean;
+				}
+			}
+
+			row << '\n';
+
+			if (samples > 0)
+			{
+				os << row.str();
+			}
 		}
 
-		S32 samples = 0;
+		typedef LLTrace::StatType<LLTrace::SampleAccumulator> trace_sample;
 
-		for (S32 frame = 1; frame <= frame_count; frame++)
+		for (auto& it : trace_sample::instance_snapshot())
 		{
-			LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
-			samples += recording.getSampleCount(it);
-			F64 mean = recording.getMean(it);
-			if (llisnan(mean))
+			std::ostringstream row;
+			row << std::setprecision(10);
+			row << it.getName();
+
+			const char* unit_label = it.getUnitLabel();
+			if (unit_label[0])
+			{
+				row << "(" << unit_label << ")";
+			}
+
+			S32 samples = 0;
+
+			for (S32 frame = 1; frame <= frame_count; frame++)
 			{
-				row << ", n/a";
+				LLTrace::Recording& recording = scene_load_recording.getPrevRecording(frame_count - frame);
+				samples += recording.getSampleCount(it);
+				F64 mean = recording.getMean(it);
+				if (llisnan(mean))
+				{
+					row << ", n/a";
+				}
+				else
+				{
+					row << ", " << mean;
+				}
 			}
-			else
+
+			row << '\n';
+
+			if (samples > 0)
 			{
-				row << ", " << mean;
+				os << row.str();
 			}
 		}
 
-		row << '\n'; 
-
-		if (samples > 0)
+		typedef LLTrace::StatType<LLTrace::MemAccumulator> trace_mem;
+		for (auto& it : trace_mem::instance_snapshot())
 		{
-			os << row.str();
-		}
-	}
+			os << it.getName() << "(KiB)";
 
-	typedef LLTrace::StatType<LLTrace::MemAccumulator> trace_mem;
-	for (auto& it : trace_mem::instance_snapshot())
-	{
-		os << it.getName() << "(KiB)";
+			for (S32 frame = 1; frame <= frame_count; frame++)
+			{
+				os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits<LLUnits::Kilobytes>();
+			}
 
-		for (S32 frame = 1; frame <= frame_count; frame++)
-		{
-			os << ", " << scene_load_recording.getPrevRecording(frame_count - frame).getMax(it).valueInUnits<LLUnits::Kilobytes>();
+			os << '\n';
 		}
 
-		os << '\n';
+		os.flush();
+		os.close();
+	}
+	catch (const std::ios_base::failure &e)
+	{
+		LL_WARNS() << "Unable to dump scene monitor results: " << e.what() << LL_ENDL;
 	}
-
-	os.flush();
-	os.close();
 }
 
 //-------------------------------------------------------------------------------------------------------------
diff --git a/indra/newview/llsetkeybinddialog.cpp b/indra/newview/llsetkeybinddialog.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4b36822e9ac6cfd06101abcfe35e13a968782403
--- /dev/null
+++ b/indra/newview/llsetkeybinddialog.cpp
@@ -0,0 +1,380 @@
+/** 
+ * @file llsetkeybinddialog.cpp
+ * @brief LLSetKeyBindDialog class implementation.
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2019, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llsetkeybinddialog.h"
+
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "lleventtimer.h"
+#include "llfloaterreg.h"
+#include "llfocusmgr.h"
+#include "llkeyconflict.h"
+#include "llviewercontrol.h"
+
+class LLSetKeyBindDialog::Updater : public LLEventTimer
+{
+public:
+
+    typedef boost::function<void(MASK)> callback_t;
+
+    Updater(callback_t cb, F32 period, MASK mask)
+        :LLEventTimer(period),
+        mMask(mask),
+        mCallback(cb)
+    {
+        mEventTimer.start();
+    }
+
+    virtual ~Updater(){}
+
+protected:
+    BOOL tick()
+    {
+        mCallback(mMask);
+        // Deletes itseft after execution
+        return TRUE;
+    }
+
+private:
+    MASK mMask;
+    callback_t mCallback;
+};
+
+bool LLSetKeyBindDialog::sRecordKeys = false;
+
+LLSetKeyBindDialog::LLSetKeyBindDialog(const LLSD& key)
+    : LLModalDialog(key),
+    pParent(NULL),
+    mKeyFilterMask(DEFAULT_KEY_FILTER),
+    pUpdater(NULL),
+    mLastMaskKey(0),
+    mContextConeOpacity(0.f),
+    mContextConeInAlpha(0.f),
+    mContextConeOutAlpha(0.f),
+    mContextConeFadeTime(0.f)
+{
+	mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
+	mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
+	mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
+}
+
+LLSetKeyBindDialog::~LLSetKeyBindDialog()
+{
+}
+
+//virtual
+BOOL LLSetKeyBindDialog::postBuild()
+{
+    childSetAction("SetEmpty", onBlank, this);
+    childSetAction("Default", onDefault, this);
+    childSetAction("Cancel", onCancel, this);
+    getChild<LLUICtrl>("Cancel")->setFocus(TRUE);
+
+    pCheckBox = getChild<LLCheckBoxCtrl>("apply_all");
+    pDesription = getChild<LLTextBase>("descritption");
+
+    gFocusMgr.setKeystrokesOnly(TRUE);
+
+    return TRUE;
+}
+
+//virtual
+void LLSetKeyBindDialog::onOpen(const LLSD& data)
+{
+     sRecordKeys = true;
+     LLModalDialog::onOpen(data);
+}
+
+//virtual
+void LLSetKeyBindDialog::onClose(bool app_quiting)
+{
+    sRecordKeys = false;
+    if (pParent)
+    {
+        pParent->onCancelKeyBind();
+        pParent = NULL;
+    }
+    if (pUpdater)
+    {
+        // Doubleclick timer has't fired, delete it
+        delete pUpdater;
+        pUpdater = NULL;
+    }
+    LLModalDialog::onClose(app_quiting);
+}
+
+void LLSetKeyBindDialog::drawFrustum()
+{
+    static LLCachedControl<F32> max_opacity(gSavedSettings, "PickerContextOpacity", 0.4f);
+    drawConeToOwner(mContextConeOpacity, max_opacity, mFrustumOrigin.get(), mContextConeFadeTime, mContextConeInAlpha, mContextConeOutAlpha);
+}
+
+//virtual
+void LLSetKeyBindDialog::draw()
+{
+    drawFrustum();
+    LLModalDialog::draw();
+}
+
+void LLSetKeyBindDialog::setParent(LLKeyBindResponderInterface* parent, LLView* frustum_origin, U32 key_mask)
+{
+    pParent = parent;
+    mFrustumOrigin = frustum_origin->getHandle();
+    mKeyFilterMask = key_mask;
+
+    std::string input;
+    if ((key_mask & ALLOW_MOUSE) != 0)
+    {
+        input = getString("mouse");
+    }
+    if ((key_mask & ALLOW_KEYS) != 0)
+    {
+        if (!input.empty())
+        {
+            input += ", ";
+        }
+        input += getString("keyboard");
+    }
+    pDesription->setText(getString("basic_description"));
+    pDesription->setTextArg("[INPUT]", input);
+}
+
+// static
+bool LLSetKeyBindDialog::recordKey(KEY key, MASK mask, BOOL down)
+{
+    if (sRecordKeys)
+    {
+        LLSetKeyBindDialog* dialog = LLFloaterReg::getTypedInstance<LLSetKeyBindDialog>("keybind_dialog", LLSD());
+        if (dialog && dialog->getVisible())
+        {
+            return dialog->recordAndHandleKey(key, mask, down);
+        }
+        else
+        {
+            LL_WARNS() << "Key recording was set despite no open dialog" << LL_ENDL;
+            sRecordKeys = false;
+        }
+    }
+    return false;
+}
+
+bool LLSetKeyBindDialog::recordAndHandleKey(KEY key, MASK mask, BOOL down)
+{
+    if ((key == 'Q' && mask == MASK_CONTROL)
+        || key == KEY_ESCAPE)
+    {
+        sRecordKeys = false;
+        closeFloater();
+        return true;
+    }
+
+    if (key == KEY_DELETE)
+    {
+        setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false);
+        sRecordKeys = false;
+        closeFloater();
+        return false;
+    }
+
+    // forbidden keys
+    if (key == KEY_NONE
+        || key == KEY_RETURN
+        || key == KEY_BACKSPACE)
+    {
+        return false;
+    }
+
+    if (key == KEY_CONTROL || key == KEY_SHIFT || key == KEY_ALT)
+    {
+        // Mask keys get special treatment
+        if ((mKeyFilterMask & ALLOW_MASKS) == 0)
+        {
+            // Masks by themself are not allowed
+            return false;
+        }
+        if (down == TRUE)
+        {
+            // Most keys are handled on 'down' event because menu is handled on 'down'
+            // masks are exceptions to let other keys be handled
+            mLastMaskKey = key;
+            return false;
+        }
+        if (mLastMaskKey != key)
+        {
+            // This was mask+key combination that got rejected, don't handle mask's key
+            // Or user did something like: press shift, press ctrl, release shift
+            return false;
+        }
+        // Mask up event often generates things like 'shift key + shift mask', filter it out.
+        if (key == KEY_CONTROL)
+        {
+            mask &= ~MASK_CONTROL;
+        }
+        if (key == KEY_SHIFT)
+        {
+            mask &= ~MASK_SHIFT;
+        }
+        if (key == KEY_ALT)
+        {
+            mask &= ~MASK_ALT;
+        }
+    }
+    if ((mKeyFilterMask & ALLOW_KEYS) == 0)
+    {
+        // basic keys not allowed
+        return false;
+    }
+    else if ((mKeyFilterMask & ALLOW_MASK_KEYS) == 0 && mask != 0)
+    {
+        // masked keys not allowed
+        return false;
+    }
+
+    if (LLKeyConflictHandler::isReservedByMenu(key, mask))
+    {
+        pDesription->setText(getString("reserved_by_menu"));
+        pDesription->setTextArg("[KEYSTR]", LLKeyboard::stringFromAccelerator(mask,key));
+        mLastMaskKey = 0;
+        return true;
+    }
+
+    setKeyBind(CLICK_NONE, key, mask, pCheckBox->getValue().asBoolean());
+    // Note/Todo: To warranty zero interference we should also consume
+    // an 'up' event if we recorded on 'down', not just close floater
+    // on first recorded combination.
+    sRecordKeys = false;
+    closeFloater();
+    return true;
+}
+
+BOOL LLSetKeyBindDialog::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)
+{
+    BOOL result = FALSE;
+    if (!pParent)
+    {
+        // we already processed 'down' event, this is 'up', consume
+        closeFloater();
+        result = TRUE;
+    }
+    if (!result && clicktype == CLICK_LEFT)
+    {
+        // try handling buttons first
+        if (down)
+        {
+            result = LLView::handleMouseDown(x, y, mask);
+        }
+        else
+        {
+            result = LLView::handleMouseUp(x, y, mask);
+        }
+        if (result)
+        {
+            setFocus(TRUE);
+            gFocusMgr.setKeystrokesOnly(TRUE);
+        }
+        // ignore selection related combinations
+        else if (down && (mask & (MASK_SHIFT | MASK_CONTROL)) == 0)
+        {
+            // this can be a double click, wait a bit;
+            if (!pUpdater)
+            {
+                // Note: default doubleclick time is 500ms, but can stretch up to 5s
+                pUpdater = new Updater(boost::bind(&onClickTimeout, this, _1), 0.7f, mask);
+                result = TRUE;
+            }
+        }
+    }
+
+    if (!result
+        && (clicktype != CLICK_LEFT) // subcases were handled above
+        && ((mKeyFilterMask & ALLOW_MOUSE) != 0)
+        && (clicktype != CLICK_RIGHT || mask != 0) // reassigning menu button is not supported
+        && ((mKeyFilterMask & ALLOW_MASK_MOUSE) != 0 || mask == 0)) // reserved for selection
+    {
+        setKeyBind(clicktype, KEY_NONE, mask, pCheckBox->getValue().asBoolean());
+        result = TRUE;
+        if (!down)
+        {
+            // wait for 'up' event before closing
+            // alternative: set pUpdater
+            closeFloater();
+        }
+    }
+
+    return result;
+}
+
+//static
+void LLSetKeyBindDialog::onCancel(void* user_data)
+{
+    LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data;
+    self->closeFloater();
+}
+
+//static
+void LLSetKeyBindDialog::onBlank(void* user_data)
+{
+    LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data;
+    // tmp needs 'no key' button
+    self->setKeyBind(CLICK_NONE, KEY_NONE, MASK_NONE, false);
+    self->closeFloater();
+}
+
+//static
+void LLSetKeyBindDialog::onDefault(void* user_data)
+{
+    LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data;
+    if (self->pParent)
+    {
+        self->pParent->onDefaultKeyBind(self->pCheckBox->getValue().asBoolean());
+        self->pParent = NULL;
+    }
+    self->closeFloater();
+}
+
+//static
+void LLSetKeyBindDialog::onClickTimeout(void* user_data, MASK mask)
+{
+    LLSetKeyBindDialog* self = (LLSetKeyBindDialog*)user_data;
+
+    // timer will delete itself after timeout
+    self->pUpdater = NULL;
+
+    self->setKeyBind(CLICK_LEFT, KEY_NONE, mask, self->pCheckBox->getValue().asBoolean());
+    self->closeFloater();
+}
+
+void LLSetKeyBindDialog::setKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes)
+{
+    if (pParent)
+    {
+        pParent->onSetKeyBind(click, key, mask, all_modes);
+        pParent = NULL;
+    }
+}
+
diff --git a/indra/newview/llsetkeybinddialog.h b/indra/newview/llsetkeybinddialog.h
new file mode 100644
index 0000000000000000000000000000000000000000..a34b9522336006f6feb1781819d58d51ca6c2956
--- /dev/null
+++ b/indra/newview/llsetkeybinddialog.h
@@ -0,0 +1,106 @@
+/** 
+ * @file llsetkeybinddialog.h
+ * @brief LLSetKeyBindDialog class definition
+ *
+ * $LicenseInfo:firstyear=2019&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2019, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_LLSETKEYBINDDIALOG_H
+#define LL_LLSETKEYBINDDIALOG_H
+
+#include "llmodaldialog.h"
+
+class LLCheckBoxCtrl;
+class LLTextBase;
+
+// Filters for LLSetKeyBindDialog
+static const U32 ALLOW_MOUSE = 1;
+static const U32 ALLOW_MASK_MOUSE = 2;
+static const U32 ALLOW_KEYS = 4; //keyboard
+static const U32 ALLOW_MASK_KEYS = 8;
+static const U32 ALLOW_MASKS = 16;
+static const U32 DEFAULT_KEY_FILTER = ALLOW_MOUSE | ALLOW_MASK_MOUSE | ALLOW_KEYS | ALLOW_MASKS | ALLOW_MASK_KEYS;
+
+
+class LLKeyBindResponderInterface
+{
+public:
+    virtual ~LLKeyBindResponderInterface() {};
+
+    virtual void onCancelKeyBind() = 0;
+    virtual void onDefaultKeyBind(bool all_modes) = 0;
+    // returns true if parent failed to set key due to key being in use
+    virtual bool onSetKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes) = 0;
+};
+
+class LLSetKeyBindDialog : public LLModalDialog
+{
+public:
+    LLSetKeyBindDialog(const LLSD& key);
+    ~LLSetKeyBindDialog();
+
+    /*virtual*/ BOOL postBuild();
+    /*virtual*/ void onOpen(const LLSD& data);
+    /*virtual*/ void onClose(bool app_quiting);
+    /*virtual*/ void draw();
+
+    void setParent(LLKeyBindResponderInterface* parent, LLView* frustum_origin, U32 key_mask = DEFAULT_KEY_FILTER);
+
+    // Wrapper around recordAndHandleKey
+    // It does not record, it handles, but handleKey function is already in use
+    static bool recordKey(KEY key, MASK mask, BOOL down);
+
+    BOOL handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down);
+    static void onCancel(void* user_data);
+    static void onBlank(void* user_data);
+    static void onDefault(void* user_data);
+    static void onClickTimeout(void* user_data, MASK mask);
+
+    class Updater;
+
+private:
+    bool recordAndHandleKey(KEY key, MASK mask, BOOL down);
+    void setKeyBind(EMouseClickType click, KEY key, MASK mask, bool all_modes);
+    LLKeyBindResponderInterface *pParent;
+    LLCheckBoxCtrl *pCheckBox;
+    LLTextBase *pDesription;
+
+    U32 mKeyFilterMask;
+    Updater *pUpdater;
+    KEY mLastMaskKey;
+
+    static bool sRecordKeys; // for convinience and not to check instance each time
+
+    // drawFrustum
+private:
+    void drawFrustum();
+
+    LLHandle <LLView>   mFrustumOrigin;
+    F32                 mContextConeOpacity;
+    F32                 mContextConeInAlpha;
+    F32                 mContextConeOutAlpha;
+    F32                 mContextConeFadeTime;
+};
+
+
+#endif  // LL_LLSETKEYBINDDIALOG_H
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index e0d15b123b68c197fab5fa8af68ecaedb7ac397b..85feae32c34bfb97c6262d06cf04396b5532f13c 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -164,8 +164,12 @@ void LLSidepanelAppearance::onOpen(const LLSD& key)
 		std::string type = key["type"].asString();
 		if (type == "my_outfits")
 		{
-			showOutfitsInventoryPanel();
+			showOutfitsInventoryPanel("outfitslist_tab");
 		}
+        else if (type == "now_wearing")
+        {
+            showOutfitsInventoryPanel("cof_tab");
+        }
 		else if (type == "edit_outfit")
 		{
 			showOutfitEditPanel();
@@ -287,7 +291,14 @@ void LLSidepanelAppearance::showOutfitsInventoryPanel()
 {
 	toggleWearableEditPanel(FALSE);
 	toggleOutfitEditPanel(FALSE);
-	toggleMyOutfitsPanel(TRUE);
+	toggleMyOutfitsPanel(TRUE, "");
+}
+
+void LLSidepanelAppearance::showOutfitsInventoryPanel(const std::string &tab_name)
+{
+    toggleWearableEditPanel(FALSE);
+    toggleOutfitEditPanel(FALSE);
+    toggleMyOutfitsPanel(TRUE, tab_name);
 }
 
 void LLSidepanelAppearance::showOutfitEditPanel()
@@ -312,37 +323,42 @@ void LLSidepanelAppearance::showOutfitEditPanel()
 		return;
 	}
 
-	toggleMyOutfitsPanel(FALSE);
+	toggleMyOutfitsPanel(FALSE, "");
 	toggleWearableEditPanel(FALSE, NULL, TRUE); // don't switch out of edit appearance mode
 	toggleOutfitEditPanel(TRUE);
 }
 
 void LLSidepanelAppearance::showWearableEditPanel(LLViewerWearable *wearable /* = NULL*/, BOOL disable_camera_switch)
 {
-	toggleMyOutfitsPanel(FALSE);
+	toggleMyOutfitsPanel(FALSE, "");
 	toggleOutfitEditPanel(FALSE, TRUE); // don't switch out of edit appearance mode
 	toggleWearableEditPanel(TRUE, wearable, disable_camera_switch);
 }
 
-void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible)
+void LLSidepanelAppearance::toggleMyOutfitsPanel(BOOL visible, const std::string& tab_name)
 {
-	if (!mPanelOutfitsInventory || mPanelOutfitsInventory->getVisible() == visible)
-	{
-		// visibility isn't changing, hence nothing to do
-		return;
-	}
-
-	mPanelOutfitsInventory->setVisible(visible);
-
-	// *TODO: Move these controls to panel_outfits_inventory.xml
-	// so that we don't need to toggle them explicitly.
-	mFilterEditor->setVisible(visible);
-	mCurrOutfitPanel->setVisible(visible);
-
-	if (visible)
-	{
-		mPanelOutfitsInventory->onOpen(LLSD());
-	}
+    if (!mPanelOutfitsInventory
+        || (mPanelOutfitsInventory->getVisible() == visible && tab_name.empty()))
+    {
+        // visibility isn't changing, hence nothing to do
+        return;
+    }
+
+    mPanelOutfitsInventory->setVisible(visible);
+
+    // *TODO: Move these controls to panel_outfits_inventory.xml
+    // so that we don't need to toggle them explicitly.
+    mFilterEditor->setVisible(visible);
+    mCurrOutfitPanel->setVisible(visible);
+
+    if (visible)
+    {
+        mPanelOutfitsInventory->onOpen(LLSD());
+        if (!tab_name.empty())
+        {
+            mPanelOutfitsInventory->openApearanceTab(tab_name);
+        }
+    }
 }
 
 void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch)
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index 93f23a29f330ad5265e9c709e2eca876d45bccda..3607a405e7ef14f3cfd4a960c4046eb6dd6d0514 100644
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -56,7 +56,8 @@ class LLSidepanelAppearance : public LLPanel
 	void fetchInventory();
 	void inventoryFetched();
 
-	void showOutfitsInventoryPanel();
+    void showOutfitsInventoryPanel(); // last selected
+	void showOutfitsInventoryPanel(const std::string& tab_name);
 	void showOutfitEditPanel();
 	void showWearableEditPanel(LLViewerWearable *wearable = NULL, BOOL disable_camera_switch = FALSE);
 	void setWearablesLoading(bool val);
@@ -80,7 +81,7 @@ class LLSidepanelAppearance : public LLPanel
 	void onOpenOutfitButtonClicked();
 	void onEditAppearanceButtonClicked();
 
-	void toggleMyOutfitsPanel(BOOL visible);
+	void toggleMyOutfitsPanel(BOOL visible, const std::string& tab_name);
 	void toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch = FALSE);
 	void toggleWearableEditPanel(BOOL visible, LLViewerWearable* wearable = NULL, BOOL disable_camera_switch = FALSE);
 
diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp
index 1fb63c7444c1d9a21253bb2b65a4583b171ac64d..f325315933869a04eb8e101a07d9c2e71f75440a 100644
--- a/indra/newview/llskinningutil.cpp
+++ b/indra/newview/llskinningutil.cpp
@@ -309,7 +309,8 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a
     if (vol_face.mJointRiggingInfoTab.needsUpdate())
     {
         S32 num_verts = vol_face.mNumVertices;
-        if (num_verts>0 && vol_face.mWeights && (skin->mJointNames.size()>0))
+        S32 num_joints = skin->mJointNames.size();
+        if (num_verts > 0 && vol_face.mWeights && num_joints > 0)
         {
             initJointNums(const_cast<LLMeshSkinInfo*>(skin), avatar);
             if (vol_face.mJointRiggingInfoTab.size()==0)
@@ -343,7 +344,7 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a
                     for (U32 k=0; k<4; ++k)
                     {
 						S32 joint_index = idx[k];
-                        if (wght[k] > 0.0f)
+                        if (wght[k] > 0.0f && num_joints > joint_index)
                         {
                             S32 joint_num = skin->mJointNums[joint_index];
                             if (joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS)
@@ -394,35 +395,6 @@ void LLSkinningUtil::updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *a
     }
 }
 
-void LLSkinningUtil::updateRiggingInfo_(LLMeshSkinInfo* skin, LLVOAvatar *avatar, S32 num_verts, LLVector4a* weights, LLVector4a* positions, U8* joint_indices, LLJointRiggingInfoTab &rig_info_tab)
-{
-    LL_RECORD_BLOCK_TIME(FTM_FACE_RIGGING_INFO);
-    for (S32 i=0; i < num_verts; i++)
-    {
-        LLVector4a& pos  = positions[i];
-        LLVector4a& wght = weights[i];
-        for (U32 k=0; k<4; ++k)
-        {
-            S32 joint_num = skin->mJointNums[joint_indices[k]];
-            llassert(joint_num >= 0 && joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS);
-            {
-                rig_info_tab[joint_num].setIsRiggedTo(true);
-                LLMatrix4a bind_shape;
-                bind_shape.loadu(skin->mBindShapeMatrix);
-                LLMatrix4a inv_bind;
-                inv_bind.loadu(skin->mInvBindMatrix[joint_indices[k]]);
-                LLMatrix4a mat;
-                matMul(bind_shape, inv_bind, mat);
-                LLVector4a pos_joint_space;
-                mat.affineTransform(pos, pos_joint_space);
-                pos_joint_space.mul(wght[k]);
-                LLVector4a *extents = rig_info_tab[joint_num].getRiggedExtents();
-                update_min_max(extents[0], extents[1], pos_joint_space);
-            }
-        }
-    }
-}
-
 // This is used for extracting rotation from a bind shape matrix that
 // already has scales baked in
 LLQuaternion LLSkinningUtil::getUnscaledQuaternion(const LLMatrix4& mat4)
diff --git a/indra/newview/llskinningutil.h b/indra/newview/llskinningutil.h
index 549aa6a29f7c9c81607296010513c10bb92119b8..efe7c85997d4281623d955a116e81f8db032a039 100644
--- a/indra/newview/llskinningutil.h
+++ b/indra/newview/llskinningutil.h
@@ -67,7 +67,6 @@ namespace LLSkinningUtil
 
     void initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar);
     void updateRiggingInfo(const LLMeshSkinInfo* skin, LLVOAvatar *avatar, LLVolumeFace& vol_face);
-    void updateRiggingInfo_(LLMeshSkinInfo* skin, LLVOAvatar *avatar, S32 num_verts, LLVector4a* weights, LLVector4a* positions, U8* joint_indices, LLJointRiggingInfoTab &rig_info_tab);
 	LLQuaternion getUnscaledQuaternion(const LLMatrix4& mat4);
 };
 
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 8fc2405f0a683af59efb6ab539aa601a9a3fdc6e..efa4a7fd66b55b27643c8d0ef1d07b25efbb2da2 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -996,7 +996,7 @@ LLSpatialGroup *LLSpatialPartition::put(LLDrawable *drawablep, BOOL was_visible)
 	}	
 	
 	LLSpatialGroup* group = drawablep->getSpatialGroup();
-	llassert(group != NULL);
+	//llassert(group != NULL);
 
 	if (group && was_visible && group->isOcclusionState(LLSpatialGroup::QUERY_PENDING))
 	{
@@ -2253,52 +2253,91 @@ void renderBoundingBox(LLDrawable* drawable, BOOL set_color = TRUE)
 	}
 }
 
-void renderNormals(LLDrawable* drawablep)
+void renderNormals(LLDrawable *drawablep)
 {
-	LLVertexBuffer::unbind();
+    if (!drawablep->isVisible())
+        return;
 
-	LLVOVolume* vol = drawablep->getVOVolume();
-	if (vol)
-	{
-		LLVolume* volume = vol->getVolume();
-		gGL.pushMatrix();
-		gGL.multMatrix((F32*) vol->getRelativeXform().mMatrix);
-		
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+    LLVertexBuffer::unbind();
 
-		LLVector4a scale(gSavedSettings.getF32("RenderDebugNormalScale"));
+    LLVOVolume *vol = drawablep->getVOVolume();
 
-		for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
-		{
-			const LLVolumeFace& face = volume->getVolumeFace(i);
+    if (vol)
+    {
+        LLVolume *volume = vol->getVolume();
 
-			for (S32 j = 0; j < face.mNumVertices; ++j)
-			{
-				gGL.begin(LLRender::LINES);
-				LLVector4a n,p;
-				
-				n.setMul(face.mNormals[j], scale);
-				p.setAdd(face.mPositions[j], n);
-				
-				gGL.diffuseColor4f(1,1,1,1);
-				gGL.vertex3fv(face.mPositions[j].getF32ptr());
-				gGL.vertex3fv(p.getF32ptr());
-				
-				if (face.mTangents)
-				{
-					n.setMul(face.mTangents[j], scale);
-					p.setAdd(face.mPositions[j], n);
-				
-					gGL.diffuseColor4f(0,1,1,1);
-					gGL.vertex3fv(face.mPositions[j].getF32ptr());
-					gGL.vertex3fv(p.getF32ptr());
-				}	
-				gGL.end();
-			}
-		}
+        // Drawable's normals & tangents are stored in model space, i.e. before any scaling is applied.
+        //
+        // SL-13490, using pos + normal to compute the 2nd vertex of a normal line segment doesn't
+        // work when there's a non-uniform scale in the mix. Normals require MVP-inverse-transpose
+        // transform. We get that effect here by pre-applying the inverse scale (twice, because
+        // one forward scale will be re-applied via the MVP in the vertex shader)
 
-		gGL.popMatrix();
-	}
+        LLVector3  scale_v3 = vol->getScale();
+        float      scale_len = scale_v3.length();
+        LLVector4a obj_scale(scale_v3.mV[VX], scale_v3.mV[VY], scale_v3.mV[VZ]);
+        obj_scale.normalize3();
+
+        // Normals &tangent line segments get scaled along with the object. Divide by scale length
+        // to keep the as-viewed lengths (relatively) constant with the debug setting length
+        float draw_length = gSavedSettings.getF32("RenderDebugNormalScale") / scale_len;
+
+        // Create inverse-scale vector for normals
+        LLVector4a inv_scale(1.0 / scale_v3.mV[VX], 1.0 / scale_v3.mV[VY], 1.0 / scale_v3.mV[VZ]);
+        inv_scale.mul(inv_scale);  // Squared, to apply inverse scale twice
+        inv_scale.normalize3fast();
+
+        gGL.pushMatrix();
+        gGL.multMatrix((F32 *) vol->getRelativeXform().mMatrix);
+
+        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+        for (S32 i = 0; i < volume->getNumVolumeFaces(); ++i)
+        {
+            const LLVolumeFace &face = volume->getVolumeFace(i);
+
+            gGL.flush();
+            gGL.diffuseColor4f(1, 1, 0, 1);
+            gGL.begin(LLRender::LINES);
+            for (S32 j = 0; j < face.mNumVertices; ++j)
+            {
+                LLVector4a n, p;
+
+                n.setMul(face.mNormals[j], 1.0);
+                n.mul(inv_scale);  // Pre-scale normal, so it's left with an inverse-transpose xform after MVP
+                n.normalize3fast();
+                n.mul(draw_length);
+                p.setAdd(face.mPositions[j], n);
+
+                gGL.vertex3fv(face.mPositions[j].getF32ptr());
+                gGL.vertex3fv(p.getF32ptr());
+            }
+            gGL.end();
+
+            // Tangents are simple vectors and do not require reorientation via pre-scaling
+            if (face.mTangents)
+            {
+                gGL.flush();
+                gGL.diffuseColor4f(0, 1, 1, 1);
+                gGL.begin(LLRender::LINES);
+                for (S32 j = 0; j < face.mNumVertices; ++j)
+                {
+                    LLVector4a t, p;
+
+                    t.setMul(face.mTangents[j], 1.0f);
+                    t.normalize3fast();
+                    t.mul(draw_length);
+                    p.setAdd(face.mPositions[j], t);
+
+                    gGL.vertex3fv(face.mPositions[j].getF32ptr());
+                    gGL.vertex3fv(p.getF32ptr());
+                }
+                gGL.end();
+            }
+        }
+
+        gGL.popMatrix();
+    }
 }
 
 S32 get_physics_detail(const LLVolumeParams& volume_params, const LLVector3& scale)
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 190c56941211ea6dfc7972f18e860ed74e34bf49..4e53bd249a03bc7980da5c9db23ca8689f556a33 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -128,10 +128,12 @@
 #include "llpanelpick.h"
 #include "llpanelgrouplandmoney.h"
 #include "llpanelgroupnotices.h"
+#include "llparcel.h"
 #include "llpreview.h"
 #include "llpreviewscript.h"
 #include "llproxy.h"
 #include "llproductinforequest.h"
+#include "llqueryflags.h"
 #include "llselectmgr.h"
 #include "llsky.h"
 #include "llstatview.h"
@@ -142,6 +144,7 @@
 #include "lltoolmgr.h"
 #include "lltrans.h"
 #include "llui.h"
+#include "lluiusage.h"
 #include "llurldispatcher.h"
 #include "llurlentry.h"
 #include "llslurl.h"
@@ -176,6 +179,7 @@
 #include "pipeline.h"
 #include "llappviewer.h"
 #include "llfasttimerview.h"
+#include "lltelemetry.h"
 #include "llfloatermap.h"
 #include "llweb.h"
 #include "llvoiceclient.h"
@@ -231,7 +235,6 @@ extern S32 gStartImageHeight;
 static bool gGotUseCircuitCodeAck = false;
 static std::string sInitialOutfit;
 static std::string sInitialOutfitGender;	// "male" or "female"
-static boost::signals2::connection sWearablesLoadedCon;
 
 static bool gUseCircuitCallbackCalled = false;
 
@@ -530,6 +533,8 @@ bool idle_startup()
 			}
 
 			#if LL_WINDOWS
+                LLPROFILE_STARTUP();
+
 				// On the windows dev builds, unpackaged, the message.xml file will 
 				// be located in indra/build-vc**/newview/<config>/app_settings.
 				std::string message_path = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"message.xml");
@@ -1450,7 +1455,10 @@ bool idle_startup()
 
 		// update the voice settings *after* gCacheName initialization
 		// so that we can construct voice UI that relies on the name cache
-		LLVoiceClient::getInstance()->updateSettings();
+		if (LLVoiceClient::instanceExists())
+		{
+			LLVoiceClient::getInstance()->updateSettings();
+		}
 		display_startup();
 
 		// create a container's instance for start a controlling conversation windows
@@ -1689,8 +1697,20 @@ bool idle_startup()
 	if (STATE_INVENTORY_SEND == LLStartUp::getStartupState())
 	{
 		display_startup();
+
+        // request mute list
+        LL_INFOS() << "Requesting Mute List" << LL_ENDL;
+        LLMuteList::getInstance()->requestFromServer(gAgent.getID());
+
+        // Get L$ and ownership credit information
+        LL_INFOS() << "Requesting Money Balance" << LL_ENDL;
+        LLStatusBar::sendMoneyBalanceRequest();
+
+        display_startup();
+
 		// Inform simulator of our language preference
 		LLAgentLanguage::update();
+
 		display_startup();
 		// unpack thin inventory
 		LLSD response = LLLoginInstance::getInstance()->getResponse();
@@ -1857,14 +1877,6 @@ bool idle_startup()
 		LLLandmark::registerCallbacks(msg);
 		display_startup();
 
-		// request mute list
-		LL_INFOS() << "Requesting Mute List" << LL_ENDL;
-		LLMuteList::getInstance()->requestFromServer(gAgent.getID());
-		display_startup();
-		// Get L$ and ownership credit information
-		LL_INFOS() << "Requesting Money Balance" << LL_ENDL;
-		LLStatusBar::sendMoneyBalanceRequest();
-		display_startup();
 		// request all group information
 		LL_INFOS() << "Requesting Agent Data" << LL_ENDL;
 		gAgent.sendAgentDataUpdateRequest();
@@ -1929,10 +1941,6 @@ bool idle_startup()
 			// Set the show start location to true, now that the user has logged
 			// on with this install.
 			gSavedSettings.setBOOL("ShowStartLocation", TRUE);
-
-			// Open Conversation floater on first login.
-			LLFloaterReg::toggleInstanceOrBringToFront("im_container");
-
 		}
 
 		display_startup();
@@ -2290,6 +2298,16 @@ bool idle_startup()
 
 		gAgentAvatarp->sendHoverHeight();
 
+		// look for parcels we own
+		send_places_query(LLUUID::null,
+			LLUUID::null,
+			"",
+			DFQ_AGENT_OWNED,
+			LLParcel::C_ANY,
+			"");
+
+		LLUIUsage::instance().clear();
+
 		return TRUE;
 	}
 
@@ -2725,11 +2743,6 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 	}
 	else
 	{
-		// FIXME SH-3860 - this creates a race condition, where COF
-		// changes (base outfit link added) after appearance update
-		// request has been submitted.
-		sWearablesLoadedCon = gAgentWearables.addLoadedCallback(LLStartUp::saveInitialOutfit);
-
 		bool do_copy = true;
 		bool do_append = false;
 		LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
@@ -2743,23 +2756,6 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 	gAgentWearables.sendDummyAgentWearablesUpdate();
 }
 
-//static
-void LLStartUp::saveInitialOutfit()
-{
-	if (sInitialOutfit.empty()) {
-		LL_DEBUGS() << "sInitialOutfit is empty" << LL_ENDL;
-		return;
-	}
-	
-	if (sWearablesLoadedCon.connected())
-	{
-		LL_DEBUGS("Avatar") << "sWearablesLoadedCon is connected, disconnecting" << LL_ENDL;
-		sWearablesLoadedCon.disconnect();
-	}
-	LL_DEBUGS("Avatar") << "calling makeNewOutfitLinks( \"" << sInitialOutfit << "\" )" << LL_ENDL;
-	LLAppearanceMgr::getInstance()->makeNewOutfitLinks(sInitialOutfit,false);
-}
-
 std::string& LLStartUp::getInitialOutfitName()
 {
 	return sInitialOutfit;
@@ -3570,11 +3566,6 @@ bool process_login_success_response()
 	}
 
 	// Request the map server url
-	// Non-agni grids have a different default location.
-	if (!LLGridManager::getInstance()->isInProductionGrid())
-	{
-		gSavedSettings.setString("MapServerURL", "http://test.map.secondlife.com.s3.amazonaws.com/");
-	}
 	std::string map_server_url = response["map-server-url"];
 	if(!map_server_url.empty())
 	{
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 3ec3ff413301252fc1788610e9952f0c00317f90..116aeb36a735ce1984080ec452a022e444f2b8d4 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -110,9 +110,6 @@ class LLStartUp
 	static void loadInitialOutfit( const std::string& outfit_folder_name,
 								   const std::string& gender_name );
 
-	//save loaded initial outfit into My Outfits category
-	static void saveInitialOutfit();
-
 	static std::string& getInitialOutfitName();
 	static std::string getUserId();
 	
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index ebee2b49e55f765801c26564defb0176fb20b22a..8910ea093ece32c282541606630e04c756285b7e 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -415,7 +415,20 @@ void LLStatusBar::sendMoneyBalanceRequest()
 	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
 	msg->nextBlockFast(_PREHASH_MoneyData);
 	msg->addUUIDFast(_PREHASH_TransactionID, LLUUID::null );
-	gAgent.sendReliableMessage();
+
+    if (gDisconnected)
+    {
+        LL_DEBUGS() << "Trying to send message when disconnected, skipping balance request!" << LL_ENDL;
+        return;
+    }
+    if (!gAgent.getRegion())
+    {
+        LL_DEBUGS() << "LLAgent::sendReliableMessage No region for agent yet, skipping balance request!" << LL_ENDL;
+        return;
+    }
+    // Double amount of retries due to this request initially happening during busy stage
+    // Ideally this should be turned into a capability
+    gMessageSystem->sendReliable(gAgent.getRegionHost(), LL_DEFAULT_RELIABLE_RETRIES * 2, TRUE, LL_PING_BASED_TIMEOUT_DUMMY, NULL, NULL);
 }
 
 
diff --git a/indra/newview/lltelemetry.cpp b/indra/newview/lltelemetry.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0c63e2fede5d45b4b56949d9399d812a98c166f4
--- /dev/null
+++ b/indra/newview/lltelemetry.cpp
@@ -0,0 +1,145 @@
+ /**
+ * @file lltelemetry.cpp
+ * @brief Wrapper for Rad Game Tools Telemetry
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lltelemetry.h"
+
+#if LLPROFILE_USE_RAD_TELEMETRY_PROFILER
+    #if LL_WINDOWS
+        #include "llwin32headers.h"
+
+        // build-vc120-64\packages\lib\release
+        // build-vc150-64\packages\lib\release
+        #ifdef _MSC_VER
+            #pragma comment(lib,"rad_tm_win64.lib")
+        #else
+            #pragma message "NOTE: Rad GameTools Telemetry requested but non-MSVC compiler not yet supported on Windows"
+        #endif
+    #endif // LL_WINDOWS
+
+    #if LL_DARWIN
+        #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Darwin"
+    #endif
+
+    #if LL_LINUX
+        #pragma message "NOTE: Rad Game Tools Telemetry requested but not yet supported on Linux"
+    #endif
+
+//
+// local consts
+//
+static const tm_int32 TELEMETRY_BUFFER_SIZE  = 8 * 1024 * 1024;
+
+//
+// local globals
+//
+static char *gTelemetryBufferPtr = NULL; // Telemetry
+
+static const char *tm_status[ TMERR_INIT_NETWORKING_FAILED + 1 ] =
+{
+      "Telemetry pass: connected"                       // TM_OK
+    , "Telemetry FAIL: disabled via #define NTELEMETRY" // TMERR_DISABLED
+    , "Telemetry FAIL: invalid paramater"               // TMERR_INVALID_PARAM
+    , "Telemetry FAIL: DLL not found"                   // TMERR_NULL_API
+    , "Telemetry FAIL: out of resources"                // TMERR_OUT_OF_RESOURCES
+    , "Telemetry FAIL: tmInitialize() not called"       // TMERR_UNINITIALIZED
+    , "Telemetry FAIL: bad hostname"                    // TMERR_BAD_HOSTNAME
+    , "Telemetry FAIL: couldn't connect to server"      // TMERR_COULD_NOT_CONNECT
+    , "Telemetry FAIL: unknown network error"           // TMERR_UNKNOWN_NETWORK
+    , "Telemetry FAIL: tmShutdown() already called"     // TMERR_ALREADY_SHUTDOWN
+    , "Telemetry FAIL: memory buffer too small"         // TMERR_ARENA_TOO_SMALL
+    , "Telemetry FAIL: server handshake error"          // TMERR_BAD_HANDSHAKE
+    , "Telemetry FAIL: unaligned parameters"            // TMERR_UNALIGNED
+    , "Telemetry FAIL: network not initialized"         // TMERR_NETWORK_NOT_INITIALIZED -- WSAStartup not called before tmOpen()
+    , "Telemetry FAIL: bad version"                     // TMERR_BAD_VERSION
+    , "Telemetry FAIL: timer too large"                 // TMERR_BAD_TIMER
+    , "Telemetry FAIL: tmOpen() already called"         // TMERR_ALREADY_OPENED
+    , "Telemetry FAIL: tmInitialize() already called"   // TMERR_ALREADY_INITIALIZED
+    , "Telemetry FAIL: could't open file"               // TMERR_FILE_OPEN_FAILED
+    , "Telemetry FAIL: tmOpen() failed networking"      // TMERR_INIT_NETWORKING_FAILED
+};
+
+//
+// exported functionality
+//
+
+void telemetry_shutdown()
+{
+    #if LL_WINDOWS
+        if (gTelemetryBufferPtr)
+        {
+            tmClose(0);
+            tmShutdown();
+
+            delete[] gTelemetryBufferPtr;
+            gTelemetryBufferPtr = NULL;
+        }
+    #endif
+}
+
+void telemetry_startup()
+{
+    #if LL_WINDOWS
+        tmLoadLibrary(TM_RELEASE); // Loads .dll
+
+        gTelemetryBufferPtr = new char[ TELEMETRY_BUFFER_SIZE ];
+        tmInitialize(TELEMETRY_BUFFER_SIZE, gTelemetryBufferPtr);
+
+        tm_error telemetry_status = tmOpen(
+            0,                     // unused
+            "SecondLife",          // app name
+            __DATE__ " " __TIME__, // build identifier
+            "localhost",           // server name (or filename)
+            TMCT_TCP,              // connection type (or TMCT_FILE)
+            4719,                  // port
+            TMOF_INIT_NETWORKING,  // open flags
+            250 );                 // timeout ms
+
+        if (telemetry_status == TMERR_UNKNOWN)
+        {
+            LL_ERRS() << "Telemetry FAIL: unknown error" << LL_ENDL;
+        }
+        else if (telemetry_status && (telemetry_status <= TMERR_INIT_NETWORKING_FAILED))
+        {
+            LL_INFOS() << tm_status[ telemetry_status ] << LL_ENDL;
+            free(gTelemetryBufferPtr);
+            gTelemetryBufferPtr = NULL;
+        }
+    #endif // LL_WINDOWS
+}
+
+// Called after we render a frame
+void telemetry_update()
+{
+    #if LL_WINDOWS
+        if (gTelemetryBufferPtr)
+        {
+            tmTick(0);
+        }
+    #endif
+}
+#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER
diff --git a/indra/newview/lltelemetry.h b/indra/newview/lltelemetry.h
new file mode 100644
index 0000000000000000000000000000000000000000..a73e5fcfa27aef28cdd4ad71f6a273885bbba7b1
--- /dev/null
+++ b/indra/newview/lltelemetry.h
@@ -0,0 +1,81 @@
+/**
+ * @file lltelemetry.h
+ * @brief Wrapper for Rad Game Tools Telemetry
+ *
+ * $LicenseInfo:firstyear=2020&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2020, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+/*
+To use:
+
+1. Uncomment #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER below
+
+2. Include this header file
+    #include "lltelemetry.h"
+
+3. Add zones to the functions you wish to profile
+    void onFoo()
+    {
+        LLPROFILE_ZONE("Foo");
+    }
+*/
+//#define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 1
+
+// Default NO local telemetry profiling
+#ifndef LLPROFILE_USE_RAD_TELEMETRY_PROFILER
+    #define LLPROFILE_USE_RAD_TELEMETRY_PROFILER 0
+    #define LLPROFILE_SHUTDOWN( ...) {}
+    #define LLPROFILE_STARTUP(  ...) {}
+    #define LLPROFILE_UPDATE(   ...) {}
+
+    #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b)
+    #define LLPROFILE_ENTER(name)
+    #define LLPROFILE_ENTER_FORMAT(format, ...)
+    #define LLPROFILE_FUNCTION
+    #define LLPROFILE_LEAVE()
+    #define LLPROFILE_THREAD_NAME(name)
+    #define LLPROFILE_ZONE(name)
+    #define LLPROFILE_ZONE_FORMAT(format, ...)
+#else
+    #include <rad_tm.h>
+
+    #define LLPROFILE_SHUTDOWN                       telemetry_shutdown
+    #define LLPROFILE_STARTUP                        telemetry_startup
+    #define LLPROFILE_UPDATE                         telemetry_update
+
+    #define LLPROFILE_AUTO_CPU_MARKER_COLOR(r, g, b) tmZoneColor(r, g, b)
+    #define LLPROFILE_ENTER(name)                    tmEnter(0, 0, name)
+    #define LLPROFILE_ENTER_FORMAT(format, ...)      tmEnter(0, 0, format, __VA_ARGS__)
+    #define LLPROFILE_FUNCTION                       tmFunction(0, 0)
+    #define LLPROFILE_LEAVE()                        tmLeave(0)
+    #define LLPROFILE_THREAD_NAME(name)              tmThreadName(0, 0, name)
+    #define LLPROFILE_ZONE(name)                     tmZone(0, 0, name)
+    #define LLPROFILE_ZONE_FORMAT(format, ...)       tmZone(0, 0, format, __VA_ARGS__)
+#endif // LLPROFILE_USE_RAD_TELEMETRY_PROFILER
+
+//
+// exported functionality
+//
+
+extern void telemetry_startup();
+extern void telemetry_shutdown();
+extern void telemetry_update(); // called after every frame update
diff --git a/indra/newview/llteleporthistorystorage.cpp b/indra/newview/llteleporthistorystorage.cpp
index 3025ea57c6a56e57cd10719e01528ed3434aa613..7a329174bc3641ef483ab240779dd083fe776054 100644
--- a/indra/newview/llteleporthistorystorage.cpp
+++ b/indra/newview/llteleporthistorystorage.cpp
@@ -33,6 +33,8 @@
 #include "lldir.h"
 #include "llteleporthistory.h"
 #include "llagent.h"
+#include "llfloaterreg.h"
+#include "llfloaterworldmap.h"
 // [RLVa:KB] - Checked: 2010-09-03 (RLVa-1.2.1b)
 #include "rlvactions.h"
 // [/RLVa:KB]
@@ -270,3 +272,23 @@ void LLTeleportHistoryStorage::goToItem(S32 idx)
 	gAgent.teleportViaLocation(mItems[idx].mGlobalPos);
 }
 
+void LLTeleportHistoryStorage::showItemOnMap(S32 idx)
+{
+    // Validate specified index.
+    if (idx < 0 || idx >= (S32)mItems.size())
+    {
+        LL_WARNS() << "Invalid teleport history index (" << idx << ") specified" << LL_ENDL;
+        dump();
+        return;
+    }
+
+    LLVector3d landmark_global_pos = mItems[idx].mGlobalPos;
+
+    LLFloaterWorldMap* worldmap_instance = LLFloaterWorldMap::getInstance();
+    if (!landmark_global_pos.isExactlyZero() && worldmap_instance)
+    {
+        worldmap_instance->trackLocation(landmark_global_pos);
+        LLFloaterReg::showInstance("world_map", "center");
+    }
+}
+
diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h
index c646bb7edfd49c5e6fff6a9c45f531f451be6784..95ca6075d1baa64d35b166efb871cd2e8e97ef16 100644
--- a/indra/newview/llteleporthistorystorage.h
+++ b/indra/newview/llteleporthistorystorage.h
@@ -107,6 +107,13 @@ class LLTeleportHistoryStorage: public LLSingleton<LLTeleportHistoryStorage>
 	 */
 	void					goToItem(S32 idx);
 
+    /**
+     * Show specific item on map.
+     *
+     * The item is specified by its index (starting from 0).
+     */
+    void					showItemOnMap(S32 idx);
+
 //private:
 // [RLVa:KB] - Checked: 2010-09-03 (RLVa-1.2.1b) | Added: RLVa-1.2.1b
 protected:
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 6ccb2f68e59d52618e8a21e09d3342a013e428ad..1c4a56b549a78654afa0ffe93e9fad2f819ce43e 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -73,6 +73,7 @@
 
 #include "llavatarappearancedefines.h"
 
+
 static const S32 LOCAL_TRACKING_ID_COLUMN = 1;
 
 //static const char CURRENT_IMAGE_NAME[] = "Current Texture";
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index 6a29be4aa17919d2f5eac2f5ff14768b38eff659..8baad30e8f09e0593a2e617cb34e283ab46e47a9 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -121,6 +121,11 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
 				data.mURLExternal = mNotification->getURLOpenExternally();
 			}
 
+			if((*it).has("width"))
+			{
+				data.mWidth = (*it)["width"].asInteger();
+			}
+
 			mButtonData.push_back(data);
 			option_index++;
 		}
@@ -159,15 +164,29 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
 	// Calc total width of buttons
 	S32 button_width = 0;
 	S32 sp = font->getWidth(std::string("OO"));
+	S32 btn_total_width = 0;
+	S32 default_size_btns = 0;
 	for( S32 i = 0; i < num_options; i++ )
-	{
+	{				
 		S32 w = S32(font->getWidth( options[i].second ) + 0.99f) + sp + 2 * LLBUTTON_H_PAD;
-		button_width = llmax( w, button_width );
+		if (mButtonData[i].mWidth > w)
+		{
+			btn_total_width += mButtonData[i].mWidth;
+		}
+		else
+		{
+			button_width = llmax(w, button_width);
+			default_size_btns++;
+		}
 	}
-	S32 btn_total_width = button_width;
+
 	if( num_options > 1 )
 	{
-		btn_total_width = (num_options * button_width) + ((num_options - 1) * BTN_HPAD);
+		btn_total_width = btn_total_width + (button_width * default_size_btns) + ((num_options - 1) * BTN_HPAD);
+	}
+	else
+	{
+		btn_total_width = llmax(btn_total_width, button_width);
 	}
 
 	// Message: create text box using raw string, as text has been structure deliberately
@@ -272,7 +291,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
 			mLineEditor->setText(edit_text_contents);
 
 			std::string notif_name = mNotification->getName();
-			if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name))
+			if (("SaveOutfitAs" == notif_name) || ("SaveSettingAs" == notif_name) || ("CreateLandmarkFolder" == notif_name))
 			{
 				mLineEditor->setPrevalidate(&LLTextValidate::validateASCII);
 			}
@@ -333,7 +352,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
 		if(btn)
 		{
 			btn->setName(options[i].first);
-			btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, button_width, BTN_HEIGHT ));
+			btn->setRect(button_rect.setOriginAndSize( button_left, VPAD, (mButtonData[i].mWidth == 0) ? button_width : mButtonData[i].mWidth, BTN_HEIGHT ));
 			btn->setLabel(options[i].second);
 			btn->setFont(font);
 
@@ -348,7 +367,7 @@ LLToastAlertPanel::LLToastAlertPanel( LLNotificationPtr notification, bool modal
 				btn->setFocus(TRUE);
 			}
 		}
-		button_left += button_width + BTN_HPAD;
+		button_left += ((mButtonData[i].mWidth == 0) ? button_width : mButtonData[i].mWidth) + BTN_HPAD;
 	}
 
 	setCheckBoxes(HPAD, VPAD);
diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h
index 9b4e054bf13656618d40d188e50e386bc2e92ffb..bd34e40642b6027c7c2508d0f89799e67d9ec658 100644
--- a/indra/newview/lltoastalertpanel.h
+++ b/indra/newview/lltoastalertpanel.h
@@ -82,9 +82,14 @@ class LLToastAlertPanel
 
 	struct ButtonData
 	{
+		ButtonData()
+		: mWidth(0)
+		{}
+		
 		LLButton* mButton;
 		std::string mURL;
 		U32 mURLExternal;
+		S32 mWidth;
 	};
 	std::vector<ButtonData> mButtonData;
 
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index bccf88128de5e436d1db2de28579ab2d1e54f22a..024f25bc98a2a7f1c8d1f2d30311e5c9fae386c6 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -387,9 +387,9 @@ void LLToastNotifyPanel::init( LLRect rect, bool show_images )
             if (mIsScriptDialog)
             {
                 // we are using default width for script buttons so we can determinate button_rows
-                //to get a number of rows we divide the required width of the buttons to button_panel_width
-                S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width);
-                //S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width;
+                // to get a number of rows we divide the required width of the buttons to button_panel_width
+                // buttons.size() is reduced by -2 due to presence of ignore button which is calculated independently a bit lower
+                S32 button_rows = llceil(F32(buttons.size() - 2) * (BUTTON_WIDTH + h_pad) / (button_panel_width + h_pad));
                 //reserve one row for the ignore_btn
                 button_rows++;
                 //calculate required panel height for scripdialog notification.
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index c5e31ff8e6bd3d1f6dc6b76cf9c225dd8c01c850..5235914c34884c0392c6d78d135e59cbdf706dfd 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -60,7 +60,7 @@ LLTool::~LLTool()
 	}
 }
 
-BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
+BOOL LLTool::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)
 {
 	BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
 	
@@ -83,9 +83,9 @@ BOOL LLTool::handleMouseDown(S32 x, S32 y, MASK mask)
 		LL_INFOS() << "LLTool left mouse down" << LL_ENDL;
 	}
 	// by default, didn't handle it
+	// AGENT_CONTROL_LBUTTON_DOWN is handled by scanMouse() and scanKey()
 	// LL_INFOS() << "LLTool::handleMouseDown" << LL_ENDL;
-	gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN);
-	return TRUE;
+	return FALSE;
 }
 
 BOOL LLTool::handleMouseUp(S32 x, S32 y, MASK mask)
@@ -95,8 +95,8 @@ BOOL LLTool::handleMouseUp(S32 x, S32 y, MASK mask)
 		LL_INFOS() << "LLTool left mouse up" << LL_ENDL;
 	}
 	// by default, didn't handle it
+	// AGENT_CONTROL_LBUTTON_UP is handled by scanMouse() and scanKey()
 	// LL_INFOS() << "LLTool::handleMouseUp" << LL_ENDL;
-	gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP);
 	return TRUE;
 }
 
diff --git a/indra/newview/lltool.h b/indra/newview/lltool.h
index 308983afdabfd16d0f108248ddc8c6c23ee38a5c..41a38804cea4baa16b23435b05edf47dd0f03e51 100644
--- a/indra/newview/lltool.h
+++ b/indra/newview/lltool.h
@@ -49,7 +49,7 @@ class LLTool
 	virtual BOOL isView() const { return FALSE; }
 
 	// Virtual functions inherited from LLMouseHandler
-	virtual BOOL	handleAnyMouseClick(S32 x, S32 y, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down);
+	virtual BOOL	handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down);
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleMiddleMouseDown(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index da2fe4b4d1a309b0f943464a5e964e75542e3a9b..ae3fc94cd608d88720c56b46329c0b65b7fea345 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -63,6 +63,7 @@
 #include "llviewerobject.h"
 #include "llviewerparcelmgr.h"
 #include "llviewerwindow.h"
+#include "llviewerinput.h"
 #include "llviewermedia.h"
 #include "llvoavatarself.h"
 #include "llviewermediafocus.h"
@@ -87,7 +88,6 @@ LLToolPie::LLToolPie()
 	mMouseOutsideSlop( false ),
 	mMouseSteerX(-1),
 	mMouseSteerY(-1),
-	mBlockClickToWalk(false),
 	mClickAction(0),
 	mClickActionBuyEnabled( gSavedSettings.getBOOL("ClickActionBuyEnabled") ),
 	mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") ),
@@ -95,7 +95,7 @@ LLToolPie::LLToolPie()
 {
 }
 
-BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
+BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down)
 {
 	BOOL result = LLMouseHandler::handleAnyMouseClick(x, y, mask, clicktype, down);
 	
@@ -176,10 +176,8 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
 	mPick.mKeyMask = mask;
 
 	mMouseButtonDown = true;
-	
-	handleLeftClickPick();
 
-	return TRUE;
+    return handleLeftClickPick();
 }
 
 // Spawn context menus on right mouse down so you can drag over and select
@@ -428,8 +426,6 @@ BOOL LLToolPie::handleLeftClickPick()
 	// put focus back "in world"
 	if (gFocusMgr.getKeyboardFocus())
 	{
-		// don't click to walk on attempt to give focus to world
-		mBlockClickToWalk = true;
 		gFocusMgr.setKeyboardFocus(NULL);
 	}
 
@@ -481,7 +477,7 @@ BOOL LLToolPie::handleLeftClickPick()
 		}
 		object = (LLViewerObject*)object->getParent();
 	}
-	if (object && object == gAgentAvatarp && !gSavedSettings.getBOOL("ClickToWalk"))
+	if (object && object == gAgentAvatarp)
 	{
 		// we left clicked on avatar, switch to focus mode
 		mMouseButtonDown = false;
@@ -498,7 +494,6 @@ BOOL LLToolPie::handleLeftClickPick()
 	//	LLFirstUse::useLeftClickNoHit();
 	/////////
 
-	// Eat the event
 	return LLTool::handleMouseDown(x, y, mask);
 }
 
@@ -619,17 +614,132 @@ void LLToolPie::resetSelection()
 	mClickAction = 0;
 }
 
-void LLToolPie::walkToClickedLocation()
+bool LLToolPie::walkToClickedLocation()
 {
-	if(mAutoPilotDestination) { mAutoPilotDestination->markDead(); }
-	mAutoPilotDestination = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE);
-	mAutoPilotDestination->setPositionGlobal(mPick.mPosGlobal);
-	mAutoPilotDestination->setPixelSize(5);
-	mAutoPilotDestination->setColor(LLColor4U(170, 210, 190));
-	mAutoPilotDestination->setDuration(3.f);
-
-	LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal;
-	gAgent.startAutoPilotGlobal(pos, std::string(), NULL, NULL, NULL, 0.f, 0.03f, FALSE);
+    if (gAgent.getFlying()							// don't auto-navigate while flying until that works
+        || !gAgentAvatarp
+        || gAgentAvatarp->isSitting())
+    {
+        return false;
+    }
+
+    LLPickInfo saved_pick = mPick;
+    if (gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK)
+    {
+        mPick = gViewerWindow->pickImmediate(mHoverPick.mMousePt.mX, mHoverPick.mMousePt.mY,
+            FALSE /* ignore transparent */,
+            FALSE /* ignore rigged */,
+            FALSE /* ignore particles */);
+    }
+    else
+    {
+        // We do not handle hover in mouselook as we do in other modes, so
+        // use croshair's position to do a pick
+        mPick = gViewerWindow->pickImmediate(gViewerWindow->getWorldViewRectScaled().getWidth() / 2,
+            gViewerWindow->getWorldViewRectScaled().getHeight() / 2,
+            FALSE /* ignore transparent */,
+            FALSE /* ignore rigged */,
+            FALSE /* ignore particles */);
+    }
+
+    if (mPick.mPickType == LLPickInfo::PICK_OBJECT)
+    {
+        if (mPick.getObject() && mPick.getObject()->isHUDAttachment())
+        {
+            mPick = saved_pick;
+            return false;
+        }
+    }
+
+    LLViewerObject* avatar_object = mPick.getObject();
+
+    // get pointer to avatar
+    while (avatar_object && !avatar_object->isAvatar())
+    {
+        avatar_object = (LLViewerObject*)avatar_object->getParent();
+    }
+
+    if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf())
+    {
+        const F64 SELF_CLICK_WALK_DISTANCE = 3.0;
+        // pretend we picked some point a bit in front of avatar
+        mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE;
+    }
+
+//    if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) ||
+//        (mPick.mObjectID.notNull() && !mPick.mPosGlobal.isExactlyZero()))
+// [RLVa:KB] - Checked: RLVa-2.0.0
+	bool fValidPick = ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) ||
+		(mPick.mObjectID.notNull() && !mPick.mPosGlobal.isExactlyZero()));
+
+	if ( (fValidPick) && (RlvActions::isRlvEnabled()) && (!RlvActions::canTeleportToLocal(mPick.mPosGlobal)) )
+	{
+		RlvUtil::notifyBlocked(RlvStringKeys::Blocked::AutoPilot);
+		fValidPick = false;
+	}
+
+	if (fValidPick)
+// [/RLVa:KB]
+    {
+        gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
+
+        if (mAutoPilotDestination) { mAutoPilotDestination->markDead(); }
+        mAutoPilotDestination = (LLHUDEffectBlob *)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_BLOB, FALSE);
+        mAutoPilotDestination->setPositionGlobal(mPick.mPosGlobal);
+        mAutoPilotDestination->setPixelSize(5);
+        mAutoPilotDestination->setColor(LLColor4U(170, 210, 190));
+        mAutoPilotDestination->setDuration(3.f);
+
+        LLVector3d pos = LLToolPie::getInstance()->getPick().mPosGlobal;
+        gAgent.startAutoPilotGlobal(pos, std::string(), NULL, NULL, NULL, 0.f, 0.03f, FALSE);
+        LLFirstUse::notMoving(false);
+        showVisualContextMenuEffect();
+        return true;
+    }
+    else
+    {
+        LL_DEBUGS() << "walk target was "
+            << (mPick.mPosGlobal.isExactlyZero() ? "zero" : "not zero")
+            << ", pick type was " << (mPick.mPickType == LLPickInfo::PICK_LAND ? "land" : "not land")
+            << ", pick object was " << mPick.mObjectID
+            << LL_ENDL;
+        mPick = saved_pick;
+        return false;
+    }
+    return true;
+}
+
+bool LLToolPie::teleportToClickedLocation()
+{
+    if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
+    {
+        // We do not handle hover in mouselook as we do in other modes, so
+        // use croshair's position to do a pick
+        BOOL pick_rigged = false;
+        mHoverPick = gViewerWindow->pickImmediate(gViewerWindow->getWorldViewRectScaled().getWidth() / 2,
+                                                  gViewerWindow->getWorldViewRectScaled().getHeight() / 2,
+                                                  FALSE,
+                                                  pick_rigged);
+    }
+    LLViewerObject* objp = mHoverPick.getObject();
+    LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL;
+
+    bool is_in_world = mHoverPick.mObjectID.notNull() && objp && !objp->isHUDAttachment();
+    bool is_land = mHoverPick.mPickType == LLPickInfo::PICK_LAND;
+    bool pos_non_zero = !mHoverPick.mPosGlobal.isExactlyZero();
+    bool has_touch_handler = (objp && objp->flagHandleTouch()) || (parentp && parentp->flagHandleTouch());
+    bool has_click_action = final_click_action(objp);
+
+    if (pos_non_zero && (is_land || (is_in_world && !has_touch_handler && !has_click_action)))
+    {
+        LLVector3d pos = mHoverPick.mPosGlobal;
+        pos.mdV[VZ] += gAgentAvatarp->getPelvisToFoot();
+        gAgent.teleportViaLocationLookAt(pos);
+        mPick = mHoverPick;
+        showVisualContextMenuEffect();
+        return true;
+    }
+    return false;
 }
 
 // When we get object properties after left-clicking on an object
@@ -713,8 +823,9 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
 		LL_DEBUGS("UserInput") << "hover handled by LLToolPie (inactive)" << LL_ENDL;
 	}
 	else if (!mMouseOutsideSlop 
-		&& mMouseButtonDown 
-		&& gSavedSettings.getBOOL("ClickToWalk"))
+		&& mMouseButtonDown
+		// disable camera steering if click on land is not used for moving
+		&& gViewerInput.isMouseBindUsed(CLICK_LEFT))
 	{
 		S32 delta_x = x - mMouseDownX;
 		S32 delta_y = y - mMouseDownY;
@@ -805,84 +916,10 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
         mDoubleClickTimer.reset();
     }
     LLViewerObject* obj = mPick.getObject();
-	U8 click_action = final_click_action(obj);
 
-	// let media have first pass at click
-	if (handleMediaMouseUp() || LLViewerMediaFocus::getInstance()->getFocus())
-	{
-		mBlockClickToWalk = true;
-	}
 	stopCameraSteering();
 	mMouseButtonDown = false;
 
-	if (click_action == CLICK_ACTION_NONE				// not doing 1-click action
-		&& gSavedSettings.getBOOL("ClickToWalk")		// click to walk enabled
-		&& !gAgent.getFlying()							// don't auto-navigate while flying until that works
-		&& gAgentAvatarp
-		&& !gAgentAvatarp->isSitting()
-		&& !mBlockClickToWalk							// another behavior hasn't cancelled click to walk
-        )
-	{
-        // We may be doing click to walk, but we don't want to use a target on
-        // a transparent object because the user thought they were clicking on
-        // whatever they were seeing through it, so recompute what was clicked on
-        // ignoring transparent objects
-        LLPickInfo savedPick = mPick;
-        mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY,
-                                             FALSE /* ignore transparent */,
-                                             FALSE /* ignore rigged */,
-                                             FALSE /* ignore particles */);
-
-//        if (!mPick.mPosGlobal.isExactlyZero()			// valid coordinates for pick
-//            && (mPick.mPickType == LLPickInfo::PICK_LAND	// we clicked on land
-//                || mPick.mObjectID.notNull()))				// or on an object
-// [RLVa:KB] - Checked: RLVa-2.0.0
-		bool fValidPick = (!mPick.mPosGlobal.isExactlyZero()			// valid coordinates for pick
-			&& (mPick.mPickType == LLPickInfo::PICK_LAND	// we clicked on land
-				|| mPick.mObjectID.notNull()));				// or on an object
-
-		if ( (fValidPick) && (RlvActions::isRlvEnabled()) && (!RlvActions::canTeleportToLocal(mPick.mPosGlobal)) )
-		{
-			RlvUtil::notifyBlocked(RlvStringKeys::Blocked::AutoPilot);
-			fValidPick = false;
-		}
-
-		if (fValidPick)
-// [/RLVa:KB]
-        {
-
-            // handle special cases of steering picks
-            LLViewerObject* avatar_object = mPick.getObject();
-
-            // get pointer to avatar
-            while (avatar_object && !avatar_object->isAvatar())
-            {
-                avatar_object = (LLViewerObject*)avatar_object->getParent();
-            }
-
-            if (avatar_object && ((LLVOAvatar*)avatar_object)->isSelf())
-            {
-                const F64 SELF_CLICK_WALK_DISTANCE = 3.0;
-                // pretend we picked some point a bit in front of avatar
-                mPick.mPosGlobal = gAgent.getPositionGlobal() + LLVector3d(LLViewerCamera::instance().getAtAxis()) * SELF_CLICK_WALK_DISTANCE;
-            }
-            gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
-            walkToClickedLocation();
-            LLFirstUse::notMoving(false);
-
-            return TRUE;
-        }
-        else
-        {
-            LL_DEBUGS("maint5901") << "walk target was "
-                                   << (mPick.mPosGlobal.isExactlyZero() ? "zero" : "not zero")
-                                   << ", pick type was " << (mPick.mPickType == LLPickInfo::PICK_LAND ? "land" : "not land")
-                                   << ", pick object was " << mPick.mObjectID
-                                   << LL_ENDL;
-            // we didn't click to walk, so restore the original target
-            mPick = savedPick;
-        }
-	}
 	gViewerWindow->setCursor(UI_CURSOR_ARROW);
 	if (hasMouseCapture())
 	{
@@ -892,7 +929,6 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
 	LLToolMgr::getInstance()->clearTransientTool();
 	gAgentCamera.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on
 
-	mBlockClickToWalk = false;
 	return LLTool::handleMouseUp(x, y, mask);
 }
 
@@ -918,78 +954,13 @@ BOOL LLToolPie::handleDoubleClick(S32 x, S32 y, MASK mask)
 		return TRUE;
 	}
     
-    	if (!mDoubleClickTimer.getStarted() || (mDoubleClickTimer.getElapsedTimeF32() > 0.3f))
+	if (!mDoubleClickTimer.getStarted() || (mDoubleClickTimer.getElapsedTimeF32() > 0.3f))
 	{
 		mDoubleClickTimer.stop();
 		return FALSE;
 	}
 	mDoubleClickTimer.stop();
 
-	if (gSavedSettings.getBOOL("DoubleClickAutoPilot"))
-	{
-        // We may be doing double click to walk, but we don't want to use a target on
-        // a transparent object because the user thought they were clicking on
-        // whatever they were seeing through it, so recompute what was clicked on
-        // ignoring transparent objects
-        LLPickInfo savedPick = mPick;
-        mPick = gViewerWindow->pickImmediate(savedPick.mMousePt.mX, savedPick.mMousePt.mY,
-                                             FALSE /* ignore transparent */,
-                                             FALSE /* ignore rigged */,
-                                             FALSE /* ignore particles */);
-
-        if(mPick.mPickType == LLPickInfo::PICK_OBJECT)
-        {
-            if (mPick.getObject() && mPick.getObject()->isHUDAttachment())
-            {
-                mPick = savedPick;
-                return FALSE;
-            }
-        }
-
-//		if ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) ||
-//			(mPick.mObjectID.notNull()  && !mPick.mPosGlobal.isExactlyZero()))
-// [RLVa:KB] - Checked: RLVa-2.0.0
-		bool fValidPick = ((mPick.mPickType == LLPickInfo::PICK_LAND && !mPick.mPosGlobal.isExactlyZero()) ||
-			(mPick.mObjectID.notNull()  && !mPick.mPosGlobal.isExactlyZero()));
-
-		if ( (fValidPick) && (RlvActions::isRlvEnabled()) && (!RlvActions::canTeleportToLocal(mPick.mPosGlobal)) )
-		{
-			RlvUtil::notifyBlocked(RlvStringKeys::Blocked::AutoPilot);
-			fValidPick = false;
-		}
-
-		if (fValidPick)
-// [/RLVa:KB]
-		{
-			walkToClickedLocation();
-			return TRUE;
-		}
-        else
-        {
-            // restore the original pick for any other purpose
-            mPick = savedPick;
-        }
-	}
-	else if (gSavedSettings.getBOOL("DoubleClickTeleport"))
-	{
-		LLViewerObject* objp = mPick.getObject();
-		LLViewerObject* parentp = objp ? objp->getRootEdit() : NULL;
-
-		bool is_in_world = mPick.mObjectID.notNull() && objp && !objp->isHUDAttachment();
-		bool is_land = mPick.mPickType == LLPickInfo::PICK_LAND;
-		bool pos_non_zero = !mPick.mPosGlobal.isExactlyZero();
-		bool has_touch_handler = (objp && objp->flagHandleTouch()) || (parentp && parentp->flagHandleTouch());
-		bool has_click_action = final_click_action(objp);
-
-		if (pos_non_zero && (is_land || (is_in_world && !has_touch_handler && !has_click_action)))
-		{
-			LLVector3d pos = mPick.mPosGlobal;
-			pos.mdV[VZ] += gAgentAvatarp->getPelvisToFoot();
-			gAgent.teleportViaLocationLookAt(pos);
-			return TRUE;
-		}
-	}
-
 	return FALSE;
 }
 
@@ -1555,7 +1526,6 @@ void LLToolPie::VisitHomePage(const LLPickInfo& info)
 void LLToolPie::handleSelect()
 {
 	// tool is reselected when app gets focus, etc.
-	mBlockClickToWalk = true;	
 }
 
 void LLToolPie::handleDeselect()
@@ -1616,7 +1586,7 @@ void LLToolPie::stopCameraSteering()
 
 bool LLToolPie::inCameraSteerMode()
 {
-	return mMouseButtonDown && mMouseOutsideSlop && gSavedSettings.getBOOL("ClickToWalk");
+	return mMouseButtonDown && mMouseOutsideSlop;
 }
 
 // true if x,y outside small box around start_x,start_y
@@ -2094,7 +2064,6 @@ void LLToolPie::startCameraSteering()
 {
 	LLFirstUse::notMoving(false);
 	mMouseOutsideSlop = true;
-	mBlockClickToWalk = true;
 
 	if (gAgentCamera.getFocusOnAvatar())
 	{
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 8b776904a2aa588f38c9cae0f50c458196c9c669..cbd2452ef8ac54c356c14147223ef0be03f16781 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -42,7 +42,7 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
 public:
 
 	// Virtual functions inherited from LLMouseHandler
-	virtual BOOL		handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down);
+	virtual BOOL		handleAnyMouseClick(S32 x, S32 y, MASK mask, EMouseClickType clicktype, BOOL down);
 	virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL		handleRightMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL		handleMouseUp(S32 x, S32 y, MASK mask);
@@ -71,8 +71,8 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
 	LLViewerObject*		getClickActionObject() { return mClickActionObject; }
 	LLObjectSelection*	getLeftClickSelection() { return (LLObjectSelection*)mLeftClickSelection; }
 	void 				resetSelection();
-	void				walkToClickedLocation();
-	void				blockClickToWalk() { mBlockClickToWalk = true; }
+	bool				walkToClickedLocation();
+	bool				teleportToClickedLocation();
 	void				stopClickToWalk();
 	
 	static void			selectionPropertiesReceived();
@@ -114,7 +114,6 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
 	LLPointer<LLHUDEffectBlob>	mAutoPilotDestination;
 	LLPointer<LLHUDEffectBlob>	mMouseSteerGrabPoint;
 	bool				mClockwise;			
-	bool				mBlockClickToWalk;
 	LLUUID				mMediaMouseCaptureID;
 	LLPickInfo			mPick;
 	LLPickInfo			mHoverPick;
diff --git a/indra/newview/llurlfloaterdispatchhandler.cpp b/indra/newview/llurlfloaterdispatchhandler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6b1a373beb9a28be4c1adeec1086096b7ca51250
--- /dev/null
+++ b/indra/newview/llurlfloaterdispatchhandler.cpp
@@ -0,0 +1,214 @@
+/** 
+ * @file llurlfloaterdispatchhandler.cpp
+ * @brief Handles URLFloater generic message from server
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llurlfloaterdispatchhandler.h"
+
+#include "llfloaterreg.h"
+#include "llfloaterhowto.h"
+#include "llfloaterwebcontent.h"
+#include "llsdserialize.h"
+#include "llviewercontrol.h"
+#include "llviewergenericmessage.h"
+#include "llweb.h"
+
+// Example:
+// llOpenFloater("guidebook", "http://page.com", []);
+
+// values specified by server side's dispatcher
+// for llopenfloater
+const std::string MESSAGE_URL_FLOATER("URLFloater");
+const std::string KEY_ACTION("action"); // "action" will be the string constant "OpenURL"
+const std::string VALUE_OPEN_URL("OpenURL");
+const std::string KEY_DATA("action_data");
+const std::string KEY_FLOATER("floater_title"); // name of the floater, not title
+const std::string KEY_URL("floater_url");
+const std::string KEY_PARAMS("floater_params");
+
+// Supported floaters
+const std::string FLOATER_GUIDEBOOK("guidebook");
+const std::string FLOATER_HOW_TO("how_to"); // alias for guidebook
+const std::string FLOATER_WEB_CONTENT("web_content");
+
+// All arguments are palceholders! Server side will need to add validation first.
+// Web content universal argument
+const std::string KEY_TRUSTED_CONTENT("trusted_content");
+
+// Guidebook specific arguments
+const std::string KEY_WIDTH("width");
+const std::string KEY_HEGHT("height");
+const std::string KEY_CAN_CLOSE("can_close");
+const std::string KEY_TITLE("title");
+
+// web_content specific arguments
+const std::string KEY_SHOW_PAGE_TITLE("show_page_title");
+const std::string KEY_ALLOW_ADRESS_ENTRY("allow_address_entry"); // It is not recomended to set this to true if trusted content is allowed
+
+
+LLUrlFloaterDispatchHandler LLUrlFloaterDispatchHandler::sUrlDispatchhandler;
+
+LLUrlFloaterDispatchHandler::LLUrlFloaterDispatchHandler()
+{
+}
+
+LLUrlFloaterDispatchHandler::~LLUrlFloaterDispatchHandler()
+{
+}
+
+void LLUrlFloaterDispatchHandler::registerInDispatcher()
+{
+    if (!gGenericDispatcher.isHandlerPresent(MESSAGE_URL_FLOATER))
+    {
+        gGenericDispatcher.addHandler(MESSAGE_URL_FLOATER, &sUrlDispatchhandler);
+    }
+}
+
+//virtual
+bool LLUrlFloaterDispatchHandler::operator()(const LLDispatcher *, const std::string& key, const LLUUID& invoice, const sparam_t& strings)
+{
+    // invoice - transaction id
+
+    LLSD message;
+    sparam_t::const_iterator it = strings.begin();
+
+    if (it != strings.end())
+    {
+        const std::string& llsdRaw = *it++;
+        std::istringstream llsdData(llsdRaw);
+        if (!LLSDSerialize::deserialize(message, llsdData, llsdRaw.length()))
+        {
+            LL_WARNS("URLFloater") << "Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL;
+            return false;
+        }
+    }
+
+    // At the moment command_params is a placeholder and code treats it as map
+    // Once server side adds argument validation this will be either a map or an array
+    std::string floater;
+    LLSD command_params;
+    std::string url;
+
+    if (message.has(KEY_ACTION) && message[KEY_ACTION].asString() == VALUE_OPEN_URL)
+    {
+        LLSD &action_data = message[KEY_DATA];
+        if (action_data.isMap())
+        {
+            floater = action_data[KEY_FLOATER].asString();
+            command_params = action_data[KEY_PARAMS];
+            url = action_data[KEY_URL].asString();
+        }
+    }
+    else if (message.has(KEY_FLOATER))
+    {
+        floater = message[KEY_FLOATER].asString();
+        command_params = message[KEY_PARAMS];
+        url = message[KEY_URL].asString();
+    }
+    else
+    {
+        LL_WARNS("URLFloater") << "Received " << MESSAGE_URL_FLOATER << " with unexpected data format: " << message << LL_ENDL;
+        return false;
+    }
+
+    if (url.find("://") == std::string::npos)
+    {
+        // try unescaping
+        url = LLURI::unescape(url);
+    }
+
+    LLFloaterWebContent::Params params;
+    params.url = url;
+
+    if (floater == FLOATER_GUIDEBOOK || floater == FLOATER_HOW_TO)
+    {
+        LL_DEBUGS("URLFloater") << "Opening how_to floater with parameters: " << message << LL_ENDL;
+        if (command_params.isMap()) // by default is undefines
+        {
+            params.trusted_content = command_params.has(KEY_TRUSTED_CONTENT) ? command_params[KEY_TRUSTED_CONTENT].asBoolean() : false;
+
+            // Script's side argument list can't include other lists, neither
+            // there is a LLRect type, so expect just width and height
+            if (command_params.has(KEY_WIDTH) && command_params.has(KEY_HEGHT))
+            {
+                LLRect rect(0, command_params[KEY_HEGHT].asInteger(), command_params[KEY_WIDTH].asInteger(), 0);
+                params.preferred_media_size.setValue(rect);
+            }
+        }
+
+        // Some locations will have customized guidebook, which this function easists for
+        // only one instance of guidebook can exist at a time, so if this command arrives,
+        // we need to close previous guidebook then reopen it.
+
+        LLFloater* instance = LLFloaterReg::findInstance("guidebook");
+        if (instance)
+        {
+            instance->closeHostedFloater();
+        }
+
+        LLFloaterReg::toggleInstanceOrBringToFront("guidebook", params);
+        
+        if (command_params.isMap())
+        {
+            LLFloater* instance = LLFloaterReg::findInstance("guidebook");
+            if (command_params.has(KEY_CAN_CLOSE))
+            {
+                instance->setCanClose(command_params[KEY_CAN_CLOSE].asBoolean());
+            }
+            if (command_params.has(KEY_TITLE))
+            {
+                instance->setTitle(command_params[KEY_TITLE].asString());
+            }
+        }
+    }
+    else if (floater == FLOATER_WEB_CONTENT)
+    {
+        LL_DEBUGS("URLFloater") << "Opening web_content floater with parameters: " << message << LL_ENDL;
+        if (command_params.isMap()) // by default is undefines, might be better idea to init params from command_params
+        {
+            params.trusted_content = command_params.has(KEY_TRUSTED_CONTENT) ? command_params[KEY_TRUSTED_CONTENT].asBoolean() : false;
+            params.show_page_title = command_params.has(KEY_SHOW_PAGE_TITLE) ? command_params[KEY_SHOW_PAGE_TITLE].asBoolean() : true;
+            params.allow_address_entry = command_params.has(KEY_ALLOW_ADRESS_ENTRY) ? command_params[KEY_ALLOW_ADRESS_ENTRY].asBoolean() : true;
+        }
+        LLFloaterReg::showInstance("web_content", params);
+    }
+    else
+    {
+        LL_DEBUGS("URLFloater") << "Unknow floater with parameters: " << message << LL_ENDL;
+        if (LLFloaterReg::isRegistered(floater))
+        {
+            // A valid floater
+            LL_INFOS("URLFloater") << "Floater " << floater << " is not supported by llopenfloater or URLFloater" << LL_ENDL;
+        }
+        else
+        {
+            // A valid message, but no such flaoter
+            LL_WARNS("URLFloater") << "Recieved a command to open unknown floater: " << floater << LL_ENDL;
+        }
+    }
+
+    return true;
+}
diff --git a/indra/newview/llurlfloaterdispatchhandler.h b/indra/newview/llurlfloaterdispatchhandler.h
new file mode 100644
index 0000000000000000000000000000000000000000..1dff52c66f8c89c9e5291d8f570a8d23885494b2
--- /dev/null
+++ b/indra/newview/llurlfloaterdispatchhandler.h
@@ -0,0 +1,49 @@
+/** 
+ * @file llurlfloaterdispatchhandler.h
+ * @brief Handles URLFloater generic message from server
+ *
+ * $LicenseInfo:firstyear=2021&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2021, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLURLFLOATERDISPATCHHANDLER_H
+#define LL_LLURLFLOATERDISPATCHHANDLER_H
+
+#include "lldispatcher.h"
+
+class LLUrlFloaterDispatchHandler : public LLDispatchHandler
+{
+public:
+    LOG_CLASS(LLUrlFloaterDispatchHandler);
+
+    LLUrlFloaterDispatchHandler();
+    virtual ~LLUrlFloaterDispatchHandler();
+
+    virtual bool operator()(const LLDispatcher *, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override;
+
+    static void registerInDispatcher();
+
+private:
+    static LLUrlFloaterDispatchHandler sUrlDispatchhandler;
+};
+
+#endif  // LL_LLURLFLOATERDISPATCHHANDLER_H
+
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 54f80a2995242302329fd9ca02b595c591243c81..7842d2427926d7cdb808748c89089d6ff4e1a619 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -49,8 +49,8 @@
 /// LLViewerAssetRequest
 ///----------------------------------------------------------------------------
 
- // There is also PoolSizeVAssetStorage value in setting that should mirror this name
-static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "VAssetStorage";
+ // There is also PoolSizeAssetStorage value in setting that should mirror this name
+static const std::string VIEWER_ASSET_STORAGE_CORO_POOL = "AssetStorage";
 
 /**
  * @brief Local class to encapsulate asset fetch requests with a timestamp.
@@ -137,6 +137,14 @@ LLViewerAssetStorage::~LLViewerAssetStorage()
         // This class has dedicated coroutine pool, clean it up, otherwise coroutines will crash later. 
         LLCoprocedureManager::instance().close(VIEWER_ASSET_STORAGE_CORO_POOL);
     }
+
+    while (mCoroWaitList.size() > 0)
+    {
+        CoroWaitList &request = mCoroWaitList.front();
+        // Clean up pending downloads, delete request and trigger callbacks
+        removeAndCallbackPendingDownloads(request.mId, request.mType, request.mId, request.mType, LL_ERR_NOERR, LLExtStat::NONE);
+        mCoroWaitList.pop_front();
+    }
 }
 
 // virtual 
@@ -350,6 +358,27 @@ void LLViewerAssetStorage::storeAssetData(
     }
 }
 
+void LLViewerAssetStorage::checkForTimeouts()
+{
+    LLAssetStorage::checkForTimeouts();
+
+    // Restore requests
+    LLCoprocedureManager* manager = LLCoprocedureManager::getInstance();
+    while (mCoroWaitList.size() > 0
+           && manager->count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE)
+    {
+        CoroWaitList &request = mCoroWaitList.front();
+        
+        bool with_http = true;
+        bool is_temp = false;
+        LLViewerAssetStatsFF::record_enqueue(request.mType, with_http, is_temp);
+
+        manager->enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro",
+            boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, request.mRequest, request.mId, request.mType, request.mCallback, request.mUserData));
+
+        mCoroWaitList.pop_front();
+    }
+}
 
 /**
  * @brief Allocate and queue an asset fetch request for the viewer
@@ -407,12 +436,20 @@ void LLViewerAssetStorage::queueRequestHttp(
     // This is the same as the current UDP logic - don't re-request a duplicate.
     if (!duplicate)
     {
-        bool with_http = true;
-        bool is_temp = false;
-        LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp);
+        // Coroutine buffer has fixed size (synchronization buffer, so we have no alternatives), so buffer any request above limit
+        if (LLCoprocedureManager::instance().count(VIEWER_ASSET_STORAGE_CORO_POOL) < LLCoprocedureManager::DEFAULT_QUEUE_SIZE)
+        {
+            bool with_http = true;
+            bool is_temp = false;
+            LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp);
 
-        LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL,"LLViewerAssetStorage::assetRequestCoro",
-            boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data));
+            LLCoprocedureManager::instance().enqueueCoprocedure(VIEWER_ASSET_STORAGE_CORO_POOL, "LLViewerAssetStorage::assetRequestCoro",
+                boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data));
+        }
+        else
+        {
+            mCoroWaitList.emplace_back(req, uuid, atype, callback, user_data);
+        }
     }
 }
 
diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h
index ef01d179b7bac20179ba983c0e3823d10fdf82fe..c1a5534b81961ce2d3667d85b4d8804ac1218ae9 100644
--- a/indra/newview/llviewerassetstorage.h
+++ b/indra/newview/llviewerassetstorage.h
@@ -45,7 +45,7 @@ class LLViewerAssetStorage : public LLAssetStorage
 
 	~LLViewerAssetStorage();
 
-	virtual void storeAssetData(
+	void storeAssetData(
 		const LLTransactionID& tid,
 		LLAssetType::EType atype,
 		LLStoreAssetCallback callback,
@@ -54,9 +54,9 @@ class LLViewerAssetStorage : public LLAssetStorage
 		bool is_priority = false,
 		bool store_local = false,
 		bool user_waiting=FALSE,
-		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT);
-	
-	virtual void storeAssetData(
+		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override;
+
+	void storeAssetData(
 		const std::string& filename,
 		const LLTransactionID& tid,
 		LLAssetType::EType type,
@@ -65,16 +65,17 @@ class LLViewerAssetStorage : public LLAssetStorage
 		bool temp_file = false,
 		bool is_priority = false,
 		bool user_waiting=FALSE,
-		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT);
+		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) override;
+
+    void checkForTimeouts() override;
 
 protected:
-	// virtual
 	void _queueDataRequest(const LLUUID& uuid,
 						   LLAssetType::EType type,
                            LLGetAssetCallback callback,
 						   void *user_data,
 						   BOOL duplicate,
-						   BOOL is_priority);
+						   BOOL is_priority) override;
 
     void queueRequestHttp(const LLUUID& uuid,
                           LLAssetType::EType type,
@@ -93,8 +94,35 @@ class LLViewerAssetStorage : public LLAssetStorage
 
     std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype);
 
-    void logAssetStorageInfo();
-    
+    void logAssetStorageInfo() override;
+
+    // Asset storage works through coroutines and coroutines have limited queue capacity
+    // This class is meant to temporary store requests when fiber's queue is full
+    class CoroWaitList
+    {
+    public:
+        CoroWaitList(LLViewerAssetRequest *req,
+            const LLUUID& uuid,
+            LLAssetType::EType atype,
+            LLGetAssetCallback &callback,
+            void *user_data)
+          : mRequest(req),
+            mId(uuid),
+            mType(atype),
+            mCallback(callback),
+            mUserData(user_data)
+        {
+        }
+
+        LLViewerAssetRequest* mRequest;
+        LLUUID mId;
+        LLAssetType::EType mType;
+        LLGetAssetCallback mCallback;
+        void *mUserData;
+    };
+    typedef std::list<CoroWaitList> wait_list_t;
+    wait_list_t mCoroWaitList;
+
     std::string mViewerAssetUrl;
     S32 mAssetCoroCount;
     S32 mCountRequests;
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 6aa9a15e65f6b9150f1ba665283c4e4897c6f2a3..9ef5ea1bd91d81d6f6f260371a4caec717b9f7f1 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -524,7 +524,10 @@ bool handleHighResSnapshotChanged(const LLSD& newvalue)
 
 bool handleVoiceClientPrefsChanged(const LLSD& newvalue)
 {
-	LLVoiceClient::getInstance()->updateSettings();
+	if (LLVoiceClient::instanceExists())
+	{
+		LLVoiceClient::getInstance()->updateSettings();
+	}
 	return true;
 }
 
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 5c1ab2e5e03ab135c53b9e36187af2fbd1a10db1..145ecb6e17570e9aebaea9119548006891fb1319 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -479,6 +479,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 			gAgent.setTeleportState( LLAgent::TELEPORT_ARRIVING );
 			gAgent.setTeleportMessage(
 				LLAgent::sTeleportProgressMessages["arriving"]);
+			gAgent.sheduleTeleportIM();
 			gTextureList.mForceResetTextureStats = TRUE;
 			gAgentCamera.resetView(TRUE, TRUE);
 			
@@ -761,10 +762,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 				glViewport(0,0,512,512);
 				LLVOAvatar::updateFreezeCounter() ;
 
-				if(!LLPipeline::sMemAllocationThrottled)
-				{		
-					LLVOAvatar::updateImpostors();
-				}
+				LLVOAvatar::updateImpostors();
 
 				set_current_projection(proj);
 				set_current_modelview(mod);
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 0f41a2c1fd4b8e2f489ef031bbfc2e3d1d9f7c04..613205754267e775993ea319cc1818b784d60a51 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -34,6 +34,7 @@
 #include "llcompilequeue.h"
 #include "llfasttimerview.h"
 #include "llfloaterabout.h"
+#include "llfloateraddpaymentmethod.h"
 #include "llfloaterauction.h"
 #include "llfloaterautoreplacesettings.h"
 #include "llfloateravatar.h"
@@ -57,6 +58,7 @@
 #include "llfloaterchatvoicevolume.h"
 #include "llfloaterconversationlog.h"
 #include "llfloaterconversationpreview.h"
+#include "llfloatercreatelandmark.h"
 #include "llfloaterdeleteprefpreset.h"
 #include "llfloaterdestinations.h"
 #include "llfloatereditextdaycycle.h"
@@ -74,6 +76,7 @@
 #include "llfloatergroups.h"
 #include "llfloaterhelpbrowser.h"
 #include "llfloaterhoverheight.h"
+#include "llfloaterhowto.h"
 #include "llfloaterhud.h"
 #include "llfloaterimagepreview.h"
 #include "llfloaterimsession.h"
@@ -196,6 +199,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterAboutUtil::registerFloater();
 	LLFloaterReg::add("block_timers", "floater_fast_timers.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFastTimerView>);
 	LLFloaterReg::add("about_land", "floater_about_land.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterLand>);
+	LLFloaterReg::add("add_payment_method", "floater_add_payment_method.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAddPaymentMethod>);
 	LLFloaterReg::add("appearance", "floater_my_appearance.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
 	LLFloaterReg::add("associate_listing", "floater_associate_listing.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAssociateListing>);
 	LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
@@ -222,6 +226,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
 	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
 	LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
+	LLFloaterReg::add("add_landmark", "floater_create_landmark.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCreateLandmark>);
 
 	LLFloaterReg::add("delete_pref_preset", "floater_delete_pref_preset.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDeletePrefPreset>);
 	LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>);
@@ -366,7 +371,7 @@ void LLViewerFloaterReg::registerFloaters()
     LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSearch>);
 	LLFloaterReg::add("my_profile", "floater_my_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
 	LLFloaterReg::add("profile", "floater_web_profile.xml", (LLFloaterBuildFunc)&LLFloaterWebProfile::create);
-	LLFloaterReg::add("how_to", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);
+	LLFloaterReg::add("guidebook", "floater_how_to.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHowTo>);
 
 	LLFloaterReg::add("big_preview", "floater_big_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBigPreview>);
 	
diff --git a/indra/newview/llviewerinput.cpp b/indra/newview/llviewerinput.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..760d3dd7e0a11f7f797c10f7f73af61dccc6813c
--- /dev/null
+++ b/indra/newview/llviewerinput.cpp
@@ -0,0 +1,1577 @@
+/** 
+ * @file llviewerinput.cpp
+ * @brief LLViewerInput class implementation
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerinput.h"
+
+#include "llappviewer.h"
+#include "llfloaterreg.h"
+#include "llmath.h"
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llfloaterimnearbychat.h"
+#include "llfocusmgr.h"
+#include "llkeybind.h" // LLKeyData
+#include "llmorphview.h"
+#include "llmoveview.h"
+#include "lltoolfocus.h"
+#include "lltoolpie.h"
+#include "llviewercontrol.h"
+#include "llviewerwindow.h"
+#include "llvoavatarself.h"
+#include "llfloatercamera.h"
+#include "llinitparam.h"
+#include "llselectmgr.h"
+
+//
+// Constants
+//
+
+const F32 FLY_TIME = 0.5f;
+const F32 FLY_FRAMES = 4;
+
+const F32 NUDGE_TIME = 0.25f;  // in seconds
+const S32 NUDGE_FRAMES = 2;
+const F32 ORBIT_NUDGE_RATE = 0.05f;  // fraction of normal speed
+
+const LLKeyData agent_control_lbutton(CLICK_LEFT, KEY_NONE, MASK_NONE, true);
+
+struct LLKeyboardActionRegistry 
+:	public LLRegistrySingleton<std::string, boost::function<bool (EKeystate keystate)>, LLKeyboardActionRegistry>
+{
+	LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry);
+};
+
+LLViewerInput gViewerInput;
+
+bool agent_jump( EKeystate s )
+{
+	static BOOL first_fly_attempt(TRUE);
+	if (KEYSTATE_UP == s)
+	{
+		first_fly_attempt = TRUE;
+		return true;
+	}
+	F32 time = gKeyboard->getCurKeyElapsedTime();
+	S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
+
+	if( time < FLY_TIME 
+		|| frame_count <= FLY_FRAMES 
+		|| gAgent.upGrabbed()
+		|| !gSavedSettings.getBOOL("AutomaticFly"))
+	{
+		gAgent.moveUp(1);
+	}
+	else
+	{
+		gAgent.setFlying(TRUE, first_fly_attempt);
+		first_fly_attempt = FALSE;
+		gAgent.moveUp(1);
+	}
+	return true;
+}
+
+bool agent_push_down( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgent.moveUp(-1);
+	return true;
+}
+
+static void agent_check_temporary_run(LLAgent::EDoubleTapRunMode mode)
+{
+// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
+	if ( (gAgent.mDoubleTapRunMode == mode) && (gAgent.getTempRun()) )
+		gAgent.clearTempRun();
+// [/RLVa:KB]
+//	if (gAgent.mDoubleTapRunMode == mode &&
+//		gAgent.getRunning() &&
+//		!gAgent.getAlwaysRun())
+//	{
+//		// Turn off temporary running.
+//		gAgent.clearRunning();
+//		gAgent.sendWalkRun(gAgent.getRunning());
+//	}
+}
+
+static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode mode)
+{
+	if (KEYSTATE_UP == s)
+	{
+		// Note: in case shift is already released, slide left/right run
+		// will be released in agent_turn_left()/agent_turn_right()
+		agent_check_temporary_run(mode);
+	}
+	else if (gSavedSettings.getBOOL("AllowTapTapHoldRun") &&
+		 KEYSTATE_DOWN == s &&
+		 !gAgent.getRunning())
+	{
+		if (gAgent.mDoubleTapRunMode == mode &&
+		    gAgent.mDoubleTapRunTimer.getElapsedTimeF32() < NUDGE_TIME)
+		{
+			// Same walk-key was pushed again quickly; this is a
+			// double-tap so engage temporary running.
+//			gAgent.setRunning();
+//			gAgent.sendWalkRun(gAgent.getRunning());
+// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
+			gAgent.setTempRun();
+// [/RLVa:KB]
+		}
+
+		// Pressing any walk-key resets the double-tap timer
+		gAgent.mDoubleTapRunTimer.reset();
+		gAgent.mDoubleTapRunMode = mode;
+	}
+}
+
+static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode )
+{
+	agent_handle_doubletap_run(s, mode);
+	if (KEYSTATE_UP == s) return;
+
+	F32 time = gKeyboard->getCurKeyElapsedTime();
+	S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
+
+	if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES)
+	{
+		gAgent.moveAtNudge(direction);
+	}
+	else
+	{
+		gAgent.moveAt(direction);
+	}
+}
+
+bool camera_move_forward( EKeystate s );
+
+bool agent_push_forward( EKeystate s )
+{
+	if(gAgent.isMovementLocked()) return true;
+
+	//in free camera control mode we need to intercept keyboard events for avatar movements
+	if (LLFloaterCamera::inFreeCameraMode())
+	{
+		camera_move_forward(s);
+	}
+	else
+	{
+		agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD);
+	}
+	return true;
+}
+
+bool camera_move_backward( EKeystate s );
+
+bool agent_push_backward( EKeystate s )
+{
+	if(gAgent.isMovementLocked()) return true;
+
+	//in free camera control mode we need to intercept keyboard events for avatar movements
+	if (LLFloaterCamera::inFreeCameraMode())
+	{
+		camera_move_backward(s);
+	}
+	else if (!gAgent.backwardGrabbed() && gAgentAvatarp->isSitting() && gSavedSettings.getBOOL("LeaveMouselook"))
+	{
+		gAgentCamera.changeCameraToThirdPerson();
+	}
+	else
+	{
+		agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD);
+	}
+	return true;
+}
+
+static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode )
+{
+	agent_handle_doubletap_run(s, mode);
+	if( KEYSTATE_UP == s ) return;
+	F32 time = gKeyboard->getCurKeyElapsedTime();
+	S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
+
+	if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES)
+	{
+		gAgent.moveLeftNudge(direction);
+	}
+	else
+	{
+		gAgent.moveLeft(direction);
+	}
+}
+
+
+bool agent_slide_left( EKeystate s )
+{
+	if(gAgent.isMovementLocked()) return true;
+	agent_slide_leftright(s, 1, LLAgent::DOUBLETAP_SLIDELEFT);
+	return true;
+}
+
+
+bool agent_slide_right( EKeystate s )
+{
+	if(gAgent.isMovementLocked()) return true;
+	agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT);
+	return true;
+}
+
+bool camera_spin_around_cw( EKeystate s );
+
+bool agent_turn_left(EKeystate s)
+{
+	//in free camera control mode we need to intercept keyboard events for avatar movements
+	if (LLFloaterCamera::inFreeCameraMode())
+	{
+		camera_spin_around_cw(s);
+		return true;
+	}
+
+	if(gAgent.isMovementLocked()) return false;
+
+	if (LLToolCamera::getInstance()->mouseSteerMode())
+	{
+		agent_slide_left(s);
+	}
+	else
+	{
+		if (KEYSTATE_UP == s)
+		{
+			// Check temporary running. In case user released 'left' key with shift already released.
+			agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDELEFT);
+			return true;
+		}
+		F32 time = gKeyboard->getCurKeyElapsedTime();
+		gAgent.moveYaw( LLFloaterMove::getYawRate( time ) );
+	}
+	return true;
+}
+
+bool camera_spin_around_ccw( EKeystate s );
+
+bool agent_turn_right( EKeystate s )
+{
+	//in free camera control mode we need to intercept keyboard events for avatar movements
+	if (LLFloaterCamera::inFreeCameraMode())
+	{
+		camera_spin_around_ccw(s);
+		return true;
+	}
+
+	if(gAgent.isMovementLocked()) return false;
+
+	if (LLToolCamera::getInstance()->mouseSteerMode())
+	{
+		agent_slide_right(s);
+	}
+	else
+	{
+		if (KEYSTATE_UP == s)
+		{
+			// Check temporary running. In case user released 'right' key with shift already released.
+			agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDERIGHT);
+			return true;
+		}
+		F32 time = gKeyboard->getCurKeyElapsedTime();
+		gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) );
+	}
+	return true;
+}
+
+bool agent_look_up( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgent.movePitch(-1);
+	//gAgent.rotate(-2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() );
+	return true;
+}
+
+
+bool agent_look_down( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgent.movePitch(1);
+	//gAgent.rotate(2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() );
+	return true;
+}
+
+bool agent_toggle_fly( EKeystate s )
+{
+	// Only catch the edge
+	if (KEYSTATE_DOWN == s )
+	{
+		LLAgent::toggleFlying();
+	}
+	return true;
+}
+
+F32 get_orbit_rate()
+{
+	F32 time = gKeyboard->getCurKeyElapsedTime();
+	if( time < NUDGE_TIME )
+	{
+		F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME;
+		//LL_INFOS() << rate << LL_ENDL;
+		return rate;
+	}
+	else
+	{
+		return 1;
+	}
+}
+
+bool camera_spin_around_ccw( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
+	return true;
+}
+
+
+bool camera_spin_around_cw( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setOrbitRightKey( get_orbit_rate() );
+	return true;
+}
+
+bool camera_spin_around_ccw_sitting( EKeystate s )
+{
+	if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return true;
+	if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning())
+	{
+		//send keystrokes, but do not change camera
+		agent_turn_right(s);
+	}
+	else
+	{
+		//change camera but do not send keystrokes
+		gAgentCamera.unlockView();
+		gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
+	}
+	return true;
+}
+
+
+bool camera_spin_around_cw_sitting( EKeystate s )
+{
+	if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return true;
+	if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning())
+	{
+		//send keystrokes, but do not change camera
+		agent_turn_left(s);
+	}
+	else
+	{
+		//change camera but do not send keystrokes
+		gAgentCamera.unlockView();
+		gAgentCamera.setOrbitRightKey( get_orbit_rate() );
+	}
+	return true;
+}
+
+
+bool camera_spin_over( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setOrbitUpKey( get_orbit_rate() );
+	return true;
+}
+
+
+bool camera_spin_under( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setOrbitDownKey( get_orbit_rate() );
+	return true;
+}
+
+bool camera_spin_over_sitting( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	if (gAgent.upGrabbed() || gAgentCamera.sitCameraEnabled())
+	{
+		//send keystrokes, but do not change camera
+		agent_jump(s);
+	}
+	else
+	{
+		//change camera but do not send keystrokes
+		gAgentCamera.setOrbitUpKey( get_orbit_rate() );
+	}
+	return true;
+}
+
+
+bool camera_spin_under_sitting( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	if (gAgent.downGrabbed() || gAgentCamera.sitCameraEnabled())
+	{
+		//send keystrokes, but do not change camera
+		agent_push_down(s);
+	}
+	else
+	{
+		//change camera but do not send keystrokes
+		gAgentCamera.setOrbitDownKey( get_orbit_rate() );
+	}
+	return true;
+}
+
+bool camera_move_forward( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setOrbitInKey( get_orbit_rate() );
+	return true;
+}
+
+
+bool camera_move_backward( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setOrbitOutKey( get_orbit_rate() );
+	return true;
+}
+
+bool camera_move_forward_sitting( EKeystate s )
+{
+	if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return true;
+	if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun()))
+	{
+		agent_push_forward(s);
+	}
+	else
+	{
+		gAgentCamera.setOrbitInKey( get_orbit_rate() );
+	}
+	return true;
+}
+
+bool camera_move_backward_sitting( EKeystate s )
+{
+	if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return true;
+
+	if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun()))
+	{
+		agent_push_backward(s);
+	}
+	else
+	{
+		gAgentCamera.setOrbitOutKey( get_orbit_rate() );
+	}
+	return true;
+}
+
+bool camera_pan_up( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setPanUpKey( get_orbit_rate() );
+	return true;
+}
+
+bool camera_pan_down( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setPanDownKey( get_orbit_rate() );
+	return true;
+}
+
+bool camera_pan_left( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setPanLeftKey( get_orbit_rate() );
+	return true;
+}
+
+bool camera_pan_right( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setPanRightKey( get_orbit_rate() );
+	return true;
+}
+
+bool camera_pan_in( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setPanInKey( get_orbit_rate() );
+	return true;
+}
+
+bool camera_pan_out( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setPanOutKey( get_orbit_rate() );
+	return true;
+}
+
+bool camera_move_forward_fast( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setOrbitInKey(2.5f);
+	return true;
+}
+
+bool camera_move_backward_fast( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gAgentCamera.unlockView();
+	gAgentCamera.setOrbitOutKey(2.5f);
+	return true;
+}
+
+
+bool edit_avatar_spin_ccw( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gMorphView->setCameraDrivenByKeys( TRUE );
+	gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
+	//gMorphView->orbitLeft( get_orbit_rate() );
+	return true;
+}
+
+
+bool edit_avatar_spin_cw( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gMorphView->setCameraDrivenByKeys( TRUE );
+	gAgentCamera.setOrbitRightKey( get_orbit_rate() );
+	//gMorphView->orbitRight( get_orbit_rate() );
+	return true;
+}
+
+bool edit_avatar_spin_over( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gMorphView->setCameraDrivenByKeys( TRUE );
+	gAgentCamera.setOrbitUpKey( get_orbit_rate() );
+	//gMorphView->orbitUp( get_orbit_rate() );
+	return true;
+}
+
+
+bool edit_avatar_spin_under( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gMorphView->setCameraDrivenByKeys( TRUE );
+	gAgentCamera.setOrbitDownKey( get_orbit_rate() );
+	//gMorphView->orbitDown( get_orbit_rate() );
+	return true;
+}
+
+bool edit_avatar_move_forward( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gMorphView->setCameraDrivenByKeys( TRUE );
+	gAgentCamera.setOrbitInKey( get_orbit_rate() );
+	//gMorphView->orbitIn();
+	return true;
+}
+
+
+bool edit_avatar_move_backward( EKeystate s )
+{
+	if( KEYSTATE_UP == s  ) return true;
+	gMorphView->setCameraDrivenByKeys( TRUE );
+	gAgentCamera.setOrbitOutKey( get_orbit_rate() );
+	//gMorphView->orbitOut();
+	return true;
+}
+
+bool stop_moving( EKeystate s )
+{
+	//it's supposed that 'stop moving' key will be held down for some time
+	if( KEYSTATE_UP == s  ) return true;
+	// stop agent
+	gAgent.setControlFlags(AGENT_CONTROL_STOP);
+
+	// cancel autopilot
+	gAgent.stopAutoPilot();
+	return true;
+}
+
+bool start_chat( EKeystate s )
+{
+    if (LLAppViewer::instance()->quitRequested())
+    {
+        return true; // can't talk, gotta go, kthxbye!
+    }
+    if (KEYSTATE_DOWN != s) return true;
+
+	// start chat
+	LLFloaterIMNearbyChat::startChat(NULL);
+	return true;
+}
+
+bool start_gesture( EKeystate s )
+{
+	LLUICtrl* focus_ctrlp = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
+	if (KEYSTATE_UP == s &&
+		! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))
+	{
+ 		if ((LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->getCurrentChat().empty())
+ 		{
+ 			// No existing chat in chat editor, insert '/'
+ 			LLFloaterIMNearbyChat::startChat("/");
+ 		}
+ 		else
+ 		{
+ 			// Don't overwrite existing text in chat editor
+ 			LLFloaterIMNearbyChat::startChat(NULL);
+ 		}
+	}
+	return true;
+}
+
+bool run_forward(EKeystate s)
+{
+    if (KEYSTATE_UP != s)
+    {
+        if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD)
+        {
+            gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_FORWARD;
+        }
+        if (!gAgent.getRunning())
+        {
+// [RLVa:KB] - @temprun
+			gAgent.setTempRun();
+// [/RLVa:KB]
+//            gAgent.setRunning();
+//            gAgent.sendWalkRun(true);
+        }
+    }
+    else if(KEYSTATE_UP == s)
+    {
+        if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_FORWARD)
+            gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE;
+// [RLVa:KB] - @temprun
+		gAgent.clearTempRun();
+// [/RLVa:KB]
+//        gAgent.clearRunning();
+//        gAgent.sendWalkRun(false);
+    }
+    agent_push_forward(s);
+    return true;
+}
+
+bool run_backward(EKeystate s)
+{
+    if (KEYSTATE_UP != s)
+    {
+        if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD)
+        {
+            gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_BACKWARD;
+        }
+        if (!gAgent.getRunning())
+        {
+// [RLVa:KB] - @temprun
+			gAgent.setTempRun();
+// [/RLVa:KB]
+//            gAgent.setRunning();
+//            gAgent.sendWalkRun(true);
+        }
+    }
+    else if (KEYSTATE_UP == s)
+    {
+        if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_BACKWARD)
+            gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE;
+// [RLVa:KB] - @temprun
+		gAgent.clearTempRun();
+// [/RLVa:KB]
+//        gAgent.clearRunning();
+//        gAgent.sendWalkRun(false);
+    }
+    agent_push_backward(s);
+    return true;
+}
+
+bool run_left(EKeystate s)
+{
+    if (KEYSTATE_UP != s)
+    {
+        if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT)
+        {
+            gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_SLIDELEFT;
+        }
+        if (!gAgent.getRunning())
+        {
+// [RLVa:KB] - @temprun
+			gAgent.setTempRun();
+// [/RLVa:KB]
+//            gAgent.setRunning();
+//            gAgent.sendWalkRun(true);
+        }
+    }
+    else if (KEYSTATE_UP == s)
+    {
+        if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_SLIDELEFT)
+            gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE;
+// [RLVa:KB] - @temprun
+		gAgent.clearTempRun();
+// [/RLVa:KB]
+//        gAgent.clearRunning();
+//        gAgent.sendWalkRun(false);
+    }
+    agent_slide_left(s);
+    return true;
+}
+
+bool run_right(EKeystate s)
+{
+    if (KEYSTATE_UP != s)
+    {
+        if (gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT)
+        {
+            gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_SLIDERIGHT;
+        }
+        if (!gAgent.getRunning())
+        {
+// [RLVa:KB] - @temprun
+			gAgent.setTempRun();
+// [/RLVa:KB]
+//            gAgent.setRunning();
+//            gAgent.sendWalkRun(true);
+        }
+    }
+    else if (KEYSTATE_UP == s)
+    {
+        if (gAgent.mDoubleTapRunMode == LLAgent::DOUBLETAP_SLIDERIGHT)
+            gAgent.mDoubleTapRunMode = LLAgent::DOUBLETAP_NONE;
+// [RLVa:KB] - @temprun
+		gAgent.clearTempRun();
+// [/RLVa:KB]
+//        gAgent.clearRunning();
+//        gAgent.sendWalkRun(false);
+    }
+    agent_slide_right(s);
+    return true;
+}
+
+bool toggle_run(EKeystate s)
+{
+    if (KEYSTATE_DOWN != s) return true;
+    bool run = gAgent.getAlwaysRun();
+    if (run)
+    {
+// [RLVa:KB] - @alwaysrun
+		gAgent.clearAlwaysRun();
+// [/RLVa:KB]
+//        gAgent.clearAlwaysRun();
+//        gAgent.clearRunning();
+    }
+    else
+    {
+// [RLVa:KB] - @alwaysrun
+		gAgent.setAlwaysRun();
+// [/RLVa:KB]
+//        gAgent.setAlwaysRun();
+//        gAgent.setRunning();
+    }
+//    gAgent.sendWalkRun(!run);
+	return true;
+}
+
+bool toggle_sit(EKeystate s)
+{
+    if (KEYSTATE_DOWN != s) return true;
+    if (gAgent.isSitting())
+    {
+        gAgent.standUp();
+    }
+    else
+    {
+        gAgent.sitDown();
+    }
+	return true;
+}
+
+bool toggle_pause_media(EKeystate s) // analogue of play/pause button in top bar
+{
+    if (KEYSTATE_DOWN != s) return true;
+    bool pause = LLViewerMedia::getInstance()->isAnyMediaPlaying();
+    LLViewerMedia::getInstance()->setAllMediaPaused(pause);
+    return true;
+}
+
+bool toggle_enable_media(EKeystate s)
+{
+    if (KEYSTATE_DOWN != s) return true;
+    bool pause = LLViewerMedia::getInstance()->isAnyMediaPlaying() || LLViewerMedia::getInstance()->isAnyMediaShowing();
+    LLViewerMedia::getInstance()->setAllMediaEnabled(!pause);
+    return true;
+}
+
+bool walk_to(EKeystate s)
+{
+    if (KEYSTATE_DOWN != s) return true;
+    return LLToolPie::getInstance()->walkToClickedLocation();
+}
+
+bool teleport_to(EKeystate s)
+{
+    if (KEYSTATE_DOWN != s) return true;
+    return LLToolPie::getInstance()->teleportToClickedLocation();
+}
+
+bool toggle_voice(EKeystate s)
+{
+    if (KEYSTATE_DOWN != s) return true;
+    if (!LLAgent::isActionAllowed("speak")) return false;
+    LLVoiceClient::getInstance()->toggleUserPTTState();
+    return true;
+}
+
+bool voice_follow_key(EKeystate s)
+{
+    if (KEYSTATE_DOWN == s)
+    {
+        if (!LLAgent::isActionAllowed("speak")) return false;
+        LLVoiceClient::getInstance()->setUserPTTState(true);
+        return true;
+    }
+    else if (KEYSTATE_UP == s && LLVoiceClient::getInstance()->getUserPTTState())
+    {
+        LLVoiceClient::getInstance()->setUserPTTState(false);
+        return true;
+    }
+    return false;
+}
+
+bool agen_control_lbutton_handle(EKeystate s)
+{
+    switch (s)
+    {
+    case KEYSTATE_DOWN:
+        gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_DOWN);
+        break;
+    case KEYSTATE_UP:
+        gAgent.setControlFlags(AGENT_CONTROL_LBUTTON_UP);
+        break;
+    default:
+        break;
+    }
+    return true;
+}
+
+#define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION);
+REGISTER_KEYBOARD_ACTION("jump", agent_jump);
+REGISTER_KEYBOARD_ACTION("push_down", agent_push_down);
+REGISTER_KEYBOARD_ACTION("push_forward", agent_push_forward);
+REGISTER_KEYBOARD_ACTION("push_backward", agent_push_backward);
+REGISTER_KEYBOARD_ACTION("look_up", agent_look_up);
+REGISTER_KEYBOARD_ACTION("look_down", agent_look_down);
+REGISTER_KEYBOARD_ACTION("toggle_fly", agent_toggle_fly);
+REGISTER_KEYBOARD_ACTION("turn_left", agent_turn_left);
+REGISTER_KEYBOARD_ACTION("turn_right", agent_turn_right);
+REGISTER_KEYBOARD_ACTION("slide_left", agent_slide_left);
+REGISTER_KEYBOARD_ACTION("slide_right", agent_slide_right);
+REGISTER_KEYBOARD_ACTION("spin_around_ccw", camera_spin_around_ccw);
+REGISTER_KEYBOARD_ACTION("spin_around_cw", camera_spin_around_cw);
+REGISTER_KEYBOARD_ACTION("spin_around_ccw_sitting", camera_spin_around_ccw_sitting);
+REGISTER_KEYBOARD_ACTION("spin_around_cw_sitting", camera_spin_around_cw_sitting);
+REGISTER_KEYBOARD_ACTION("spin_over", camera_spin_over);
+REGISTER_KEYBOARD_ACTION("spin_under", camera_spin_under);
+REGISTER_KEYBOARD_ACTION("spin_over_sitting", camera_spin_over_sitting);
+REGISTER_KEYBOARD_ACTION("spin_under_sitting", camera_spin_under_sitting);
+REGISTER_KEYBOARD_ACTION("move_forward", camera_move_forward);
+REGISTER_KEYBOARD_ACTION("move_backward", camera_move_backward);
+REGISTER_KEYBOARD_ACTION("move_forward_sitting", camera_move_forward_sitting);
+REGISTER_KEYBOARD_ACTION("move_backward_sitting", camera_move_backward_sitting);
+REGISTER_KEYBOARD_ACTION("pan_up", camera_pan_up);
+REGISTER_KEYBOARD_ACTION("pan_down", camera_pan_down);
+REGISTER_KEYBOARD_ACTION("pan_left", camera_pan_left);
+REGISTER_KEYBOARD_ACTION("pan_right", camera_pan_right);
+REGISTER_KEYBOARD_ACTION("pan_in", camera_pan_in);
+REGISTER_KEYBOARD_ACTION("pan_out", camera_pan_out);
+REGISTER_KEYBOARD_ACTION("move_forward_fast", camera_move_forward_fast);
+REGISTER_KEYBOARD_ACTION("move_backward_fast", camera_move_backward_fast);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_ccw", edit_avatar_spin_ccw);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_cw", edit_avatar_spin_cw);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_over", edit_avatar_spin_over);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_under", edit_avatar_spin_under);
+REGISTER_KEYBOARD_ACTION("edit_avatar_move_forward", edit_avatar_move_forward);
+REGISTER_KEYBOARD_ACTION("edit_avatar_move_backward", edit_avatar_move_backward);
+REGISTER_KEYBOARD_ACTION("stop_moving", stop_moving);
+REGISTER_KEYBOARD_ACTION("start_chat", start_chat);
+REGISTER_KEYBOARD_ACTION("start_gesture", start_gesture);
+REGISTER_KEYBOARD_ACTION("run_forward", run_forward);
+REGISTER_KEYBOARD_ACTION("run_backward", run_backward);
+REGISTER_KEYBOARD_ACTION("run_left", run_left);
+REGISTER_KEYBOARD_ACTION("run_right", run_right);
+REGISTER_KEYBOARD_ACTION("toggle_run", toggle_run);
+REGISTER_KEYBOARD_ACTION("toggle_sit", toggle_sit);
+REGISTER_KEYBOARD_ACTION("toggle_pause_media", toggle_pause_media);
+REGISTER_KEYBOARD_ACTION("toggle_enable_media", toggle_enable_media);
+REGISTER_KEYBOARD_ACTION("teleport_to", teleport_to);
+REGISTER_KEYBOARD_ACTION("walk_to", walk_to);
+REGISTER_KEYBOARD_ACTION("toggle_voice", toggle_voice);
+REGISTER_KEYBOARD_ACTION("voice_follow_key", voice_follow_key);
+#undef REGISTER_KEYBOARD_ACTION
+
+LLViewerInput::LLViewerInput()
+{
+    resetBindings();
+
+	for (S32 i = 0; i < KEY_COUNT; i++)
+	{
+		mKeyHandledByUI[i] = FALSE;
+    }
+    for (S32 i = 0; i < CLICK_COUNT; i++)
+    {
+        mMouseLevel[i] = MOUSE_STATE_SILENT;
+    }
+	// we want the UI to never see these keys so that they can always control the avatar/camera
+	for(KEY k = KEY_PAD_UP; k <= KEY_PAD_DIVIDE; k++) 
+	{
+		mKeysSkippedByUI.insert(k);	
+	}
+}
+
+// static
+BOOL LLViewerInput::modeFromString(const std::string& string, S32 *mode)
+{
+	if (string == "FIRST_PERSON")
+	{
+		*mode = MODE_FIRST_PERSON;
+		return TRUE;
+	}
+	else if (string == "THIRD_PERSON")
+	{
+		*mode = MODE_THIRD_PERSON;
+		return TRUE;
+	}
+	else if (string == "EDIT_AVATAR")
+	{
+		*mode = MODE_EDIT_AVATAR;
+		return TRUE;
+	}
+	else if (string == "SITTING")
+	{
+		*mode = MODE_SITTING;
+		return TRUE;
+	}
+	else
+	{
+		*mode = MODE_THIRD_PERSON;
+		return FALSE;
+	}
+}
+
+// static
+BOOL LLViewerInput::mouseFromString(const std::string& string, EMouseClickType *mode)
+{
+    if (string == "LMB")
+    {
+        *mode = CLICK_LEFT;
+        return TRUE;
+    }
+    else if (string == "Double LMB")
+    {
+        *mode = CLICK_DOUBLELEFT;
+        return TRUE;
+    }
+    else if (string == "MMB")
+    {
+        *mode = CLICK_MIDDLE;
+        return TRUE;
+    }
+    else if (string == "MB4")
+    {
+        *mode = CLICK_BUTTON4;
+        return TRUE;
+    }
+    else if (string == "MB5")
+    {
+        *mode = CLICK_BUTTON5;
+        return TRUE;
+    }
+    else
+    {
+        *mode = CLICK_NONE;
+        return FALSE;
+    }
+}
+
+BOOL LLViewerInput::handleKey(KEY translated_key, MASK translated_mask, BOOL repeated)
+{
+	// check for re-map
+	EKeyboardMode mode = gViewerInput.getMode();
+	U32 keyidx = (translated_mask<<16) | translated_key;
+	key_remap_t::iterator iter = mRemapKeys[mode].find(keyidx);
+	if (iter != mRemapKeys[mode].end())
+	{
+		translated_key = (iter->second) & 0xff;
+		translated_mask = (iter->second)>>16;
+	}
+
+	// No repeats of F-keys
+	BOOL repeatable_key = (translated_key < KEY_F1 || translated_key > KEY_F12);
+	if (!repeatable_key && repeated)
+	{
+		return FALSE;
+	}
+
+	LL_DEBUGS("UserInput") << "keydown -" << translated_key << "-" << LL_ENDL;
+	// skip skipped keys
+	if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end()) 
+	{
+		mKeyHandledByUI[translated_key] = FALSE;
+		LL_INFOS("KeyboardHandling") << "Key wasn't handled by UI!" << LL_ENDL;
+	}
+	else
+	{
+		// it is sufficient to set this value once per call to handlekey
+		// without clearing it, as it is only used in the subsequent call to scanKey
+		mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask); 
+		// mKeyHandledByUI is not what you think ... this indicates whether the UI has handled this keypress yet (any keypress)
+		// NOT whether some UI shortcut wishes to handle the keypress
+	  
+	}
+	return mKeyHandledByUI[translated_key];
+}
+
+BOOL LLViewerInput::handleKeyUp(KEY translated_key, MASK translated_mask)
+{
+	return gViewerWindow->handleKeyUp(translated_key, translated_mask);
+}
+
+BOOL LLViewerInput::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name)
+{
+	S32 index;
+	typedef boost::function<bool(EKeystate)> function_t;
+	function_t function = NULL;
+	std::string name;
+
+	// Allow remapping of F2-F12
+	if (function_name[0] == 'F')
+	{
+		int c1 = function_name[1] - '0';
+		int c2 = function_name[2] ? function_name[2] - '0' : -1;
+		if (c1 >= 0 && c1 <= 9 && c2 >= -1 && c2 <= 9)
+		{
+			int idx = c1;
+			if (c2 >= 0)
+				idx = idx*10 + c2;
+			if (idx >=2 && idx <= 12)
+			{
+				U32 keyidx = ((mask<<16)|key);
+				(mRemapKeys[mode])[keyidx] = ((0<<16)|(KEY_F1+(idx-1)));
+				return TRUE;
+			}
+		}
+	}
+
+	// Not remapped, look for a function
+	
+	function_t* result = LLKeyboardActionRegistry::getValue(function_name);
+	if (result)
+	{
+		function = *result;
+	}
+
+	if (!function)
+	{
+		LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL;
+		return FALSE;
+	}
+
+	// check for duplicate first and overwrite
+    S32 size = mKeyBindings[mode].size();
+    for (index = 0; index < size; index++)
+    {
+        if (key == mKeyBindings[mode][index].mKey && mask == mKeyBindings[mode][index].mMask)
+            break;
+    }
+
+	if (mode >= MODE_COUNT)
+	{
+		LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL;
+		return FALSE;
+	}
+
+    LLKeyboardBinding bind;
+    bind.mKey = key;
+    bind.mMask = mask;
+    bind.mFunction = function;
+
+    mKeyBindings[mode].push_back(bind);
+
+	return TRUE;
+}
+
+BOOL LLViewerInput::bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const std::string& function_name)
+{
+    S32 index;
+    typedef boost::function<bool(EKeystate)> function_t;
+    function_t function = NULL;
+
+    function_t* result = LLKeyboardActionRegistry::getValue(function_name);
+    if (result)
+    {
+        function = *result;
+    }
+
+    if (!function)
+    {
+        LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL;
+        return FALSE;
+    }
+
+    // check for duplicate first and overwrite
+    S32 size = mMouseBindings[mode].size();
+    for (index = 0; index < size; index++)
+    {
+        if (mouse == mMouseBindings[mode][index].mMouse && mask == mMouseBindings[mode][index].mMask)
+            break;
+    }
+
+    if (mode >= MODE_COUNT)
+    {
+        LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL;
+        return FALSE;
+    }
+
+    LLMouseBinding bind;
+    bind.mMouse = mouse;
+    bind.mMask = mask;
+    bind.mFunction = function;
+
+    mMouseBindings[mode].push_back(bind);
+
+    return TRUE;
+}
+
+LLViewerInput::KeyBinding::KeyBinding()
+:	key("key"),
+	mouse("mouse"),
+	mask("mask"),
+	command("command")
+{}
+
+LLViewerInput::KeyMode::KeyMode()
+:	bindings("binding")
+{}
+
+LLViewerInput::Keys::Keys()
+:	first_person("first_person"),
+	third_person("third_person"),
+	sitting("sitting"),
+	edit_avatar("edit_avatar")
+{}
+
+void LLViewerInput::resetBindings()
+{
+    for (S32 i = 0; i < MODE_COUNT; i++)
+    {
+        mKeyBindings[i].clear();
+        mMouseBindings[i].clear();
+    }
+}
+
+S32 LLViewerInput::loadBindingsXML(const std::string& filename)
+{
+    resetBindings();
+
+	S32 binding_count = 0;
+	Keys keys;
+	LLSimpleXUIParser parser;
+
+	if (parser.readXUI(filename, keys) 
+		&& keys.validateBlock())
+	{
+		binding_count += loadBindingMode(keys.first_person, MODE_FIRST_PERSON);
+		binding_count += loadBindingMode(keys.third_person, MODE_THIRD_PERSON);
+		binding_count += loadBindingMode(keys.sitting, MODE_SITTING);
+		binding_count += loadBindingMode(keys.edit_avatar, MODE_EDIT_AVATAR);
+	}
+	return binding_count;
+}
+
+S32 count_masks(const MASK &mask)
+{
+    S32 res = 0;
+    if (mask & MASK_CONTROL)
+    {
+        res++;
+    }
+    if (mask & MASK_SHIFT)
+    {
+        res++;
+    }
+    if (mask & MASK_ALT)
+    {
+        res++;
+    }
+    return res;
+}
+
+bool compare_key_by_mask(LLKeyboardBinding i1, LLKeyboardBinding i2)
+{
+    return (count_masks(i1.mMask) > count_masks(i2.mMask));
+}
+
+bool compare_mouse_by_mask(LLMouseBinding i1, LLMouseBinding i2)
+{
+    return (count_masks(i1.mMask) > count_masks(i2.mMask));
+}
+
+S32 LLViewerInput::loadBindingMode(const LLViewerInput::KeyMode& keymode, S32 mode)
+{
+	S32 binding_count = 0;
+	for (LLInitParam::ParamIterator<KeyBinding>::const_iterator it = keymode.bindings.begin(), 
+			end_it = keymode.bindings.end();
+		it != end_it;
+		++it)
+	{
+        bool processed = false;
+        std::string key_str = it->key.getValue();
+        if (!key_str.empty() && key_str != "NONE")
+        {
+            KEY key;
+            LLKeyboard::keyFromString(key_str, &key);
+            if (key != KEY_NONE)
+            {
+                MASK mask;
+                LLKeyboard::maskFromString(it->mask, &mask);
+                bindKey(mode, key, mask, it->command);
+                processed = true;
+            }
+            else
+            {
+                LL_WARNS_ONCE() << "There might be issues in keybindings' file" << LL_ENDL;
+            }
+        }
+        if (!processed && it->mouse.isProvided() && !it->mouse.getValue().empty())
+        {
+            EMouseClickType mouse;
+            mouseFromString(it->mouse.getValue(), &mouse);
+            if (mouse != CLICK_NONE)
+            {
+                MASK mask;
+                LLKeyboard::maskFromString(it->mask, &mask);
+                bindMouse(mode, mouse, mask, it->command);
+                processed = true;
+            }
+            else
+            {
+                LL_WARNS_ONCE() << "There might be issues in keybindings' file" << LL_ENDL;
+            }
+        }
+        if (processed)
+        {
+            // total
+            binding_count++;
+        }
+    }
+
+    // sort lists by mask (so that Shift+W is executed before W, if both are assigned, but if Shift+W is not assigned W should be executed)
+    std::sort(mKeyBindings[mode].begin(), mKeyBindings[mode].end(), compare_key_by_mask);
+    std::sort(mMouseBindings[mode].begin(), mMouseBindings[mode].end(), compare_mouse_by_mask);
+
+	return binding_count;
+}
+
+EKeyboardMode LLViewerInput::getMode() const
+{
+	if ( gAgentCamera.cameraMouselook() )
+	{
+		return MODE_FIRST_PERSON;
+	}
+	else if ( gMorphView && gMorphView->getVisible())
+	{
+		return MODE_EDIT_AVATAR;
+	}
+	else if (isAgentAvatarValid() && gAgentAvatarp->isSitting())
+	{
+		return MODE_SITTING;
+	}
+	else
+	{
+		return MODE_THIRD_PERSON;
+	}
+}
+
+bool LLViewerInput::scanKey(const std::vector<LLKeyboardBinding> &binding,
+                               S32 binding_count,
+                               KEY key,
+                               MASK mask,
+                               BOOL key_down,
+                               BOOL key_up,
+                               BOOL key_level,
+                               bool repeat) const
+{
+	for (S32 i = 0; i < binding_count; i++)
+	{
+		if (binding[i].mKey == key)
+		{
+			if ((binding[i].mMask & mask) == binding[i].mMask)
+			{
+				bool res = false;
+				if (key_down && !repeat)
+				{
+					// ...key went down this frame, call function
+					res = binding[i].mFunction( KEYSTATE_DOWN );
+					return true;
+				}
+				else if (key_up)
+				{
+					// ...key went down this frame, call function
+					res = binding[i].mFunction( KEYSTATE_UP );
+				}
+				else if (key_level)
+				{
+					// ...key held down from previous frame
+					// Not windows, just call the function.
+					res = binding[i].mFunction( KEYSTATE_LEVEL );
+				}//if
+				// Key+Mask combinations are supposed to be unique, so we won't find anything else
+				return res;
+			}//if
+		}//if
+	}//for
+	return false;
+}
+
+// Called from scanKeyboard.
+bool LLViewerInput::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level) const
+{
+	if (LLApp::isExiting())
+	{
+		return false;
+	}
+
+	S32 mode = getMode();
+	// Consider keyboard scanning as NOT mouse event. JC
+	MASK mask = gKeyboard->currentMask(FALSE);
+
+	if (mKeyHandledByUI[key])
+	{
+		return false;
+	}
+
+	// don't process key down on repeated keys
+	BOOL repeat = gKeyboard->getKeyRepeated(key);
+
+    bool res = scanKey(mKeyBindings[mode], mKeyBindings[mode].size(), key, mask, key_down, key_up, key_level, repeat);
+
+    if (!res && agent_control_lbutton.canHandle(CLICK_NONE, key, mask))
+    {
+        if (key_down && !repeat)
+        {
+            res = agen_control_lbutton_handle(KEYSTATE_DOWN);
+        }
+        if (key_up)
+        {
+            res = agen_control_lbutton_handle(KEYSTATE_UP);
+        }
+    }
+    return res;
+}
+
+BOOL LLViewerInput::handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down)
+{
+    BOOL handled = gViewerWindow->handleAnyMouseClick(window_impl, pos, mask, clicktype, down);
+
+    if (clicktype != CLICK_NONE)
+    {
+        // Special case
+        // If UI doesn't handle double click, LMB click is issued, so supres LMB 'down' when doubleclick is set
+        // handle !down as if we are handling doubleclick
+
+        bool double_click_sp = (clicktype == CLICK_LEFT
+            && (mMouseLevel[CLICK_DOUBLELEFT] != MOUSE_STATE_SILENT)
+            && mMouseLevel[CLICK_LEFT] == MOUSE_STATE_SILENT);
+        if (double_click_sp && !down)
+        {
+            // Process doubleclick instead
+            clicktype = CLICK_DOUBLELEFT;
+        }
+
+
+        if (double_click_sp && down)
+        {
+            // Consume click.
+            // Due to handling, double click that is not handled will be immediately followed by LMB click
+        }
+        // If UI handled 'down', it should handle 'up' as well
+        // If we handle 'down' not by UI, then we should handle 'up'/'level' regardless of UI
+        else if (handled)
+        {
+            // UI handled new 'down' so iterupt whatever state we were in.
+            if (mMouseLevel[clicktype] != MOUSE_STATE_SILENT)
+            {
+                if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN)
+                {
+                    mMouseLevel[clicktype] = MOUSE_STATE_CLICK;
+                }
+                else
+                {
+                    mMouseLevel[clicktype] = MOUSE_STATE_UP;
+                }
+            }
+        }
+        else if (down)
+        {
+            if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN)
+            {
+                // this is repeated hit (mouse does not repeat event until release)
+                // for now treat rapid clicking like mouse being held
+                mMouseLevel[clicktype] = MOUSE_STATE_LEVEL;
+            }
+            else
+            {
+                mMouseLevel[clicktype] = MOUSE_STATE_DOWN;
+            }
+        }
+        else if (mMouseLevel[clicktype] != MOUSE_STATE_SILENT)
+        {
+            // Released mouse key
+            if (mMouseLevel[clicktype] == MOUSE_STATE_DOWN)
+            {
+                mMouseLevel[clicktype] = MOUSE_STATE_CLICK;
+            }
+            else 
+            {
+                mMouseLevel[clicktype] = MOUSE_STATE_UP;
+            }
+        }
+    }
+
+    return handled;
+}
+
+bool LLViewerInput::scanMouse(const std::vector<LLMouseBinding> &binding, S32 binding_count, EMouseClickType mouse, MASK mask, EMouseState state) const
+{
+    for (S32 i = 0; i < binding_count; i++)
+    {
+        if (binding[i].mMouse == mouse && (binding[i].mMask & mask) == binding[i].mMask)
+        {
+            bool res = false;
+            switch (state)
+            {
+            case MOUSE_STATE_DOWN:
+                res = binding[i].mFunction(KEYSTATE_DOWN);
+                break;
+            case MOUSE_STATE_CLICK:
+                // Button went down and up in scope of single frame
+                // might not work best with some functions,
+                // but some function need specific states specifically
+                res = binding[i].mFunction(KEYSTATE_DOWN);
+                res |= binding[i].mFunction(KEYSTATE_UP);
+                break;
+            case MOUSE_STATE_LEVEL:
+                res = binding[i].mFunction(KEYSTATE_LEVEL);
+                break;
+            case MOUSE_STATE_UP:
+                res = binding[i].mFunction(KEYSTATE_UP);
+                break;
+            default:
+                break;
+            }
+            // Key+Mask combinations are supposed to be unique, no need to continue
+            return res;
+        }
+    }
+    return false;
+}
+
+// todo: this recods key, scanMouse() triggers functions with EKeystate
+bool LLViewerInput::scanMouse(EMouseClickType click, EMouseState state) const
+{
+    bool res = false;
+    S32 mode = getMode();
+    MASK mask = gKeyboard->currentMask(TRUE);
+    res = scanMouse(mMouseBindings[mode], mMouseBindings[mode].size(), click, mask, state);
+    // no user defined actions found or those actions can't handle the key/button, handle control if nessesary
+    if (!res && agent_control_lbutton.canHandle(click, KEY_NONE, mask))
+    {
+        switch (state)
+        {
+        case MOUSE_STATE_DOWN:
+            agen_control_lbutton_handle(KEYSTATE_DOWN);
+            res = true;
+            break;
+        case MOUSE_STATE_CLICK:
+            // might not work best with some functions,
+            // but some function need specific states too specifically
+            agen_control_lbutton_handle(KEYSTATE_DOWN);
+            agen_control_lbutton_handle(KEYSTATE_UP);
+            res = true;
+            break;
+        case MOUSE_STATE_UP:
+            agen_control_lbutton_handle(KEYSTATE_UP);
+            res = true;
+            break;
+        default:
+            break;
+        }
+    }
+    return res;
+}
+
+void LLViewerInput::scanMouse()
+{
+    for (S32 i = 0; i < CLICK_COUNT; i++)
+    {
+        if (mMouseLevel[i] != MOUSE_STATE_SILENT)
+        {
+            scanMouse((EMouseClickType)i, mMouseLevel[i]);
+            if (mMouseLevel[i] == MOUSE_STATE_DOWN)
+            {
+                // mouse doesn't support 'continued' state, so after handling, switch to LEVEL
+                mMouseLevel[i] = MOUSE_STATE_LEVEL;
+            }
+            else if (mMouseLevel[i] == MOUSE_STATE_UP || mMouseLevel[i] == MOUSE_STATE_CLICK)
+            {
+                mMouseLevel[i] = MOUSE_STATE_SILENT;
+            }
+        }
+    }
+}
+
+bool LLViewerInput::isMouseBindUsed(const EMouseClickType mouse, const MASK mask, const S32 mode)
+{
+    S32 size = mMouseBindings[mode].size();
+    for (S32 index = 0; index < size; index++)
+    {
+        if (mouse == mMouseBindings[mode][index].mMouse && mask == mMouseBindings[mode][index].mMask)
+            return true;
+    }
+    return false;
+}
diff --git a/indra/newview/llviewerinput.h b/indra/newview/llviewerinput.h
new file mode 100644
index 0000000000000000000000000000000000000000..281a209896237a7ec82a433798560b9a881e22a3
--- /dev/null
+++ b/indra/newview/llviewerinput.h
@@ -0,0 +1,179 @@
+/** 
+ * @file llviewerinput.h
+ * @brief LLViewerInput class header file
+ *
+ * $LicenseInfo:firstyear=2005&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLVIEWERINPUT_H
+#define LL_LLVIEWERINPUT_H
+
+#include "llkeyboard.h" // For EKeystate
+#include "llinitparam.h"
+
+const S32 MAX_KEY_BINDINGS = 128; // was 60
+
+class LLNamedFunction
+{
+public:
+	LLNamedFunction() : mFunction(NULL) { };
+	~LLNamedFunction() { };
+
+	std::string	mName;
+	LLKeyFunc	mFunction;
+};
+
+class LLKeyboardBinding
+{
+public:
+    KEY				mKey;
+    MASK			mMask;
+
+    LLKeyFunc		mFunction;
+};
+
+class LLMouseBinding
+{
+public:
+    EMouseClickType	mMouse;
+    MASK			mMask;
+
+    LLKeyFunc		mFunction;
+};
+
+
+typedef enum e_keyboard_mode
+{
+	MODE_FIRST_PERSON,
+	MODE_THIRD_PERSON,
+	MODE_EDIT_AVATAR,
+	MODE_SITTING,
+	MODE_COUNT
+} EKeyboardMode;
+
+class LLWindow;
+
+void bind_keyboard_functions();
+
+class LLViewerInput
+{
+public:
+	struct KeyBinding : public LLInitParam::Block<KeyBinding>
+	{
+		Mandatory<std::string>	key,
+								mask,
+								command;
+		Optional<std::string>	mouse; // Note, not mandatory for the sake of backward campatibility with keys.xml
+
+		KeyBinding();
+	};
+
+	struct KeyMode : public LLInitParam::Block<KeyMode>
+	{
+		Multiple<KeyBinding>		bindings;
+
+		KeyMode();
+	};
+
+	struct Keys : public LLInitParam::Block<Keys>
+	{
+		Optional<KeyMode>	first_person,
+							third_person,
+							sitting,
+							edit_avatar;
+
+		Keys();
+	};
+
+	LLViewerInput();
+
+	BOOL			handleKey(KEY key, MASK mask, BOOL repeated);
+	BOOL			handleKeyUp(KEY key, MASK mask);
+
+	S32				loadBindingsXML(const std::string& filename);										// returns number bound, 0 on error
+	EKeyboardMode	getMode() const;
+
+	static BOOL		modeFromString(const std::string& string, S32 *mode);			// False on failure
+	static BOOL		mouseFromString(const std::string& string, EMouseClickType *mode);// False on failure
+
+    bool            scanKey(KEY key,
+                            BOOL key_down,
+                            BOOL key_up,
+                            BOOL key_level) const;
+
+    // handleMouse() records state, scanMouse() goes through states, scanMouse(click) processes individual saved states after UI is done with them
+    BOOL            handleMouse(LLWindow *window_impl, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);
+    void            scanMouse();
+
+    bool            isMouseBindUsed(const EMouseClickType mouse, const MASK mask = MASK_NONE, const S32 mode = MODE_THIRD_PERSON);
+
+private:
+    bool            scanKey(const std::vector<LLKeyboardBinding> &binding,
+                            S32 binding_count,
+                            KEY key,
+                            MASK mask,
+                            BOOL key_down,
+                            BOOL key_up,
+                            BOOL key_level,
+                            bool repeat) const;
+
+    enum EMouseState
+    {
+        MOUSE_STATE_DOWN, // key down this frame
+        MOUSE_STATE_CLICK, // key went up and down in scope of same frame
+        MOUSE_STATE_LEVEL, // clicked again fast, or never released
+        MOUSE_STATE_UP, // went up this frame
+        MOUSE_STATE_SILENT // notified about 'up', do not notify again
+    };
+    bool			scanMouse(EMouseClickType click, EMouseState state) const;
+    bool            scanMouse(const std::vector<LLMouseBinding> &binding,
+                          S32 binding_count,
+                          EMouseClickType mouse,
+                          MASK mask,
+                          EMouseState state) const;
+
+    S32				loadBindingMode(const LLViewerInput::KeyMode& keymode, S32 mode);
+    BOOL			bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name);
+    BOOL			bindMouse(const S32 mode, const EMouseClickType mouse, const MASK mask, const std::string& function_name);
+    void			resetBindings();
+
+	// Hold all the ugly stuff torn out to make LLKeyboard non-viewer-specific here
+
+    // TODO: at some point it is better to remake this, especially keyaboard part
+    // would be much better to send to functions actual state of the button than
+    // to send what we think function wants based on collection of bools (mKeyRepeated, mKeyLevel, mKeyDown)
+    std::vector<LLKeyboardBinding>	mKeyBindings[MODE_COUNT];
+    std::vector<LLMouseBinding>		mMouseBindings[MODE_COUNT];
+
+	typedef std::map<U32, U32> key_remap_t;
+	key_remap_t		mRemapKeys[MODE_COUNT];
+	std::set<KEY>	mKeysSkippedByUI;
+	BOOL			mKeyHandledByUI[KEY_COUNT];		// key processed successfully by UI
+
+    // This is indentical to what llkeyboard does (mKeyRepeated, mKeyLevel, mKeyDown e t c),
+    // just instead of remembering individually as bools,  we record state as enum
+    EMouseState		mMouseLevel[CLICK_COUNT];	// records of key state
+};
+
+extern LLViewerInput gViewerInput;
+
+#endif // LL_LLVIEWERINPUT_H
diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp
index a448a95904bee8bcf65690f13b3da612164fe901..9653e80b536c68810a43d16162be0a9f2cd62348 100644
--- a/indra/newview/llviewerjoint.cpp
+++ b/indra/newview/llviewerjoint.cpp
@@ -143,8 +143,10 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
 	//----------------------------------------------------------------
 	for (LLJoint* j : mChildren)
 	{
-		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(j);
-		F32 jointLOD = joint ? joint->getLOD() : 0;
+		// LLViewerJoint is derived from LLAvatarJoint,
+		// all children of LLAvatarJoint are assumed to be LLAvatarJoint
+		LLAvatarJoint* joint = static_cast<LLAvatarJoint*>(j);
+		F32 jointLOD = joint->getLOD();
 		if (pixelArea >= jointLOD || sDisableLOD)
 		{
 			triangle_count += joint->render( pixelArea, TRUE, is_dummy );
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index fdfd22c1170da310609a381ff2cd172f968e7271..63ad708e59bd1f43e826c724f892b2683af9724e 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -56,7 +56,7 @@
 #include "m4math.h"
 #include "llmatrix4a.h"
 
-#if !LL_DARWIN && !LL_LINUX && !LL_SOLARIS
+#if !LL_DARWIN && !LL_LINUX
 extern PFNGLWEIGHTPOINTERARBPROC glWeightPointerARB;
 extern PFNGLWEIGHTFVARBPROC glWeightfvARB;
 extern PFNGLVERTEXBLENDARBPROC glVertexBlendARB;
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
deleted file mode 100644
index d04b2e8f9afab9b9a854990dbad2436bd6ba78ca..0000000000000000000000000000000000000000
--- a/indra/newview/llviewerkeyboard.cpp
+++ /dev/null
@@ -1,1046 +0,0 @@
-/** 
- * @file llviewerkeyboard.cpp
- * @brief LLViewerKeyboard class implementation
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llappviewer.h"
-#include "llfloaterreg.h"
-#include "llviewerkeyboard.h"
-#include "llmath.h"
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llfloaterimnearbychat.h"
-#include "llviewercontrol.h"
-#include "llfocusmgr.h"
-#include "llmorphview.h"
-#include "llmoveview.h"
-#include "lltoolfocus.h"
-#include "llviewerwindow.h"
-#include "llvoavatarself.h"
-#include "llfloatercamera.h"
-#include "llinitparam.h"
-
-//
-// Constants
-//
-
-const F32 FLY_TIME = 0.5f;
-const F32 FLY_FRAMES = 4;
-
-const F32 NUDGE_TIME = 0.25f;  // in seconds
-const S32 NUDGE_FRAMES = 2;
-const F32 ORBIT_NUDGE_RATE = 0.05f;  // fraction of normal speed
-
-struct LLKeyboardActionRegistry 
-:	public LLRegistrySingleton<std::string, boost::function<void (EKeystate keystate)>, LLKeyboardActionRegistry>
-{
-	LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry);
-};
-
-LLViewerKeyboard gViewerKeyboard;
-
-void agent_jump( EKeystate s )
-{
-	static BOOL first_fly_attempt(TRUE);
-	if (KEYSTATE_UP == s)
-	{
-		first_fly_attempt = TRUE;
-		return;
-	}
-	F32 time = gKeyboard->getCurKeyElapsedTime();
-	S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
-
-	if( time < FLY_TIME 
-		|| frame_count <= FLY_FRAMES 
-		|| gAgent.upGrabbed()
-		|| !gSavedSettings.getBOOL("AutomaticFly"))
-	{
-		gAgent.moveUp(1);
-	}
-	else
-	{
-		gAgent.setFlying(TRUE, first_fly_attempt);
-		first_fly_attempt = FALSE;
-		gAgent.moveUp(1);
-	}
-}
-
-void agent_push_down( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgent.moveUp(-1);
-}
-
-static void agent_check_temporary_run(LLAgent::EDoubleTapRunMode mode)
-{
-// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
-	if ( (gAgent.mDoubleTapRunMode == mode) && (gAgent.getTempRun()) )
-		gAgent.clearTempRun();
-// [/RLVa:KB]
-//	if (gAgent.mDoubleTapRunMode == mode &&
-//		gAgent.getRunning() &&
-//		!gAgent.getAlwaysRun())
-//	{
-//		// Turn off temporary running.
-//		gAgent.clearRunning();
-//		gAgent.sendWalkRun(gAgent.getRunning());
-//	}
-}
-
-static void agent_handle_doubletap_run(EKeystate s, LLAgent::EDoubleTapRunMode mode)
-{
-	if (KEYSTATE_UP == s)
-	{
-		// Note: in case shift is already released, slide left/right run
-		// will be released in agent_turn_left()/agent_turn_right()
-		agent_check_temporary_run(mode);
-	}
-	else if (gSavedSettings.getBOOL("AllowTapTapHoldRun") &&
-		 KEYSTATE_DOWN == s &&
-		 !gAgent.getRunning())
-	{
-		if (gAgent.mDoubleTapRunMode == mode &&
-		    gAgent.mDoubleTapRunTimer.getElapsedTimeF32() < NUDGE_TIME)
-		{
-			// Same walk-key was pushed again quickly; this is a
-			// double-tap so engage temporary running.
-//			gAgent.setRunning();
-//			gAgent.sendWalkRun(gAgent.getRunning());
-// [RLVa:KB] - Checked: 2011-05-11 (RLVa-1.3.0i) | Added: RLVa-1.3.0i
-			gAgent.setTempRun();
-// [/RLVa:KB]
-		}
-
-		// Pressing any walk-key resets the double-tap timer
-		gAgent.mDoubleTapRunTimer.reset();
-		gAgent.mDoubleTapRunMode = mode;
-	}
-}
-
-static void agent_push_forwardbackward( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode )
-{
-	agent_handle_doubletap_run(s, mode);
-	if (KEYSTATE_UP == s) return;
-
-	F32 time = gKeyboard->getCurKeyElapsedTime();
-	S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
-
-	if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES)
-	{
-		gAgent.moveAtNudge(direction);
-	}
-	else
-	{
-		gAgent.moveAt(direction);
-	}
-}
-
-void camera_move_forward( EKeystate s );
-
-void agent_push_forward( EKeystate s )
-{
-	if(gAgent.isMovementLocked()) return;
-
-	//in free camera control mode we need to intercept keyboard events for avatar movements
-	if (LLFloaterCamera::inFreeCameraMode())
-	{
-		camera_move_forward(s);
-	}
-	else
-	{
-		agent_push_forwardbackward(s, 1, LLAgent::DOUBLETAP_FORWARD);
-	}
-}
-
-void camera_move_backward( EKeystate s );
-
-void agent_push_backward( EKeystate s )
-{
-	if(gAgent.isMovementLocked()) return;
-
-	//in free camera control mode we need to intercept keyboard events for avatar movements
-	if (LLFloaterCamera::inFreeCameraMode())
-	{
-		camera_move_backward(s);
-	}
-	else if (!gAgent.backwardGrabbed() && gAgentAvatarp->isSitting() && gSavedSettings.getBOOL("LeaveMouselook"))
-	{
-		gAgentCamera.changeCameraToThirdPerson();
-	}
-	else
-	{
-		agent_push_forwardbackward(s, -1, LLAgent::DOUBLETAP_BACKWARD);
-	}
-}
-
-static void agent_slide_leftright( EKeystate s, S32 direction, LLAgent::EDoubleTapRunMode mode )
-{
-	agent_handle_doubletap_run(s, mode);
-	if( KEYSTATE_UP == s ) return;
-	F32 time = gKeyboard->getCurKeyElapsedTime();
-	S32 frame_count = ll_round(gKeyboard->getCurKeyElapsedFrameCount());
-
-	if( time < NUDGE_TIME || frame_count <= NUDGE_FRAMES)
-	{
-		gAgent.moveLeftNudge(direction);
-	}
-	else
-	{
-		gAgent.moveLeft(direction);
-	}
-}
-
-
-void agent_slide_left( EKeystate s )
-{
-	if(gAgent.isMovementLocked()) return;
-	agent_slide_leftright(s, 1, LLAgent::DOUBLETAP_SLIDELEFT);
-}
-
-
-void agent_slide_right( EKeystate s )
-{
-	if(gAgent.isMovementLocked()) return;
-	agent_slide_leftright(s, -1, LLAgent::DOUBLETAP_SLIDERIGHT);
-}
-
-void camera_spin_around_cw( EKeystate s );
-
-void agent_turn_left( EKeystate s )
-{
-	//in free camera control mode we need to intercept keyboard events for avatar movements
-	if (LLFloaterCamera::inFreeCameraMode())
-	{
-		camera_spin_around_cw(s);
-		return;
-	}
-
-	if(gAgent.isMovementLocked()) return;
-
-	if (LLToolCamera::getInstance()->mouseSteerMode())
-	{
-		agent_slide_left(s);
-	}
-	else
-	{
-		if (KEYSTATE_UP == s)
-		{
-			// Check temporary running. In case user released 'left' key with shift already released.
-			agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDELEFT);
-			return;
-		}
-		F32 time = gKeyboard->getCurKeyElapsedTime();
-		gAgent.moveYaw( LLFloaterMove::getYawRate( time ) );
-	}
-}
-
-void camera_spin_around_ccw( EKeystate s );
-
-void agent_turn_right( EKeystate s )
-{
-	//in free camera control mode we need to intercept keyboard events for avatar movements
-	if (LLFloaterCamera::inFreeCameraMode())
-	{
-		camera_spin_around_ccw(s);
-		return;
-	}
-
-	if(gAgent.isMovementLocked()) return;
-
-	if (LLToolCamera::getInstance()->mouseSteerMode())
-	{
-		agent_slide_right(s);
-	}
-	else
-	{
-		if (KEYSTATE_UP == s)
-		{
-			// Check temporary running. In case user released 'right' key with shift already released.
-			agent_check_temporary_run(LLAgent::DOUBLETAP_SLIDERIGHT);
-			return;
-		}
-		F32 time = gKeyboard->getCurKeyElapsedTime();
-		gAgent.moveYaw( -LLFloaterMove::getYawRate( time ) );
-	}
-}
-
-void agent_look_up( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgent.movePitch(-1);
-	//gAgent.rotate(-2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() );
-}
-
-
-void agent_look_down( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgent.movePitch(1);
-	//gAgent.rotate(2.f * DEG_TO_RAD, gAgent.getFrame().getLeftAxis() );
-}
-
-void agent_toggle_fly( EKeystate s )
-{
-	// Only catch the edge
-	if (KEYSTATE_DOWN == s )
-	{
-		LLAgent::toggleFlying();
-	}
-}
-
-F32 get_orbit_rate()
-{
-	F32 time = gKeyboard->getCurKeyElapsedTime();
-	if( time < NUDGE_TIME )
-	{
-		F32 rate = ORBIT_NUDGE_RATE + time * (1 - ORBIT_NUDGE_RATE)/ NUDGE_TIME;
-		//LL_INFOS() << rate << LL_ENDL;
-		return rate;
-	}
-	else
-	{
-		return 1;
-	}
-}
-
-void camera_spin_around_ccw( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
-}
-
-
-void camera_spin_around_cw( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setOrbitRightKey( get_orbit_rate() );
-}
-
-void camera_spin_around_ccw_sitting( EKeystate s )
-{
-	if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDERIGHT ) return;
-	if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning())
-	{
-		//send keystrokes, but do not change camera
-		agent_turn_right(s);
-	}
-	else
-	{
-		//change camera but do not send keystrokes
-		gAgentCamera.unlockView();
-		gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
-	}
-}
-
-
-void camera_spin_around_cw_sitting( EKeystate s )
-{
-	if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_SLIDELEFT ) return;
-	if (gAgent.rotateGrabbed() || gAgentCamera.sitCameraEnabled() || gAgent.getRunning())
-	{
-		//send keystrokes, but do not change camera
-		agent_turn_left(s);
-	}
-	else
-	{
-		//change camera but do not send keystrokes
-		gAgentCamera.unlockView();
-		gAgentCamera.setOrbitRightKey( get_orbit_rate() );
-	}
-}
-
-
-void camera_spin_over( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setOrbitUpKey( get_orbit_rate() );
-}
-
-
-void camera_spin_under( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setOrbitDownKey( get_orbit_rate() );
-}
-
-void camera_spin_over_sitting( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	if (gAgent.upGrabbed() || gAgentCamera.sitCameraEnabled())
-	{
-		//send keystrokes, but do not change camera
-		agent_jump(s);
-	}
-	else
-	{
-		//change camera but do not send keystrokes
-		gAgentCamera.setOrbitUpKey( get_orbit_rate() );
-	}
-}
-
-
-void camera_spin_under_sitting( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	if (gAgent.downGrabbed() || gAgentCamera.sitCameraEnabled())
-	{
-		//send keystrokes, but do not change camera
-		agent_push_down(s);
-	}
-	else
-	{
-		//change camera but do not send keystrokes
-		gAgentCamera.setOrbitDownKey( get_orbit_rate() );
-	}
-}
-
-void camera_move_forward( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setOrbitInKey( get_orbit_rate() );
-}
-
-
-void camera_move_backward( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setOrbitOutKey( get_orbit_rate() );
-}
-
-void camera_move_forward_sitting( EKeystate s )
-{
-	if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_FORWARD ) return;
-	if (gAgent.forwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun()))
-	{
-		agent_push_forward(s);
-	}
-	else
-	{
-		gAgentCamera.setOrbitInKey( get_orbit_rate() );
-	}
-}
-
-
-void camera_move_backward_sitting( EKeystate s )
-{
-	if( KEYSTATE_UP == s && gAgent.mDoubleTapRunMode != LLAgent::DOUBLETAP_BACKWARD ) return;
-
-	if (gAgent.backwardGrabbed() || gAgentCamera.sitCameraEnabled() || (gAgent.getRunning() && !gAgent.getAlwaysRun()))
-	{
-		agent_push_backward(s);
-	}
-	else
-	{
-		gAgentCamera.setOrbitOutKey( get_orbit_rate() );
-	}
-}
-
-void camera_pan_up( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setPanUpKey( get_orbit_rate() );
-}
-
-void camera_pan_down( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setPanDownKey( get_orbit_rate() );
-}
-
-void camera_pan_left( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setPanLeftKey( get_orbit_rate() );
-}
-
-void camera_pan_right( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setPanRightKey( get_orbit_rate() );
-}
-
-void camera_pan_in( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setPanInKey( get_orbit_rate() );
-}
-
-void camera_pan_out( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setPanOutKey( get_orbit_rate() );
-}
-
-void camera_move_forward_fast( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setOrbitInKey(2.5f);
-}
-
-void camera_move_backward_fast( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gAgentCamera.unlockView();
-	gAgentCamera.setOrbitOutKey(2.5f);
-}
-
-
-void edit_avatar_spin_ccw( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gMorphView->setCameraDrivenByKeys( TRUE );
-	gAgentCamera.setOrbitLeftKey( get_orbit_rate() );
-	//gMorphView->orbitLeft( get_orbit_rate() );
-}
-
-
-void edit_avatar_spin_cw( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gMorphView->setCameraDrivenByKeys( TRUE );
-	gAgentCamera.setOrbitRightKey( get_orbit_rate() );
-	//gMorphView->orbitRight( get_orbit_rate() );
-}
-
-void edit_avatar_spin_over( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gMorphView->setCameraDrivenByKeys( TRUE );
-	gAgentCamera.setOrbitUpKey( get_orbit_rate() );
-	//gMorphView->orbitUp( get_orbit_rate() );
-}
-
-
-void edit_avatar_spin_under( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gMorphView->setCameraDrivenByKeys( TRUE );
-	gAgentCamera.setOrbitDownKey( get_orbit_rate() );
-	//gMorphView->orbitDown( get_orbit_rate() );
-}
-
-void edit_avatar_move_forward( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gMorphView->setCameraDrivenByKeys( TRUE );
-	gAgentCamera.setOrbitInKey( get_orbit_rate() );
-	//gMorphView->orbitIn();
-}
-
-
-void edit_avatar_move_backward( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	gMorphView->setCameraDrivenByKeys( TRUE );
-	gAgentCamera.setOrbitOutKey( get_orbit_rate() );
-	//gMorphView->orbitOut();
-}
-
-void stop_moving( EKeystate s )
-{
-	if( KEYSTATE_UP == s  ) return;
-	// stop agent
-	gAgent.setControlFlags(AGENT_CONTROL_STOP);
-
-	// cancel autopilot
-	gAgent.stopAutoPilot();
-}
-
-void start_chat( EKeystate s )
-{
-    if (LLAppViewer::instance()->quitRequested())
-    {
-        return; // can't talk, gotta go, kthxbye!
-    }
-    
-	// start chat
-	LLFloaterIMNearbyChat::startChat(NULL);
-}
-
-void start_gesture( EKeystate s )
-{
-	LLUICtrl* focus_ctrlp = dynamic_cast<LLUICtrl*>(gFocusMgr.getKeyboardFocus());
-	if (KEYSTATE_UP == s &&
-		! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))
-	{
- 		if ((LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->getCurrentChat().empty())
- 		{
- 			// No existing chat in chat editor, insert '/'
- 			LLFloaterIMNearbyChat::startChat("/");
- 		}
- 		else
- 		{
- 			// Don't overwrite existing text in chat editor
- 			LLFloaterIMNearbyChat::startChat(NULL);
- 		}
-	}
-}
-
-#define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION);
-REGISTER_KEYBOARD_ACTION("jump", agent_jump);
-REGISTER_KEYBOARD_ACTION("push_down", agent_push_down);
-REGISTER_KEYBOARD_ACTION("push_forward", agent_push_forward);
-REGISTER_KEYBOARD_ACTION("push_backward", agent_push_backward);
-REGISTER_KEYBOARD_ACTION("look_up", agent_look_up);
-REGISTER_KEYBOARD_ACTION("look_down", agent_look_down);
-REGISTER_KEYBOARD_ACTION("toggle_fly", agent_toggle_fly);
-REGISTER_KEYBOARD_ACTION("turn_left", agent_turn_left);
-REGISTER_KEYBOARD_ACTION("turn_right", agent_turn_right);
-REGISTER_KEYBOARD_ACTION("slide_left", agent_slide_left);
-REGISTER_KEYBOARD_ACTION("slide_right", agent_slide_right);
-REGISTER_KEYBOARD_ACTION("spin_around_ccw", camera_spin_around_ccw);
-REGISTER_KEYBOARD_ACTION("spin_around_cw", camera_spin_around_cw);
-REGISTER_KEYBOARD_ACTION("spin_around_ccw_sitting", camera_spin_around_ccw_sitting);
-REGISTER_KEYBOARD_ACTION("spin_around_cw_sitting", camera_spin_around_cw_sitting);
-REGISTER_KEYBOARD_ACTION("spin_over", camera_spin_over);
-REGISTER_KEYBOARD_ACTION("spin_under", camera_spin_under);
-REGISTER_KEYBOARD_ACTION("spin_over_sitting", camera_spin_over_sitting);
-REGISTER_KEYBOARD_ACTION("spin_under_sitting", camera_spin_under_sitting);
-REGISTER_KEYBOARD_ACTION("move_forward", camera_move_forward);
-REGISTER_KEYBOARD_ACTION("move_backward", camera_move_backward);
-REGISTER_KEYBOARD_ACTION("move_forward_sitting", camera_move_forward_sitting);
-REGISTER_KEYBOARD_ACTION("move_backward_sitting", camera_move_backward_sitting);
-REGISTER_KEYBOARD_ACTION("pan_up", camera_pan_up);
-REGISTER_KEYBOARD_ACTION("pan_down", camera_pan_down);
-REGISTER_KEYBOARD_ACTION("pan_left", camera_pan_left);
-REGISTER_KEYBOARD_ACTION("pan_right", camera_pan_right);
-REGISTER_KEYBOARD_ACTION("pan_in", camera_pan_in);
-REGISTER_KEYBOARD_ACTION("pan_out", camera_pan_out);
-REGISTER_KEYBOARD_ACTION("move_forward_fast", camera_move_forward_fast);
-REGISTER_KEYBOARD_ACTION("move_backward_fast", camera_move_backward_fast);
-REGISTER_KEYBOARD_ACTION("edit_avatar_spin_ccw", edit_avatar_spin_ccw);
-REGISTER_KEYBOARD_ACTION("edit_avatar_spin_cw", edit_avatar_spin_cw);
-REGISTER_KEYBOARD_ACTION("edit_avatar_spin_over", edit_avatar_spin_over);
-REGISTER_KEYBOARD_ACTION("edit_avatar_spin_under", edit_avatar_spin_under);
-REGISTER_KEYBOARD_ACTION("edit_avatar_move_forward", edit_avatar_move_forward);
-REGISTER_KEYBOARD_ACTION("edit_avatar_move_backward", edit_avatar_move_backward);
-REGISTER_KEYBOARD_ACTION("stop_moving", stop_moving);
-REGISTER_KEYBOARD_ACTION("start_chat", start_chat);
-REGISTER_KEYBOARD_ACTION("start_gesture", start_gesture);
-#undef REGISTER_KEYBOARD_ACTION
-
-LLViewerKeyboard::LLViewerKeyboard()
-{
-	for (S32 i = 0; i < MODE_COUNT; i++)
-	{
-		mBindingCount[i] = 0;
-	}
-
-	for (S32 i = 0; i < KEY_COUNT; i++)
-	{
-		mKeyHandledByUI[i] = FALSE;
-	}
-	// we want the UI to never see these keys so that they can always control the avatar/camera
-	for(KEY k = KEY_PAD_UP; k <= KEY_PAD_DIVIDE; k++) 
-	{
-		mKeysSkippedByUI.insert(k);	
-	}
-}
-
-BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode)
-{
-	if (string == "FIRST_PERSON")
-	{
-		*mode = MODE_FIRST_PERSON;
-		return TRUE;
-	}
-	else if (string == "THIRD_PERSON")
-	{
-		*mode = MODE_THIRD_PERSON;
-		return TRUE;
-	}
-	else if (string == "EDIT")
-	{
-		*mode = MODE_EDIT;
-		return TRUE;
-	}
-	else if (string == "EDIT_AVATAR")
-	{
-		*mode = MODE_EDIT_AVATAR;
-		return TRUE;
-	}
-	else if (string == "SITTING")
-	{
-		*mode = MODE_SITTING;
-		return TRUE;
-	}
-	else
-	{
-		*mode = MODE_THIRD_PERSON;
-		return FALSE;
-	}
-}
-
-BOOL LLViewerKeyboard::handleKey(KEY translated_key,  MASK translated_mask, BOOL repeated)
-{
-	// check for re-map
-	EKeyboardMode mode = gViewerKeyboard.getMode();
-	U32 keyidx = (translated_mask<<16) | translated_key;
-	key_remap_t::iterator iter = mRemapKeys[mode].find(keyidx);
-	if (iter != mRemapKeys[mode].end())
-	{
-		translated_key = (iter->second) & 0xff;
-		translated_mask = (iter->second)>>16;
-	}
-
-	// No repeats of F-keys
-	BOOL repeatable_key = (translated_key < KEY_F1 || translated_key > KEY_F12);
-	if (!repeatable_key && repeated)
-	{
-		return FALSE;
-	}
-
-	LL_DEBUGS("UserInput") << "keydown -" << translated_key << "-" << LL_ENDL;
-	// skip skipped keys
-	if(mKeysSkippedByUI.find(translated_key) != mKeysSkippedByUI.end()) 
-	{
-		mKeyHandledByUI[translated_key] = FALSE;
-		LL_INFOS("KeyboardHandling") << "Key wasn't handled by UI!" << LL_ENDL;
-	}
-	else
-	{
-		// it is sufficient to set this value once per call to handlekey
-		// without clearing it, as it is only used in the subsequent call to scanKey
-		mKeyHandledByUI[translated_key] = gViewerWindow->handleKey(translated_key, translated_mask); 
-		// mKeyHandledByUI is not what you think ... this indicates whether the UI has handled this keypress yet (any keypress)
-		// NOT whether some UI shortcut wishes to handle the keypress
-	  
-	}
-	return mKeyHandledByUI[translated_key];
-}
-
-BOOL LLViewerKeyboard::handleKeyUp(KEY translated_key, MASK translated_mask)
-{
-	return gViewerWindow->handleKeyUp(translated_key, translated_mask);
-}
-
-BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name)
-{
-	S32 index;
-	typedef boost::function<void(EKeystate)> function_t;
-	function_t function = NULL;
-	std::string name;
-
-	// Allow remapping of F2-F12
-	if (function_name[0] == 'F')
-	{
-		int c1 = function_name[1] - '0';
-		int c2 = function_name[2] ? function_name[2] - '0' : -1;
-		if (c1 >= 0 && c1 <= 9 && c2 >= -1 && c2 <= 9)
-		{
-			int idx = c1;
-			if (c2 >= 0)
-				idx = idx*10 + c2;
-			if (idx >=2 && idx <= 12)
-			{
-				U32 keyidx = ((mask<<16)|key);
-				(mRemapKeys[mode])[keyidx] = ((0<<16)|(KEY_F1+(idx-1)));
-				return TRUE;
-			}
-		}
-	}
-
-	// Not remapped, look for a function
-	
-	function_t* result = LLKeyboardActionRegistry::getValue(function_name);
-	if (result)
-	{
-		function = *result;
-	}
-
-	if (!function)
-	{
-		LL_ERRS() << "Can't bind key to function " << function_name << ", no function with this name found" << LL_ENDL;
-		return FALSE;
-	}
-
-	// check for duplicate first and overwrite
-	for (index = 0; index < mBindingCount[mode]; index++)
-	{
-		if (key == mBindings[mode][index].mKey && mask == mBindings[mode][index].mMask)
-			break;
-	}
-
-	if (index >= MAX_KEY_BINDINGS)
-	{
-		LL_ERRS() << "LLKeyboard::bindKey() - too many keys for mode " << mode << LL_ENDL;
-		return FALSE;
-	}
-
-	if (mode >= MODE_COUNT)
-	{
-		LL_ERRS() << "LLKeyboard::bindKey() - unknown mode passed" << mode << LL_ENDL;
-		return FALSE;
-	}
-
-	mBindings[mode][index].mKey = key;
-	mBindings[mode][index].mMask = mask;
-	mBindings[mode][index].mFunction = function;
-
-	if (index == mBindingCount[mode])
-		mBindingCount[mode]++;
-
-	return TRUE;
-}
-
-LLViewerKeyboard::KeyBinding::KeyBinding()
-:	key("key"),
-	mask("mask"),
-	command("command")
-{}
-
-LLViewerKeyboard::KeyMode::KeyMode(EKeyboardMode _mode)
-:	bindings("binding"),
-	mode(_mode)
-{}
-
-LLViewerKeyboard::Keys::Keys()
-:	first_person("first_person", KeyMode(MODE_FIRST_PERSON)),
-	third_person("third_person", KeyMode(MODE_THIRD_PERSON)),
-	edit("edit", KeyMode(MODE_EDIT)),
-	sitting("sitting", KeyMode(MODE_SITTING)),
-	edit_avatar("edit_avatar", KeyMode(MODE_EDIT_AVATAR))
-{}
-
-S32 LLViewerKeyboard::loadBindingsXML(const std::string& filename)
-{
-	S32 binding_count = 0;
-	Keys keys;
-	LLSimpleXUIParser parser;
-
-	if (parser.readXUI(filename, keys) 
-		&& keys.validateBlock())
-	{
-		binding_count += loadBindingMode(keys.first_person);
-		binding_count += loadBindingMode(keys.third_person);
-		binding_count += loadBindingMode(keys.edit);
-		binding_count += loadBindingMode(keys.sitting);
-		binding_count += loadBindingMode(keys.edit_avatar);
-	}
-	return binding_count;
-}
-
-S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode)
-{
-	S32 binding_count = 0;
-	for (LLInitParam::ParamIterator<KeyBinding>::const_iterator it = keymode.bindings.begin(), 
-			end_it = keymode.bindings.end();
-		it != end_it;
-		++it)
-	{
-		KEY key;
-		MASK mask;
-		LLKeyboard::keyFromString(it->key, &key);
-		LLKeyboard::maskFromString(it->mask, &mask);
-		bindKey(keymode.mode, key, mask, it->command);
-		binding_count++;
-	}
-
-	return binding_count;
-}
-
-S32 LLViewerKeyboard::loadBindings(const std::string& filename)
-{
-	LLFILE *fp;
-	const S32 BUFFER_SIZE = 2048;
-	char buffer[BUFFER_SIZE];	/* Flawfinder: ignore */
-	// *NOTE: This buffer size is hard coded into scanf() below.
-	char mode_string[MAX_STRING] = "";	/* Flawfinder: ignore */
-	char key_string[MAX_STRING] = "";	/* Flawfinder: ignore */
-	char mask_string[MAX_STRING] = "";	/* Flawfinder: ignore */
-	char function_string[MAX_STRING] = "";	/* Flawfinder: ignore */
-	S32 mode = MODE_THIRD_PERSON;
-	KEY key = 0;
-	MASK mask = 0;
-	S32 tokens_read;
-	S32 binding_count = 0;
-	S32 line_count = 0;
-
-	if(filename.empty())
-	{
-		LL_ERRS() << " No filename specified" << LL_ENDL;
-		return 0;
-	}
-
-	fp = LLFile::fopen(filename, "r");
-
-	if (!fp)
-	{
-		return 0;
-	}
-
-
-	while (!feof(fp))
-	{
-		line_count++;
-		if (!fgets(buffer, BUFFER_SIZE, fp))
-			break;
-
-		// skip over comments, blank lines
-		if (buffer[0] == '#' || buffer[0] == '\n') continue;
-
-		// grab the binding strings
-		tokens_read = sscanf(	/* Flawfinder: ignore */
-			buffer,
-			"%254s %254s %254s %254s",
-			mode_string,
-			key_string,
-			mask_string,
-			function_string);
-
-		if (tokens_read == EOF)
-		{
-			LL_INFOS() << "Unexpected end-of-file at line " << line_count << " of key binding file " << filename << LL_ENDL;
-			fclose(fp);
-			return 0;
-		}
-		else if (tokens_read < 4)
-		{
-			LL_INFOS() << "Can't read line " << line_count << " of key binding file " << filename << LL_ENDL;
-			continue;
-		}
-
-		// convert mode
-		if (!modeFromString(mode_string, &mode))
-		{
-			LL_INFOS() << "Unknown mode on line " << line_count << " of key binding file " << filename << LL_ENDL;
-			LL_INFOS() << "Mode must be one of FIRST_PERSON, THIRD_PERSON, EDIT, EDIT_AVATAR" << LL_ENDL;
-			continue;
-		}
-
-		// convert key
-		if (!LLKeyboard::keyFromString(key_string, &key))
-		{
-			LL_INFOS() << "Can't interpret key on line " << line_count << " of key binding file " << filename << LL_ENDL;
-			continue;
-		}
-
-		// convert mask
-		if (!LLKeyboard::maskFromString(mask_string, &mask))
-		{
-			LL_INFOS() << "Can't interpret mask on line " << line_count << " of key binding file " << filename << LL_ENDL;
-			continue;
-		}
-
-		// bind key
-		if (bindKey(mode, key, mask, function_string))
-		{
-			binding_count++;
-		}
-	}
-
-	fclose(fp);
-
-	return binding_count;
-}
-
-
-EKeyboardMode LLViewerKeyboard::getMode()
-{
-	if ( gAgentCamera.cameraMouselook() )
-	{
-		return MODE_FIRST_PERSON;
-	}
-	else if ( gMorphView && gMorphView->getVisible())
-	{
-		return MODE_EDIT_AVATAR;
-	}
-	else if (isAgentAvatarValid() && gAgentAvatarp->isSitting())
-	{
-		return MODE_SITTING;
-	}
-	else
-	{
-		return MODE_THIRD_PERSON;
-	}
-}
-
-
-// Called from scanKeyboard.
-void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
-{
-	if (LLApp::isExiting())
-	{
-		return;
-	}
-
-	S32 mode = getMode();
-	// Consider keyboard scanning as NOT mouse event. JC
-	MASK mask = gKeyboard->currentMask(FALSE);
-
-	LLKeyBinding* binding = mBindings[mode];
-	S32 binding_count = mBindingCount[mode];
-
-
-	if (mKeyHandledByUI[key])
-	{
-		return;
-	}
-
-	// don't process key down on repeated keys
-	BOOL repeat = gKeyboard->getKeyRepeated(key);
-
-	for (S32 i = 0; i < binding_count; i++)
-	{
-		//for (S32 key = 0; key < KEY_COUNT; key++)
-		if (binding[i].mKey == key)
-		{
-			//if (binding[i].mKey == key && binding[i].mMask == mask)
-			if (binding[i].mMask == mask)
-			{
-				if (key_down && !repeat)
-				{
-					// ...key went down this frame, call function
-					binding[i].mFunction( KEYSTATE_DOWN );
-				}
-				else if (key_up)
-				{
-					// ...key went down this frame, call function
-					binding[i].mFunction( KEYSTATE_UP );
-				}
-				else if (key_level)
-				{
-					// ...key held down from previous frame
-					// Not windows, just call the function.
-					binding[i].mFunction( KEYSTATE_LEVEL );
-				}//if
-			}//if
-		}//for
-	}//for
-}
diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h
deleted file mode 100644
index 110dc89d2895bfb14fe33cd89c8f0233924bf521..0000000000000000000000000000000000000000
--- a/indra/newview/llviewerkeyboard.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/** 
- * @file llviewerkeyboard.h
- * @brief LLViewerKeyboard class header file
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLVIEWERKEYBOARD_H
-#define LL_LLVIEWERKEYBOARD_H
-
-#include "llkeyboard.h" // For EKeystate
-#include "llinitparam.h"
-
-const S32 MAX_NAMED_FUNCTIONS = 100;
-const S32 MAX_KEY_BINDINGS = 128; // was 60
-
-class LLNamedFunction
-{
-public:
-	LLNamedFunction() : mFunction(NULL) { };
-	~LLNamedFunction() { };
-
-	std::string	mName;
-	LLKeyFunc	mFunction;
-};
-
-typedef enum e_keyboard_mode
-{
-	MODE_FIRST_PERSON,
-	MODE_THIRD_PERSON,
-	MODE_EDIT,
-	MODE_EDIT_AVATAR,
-	MODE_SITTING,
-	MODE_COUNT
-} EKeyboardMode;
-
-
-void bind_keyboard_functions();
-
-class LLViewerKeyboard
-{
-public:
-	struct KeyBinding : public LLInitParam::Block<KeyBinding>
-	{
-		Mandatory<std::string>	key,
-								mask,
-								command;
-
-		KeyBinding();
-	};
-
-	struct KeyMode : public LLInitParam::Block<KeyMode>
-	{
-		Multiple<KeyBinding>		bindings;
-		EKeyboardMode				mode;
-		KeyMode(EKeyboardMode mode);
-	};
-
-	struct Keys : public LLInitParam::Block<Keys>
-	{
-		Optional<KeyMode>	first_person,
-							third_person,
-							edit,
-							sitting,
-							edit_avatar;
-
-		Keys();
-	};
-
-	LLViewerKeyboard();
-
-	BOOL			handleKey(KEY key, MASK mask, BOOL repeated);
-	BOOL			handleKeyUp(KEY key, MASK mask);
-
-	S32				loadBindings(const std::string& filename);										// returns number bound, 0 on error
-	S32				loadBindingsXML(const std::string& filename);										// returns number bound, 0 on error
-	EKeyboardMode	getMode();
-
-	BOOL			modeFromString(const std::string& string, S32 *mode);			// False on failure
-
-	void			scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level);
-
-private:
-	S32				loadBindingMode(const LLViewerKeyboard::KeyMode& keymode);
-	BOOL			bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name);
-
-	// Hold all the ugly stuff torn out to make LLKeyboard non-viewer-specific here
-	S32				mBindingCount[MODE_COUNT];
-	LLKeyBinding	mBindings[MODE_COUNT][MAX_KEY_BINDINGS];
-
-	typedef std::map<U32, U32> key_remap_t;
-	key_remap_t		mRemapKeys[MODE_COUNT];
-	std::set<KEY>	mKeysSkippedByUI;
-	BOOL			mKeyHandledByUI[KEY_COUNT];		// key processed successfully by UI
-};
-
-extern LLViewerKeyboard gViewerKeyboard;
-
-#endif // LL_LLVIEWERKEYBOARD_H
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index f49af5b091a0d186e9a891d99da667d373056804..25580681d49fd475f1cc6a3cb023e6a9a81f21b1 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -67,6 +67,7 @@
 #include "llfloaterimcontainer.h"
 #include "llfloaterland.h"
 #include "llfloaterimnearbychat.h"
+#include "llfloaterlandholdings.h"
 #include "llfloaterpathfindingcharacters.h"
 #include "llfloaterpathfindinglinksets.h"
 #include "llfloaterpay.h"
@@ -193,11 +194,15 @@ const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents"
 LLMenuGL* gAttachSubMenu = NULL;
 LLMenuGL* gDetachSubMenu = NULL;
 LLMenuGL* gTakeOffClothes = NULL;
+LLMenuGL* gDetachAvatarMenu = NULL;
+LLMenuGL* gDetachHUDAvatarMenu = NULL;
 LLContextMenu* gAttachScreenPieMenu = NULL;
 LLContextMenu* gAttachPieMenu = NULL;
 LLContextMenu* gAttachBodyPartPieMenus[9];
 LLContextMenu* gDetachPieMenu = NULL;
 LLContextMenu* gDetachScreenPieMenu = NULL;
+LLContextMenu* gDetachAttSelfMenu = NULL;
+LLContextMenu* gDetachHUDAttSelfMenu = NULL;
 LLContextMenu* gDetachBodyPartPieMenus[9];
 
 //
@@ -452,6 +457,9 @@ void init_menus()
 	gMenuAttachmentOther = LLUICtrlFactory::createFromFile<LLContextMenu>(
 		"menu_attachment_other.xml", gMenuHolder, registry);
 
+	gDetachHUDAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self HUD", true);
+	gDetachAttSelfMenu = gMenuHolder->getChild<LLContextMenu>("Detach Self", true);
+
 	gMenuLand = LLUICtrlFactory::createFromFile<LLContextMenu>(
 		"menu_land.xml", gMenuHolder, registry);
 
@@ -508,6 +516,9 @@ void init_menus()
 	gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);
 	gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE);
 
+	gDetachAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach", true);
+	gDetachHUDAvatarMenu = gMenuHolder->getChild<LLMenuGL>("Avatar Detach HUD", true);
+
 	// Don't display the Memory console menu if the feature is turned off
 	LLMenuItemCheckGL *memoryMenu = gMenuBarView->getChild<LLMenuItemCheckGL>("Memory", TRUE);
 	if (memoryMenu)
@@ -684,19 +695,6 @@ class LLAdvancedCheckHUDInfo : public view_listener_t
 };
 
 
-//////////////
-// FLYING   //
-//////////////
-
-class LLAdvancedAgentFlyingInfo : public view_listener_t
-{
-	bool handleEvent(const LLSD&)
-	{
-		return gAgent.getFlying();
-	}
-};
-
-
 ///////////////////////
 // CLEAR GROUP CACHE //
 ///////////////////////
@@ -3201,20 +3199,11 @@ class LLAvatarCheckImpostorMode : public view_listener_t
 		switch (mode) 
 		{
 			case 0:
-// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
-				return LLRenderMuteList::instance().getSavedVisualMuteSetting(avatar->getID()) == LLVOAvatar::AV_RENDER_NORMALLY;
-// [/RLVa:KB]
-//				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY);
+				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_RENDER_NORMALLY);
 			case 1:
-// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
-				return LLRenderMuteList::instance().getSavedVisualMuteSetting(avatar->getID()) == LLVOAvatar::AV_DO_NOT_RENDER;
-// [/RLVa:KB]
-//				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
+				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_DO_NOT_RENDER);
 			case 2:
-// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
-				return LLRenderMuteList::instance().getSavedVisualMuteSetting(avatar->getID()) == LLVOAvatar::AV_ALWAYS_RENDER;
-// [/RLVa:KB]
-//				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
+				return (avatar->getVisualMuteSettings() == LLVOAvatar::AV_ALWAYS_RENDER);
 			default:
 				return false;
 		}
@@ -3268,6 +3257,7 @@ class LLObjectMute : public view_listener_t
 		if (avatar)
 		{
 			avatar->mNeedsImpostorUpdate = TRUE;
+			avatar->mLastImpostorUpdateReason = 9;
 
 			id = avatar->getID();
 // [RLVa:KB] - Checked: RLVa-1.0.0
@@ -3850,6 +3840,35 @@ bool enable_sitdown_self()
 //	return show_sitdown_self() && !gAgentAvatarp->isEditingAppearance() && !gAgent.getFlying();
 }
 
+class LLSelfToggleSitStand : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		if (isAgentAvatarValid())
+		{
+			if (gAgentAvatarp->isSitting())
+			{
+				gAgent.standUp();
+			}
+			else
+			{
+				gAgent.sitDown();
+			}
+		}
+		return true;
+	}
+};
+
+bool enable_sit_stand()
+{
+	return enable_sitdown_self() || enable_standup_self();
+}
+
+bool enable_fly_land()
+{
+	return gAgent.getFlying() || LLAgent::enableFlying();
+}
+
 class LLCheckPanelPeopleTab : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -4797,6 +4816,18 @@ void handle_take_copy()
 	derez_objects(DRD_ACQUIRE_TO_AGENT_INVENTORY, category_id);
 }
 
+void handle_link_objects()
+{
+	if (LLSelectMgr::getInstance()->getSelection()->isEmpty())
+	{
+		LLFloaterReg::toggleInstanceOrBringToFront("places");
+	}
+	else
+	{
+		LLSelectMgr::getInstance()->linkObjects();
+	}
+}
+
 // You can return an object to its owner if it is on your land.
 class LLObjectReturn : public view_listener_t
 {
@@ -5108,7 +5139,7 @@ void handle_buy_or_take()
 		{
 			LLStringUtil::format_map_t args;
 			args["AMOUNT"] = llformat("%d", total_price);
-			LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "BuyingCosts", args ), total_price );
+			LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString( "this_object_costs", args ), total_price );
 		}
 	}
 	else
@@ -5137,13 +5168,6 @@ bool tools_visible_take_object()
 	return !is_selection_buy_not_take();
 }
 
-bool enable_how_to_visible(const LLSD& param)
-{
-	LLFloaterWebContent::Params p;
-	p.target = "__help_how_to";
-	return LLFloaterReg::instanceVisible("how_to", p);
-}
-
 class LLToolsEnableBuyOrTake : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -5575,7 +5599,7 @@ class LLToolsSelectNextPartFace : public view_listener_t
                         new_te = to_select->getNumTEs() - 1;
                     }
                 }
-                LLSelectMgr::getInstance()->addAsIndividual(to_select, new_te, FALSE);
+                LLSelectMgr::getInstance()->selectObjectOnly(to_select, new_te);
             }
             else
             {
@@ -6117,6 +6141,16 @@ class LLWorldSetHomeLocation : public view_listener_t
 	}
 };
 
+class LLWorldLindenHome : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		std::string url = LLFloaterLandHoldings::sHasLindenHome ? LLTrans::getString("lindenhomes_my_home_url") : LLTrans::getString("lindenhomes_get_home_url");
+		LLWeb::loadURL(url);
+		return true;
+	}
+};
+
 class LLWorldTeleportHome : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -6204,7 +6238,7 @@ class LLWorldCreateLandmark : public view_listener_t
 			return true;
 // [/RLVa:KB]
 
-		LLFloaterSidePanelContainer::showPanel("places", LLSD().with("type", "create_landmark"));
+		LLFloaterReg::showInstance("add_landmark");
 
 		return true;
 	}
@@ -6582,6 +6616,11 @@ void handle_edit_outfit()
 	LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
 }
 
+void handle_now_wearing()
+{
+    LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "now_wearing"));
+}
+
 void handle_edit_shape()
 {
 	LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_shape"));
@@ -8119,15 +8158,7 @@ class LLToggleHowTo : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		LLFloaterWebContent::Params p;
-		std::string url = gSavedSettings.getString("HowToHelpURL");
-		p.url = LLWeb::expandURLSubstitutions(url, LLSD());
-		p.show_chrome = false;
-		p.target = "__help_how_to";
-		p.show_page_title = false;
-		p.preferred_media_size = LLRect(0, 460, 335, 0);
-
-		LLFloaterReg::toggleInstanceOrBringToFront("how_to", p);
+		LLFloaterReg::toggleInstanceOrBringToFront("guidebook");
 		return true;
 	}
 };
@@ -8506,7 +8537,6 @@ BOOL LLViewerMenuHolderGL::hideMenus()
 	
 	if (LLMenuHolderGL::hideMenus())
 	{
-		LLToolPie::instance().blockClickToWalk();
 		handled = TRUE;
 	}
 
@@ -9044,37 +9074,32 @@ class LLWorldEnvSettings : public view_listener_t
 		
 		if (event_name == "sunrise")
 		{
-            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNRISE);
-            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
-            LLEnvironment::instance().updateEnvironment();
+            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNRISE, LLEnvironment::TRANSITION_INSTANT);
+            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
             defocusEnvFloaters();
 		}
 		else if (event_name == "noon")
 		{
-            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY);
-            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
-            LLEnvironment::instance().updateEnvironment();
+            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDDAY, LLEnvironment::TRANSITION_INSTANT);
+            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
             defocusEnvFloaters();
 		}
 		else if (event_name == "sunset")
 		{
-            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET);
-            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
-            LLEnvironment::instance().updateEnvironment();
+            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET, LLEnvironment::TRANSITION_INSTANT);
+            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
             defocusEnvFloaters();
 		}
 		else if (event_name == "midnight")
 		{
-            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT);
-            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
-            LLEnvironment::instance().updateEnvironment();
+            LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_MIDNIGHT, LLEnvironment::TRANSITION_INSTANT);
+            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
             defocusEnvFloaters();
 		}
         else if (event_name == "region")
 		{
             LLEnvironment::instance().clearEnvironment(LLEnvironment::ENV_LOCAL);
-            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL);
-            LLEnvironment::instance().updateEnvironment();
+            LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT);
             defocusEnvFloaters();
 		}
         else if (event_name == "pause_clouds")
@@ -9245,6 +9270,17 @@ class LLUploadCostCalculator : public view_listener_t
 	}
 };
 
+class LLUpdateMembershipLabel : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		const std::string label_str =  LLAgentBenefitsMgr::isCurrent("Base") ? LLTrans::getString("MembershipUpgradeText") : LLTrans::getString("MembershipPremiumText");
+		gMenuHolder->childSetLabelArg("Membership", "[Membership]", label_str);
+
+		return true;
+	}
+};
+
 void handle_voice_morphing_subscribe()
 {
 	LLWeb::loadURL(LLTrans::getString("voice_morphing_url"));
@@ -9397,11 +9433,13 @@ void initialize_menus()
 
 	view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
 
+	view_listener_t::addEnable(new LLUpdateMembershipLabel(), "Membership.UpdateLabel");
+
 	enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed));
 
 	// Agent
 	commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying));
-	enable.add("Agent.enableFlying", boost::bind(&LLAgent::enableFlying));
+	enable.add("Agent.enableFlyLand", boost::bind(&enable_fly_land));
 	commit.add("Agent.PressMicrophone", boost::bind(&LLAgent::pressMicrophone, _2));
 	commit.add("Agent.ReleaseMicrophone", boost::bind(&LLAgent::releaseMicrophone, _2));
 	commit.add("Agent.ToggleMicrophone", boost::bind(&LLAgent::toggleMicrophone, _2));
@@ -9417,6 +9455,7 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLEnableHoverHeight(), "Edit.EnableHoverHeight");
 	view_listener_t::addMenu(new LLEnableEditPhysics(), "Edit.EnableEditPhysics");
 	commit.add("CustomizeAvatar", boost::bind(&handle_customize_avatar));
+    commit.add("NowWearing", boost::bind(&handle_now_wearing));
 	commit.add("EditOutfit", boost::bind(&handle_edit_outfit));
 	commit.add("EditShape", boost::bind(&handle_edit_shape));
 	commit.add("HoverHeight", boost::bind(&handle_hover_height));
@@ -9449,9 +9488,6 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb");
 	view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
 	
-	// Me > Movement
-	view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
-
 	//Communicate Nearby chat
 	view_listener_t::addMenu(new LLCommunicateNearbyChat(), "Communicate.NearbyChat");
 
@@ -9473,6 +9509,7 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome");
 	view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway");
 	view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb");
+	view_listener_t::addMenu(new LLWorldLindenHome(), "World.LindenHome");
 
 	view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark");
 // [RLVa:KB]
@@ -9501,7 +9538,7 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLToolsSnapObjectXY(), "Tools.SnapObjectXY");
 	view_listener_t::addMenu(new LLToolsUseSelectionForGrid(), "Tools.UseSelectionForGrid");
 	view_listener_t::addMenu(new LLToolsSelectNextPartFace(), "Tools.SelectNextPart");
-	commit.add("Tools.Link", boost::bind(&LLSelectMgr::linkObjects, LLSelectMgr::getInstance()));
+	commit.add("Tools.Link", boost::bind(&handle_link_objects));
 	commit.add("Tools.Unlink", boost::bind(&LLSelectMgr::unlinkObjects, LLSelectMgr::getInstance()));
 	view_listener_t::addMenu(new LLToolsStopAllAnimations(), "Tools.StopAllAnimations");
 	view_listener_t::addMenu(new LLToolsReleaseKeys(), "Tools.ReleaseKeys");
@@ -9530,7 +9567,6 @@ void initialize_menus()
 	// Help menu
 	// most items use the ShowFloater method
 	view_listener_t::addMenu(new LLToggleHowTo(), "Help.ToggleHowTo");
-	enable.add("Help.HowToVisible", boost::bind(&enable_how_to_visible, _2));
 
 	// Advanced menu
 	view_listener_t::addMenu(new LLAdvancedToggleConsole(), "Advanced.ToggleConsole");
@@ -9721,11 +9757,8 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLAdminOnSaveState(), "Admin.OnSaveState");
 
 	// Self context menu
-	view_listener_t::addMenu(new LLSelfStandUp(), "Self.StandUp");
-	enable.add("Self.EnableStandUp", boost::bind(&enable_standup_self));
-	view_listener_t::addMenu(new LLSelfSitDown(), "Self.SitDown");
-	enable.add("Self.EnableSitDown", boost::bind(&enable_sitdown_self)); 
-	enable.add("Self.ShowSitDown", boost::bind(&show_sitdown_self));
+	view_listener_t::addMenu(new LLSelfToggleSitStand(), "Self.ToggleSitStand");
+	enable.add("Self.EnableSitStand", boost::bind(&enable_sit_stand));
 	view_listener_t::addMenu(new LLSelfRemoveAllAttachments(), "Self.RemoveAllAttachments");
 
 	view_listener_t::addMenu(new LLSelfEnableRemoveAllAttachments(), "Self.EnableRemoveAllAttachments");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 7a37c7efbd1c928d12667b417750ed6562d2bcf9..272a1f3990ef0ad5a2c595b626338ff5de9ccff8 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -192,10 +192,14 @@ extern LLContextMenu		*gMenuMuteParticle;
 extern LLMenuGL* gAttachSubMenu;
 extern LLMenuGL* gDetachSubMenu;
 extern LLMenuGL* gTakeOffClothes;
+extern LLMenuGL* gDetachAvatarMenu;
+extern LLMenuGL* gDetachHUDAvatarMenu;
 extern LLContextMenu* gAttachScreenPieMenu;
 extern LLContextMenu* gDetachScreenPieMenu;
+extern LLContextMenu* gDetachHUDAttSelfMenu;
 extern LLContextMenu* gAttachPieMenu;
 extern LLContextMenu* gDetachPieMenu;
+extern LLContextMenu* gDetachAttSelfMenu;
 extern LLContextMenu* gAttachBodyPartPieMenus[9];
 extern LLContextMenu* gDetachBodyPartPieMenus[9];
 
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 4b231c70671bc5e5224ba1d52800944ae58f5c7b..15181dcd9f7635f8163cf4f865d47b370a9c3e5a 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -830,10 +830,7 @@ void upload_done_callback(
 				
 				if(!(can_afford_transaction(expected_upload_cost)))
 				{
-					LLStringUtil::format_map_t args;
-					args["NAME"] = data->mAssetInfo.getName();
-					args["AMOUNT"] = llformat("%d", expected_upload_cost);
-					LLBuyCurrencyHTML::openCurrencyFloater( LLTrans::getString("UploadingCosts", args), expected_upload_cost );
+					LLBuyCurrencyHTML::openCurrencyFloater( "", expected_upload_cost );
 					is_balance_sufficient = FALSE;
 				}
 				else if(region)
@@ -967,10 +964,7 @@ void upload_new_resource(
 			if (balance < uploadInfo->getExpectedUploadCost())
 			{
 				// insufficient funds, bail on this upload
-				LLStringUtil::format_map_t args;
-				args["NAME"] = uploadInfo->getName();
-                args["AMOUNT"] = llformat("%d", uploadInfo->getExpectedUploadCost());
-                LLBuyCurrencyHTML::openCurrencyFloater(LLTrans::getString("UploadingCosts", args), uploadInfo->getExpectedUploadCost());
+                LLBuyCurrencyHTML::openCurrencyFloater("", uploadInfo->getExpectedUploadCost());
 				return;
 			}
 		}
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 08169961a55b43939d2a4768ec40203212292f23..891dd92b54987fcb73e43412a4d5dc5093b71300 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -122,7 +122,6 @@
 #include "rlvui.h"
 // [/RLVa:KB]
 
-#include <boost/algorithm/string/split.hpp> //
 #include <boost/foreach.hpp>
 
 #include "llnotificationmanager.h" //
@@ -795,7 +794,6 @@ void response_group_invitation_coro(std::string url, LLUUID group_id, bool notif
             LL_DEBUGS("GroupInvite") << "Successfully sent response to group " << group_id << " invitation" << LL_ENDL;
             if (notify_and_update)
             {
-                LLNotificationsUtil::add("JoinGroupSuccess");
                 gAgent.sendAgentDataUpdateRequest();
 
                 LLGroupMgr::getInstance()->clearGroupData(group_id);
@@ -5345,6 +5343,15 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
 		// notification was specified using the new mechanism, so we can just handle it here
 		std::string notificationID;
 		msgsystem->getStringFast(_PREHASH_AlertInfo, _PREHASH_Message, notificationID);
+
+		//SL-13824 skip notification when both joining a group and leaving a group
+		//remove this after server stops sending these messages  
+		if (notificationID == "JoinGroupSuccess" ||
+			notificationID == "GroupDepart")
+		{
+			return true;
+		}
+
 		if (!LLNotifications::getInstance()->templateExists(notificationID))
 		{
 			return false;
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index a593905060bec4c166f7637c005dc8e39b04848f..be05ac0d3af041c3797a193879aa6aef24b04f5d 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -130,7 +130,7 @@ void LLGridManager::initialize(const std::string& grid_file)
 				  "https://secondlife.aditi.lindenlab.com/helpers/",
 				  DEFAULT_LOGIN_PAGE,
 				  SL_UPDATE_QUERY_URL,
-				  "https://my.aditi.lindenlab.com/",
+				  "https://my.secondlife-beta.com/",
 				  "Aditi");
 
 	LLSD other_grids;
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index b161c6fc3699874abe23cbe1fff2a1e290d521ad..e723d9cbc94aba2d37e7bc7b35023067bc1da694 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -1715,9 +1715,6 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
 			// Let interesting parties know about agent parcel change.
 			LLViewerParcelMgr* instance = LLViewerParcelMgr::getInstance();
 
-			// Notify anything that wants to know when the agent changes parcels
-			gAgent.changeParcels();
-
 			if (instance->mTeleportInProgress)
 			{
 				instance->mTeleportInProgress = FALSE;
@@ -1733,6 +1730,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
 			}
             parcel->setParcelEnvironmentVersion(parcel_environment_version);
             LL_DEBUGS("ENVIRONMENT") << "Parcel environment version is " << parcel->getParcelEnvironmentVersion() << LL_ENDL;
+
             // Notify anything that wants to know when the agent changes parcels
             gAgent.changeParcels();
             instance->mTeleportInProgress = FALSE;
diff --git a/indra/newview/llviewerpartsource.cpp b/indra/newview/llviewerpartsource.cpp
index 998ae52fe0b9687c757d38ab7c05f2c35ea72632..f042040e98a58cf19ccb334da10428b31c8a4615 100644
--- a/indra/newview/llviewerpartsource.cpp
+++ b/indra/newview/llviewerpartsource.cpp
@@ -136,7 +136,7 @@ void LLViewerPartSourceScript::update(const F32 dt)
 	{
 		mOwnerAvatarp = find_avatar(mOwnerUUID);
 	}
-	if (mOwnerAvatarp.notNull() && LLVOAvatar::AV_DO_NOT_RENDER == mOwnerAvatarp->getVisualMuteSettings())
+	if (mOwnerAvatarp.notNull() && LLVOAvatar::AOA_NORMAL != mOwnerAvatarp->getOverallAppearance())
 	{
 		return;
 	}
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 05f88b0a75f42ec1ed0b604e11761cd1b952cca9..314c1a1f1eca236ed7ec069cd1a49b41ff55ea73 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -63,6 +63,7 @@
 #include "llsdutil.h"
 #include "llcorehttputil.h"
 #include "llvoicevivox.h"
+#include "lluiusage.h"
 
 namespace LLStatViewer
 {
@@ -577,6 +578,8 @@ void send_viewer_stats(bool include_preferences)
 	fail["invalid"] = (S32) gMessageSystem->mInvalidOnCircuitPackets;
 	fail["missing_updater"] = (S32) LLAppViewer::instance()->isUpdaterMissing();
 
+	body["ui"] = LLUIUsage::instance().asLLSD();
+		
 	body["stats"]["voice"] = LLVoiceVivoxStats::getInstance()->read();
 
 	// Misc stats, two strings and two ints
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index d6574fdf011db4b1c0b5d3c9bc614e14feffec0f..25fdf694c3ca1ebf49fbbf1ad1503af2926afbe1 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -3317,13 +3317,6 @@ void LLViewerLODTexture::processTextureStats()
 	{
 		mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, (S8)mDesiredSavedRawDiscardLevel);
 	}
-	else if(LLPipeline::sMemAllocationThrottled)//release memory of large textures by decrease their resolutions.
-	{
-		if(scaleDown())
-		{
-			mDesiredDiscardLevel = mCachedRawDiscardLevel;
-		}
-	}
 }
 
 bool LLViewerLODTexture::scaleDown()
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 9ab3eb90afe09290b1b16f752145e75dbfc9fb98..f1c34be6adcde7662c4470911a2c6457877cb3f8 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -45,7 +45,8 @@
 #include "llmeshrepository.h"
 #include "llnotificationhandler.h"
 #include "llpanellogin.h"
-#include "llviewerkeyboard.h"
+#include "llsetkeybinddialog.h"
+#include "llviewerinput.h"
 #include "llviewermenu.h"
 
 #include "llviewquery.h"
@@ -173,7 +174,7 @@
 #include "llviewergesture.h"
 #include "llviewertexturelist.h"
 #include "llviewerinventory.h"
-#include "llviewerkeyboard.h"
+#include "llviewerinput.h"
 #include "llviewermedia.h"
 #include "llviewermediafocus.h"
 #include "llviewermenu.h"
@@ -317,6 +318,99 @@ RecordToChatConsole::RecordToChatConsole():
     mRecorder->showMultiline(true);
 }
 
+////////////////////////////////////////////////////////////////////////////
+//
+// Print Utility
+//
+
+// Convert a normalized float (-1.0 <= x <= +1.0) to a fixed 1.4 format string:
+//
+//    s#.####
+//
+// Where:
+//    s  sign character; space if x is positiv, minus if negative
+//    #  decimal digits
+//
+// This is similar to printf("%+.4f") except positive numbers are NOT cluttered with a leading '+' sign.
+// NOTE: This does NOT null terminate the output
+void normalized_float_to_string(const float x, char *out_str)
+{
+    static const unsigned char DECIMAL_BCD2[] =
+    {
+        0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09,
+        0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19,
+        0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29,
+        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
+        0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
+        0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
+        0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
+        0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
+        0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
+        0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99
+    };
+
+    int neg = (x < 0);
+    int rem = neg
+            ? (int)(x * -10000.)
+            : (int)(x *  10000.);
+
+    int d10 = rem % 100; rem /= 100;
+    int d32 = rem % 100; rem /= 100;
+
+    out_str[6] = '0' + ((DECIMAL_BCD2[ d10 ] >> 0) & 0xF);
+    out_str[5] = '0' + ((DECIMAL_BCD2[ d10 ] >> 4) & 0xF);
+    out_str[4] = '0' + ((DECIMAL_BCD2[ d32 ] >> 0) & 0xF);
+    out_str[3] = '0' + ((DECIMAL_BCD2[ d32 ] >> 4) & 0xF);
+    out_str[2] = '.';
+    out_str[1] = '0' + (rem & 1);
+    out_str[0] = " -"[neg]; // Could always show '+' for positive but this clutters up the common case
+}
+
+// normalized float
+//    printf("%-.4f    %-.4f    %-.4f")
+// Params:
+//   float  &matrix_row[4]
+//   int    matrix_cell_index
+//   string out_buffer (size 32)
+// Note: The buffer is assumed to be pre-filled with spaces
+#define MATRIX_ROW_N32_TO_STR(matrix_row, i, out_buffer)          \
+    normalized_float_to_string(matrix_row[i+0], out_buffer +  0); \
+    normalized_float_to_string(matrix_row[i+1], out_buffer + 11); \
+    normalized_float_to_string(matrix_row[i+2], out_buffer + 22); \
+    out_buffer[31] = 0;
+
+
+// regular float
+//    sprintf(buffer, "%-8.2f  %-8.2f  %-8.2f", matrix_row[i+0], matrix_row[i+1], matrix_row[i+2]);
+// Params:
+//   float  &matrix_row[4]
+//   int    matrix_cell_index
+//   char   out_buffer[32]
+// Note: The buffer is assumed to be pre-filled with spaces
+#define MATRIX_ROW_F32_TO_STR(matrix_row, i, out_buffer) {                       \
+    static const char *format[3] = {                                             \
+        "%-8.2f"  ,  /* 0 */                                                     \
+        ">  99K  ",  /* 1 */                                                     \
+        "< -99K  "   /* 2 */                                                     \
+    };                                                                           \
+                                                                                 \
+    F32 temp_0 = matrix_row[i+0];                                                \
+    F32 temp_1 = matrix_row[i+1];                                                \
+    F32 temp_2 = matrix_row[i+2];                                                \
+                                                                                 \
+    U8 flag_0 = (((U8)(temp_0 < -99999.99)) << 1) | ((U8)(temp_0 > 99999.99));   \
+    U8 flag_1 = (((U8)(temp_1 < -99999.99)) << 1) | ((U8)(temp_1 > 99999.99));   \
+    U8 flag_2 = (((U8)(temp_2 < -99999.99)) << 1) | ((U8)(temp_2 > 99999.99));   \
+                                                                                 \
+    if (temp_0 < 0.f) out_buffer[ 0] = '-';                                      \
+    if (temp_1 < 0.f) out_buffer[11] = '-';                                      \
+    if (temp_2 < 0.f) out_buffer[22] = '-';                                      \
+                                                                                 \
+    sprintf(out_buffer+ 1,format[flag_0],fabsf(temp_0)); out_buffer[ 1+8] = ' '; \
+    sprintf(out_buffer+12,format[flag_1],fabsf(temp_1)); out_buffer[12+8] = ' '; \
+    sprintf(out_buffer+23,format[flag_2],fabsf(temp_2)); out_buffer[23+8] =  0 ; \
+}
+
 ////////////////////////////////////////////////////////////////////////////
 //
 // LLDebugText
@@ -339,7 +433,11 @@ class LLDebugText
 	typedef std::vector<Line> line_list_t;
 	line_list_t mLineList;
 	LLColor4 mTextColor;
-	
+
+	LLColor4 mBackColor;
+	LLRect mBackRectCamera1;
+	LLRect mBackRectCamera2;
+
 	void addText(S32 x, S32 y, const std::string &text) 
 	{
 		mLineList.push_back(Line(text, x, y));
@@ -381,11 +479,22 @@ class LLDebugText
 		mTextColor = LLColor4( 0.86f, 0.86f, 0.86f, 1.f );
 
 		// Draw stuff growing up from right lower corner of screen
-		S32 xpos = mWindow->getWorldViewWidthScaled() - 400;
+		S32 x_right = mWindow->getWorldViewWidthScaled();
+		S32 xpos = x_right - 400;
 		xpos = llmax(xpos, 0);
 		S32 ypos = 64;
 		const S32 y_inc = 20;
 
+		// Camera matrix text is hard to see again a white background
+		// Add a dark background underneath the matrices for readability (contrast)
+		mBackRectCamera1.mLeft   = xpos;
+		mBackRectCamera1.mRight  = x_right;
+		mBackRectCamera1.mTop    = -1;
+		mBackRectCamera1.mBottom = -1;
+		mBackRectCamera2 = mBackRectCamera1;
+
+		mBackColor = LLUIColorTable::instance().getColor( "MenuDefaultBgColor" );
+
 		clearText();
 		
 		if (gSavedSettings.getBOOL("DebugShowTime"))
@@ -730,48 +839,45 @@ class LLDebugText
 		}
 		if (gSavedSettings.getBOOL("DebugShowRenderMatrices"))
 		{
-			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLProjection[12], gGLProjection[13], gGLProjection[14], gGLProjection[15]));
-			ypos += y_inc;
+			char camera_lines[8][32];
+			memset(camera_lines, ' ', sizeof(camera_lines));
 
-			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLProjection[8], gGLProjection[9], gGLProjection[10], gGLProjection[11]));
-			ypos += y_inc;
-
-			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLProjection[4], gGLProjection[5], gGLProjection[6], gGLProjection[7]));
-			ypos += y_inc;
-
-			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLProjection[0], gGLProjection[1], gGLProjection[2], gGLProjection[3]));
-			ypos += y_inc;
+			// Projection last column is always <0,0,-1.0001,0>
+			// Projection last row is always <0,0,-0.2>
+			mBackRectCamera1.mBottom = ypos - y_inc + 2;
+			MATRIX_ROW_N32_TO_STR(gGLProjection, 12,camera_lines[7]); addText(xpos, ypos, std::string(camera_lines[7])); ypos += y_inc;
+			MATRIX_ROW_N32_TO_STR(gGLProjection,  8,camera_lines[6]); addText(xpos, ypos, std::string(camera_lines[6])); ypos += y_inc;
+			MATRIX_ROW_N32_TO_STR(gGLProjection,  4,camera_lines[5]); addText(xpos, ypos, std::string(camera_lines[5])); ypos += y_inc; mBackRectCamera1.mTop    = ypos + 2;
+			MATRIX_ROW_N32_TO_STR(gGLProjection,  0,camera_lines[4]); addText(xpos, ypos, std::string(camera_lines[4])); ypos += y_inc; mBackRectCamera2.mBottom = ypos + 2;
 
 			addText(xpos, ypos, "Projection Matrix");
 			ypos += y_inc;
 
-
-			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLModelView[12], gGLModelView[13], gGLModelView[14], gGLModelView[15]));
-			ypos += y_inc;
-
-			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLModelView[8], gGLModelView[9], gGLModelView[10], gGLModelView[11]));
-			ypos += y_inc;
-
-			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLModelView[4], gGLModelView[5], gGLModelView[6], gGLModelView[7]));
-			ypos += y_inc;
-
-			addText(xpos, ypos, llformat("%.4f    .%4f    %.4f    %.4f", gGLModelView[0], gGLModelView[1], gGLModelView[2], gGLModelView[3]));
-			ypos += y_inc;
+			// View last column is always <0,0,0,1>
+			MATRIX_ROW_F32_TO_STR(gGLModelView, 12,camera_lines[3]); addText(xpos, ypos, std::string(camera_lines[3])); ypos += y_inc;
+			MATRIX_ROW_N32_TO_STR(gGLModelView,  8,camera_lines[2]); addText(xpos, ypos, std::string(camera_lines[2])); ypos += y_inc;
+			MATRIX_ROW_N32_TO_STR(gGLModelView,  4,camera_lines[1]); addText(xpos, ypos, std::string(camera_lines[1])); ypos += y_inc; mBackRectCamera2.mTop = ypos + 2;
+			MATRIX_ROW_N32_TO_STR(gGLModelView,  0,camera_lines[0]); addText(xpos, ypos, std::string(camera_lines[0])); ypos += y_inc;
 
 			addText(xpos, ypos, "View Matrix");
 			ypos += y_inc;
 		}
 		// disable use of glReadPixels which messes up nVidia nSight graphics debugging
-		if (gSavedSettings.getBOOL("DebugShowColor") && !LLRender::sNsightDebugSupport)
-		{
-			U8 color[4];
-			LLCoordGL coord = gViewerWindow->getCurrentMouse();
-			glReadPixels(coord.mX, coord.mY, 1,1,GL_RGBA, GL_UNSIGNED_BYTE, color);
-			addText(xpos, ypos, llformat("%d %d %d %d", color[0], color[1], color[2], color[3]));
-			ypos += y_inc;
-		}
+        if (gSavedSettings.getBOOL("DebugShowColor") && !LLRender::sNsightDebugSupport)
+        {
+            U8 color[4];
+            LLCoordGL coord = gViewerWindow->getCurrentMouse();
 
-		// only display these messages if we are actually rendering beacons at this moment
+            // Convert x,y to raw pixel coords
+            S32 x_raw = llround(coord.mX * gViewerWindow->getWindowWidthRaw() / (F32) gViewerWindow->getWindowWidthScaled());
+            S32 y_raw = llround(coord.mY * gViewerWindow->getWindowHeightRaw() / (F32) gViewerWindow->getWindowHeightScaled());
+            
+            glReadPixels(x_raw, y_raw, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
+            addText(xpos, ypos, llformat("Pixel <%1d, %1d> R:%1d G:%1d B:%1d A:%1d", x_raw, y_raw, color[0], color[1], color[2], color[3]));
+            ypos += y_inc;
+        }
+
+        // only display these messages if we are actually rendering beacons at this moment
 		if (LLPipeline::getRenderBeacons() && LLFloaterReg::instanceVisible("beacons"))
 		{
 			if (LLPipeline::getRenderMOAPBeacons())
@@ -898,6 +1004,18 @@ class LLDebugText
 	void draw()
 	{
 		LL_RECORD_BLOCK_TIME(FTM_DISPLAY_DEBUG_TEXT);
+
+		// Camera matrix text is hard to see again a white background
+		// Add a dark background underneath the matrices for readability (contrast)
+		if (mBackRectCamera1.mTop >= 0)
+		{
+			mBackColor.setAlpha( 0.75f );
+			gl_rect_2d(mBackRectCamera1, mBackColor, true);
+
+			mBackColor.setAlpha( 0.66f );
+			gl_rect_2d(mBackRectCamera2, mBackColor, true);
+		}
+
 		for (line_list_t::iterator iter = mLineList.begin();
 			 iter != mLineList.end(); ++iter)
 		{
@@ -906,7 +1024,6 @@ class LLDebugText
 											 LLFontGL::LEFT, LLFontGL::TOP,
 											 LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE);
 		}
-		mLineList.clear();
 	}
 
 };
@@ -935,7 +1052,18 @@ LLViewerWindow::Params::Params()
 {}
 
 
-BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window,  LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down)
+void LLViewerWindow::handlePieMenu(S32 x, S32 y, MASK mask)
+{
+    if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() && gAgent.isInitialized())
+    {
+        // If the current tool didn't process the click, we should show
+        // the pie menu.  This can be done by passing the event to the pie
+        // menu tool.
+        LLToolPie::getInstance()->handleRightMouseDown(x, y, mask);
+    }
+}
+
+BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down)
 {
 	const char* buttonname = "";
 	const char* buttonstatestr = "";
@@ -959,28 +1087,30 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window,  LLCoordGL pos, MASK
 		
 		switch (clicktype)
 		{
-		case LLMouseHandler::CLICK_LEFT:
+		case CLICK_LEFT:
 			mLeftMouseDown = down;
 			buttonname = "Left";
 			break;
-		case LLMouseHandler::CLICK_RIGHT:
+		case CLICK_RIGHT:
 			mRightMouseDown = down;
 			buttonname = "Right";
 			break;
-		case LLMouseHandler::CLICK_MIDDLE:
+		case CLICK_MIDDLE:
 			mMiddleMouseDown = down;
 			buttonname = "Middle";
 			break;
-		case LLMouseHandler::CLICK_DOUBLELEFT:
+		case CLICK_DOUBLELEFT:
 			mLeftMouseDown = down;
 			buttonname = "Left Double Click";
 			break;
-		case LLMouseHandler::CLICK_BUTTON4:
+		case CLICK_BUTTON4:
 			buttonname = "Button 4";
 			break;
-		case LLMouseHandler::CLICK_BUTTON5:
+		case CLICK_BUTTON5:
 			buttonname = "Button 5";
 			break;
+		default:
+			break; // COUNT and NONE
 		}
 		
 		LLView::sMouseHandlerMessage.clear();
@@ -1031,6 +1161,11 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window,  LLCoordGL pos, MASK
 				LLViewerEventRecorder::instance().logMouseEvent(std::string(buttonstatestr),std::string(buttonname)); 
 
 			}
+			else if (down && clicktype == CLICK_RIGHT)
+			{
+				handlePieMenu(x, y, mask);
+				r = TRUE;
+			}
 			return r;
 		}
 
@@ -1077,7 +1212,12 @@ BOOL LLViewerWindow::handleAnyMouseClick(LLWindow *window,  LLCoordGL pos, MASK
 		return TRUE;
 	}
 
-	
+	if (down && clicktype == CLICK_RIGHT)
+	{
+		handlePieMenu(x, y, mask);
+		return TRUE;
+	}
+
 	// If we got this far on a down-click, it wasn't handled.
 	// Up-clicks, though, are always handled as far as the OS is concerned.
 	BOOL default_rtn = !down;
@@ -1096,7 +1236,8 @@ BOOL LLViewerWindow::handleMouseDown(LLWindow *window,  LLCoordGL pos, MASK mask
         mMouseDownTimer.reset();
     }    
     BOOL down = TRUE;
-	return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
+    //handleMouse() loops back to LLViewerWindow::handleAnyMouseClick
+    return gViewerInput.handleMouse(window, pos, mask, CLICK_LEFT, down);
 }
 
 BOOL LLViewerWindow::handleDoubleClick(LLWindow *window,  LLCoordGL pos, MASK mask)
@@ -1104,8 +1245,7 @@ BOOL LLViewerWindow::handleDoubleClick(LLWindow *window,  LLCoordGL pos, MASK ma
 	// try handling as a double-click first, then a single-click if that
 	// wasn't handled.
 	BOOL down = TRUE;
-	if (handleAnyMouseClick(window, pos, mask,
-				LLMouseHandler::CLICK_DOUBLELEFT, down))
+	if (gViewerInput.handleMouse(window, pos, mask, CLICK_DOUBLELEFT, down))
 	{
 		return TRUE;
 	}
@@ -1119,47 +1259,24 @@ BOOL LLViewerWindow::handleMouseUp(LLWindow *window,  LLCoordGL pos, MASK mask)
         mMouseDownTimer.stop();
     }
     BOOL down = FALSE;
-	return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_LEFT,down);
+    return gViewerInput.handleMouse(window, pos, mask, CLICK_LEFT, down);
 }
-
-
 BOOL LLViewerWindow::handleRightMouseDown(LLWindow *window,  LLCoordGL pos, MASK mask)
 {
-	S32 x = pos.mX;
-	S32 y = pos.mY;
-	x = ll_round((F32)x / mDisplayScale.mV[VX]);
-	y = ll_round((F32)y / mDisplayScale.mV[VY]);
-
 	BOOL down = TRUE;
-	BOOL handle = handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down);
-	if (handle)
-		return handle;
-
-	// *HACK: this should be rolled into the composite tool logic, not
-	// hardcoded at the top level.
-	if (CAMERA_MODE_CUSTOMIZE_AVATAR != gAgentCamera.getCameraMode() && LLToolMgr::getInstance()->getCurrentTool() != LLToolPie::getInstance() && gAgent.isInitialized())
-	{
-		// If the current tool didn't process the click, we should show
-		// the pie menu.  This can be done by passing the event to the pie
-		// menu tool.
-		LLToolPie::getInstance()->handleRightMouseDown(x, y, mask);
-		// show_context_menu( x, y, mask );
-	}
-
-	return TRUE;
+	return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down);
 }
 
 BOOL LLViewerWindow::handleRightMouseUp(LLWindow *window,  LLCoordGL pos, MASK mask)
 {
 	BOOL down = FALSE;
- 	return handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_RIGHT,down);
+ 	return gViewerInput.handleMouse(window, pos, mask, CLICK_RIGHT, down);
 }
 
 BOOL LLViewerWindow::handleMiddleMouseDown(LLWindow *window,  LLCoordGL pos, MASK mask)
 {
 	BOOL down = TRUE;
-	LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, true);
- 	handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
+ 	gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down);
   
   	// Always handled as far as the OS is concerned.
 	return TRUE;
@@ -1314,8 +1431,7 @@ LLWindowCallbacks::DragNDropResult LLViewerWindow::handleDragNDrop( LLWindow *wi
 BOOL LLViewerWindow::handleMiddleMouseUp(LLWindow *window,  LLCoordGL pos, MASK mask)
 {
 	BOOL down = FALSE;
-	LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_MIDDLE, false);
- 	handleAnyMouseClick(window,pos,mask,LLMouseHandler::CLICK_MIDDLE,down);
+ 	gViewerInput.handleMouse(window, pos, mask, CLICK_MIDDLE, down);
   
   	// Always handled as far as the OS is concerned.
 	return TRUE;
@@ -1326,12 +1442,10 @@ BOOL LLViewerWindow::handleOtherMouse(LLWindow *window, LLCoordGL pos, MASK mask
     switch (button)
     {
     case 4:
-        LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON4, down);
-        handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON4, down);
+        gViewerInput.handleMouse(window, pos, mask, CLICK_BUTTON4, down);
         break;
     case 5:
-        LLVoiceClient::getInstance()->updateMouseState(LLMouseHandler::CLICK_BUTTON5, down);
-        handleAnyMouseClick(window, pos, mask, LLMouseHandler::CLICK_BUTTON5, down);
+        gViewerInput.handleMouse(window, pos, mask, CLICK_BUTTON5, down);
         break;
     default:
         break;
@@ -1478,9 +1592,6 @@ void LLViewerWindow::handleFocusLost(LLWindow *window)
 
 BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key,  MASK mask, BOOL repeated)
 {
-	// Let the voice chat code check for its PTT key.  Note that this never affects event processing.
-	LLVoiceClient::getInstance()->keyDown(key, mask);
-
 	if (gAwayTimer.getElapsedTimeF32() > LLAgent::MIN_AFK_TIME)
 	{
 		gAgent.clearAFK();
@@ -1499,14 +1610,12 @@ BOOL LLViewerWindow::handleTranslatedKeyDown(KEY key,  MASK mask, BOOL repeated)
     		return FALSE;
 	}
 
-	return gViewerKeyboard.handleKey(key, mask, repeated);
+    // remaps, handles ignored cases and returns back to viewer window.
+    return gViewerInput.handleKey(key, mask, repeated);
 }
 
 BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key,  MASK mask)
 {
-	// Let the voice chat code check for its PTT key.  Note that this never affects event processing.
-	LLVoiceClient::getInstance()->keyUp(key, mask);
-
 	// Let the inspect tool code check for ALT key to set LLToolSelectRect active instead LLToolCamera
 	LLToolCompInspect * tool_inspectp = LLToolCompInspect::getInstance();
 	if (LLToolMgr::getInstance()->getCurrentTool() == tool_inspectp)
@@ -1514,13 +1623,13 @@ BOOL LLViewerWindow::handleTranslatedKeyUp(KEY key,  MASK mask)
 		tool_inspectp->keyUp(key, mask);
 	}
 
-	return gViewerKeyboard.handleKeyUp(key, mask);
+	return gViewerInput.handleKeyUp(key, mask);
 }
 
 void LLViewerWindow::handleScanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level)
 {
 	LLViewerJoystick::getInstance()->setCameraNeedsUpdate(true);
-	gViewerKeyboard.scanKey(key, key_down, key_up, key_level);
+	gViewerInput.scanKey(key, key_down, key_up, key_level);
 	return; // Be clear this function returns nothing
 }
 
@@ -1822,8 +1931,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 		ms_sleep(5000) ; //wait for 5 seconds.
 
 		LLSplashScreen::update(LLTrans::getString("ShuttingDown"));
-#if LL_LINUX || LL_SOLARIS
-		LL_WARNS() << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly.  See README-linux.txt or README-solaris.txt for further information."
+#if LL_LINUX
+		LL_WARNS() << "Unable to create window, be sure screen is set at 32-bit color and your graphics driver is configured correctly.  See README-linux.txt for further information."
 				<< LL_ENDL;
 #else
 		LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
@@ -2338,7 +2447,6 @@ void LLViewerWindow::shutdownGL()
 LLViewerWindow::~LLViewerWindow()
 {
 	LL_INFOS() << "Destroying Window" << LL_ENDL;
-	gDebugWindowProc = TRUE; // event catching, disable once we figure out cause for exit crashes
 	destroyWindow();
 
 	delete mDebugText;
@@ -2429,6 +2537,11 @@ void LLViewerWindow::reshape(S32 width, S32 height)
 		// round up when converting coordinates to make sure there are no gaps at edge of window
 		LLView::sForceReshape = display_scale_changed;
 		mRootView->reshape(llceil((F32)width / mDisplayScale.mV[VX]), llceil((F32)height / mDisplayScale.mV[VY]));
+        if (display_scale_changed)
+        {
+            // Needs only a 'scale change' update, everything else gets handled by LLLayoutStack::updateClass()
+            LLPanelLogin::reshapePanel();
+        }
 		LLView::sForceReshape = FALSE;
 
 		// clear font width caches
@@ -2717,6 +2830,13 @@ void LLViewerWindow::draw()
 // Takes a single keyup event, usually when UI is visible
 BOOL LLViewerWindow::handleKeyUp(KEY key, MASK mask)
 {
+    if (LLSetKeyBindDialog::recordKey(key, mask, FALSE))
+    {
+        LL_DEBUGS() << "KeyUp handled by LLSetKeyBindDialog" << LL_ENDL;
+        LLViewerEventRecorder::instance().logKeyEvent(key, mask);
+        return TRUE;
+    }
+
     LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
 
     if (keyboard_focus
@@ -2760,23 +2880,74 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	// hide tooltips on keypress
 	LLToolTipMgr::instance().blockToolTips();
 
-    LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
+    // Menus get handled on key down instead of key up
+    // so keybindings have to be recorded before that
+    if (LLSetKeyBindDialog::recordKey(key, mask, TRUE))
+    {
+        LL_DEBUGS() << "Key handled by LLSetKeyBindDialog" << LL_ENDL;
+        LLViewerEventRecorder::instance().logKeyEvent(key,mask);
+        return TRUE;
+    }
 
+    LLFocusableElement* keyboard_focus = gFocusMgr.getKeyboardFocus();
+    
     if (keyboard_focus
-		&& !(mask & (MASK_CONTROL | MASK_ALT))
-		&& !gFocusMgr.getKeystrokesOnly())
-	{
-		// We have keyboard focus, and it's not an accelerator
-        if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown())
+        && !gFocusMgr.getKeystrokesOnly())
+    {
+#ifdef LL_WINDOWS
+        // On windows Alt Gr key generates additional Ctrl event, as result handling situations
+        // like 'AltGr + D' will result in 'Alt+Ctrl+D'. If it results in WM_CHAR, don't let it
+        // pass into menu or it will trigger 'develop' menu assigned to this combination on top
+        // of character handling.
+        // Alt Gr can be additionally modified by Shift
+        const MASK alt_gr = MASK_CONTROL | MASK_ALT;
+        if ((mask & alt_gr) != 0
+            && key >= 0x30
+            && key <= 0x5A
+            && (GetKeyState(VK_RMENU) & 0x8000) != 0
+            && (GetKeyState(VK_RCONTROL) & 0x8000) == 0) // ensure right control is not pressed, only left one
         {
-            return keyboard_focus->handleKey(key, mask, FALSE );
+            // Alt Gr key is represented as right alt and left control.
+            // Any alt+ctrl combination is treated as Alt Gr by TranslateMessage() and
+            // will generate a WM_CHAR message, but here we only treat virtual Alt Graph
+            // key by checking if this specific combination has unicode char.
+            //
+            // I decided to handle only virtual RAlt+LCtrl==AltGr combination to minimize
+            // impact on menu, but the right way might be to handle all Alt+Ctrl calls.
+
+            BYTE keyboard_state[256];
+            if (GetKeyboardState(keyboard_state))
+            {
+                const int char_count = 6;
+                wchar_t chars[char_count];
+                HKL layout = GetKeyboardLayout(0);
+                // ToUnicodeEx changes buffer state on OS below Win10, which is undesirable,
+                // but since we already did a TranslateMessage() in gatherInput(), this
+                // should have no negative effect
+                int res = ToUnicodeEx(key, 0, keyboard_state, chars, char_count, 1 << 2 /*do not modify buffer flag*/, layout);
+                if (res == 1 && chars[0] >= 0x20)
+                {
+                    // Let it fall through to character handler and get a WM_CHAR.
+                    return TRUE;
+                }
+            }
         }
-		else if (key < 0x80)
-		{
-			// Not a special key, so likely (we hope) to generate a character.  Let it fall through to character handler first.
-            return (keyboard_focus != NULL);
-		}
-	}
+#endif
+
+        if (!(mask & (MASK_CONTROL | MASK_ALT)))
+        {
+            // We have keyboard focus, and it's not an accelerator
+            if (keyboard_focus && keyboard_focus->wantsKeyUpKeyDown())
+            {
+                return keyboard_focus->handleKey(key, mask, FALSE);
+            }
+            else if (key < 0x80)
+            {
+                // Not a special key, so likely (we hope) to generate a character.  Let it fall through to character handler first.
+                return TRUE;
+            }
+        }
+    }
 
 	// let menus handle navigation keys for navigation
 	if ((gMenuBarView && gMenuBarView->handleKey(key, mask, TRUE))
@@ -2975,7 +3146,8 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
 	{
 		if (mask != MASK_ALT)
 		{
-			return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
+			// remaps, handles ignored cases and returns back to viewer window.
+			return gViewerInput.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
 		}
 	}
 
@@ -4718,10 +4890,6 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 		return FALSE;
 	}
 	//check if there is enough memory for the snapshot image
-	if(LLPipeline::sMemAllocationThrottled)
-	{
-		return FALSE ; //snapshot taking is disabled due to memory restriction.
-	}
 	if(image_width * image_height > (1 << 22)) //if snapshot image is larger than 2K by 2K
 	{
 		if(!LLMemory::tryToAlloc(NULL, image_width * image_height * 3))
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index e282905a1c51f488115fd4d52096f9d3b6821fa9..8a6df613dc28aa724475bdee092e1ddb3c8b3050 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -175,8 +175,9 @@ class LLViewerWindow : public LLWindowCallbacks
 	void			initWorldUI();
 	void			setUIVisibility(bool);
 	bool			getUIVisibility();
+	void			handlePieMenu(S32 x, S32 y, MASK mask);
 
-	BOOL handleAnyMouseClick(LLWindow *window,  LLCoordGL pos, MASK mask, LLMouseHandler::EClickType clicktype, BOOL down);
+	BOOL handleAnyMouseClick(LLWindow *window, LLCoordGL pos, MASK mask, EMouseClickType clicktype, BOOL down);
 
 	//
 	// LLWindowCallback interface implementation
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 5e353e6e7d7ce106fb3537464dccfd0ab0d37789..08f15a16bfe33b5274dc9d855e09c3ecad02055f 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -212,6 +212,8 @@ enum ERenderName
 	RENDER_NAME_FADE
 };
 
+#define JELLYDOLLS_SHOULD_IMPOSTOR
+
 //-----------------------------------------------------------------------------
 // Callback data
 //-----------------------------------------------------------------------------
@@ -579,7 +581,8 @@ class LLPelvisFixMotion :
 // Static Data
 //-----------------------------------------------------------------------------
 S32 LLVOAvatar::sFreezeCounter = 0;
-U32 LLVOAvatar::sMaxNonImpostors = 12; // overridden based on graphics setting
+U32 LLVOAvatar::sMaxNonImpostors = 12; // Set from RenderAvatarMaxNonImpostors
+bool LLVOAvatar::sLimitNonImpostors = false; // True unless RenderAvatarMaxNonImpostors is 0 (unlimited)
 F32 LLVOAvatar::sRenderDistance = 256.f;
 S32	LLVOAvatar::sNumVisibleAvatars = 0;
 S32	LLVOAvatar::sNumLODChangesThisFrame = 0;
@@ -606,7 +609,6 @@ BOOL LLVOAvatar::sShowFootPlane = FALSE;
 BOOL LLVOAvatar::sVisibleInFirstPerson = FALSE;
 F32 LLVOAvatar::sLODFactor = 1.f;
 F32 LLVOAvatar::sPhysicsLODFactor = 1.f;
-bool LLVOAvatar::sUseImpostors = false; // overwridden by RenderAvatarMaxNonImpostors
 BOOL LLVOAvatar::sJointDebug = FALSE;
 F32 LLVOAvatar::sUnbakedTime = 0.f;
 F32 LLVOAvatar::sUnbakedUpdateTime = 0.f;
@@ -639,6 +641,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	mMeshValid(FALSE),
 	mVisible(FALSE),
 	mLastImpostorUpdateFrameTime(0.f),
+	mLastImpostorUpdateReason(0),
 	mWindFreq(0.f),
 	mRipplePhase( 0.f ),
 	mBelowWater(FALSE),
@@ -661,6 +664,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	mNeedsSkin(FALSE),
 	mLastSkinTime(0.f),
 	mUpdatePeriod(1),
+	mOverallAppearance(AOA_INVISIBLE),
 	mVisualComplexityStale(true),
 	mVisuallyMuteSetting(AV_RENDER_NORMALLY),
 	mMutedAVColor(LLColor4::white /* used for "uninitialize" */),
@@ -705,6 +709,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	setAnimationData("Speed", &mSpeed);
 
 	mNeedsImpostorUpdate = TRUE;
+	mLastImpostorUpdateReason = 0;
 	mNeedsAnimUpdate = TRUE;
 
 	mNeedsExtentUpdate = true;
@@ -760,8 +765,8 @@ std::string LLVOAvatar::avString() const
     }
     else
     {
-	std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
-	return " Avatar '" + getFullname() + "' " + viz_string + " ";
+		std::string viz_string = LLVOAvatar::rezStatusToString(getRezzedStatus());
+		return " Avatar '" + getFullname() + "' " + viz_string + " ";
     }
 }
 
@@ -1080,6 +1085,7 @@ void LLVOAvatar::resetImpostors()
 		LLVOAvatar* avatar = (LLVOAvatar*) *iter;
 		avatar->mImpostor.release();
 		avatar->mNeedsImpostorUpdate = TRUE;
+		avatar->mLastImpostorUpdateReason = 1;
 	}
 }
 
@@ -1324,72 +1330,84 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
     LL_RECORD_BLOCK_TIME(FTM_AVATAR_EXTENT_UPDATE);
 
     S32 box_detail = gSavedSettings.getS32("AvatarBoundingBoxComplexity");
+    if (getOverallAppearance() != AOA_NORMAL)
+    {
+        if (isControlAvatar())
+        {
+            // Animated objects don't show system avatar but do need to include rigged meshes in their bounding box.
+            box_detail = 3;
+        }
+        else
+        {
+            // Jellydolled avatars ignore attachments, etc, use only system avatar.
+            box_detail = 1;
+        }
+    }
 
     // FIXME the update_min_max function used below assumes there is a
     // known starting point, but in general there isn't. Ideally the
     // box update logic should be modified to handle the no-point-yet
     // case. For most models, starting with the pelvis is safe though.
     LLVector3 zero_pos;
-	LLVector4a pos;
+    LLVector4a pos;
     if (dist_vec(zero_pos, mPelvisp->getWorldPosition())<0.001)
     {
         // Don't use pelvis until av initialized
-	pos.load3(getRenderPosition().mV);
+        pos.load3(getRenderPosition().mV);
     }
     else
     {
         pos.load3(mPelvisp->getWorldPosition().mV);
     }
-	newMin = pos;
-	newMax = pos;
+    newMin = pos;
+    newMax = pos;
 
-	//stretch bounding box by joint positions. Doing this for
-	//control avs, where the polymeshes aren't maintained or
-	//displayed, can give inaccurate boxes due to joints stuck at (0,0,0).
-    if ((box_detail>=1) && !isControlAvatar())
+    if (box_detail>=1 && !isControlAvatar())
     {
-	for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i)
-	{
-		LLPolyMesh* mesh = i->second;
-		for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.size(); joint_num++)
-		{
-			LLVector4a trans;
-			trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV);
-			update_min_max(newMin, newMax, trans);
-		}
-	}
-
+        //stretch bounding box by joint positions. Doing this for
+        //control avs, where the polymeshes aren't maintained or
+        //displayed, can give inaccurate boxes due to joints stuck at (0,0,0).
+        for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i)
+        {
+            LLPolyMesh* mesh = i->second;
+            for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.size(); joint_num++)
+            {
+                LLVector4a trans;
+                trans.load3( mesh->mJointRenderData[joint_num]->mWorldMatrix->getTranslation().mV);
+                update_min_max(newMin, newMax, trans);
+            }
+        }
     }
 
-	// Pad bounding box for starting joint, plus polymesh if
-	// applicable. Subsequent calcs should be accurate enough to not
-	// need padding.
-	LLVector4a padding(0.25);
-	newMin.sub(padding);
-	newMax.add(padding);
+    // Pad bounding box for starting joint, plus polymesh if
+    // applicable. Subsequent calcs should be accurate enough to not
+    // need padding.
+    LLVector4a padding(0.25);
+    newMin.sub(padding);
+    newMax.add(padding);
 
 
-	//stretch bounding box by static attachments
+    //stretch bounding box by static attachments
     if (box_detail >= 2)
     {
         float max_attachment_span = get_default_max_prim_scale() * 5.0f;
-	
-	for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); 
-		 iter != mAttachmentPoints.end();
-		 ++iter)
-	{
-		LLViewerJointAttachment* attachment = iter->second;
+    
+        for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); 
+             iter != mAttachmentPoints.end();
+             ++iter)
+        {
+            LLViewerJointAttachment* attachment = iter->second;
 
-		if (attachment->getValid())
-		{
-			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
-				 attachment_iter != attachment->mAttachedObjects.end();
-				 ++attachment_iter)
-			{
+            if (attachment->getValid())
+            {
+                for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+                     attachment_iter != attachment->mAttachedObjects.end();
+                     ++attachment_iter)
+                {
                     // Don't we need to look at children of attached_object as well?
-                const LLViewerObject* attached_object = attachment_iter->get();
-				if (attached_object && !attached_object->isHUDAttachment())
-				{
+                    const LLViewerObject* attached_object = attachment_iter->get();
+                    if (attached_object && !attached_object->isHUDAttachment())
+                    {
                         const LLVOVolume *vol = dynamic_cast<const LLVOVolume*>(attached_object);
                         if (vol && vol->isAnimatedObject())
                         {
@@ -1411,39 +1429,39 @@ void LLVOAvatar::calculateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
                         {
                             continue;
                         }
-					LLDrawable* drawable = attached_object->mDrawable;
-					if (drawable && !drawable->isState(LLDrawable::RIGGED))
-					{
-						LLSpatialBridge* bridge = drawable->getSpatialBridge();
-						if (bridge)
-						{
-							const LLVector4a* ext = bridge->getSpatialExtents();
-							LLVector4a distance;
-							distance.setSub(ext[1], ext[0]);
-							LLVector4a max_span(max_attachment_span);
-
-							S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7;
-						
-							// Only add the prim to spatial extents calculations if it isn't a megaprim.
-							// max_attachment_span calculated at the start of the function 
-							// (currently 5 times our max prim size) 
-							if (lt == 0x7)
-							{
-								update_min_max(newMin,newMax,ext[0]);
-								update_min_max(newMin,newMax,ext[1]);
-							}
-						}
-					}
-				}
-			}
-		}
-	}
+                        LLDrawable* drawable = attached_object->mDrawable;
+                        if (drawable && !drawable->isState(LLDrawable::RIGGED))
+                        {
+                            LLSpatialBridge* bridge = drawable->getSpatialBridge();
+                            if (bridge)
+                            {
+                                const LLVector4a* ext = bridge->getSpatialExtents();
+                                LLVector4a distance;
+                                distance.setSub(ext[1], ext[0]);
+                                LLVector4a max_span(max_attachment_span);
+
+                                S32 lt = distance.lessThan(max_span).getGatheredBits() & 0x7;
+                        
+                                // Only add the prim to spatial extents calculations if it isn't a megaprim.
+                                // max_attachment_span calculated at the start of the function 
+                                // (currently 5 times our max prim size) 
+                                if (lt == 0x7)
+                                {
+                                    update_min_max(newMin,newMax,ext[0]);
+                                    update_min_max(newMin,newMax,ext[1]);
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        }
     }
 
     // Stretch bounding box by rigged mesh joint boxes
     if (box_detail>=3)
     {
-		updateRiggingInfo();
+        updateRiggingInfo();
         for (S32 joint_num = 0; joint_num < LL_CHARACTER_MAX_ANIMATED_JOINTS; joint_num++)
         {
             LLJoint *joint = getJoint(joint_num);
@@ -2029,6 +2047,38 @@ void LLVOAvatar::resetVisualParams()
 	}
 }
 
+void LLVOAvatar::applyDefaultParams()
+{
+	// These are params from avs with newly created copies of shape,
+	// skin, hair, eyes, plus gender set as noted. Run arche_tool.py
+	// to get params from some other xml appearance dump.
+	std::map<S32, U8> male_params = {
+		{1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,255}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127}
+	};
+	std::map<S32, U8> female_params = {
+		{1,33}, {2,61}, {4,85}, {5,23}, {6,58}, {7,127}, {8,63}, {10,85}, {11,63}, {12,42}, {13,0}, {14,85}, {15,63}, {16,36}, {17,85}, {18,95}, {19,153}, {20,63}, {21,34}, {22,0}, {23,63}, {24,109}, {25,88}, {27,132}, {31,63}, {33,136}, {34,81}, {35,85}, {36,103}, {37,136}, {38,127}, {80,0}, {93,203}, {98,0}, {99,0}, {105,127}, {108,0}, {110,0}, {111,127}, {112,0}, {113,0}, {114,127}, {115,0}, {116,0}, {117,0}, {119,127}, {130,114}, {131,127}, {132,99}, {133,63}, {134,127}, {135,140}, {136,127}, {137,127}, {140,0}, {141,0}, {142,0}, {143,191}, {150,0}, {155,104}, {157,0}, {162,0}, {163,0}, {165,0}, {166,0}, {167,0}, {168,0}, {169,0}, {177,0}, {181,145}, {182,216}, {183,133}, {184,0}, {185,127}, {192,0}, {193,127}, {196,170}, {198,0}, {503,0}, {505,127}, {506,127}, {507,109}, {508,85}, {513,127}, {514,127}, {515,63}, {517,85}, {518,42}, {603,100}, {604,216}, {605,214}, {606,204}, {607,204}, {608,204}, {609,51}, {616,25}, {617,89}, {619,76}, {624,204}, {625,0}, {629,127}, {637,0}, {638,0}, {646,144}, {647,85}, {649,127}, {650,132}, {652,127}, {653,85}, {654,0}, {656,127}, {659,127}, {662,127}, {663,127}, {664,127}, {665,127}, {674,59}, {675,127}, {676,85}, {678,127}, {682,127}, {683,106}, {684,47}, {685,79}, {690,127}, {692,127}, {693,204}, {700,63}, {701,0}, {702,0}, {703,0}, {704,0}, {705,127}, {706,127}, {707,0}, {708,0}, {709,0}, {710,0}, {711,127}, {712,0}, {713,159}, {714,0}, {715,0}, {750,178}, {752,127}, {753,36}, {754,85}, {755,131}, {756,127}, {757,127}, {758,127}, {759,153}, {760,95}, {762,0}, {763,140}, {764,74}, {765,27}, {769,127}, {773,127}, {775,0}, {779,214}, {780,204}, {781,198}, {785,0}, {789,0}, {795,63}, {796,30}, {799,127}, {800,226}, {801,255}, {802,198}, {803,255}, {804,255}, {805,255}, {806,255}, {807,255}, {808,255}, {812,255}, {813,255}, {814,255}, {815,204}, {816,0}, {817,255}, {818,255}, {819,255}, {820,255}, {821,255}, {822,255}, {823,255}, {824,255}, {825,255}, {826,255}, {827,255}, {828,0}, {829,255}, {830,255}, {834,255}, {835,255}, {836,255}, {840,0}, {841,127}, {842,127}, {844,255}, {848,25}, {858,100}, {859,255}, {860,255}, {861,255}, {862,255}, {863,84}, {868,0}, {869,0}, {877,0}, {879,51}, {880,132}, {921,255}, {922,255}, {923,255}, {10000,0}, {10001,0}, {10002,25}, {10003,0}, {10004,25}, {10005,23}, {10006,51}, {10007,0}, {10008,25}, {10009,23}, {10010,51}, {10011,0}, {10012,0}, {10013,25}, {10014,0}, {10015,25}, {10016,23}, {10017,51}, {10018,0}, {10019,0}, {10020,25}, {10021,0}, {10022,25}, {10023,23}, {10024,51}, {10025,0}, {10026,25}, {10027,23}, {10028,51}, {10029,0}, {10030,25}, {10031,23}, {10032,51}, {11000,1}, {11001,127}
+	};
+	std::map<S32, U8> *params = NULL;
+	if (getSex() == SEX_MALE)
+		params = &male_params;
+	else
+		params = &female_params;
+			
+	for( auto it = params->begin(); it != params->end(); ++it)
+	{
+		LLVisualParam* param = getVisualParam(it->first);
+		if( !param )
+		{
+			// invalid id
+			break;
+		}
+
+		U8 value = it->second;
+		F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight());
+		param->setWeight(newWeight);
+	}
+}
+
 //-----------------------------------------------------------------------------
 // resetSkeleton()
 //-----------------------------------------------------------------------------
@@ -2091,15 +2141,30 @@ void LLVOAvatar::resetSkeleton(bool reset_animations)
     }
 
     // Reset tweakable params to preserved state
-    if (mLastProcessedAppearance)
-    {
-    bool slam_params = true;
-    applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params);
-    }
+	if (getOverallAppearance() == AOA_NORMAL)
+	{
+		if (mLastProcessedAppearance)
+		{
+			bool slam_params = true;
+			applyParsedAppearanceMessage(*mLastProcessedAppearance, slam_params);
+		}
+	}
+	else
+	{
+		// Stripped down approximation of
+		// applyParsedAppearanceMessage, but with alternative default
+		// (jellydoll) params
+		setCompositeUpdatesEnabled( FALSE );
+		gPipeline.markGLRebuild(this);
+		applyDefaultParams();
+		setCompositeUpdatesEnabled( TRUE );
+		updateMeshTextures();
+		updateMeshVisibility();
+	}
     updateVisualParams();
 
     // Restore attachment pos overrides
-    updateAttachmentOverrides();
+	updateAttachmentOverrides();
 
     // Animations
     if (reset_animations)
@@ -2734,7 +2799,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
 	BOOL visible = isVisible() || mNeedsAnimUpdate;
 
 	// update attachments positions
-	if (detailed_update || !sUseImpostors)
+	if (detailed_update)
 	{
 		LL_RECORD_BLOCK_TIME(FTM_ATTACHMENT_UPDATE);
 		for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); 
@@ -2794,6 +2859,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
 			if (angle_diff > F_PI/512.f*distance*mUpdatePeriod)
 			{
 				mNeedsImpostorUpdate = TRUE;
+				mLastImpostorUpdateReason = 2;
 			}
 		}
 
@@ -2805,6 +2871,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
 			if (dist_diff/mImpostorDistance > 0.1f)
 			{
 				mNeedsImpostorUpdate = TRUE;
+				mLastImpostorUpdateReason = 3;
 			}
 			else
 			{
@@ -2817,6 +2884,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
 				if (diff.getLength3().getF32() > 0.05f)
 				{
 					mNeedsImpostorUpdate = TRUE;
+					mLastImpostorUpdateReason = 4;
 				}
 				else
 				{
@@ -2824,6 +2892,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
 					if (diff.getLength3().getF32() > 0.05f)
 					{
 						mNeedsImpostorUpdate = TRUE;
+						mLastImpostorUpdateReason = 5;
 					}
 				}
 			}
@@ -2832,13 +2901,13 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
 
     if (mDrawable.notNull())
     {
-	mDrawable->movePartition();
+		mDrawable->movePartition();
 	
-	//force a move if sitting on an active object
-	if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive())
-	{
-		gPipeline.markMoved(mDrawable, TRUE);
-	}
+		//force a move if sitting on an active object
+		if (getParent() && ((LLViewerObject*) getParent())->mDrawable->isActive())
+		{
+			gPipeline.markMoved(mDrawable, TRUE);
+		}
     }
 }
 
@@ -3610,25 +3679,31 @@ bool LLVOAvatar::isVisuallyMuted()
 	// * check against the render cost and attachment limits
 	if (!isSelf())
 	{
-		if (mVisuallyMuteSetting == AV_ALWAYS_RENDER)
+// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
+		if (isRlvSilhouette())
+		{
+			muted = true;
+		}
+		else if (mVisuallyMuteSetting == AV_ALWAYS_RENDER)
+// [/RLVa:KB]
+//		if (mVisuallyMuteSetting == AV_ALWAYS_RENDER)
 		{
 			muted = false;
 		}
 		else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER)
-		{	// Always want to see this AV as an impostor
+		{
+#ifdef JELLYDOLLS_SHOULD_IMPOSTOR
 			muted = true;
+			// Always want to see this AV as an impostor
+#else
+			muted = false;
+#endif
 		}
         else if (isInMuteList())
         {
             muted = true;
         }
-// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
-		else if (isRlvSilhouette())
-		{
-			muted = true;
-		}
-// [/RLVa:KB]
-		else
+		else 
 		{
 			muted = isTooComplex();
 		}
@@ -3637,7 +3712,7 @@ bool LLVOAvatar::isVisuallyMuted()
 	return muted;
 }
 
-bool LLVOAvatar::isInMuteList()
+bool LLVOAvatar::isInMuteList() const
 {
 	bool muted = false;
 	F64 now = LLFrameTimer::getTotalSeconds();
@@ -3657,9 +3732,9 @@ bool LLVOAvatar::isInMuteList()
 }
 
 // [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
-bool LLVOAvatar::isRlvSilhouette()
+bool LLVOAvatar::isRlvSilhouette() const
 {
-	if (!gRlvHandler.hasBehaviour(RLV_BHVR_SETCAM_AVDIST))
+	if (!RlvActions::hasBehaviour(RLV_BHVR_SETCAM_AVDIST))
 		return false;
 
 	static RlvCachedBehaviourModifier<float> s_nSetCamAvDist(RLV_MODIFIER_SETCAM_AVDIST);
@@ -3667,14 +3742,14 @@ bool LLVOAvatar::isRlvSilhouette()
 	const F64 now = LLFrameTimer::getTotalSeconds();
 	if (now >= mCachedRlvSilhouetteUpdateTime)
 	{
-		const F64 SECONDS_BETWEEN_NEARBY_UPDATES = .5f;
+		const F64 SECONDS_BETWEEN_SILHOUETTE_UPDATES = .5f;
 		bool fIsRlvSilhouette = dist_vec_squared(gAgent.getPositionGlobal(), getPositionGlobal()) > s_nSetCamAvDist() * s_nSetCamAvDist();
 		if (fIsRlvSilhouette != mCachedIsRlvSilhouette)
 		{
 			mCachedIsRlvSilhouette = fIsRlvSilhouette;
 			mNeedsImpostorUpdate = TRUE;
 		}
-		mCachedRlvSilhouetteUpdateTime = now + SECONDS_BETWEEN_NEARBY_UPDATES;
+		mCachedRlvSilhouetteUpdateTime = now + SECONDS_BETWEEN_SILHOUETTE_UPDATES;
 	}
 	return mCachedIsRlvSilhouette;
 }
@@ -3723,9 +3798,14 @@ void LLVOAvatar::updateAppearanceMessageDebugText()
 		if (hover_offset[2] != 0.0)
 		{
 			debug_line += llformat(" hov_z: %.3f", hover_offset[2]);
-        debug_line += llformat(" %s", (isSitting() ? "S" : "T"));
+			debug_line += llformat(" %s", (isSitting() ? "S" : "T"));
 			debug_line += llformat("%s", (isMotionActive(ANIM_AGENT_SIT_GROUND_CONSTRAINED) ? "G" : "-"));
 		}
+		if (mInAir)
+		{
+			debug_line += " A";
+			
+		}
 
         LLVector3 ankle_right_pos_agent = mFootRightp->getWorldPosition();
 		LLVector3 normal;
@@ -3738,9 +3818,38 @@ void LLVOAvatar::updateAppearanceMessageDebugText()
         LLVector3 pelvis_pos = mPelvisp->getPosition();
         debug_line += llformat(" rp %.3f pp %.3f", root_pos[2], pelvis_pos[2]);
 
-    S32 is_visible = (S32) isVisible();
-    S32 is_m_visible = (S32) mVisible;
-    debug_line += llformat(" v %d/%d", is_visible, is_m_visible);
+		const LLVector3& scale = getScale();
+		debug_line += llformat(" scale-z %.3f", scale[2]);
+		S32 is_visible = (S32) isVisible();
+		S32 is_m_visible = (S32) mVisible;
+		debug_line += llformat(" v %d/%d", is_visible, is_m_visible);
+
+		AvatarOverallAppearance aoa = getOverallAppearance();
+		if (aoa == AOA_NORMAL)
+		{
+			debug_line += " N";
+		}
+		else if (aoa == AOA_JELLYDOLL)
+		{
+			debug_line += " J";
+		}
+		else
+		{
+			debug_line += " I";
+		}
+
+		if (mMeshValid)
+		{
+			debug_line += "m";
+		}
+		else
+		{
+			debug_line += "-";
+		}
+		if (isImpostor())
+		{
+			debug_line += " Imp" + llformat("%d[%d]:%.1f", mUpdatePeriod, mLastImpostorUpdateReason, ((F32)(gFrameTimeSeconds-mLastImpostorUpdateFrameTime)));
+		}
 
 		addDebugText(debug_line);
 }
@@ -3782,13 +3891,13 @@ LLViewerInventoryItem* recursiveGetObjectInventoryItem(LLViewerObject *vobj, LLU
 
 void LLVOAvatar::updateAnimationDebugText()
 {
-		for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
-			 iter != mMotionController.getActiveMotions().end(); ++iter)
+	for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
+		 iter != mMotionController.getActiveMotions().end(); ++iter)
+	{
+		LLMotion* motionp = *iter;
+		if (motionp->getMinPixelArea() < getPixelArea())
 		{
-			LLMotion* motionp = *iter;
-			if (motionp->getMinPixelArea() < getPixelArea())
-			{
-				std::string output;
+			std::string output;
             std::string motion_name = motionp->getName();
             if (motion_name.empty())
             {
@@ -3805,73 +3914,74 @@ void LLVOAvatar::updateAnimationDebugText()
                 }
             }
             if (motion_name.empty())
+			{
+				std::string name;
+				if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf())
 				{
-					std::string name;
-					if (gAgent.isGodlikeWithoutAdminMenuFakery() || isSelf())
+					name = motionp->getID().asString();
+					LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin();
+					for (; anim_it != mAnimationSources.end(); ++anim_it)
 					{
-						name = motionp->getID().asString();
-						LLVOAvatar::AnimSourceIterator anim_it = mAnimationSources.begin();
-						for (; anim_it != mAnimationSources.end(); ++anim_it)
+						if (anim_it->second == motionp->getID())
 						{
-							if (anim_it->second == motionp->getID())
+							LLViewerObject* object = gObjectList.findObject(anim_it->first);
+							if (!object)
+							{
+								break;
+							}
+							if (object->isAvatar())
+							{
+								if (mMotionController.mIsSelf)
+								{
+									// Searching inventory by asset id is really long
+									// so just mark as inventory
+									// Also item is likely to be named by LLPreviewAnim
+									name += "(inventory)";
+								}
+							}
+							else
 							{
-								LLViewerObject* object = gObjectList.findObject(anim_it->first);
-								if (!object)
+								LLViewerInventoryItem* item = NULL;
+								if (!object->isInventoryDirty())
 								{
-									break;
+									item = object->getInventoryItemByAsset(motionp->getID());
 								}
-								if (object->isAvatar())
+								if (item)
 								{
-									if (mMotionController.mIsSelf)
-									{
-										// Searching inventory by asset id is really long
-										// so just mark as inventory
-										// Also item is likely to be named by LLPreviewAnim
-										name += "(inventory)";
-									}
+									name = item->getName();
+								}
+								else if (object->isAttachment())
+								{
+									name += "(att:" + getAttachmentItemName() + ")";
 								}
 								else
 								{
-									LLViewerInventoryItem* item = NULL;
-									if (!object->isInventoryDirty())
-									{
-										item = object->getInventoryItemByAsset(motionp->getID());
-									}
-									if (item)
-									{
-										name = item->getName();
-									}
-									else if (object->isAttachment())
-									{
-										name += "(" + getAttachmentItemName() + ")";
-									}
-									else
-									{
-										// in-world object, name or content unknown
-										name += "(in-world)";
-									}
+									// in-world object, name or content unknown
+									name += "(in-world)";
 								}
-								break;
 							}
+							break;
 						}
 					}
-					else
-					{
-						name = LLUUID::null.asString();
-					}
-					output = llformat("%s - %d",
-							  name.c_str(),
-							  (U32)motionp->getPriority());
 				}
 				else
 				{
-					output = llformat("%s - %d",
-                                  motion_name.c_str(),
-							  (U32)motionp->getPriority());
+					name = LLUUID::null.asString();
 				}
-				addDebugText(output);
+				motion_name = name;
 			}
+			std::string motion_tag = "";
+			if (mPlayingAnimations.find(motionp->getID()) != mPlayingAnimations.end())
+			{
+				motion_tag = "*";
+			}
+			output = llformat("%s%s - %d",
+							  motion_name.c_str(),
+							  motion_tag.c_str(),
+							  (U32)motionp->getPriority());
+			addDebugText(output);
 		}
+	}
 }
 
 void LLVOAvatar::updateDebugText()
@@ -4000,7 +4110,14 @@ void LLVOAvatar::updateFootstepSounds()
 // computeUpdatePeriod()
 // Factored out from updateCharacter()
 // Set new value for mUpdatePeriod based on distance and various other factors.
-//------------------------------------------------------------------------
+//
+// Note 10-2020: it turns out that none of these update period
+// calculations have been having any effect, because
+// mNeedsImpostorUpdate was not being set in updateCharacter(). So
+// it's really open to question whether we want to enable time based updates, and if
+// so, at what rate. Leaving the rates as given would lead to
+// drastically more frequent impostor updates than we've been doing all these years.
+// ------------------------------------------------------------------------
 void LLVOAvatar::computeUpdatePeriod()
 {
 	bool visually_muted = isVisuallyMuted();
@@ -4008,7 +4125,7 @@ void LLVOAvatar::computeUpdatePeriod()
         && isVisible() 
         && (!isSelf() || visually_muted)
         && !isUIAvatar()
-        && sUseImpostors
+        && (sLimitNonImpostors || visually_muted)
         && !mNeedsAnimUpdate 
         && !sFreezeCounter)
 	{
@@ -4016,11 +4133,14 @@ void LLVOAvatar::computeUpdatePeriod()
 		LLVector4a size;
 		size.setSub(ext[1],ext[0]);
 		F32 mag = size.getLength3().getF32()*0.5f;
+
+		const S32 UPDATE_RATE_SLOW = 64;
+		const S32 UPDATE_RATE_MED = 48;
+		const S32 UPDATE_RATE_FAST = 32;
 		
-		F32 impostor_area = 256.f*512.f*(8.125f - LLVOAvatar::sLODFactor*8.f);
 		if (visually_muted)
-		{ // visually muted avatars update at 16 hz
-			mUpdatePeriod = 16;
+		{   // visually muted avatars update at lowest rate
+			mUpdatePeriod = UPDATE_RATE_SLOW;
 		}
 		else if (! shouldImpostor()
 				 || mDrawable->mDistanceWRTCamera < 1.f + mag)
@@ -4029,34 +4149,29 @@ void LLVOAvatar::computeUpdatePeriod()
 			// impostor camera near clip plane
 			mUpdatePeriod = 1;
 		}
-		else if ( shouldImpostor(4) )
+		else if ( shouldImpostor(4.0) )
 		{ //background avatars are REALLY slow updating impostors
-			mUpdatePeriod = 16;
+			mUpdatePeriod = UPDATE_RATE_SLOW;
 		}
 		else if (mLastRezzedStatus <= 0)
 		{
 			// Don't update cloud avatars too often
-			mUpdatePeriod = 8;
+			mUpdatePeriod = UPDATE_RATE_SLOW;
 		}
-		else if ( shouldImpostor(3) )
+		else if ( shouldImpostor(3.0) )
 		{ //back 25% of max visible avatars are slow updating impostors
-			mUpdatePeriod = 8;
+			mUpdatePeriod = UPDATE_RATE_MED;
 		}
-		else if (mImpostorPixelArea <= impostor_area)
-		{  // stuff in between gets an update period based on pixel area
-			mUpdatePeriod = llclamp((S32) sqrtf(impostor_area*4.f/mImpostorPixelArea), 2, 8);
-		}
-		else
+		else 
 		{
 			//nearby avatars, update the impostors more frequently.
-			mUpdatePeriod = 4;
+			mUpdatePeriod = UPDATE_RATE_FAST;
 		}
 	}
 	else
 	{
 		mUpdatePeriod = 1;
 	}
-
 }
 
 //------------------------------------------------------------------------
@@ -4327,7 +4442,33 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
 		if (!isSitting() && !was_sit_ground_constrained)
 		{
 			root_pos += LLVector3d(getHoverOffset());
-		}
+			if (getOverallAppearance() == AOA_JELLYDOLL)
+			{
+				F32 offz = -0.5 * (getScale()[VZ] - mBodySize.mV[VZ]);
+				root_pos[2] += offz;
+				// if (!isSelf() && !isControlAvatar())
+				// {
+				// 	LL_DEBUGS("Avatar") << "av " << getFullname() 
+				// 						<< " frame " << LLFrameTimer::getFrameCount()
+				// 						<< " root adjust offz " << offz
+				// 						<< " scalez " << getScale()[VZ]
+				// 						<< " bsz " << mBodySize.mV[VZ]
+				// 						<< LL_ENDL;
+				// }
+			}
+		}
+		// if (!isSelf() && !isControlAvatar())
+		// {
+		// 	LL_DEBUGS("Avatar") << "av " << getFullname() << " aoa " << (S32) getOverallAppearance()
+		// 						<< " frame " << LLFrameTimer::getFrameCount()
+		// 						<< " scalez " << getScale()[VZ]
+		// 						<< " bsz " << mBodySize.mV[VZ]
+		// 						<< " root pos " << root_pos[2]
+		// 						<< " curr rootz " << mRoot->getPosition()[2] 
+		// 						<< " pp-z " << mPelvisp->getPosition()[2]
+		// 						<< " renderpos " << getRenderPosition()
+		// 						<< LL_ENDL;
+		// }
 
         LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);
         if (cav)
@@ -4338,6 +4479,14 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
         else
         {
             LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
+			// if (!isSelf() && !isControlAvatar())
+			// {
+			// 	LL_DEBUGS("Avatar") << "av " << getFullname() 
+			// 						<< " frame " << LLFrameTimer::getFrameCount()
+			// 						<< " newPosition " << newPosition
+			// 						<< " renderpos " << getRenderPosition()
+			// 						<< LL_ENDL;
+			// }
             if (newPosition != mRoot->getXform()->getWorldPosition())
             {		
                 mRoot->touch();
@@ -4368,6 +4517,37 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
 }
 
 //------------------------------------------------------------------------
+// LLVOAvatar::computeNeedsUpdate()
+// 
+// Most of the logic here is to figure out when to periodically update impostors.
+// Non-impostors have mUpdatePeriod == 1 and will need update every frame.
+//------------------------------------------------------------------------
+bool LLVOAvatar::computeNeedsUpdate()
+{
+	const F32 MAX_IMPOSTOR_INTERVAL = 4.0f;
+	computeUpdatePeriod();
+
+	bool needs_update_by_frame_count = ((LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0);
+
+    bool needs_update_by_max_time = ((gFrameTimeSeconds-mLastImpostorUpdateFrameTime)> MAX_IMPOSTOR_INTERVAL);
+	bool needs_update = needs_update_by_frame_count || needs_update_by_max_time;
+
+	if (needs_update && !isSelf())
+	{
+		if (needs_update_by_max_time)
+		{
+			mNeedsImpostorUpdate = TRUE;
+			mLastImpostorUpdateReason = 11;
+		}
+		else
+		{
+			//mNeedsImpostorUpdate = TRUE;
+			//mLastImpostorUpdateReason = 10;
+		}
+	}
+	return needs_update;
+}
+
 // updateCharacter()
 //
 // This is called for all avatars, so there are 4 possible situations:
@@ -4390,7 +4570,7 @@ void LLVOAvatar::updateRootPositionAndRotation(LLAgent& agent, F32 speed, bool w
 // simulator.
 //
 //------------------------------------------------------------------------
-BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
+bool LLVOAvatar::updateCharacter(LLAgent &agent)
 {	
 	updateDebugText();
 	
@@ -4402,6 +4582,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 	BOOL visible = isVisible();
     bool is_control_avatar = isControlAvatar(); // capture state to simplify tracing
 	bool is_attachment = false;
+
 	if (is_control_avatar)
 	{
         LLControlAvatar *cav = dynamic_cast<LLControlAvatar*>(this);
@@ -4421,11 +4602,11 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 
 	//--------------------------------------------------------------------
 	// The rest should only be done occasionally for far away avatars.
-    // Set mUpdatePeriod and visible based on distance and other criteria.
+    // Set mUpdatePeriod and visible based on distance and other criteria,
+	// and flag for impostor update if needed.
 	//--------------------------------------------------------------------
-    computeUpdatePeriod();
-    bool needs_update = (LLDrawable::getCurrentFrame()+mID.mData[0])%mUpdatePeriod == 0;
-
+	bool needs_update = computeNeedsUpdate();
+	
 	//--------------------------------------------------------------------
 	// Early out if does not need update and not self
 	// don't early out for your own avatar, as we rely on your animations playing reliably
@@ -4438,6 +4619,12 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		return FALSE;
 	}
 
+	//--------------------------------------------------------------------
+	// Handle transitions between regular rendering, jellydoll, or invisible.
+	// Can trigger skeleton reset or animation changes
+	//--------------------------------------------------------------------
+	updateOverallAppearance();
+	
 	//--------------------------------------------------------------------
 	// change animation time quanta based on avatar render load
 	//--------------------------------------------------------------------
@@ -4521,8 +4708,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 
     if (visible)
     {
-	// System avatar mesh vertices need to be reskinned.
-	mNeedsSkin = TRUE;
+		// System avatar mesh vertices need to be reskinned.
+		mNeedsSkin = TRUE;
     }
 
 	return visible;
@@ -4968,7 +5155,8 @@ U32 LLVOAvatar::renderSkinned()
 			}
 			if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
 			{
-				if (isTextureVisible(TEX_HEAD_BAKED) || isUIAvatar())
+	
+				if (isTextureVisible(TEX_HEAD_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
 				{
 					LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
 					if (head_mesh)
@@ -4978,7 +5166,7 @@ U32 LLVOAvatar::renderSkinned()
 					first_pass = FALSE;
 				}
 			}
-			if (isTextureVisible(TEX_UPPER_BAKED) || isUIAvatar())
+			if (isTextureVisible(TEX_UPPER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
 			{
 				LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
 				if (upper_mesh)
@@ -4988,7 +5176,7 @@ U32 LLVOAvatar::renderSkinned()
 				first_pass = FALSE;
 			}
 			
-			if (isTextureVisible(TEX_LOWER_BAKED) || isUIAvatar())
+			if (isTextureVisible(TEX_LOWER_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
 			{
 				LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
 				if (lower_mesh)
@@ -5045,7 +5233,7 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
 			}
 			first_pass = FALSE;
 		}
-		if (isTextureVisible(TEX_HAIR_BAKED))
+		if (isTextureVisible(TEX_HAIR_BAKED) && (getOverallAppearance() != AOA_JELLYDOLL))
 		{
 			LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
 			if (hair_mesh)
@@ -5093,7 +5281,7 @@ U32 LLVOAvatar::renderRigid()
 		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.5f);
 	}
 
-	if (isTextureVisible(TEX_EYES_BAKED)  || isUIAvatar())
+	if (isTextureVisible(TEX_EYES_BAKED) || (getOverallAppearance() == AOA_JELLYDOLL && !isControlAvatar()) || isUIAvatar())
 	{
 		LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT);
 		LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT);
@@ -5722,8 +5910,8 @@ void LLVOAvatar::processAnimationStateChanges()
 		stopMotion(ANIM_AGENT_TARGET);
         if (mEnableDefaultMotions)
         {
-		startMotion(ANIM_AGENT_BODY_NOISE);
-	}
+			startMotion(ANIM_AGENT_BODY_NOISE);
+		}
 	}
 	
 	// clear all current animations
@@ -5743,23 +5931,32 @@ void LLVOAvatar::processAnimationStateChanges()
 		++anim_it;
 	}
 
+	// if jellydolled, shelve all playing animations
+	if (getOverallAppearance() != AOA_NORMAL)
+	{
+		mPlayingAnimations.clear();
+	}
+	
 	// start up all new anims
-	for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();)
+	if (getOverallAppearance() == AOA_NORMAL)
 	{
-		AnimIterator found_anim = mPlayingAnimations.find(anim_it->first);
-
-		// signaled but not playing, or different sequence id, start motion
-		if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second)
+		for (anim_it = mSignaledAnimations.begin(); anim_it != mSignaledAnimations.end();)
 		{
-			if (processSingleAnimationStateChange(anim_it->first, TRUE))
+			AnimIterator found_anim = mPlayingAnimations.find(anim_it->first);
+
+			// signaled but not playing, or different sequence id, start motion
+			if (found_anim == mPlayingAnimations.end() || found_anim->second != anim_it->second)
 			{
-				mPlayingAnimations[anim_it->first] = anim_it->second;
-				++anim_it;
-				continue;
+				if (processSingleAnimationStateChange(anim_it->first, TRUE))
+				{
+					mPlayingAnimations[anim_it->first] = anim_it->second;
+					++anim_it;
+					continue;
+				}
 			}
-		}
 
-		++anim_it;
+			++anim_it;
+		}
 	}
 
 	// clear source information for animations which have been stopped
@@ -6322,6 +6519,11 @@ void LLVOAvatar::addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LL
 	}
 
     LLScopedContextString str("addAttachmentOverridesForObject " + getFullname());
+
+	if (getOverallAppearance() != AOA_NORMAL)
+	{
+		return;
+	}
     
     LL_DEBUGS("AnimatedObjects") << "adding" << LL_ENDL;
     dumpStack("AnimatedObjectsStack");
@@ -7769,9 +7971,15 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color)
 }
 
 // virtual
+// Do rigged mesh attachments display with this av?
 bool LLVOAvatar::shouldRenderRigged() const
 {
-    return true;
+	if (getOverallAppearance() == AOA_NORMAL)
+	{
+		return true;
+	}
+	// TBD - render for AOA_JELLYDOLL?
+	return false;
 }
 
 // FIXME: We have an mVisible member, set in updateVisibility(), but this
@@ -8052,12 +8260,14 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
 	}
 
 	// did our loading state "change" from last call?
-	// runway - why are we updating every 30 calls even if nothing has changed?
+	// FIXME runway - why are we updating every 30 calls even if nothing has changed?
+	// This causes updateLOD() to run every 30 frames, among other things.
 	const S32 UPDATE_RATE = 30;
 	BOOL changed =
 		((mFullyLoaded != mPreviousFullyLoaded) ||         // if the value is different from the previous call
 		 (!mFullyLoadedInitialized) ||                     // if we've never been called before
 		 (mFullyLoadedFrameCounter % UPDATE_RATE == 0));   // every now and then issue a change
+	BOOL fully_loaded_changed = (mFullyLoaded != mPreviousFullyLoaded);
 
 	mPreviousFullyLoaded = mFullyLoaded;
 	mFullyLoadedInitialized = TRUE;
@@ -8068,7 +8278,13 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
         // to know about outfit switching
         LLAvatarRenderNotifier::getInstance()->updateNotificationState();
     }
-	
+
+	if (fully_loaded_changed && !isSelf() && mFullyLoaded && isImpostor())
+	{
+		// Fix for jellydoll initially invisible
+		mNeedsImpostorUpdate = TRUE;
+		mLastImpostorUpdateReason = 6;
+	}	
 	return changed;
 }
 
@@ -8144,47 +8360,25 @@ void LLVOAvatar::updateMeshVisibility()
 	bool bake_flag[BAKED_NUM_INDICES];
 	memset(bake_flag, 0, BAKED_NUM_INDICES*sizeof(bool));
 
-	for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
-		iter != mAttachmentPoints.end();
-		++iter)
+	if (getOverallAppearance() == AOA_NORMAL)
 	{
-		LLViewerJointAttachment* attachment = iter->second;
-		if (attachment)
+		for (attachment_map_t::iterator iter = mAttachmentPoints.begin();
+			 iter != mAttachmentPoints.end();
+			 ++iter)
 		{
-			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
-				attachment_iter != attachment->mAttachedObjects.end();
-				++attachment_iter)
+			LLViewerJointAttachment* attachment = iter->second;
+			if (attachment)
 			{
-				LLViewerObject *objectp = attachment_iter->get();
-				if (objectp)
-				{
-					for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++)
-					{
-						LLTextureEntry* tex_entry = objectp->getTE(face_index);
-						bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD);
-						bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES);
-						bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR);
-						bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER);
-						bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER);
-						bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT);
-						bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM);
-						bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG);
-						bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1);
-						bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2);
-						bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3);
-					}
-				}
-
-				LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
-				for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
-					iter1 != child_list.end(); ++iter1)
+				for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+					 attachment_iter != attachment->mAttachedObjects.end();
+					 ++attachment_iter)
 				{
-					LLViewerObject* objectchild = *iter1;
-					if (objectchild)
+					LLViewerObject *objectp = attachment_iter->get();
+					if (objectp)
 					{
-						for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++)
+						for (int face_index = 0; face_index < objectp->getNumTEs(); face_index++)
 						{
-							LLTextureEntry* tex_entry = objectchild->getTE(face_index);
+							LLTextureEntry* tex_entry = objectp->getTE(face_index);
 							bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD);
 							bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES);
 							bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR);
@@ -8198,6 +8392,31 @@ void LLVOAvatar::updateMeshVisibility()
 							bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3);
 						}
 					}
+
+					LLViewerObject::const_child_list_t& child_list = objectp->getChildren();
+					for (LLViewerObject::child_list_t::const_iterator iter1 = child_list.begin();
+						 iter1 != child_list.end(); ++iter1)
+					{
+						LLViewerObject* objectchild = *iter1;
+						if (objectchild)
+						{
+							for (int face_index = 0; face_index < objectchild->getNumTEs(); face_index++)
+							{
+								LLTextureEntry* tex_entry = objectchild->getTE(face_index);
+								bake_flag[BAKED_HEAD] |= (tex_entry->getID() == IMG_USE_BAKED_HEAD);
+								bake_flag[BAKED_EYES] |= (tex_entry->getID() == IMG_USE_BAKED_EYES);
+								bake_flag[BAKED_HAIR] |= (tex_entry->getID() == IMG_USE_BAKED_HAIR);
+								bake_flag[BAKED_LOWER] |= (tex_entry->getID() == IMG_USE_BAKED_LOWER);
+								bake_flag[BAKED_UPPER] |= (tex_entry->getID() == IMG_USE_BAKED_UPPER);
+								bake_flag[BAKED_SKIRT] |= (tex_entry->getID() == IMG_USE_BAKED_SKIRT);
+								bake_flag[BAKED_LEFT_ARM] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTARM);
+								bake_flag[BAKED_LEFT_LEG] |= (tex_entry->getID() == IMG_USE_BAKED_LEFTLEG);
+								bake_flag[BAKED_AUX1] |= (tex_entry->getID() == IMG_USE_BAKED_AUX1);
+								bake_flag[BAKED_AUX2] |= (tex_entry->getID() == IMG_USE_BAKED_AUX2);
+								bake_flag[BAKED_AUX3] |= (tex_entry->getID() == IMG_USE_BAKED_AUX3);
+							}
+						}
+					}
 				}
 			}
 		}
@@ -9128,7 +9347,11 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
     mLastProcessedAppearance = contents;
 
     bool slam_params = false;
-    applyParsedAppearanceMessage(*contents, slam_params);
+	applyParsedAppearanceMessage(*contents, slam_params);
+	if (getOverallAppearance() != AOA_NORMAL)
+	{
+		resetSkeleton(false);
+	}
 }
 
 void LLVOAvatar::applyParsedAppearanceMessage(LLAppearanceMessageContents& contents, bool slam_params)
@@ -10021,7 +10244,7 @@ BOOL LLVOAvatar::updateLOD()
         return FALSE;
     }
     
-	if (isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry())
+	if (!LLPipeline::sImpostorRender && isImpostor() && 0 != mDrawable->getNumFaces() && mDrawable->getFace(0)->hasGeometry())
 	{
 		return TRUE;
 	}
@@ -10212,10 +10435,10 @@ void LLVOAvatar::updateImpostors()
 		iter != instances_copy.end(); ++iter)
 	{
 		LLVOAvatar* avatar = (LLVOAvatar*) *iter;
-		if (!avatar->isDead() && avatar->isVisible()
-			&& (
-                (avatar->isImpostor() || LLVOAvatar::AV_DO_NOT_RENDER == avatar->getVisualMuteSettings()) && avatar->needsImpostorUpdate())
-            )
+		if (!avatar->isDead()
+			&& avatar->isVisible()
+			&& avatar->isImpostor()
+			&& avatar->needsImpostorUpdate())
 		{
             avatar->calcMutedAVColor();
 			gPipeline.generateImpostor(avatar);
@@ -10228,12 +10451,20 @@ void LLVOAvatar::updateImpostors()
 // virtual
 BOOL LLVOAvatar::isImpostor()
 {
-	return sUseImpostors && (isVisuallyMuted() || (mUpdatePeriod >= IMPOSTOR_PERIOD)) ? TRUE : FALSE;
+	return isVisuallyMuted() || (sLimitNonImpostors && (mUpdatePeriod > 1));
 }
 
-BOOL LLVOAvatar::shouldImpostor(const U32 rank_factor) const
+BOOL LLVOAvatar::shouldImpostor(const F32 rank_factor)
 {
-	return (!isSelf() && sUseImpostors && mVisibilityRank > (sMaxNonImpostors * rank_factor));
+	if (isSelf())
+	{
+		return false;
+	}
+	if (isVisuallyMuted())
+	{
+		return true;
+	}
+	return sLimitNonImpostors && (mVisibilityRank > sMaxNonImpostors * rank_factor);
 }
 
 BOOL LLVOAvatar::needsImpostorUpdate() const
@@ -10276,16 +10507,16 @@ void LLVOAvatar::getImpostorValues(LLVector4a* extents, LLVector3& angle, F32& d
 }
 
 // static
-const U32 LLVOAvatar::IMPOSTORS_OFF = 66; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors
+const U32 LLVOAvatar::NON_IMPOSTORS_MAX_SLIDER = 66; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors
 										   * slider in panel_preferences_graphics1.xml */
 
 // static
 void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue)
 {
 	U32  oldmax = sMaxNonImpostors;
-	bool oldflg = sUseImpostors;
+	bool oldflg = sLimitNonImpostors;
 	
-	if (IMPOSTORS_OFF <= newMaxNonImpostorsValue)
+	if (NON_IMPOSTORS_MAX_SLIDER <= newMaxNonImpostorsValue)
 	{
 		sMaxNonImpostors = 0;
 	}
@@ -10293,13 +10524,13 @@ void LLVOAvatar::updateImpostorRendering(U32 newMaxNonImpostorsValue)
 	{
 		sMaxNonImpostors = newMaxNonImpostorsValue;
 	}
-	// the sUseImpostors flag depends on whether or not sMaxNonImpostors is set to the no-limit value (0)
-	sUseImpostors = (0 != sMaxNonImpostors);
-    if ( oldflg != sUseImpostors )
+	// the sLimitNonImpostors flag depends on whether or not sMaxNonImpostors is set to the no-limit value (0)
+	sLimitNonImpostors = (0 != sMaxNonImpostors);
+    if ( oldflg != sLimitNonImpostors )
     {
         LL_DEBUGS("AvatarRender")
             << "was " << (oldflg ? "use" : "don't use" ) << " impostors (max " << oldmax << "); "
-            << "now " << (sUseImpostors ? "use" : "don't use" ) << " impostors (max " << sMaxNonImpostors << "); "
+            << "now " << (sLimitNonImpostors ? "use" : "don't use" ) << " impostors (max " << sMaxNonImpostors << "); "
             << LL_ENDL;
     }
 }
@@ -10684,33 +10915,197 @@ void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)
 {
     mVisuallyMuteSetting = set;
     mNeedsImpostorUpdate = TRUE;
+	mLastImpostorUpdateReason = 7;
 
     LLRenderMuteList::getInstance()->saveVisualMuteSetting(getID(), S32(set));
 }
 
+
+void LLVOAvatar::setOverallAppearanceNormal()
+{
+	if (isControlAvatar())
+		return;
+
+    LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition();
+	resetSkeleton(false);
+    getJoint("mPelvis")->setPosition(pelvis_pos);
+
+	for (auto it = mJellyAnims.begin(); it !=  mJellyAnims.end(); ++it)
+	{
+		bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end());
+		LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL;
+		if (!is_playing)
+		{
+			// Anim was not requested for this av by sim, but may be playing locally
+			stopMotion(*it);
+		}
+	}
+	mJellyAnims.clear();
+
+	processAnimationStateChanges();
+}
+
+void LLVOAvatar::setOverallAppearanceJellyDoll()
+{
+	if (isControlAvatar())
+		return;
+
+	// stop current animations
+	{
+		for ( LLVOAvatar::AnimIterator anim_it= mPlayingAnimations.begin();
+			  anim_it != mPlayingAnimations.end();
+			  ++anim_it)
+		{
+			{
+				stopMotion(anim_it->first, TRUE);
+			}
+		}
+	}
+	processAnimationStateChanges();
+
+	// Start any needed anims for jellydoll
+	updateOverallAppearanceAnimations();
+	
+    LLVector3 pelvis_pos = getJoint("mPelvis")->getPosition();
+	resetSkeleton(false);
+    getJoint("mPelvis")->setPosition(pelvis_pos);
+
+}
+
+void LLVOAvatar::setOverallAppearanceInvisible()
+{
+}
+
+void LLVOAvatar::updateOverallAppearance()
+{
+	AvatarOverallAppearance new_overall = getOverallAppearance();
+	if (new_overall != mOverallAppearance)
+	{
+		switch (new_overall)
+		{
+			case AOA_NORMAL:
+				setOverallAppearanceNormal();
+				break;
+			case AOA_JELLYDOLL:
+				setOverallAppearanceJellyDoll();
+				break;
+			case AOA_INVISIBLE:
+				setOverallAppearanceInvisible();
+				break;
+		}
+		mOverallAppearance = new_overall;
+		if (!isSelf())
+		{
+			mNeedsImpostorUpdate = TRUE;
+			mLastImpostorUpdateReason = 8;
+		}
+		updateMeshVisibility();
+	}
+
+	// This needs to be done even if overall appearance has not
+	// changed, since sit/stand status can be different.
+	updateOverallAppearanceAnimations();
+}
+
+void LLVOAvatar::updateOverallAppearanceAnimations()
+{
+	if (isControlAvatar())
+		return;
+
+	if (getOverallAppearance() == AOA_JELLYDOLL)
+	{
+		LLUUID motion_id;
+		if (isSitting() && getParent()) // sitting on object
+		{
+			motion_id = ANIM_AGENT_SIT_FEMALE; 
+		}
+		else if (isSitting()) // sitting on ground
+		{
+			motion_id = ANIM_AGENT_SIT_GROUND_CONSTRAINED;
+		}
+		else // standing
+		{
+			motion_id = ANIM_AGENT_STAND;
+		}
+		if (mJellyAnims.find(motion_id) == mJellyAnims.end())
+		{
+			for (auto it = mJellyAnims.begin(); it !=  mJellyAnims.end(); ++it)
+			{
+				bool is_playing = (mPlayingAnimations.find(*it) != mPlayingAnimations.end());
+				LL_DEBUGS("Avatar") << "jelly anim " << *it << " " << is_playing << LL_ENDL;
+				if (!is_playing)
+				{
+					// Anim was not requested for this av by sim, but may be playing locally
+					stopMotion(*it, TRUE);
+				}
+			}
+			mJellyAnims.clear();
+
+			startMotion(motion_id);
+			mJellyAnims.insert(motion_id);
+
+			processAnimationStateChanges();
+		}
+	}
+}
+
+// Based on isVisuallyMuted(), but has 3 possible results.
+LLVOAvatar::AvatarOverallAppearance LLVOAvatar::getOverallAppearance() const
+{
+	AvatarOverallAppearance result = AOA_NORMAL;
+
+	// Priority order (highest priority first)
+	// * own avatar is always drawn normally
+	// * if on the "always draw normally" list, draw them normally
+	// * if on the "always visually mute" list, show as jellydoll
+	// * if explicitly muted (blocked), show as invisible
+	// * check against the render cost and attachment limits - if too complex, show as jellydoll
+	if (isSelf())
+	{
+		result = AOA_NORMAL;
+	}
+	else // !isSelf()
+	{
+		if (isInMuteList())
+		{
+			result = AOA_INVISIBLE;
+		}
+		else if (mVisuallyMuteSetting == AV_ALWAYS_RENDER)
+		{
+			result = AOA_NORMAL;
+		}
+		else if (mVisuallyMuteSetting == AV_DO_NOT_RENDER)
+		{	// Always want to see this AV as an impostor
+			result = AOA_JELLYDOLL;
+		}
+		else if (isTooComplex())
+		{
+			result = AOA_JELLYDOLL;
+		}
+	}
+
+	return result;
+}
+
 void LLVOAvatar::calcMutedAVColor()
 {
     LLColor4 new_color(mMutedAVColor);
     std::string change_msg;
     LLUUID av_id(getID());
 
-    if (getVisualMuteSettings() == AV_DO_NOT_RENDER)
-    {
 // [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
-		 if (isRlvSilhouette())
-		 {
-			 new_color = LLColor4::silhouette;
-			 change_msg = " not rendered: color is silhouette";
-		 }
-		 else
-		 {
-// [/RLVa:KB]
-			// explicitly not-rendered avatars are light grey
-			 new_color = LLColor4::grey3;
-			 change_msg = " not rendered: color is grey3";
-// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
-		 }
+	if (isRlvSilhouette())
+	{
+		new_color = LLColor4::silhouette;
+		change_msg = " not rendered: color is silhouette";
+	}
+    else if (getVisualMuteSettings() == AV_DO_NOT_RENDER)
 // [/RLVa:KB]
+//    if (getVisualMuteSettings() == AV_DO_NOT_RENDER)
+    {
+        // explicitly not-rendered avatars are light grey
+        new_color = LLColor4::grey4;
+        change_msg = " not rendered: color is grey4";
     }
     else if (LLMuteList::getInstance()->isMuted(av_id)) // the user blocked them
     {
@@ -10723,29 +11118,31 @@ void LLVOAvatar::calcMutedAVColor()
         new_color = LLColor4::white;
         change_msg = " simple imposter ";
     }
-//    else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 )
-// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
-	else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 || mMutedAVColor == LLColor4::silhouette)
-// [/RLVa:KB]
-   {
+#ifdef COLORIZE_JELLYDOLLS
+    else if ( mMutedAVColor == LLColor4::white || mMutedAVColor == LLColor4::grey3 || mMutedAVColor == LLColor4::grey4 )
+	{
         // select a color based on the first byte of the agents uuid so any muted agent is always the same color
         F32 color_value = (F32) (av_id.mData[0]);
-        F32 spectrum = (color_value / 256.0);		// spectrum is between 0 and 1.f
+        F32 spectrum = (color_value / 256.0);          // spectrum is between 0 and 1.f
 
-        // Array of colors.  These are arranged so only one RGB color changes between each step, 
+        // Array of colors.  These are arranged so only one RGB color changes between each step,
         // and it loops back to red so there is an even distribution.  It is not a heat map
-        const S32 NUM_SPECTRUM_COLORS = 7;              
+        const S32 NUM_SPECTRUM_COLORS = 7;
         static LLColor4 * spectrum_color[NUM_SPECTRUM_COLORS] = { &LLColor4::red, &LLColor4::magenta, &LLColor4::blue, &LLColor4::cyan, &LLColor4::green, &LLColor4::yellow, &LLColor4::red };
- 
-        spectrum = spectrum * (NUM_SPECTRUM_COLORS - 1);		// Scale to range of number of colors
-        S32 spectrum_index_1  = floor(spectrum);				// Desired color will be after this index
-        S32 spectrum_index_2  = spectrum_index_1 + 1;			//    and before this index (inclusive)
+
+        spectrum = spectrum * (NUM_SPECTRUM_COLORS - 1);               // Scale to range of number of colors
+        S32 spectrum_index_1  = floor(spectrum);                               // Desired color will be after this index
+        S32 spectrum_index_2  = spectrum_index_1 + 1;                  //    and before this index (inclusive)
         F32 fractBetween = spectrum - (F32)(spectrum_index_1);  // distance between the two indexes (0-1)
- 
-        new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween);
-        new_color.normalize();
-        new_color *= 0.28f;		// Tone it down
 
+        new_color = lerp(*spectrum_color[spectrum_index_1], *spectrum_color[spectrum_index_2], fractBetween);
+		new_color.normalize();
+        new_color *= 0.28f;            // Tone it down
+	}
+#endif
+    else
+    {
+		new_color = LLColor4::grey4;
         change_msg = " over limit color ";
     }
 
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index 6abef41038a80ea0dffcdd262cd983c68588201b..aeb7795c4e8bf54efc18d96d4d2256cc41a4cfa3 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -91,6 +91,7 @@ class LLVOAvatar :
 
 public:
 	friend class LLVOAvatarSelf;
+	friend class LLAvatarCheckImpostorMode;
 
 /********************************************************************************
  **                                                                            **
@@ -131,6 +132,7 @@ class LLVOAvatar :
 public:
 	/*virtual*/ void			updateGL();
 	/*virtual*/ LLVOAvatar*		asAvatar();
+
 	virtual U32    	 	 	processUpdateMessage(LLMessageSystem *mesgsys,
 													 void **user_data,
 													 U32 block_num,
@@ -252,6 +254,11 @@ class LLVOAvatar :
 	virtual bool 	isControlAvatar() const { return mIsControlAvatar; } // True if this avatar is a control av (no associated user)
 	virtual bool 	isUIAvatar() const { return mIsUIAvatar; } // True if this avatar is a supplemental av used in some UI views (no associated user)
 
+	// If this is an attachment, return the avatar it is attached to. Otherwise NULL.
+	virtual const LLVOAvatar *getAttachedAvatar() const { return NULL; }
+	virtual LLVOAvatar *getAttachedAvatar() { return NULL; }
+
+
 private: //aligned members
 	LL_ALIGN_16(LLVector4a	mImpostorExtents[2]);
 
@@ -262,7 +269,8 @@ class LLVOAvatar :
     void			updateAppearanceMessageDebugText();
 	void 			updateAnimationDebugText();
 	virtual void	updateDebugText();
-	virtual BOOL 	updateCharacter(LLAgent &agent);
+	virtual bool 	computeNeedsUpdate();
+	virtual bool 	updateCharacter(LLAgent &agent);
     void			updateFootstepSounds();
     void			computeUpdatePeriod();
     void			updateOrientation(LLAgent &agent, F32 speed, F32 delta_time);
@@ -314,12 +322,12 @@ class LLVOAvatar :
 public:
 	static S32		sRenderName;
 	static BOOL		sRenderGroupTitles;
-	static const U32 IMPOSTORS_OFF; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors
-									 * slider in panel_preferences_graphics1.xml */
-	static U32		sMaxNonImpostors; //(affected by control "RenderAvatarMaxNonImpostors")
-	static F32		sRenderDistance; //distance at which avatars will render.
+	static const U32 NON_IMPOSTORS_MAX_SLIDER; /* Must equal the maximum allowed the RenderAvatarMaxNonImpostors
+												* slider in panel_preferences_graphics1.xml */
+	static U32		sMaxNonImpostors; // affected by control "RenderAvatarMaxNonImpostors"
+	static bool		sLimitNonImpostors; // use impostors for far away avatars
+	static F32		sRenderDistance; // distance at which avatars will render.
 	static BOOL		sShowAnimationDebug; // show animation debug info
-	static bool		sUseImpostors; //use impostors for far away avatars
 	static BOOL		sShowFootPlane;	// show foot collision plane reported by server
 	static BOOL		sShowCollisionVolumes;	// show skeletal collision volumes
 	static BOOL		sVisibleInFirstPerson;
@@ -407,6 +415,7 @@ class LLVOAvatar :
     void                initAttachmentPoints(bool ignore_hud_joints = false);
 	/*virtual*/ void	buildCharacter();
     void                resetVisualParams();
+	void				applyDefaultParams();
     void				resetSkeleton(bool reset_animations);
 
 	LLVector3			mCurRootToHeadOffset;
@@ -427,12 +436,15 @@ class LLVOAvatar :
 public:
 	U32 		renderImpostor(LLColor4U color = LLColor4U(255,255,255,255), S32 diffuse_channel = 0);
 	bool		isVisuallyMuted();
-	bool 		isInMuteList();
+	bool 		isInMuteList() const;
 // [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
-	bool        isRlvSilhouette();
+	bool        isRlvSilhouette() const;
 // [/RLVa:KB]
 	void		forceUpdateVisualMuteSettings();
 
+	// Visual Mute Setting is an input. Does not necessarily determine
+	// what the avatar looks like, because it interacts with other
+	// settings like muting, complexity threshold. Should be private or protected.
 	enum VisualMuteSettings
 	{
 		AV_RENDER_NORMALLY = 0,
@@ -440,10 +452,35 @@ class LLVOAvatar :
 		AV_ALWAYS_RENDER   = 2
 	};
 	void		setVisualMuteSettings(VisualMuteSettings set);
-// [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
-	VisualMuteSettings  getVisualMuteSettings()						{ return (!isRlvSilhouette()) ? mVisuallyMuteSetting : AV_DO_NOT_RENDER; };
-// [/RLVa:KB]
-//	VisualMuteSettings  getVisualMuteSettings()						{ return mVisuallyMuteSetting;	};
+
+protected:
+	// If you think you need to access this outside LLVOAvatar, you probably want getOverallAppearance()
+	VisualMuteSettings  getVisualMuteSettings()						{ return mVisuallyMuteSetting;	};
+
+public:
+
+	// Overall Appearance is an output. Depending on whether the
+	// avatar is blocked/muted, whether it exceeds the complexity
+	// threshold, etc, avatar will want to be displayed in one of
+	// these ways. Rendering code that wants to know how to display an
+	// avatar should be looking at this value, NOT the visual mute
+	// settings
+	enum AvatarOverallAppearance
+	{
+		AOA_NORMAL,
+		AOA_JELLYDOLL,
+		AOA_INVISIBLE
+	};
+
+	AvatarOverallAppearance getOverallAppearance() const;
+	void setOverallAppearanceNormal();
+	void setOverallAppearanceJellyDoll();
+	void setOverallAppearanceInvisible();
+		
+	void updateOverallAppearance();
+	void updateOverallAppearanceAnimations();
+
+	std::set<LLUUID> mJellyAnims;
 
 	U32 		renderRigid();
 	U32 		renderSkinned();
@@ -457,7 +494,8 @@ class LLVOAvatar :
 	static void	restoreGL();
 	S32			mSpecialRenderMode; // special lighting
         
-  private:
+private:
+	AvatarOverallAppearance mOverallAppearance;
 	F32			mAttachmentSurfaceArea; //estimated surface area of attachments
     U32			mAttachmentVisibleTriangleCount;
     F32			mAttachmentEstTriangleCount;
@@ -474,11 +512,11 @@ class LLVOAvatar :
 	mutable bool mVisualComplexityStale;
 	U32          mReportedVisualComplexity; // from other viewers through the simulator
 
-	bool		mCachedInMuteList;
-	F64			mCachedMuteListUpdateTime;
+	mutable bool		mCachedInMuteList;
+	mutable F64			mCachedMuteListUpdateTime;
 // [RLVa:KB] - Checked: RLVa-2.2 (@setcam_avdist)
-	mutable bool mCachedIsRlvSilhouette = false;
-	mutable F64  mCachedRlvSilhouetteUpdateTime = 0.f;
+	mutable bool        mCachedIsRlvSilhouette = false;
+	mutable F64         mCachedRlvSilhouetteUpdateTime = 0.f;
 // [/RLVa:KB]
 
 	VisualMuteSettings		mVisuallyMuteSetting;			// Always or never visually mute this AV
@@ -530,7 +568,7 @@ class LLVOAvatar :
 	//--------------------------------------------------------------------
 public:
 	virtual BOOL isImpostor();
-	BOOL 		shouldImpostor(const U32 rank_factor = 1) const;
+	BOOL 		shouldImpostor(const F32 rank_factor = 1.0);
 	BOOL 	    needsImpostorUpdate() const;
 	const LLVector3& getImpostorOffset() const;
 	const LLVector2& getImpostorDim() const;
@@ -540,7 +578,11 @@ class LLVOAvatar :
 	static void	resetImpostors();
 	static void updateImpostors();
 	LLRenderTarget mImpostor;
-	BOOL		mNeedsImpostorUpdate;
+// [RLVa:KB] - Checked: RLVa-2.4 (@setcam_avdist)
+	mutable BOOL mNeedsImpostorUpdate;
+// [/RLVa:KB]
+//	BOOL		mNeedsImpostorUpdate;
+	S32			mLastImpostorUpdateReason;
 	F32SecondsImplicit mLastImpostorUpdateFrameTime;
     const LLVector3*  getLastAnimExtents() const { return mLastAnimExtents; }
 	void		setNeedsExtentUpdate(bool val) { mNeedsExtentUpdate = val; }
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 69aa7d034ccfa60a26677f724f27590e87683439..167e8acb82aa870862665aa3539aaa9557b67617 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -482,6 +482,8 @@ BOOL LLVOAvatarSelf::buildMenus()
 		if (gDetachBodyPartPieMenus[i])
 		{
 			gDetachPieMenu->appendContextSubMenu( gDetachBodyPartPieMenus[i] );
+			gDetachAttSelfMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]);
+			gDetachAvatarMenu->appendContextSubMenu(gDetachBodyPartPieMenus[i]);
 		}
 		else
 		{
@@ -510,12 +512,14 @@ BOOL LLVOAvatarSelf::buildMenus()
 					LLMenuItemCallGL* item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
 
 					gDetachPieMenu->addChild(item);
-						
+					gDetachAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
+					gDetachAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
 					break;
 				}
 			}
 		}
 	}
+	
 
 	// add screen attachments
 	for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); 
@@ -550,6 +554,8 @@ BOOL LLVOAvatarSelf::buildMenus()
 			item_params.on_enable.parameter = iter->first;
 			item = LLUICtrlFactory::create<LLMenuItemCallGL>(item_params);
 			gDetachScreenPieMenu->addChild(item);
+			gDetachHUDAttSelfMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
+			gDetachHUDAvatarMenu->addChild(LLUICtrlFactory::create<LLMenuItemCallGL>(item_params));
 		}
 	}
 
@@ -692,7 +698,7 @@ LLVOAvatarSelf::~LLVOAvatarSelf()
  *********************************************************************************/
 
 // virtual
-BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)
+bool LLVOAvatarSelf::updateCharacter(LLAgent &agent)
 {
 	// update screen joint size
 	if (mScreenp)
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 8da24cbcfa8bdf70ad0f2d7a49008bf079beffa5..13836ef0a01595972acfc846e5ab8bc81564c77c 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -116,7 +116,7 @@ class LLVOAvatarSelf :
 	// Updates
 	//--------------------------------------------------------------------
 public:
-	/*virtual*/ BOOL 	updateCharacter(LLAgent &agent);
+	/*virtual*/ bool 	updateCharacter(LLAgent &agent);
 	/*virtual*/ void 	idleUpdateTractorBeam();
 	bool				checkStuckAppearance();
 
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 377f3174f3407930b5385debe2b9fb5518bfff9b..e2bd1a39c7f1899d9f5ed5f695bc66db45e75a8f 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -180,6 +180,13 @@ void LLVoiceClient::terminate()
 {
 	if (mVoiceModule) mVoiceModule->terminate();
 	mVoiceModule = NULL;
+    m_servicePump = NULL;
+
+    // Shutdown speaker volume storage before LLSingletonBase::deleteAll() does it
+    if (LLSpeakerVolumeStorage::instanceExists())
+    {
+        LLSpeakerVolumeStorage::deleteSingleton();
+    }
 }
 
 const LLVoiceVersionInfo LLVoiceClient::getVersion()
@@ -200,8 +207,6 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion()
 void LLVoiceClient::updateSettings()
 {
 	setUsePTT(gSavedSettings.getBOOL("PTTCurrentlyEnabled"));
-	std::string keyString = gSavedSettings.getString("PushToTalkButton");
-	setPTTKey(keyString);
 	setPTTIsToggle(gSavedSettings.getBOOL("PushToTalkToggle"));
 	mDisableMic = gSavedSettings.getBOOL("VoiceDisableMic");
 
@@ -637,32 +642,6 @@ bool LLVoiceClient::getPTTIsToggle()
 	return mPTTIsToggle;
 }
 
-void LLVoiceClient::setPTTKey(std::string &key)
-{
-	// Value is stored as text for readability
-	if(key == "MiddleMouse")
-	{
-		mPTTMouseButton = LLMouseHandler::CLICK_MIDDLE;
-	}
-	else if(key == "MouseButton4")
-	{
-		mPTTMouseButton = LLMouseHandler::CLICK_BUTTON4;
-	}
-	else if (key == "MouseButton5")
-	{
-		mPTTMouseButton = LLMouseHandler::CLICK_BUTTON5;
-	}
-	else
-	{
-		mPTTMouseButton = 0;
-		if(!LLKeyboard::keyFromString(key, &mPTTKey))
-		{
-			// If the call failed, don't match any key.
-			key = KEY_NONE;
-		}
-	}
-}
-
 void LLVoiceClient::inputUserControlState(bool down)
 {
 	if(mPTTIsToggle)
@@ -683,43 +662,6 @@ void LLVoiceClient::toggleUserPTTState(void)
 	setUserPTTState(!getUserPTTState());
 }
 
-void LLVoiceClient::keyDown(KEY key, MASK mask)
-{	
-	if (gKeyboard->getKeyRepeated(key))
-	{
-		// ignore auto-repeat keys                                                                         
-		return;
-	}
-	
-	if (mPTTMouseButton == 0 && LLAgent::isActionAllowed("speak") && (key == mPTTKey))
-	{
-		bool down = gKeyboard->getKeyDown(mPTTKey);
-		if (down)
-		{
-			inputUserControlState(down);
-		}
-	}
-	
-}
-void LLVoiceClient::keyUp(KEY key, MASK mask)
-{
-	if (mPTTMouseButton == 0 && (key == mPTTKey))
-	{
-		bool down = gKeyboard->getKeyDown(mPTTKey);
-		if (!down)
-		{
-			inputUserControlState(down);
-		}
-	}
-}
-void LLVoiceClient::updateMouseState(S32 click, bool down)
-{
-	if(mPTTMouseButton == click && LLAgent::isActionAllowed("speak"))
-	{
-		inputUserControlState(down);
-	}
-}
-
 
 //-------------------------------------------
 // nearby speaker accessors
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 1a4d253208227767c362f3012192d650e2d5efdc..cf527a4464ffca1fd3978c5571dc81f3e6b60e05 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -408,16 +408,10 @@ class LLVoiceClient: public LLParamSingleton<LLVoiceClient>
 	void setUsePTT(bool usePTT);
 	void setPTTIsToggle(bool PTTIsToggle);
 	bool getPTTIsToggle();	
-	void setPTTKey(std::string &key);
-	
+
 	void updateMicMuteLogic();
-	
+
 	BOOL lipSyncEnabled();
-	
-	// PTT key triggering
-	void keyDown(KEY key, MASK mask);
-	void keyUp(KEY key, MASK mask);
-	void updateMouseState(S32 click, bool down);
 
 	boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); }
 
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index a8d668420e127dac98e2585601dd4b8f57b83151..7d8aa6fbbd6b91ea5c47bf084a4a2b755ad3a9ee 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -359,7 +359,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
 //	gMuteListp->addObserver(&mutelist_listener);
 
 	
-#if LL_DARWIN || LL_LINUX || LL_SOLARIS
+#if LL_DARWIN || LL_LINUX
 		// HACK: THIS DOES NOT BELONG HERE
 		// When the vivox daemon dies, the next write attempt on our socket generates a SIGPIPE, which kills us.
 		// This should cause us to ignore SIGPIPE and handle the error through proper channels.
@@ -391,7 +391,7 @@ LLVivoxVoiceClient::~LLVivoxVoiceClient()
 void LLVivoxVoiceClient::init(LLPumpIO *pump)
 {
 	// constructor will set up LLVoiceClient::getInstance()
-	LLVivoxVoiceClient::getInstance()->mPump = pump;
+	mPump = pump;
 
 //     LLCoros::instance().launch("LLVivoxVoiceClient::voiceControlCoro",
 //         boost::bind(&LLVivoxVoiceClient::voiceControlCoro, LLVivoxVoiceClient::getInstance()));
@@ -419,6 +419,7 @@ void LLVivoxVoiceClient::terminate()
 	}
 
     sShuttingDown = true;
+    mPump = NULL;
 }
 
 //---------------------------------------------------
@@ -683,6 +684,21 @@ void LLVivoxVoiceClient::voiceControlCoro()
         bool success = startAndConnectSession();
         if (success)
         {
+			// enable/disable the automatic VAD and explicitly set the initial values of 
+			// the VAD variables ourselves when it is off - see SL-15072 for more details
+			// note: we set the other parameters too even if the auto VAD is on which is ok
+			unsigned int vad_auto = gSavedSettings.getU32("VivoxVadAuto");
+			unsigned int vad_hangover = gSavedSettings.getU32("VivoxVadHangover");
+			unsigned int vad_noise_floor = gSavedSettings.getU32("VivoxVadNoiseFloor");
+			unsigned int vad_sensitivity = gSavedSettings.getU32("VivoxVadSensitivity");
+			setupVADParams(vad_auto, vad_hangover, vad_noise_floor, vad_sensitivity);
+			
+			// watch for changes to the VAD settings via Debug Settings UI and act on them accordingly
+			gSavedSettings.getControl("VivoxVadAuto")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
+			gSavedSettings.getControl("VivoxVadHangover")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
+			gSavedSettings.getControl("VivoxVadNoiseFloor")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
+			gSavedSettings.getControl("VivoxVadSensitivity")->getSignal()->connect(boost::bind(&LLVivoxVoiceClient::onVADSettingsChange, this));
+
             if (mTuningMode)
             {
                 performMicTuning();
@@ -953,10 +969,15 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
 
     llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
 
-    while (!mPump)
-    {   // Can't do this until we have the pump available.
+    while (!mPump && !sShuttingDown)
+    {   // Can't use the pump until we have it available.
         llcoro::suspend();
     }
+
+    if (sShuttingDown)
+    {
+        return false;
+    }
     
     // MBW -- Note to self: pumps and pipes examples in
     //  indra/test/io.cpp
@@ -969,8 +990,10 @@ bool LLVivoxVoiceClient::startAndLaunchDaemon()
     readChain.push_back(LLIOPipe::ptr_t(new LLIOSocketReader(mSocket)));
     readChain.push_back(LLIOPipe::ptr_t(new LLVivoxProtocolParser()));
 
+
     mPump->addChain(readChain, NEVER_CHAIN_EXPIRY_SECS);
 
+
     //---------------------------------------------------------------------
     llcoro::suspendUntilTimeout(UPDATE_THROTTLE_SECONDS);
 
@@ -993,6 +1016,11 @@ bool LLVivoxVoiceClient::provisionVoiceAccount()
         // *TODO* Pump a message for wake up.
         llcoro::suspend();
     }
+    
+    if (sShuttingDown)
+    {
+        return false;
+    }
 
     std::string url = gAgent.getRegionCapability("ProvisionVoiceAccountRequest");
 
@@ -3217,6 +3245,73 @@ void LLVivoxVoiceClient::sendLocalAudioUpdates()
 	}
 }
 
+/**
+ * Because of the recurring voice cutout issues (SL-15072) we are going to try
+ * to disable the automatic VAD (Voice Activity Detection) and set the associated
+ * parameters directly. We will expose them via Debug Settings and that should
+ * let us iterate on a collection of values that work for us. Hopefully! 
+ *
+ * From the VIVOX Docs:
+ *
+ * VadAuto: A flag indicating if the automatic VAD is enabled (1) or disabled (0)
+ *
+ * VadHangover: The time (in milliseconds) that it takes
+ * for the VAD to switch back to silence from speech mode after the last speech
+ * frame has been detected.
+ *
+ * VadNoiseFloor: A dimensionless value between 0 and 
+ * 20000 (default 576) that controls the maximum level at which the noise floor
+ * may be set at by the VAD's noise tracking. Too low of a value will make noise
+ * tracking ineffective (A value of 0 disables noise tracking and the VAD then 
+ * relies purely on the sensitivity property). Too high of a value will make 
+ * long speech classifiable as noise.
+ *
+ * VadSensitivity: A dimensionless value between 0 and 
+ * 100, indicating the 'sensitivity of the VAD'. Increasing this value corresponds
+ * to decreasing the sensitivity of the VAD (i.e. '0' is most sensitive, 
+ * while 100 is 'least sensitive')
+ */
+void LLVivoxVoiceClient::setupVADParams(unsigned int vad_auto,
+                                        unsigned int vad_hangover,
+                                        unsigned int vad_noise_floor,
+                                        unsigned int vad_sensitivity)
+{
+    std::ostringstream stream;
+
+    LL_INFOS("Voice") << "Setting the automatic VAD to "
+        << (vad_auto ? "True" : "False")
+		<< " and discrete values to"
+		<< " VadHangover = " << vad_hangover
+		<< ", VadSensitivity = " << vad_sensitivity
+		<< ", VadNoiseFloor = " << vad_noise_floor
+        << LL_ENDL;
+
+	// Create a request to set the VAD parameters:
+	stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Aux.SetVadProperties.1\">"
+               << "<VadAuto>" << vad_auto << "</VadAuto>"
+               << "<VadHangover>" << vad_hangover << "</VadHangover>"
+               << "<VadSensitivity>" << vad_sensitivity << "</VadSensitivity>"
+               << "<VadNoiseFloor>" << vad_noise_floor << "</VadNoiseFloor>"
+           << "</Request>\n\n\n";
+
+    if (!stream.str().empty())
+    {
+        writeString(stream.str());
+    }
+}
+
+void LLVivoxVoiceClient::onVADSettingsChange()
+{
+	// pick up the VAD variables (one of which was changed)
+	unsigned int vad_auto = gSavedSettings.getU32("VivoxVadAuto");
+	unsigned int vad_hangover = gSavedSettings.getU32("VivoxVadHangover");
+	unsigned int vad_noise_floor = gSavedSettings.getU32("VivoxVadNoiseFloor");
+	unsigned int vad_sensitivity = gSavedSettings.getU32("VivoxVadSensitivity");
+
+	// build a VAD params change request and send it to SLVoice
+	setupVADParams(vad_auto, vad_hangover, vad_noise_floor, vad_sensitivity);
+}
+
 /////////////////////////////
 // Response/Event handlers
 
@@ -7569,6 +7664,18 @@ void LLVivoxProtocolParser::processResponse(std::string tag)
 		{
 			LLVivoxVoiceClient::getInstance()->accountGetTemplateFontsResponse(statusCode, statusString);
 		}
+		else if (!stricmp(actionCstr, "Aux.SetVadProperties.1"))
+		{
+			// both values of statusCode (old and more recent) indicate valid requests
+			if (statusCode != 0 && statusCode != 200)
+			{
+				LL_WARNS("Voice") << "Aux.SetVadProperties.1 request failed: "
+					<< "statusCode: " << statusCode
+					<< " and "
+					<< "statusString: " << statusString
+					<< LL_ENDL;
+			}
+		}
 		/*
 		 else if (!stricmp(actionCstr, "Account.ChannelGetList.1"))
 		 {
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 699c85066bcd9ff6db96e7eab976483d1adab3d6..746201af04abb4d0d15c01a6442b4e0ef1de4c08 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -472,6 +472,12 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 	
 	void muteListChanged();
 		
+	/////////////////////////////
+	// VAD changes
+	// disable auto-VAD and configure VAD parameters explicitly
+	void setupVADParams(unsigned int vad_auto, unsigned int vad_hangover, unsigned int vad_noise_floor, unsigned int vad_sensitivity);
+	void onVADSettingsChange();
+
 	/////////////////////////////
 	// Sending updates of current state
 	void updatePosition(void);
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 2037aca7e97d5d2ba5b03e07cfde9c94e412ef95..878d7287ede083fa1b371d42f9934da2343b6a7d 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -209,14 +209,7 @@ void LLSkyTex::create()
 
 void LLSkyTex::createGLImage(S32 which)
 {	
-    if (mIsShiny)
-    {
-        mTexture[which]->setExplicitFormat(GL_RGBA8, GL_RGBA);
-    }
-    else
-    {
-        mTexture[which]->setExplicitFormat(GL_SRGB8_ALPHA8, GL_RGBA);
-    }
+	mTexture[which]->setExplicitFormat(GL_RGBA8, GL_RGBA);
 	mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL);
 	mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
 }
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 8e46ccd555d866fc246536b5ad2aace5b3411635..41099cb5700dbc61e3830ab9e1dbf9e794a92c11 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -45,6 +45,8 @@
 #include "llviewertexturelist.h"
 #include "llviewerobjectlist.h"
 #include "llviewerregion.h"
+#include "llvolumemgr.h"
+#include "llvovolume.h"
 #include "llworld.h"
 #include "noise.h"
 #include "pipeline.h"
@@ -85,6 +87,9 @@ LLVOTree::LLVOTree(const LLUUID &id, const LLPCode pcode, LLViewerRegion *region
 	mFrameCount = 0;
 	mWind = mRegionp->mWind.getVelocity(getPositionRegion());
 	mTrunkLOD = 0;
+
+	// if assert triggers, idleUpdate() needs to be revised and adjusted to new LOD levels
+	llassert(sMAX_NUM_TREE_LOD_LEVELS == LLVolumeLODGroup::NUM_LODS);
 }
 
 
@@ -347,8 +352,11 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time)
 		return;
 	}
 	
-	S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ;
+	S32 trunk_LOD = sMAX_NUM_TREE_LOD_LEVELS ; // disabled
 	F32 app_angle = getAppAngle()*LLVOTree::sTreeFactor;
+	F32 distance = mDrawable->mDistanceWRTCamera * LLVOVolume::sDistanceFactor * (F_PI / 3.f);
+	F32 diameter = getScale().length(); // trees have very broken scale, but length rougtly outlines proper diameter
+	F32 sz = mBillboardScale * mBillboardRatio * diameter;
 
 	for (S32 j = 0; j < sMAX_NUM_TREE_LOD_LEVELS; j++)
 	{
@@ -357,7 +365,14 @@ void LLVOTree::idleUpdate(LLAgent &agent, const F64 &time)
 			trunk_LOD = j;
 			break;
 		}
-	} 
+	}
+
+    F32 tan_angle = (LLVOTree::sTreeFactor * 64 * sz) / distance;
+    S32 cur_detail = LLVolumeLODGroup::getDetailFromTan(ll_round(tan_angle, 0.01f)); // larger value, better quality
+
+    // for trunk_LOD lower value means better quality, but both trunk_LOD and cur_detail have 4 levels
+    trunk_LOD = llmax(trunk_LOD, LLVolumeLODGroup::NUM_LODS - cur_detail - 1);
+    trunk_LOD = llmin(trunk_LOD, sMAX_NUM_TREE_LOD_LEVELS);
 
 	if (mReferenceBuffer.isNull())
 	{
@@ -408,8 +423,9 @@ void LLVOTree::setPixelAreaAndAngle(LLAgent &agent)
 	LLVector3 lookAt = center - viewer_pos_agent;
 	F32 dist = lookAt.normVec() ;	
 	F32 cos_angle_to_view_dir = lookAt * LLViewerCamera::getInstance()->getXAxis() ;	
-	
-	F32 range = dist - getMinScale()/2;
+	F32 radius = getScale().length()*0.5f;
+	F32 range = dist - radius;
+
 	if (range < F_ALMOST_ZERO || isHUDAttachment())		// range == zero
 	{
 		mAppAngle = 180.f;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 50fc4ee951a584541180d46af7a82eb7b8f29dfa..4898fbf2337a0375b2fbddcbfa48dceb462345c6 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -2341,8 +2341,7 @@ bool LLVOVolume::notifyAboutCreatingTexture(LLViewerTexture *texture)
 	//setup new materials
 	for(map_te_material::const_iterator it = new_material.begin(), end = new_material.end(); it != end; ++it)
 	{
-		// These are placeholder materials, they shouldn't be sent to server
-		LLMaterialMgr::getInstance()->setLocalMaterial(getRegion()->getRegionID(), it->second);
+		LLMaterialMgr::getInstance()->put(getID(), it->first, *it->second);
 		LLViewerObject::setTEMaterialParams(it->first, it->second);
 	}
 
diff --git a/indra/newview/llwindowlistener.cpp b/indra/newview/llwindowlistener.cpp
index 9e4297baafc13a903d8ae97dc6436cd11d8aed51..aa8c79b0d280a89e6cb30860017f94c18cc854aa 100644
--- a/indra/newview/llwindowlistener.cpp
+++ b/indra/newview/llwindowlistener.cpp
@@ -37,7 +37,7 @@
 #include "llview.h"
 #include "llviewinject.h"
 #include "llviewerwindow.h"
-#include "llviewerkeyboard.h"
+#include "llviewerinput.h"
 #include "llrootview.h"
 #include "llsdutil.h"
 #include "stringize.h"
@@ -279,7 +279,7 @@ void LLWindowListener::keyDown(LLSD const & evt)
 			response.setResponse(target_view->getInfo());
 			
 			gFocusMgr.setKeyboardFocus(target_view);
-			gViewerKeyboard.handleKey(key, mask, false);
+			gViewerInput.handleKey(key, mask, false);
 			if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
 		}
 		else 
@@ -291,7 +291,7 @@ void LLWindowListener::keyDown(LLSD const & evt)
 	}
 	else 
 	{
-		gViewerKeyboard.handleKey(key, mask, false); 
+		gViewerInput.handleKey(key, mask, false); 
 		if(key < 0x80) mWindow->handleUnicodeChar(key, mask);
 	}
 }
diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp
index a2e519a61aa14057f5f29c24df900fc5e5fc76bb..040d0deaf351e237428b51f00c539f07a19f282c 100644
--- a/indra/newview/llworldmipmap.cpp
+++ b/indra/newview/llworldmipmap.cpp
@@ -190,6 +190,8 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32
 	//LL_INFOS("WorldMap") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL;
 
 	LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	LL_INFOS("MAPURL") << "fetching map tile from " << imageurl << LL_ENDL;
+
 	img->setBoostLevel(LLGLTexture::BOOST_MAP);
 
 	// Return the smart pointer
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 7e63a20beee81e57bfefa0018f480e724600af86..514effe3e12f66a4858919e91cda7ce19bd88876 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -134,6 +134,16 @@
 //
 #define MATERIALS_IN_REFLECTIONS 0
 
+// NOTE: Keep in sync with indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+// NOTE: Unused consts are commented out since some compilers (on macOS) may complain about unused variables.
+//  const S32 WATER_REFLECT_NONE_WATER_OPAQUE       = -2;
+    const S32 WATER_REFLECT_NONE_WATER_TRANSPARENT  = -1;
+    const S32 WATER_REFLECT_MINIMAL                 =  0;
+//  const S32 WATER_REFLECT_TERRAIN                 =  1;
+    const S32 WATER_REFLECT_STATIC_OBJECTS          =  2;
+    const S32 WATER_REFLECT_AVATARS                 =  3;
+    const S32 WATER_REFLECT_EVERYTHING              =  4;
+
 bool gShiftFrame = false;
 
 //cached settings
@@ -356,7 +366,6 @@ bool	LLPipeline::sRenderFrameTest = false;
 bool	LLPipeline::sRenderAttachedLights = true;
 bool	LLPipeline::sRenderAttachedParticles = true;
 bool	LLPipeline::sRenderDeferred = false;
-bool    LLPipeline::sMemAllocationThrottled = false;
 S32		LLPipeline::sVisibleLightCount = 0;
 F32		LLPipeline::sMinRenderSize = 0.f;
 bool	LLPipeline::sRenderingHUDs;
@@ -735,24 +744,6 @@ void LLPipeline::destroyGL()
 
 static LLTrace::BlockTimerStatHandle FTM_RESIZE_SCREEN_TEXTURE("Resize Screen Texture");
 
-//static
-void LLPipeline::throttleNewMemoryAllocation(bool disable)
-{
-	if(sMemAllocationThrottled != disable)
-	{
-		sMemAllocationThrottled = disable ;
-
-		if(sMemAllocationThrottled)
-		{
-			//send out notification
-			LLNotification::Params params("LowMemory");
-			LLNotifications::instance().add(params);
-
-			//release some memory.
-		}
-	}
-}
-
 void LLPipeline::requestResizeScreenTexture()
 {
     gResizeScreenTexture = TRUE;
@@ -3152,9 +3143,10 @@ void LLPipeline::markVisible(LLDrawable *drawablep, LLCamera& camera)
 					if (vobj) // this test may not be needed, see above
 					{
 						LLVOAvatar* av = vobj->asAvatar();
-						if (av && (av->isImpostor() 
-							|| av->isInMuteList() 
-							|| (LLVOAvatar::AV_DO_NOT_RENDER == av->getVisualMuteSettings() && !av->needsImpostorUpdate()) ))
+						if (av &&
+							((!sImpostorRender && av->isImpostor()) //ignore impostor flag during impostor pass
+							 || av->isInMuteList() 
+							 || (LLVOAvatar::AOA_JELLYDOLL == av->getOverallAppearance() && !av->needsImpostorUpdate()) ))
 						{
 							return;
 						}
@@ -9420,30 +9412,29 @@ inline float sgn(float a)
 }
 
 void LLPipeline::generateWaterReflection(LLCamera& camera_in)
-{	
-	if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
-	{
-		bool skip_avatar_update = false;
-		if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
-		{
-			skip_avatar_update = true;
-		}
-		
-        LLCamera camera = camera_in;
+{
+    if (LLPipeline::sWaterReflections && assertInitialized() && LLDrawPoolWater::sNeedsReflectionUpdate)
+    {
+        bool skip_avatar_update = false;
+        if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson)
+        {
+            skip_avatar_update = true;
+        }
 
+        LLCamera camera = camera_in;
         camera.setFar(camera_in.getFar() * 0.75f);
 
         bool camera_is_underwater = LLViewerCamera::getInstance()->cameraUnderWater();
 
-		LLPipeline::sReflectionRender = true;
-		
-		gPipeline.pushRenderTypeMask();
+        LLPipeline::sReflectionRender = true;
+
+        gPipeline.pushRenderTypeMask();
 
         glh::matrix4f saved_modelview  = get_current_modelview();
         glh::matrix4f saved_projection = get_current_projection();
-		glh::matrix4f mat;
+        glh::matrix4f mat;
 
-        S32 detail = RenderReflectionDetail;
+        S32 reflection_detail  = RenderReflectionDetail;
 
         F32 water_height      = gAgent.getRegion()->getWaterHeight(); 
         F32 camera_height     = camera_in.getOrigin().mV[VZ];
@@ -9457,32 +9448,34 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 
         camera.setOriginAndLookAt(reflect_origin, LLVector3::z_axis, reflect_interest_point);
 
-		//plane params
+        //plane params
         LLPlane plane;
-		LLVector3 pnorm;
-		S32 water_clip = 0;
+        LLVector3 pnorm;
+        S32 water_clip = 0;
         if (!camera_is_underwater)
-		{ //camera is above water, clip plane points up
-			pnorm.setVec(0,0,1);
+        {
+            //camera is above water, clip plane points up
+            pnorm.setVec(0,0,1);
             plane.setVec(pnorm, -water_height);
             water_clip = 1;
-		}
-		else
-		{	//camera is below water, clip plane points down
-			pnorm = LLVector3(0,0,-1);
+        }
+        else
+        {
+            //camera is below water, clip plane points down
+            pnorm = LLVector3(0,0,-1);
             plane.setVec(pnorm, water_height);
             water_clip = -1;
-		}
+        }
 
         S32 occlusion = LLPipeline::sUseOcclusion;
 
-			//disable occlusion culling for reflection map for now
-			LLPipeline::sUseOcclusion = 0;
+        //disable occlusion culling for reflection map for now
+        LLPipeline::sUseOcclusion = 0;
 
         if (!camera_is_underwater)
-        {   //generate planar reflection map
-
-			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
+        {
+            //generate planar reflection map
+            LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER0;
 
             gGL.matrixMode(LLRender::MM_MODELVIEW);
             gGL.pushMatrix();
@@ -9495,9 +9488,9 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
             mReflectionModelView = mat;
 
             set_current_modelview(mat);
-			gGL.loadMatrix(mat.m);
+            gGL.loadMatrix(mat.m);
 
-			LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
+            LLViewerCamera::updateFrustumPlanes(camera, FALSE, TRUE);
 
             glh::vec3f    origin(0, 0, 0);
             glh::matrix4f inv_mat = mat.inverse();
@@ -9505,10 +9498,10 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
 
             camera.setOrigin(origin.v);
 
-			glCullFace(GL_FRONT);
+            glCullFace(GL_FRONT);
 
-			if (LLDrawPoolWater::sNeedsReflectionUpdate)
-			{
+            if (LLDrawPoolWater::sNeedsReflectionUpdate)
+            {
                 gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
                 glClearColor(0,0,0,0);
                 mWaterRef.bindTarget();
@@ -9518,106 +9511,127 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
                 gGL.setColorMask(true, false);
                 mWaterRef.getViewport(gGLViewport);
 
-				//initial sky pass (no user clip plane)
-				{ //mask out everything but the sky
-					gPipeline.pushRenderTypeMask();
-					gPipeline.andRenderTypeMask(LLPipeline::RENDER_TYPE_SKY,
-						LLPipeline::RENDER_TYPE_WL_SKY,
-						LLPipeline::RENDER_TYPE_CLOUDS,
-						LLPipeline::END_RENDER_TYPES);
+                //initial sky pass (no user clip plane)
+                //mask out everything but the sky
+                gPipeline.pushRenderTypeMask();
+                {
+                    if (reflection_detail >= WATER_REFLECT_MINIMAL)
+                    {
+                        gPipeline.andRenderTypeMask(
+                            LLPipeline::RENDER_TYPE_SKY,
+                            LLPipeline::RENDER_TYPE_WL_SKY,
+                            LLPipeline::RENDER_TYPE_CLOUDS,
+                            LLPipeline::END_RENDER_TYPES);
+                    }
+                    else
+                    {
+                        gPipeline.andRenderTypeMask(
+                            LLPipeline::RENDER_TYPE_SKY,
+                            LLPipeline::RENDER_TYPE_WL_SKY,
+                            LLPipeline::END_RENDER_TYPES);
+                    }
 
                     updateCull(camera, mSky);
                     stateSort(camera, mSky);
-						renderGeom(camera, TRUE);
-
-					gPipeline.popRenderTypeMask();
-				}
+                    renderGeom(camera, TRUE);
+                }
+                gPipeline.popRenderTypeMask();
 
-				gPipeline.pushRenderTypeMask();
+                if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
+                {
+                    gPipeline.pushRenderTypeMask();
+                    {
+                        clearRenderTypeMask(
+                            LLPipeline::RENDER_TYPE_WATER,
+                            LLPipeline::RENDER_TYPE_VOIDWATER,
+                            LLPipeline::RENDER_TYPE_GROUND,
+                            LLPipeline::RENDER_TYPE_SKY,
+                            LLPipeline::RENDER_TYPE_CLOUDS,
+                            LLPipeline::END_RENDER_TYPES);
+
+                        if (reflection_detail > WATER_REFLECT_MINIMAL)
+                        { //mask out selected geometry based on reflection detail
+                            if (reflection_detail < WATER_REFLECT_EVERYTHING)
+                            {
+                                clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
+                                if (reflection_detail < WATER_REFLECT_AVATARS)
+                                {
+                                    clearRenderTypeMask(
+                                        LLPipeline::RENDER_TYPE_AVATAR,
+                                        LLPipeline::RENDER_TYPE_CONTROL_AV,
+                                        END_RENDER_TYPES);
+                                    if (reflection_detail < WATER_REFLECT_STATIC_OBJECTS)
+                                    {
+                                        clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
+                                    }
+                                }
+                            }
 
-				clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
-					LLPipeline::RENDER_TYPE_VOIDWATER,
-					LLPipeline::RENDER_TYPE_GROUND,
-					LLPipeline::RENDER_TYPE_SKY,
-					LLPipeline::RENDER_TYPE_CLOUDS,
-					LLPipeline::END_RENDER_TYPES);	
-
-				if (detail > 0)
-				{ //mask out selected geometry based on reflection detail
-					if (detail < 4)
-					{
-						clearRenderTypeMask(LLPipeline::RENDER_TYPE_PARTICLES, END_RENDER_TYPES);
-						if (detail < 3)
-						{
-                            clearRenderTypeMask(LLPipeline::RENDER_TYPE_AVATAR, LLPipeline::RENDER_TYPE_CONTROL_AV, END_RENDER_TYPES);
-							if (detail < 2)
-							{
-								clearRenderTypeMask(LLPipeline::RENDER_TYPE_VOLUME, END_RENDER_TYPES);
-							}
-						}
-					}
+                            LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection);
+                            LLGLDisable cull(GL_CULL_FACE);
+                            updateCull(camera, mReflectedObjects, -water_clip, &plane);
+                            stateSort(camera, mReflectedObjects);
+                            renderGeom(camera);
+                        }
+                    }
+                    gPipeline.popRenderTypeMask();
+                }
 
-                    LLGLUserClipPlane clip_plane(plane, mReflectionModelView, saved_projection);
-					LLGLDisable cull(GL_CULL_FACE);
-                    updateCull(camera, mReflectedObjects, -water_clip, &plane);
-                    stateSort(camera, mReflectedObjects);
-							renderGeom(camera);
-						}
-                gPipeline.popRenderTypeMask();
                 mWaterRef.flush();
-				}
+            }
 
-			glCullFace(GL_BACK);
+            glCullFace(GL_BACK);
             gGL.matrixMode(LLRender::MM_MODELVIEW);
-			gGL.popMatrix();
-            
+            gGL.popMatrix();
+
             set_current_modelview(saved_modelview);
-		}
+        }
 
         //LLPipeline::sUseOcclusion = occlusion;
 
-		camera.setOrigin(camera_in.getOrigin());
-		//render distortion map
-		static bool last_update = true;
-		if (last_update)
-		{
+        camera.setOrigin(camera_in.getOrigin());
+        //render distortion map
+        static bool last_update = true;
+        if (last_update)
+        {
             gPipeline.pushRenderTypeMask();
 
-			camera.setFar(camera_in.getFar());
-			clearRenderTypeMask(LLPipeline::RENDER_TYPE_WATER,
-								LLPipeline::RENDER_TYPE_VOIDWATER,
-								LLPipeline::RENDER_TYPE_GROUND,
-								END_RENDER_TYPES);	
+            camera.setFar(camera_in.getFar());
+            clearRenderTypeMask(
+                LLPipeline::RENDER_TYPE_WATER,
+                LLPipeline::RENDER_TYPE_VOIDWATER,
+                LLPipeline::RENDER_TYPE_GROUND,
+                END_RENDER_TYPES);
 
             // intentionally inverted so that distortion map contents (objects under the water when we're above it)
             // will properly include water fog effects
             LLPipeline::sUnderWaterRender = !camera_is_underwater;
 
-			if (LLPipeline::sUnderWaterRender)
-			{
+            if (LLPipeline::sUnderWaterRender)
+            {
                 clearRenderTypeMask(
-                                    LLPipeline::RENDER_TYPE_GROUND,
-									LLPipeline::RENDER_TYPE_SKY,
-									LLPipeline::RENDER_TYPE_CLOUDS,
-									LLPipeline::RENDER_TYPE_WL_SKY,
-									END_RENDER_TYPES);		
-			}
-			LLViewerCamera::updateFrustumPlanes(camera);
+                    LLPipeline::RENDER_TYPE_GROUND,
+                    LLPipeline::RENDER_TYPE_SKY,
+                    LLPipeline::RENDER_TYPE_CLOUDS,
+                    LLPipeline::RENDER_TYPE_WL_SKY,
+                    END_RENDER_TYPES);
+            }
+            LLViewerCamera::updateFrustumPlanes(camera);
+
+            gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
-			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-			
             if (LLPipeline::sUnderWaterRender || LLDrawPoolWater::sNeedsDistortionUpdate)
             {
                 LLPipeline::sDistortionRender = true;
 
                 LLColor3 col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
-			glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
+                glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
+
+                LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
 
-			LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
-			
                 mWaterDis.bindTarget();
-			mWaterDis.getViewport(gGLViewport);
-			
+                mWaterDis.getViewport(gGLViewport);
+
                 gGL.setColorMask(true, true);
                 mWaterDis.clear();
                 gGL.setColorMask(true, false);
@@ -9629,66 +9643,69 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
                 LLPlane plane(-pnorm, water_dist);
                 LLGLUserClipPlane clip_plane(plane, saved_modelview, saved_projection);
 
-				gGL.setColorMask(true, true);
-				mWaterDis.clear();
-				gGL.setColorMask(true, false);
+                gGL.setColorMask(true, true);
+                mWaterDis.clear();
+                gGL.setColorMask(true, false);
 
                 // ignore clip plane if we're underwater and viewing distortion map of objects above waterline
                 if (camera_is_underwater)
-				{
+                {
                     clip_plane.disable();
-				}
+                }
 
-                updateCull(camera, mRefractedObjects, water_clip, &plane);
-                stateSort(camera, mRefractedObjects);
-					renderGeom(camera);
+                if (reflection_detail >= WATER_REFLECT_NONE_WATER_TRANSPARENT)
+                {
+                    updateCull(camera, mRefractedObjects, water_clip, &plane);
+                    stateSort(camera, mRefractedObjects);
+                    renderGeom(camera);
+                }
 
-					if (LLGLSLShader::sNoFixedFunction)
-					{
-						gUIProgram.bind();
-					}
-					
-					LLWorld::getInstance()->renderPropertyLines();
-					
-					if (LLGLSLShader::sNoFixedFunction)
-					{
-						gUIProgram.unbind();
-					}
+                if (LLGLSLShader::sNoFixedFunction)
+                {
+                    gUIProgram.bind();
+                }
+
+                LLWorld::getInstance()->renderPropertyLines();
+
+                if (LLGLSLShader::sNoFixedFunction)
+                {
+                    gUIProgram.unbind();
+                }
 
                 mWaterDis.flush();
-			}
+            }
 
             LLPipeline::sDistortionRender = false;
-			
+
             gPipeline.popRenderTypeMask();
-		}
-		last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
+        }
+        last_update = LLDrawPoolWater::sNeedsReflectionUpdate && LLDrawPoolWater::sNeedsDistortionUpdate;
 
         gPipeline.popRenderTypeMask();
 
         LLPipeline::sUseOcclusion     = occlusion;
         LLPipeline::sUnderWaterRender = false;
-		LLPipeline::sReflectionRender = false;
+        LLPipeline::sReflectionRender = false;
 
         LLDrawPoolWater::sNeedsReflectionUpdate = FALSE;
         LLDrawPoolWater::sNeedsDistortionUpdate = FALSE;
 
-		if (!LLRenderTarget::sUseFBO)
-		{
-			glClear(GL_DEPTH_BUFFER_BIT);
-		}
-		glClearColor(0.f, 0.f, 0.f, 0.f);
-		gViewerWindow->setup3DViewport();
-		
-		LLGLState::checkStates();
+        if (!LLRenderTarget::sUseFBO)
+        {
+            glClear(GL_DEPTH_BUFFER_BIT);
+        }
+        glClearColor(0.f, 0.f, 0.f, 0.f);
+        gViewerWindow->setup3DViewport();
 
-		if (!skip_avatar_update)
-		{
-			gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
-		}
+        LLGLState::checkStates();
 
-		LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
-	}
+        if (!skip_avatar_update)
+        {
+            gAgentAvatarp->updateAttachmentVisibility(gAgentCamera.getCameraMode());
+        }
+
+        LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
+    }
 }
 
 glh::matrix4f look(const LLVector3 pos, const LLVector3 dir, const LLVector3 up)
@@ -11104,7 +11121,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 	{
 		LL_RECORD_BLOCK_TIME(FTM_IMPOSTOR_MARK_VISIBLE);
 		markVisible(avatar->mDrawable, *viewer_camera);
-		LLVOAvatar::sUseImpostors = false; // @TODO ???
 
 		LLVOAvatar::attachment_map_t::iterator iter;
 		for (iter = avatar->mAttachmentPoints.begin();
@@ -11344,7 +11360,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar)
 
 	avatar->setImpostorDim(tdim);
 
-	LLVOAvatar::sUseImpostors = (0 != LLVOAvatar::sMaxNonImpostors);
 	sUseOcclusion = occlusion;
 	sReflectionRender = false;
 	sImpostorRender = false;
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 0dbb65e66c34926c9421339871969ebe147846f6..4d996384aa6d6eb15b9293eab8c19269d9c2e308 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -414,10 +414,6 @@ class LLPipeline
 	static void updateRenderDeferred();
 	static void refreshCachedSettings();
 
-	static void throttleNewMemoryAllocation(bool disable);
-
-	
-
 	void addDebugBlip(const LLVector3& position, const LLColor4& color);
 
 	void hidePermanentObjects( std::vector<U32>& restoreList );
@@ -600,7 +596,6 @@ class LLPipeline
 	static bool				sRenderAttachedLights;
 	static bool				sRenderAttachedParticles;
 	static bool				sRenderDeferred;
-	static bool             sMemAllocationThrottled;
 	static S32				sVisibleLightCount;
 	static F32				sMinRenderSize;
 	static bool				sRenderingHUDs;
diff --git a/indra/newview/rlvcommon.cpp b/indra/newview/rlvcommon.cpp
index 0c9304962391f641efb3132df72cf50ab9240ac3..581002e631e05267ffa7a87a8c7700d63e59721b 100644
--- a/indra/newview/rlvcommon.cpp
+++ b/indra/newview/rlvcommon.cpp
@@ -279,6 +279,23 @@ void RlvStrings::initClass()
 	}
 }
 
+// Used to provide fallback behaviour whenever we rename/split/join customizable string values
+LLSD& RlvStrings::cleanStringValues(LLSD& sdStringValues)
+{
+	LLSD sdValues(sdStringValues);
+	for (LLSD::map_const_iterator itString = sdValues.beginMap(); itString != sdValues.endMap(); ++itString)
+	{
+		if (itString->first == "blocked_tplurerequest_remote")
+		{
+			sdStringValues.erase("blocked_tplurerequest_remote");
+			sdStringValues[RlvStringKeys::Blocked::TpLureRemote] = itString->second;
+			sdStringValues[RlvStringKeys::Blocked::TpRequestRemote] = itString->second;
+		}
+	}
+
+	return sdStringValues;
+}
+
 // Checked: 2011-11-08 (RLVa-1.5.0)
 void RlvStrings::loadFromFile(const std::string& strFilePath, bool fUserOverride)
 {
@@ -289,7 +306,7 @@ void RlvStrings::loadFromFile(const std::string& strFilePath, bool fUserOverride
 
 	if (sdFileData.has("strings"))
 	{
-		const LLSD& sdStrings = sdFileData["strings"];
+		const LLSD sdStrings = (!fUserOverride) ? sdFileData["strings"] : cleanStringValues(sdFileData["strings"]);
 		for (LLSD::map_const_iterator itString = sdStrings.beginMap(); itString != sdStrings.endMap(); ++itString)
 		{
 			if ( (!itString->second.has("value")) || ((fUserOverride) && (!hasString(itString->first))) )
diff --git a/indra/newview/rlvcommon.h b/indra/newview/rlvcommon.h
index 008e4d6fa4553076f3383a914c13b07a8b5db450..666d036e4de96fd82e7acce9539a58ae3a74e2eb 100644
--- a/indra/newview/rlvcommon.h
+++ b/indra/newview/rlvcommon.h
@@ -148,6 +148,7 @@ class RlvStrings
 {
 public:
 	static void initClass();
+	static LLSD& cleanStringValues(LLSD& sdValues);
 	static void loadFromFile(const std::string& strFilePath, bool fDefault);
 	static void saveToFile(const std::string& strFilePath);
 
diff --git a/indra/newview/rlvdefines.h b/indra/newview/rlvdefines.h
index b560f30e7f33e535a5eaf81c025ed4160fc3261b..eba82af225f7d0bb10f63f133d59c263c938bf23 100644
--- a/indra/newview/rlvdefines.h
+++ b/indra/newview/rlvdefines.h
@@ -469,28 +469,30 @@ namespace RlvStringKeys
 		/*inline*/ constexpr boost::string_view StartIm = make_string_view("blocked_startim");
 		/*inline*/ constexpr boost::string_view Teleport = make_string_view("blocked_teleport");
 		/*inline*/ constexpr boost::string_view TeleportOffer = make_string_view("blocked_teleport_offer");
-		/*inline*/ constexpr boost::string_view TpLureRequestRemote = make_string_view("blocked_tplurerequest_remote");
+		/*inline*/ constexpr boost::string_view TpLureRemote = make_string_view("blocked_tplure_remote");
+		/*inline*/ constexpr boost::string_view TpRequestRemote = make_string_view("blocked_tprequest_remote");
 		/*inline*/ constexpr boost::string_view ViewXxx = make_string_view("blocked_viewxxx");
 		/*inline*/ constexpr boost::string_view Wireframe = make_string_view("blocked_wireframe");
 #else
-		constexpr const char AutoPilot[] = "blocked_autopilot";
-		constexpr const char Generic[] = "blocked_generic";
-		constexpr const char GroupChange[] = "blocked_groupchange";
-		constexpr const char InvFolder[] = "blocked_invfolder";
-		constexpr const char PermissionAttach[] = "blocked_permattach";
-		constexpr const char PermissionTeleport[] = "blocked_permteleport";
-		constexpr const char RecvIm[] = "blocked_recvim";
-		constexpr const char RecvImRemote[] = "blocked_recvim_remote";
-		constexpr const char SendIm[] = "blocked_sendim";
-		constexpr const char Share[] = "blocked_share";
-		constexpr const char ShareGeneric[] = "blocked_share_generic";
-		constexpr const char StartConference[] = "blocked_startconf";
-		constexpr const char StartIm[] = "blocked_startim";
-		constexpr const char Teleport[] = "blocked_teleport";
-		constexpr const char TeleportOffer[] = "blocked_teleport_offer";
-		constexpr const char TpLureRequestRemote[] = "blocked_tplurerequest_remote";
-		constexpr const char ViewXxx[] = "blocked_viewxxx";
-		constexpr const char Wireframe[] = "blocked_wireframe";
+		static constexpr const char AutoPilot[] = "blocked_autopilot";
+		static constexpr const char Generic[] = "blocked_generic";
+		static constexpr const char GroupChange[] = "blocked_groupchange";
+		static constexpr const char InvFolder[] = "blocked_invfolder";
+		static constexpr const char PermissionAttach[] = "blocked_permattach";
+		static constexpr const char PermissionTeleport[] = "blocked_permteleport";
+		static constexpr const char RecvIm[] = "blocked_recvim";
+		static constexpr const char RecvImRemote[] = "blocked_recvim_remote";
+		static constexpr const char SendIm[] = "blocked_sendim";
+		static constexpr const char Share[] = "blocked_share";
+		static constexpr const char ShareGeneric[] = "blocked_share_generic";
+		static constexpr const char StartConference[] = "blocked_startconf";
+		static constexpr const char StartIm[] = "blocked_startim";
+		static constexpr const char Teleport[] = "blocked_teleport";
+		static constexpr const char TeleportOffer[] = "blocked_teleport_offer";
+		static constexpr const char TpLureRemote[] = "blocked_tplure_remote";
+		static constexpr const char TpRequestRemote[] = "blocked_tprequest_remote";
+		static constexpr const char ViewXxx[] = "blocked_viewxxx";
+		static constexpr const char Wireframe[] = "blocked_wireframe";
 #endif // CATZNIP_STRINGVIEW
 	}
 
diff --git a/indra/newview/rlvhandler.cpp b/indra/newview/rlvhandler.cpp
index 14d87389148d7a25903eaf227f99d45bdaea9956..3a7662c0cf67ec2e7ce1dfd5010f40b4f36744b4 100644
--- a/indra/newview/rlvhandler.cpp
+++ b/indra/newview/rlvhandler.cpp
@@ -38,6 +38,7 @@
 #include "llavatarnamecache.h"			// @shownames
 #include "llavatarlist.h"				// @shownames
 #include "llfloatercamera.h"			// @setcam family
+#include "llfloaterimnearbychat.h"		// @shownames
 #include "llfloatersidepanelcontainer.h"// @shownames
 #include "llnotifications.h"			// @list IM query
 #include "llnotificationsutil.h"
@@ -45,6 +46,7 @@
 #include "llpaneloutfitsinventory.h"	// @showinv - "Appearance" floater
 #include "llpanelpeople.h"				// @shownames
 #include "llpanelwearing.h"				// @showinv - "Appearance / Current Outfit" panel
+#include "llparticipantlist.h"			// @shownames
 #include "llregionhandle.h"				// @tpto
 #include "llsidepanelappearance.h"		// @showinv - "Appearance / Edit appearance" panel
 #include "lltabcontainer.h"				// @showinv - Tab container control for inventory tabs
@@ -2435,6 +2437,7 @@ void RlvBehaviourToggleHandler<RLV_BHVR_SETCAM>::onCommandToggle(ERlvBehaviour e
 		RlvBehaviourToggleHandler<RLV_BHVR_SETCAM_UNLOCK>::onCommandToggle(RLV_BHVR_SETCAM_UNLOCK, !fHasCamUnlock);
 
 	gRlvHandler.setCameraOverride(fHasBhvr);
+	RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_AVDIST)->setPrimaryObject(idRlvObject);
 	RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_AVDISTMIN)->setPrimaryObject(idRlvObject);
 	RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_AVDISTMAX)->setPrimaryObject(idRlvObject);
 	RlvBehaviourDictionary::instance().getModifier(RLV_MODIFIER_SETCAM_ORIGINDISTMIN)->setPrimaryObject(idRlvObject);
@@ -2602,6 +2605,15 @@ void RlvBehaviourToggleHandler<RLV_BHVR_SHOWNAMES>::onCommandToggle(ERlvBehaviou
 		pPeoplePanel->getNearbyList()->updateAvatarNames();
 	}
 
+	// Refresh the nearby participant list
+	if (LLFloaterIMNearbyChat* pNearbyChatFloater = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))
+	{
+		if (LLParticipantList* pParticipantList = pNearbyChatFloater->getParticipantList())
+		{
+			pParticipantList->refreshNames();
+		}
+	}
+
 	// Force the use of the "display name" cache so we can filter both display and legacy names (or return back to the user's preference)
 	if (fHasBhvr)
 	{
@@ -2694,6 +2706,17 @@ void RlvBehaviourToggleHandler<RLV_BHVR_SHOWNEARBY>::onCommandToggle(ERlvBehavio
 			pPeoplePanel->updateNearbyList();
 	}
 
+	// Refresh the nearby participant list
+	if (LLFloaterIMNearbyChat* pNearbyChatFloater = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))
+	{
+#ifdef CATZNIP
+		pNearbyChatFloater->updateShowParticipantList();
+		pNearbyChatFloater->updateExpandCollapseBtn();
+#else
+		// *TODO - Solution for CHUI
+#endif // CATZNIP
+	}
+
 	// Refresh that avatar's name tag and all HUD text
 	LLHUDText::refreshAllObjectText();
 }
diff --git a/indra/newview/rlvhelper.cpp b/indra/newview/rlvhelper.cpp
index 212871bbe83a054a0e8145d503dc361e9220a6ed..e6d548753a44b99eb391950d6411d5b709aac964 100644
--- a/indra/newview/rlvhelper.cpp
+++ b/indra/newview/rlvhelper.cpp
@@ -704,6 +704,10 @@ bool RlvBehaviourModifier::convertOptionValue(const std::string& optionValue, co
 	{
 		return false;
 	}
+	catch (const std::out_of_range&)
+	{
+		return false;
+	}
 }
 
 // ============================================================================
@@ -811,6 +815,10 @@ bool RlvCommandOptionHelper::parseOption<int>(const std::string& strOption, int&
 	{
 		return false;
 	}
+	catch (const std::out_of_range&)
+	{
+		return false;
+	}
 	return true;
 }
 
@@ -831,6 +839,10 @@ bool RlvCommandOptionHelper::parseOption<bool>(const std::string& strOption, boo
 		ss >> std::boolalpha >> fOption;
 		return !ss.fail();
 	}
+	catch (const std::out_of_range&)
+	{
+		return false;
+	}
 }
 
 template<>
@@ -844,6 +856,10 @@ bool RlvCommandOptionHelper::parseOption<float>(const std::string& strOption, fl
 	{
 		return false;
 	}
+	catch (const std::out_of_range&)
+	{
+		return false;
+	}
 	return true;
 }
 
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index e1cf7080947717310e2252113363104e9995636d..7beb013fba7ad588b93816c6c80e802d93ef08da 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -336,6 +336,9 @@
     <color
      name="ContextSilhouetteColor"
      reference="EmphasisColor" />
+    <color
+     name="ConversationFriendColor"
+     value="0.42 0.85 0.71 1" />
     <color
      name="DefaultHighlightDark"
      reference="White_10" />
@@ -850,6 +853,9 @@
     <color
     name="ColorSwatchBorderColor"
     value="0.45098 0.517647 0.607843 1"/>
+    <color
+     name="ChatTeleportSeparatorColor"
+     reference="Black" />
     <color
      name="ChatTimestampColor"
      reference="White" />
@@ -960,4 +966,7 @@
   <color
     name="OutfitGalleryItemUnselected"
     value="0.4 0.4 0.4 1" />
+  <color
+    name="AddPaymentPanel"
+    value="0.27 0.27 0.27 1" />
 </colors>
diff --git a/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png b/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png
new file mode 100644
index 0000000000000000000000000000000000000000..048da25c9286bfb85c8d20be17d81e4d81b3df73
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Inv_Toolbar_SearchVisibility.png differ
diff --git a/indra/newview/skins/default/textures/navbar/Landmarks.png b/indra/newview/skins/default/textures/navbar/Landmarks.png
new file mode 100644
index 0000000000000000000000000000000000000000..2b35de913b26974ac8d191de8a0a28be451e63ac
Binary files /dev/null and b/indra/newview/skins/default/textures/navbar/Landmarks.png differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index a875c4e84829c8ba6d450d8f0de848e24c3dc78c..03878d9fe73e187c7f9306cce1c092436c44bc16 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -45,6 +45,10 @@ with the same filename but different name
   <texture name="AddItem_Off" file_name="icons/AddItem_Off.png" preload="false" />
   <texture name="AddItem_Press" file_name="icons/AddItem_Press.png" preload="false" />
 
+  <texture name="add_payment_image_center"  file_name="windows/add_payment_image_center.png" preload="true" />
+  <texture name="add_payment_image_left"  file_name="windows/add_payment_image_left.png" preload="true" />
+  <texture name="add_payment_image_right"  file_name="windows/add_payment_image_right.png" preload="true" />
+
   <texture name="Arrow_Left_Off" file_name="navbar/Arrow_Left_Off.png" preload="true" />
   <texture name="Arrow_Right_Off" file_name="navbar/Arrow_Right_Off.png" preload="true" />
 
@@ -333,7 +337,11 @@ with the same filename but different name
   <texture name="Inv_Unknown" file_name="icons/Inv_UnknownObject.png" preload="false" />
   <texture name="Inv_VersionFolderClosed" file_name="icons/Inv_VersionFolderClosed.png" preload="false" />
   <texture name="Inv_VersionFolderOpen" file_name="icons/Inv_VersionFolderOpen.png" preload="false" />
-  
+
+  <texture name="Inv_Toolbar_SearchVisibility" file_name="icons/Inv_Toolbar_SearchVisibility.png" preload="false" />
+
+  <texture name="Landmarks_overlay" file_name="navbar/Landmarks.png" preload="false" />
+
   <texture name="Linden_Dollar_Alert" file_name="widgets/Linden_Dollar_Alert.png"/>
   <texture name="Linden_Dollar_Background" file_name="widgets/Linden_Dollar_Background.png"/>
 
@@ -649,6 +657,7 @@ with the same filename but different name
   <texture name="TextField_Search_Off" file_name="widgets/TextField_Search_Off.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
   <texture name="TextField_Disabled" file_name="widgets/TextField_Disabled.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
   <texture name="TextField_Active" file_name="widgets/TextField_Active.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
+  <texture name="TextField_Search_Highlight" file_name="widgets/TextField_Search_Highlight.png" preload="true" scale.left="9" scale.top="12" scale.right="248" scale.bottom="12" />
 
 
   <texture name="Toast_CloseBtn" file_name="windows/Toast_CloseBtn.png" preload="true" />
diff --git a/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png b/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png
new file mode 100644
index 0000000000000000000000000000000000000000..e3944289c6f865ad4a4f57223bba9bd8ef43219d
Binary files /dev/null and b/indra/newview/skins/default/textures/widgets/TextField_Search_Highlight.png differ
diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_center.png b/indra/newview/skins/default/textures/windows/add_payment_image_center.png
new file mode 100644
index 0000000000000000000000000000000000000000..b5459136cb7a8e1d54a1b3156d2f4c6a3475f1da
Binary files /dev/null and b/indra/newview/skins/default/textures/windows/add_payment_image_center.png differ
diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_left.png b/indra/newview/skins/default/textures/windows/add_payment_image_left.png
new file mode 100644
index 0000000000000000000000000000000000000000..7fb65e724a07f8daf4b79d7c619d59d480252064
Binary files /dev/null and b/indra/newview/skins/default/textures/windows/add_payment_image_left.png differ
diff --git a/indra/newview/skins/default/textures/windows/add_payment_image_right.png b/indra/newview/skins/default/textures/windows/add_payment_image_right.png
new file mode 100644
index 0000000000000000000000000000000000000000..f1937b6318022af9bafb10ab9c12a29d92a0a260
Binary files /dev/null and b/indra/newview/skins/default/textures/windows/add_payment_image_right.png differ
diff --git a/indra/newview/skins/default/textures/windows/first_login_image_left.png b/indra/newview/skins/default/textures/windows/first_login_image_left.png
index 1fa10fde532d08bd105bea355a4bbf233039c86a..77904d7d1288e123016e1d4f4c19a3c607336a8f 100644
Binary files a/indra/newview/skins/default/textures/windows/first_login_image_left.png and b/indra/newview/skins/default/textures/windows/first_login_image_left.png differ
diff --git a/indra/newview/skins/default/textures/windows/first_login_image_right.png b/indra/newview/skins/default/textures/windows/first_login_image_right.png
index d764d846b731d03ec54e3bdc5391aea17952eb69..35ecce9c0703486c9f9f08378bcd0aff354c01d2 100644
Binary files a/indra/newview/skins/default/textures/windows/first_login_image_right.png and b/indra/newview/skins/default/textures/windows/first_login_image_right.png differ
diff --git a/indra/newview/skins/default/xui/en/control_table_contents_camera.xml b/indra/newview/skins/default/xui/en/control_table_contents_camera.xml
new file mode 100644
index 0000000000000000000000000000000000000000..24cbb2b8850a0f2cd06132ac45db9ae3aa2d4ee8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/control_table_contents_camera.xml
@@ -0,0 +1,240 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<contents>
+    <rows
+     enabled="false"
+     name="camera_actions"
+     value="">
+        <columns
+         type="icontext"
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         label="Camera"
+         name="lst_action"
+         value="Cam_FreeCam_Off" />
+    </rows>
+    <rows
+     name="look_up"
+     value="look_up">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Look Up" />
+    </rows>
+    <rows
+     name="look_down"
+     value="look_down">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Look Down" />
+    </rows>
+    <rows
+     name="move_forward"
+     value="move_forward">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Forward" />
+    </rows>
+    <rows
+     name="move_backward"
+     value="move_backward">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Backward" />
+    </rows>
+    <rows
+     name="move_forward_fast"
+     value="move_forward_fast">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Forward Fast" />
+    </rows>
+    <rows
+     name="move_backward_fast"
+     value="move_backward_fast">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Backward Fast" />
+    </rows>
+    <rows
+     name="spin_over"
+     value="spin_over">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Spin Over" />
+    </rows>
+    <rows
+     name="spin_under"
+     value="spin_under">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Spin Under" />
+    </rows>
+    <rows
+     name="pan_up"
+     value="pan_up">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Pan Up" />
+    </rows>
+    <rows
+     name="pan_down"
+     value="pan_down">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Pan Down" />
+    </rows>
+    <rows
+     name="pan_left"
+     value="pan_left">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Pan Left" />
+    </rows>
+    <rows
+     name="pan_right"
+     value="pan_right">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Pan Right" />
+    </rows>
+    <rows
+     name="pan_in"
+     value="pan_in">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Pan In" />
+    </rows>
+    <rows
+     name="pan_out"
+     value="pan_out">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Pan Out" />
+    </rows>
+    <rows
+     name="spin_around_ccw"
+     value="spin_around_ccw">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         tool_tip="Camera spin around counterclockwise"
+         value="Counterclockwise" />
+    </rows>
+    <rows
+     name="spin_around_cw"
+     value="spin_around_cw">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         tool_tip="Camera spin around clockwise"
+         value="Clockwise" />
+    </rows>
+    <rows
+     name="move_forward_sitting"
+     value="move_forward_sitting">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Forward Sitting" />
+    </rows>
+    <rows
+     name="move_backward_sitting"
+     value="move_backward_sitting">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Backward Sitting" />
+    </rows>
+    <rows
+     name="spin_over_sitting"
+     value="spin_over_sitting">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Spin Over Sitting" />
+    </rows>
+    <rows
+     name="spin_under_sitting"
+     value="spin_under_sitting">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Spin Under Sitting" />
+    </rows>
+    <rows
+     name="spin_around_ccw_sitting"
+     value="spin_around_ccw_sitting">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         tool_tip="Camera spin around counterclockwise sitting"
+         value="Counterclockwise Sitting" />
+    </rows>
+    <rows
+     name="spin_around_cw_sitting"
+     value="spin_around_cw_sitting">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         tool_tip="Camera spin around clockwise sitting"
+         value="Clockwise Sitting" />
+    </rows>
+</contents>
diff --git a/indra/newview/skins/default/xui/en/control_table_contents_columns_basic.xml b/indra/newview/skins/default/xui/en/control_table_contents_columns_basic.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e707aaf22c63dda1441fc52aabbf85b49dac04c8
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/control_table_contents_columns_basic.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<contents>
+    <columns
+     relative_width="0.34"
+     label="Action"
+     name="lst_action" />
+    <columns
+     relative_width="0.22"
+     label="Primary Control"
+     name="lst_ctrl1" />
+    <columns
+     relative_width="0.22"
+     label="Alternate 1"
+     name="lst_ctrl2" />
+    <columns
+     relative_width="0.22"
+     label="Alternate 2"
+     name="lst_ctrl3" />
+</contents>
diff --git a/indra/newview/skins/default/xui/en/control_table_contents_editing.xml b/indra/newview/skins/default/xui/en/control_table_contents_editing.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2a3314840aa20a8445e05ea2a1c1d0dd75a7b33b
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/control_table_contents_editing.xml
@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<contents>
+    <rows
+     enabled="false"
+     name="editing_actions"
+     value="">
+        <columns
+         type="icontext"
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         label="Editing"
+         name="lst_action"
+         value="Tool_Dozer" />
+    </rows>
+    <rows
+     name="edit_avatar_spin_ccw"
+     value="edit_avatar_spin_ccw">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         tool_tip="Camera spin around avatar counterclockwise"
+         value="Counterclockwise" />
+    </rows>
+    <rows
+     name="edit_avatar_spin_cw"
+     value="edit_avatar_spin_cw">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         tool_tip="Camera spin around avatar clockwise"
+         value="Clockwise" />
+    </rows>
+    <rows
+     name="edit_avatar_spin_over"
+     value="edit_avatar_spin_over">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         tool_tip="Camera spin over avatar"
+         value="Camera Spin Over" />
+    </rows>
+    <rows
+     name="edit_avatar_spin_under"
+     value="edit_avatar_spin_under">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         tool_tip="Camera spin under avatar"
+         value="Camera Spin Under" />
+    </rows>
+    <rows
+     name="edit_avatar_move_forward"
+     value="edit_avatar_move_forward">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Forward" />
+    </rows>
+    <rows
+     name="edit_avatar_move_backward"
+     value="edit_avatar_move_backward">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Camera Backward" />
+    </rows>
+</contents>
diff --git a/indra/newview/skins/default/xui/en/control_table_contents_media.xml b/indra/newview/skins/default/xui/en/control_table_contents_media.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ce5d3556b612988e32fab8aa341b334b7e06d132
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/control_table_contents_media.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<contents>
+    <rows
+     enabled="false"
+     name="media_actions"
+     value="">
+        <columns
+         type="icontext"
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         label="Sound and Media"
+         name="lst_action"
+         value="Audio_Press" />
+    </rows>
+    <rows
+     name="toggle_pause_media"
+     value="toggle_pause_media">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Play/Pause Media" />
+    </rows>
+    <rows
+     name="toggle_enable_media"
+     value="toggle_enable_media">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Play/Stop All Media" />
+    </rows>
+    <rows
+     name="voice_follow_key"
+     value="voice_follow_key">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Voice" />
+    </rows>
+    <rows
+     name="toggle_voice"
+     value="toggle_voice">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Toggle Voice" />
+    </rows>
+    <rows
+     name="start_chat"
+     value="start_chat">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Start Chat" />
+    </rows>
+    <rows
+     name="start_gesture"
+     value="start_gesture">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Start Gesture" />
+    </rows>
+</contents>
diff --git a/indra/newview/skins/default/xui/en/control_table_contents_movement.xml b/indra/newview/skins/default/xui/en/control_table_contents_movement.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b410d2dc1c752c698634daa6c4419d9ac06329f6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/control_table_contents_movement.xml
@@ -0,0 +1,198 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<contents>
+    <rows
+     enabled="false"
+     name="move_actions"
+     value="">
+        <columns
+         type="icontext"
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         label="Move Actions"
+         name="lst_action"
+         value="Move_Walk_Off" />
+    </rows>
+    <rows
+     name="walk_to"
+     value="walk_to">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         tool_tip="Walk to location mouse cursor points to"
+         value="Walk to" />
+    </rows>
+    <rows
+     name="teleport_to"
+     value="teleport_to">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         tool_tip="Teleport to location mouse cursor points to, but not all locations allow direct teleportation so you might be teleported closer to destination instead"
+         value="Teleport to" />
+    </rows>
+    <rows
+     name="push_forward"
+     value="push_forward">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Move Forward" />
+    </rows>
+    <rows
+     name="push_backward"
+     value="push_backward">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Move Backward" />
+    </rows>
+    <rows
+     name="turn_left"
+     value="turn_left">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Left" />
+    </rows>
+    <rows
+     name="turn_right"
+     value="turn_right">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Right" />
+    </rows>
+    <rows
+     name="slide_left"
+     value="slide_left">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Strafe left" />
+    </rows>
+    <rows
+     name="slide_right"
+     value="slide_right">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Strafe right" />
+    </rows>
+    <rows
+     name="jump"
+     value="jump">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Jump/Up" />
+    </rows>
+    <rows
+     name="push_down"
+     value="push_down">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Down" />
+    </rows>
+    <rows
+     name="run_forward"
+     value="run_forward">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Run Forward" />
+    </rows>
+    <rows
+     name="run_backward"
+     value="run_backward">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Run Backward" />
+    </rows>
+    <rows
+     name="run_left"
+     value="run_left">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Run Left" />
+    </rows>
+    <rows
+     name="run_right"
+     value="run_right">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Run Right" />
+    </rows>
+    <rows
+     name="toggle_run"
+     value="toggle_run">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Toggle Run" />
+    </rows>
+    <rows
+     name="toggle_fly"
+     value="toggle_fly">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Fly/Stop flying" />
+    </rows>
+    <rows
+     name="toggle_sit"
+     value="toggle_sit">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Sit/Stand" />
+    </rows>
+    <rows
+     name="stop_moving"
+     value="stop_moving">
+        <columns
+         column="lst_action"
+         font="SansSerif"
+         halign="left"
+         name="lst_action"
+         value="Stop Moving" />
+    </rows>
+</contents>
diff --git a/indra/newview/skins/default/xui/en/floater_add_payment_method.xml b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1f980564d4d2499f2d38eafc486d821add8c321f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_add_payment_method.xml
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ height="405"
+ width="900"
+ layout="topleft"
+ name="floater_add_payment_method"
+ single_instance="true"
+ show_title="false"
+ legacy_header_height="0"
+ header_height="0"
+ background_visible="false"
+ can_resize="false"
+ can_drag_on_left="false"
+ can_minimize="false"
+ can_close="false">
+  <floater.string
+    name="continue_url">
+    https://secondlife.com/my/lindex/buy.php?associate_for_viewer=1
+  </floater.string>
+  <panel
+   background_opaque="false"
+   bg_alpha_color="AddPaymentPanel"
+   border_visible="false"
+   background_visible="true"
+   label="wrapper_panel"
+   layout="topleft"
+   left="0"
+   name="wrapper_panel"
+   top="0"
+   height="405"
+   width="900"
+   follows="all"
+   translate="false">
+    <text
+     type="string"
+     length="1"
+     follows="top|left|right"
+     font="SansSerifLargeBold"
+     text_color="White"
+     layout="topleft"
+     left="0"
+     height="14"
+     top_pad="30"
+     width="900"
+     halign="center"
+     name="title_txt">
+      Add a payment method to buy Linden dollars and enjoy more of Second Life.
+    </text>
+    <button
+     follows="top|left|right"
+     height="24"
+     label="Get started"
+     font="SansSerifMedium"
+     layout="topleft"
+     left="320"
+     name="continue_btn"
+     image_unselected="PushButton_Login"
+     image_pressed="PushButton_Login_Pressed"
+     image_hover_unselected="PushButton_Login_Over"
+     label_color="White"
+     top_pad ="15"
+     width="140"/>
+    <button
+     follows="top|left|right"
+     height="24"
+     label="Later"
+     layout="topleft"
+     left_pad="9"
+     name="close_btn"
+     width="90"/>
+    <icon
+     height="195"
+     width="260" 
+     image_name="add_payment_image_left"
+     layout="topleft"
+     left="30"
+     name="image_left"
+     top_pad="30"
+     use_draw_context_alpha="false"/>
+    <icon
+     height="195"
+     width="260"
+     image_name="add_payment_image_center"
+     layout="topleft"
+     left_pad="30"
+     name="image_center"
+     use_draw_context_alpha="false"/>
+    <icon
+     height="195"
+     width="260"
+     image_name="add_payment_image_right"
+     layout="topleft"
+     left_pad="30"
+     name="image_right"
+     use_draw_context_alpha="false"/>
+    <text
+     type="string"
+     length="1"
+     follows="top|left"
+     font="SansSerifMedium"
+     text_color="White"
+     height="75"
+     width="260"
+     top_pad="15"
+     layout="topleft"
+     word_wrap="true"
+     left="30"
+     name="image_left_desc">
+      Create an avatar you love. Choose from millions of items in stores and the Second Life Marketplace. Your style is here.
+    </text>
+    <text
+     type="string"
+     length="1"
+     follows="top|left"
+     font="SansSerifMedium"
+     text_color="White"
+     height="75"
+     width="260"
+     layout="topleft"
+     word_wrap="true"
+     left_pad="30"
+     name="image_center_desc">
+      Donate to your favorite performers and hosts. Your support helps them create great experiences.
+    </text>
+    <text
+     type="string"
+     length="1"
+     follows="top|left"
+     font="SansSerifMedium"
+     text_color="White"
+     height="75"
+     width="260"
+     layout="topleft"
+     word_wrap="true"
+     left_pad="30"
+     name="image_right_desc">
+      Make the home of your dreams. With millions of items available to purchase, you can make your retreat unique.
+    </text>
+  </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml
index 59589e3665e10cfa54a0f5cac7048e6a6a6ae8fe..f4a686bae1406c41625402d915b80dd8f25c4dd0 100644
--- a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml
+++ b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml
@@ -5,14 +5,14 @@
          save_rect="false"
          title="Personal Lighting"
          width="845"
-         height="240"
+         height="280"
          min_width="500"
-         min_height="235"
+         min_height="275"
          single_instance="true"
          can_resize="false">
     <layout_stack name="outer_stack"
                   width="845"
-                  height="230"
+                  height="275"
                   follows="all"
                   animate="false"
                   top="0"
@@ -276,19 +276,57 @@
                                         height="150"
                                         width="150"
                                         thumb_mode="sun"/>
+                  <text follows="left|top"
+                        height="10"
+                        layout="topleft"
+                        left_delta="0"
+                        top_pad="5"
+                        width="200">Azimuth:</text>
+                  <slider decimal_digits="2"
+                          follows="left|top"
+                          height="16"
+                          increment="0.01"
+                          initial_value="0"
+                          layout="topleft"
+                          left_delta="5"
+                          min_val="0"
+                          max_val="359.99"
+                          name="sun_azimuth"
+                          top_pad="5"
+                          width="130"
+                          can_edit_text="true"/>
+                  <text follows="left|top"
+                        height="10"
+                        layout="topleft"
+                        left_delta="-5"
+                        top_pad="5"
+                        width="200">Elevation:</text>
+                  <slider decimal_digits="2"
+                          follows="left|top"
+                          height="16"
+                          increment="0.01"
+                          initial_value="0"
+                          layout="topleft"
+                          left_delta="5"
+                          min_val="-90"
+                          max_val="90"
+                          name="sun_elevation"
+                          top_pad="5"
+                          width="130"
+                          can_edit_text="true"/>
                     <check_box control_name="sunbeacon"
                                width="60"
                                height="16"
                                label="Show Beacon"
                                layout="topleft"
                                name="sunbeacon"
-                               left_delta="55"
-                               bottom="-20"
-                               follows="bottom|right"/>
+                               left_delta="-5"
+                               top_pad="8"
+                               follows="left|top"/>
                     <text follows="left|top"
                           height="10"
                           layout="topleft"
-                          left_pad="40"
+                          left_pad="95"
                           top="25"
                           width="80">Scale:</text>
                     <slider decimal_digits="2"
@@ -385,15 +423,53 @@
                                         height="150"
                                         width="150"
                                         thumb_mode="moon"/>
+                  <text follows="left|top"
+                        height="10"
+                        layout="topleft"
+                        left_delta="0"
+                        top_pad="5"
+                        width="200">Azimuth:</text>
+                  <slider decimal_digits="2"
+                          follows="left|top"
+                          height="16"
+                          increment="0.01"
+                          initial_value="0"
+                          layout="topleft"
+                          left_delta="5"
+                          min_val="0"
+                          max_val="359.99"
+                          name="moon_azimuth"
+                          top_pad="5"
+                          width="130"
+                          can_edit_text="true"/>
+                  <text follows="left|top"
+                        height="10"
+                        layout="topleft"
+                        left_delta="-5"
+                        top_pad="5"
+                        width="200">Elevation:</text>
+                  <slider decimal_digits="2"
+                          follows="left|top"
+                          height="16"
+                          increment="0.01"
+                          initial_value="0"
+                          layout="topleft"
+                          left_delta="5"
+                          min_val="-90"
+                          max_val="90"
+                          name="moon_elevation"
+                          top_pad="5"
+                          width="130"
+                          can_edit_text="true"/>
                     <check_box control_name="moonbeacon"
+                               follows="left|top"
                                width="60"
                                height="16"
                                label="Show Beacon"
                                layout="topleft"
                                name="moonbeacon"
-                               right="-50"
-                               bottom="-20"
-                               follows="bottom|right"/>
+                               left_delta="0"
+                               top_pad="8"/>
                 </layout_panel>
             </layout_stack>
         </layout_panel>
diff --git a/indra/newview/skins/default/xui/en/floater_avatar.xml b/indra/newview/skins/default/xui/en/floater_avatar.xml
index 92c5d8bcbe235ddb4d4eba241682f9d1324bd950..3df2683ca8ba2948184169c1d8bbe057d7efd02f 100644
--- a/indra/newview/skins/default/xui/en/floater_avatar.xml
+++ b/indra/newview/skins/default/xui/en/floater_avatar.xml
@@ -14,7 +14,7 @@
  help_topic="avatar"
  save_rect="true"
  save_visibility="true"
- title="CHOOSE AN AVATAR"
+ title="COMPLETE AVATARS"
  width="700">
     <web_browser
       top="25"
diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
index 061af1b67c6b0f7e8e8ac290d903079a0bb0f96a..e8e83301be432266a14f7ceecf790be650470fcc 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <floater
- legacy_header_height="18"
+
  can_minimize="false"
- height="275"
+ height="285"
  layout="topleft"
  title="BUY L$"
  name="buy currency"
@@ -17,277 +17,385 @@
      name="info_cannot_buy">
         Unable to Buy
     </floater.string>
+    <floater.string
+     name="estimated_zero">
+        US$ 0.00
+    </floater.string>
     <icon
-     height="215"
+     height="245"
      image_name="Linden_Dollar_Background"
      layout="topleft"
      left="0"
      name="normal_background"
-     top="17"
+     top="0"
      use_draw_context_alpha="false"
      width="350" />
-   <text
-     type="string"
-     length="1"
-     follows="top|left|right"
-     font="SansSerifHuge"
-     layout="topleft"
-     left="20"
-     height="30"
-     top="25"
-     width="340"
-     name="info_need_more">
-        You need more L$
-    </text>
-    <text
-     type="string"
-     length="1"
-     follows="top|left"
-     height="16"
+  <layout_stack
+    animate="false"
+    name="outer_stack"
+    layout="topleft"
+    follows="all"
+    orientation="vertical"
+    left="0"
+    top="0"
+    width="350"
+    height="285">
+    <layout_panel
+     auto_resize="false"
+     name="layout_panel_title"
      layout="topleft"
-     top="246"
-     left="15"
-     width="300"
-     name="contacting">
-        Contacting LindeX...
-    </text>
-    <text
-     type="string"
-     length="1"
-     follows="top|left"
-     font="SansSerifHuge"
+     follows="all"
+     width="350"
+     height="35">
+      <text
+       type="string"
+       length="1"
+       follows="top|left|right"
+       font="SansSerifLarge"
+       layout="topleft"
+       left="20"
+       height="30"
+       top="8"
+       width="340"
+       name="info_need_more">
+          You need more L$
+      </text>
+      <text
+       type="string"
+       length="1"
+       follows="top|left|right"
+       font="SansSerifLarge"
+       layout="topleft"
+       left="20"
+       height="30"
+       top="8"
+       width="300"
+       name="info_buying">
+          Buy L$
+      </text>
+      <view_border
+       bevel_style="none"
+       height="0"
+       layout="topleft"
+       left="20"
+       name="text_border"
+       top_delta="25"
+       width="300"/>
+    </layout_panel>
+    <layout_panel
+     auto_resize="false"
+     name="layout_panel_price"
      layout="topleft"
-     left="20"
-     height="30"
-     top="25"
-     width="300"
-     name="info_buying">
-        Buy L$
-    </text>
-    <text
-     type="string"
-     length="1"
-     follows="top|left"
-     font="SansSerifMedium"
-     height="16"
+     follows="all"
+     width="350"
+     height="18">
+      <text
+       type="string"
+       length="1"
+       follows="top|left"
+       font="SansSerifMedium"
+       height="16"
+       layout="topleft"
+       left="20"
+       name="target_price_label"
+       top_pad="3"
+       width="210">
+          You need
+      </text>
+      <text
+       type="string"
+       length="1"
+       font="SansSerifMedium"
+       follows="top|left"
+       halign="right"
+       height="16"
+       layout="topleft"
+       left="200"
+       name="target_price"
+       top_delta="0"
+       width="120">
+          L$ [AMT]
+      </text>
+    </layout_panel>
+    <layout_panel
+     auto_resize="false"
+     name="layout_panel_balance"
      layout="topleft"
-     left="20"
-     name="balance_label"
-     top="65"
-     width="210">
-        I have
-    </text>
-    <text
-     type="string"
-     length="1"
-     font="SansSerifMedium"
-     follows="top|left"
-     halign="right"
-     height="16"
-     layout="topleft"
-     left="200"
-     name="balance_amount"
-     top_delta="0"
-     width="120">
+     follows="all"
+     width="350"
+     height="19">
+      <text
+       type="string"
+       length="1"
+       follows="top|left"
+       font="SansSerifMedium"
+       height="16"
+       layout="topleft"
+       left="20"
+       name="balance_label"
+       top_pad="5"
+       width="210">
+        You now have
+      </text>
+      <text
+       type="string"
+       length="1"
+       font="SansSerifMedium"
+       follows="top|left"
+       halign="right"
+       height="16"
+       layout="topleft"
+       left="200"
+       name="balance_amount"
+       top_delta="0"
+       width="120">
         L$ [AMT]
-    </text>
-    <text
-     type="string"
-     length="1"
-     follows="top|left"
-     font="SansSerifMedium"
-     height="16"
-     top="95"
-     layout="topleft"
-     left="20"
-     name="currency_action"
-     width="210">
-        I want to buy
-    </text>
-    <text
-     font="SansSerifMedium"
-     type="string"
-     length="1"
-     follows="left|top"
-     height="16"
-     layout="topleft"
-     top_delta="0"
-     left="217"
-     name="currency_label"
-     width="15">
-      L$
-    </text>
-    <line_editor
-     type="string"
-     max_length_bytes="10"
-     halign="right"
-     font="SansSerifMedium"
-     select_on_focus="true"
-     follows="top|left"
-     top_delta="-7"
-     height="22"
-     label="L$"
-     left_pad="3"
-     name="currency_amt"
-     width="85">
-        1234
-    </line_editor>
-    <text
-     type="string"
-     font="SansSerifMedium"
-     length="1"
-     follows="top|left"
-     height="16"
-     layout="topleft"
-     left="20"
-     top="125"
-     name="buying_label"
-     width="210">
-        For the price
-    </text>
-    <text
-     type="string"
-     length="1"
-     font="SansSerifMedium"
-     text_color="EmphasisColor"
-     follows="top|left"
-     halign="right"
-     height="16"
-     top_delta="0"
+      </text>
+    </layout_panel>
+    <layout_panel
+     auto_resize="false"
+     name="layout_panel_required"
      layout="topleft"
-     left="150"
-     name="currency_est"
-     width="170">
-     approx. [LOCALAMOUNT]
-    </text>
-    <text
-     type="string"
-     font="SansSerifSmall"
-     text_color="EmphasisColor"
-     length="1"
-     follows="top|left"
-     height="16"
-     layout="topleft"
-     top="125"
-     left="170"
-     width="150"
-     halign="right"
-     name="getting_data">
-        Estimating...
-    </text>
-    <text
-     type="string"
-     font="SansSerifSmall"
-     top="145"
-     length="1"
-     follows="top|left"
-     height="16"
-     halign="right"
-     left="20"
-     width="300"
-     layout="topleft"
-     name="buy_action">
-        [ACTION]
-    </text>
-    <text
-     type="string"
-     font="SansSerifMedium"
-     length="1"
-     follows="top|left"
-     height="16"
-     layout="topleft"
-     left="20"
-     name="total_label"
-     top="165"
-     width="210">
-        My new balance will be
-    </text>
-    <text
-     type="string"
-     length="1"
-     font="SansSerifMedium"
-     follows="top|left"
-     top_delta="0"
-     height="16"
-     layout="topleft"
-     left="200"
-     halign="right"
-     name="total_amount"
-     width="120">
+     follows="all"
+     width="350"
+     height="22">
+      <text
+        type="string"
+        length="1"
+        follows="top|left"
+        font="SansSerifMedium"
+        font.style="BOLD"
+        height="16"
+        layout="topleft"
+        left="20"
+        name="required_label"
+        top_pad="6"
+        width="210">
+        You should buy at least
+      </text>
+      <text
+       type="string"
+       length="1"
+       font="SansSerifMedium"
+       follows="top|left"
+       halign="right"
+       height="16"
+       layout="topleft"
+       left="200"
+       name="required_amount"
+       top_delta="0"
+       width="120">
         L$ [AMT]
-    </text>
-    <text
-     type="string"
-     length="1"
-     text_color="LtGray_50"
-     follows="top|left"
+      </text>
+    </layout_panel>
+    <layout_panel
+     auto_resize="false"
+     name="layout_panel_action"
      layout="topleft"
-     halign="right"
-     top="189"
-     left="20"
-     width="300"
-     height="30"
-     name="currency_links">
-      [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
-    </text>
-    <text
-     type="string"
-     length="1"
-     text_color="LtGray_50"
-     follows="top|left"
+     follows="all"
+     width="350"
+     height="90">
+      <view_border
+       bevel_style="none"
+       height="0"
+       layout="topleft"
+       left="20"
+       name="text_border_2"
+       top_pad="5"
+       width="300"/>
+      <text
+       type="string"
+       length="1"
+       follows="top|left"
+       font="SansSerifMedium"
+       height="16"
+       top_pad="15"
+       layout="topleft"
+       left="20"
+       name="currency_action"
+       width="210">
+          Choose amount to buy
+      </text>
+      <text
+       font="SansSerifMedium"
+       type="string"
+       length="1"
+       follows="left|top"
+       height="16"
+       layout="topleft"
+       top_delta="0"
+       left="247"
+       name="currency_label"
+       width="15">
+        L$
+      </text>
+      <line_editor
+       type="string"
+       max_length_bytes="10"
+       halign="right"
+       font="SansSerifMedium"
+       select_on_focus="true"
+       follows="top|left"
+       top_delta="-4"
+       height="22"
+       label="L$"
+       left_pad="3"
+       name="currency_amt"
+       width="55">
+          1234
+      </line_editor>
+      <text
+       type="string"
+       length="1"
+       font="SansSerifMedium"
+       text_color="EmphasisColor"
+       follows="top|left"
+       halign="right"
+       height="16"
+       top_pad="4"
+       layout="topleft"
+       left="150"
+       name="currency_est"
+       width="170">
+       Approx. [LOCALAMOUNT]
+      </text>
+      <text
+       type="string"
+       font="SansSerifSmall"
+       text_color="EmphasisColor"
+       length="1"
+       follows="top|left"
+       height="16"
+       layout="topleft"
+       left="170"
+       top_delta="0"
+       width="150"
+       halign="right"
+       name="getting_data">
+          Estimating...
+      </text>
+      <text
+       type="string"
+       font="SansSerifMedium"
+       length="1"
+       follows="top|left"
+       height="16"
+       layout="topleft"
+       left="20"
+       name="total_label"
+       top_pad="10"
+       width="210">
+          Your new balance will be
+      </text>
+      <text
+       type="string"
+       length="1"
+       font="SansSerifMedium"
+       follows="top|left"
+       top_delta="0"
+       height="16"
+       layout="topleft"
+       left="200"
+       halign="right"
+       name="total_amount"
+       width="120">
+          L$ [AMT]
+      </text>
+    </layout_panel>
+    <layout_panel
+     auto_resize="false"
+     name="layout_panel_msg"
      layout="topleft"
-     halign="right"
-     top="202"
-     left="20"
-     width="300"
-     height="30"
-     name="exchange_rate_note">
+     follows="all"
+     width="350"
+     height="50">
+      <view_border
+       bevel_style="none"
+       height="0"
+       layout="topleft"
+       left="20"
+       name="text_border_3"
+       top_pad="0"
+       width="300"/>
+      <text
+       type="string"
+       length="1"
+       text_color="LtGray_50"
+       follows="top|left"
+       layout="topleft"
+       halign="right"
+       top_pad="3"
+       left="20"
+       width="300"
+       height="30"
+       name="currency_links">
+        [http://www.secondlife.com/my/account/payment_method_management.php payment method] | [http://www.secondlife.com/my/account/currency.php currency]
+      </text>
+      <text
+       type="string"
+       length="1"
+       text_color="LtGray_50"
+       follows="top|left"
+       layout="topleft"
+       halign="right"
+       top="19"
+       left="20"
+       width="300"
+       height="30"
+       name="exchange_rate_note">
 Re-enter amount to see the latest exchange rate.
-    </text>
-    <text
-     type="string"
-     length="1"
-     text_color="LtGray_50"
-     follows="top|left"
-     layout="topleft"
-     halign="right"
-     top="208"
-     left="10"
-     width="310"
-     height="35"
-     name="purchase_warning_repurchase">
-        Confirming this purchase only buys L$, not the object.
-    </text>
-    <text
-     type="string"
-     length="1"
-     text_color="LtGray_50"
-     follows="top|left"
-     layout="topleft"
-     halign="right"
-     top="213"
-     left="20"
-     width="300"
-     height="30"
-     name="purchase_warning_notenough">
-        You aren&apos;t buying enough L$. Please increase the amount.
-    </text>
-
-    <button
-     follows="bottom|left"
-     height="20"
-     label="Buy Now"
-     layout="topleft"
-     left="151"
-     name="buy_btn"
-     top="242"
-     width="90"/>
-    <button
-     follows="bottom|right"
-     height="20"
-     label="Cancel"
+      </text>
+      <text
+       type="string"
+       length="1"
+       follows="top|left"
+       layout="topleft"
+       font="SansSerifMedium"
+       top="10"
+       left="20"
+       width="310"
+       height="35"
+       name="purchase_warning_repurchase">
+After you receive your L$, you should try your
+purchase again.
+      </text>
+    </layout_panel>
+    <layout_panel
+     auto_resize="false"
+     name="layout_panel_buttons"
      layout="topleft"
-     left_pad="10"
-     name="cancel_btn"
-     width="90"/>
+     follows="all"
+     width="350"
+     height="40">
+      <text
+       type="string"
+       length="1"
+       follows="top|left"
+       height="16"
+       layout="topleft"
+       top_pad="0"
+       left="15"
+       width="300"
+       name="contacting">
+          Contacting LindeX...
+        </text>
+      <button
+       follows="top|left|right"
+       height="20"
+       label="Buy L$ now"
+       layout="topleft"
+       left="151"
+       name="buy_btn"
+       bottom_delta ="8"
+       width="90"/>
+      <button
+       follows="top|left|right"
+       height="20"
+       label="Cancel"
+       layout="topleft"
+       left_pad="10"     
+       name="cancel_btn"
+       width="90"/>
+    </layout_panel>
+  </layout_stack>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_buy_object.xml b/indra/newview/skins/default/xui/en/floater_buy_object.xml
index 49be4290c702ddbf5a15360ed537ae981cfdb6ed..1f7d52dbf5b504c6c4d4df0245add2dd998a91f4 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_object.xml
@@ -32,6 +32,10 @@
      name="no_transfer_text">
         (no transfer)
     </floater.string>
+    <floater.string
+      name="mupliple_selected">
+        Mupliple selection
+    </floater.string>
     <scroll_list
      background_visible="true"
      draw_border="false"
diff --git a/indra/newview/skins/default/xui/en/floater_create_landmark.xml b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
new file mode 100644
index 0000000000000000000000000000000000000000..dcedaceaeba856d2d0cf7e3da8c6304a5a064c64
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_create_landmark.xml
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ can_resize="false"
+ show_title="false"
+ can_minimize="false"
+ can_close="false"
+ header_height="10"
+ bg_opaque_image="Window_NoTitle_Foreground"
+ bg_alpha_image="Window_NoTitle_Background"
+ height="305"
+ layout="topleft"
+ name="create_landmark"
+ width="330">
+  <string name="favorites_bar">
+    Favorites bar
+  </string>
+    <text
+     follows="left|top"
+     height="15"
+     layout="topleft"
+     left="20"
+     name="title_label"
+     top="5"
+     font="SansSerifLargeBold"
+     value="Landmark added"
+     width="290" />
+    <text
+     follows="left|top"
+     height="15"
+     layout="topleft"
+     left="20"
+     name="name_label"
+     top_pad="10"
+     value="Name"
+     width="290" />
+    <line_editor
+     follows="left|top"
+     height="22"
+     layout="topleft"
+     max_length_bytes="63"
+     name="title_editor"
+     prevalidate_callback="ascii"
+     text_readonly_color="white"
+     top_pad="5"
+     width="290" />
+    <text
+     follows="left|top"
+     height="15"
+     layout="topleft"
+     name="folder_label"
+     top_pad="10"
+     value="Landmark location:"
+     width="290" />
+    <combo_box
+     follows="bottom|left"
+     height="23"
+     layout="topleft"
+     name="folder_combo"
+     top_pad="2"
+     width="290" />
+    <text
+     follows="left|top"
+     layout="topleft"
+     top_pad="6"
+     left="20"
+     name="new_folder_textbox"
+     height="20"
+     parse_urls="true"
+     skip_link_underline="true"
+     wrap="true">
+        [secondlife:/// Create new folder]
+    </text>
+    <text
+     follows="left|top"
+     height="15"
+     layout="topleft"
+     name="notes_label"
+     top_pad="10"
+     value="My notes"
+     width="290" />
+    <text_editor
+     bg_readonly_color="DkGray0"
+     follows="all"
+     height="75"
+     layout="topleft"
+     max_length="127"
+     name="notes_editor"
+     spellcheck="true"
+     text_readonly_color="white"
+     text_type="ascii_with_newline"
+     top_pad="5"
+     width="290"
+     wrap="true" />
+    <button
+     follows="bottom|left|right"
+     height="23"
+     label="OK"
+     layout="topleft"
+     mouse_opaque="false"
+     name="ok_btn"
+     top_pad="10"
+     left="19"
+     width="140" />
+    <button
+     follows="bottom|left|right"
+     height="23"
+     label="Cancel"
+     layout="topleft"
+     left_pad="12"
+     mouse_opaque="false"
+     name="cancel_btn"
+     width="140" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml
index 30e9002230d9e799d72e8a0c34f02462ebca51d1..c609e3bd3a6597cc7960eb7f569c32039d60c563 100644
--- a/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml
+++ b/indra/newview/skins/default/xui/en/floater_edit_ext_day_cycle.xml
@@ -616,7 +616,7 @@
                     follows="top|left"
                     height="23"
                     label="Save"
-                    left="5"
+                    left="200"
                     top_pad="0"
                     name="save_btn"
                     width="156" />
diff --git a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml
index dbf91b0834fc1eb79bccd99cce3038b801c3a699..a6e20880a91fd9ded8069bf266b3d1dff9f0e6a0 100644
--- a/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml
+++ b/indra/newview/skins/default/xui/en/floater_fixedenvironment.xml
@@ -89,7 +89,7 @@
                 follows="left|top|right|bottom"
                 auto_resize="false"
                 user_resize="false"
-                height="40"
+                height="29"
                 visible="true">
             <layout_stack
                     follows="bottom|left|right"
@@ -97,7 +97,7 @@
                     layout="topleft"
                     mouse_opaque="false"
                     name="button_bar_ls"
-                    left="0"
+                    left="212"
                     orientation="horizontal"
                     top="0"
                     width="313">
diff --git a/indra/newview/skins/default/xui/en/floater_how_to.xml b/indra/newview/skins/default/xui/en/floater_how_to.xml
index 8c0077a8cc8eecf4db8c6051cf1d1c07338909ce..baff8e1bc065ad3cdcb90d7be0c6965f131a5fd2 100644
--- a/indra/newview/skins/default/xui/en/floater_how_to.xml
+++ b/indra/newview/skins/default/xui/en/floater_how_to.xml
@@ -1,18 +1,17 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
   legacy_header_height="18"
-  can_resize="true"
-  can_minimize="true" 
-  height="775"
+  can_resize="false"
+  can_minimize="false"
+  can_close="false"
+  height="525"
   layout="topleft"
-  min_height="360"
-  left="10000"
-  top="10" 
-  min_width="335"
   name="floater_how_to"
-  help_topic="how_to"
   single_instance="true"
+  save_visibility="true"
   save_rect="true"
-  title="HOW TO"
-  width="780"
+  title="WELCOME ISLAND GUIDEBOOK"
+  width="310"
+  rel_x="-0.469309"
+  rel_y="-0.011166"
   filename="floater_web_content.xml"/>
\ No newline at end of file
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 c64ee5565af46d244f997551807daae00e8b3594..15f02ab9c35f3ab925a733185fc9d1a69b23b0f5 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -267,6 +267,36 @@
                  right="-1">
                     <layout_panel
                      name="input_editor_layout_panel">
+                        <avatar_icon
+                         follows="left|bottom"
+                         name="avatar_icon"
+                         height="20"
+                         default_icon_name="Generic_Person"
+                         layout="topleft"
+                         left="3"
+                         bottom="-9"
+                         visible="false"
+                         width="20" />
+                        <group_icon
+                         follows="left|bottom"
+                         name="group_chat_icon"
+                         height="20"
+                         default_icon_name="Generic_Group"
+                         layout="topleft"
+                         left="3"
+                         bottom="-9"
+                         visible="false"
+                         width="20" />
+                        <icon
+                         follows="left|bottom"
+                         height="20"
+                         image_name="Nearby_chat_icon"
+                         layout="topleft"
+                         left="3"
+                         bottom="-9"
+                         name="nearby_chat_icon"
+                         visible="false"
+                         width="20"/>
                         <chat_editor
                          layout="topleft"
                          expand_lines_count="5"
@@ -280,7 +310,7 @@
                          spellcheck="true"
                          tab_group="3"
                          bottom="-8"
-                         left="5"
+                         left_pad="5"
                          right="-5"
                          wrap="true" />
                     </layout_panel>
diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml
index 02a21764cee30b937980f7312007654936340e0f..7f863756eb92147f52494c17999bca9f4fce907a 100644
--- a/indra/newview/skins/default/xui/en/floater_model_preview.xml
+++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml
@@ -1362,7 +1362,7 @@
          top_pad="9"
          left="6"
          width="70"
-         label="Enable detailed logging"
+         label="Enable detailed logging (can be very slow)"
          name="verbose_logging"/>
       </panel>
     </tab_container>
diff --git a/indra/newview/skins/default/xui/en/floater_my_appearance.xml b/indra/newview/skins/default/xui/en/floater_my_appearance.xml
index fdea7a821ab28e26259eb9d2a54d417f77a5af57..35ad87ceb02c395c27d28ab485cca5f3a38bce5b 100644
--- a/indra/newview/skins/default/xui/en/floater_my_appearance.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_appearance.xml
@@ -11,7 +11,7 @@
   save_rect="true"
   single_instance="true"
   reuse_instance="true"
-  title="APPEARANCE"
+  title="AVATAR"
   min_height="440"
   min_width="333"
   width="333">
diff --git a/indra/newview/skins/default/xui/en/floater_my_scripts.xml b/indra/newview/skins/default/xui/en/floater_my_scripts.xml
index 3b0b6723c7e941187001c51aeea968f138e0d8af..ee6defce9d56ca45b43fe7911475e3ba6fced0e7 100644
--- a/indra/newview/skins/default/xui/en/floater_my_scripts.xml
+++ b/indra/newview/skins/default/xui/en/floater_my_scripts.xml
@@ -7,7 +7,7 @@
  layout="topleft"
  name="myscripts"
  save_rect="true"
- title="My Scripts"
+ title="ATTACHMENT SCRIPTS"
  min_width="620"
  width="620">
   <panel
diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml
index 0e62d50072eb1940726e1c00a3fa296340d97419..ee730dcb013e1339b6cb5637a9e56d8356c7b3c1 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences.xml
@@ -169,6 +169,13 @@ https://accounts.secondlife.com/change_email/
          layout="topleft"
          help_topic="preferences_uploads_tab"
          name="uploads" />
+        <panel
+         class="panel_preference_controls"
+         filename="panel_preferences_controls.xml"
+         label="Controls"
+         layout="topleft"
+         help_topic="preferences_controls_tab"
+         name="controls" />
     </tab_container>
 
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index e282f1b179c10935c715565147af7fa0d5aa77d9..3cc99b28c933af98a8ac012af6fb9534f2898779 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -723,6 +723,14 @@
     top_delta="0"
     name="Reflections"
     width="150">
+      <combo_box.item
+        label="None; opaque"
+        name="0"
+        value="-2"/>
+      <combo_box.item
+        label="None; transparent"
+        name="0"
+        value="-1"/>
       <combo_box.item
         label="Minimal"
         name="0"
diff --git a/indra/newview/skins/default/xui/en/floater_publish_classified.xml b/indra/newview/skins/default/xui/en/floater_publish_classified.xml
index 322e34272c09c3a4153ac3c985b404bdb9820267..84e0b489d0eff34783b40f15a69b7338f094162e 100644
--- a/indra/newview/skins/default/xui/en/floater_publish_classified.xml
+++ b/indra/newview/skins/default/xui/en/floater_publish_classified.xml
@@ -6,6 +6,7 @@
  layout="topleft"
  name="publish_classified"
  title="Publishing Classified"
+ help_topic="profile_edit_classified"
  width="320">
     <text
      top="20"
diff --git a/indra/newview/skins/default/xui/en/floater_select_key.xml b/indra/newview/skins/default/xui/en/floater_select_key.xml
index 4e89df5a7352f7770c5058f564e03aa922a0061d..48d9eee4cd456039c4dc1e304f30bc2d2ff7a4d2 100644
--- a/indra/newview/skins/default/xui/en/floater_select_key.xml
+++ b/indra/newview/skins/default/xui/en/floater_select_key.xml
@@ -4,10 +4,27 @@
  border="false"
  can_close="false"
  can_minimize="false"
- height="90"
+ height="116"
  layout="topleft"
  name="modal container"
- width="240">
+ width="272">
+  <floater.string
+   name="keyboard">
+    Keyboard
+  </floater.string>
+  <floater.string
+   name="mouse">
+    Mouse Buttons
+  </floater.string>
+  <floater.string
+   name="basic_description">
+Press a key to set your trigger.
+Allowed input: [INPUT].
+  </floater.string>
+  <floater.string
+   name="reserved_by_menu">
+Combination [KEYSTR] is reserved by menu.
+  </floater.string>
     <text
      type="string"
      halign="center"
@@ -16,19 +33,47 @@
      height="30"
      layout="topleft"
      left="30"
-     name="Save item as:"
+     name="descritption"
      top="25"
      word_wrap="true"
-     width="180">
-        Press a key to set your Speak button trigger.
+     width="212">
+Press a key to set your trigger.
+Allowed input: [INPUT].
     </text>
+    <check_box
+     follows="top|left"
+     height="20"
+     initial_value="false"
+     label="Apply to all"
+     layout="topleft"
+     left="90"
+     name="apply_all"
+     tool_tip="Viewer uses different control combinations depending on what you are doing in world, setting this will apply your change to all combinations"
+     top_pad="8"
+     width="160" />
+  
+    <button
+     height="23"
+     label="Set Empty"
+     layout="topleft"
+     left="8"
+     name="SetEmpty"
+     top_pad="6"
+     width="80" />
+    <button
+     height="23"
+     label="Default"
+     layout="topleft"
+     left_pad="8"
+     name="Default"
+     top_delta="0"
+     width="80" />
     <button
      height="23"
      label="Cancel"
-     label_selected="Cancel"
      layout="topleft"
-     right="-10"
+     left_pad="8"
      name="Cancel"
-     top_pad="8"
-     width="100" />
+     top_delta="0"
+     width="80" />
 </floater>
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 b955d8313f7a677538ec9e46eeb8797ce75cca76..23b0edc3fe1304963811c03c062f882aa9cea846 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -179,16 +179,13 @@
           parameter="avatar_render_settings" />
       </menu_item_call>
       </context_menu>
-  <menu_item_separator
-       layout="topleft" name="Impostor seperator"/>
-
   <menu_item_call
      enabled="false"
      label="Block Particle Owner"
      name="Mute Particle">
     <menu_item_call.on_click
      function="Particle.Mute" />
-    <menu_item_call.on_enable
+    <menu_item_call.on_visible
      function="EnableMuteParticle" />
   </menu_item_call>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index 59faf6a9f58664872e5498e75bf022dec8f550c2..26b1c86c53bab1be966053fcf0432e338eb5310f 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -4,28 +4,7 @@
  name="Attachment Pie">
     <menu_item_call
      enabled="false"
-     label="Touch"
-     layout="topleft"
-     name="Attachment Object Touch">
-        <menu_item_call.on_click
-         function="Object.Touch" />
-        <menu_item_call.on_enable
-         function="Object.EnableTouch"
-         name="EnableTouch"/>
-    </menu_item_call>
-    <!--menu_item_call
-     label="Stand Up"
-     layout="topleft"
-     name="Stand Up">
-        <menu_item_call.on_click
-         function="Self.StandUp"
-         parameter="" />
-        <menu_item_call.on_enable
-         function="Self.EnableStandUp" />
-    </menu_item_call-->
-    <menu_item_call
-     enabled="false"
-     label="Edit"
+     label="Edit item"
      layout="topleft"
      name="Edit...">
         <menu_item_call.on_click
@@ -35,7 +14,7 @@
     </menu_item_call>
     <menu_item_call
      enabled="false"
-     label="Detach"
+     label="Detach item"
      layout="topleft"
      name="Detach">
         <menu_item_call.on_click
@@ -43,98 +22,278 @@
         <menu_item_call.on_enable
          function="Attachment.EnableDetach" />
     </menu_item_call>
-  <menu_item_separator
-    layout="topleft" />
-
     <menu_item_call
-     label="Sit Down"
+     enabled="false"
+     label="Touch item"
      layout="topleft"
-     name="Sit Down Here">
+     name="Attachment Object Touch">
         <menu_item_call.on_click
-         function="Self.SitDown"
-         parameter="" />
+         function="Object.Touch" />
         <menu_item_call.on_enable
-         function="Self.EnableSitDown" />
+         function="Object.EnableTouch"
+         name="EnableTouch"/>
     </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
 
   <menu_item_call
-label="Stand Up"
-layout="topleft"
-name="Stand Up">
+  label="Now wearing..."
+  name="NowWearing">
     <menu_item_call.on_click
-     function="Self.StandUp"
-     parameter="" />
+     function="NowWearing" />
     <menu_item_call.on_enable
-     function="Self.EnableStandUp" />
+     function="Edit.EnableCustomizeAvatar" />
   </menu_item_call>
   <menu_item_call
-  label="My Appearance"
+  label="My Outfits..."
   name="Change Outfit">
     <menu_item_call.on_click
      function="CustomizeAvatar" />
     <menu_item_call.on_enable
      function="Edit.EnableCustomizeAvatar" />
   </menu_item_call>
-  <menu_item_call label="Edit My Outfit"
-layout="topleft"
-name="Edit Outfit">
+  <menu_item_call label="Hover height..."
+     layout="topleft"
+     name="Hover Height">
     <menu_item_call.on_click
-     function="EditOutfit" />
+     function="HoverHeight" />
     <menu_item_call.on_enable
-     function="Edit.EnableCustomizeAvatar" />
+     function="Edit.EnableHoverHeight" />
   </menu_item_call>
-  <menu_item_call label="Edit My Shape"
+  <menu_item_call label="Shape..."
     layout="topleft"
-    name="Edit My Shape">
+    name="Edit Shape">
     <menu_item_call.on_click
      function="EditShape" />
     <menu_item_call.on_enable
      function="Edit.EnableEditShape" />
   </menu_item_call>
-  <menu_item_call label="Hover Height"
-     layout="topleft"
-     name="Hover Height">
-     <menu_item_call.on_click
-      function="HoverHeight" />
-     <menu_item_call.on_enable
-      function="Edit.EnableHoverHeight" />
+  <menu_item_call label="Edit outfit parts..."
+    layout="topleft"
+    name="Edit Outfit">
+    <menu_item_call.on_click
+     function="EditOutfit" />
+    <menu_item_call.on_enable
+     function="Edit.EnableCustomizeAvatar" />
   </menu_item_call>
-  <menu_item_call label="Reset Skeleton"
+  <context_menu
+  label="Take off"
+  layout="topleft"
+  name="Take Off &gt;">
+    <context_menu
+     label="Clothes"
+     layout="topleft"
+     name="Clothes &gt;">
+      <menu_item_call
+       enabled="false"
+       label="Shirt"
        layout="topleft"
-       name="Reset Skeleton">
-       <menu_item_call.on_click
-        function="Avatar.ResetSkeleton" />
-  </menu_item_call>
-  <menu_item_call label="Reset Skeleton And Animations"
+       name="Shirt">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="shirt" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="shirt" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Pants"
        layout="topleft"
-       name="Reset Skeleton And Animations">
-       <menu_item_call.on_click
-        function="Avatar.ResetSkeletonAndAnimations" />
-  </menu_item_call>
-
+       name="Pants">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="pants" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="pants" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Skirt"
+       layout="topleft"
+       name="Skirt">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="skirt" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="skirt" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Shoes"
+       layout="topleft"
+       name="Shoes">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="shoes" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="shoes" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Socks"
+       layout="topleft"
+       name="Socks">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="socks" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="socks" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Jacket"
+       layout="topleft"
+       name="Jacket">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="jacket" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="jacket" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Gloves"
+       layout="topleft"
+       name="Gloves">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="gloves" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="gloves" />
+      </menu_item_call>
+      <menu_item_call
+            enabled="false"
+            label="Undershirt"
+            layout="topleft"
+            name="Self Undershirt">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="undershirt" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="undershirt" />
+      </menu_item_call>
+      <menu_item_call
+        enabled="false"
+        label="Underpants"
+        layout="topleft"
+        name="Self Underpants">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="underpants" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="underpants" />
+      </menu_item_call>
+      <menu_item_call
+        enabled="false"
+        label="Tattoo"
+        layout="topleft"
+        name="Self Tattoo">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="tattoo" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="tattoo" />
+      </menu_item_call>
+      <menu_item_call
+        enabled="false"
+        label="Physics"
+        layout="topleft"
+        name="Self Physics">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="physics" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="physics" />
+      </menu_item_call>
+      <menu_item_call
+        enabled="false"
+        label="Alpha"
+        layout="topleft"
+        name="Self Alpha">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="alpha" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="alpha" />
+      </menu_item_call>
+      <menu_item_separator
+       layout="topleft" />
+      <menu_item_call
+       label="All Clothes"
+       layout="topleft"
+       name="All Clothes">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="all" />
+      </menu_item_call>
+    </context_menu>
+    <context_menu
+     label="HUD"
+     layout="topleft"
+     name="Detach Self HUD" />
+    <context_menu
+     label="Detach"
+     layout="topleft"
+     name="Detach Self" />
+    <menu_item_call
+     label="Detach All"
+     layout="topleft"
+     name="Detach All">
+      <menu_item_call.on_click
+       function="Self.RemoveAllAttachments"
+       parameter="" />
+      <menu_item_call.on_enable
+       function="Self.EnableRemoveAllAttachments" />
+    </menu_item_call>
+  </context_menu>
+  <menu_item_separator/>
   <menu_item_call
-    label="My Friends"
+    label="Sit / stand"
     layout="topleft"
-    name="Friends...">
+    name="Sit stand">
     <menu_item_call.on_click
-     function="SideTray.PanelPeopleTab"
-     parameter="friends_panel" />
+     function="Self.ToggleSitStand"/>
+    <menu_item_call.on_enable
+     function="Self.EnableSitStand" />
   </menu_item_call>
   <menu_item_call
-   label="My Groups"
-   layout="topleft"
-   name="Groups...">
+     label="Fly / land"
+     name="Fly land">
     <menu_item_call.on_click
-     function="SideTray.PanelPeopleTab"
-     parameter="groups_panel" />
+     function="Agent.toggleFlying" />
+    <menu_item_call.on_enable
+     function="Agent.enableFlyLand" />
   </menu_item_call>
   <menu_item_call
-    label="My Profile"
-    layout="topleft"
-    name="Profile...">
+     label="Stop animations"
+     name="Stop Animating My Avatar">
     <menu_item_call.on_click
-     function="ShowAgentProfile"
-     parameter="agent" />
+     function="Tools.StopAllAnimations" />
+  </menu_item_call>
+  <menu_item_separator/>
+  <menu_item_call label="Reset skeleton"
+       layout="topleft"
+       name="Reset Skeleton">
+       <menu_item_call.on_click
+        function="Avatar.ResetSkeleton" />
+  </menu_item_call>
+  <menu_item_call label="Reset skeleton and animations"
+       layout="topleft"
+       name="Reset Skeleton And Animations">
+       <menu_item_call.on_click
+        function="Avatar.ResetSkeletonAndAnimations" />
   </menu_item_call>
   <menu_item_call
  label="Debug Textures"
@@ -152,27 +311,27 @@ name="Edit Outfit">
             <menu_item_call.on_visible
              function="Advanced.EnableAppearanceToXML"/>
     </menu_item_call>
-  <menu_item_separator
-  layout="topleft" />
-  <menu_item_call
- enabled="false"
- label="Drop"
- layout="topleft"
- name="Drop">
-    <menu_item_call.on_click
-     function="Attachment.Drop" />
-    <menu_item_call.on_enable
-     function="Attachment.EnableDrop" />
-  </menu_item_call>
-  <menu_item_separator
-       layout="topleft" />
   <menu_item_call
      enabled="false"
      label="Block Particle Owner"
      name="Mute Particle">
     <menu_item_call.on_click
      function="Particle.Mute" />
-    <menu_item_call.on_enable
+    <menu_item_call.on_visible
      function="EnableMuteParticle" />
   </menu_item_call>
+
+  <menu_item_separator
+   layout="topleft" />
+  
+  <menu_item_call
+   enabled="false"
+   label="Drop item"
+   layout="topleft"
+   name="Drop">
+    <menu_item_call.on_click
+     function="Attachment.Drop" />
+    <menu_item_call.on_enable
+     function="Attachment.EnableDrop" />
+  </menu_item_call>
 </context_menu>
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 f2babde290b0fbcdb64eaedf1a14ab41572161a1..16ed1648da4eb10900cb682507523dd3813839c1 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -173,16 +173,13 @@
       </menu_item_call>
       </context_menu>
 
-  <menu_item_separator 
-    layout="topleft"  name="Impostor seperator"/>
-
   <menu_item_call
      enabled="false"
      label="Block Particle Owner"
      name="Mute Particle">
     <menu_item_call.on_click
      function="Particle.Mute" />
-    <menu_item_call.on_enable
+    <menu_item_call.on_visible
      function="EnableMuteParticle" />
   </menu_item_call>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
index 9e181d0b6d139f372285bf41b97eaea760efe32b..500b6fffc264a64092db73a4c81daae34ebb31b4 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -3,209 +3,16 @@
  layout="topleft"
  name="Self Pie">
     <menu_item_call
-     label="Sit Down"
+     label="Now wearing..."
      layout="topleft"
-     name="Sit Down Here">
+     name="NowWearing">
         <menu_item_call.on_click
-         function="Self.SitDown"
-         parameter="" />
+         function="NowWearing" />
         <menu_item_call.on_enable
-         function="Self.EnableSitDown" />
+         function="Edit.EnableCustomizeAvatar" />
     </menu_item_call>
     <menu_item_call
-     label="Stand Up"
-     layout="topleft"
-     name="Stand Up">
-        <menu_item_call.on_click
-         function="Self.StandUp"
-         parameter="" />
-        <menu_item_call.on_enable
-         function="Self.EnableStandUp" />
-    </menu_item_call>
-    <context_menu
-     label="Take Off"
-     layout="topleft"
-     name="Take Off &gt;">
-        <context_menu
-         label="Clothes"
-         layout="topleft"
-         name="Clothes &gt;">
-            <menu_item_call
-             enabled="false"
-             label="Shirt"
-             layout="topleft"
-             name="Shirt">
-                <menu_item_call.on_click
-                 function="Edit.TakeOff"
-                 parameter="shirt" />
-                <menu_item_call.on_enable
-                 function="Edit.EnableTakeOff"
-                 parameter="shirt" />
-            </menu_item_call>
-            <menu_item_call
-             enabled="false"
-             label="Pants"
-             layout="topleft"
-             name="Pants">
-                <menu_item_call.on_click
-                 function="Edit.TakeOff"
-                 parameter="pants" />
-                <menu_item_call.on_enable
-                 function="Edit.EnableTakeOff"
-                 parameter="pants" />
-            </menu_item_call>
-            <menu_item_call
-             enabled="false"
-             label="Skirt"
-             layout="topleft"
-             name="Skirt">
-                <menu_item_call.on_click
-                 function="Edit.TakeOff"
-                 parameter="skirt" />
-                <menu_item_call.on_enable
-                 function="Edit.EnableTakeOff"
-                 parameter="skirt" />
-            </menu_item_call>
-            <menu_item_call
-             enabled="false"
-             label="Shoes"
-             layout="topleft"
-             name="Shoes">
-                <menu_item_call.on_click
-                 function="Edit.TakeOff"
-                 parameter="shoes" />
-                <menu_item_call.on_enable
-                 function="Edit.EnableTakeOff"
-                 parameter="shoes" />
-            </menu_item_call>
-            <menu_item_call
-             enabled="false"
-             label="Socks"
-             layout="topleft"
-             name="Socks">
-                <menu_item_call.on_click
-                 function="Edit.TakeOff"
-                 parameter="socks" />
-                <menu_item_call.on_enable
-                 function="Edit.EnableTakeOff"
-                 parameter="socks" />
-            </menu_item_call>
-            <menu_item_call
-             enabled="false"
-             label="Jacket"
-             layout="topleft"
-             name="Jacket">
-                <menu_item_call.on_click
-                 function="Edit.TakeOff"
-                 parameter="jacket" />
-                <menu_item_call.on_enable
-                 function="Edit.EnableTakeOff"
-                 parameter="jacket" />
-            </menu_item_call>
-            <menu_item_call
-             enabled="false"
-             label="Gloves"
-             layout="topleft"
-             name="Gloves">
-                <menu_item_call.on_click
-                 function="Edit.TakeOff"
-                 parameter="gloves" />
-                <menu_item_call.on_enable
-                 function="Edit.EnableTakeOff"
-                 parameter="gloves" />
-            </menu_item_call>
-           <menu_item_call
-                 enabled="false"
-                 label="Undershirt"
-                 layout="topleft"
-                 name="Self Undershirt">
-                    <menu_item_call.on_click
-                     function="Edit.TakeOff"
-                     parameter="undershirt" />
-                    <menu_item_call.on_enable
-                     function="Edit.EnableTakeOff"
-                     parameter="undershirt" />
-                </menu_item_call>
-               <menu_item_call
-                 enabled="false"
-                 label="Underpants"
-                 layout="topleft"
-                 name="Self Underpants">
-                    <menu_item_call.on_click
-                     function="Edit.TakeOff"
-                     parameter="underpants" />
-                    <menu_item_call.on_enable
-                     function="Edit.EnableTakeOff"
-                     parameter="underpants" />
-                </menu_item_call>
-               <menu_item_call
-                 enabled="false"
-                 label="Tattoo"
-                 layout="topleft"
-                 name="Self Tattoo">
-                    <menu_item_call.on_click
-                     function="Edit.TakeOff"
-                     parameter="tattoo" />
-                    <menu_item_call.on_enable
-                     function="Edit.EnableTakeOff"
-                     parameter="tattoo" />
-                </menu_item_call>
-               <menu_item_call
-                 enabled="false"
-                 label="Physics"
-                 layout="topleft"
-                 name="Self Physics">
-                    <menu_item_call.on_click
-                     function="Edit.TakeOff"
-                     parameter="physics" />
-                    <menu_item_call.on_enable
-                     function="Edit.EnableTakeOff"
-                     parameter="physics" />
-                </menu_item_call>
-               <menu_item_call
-                 enabled="false"
-                 label="Alpha"
-                 layout="topleft"
-                 name="Self Alpha">
-                    <menu_item_call.on_click
-                     function="Edit.TakeOff"
-                     parameter="alpha" />
-                    <menu_item_call.on_enable
-                     function="Edit.EnableTakeOff"
-                     parameter="alpha" />
-                </menu_item_call>
-                <menu_item_separator
-                 layout="topleft" />
-                <menu_item_call
-                 label="All Clothes"
-                 layout="topleft"
-                 name="All Clothes">
-                    <menu_item_call.on_click
-                     function="Edit.TakeOff"
-                     parameter="all" />
-                </menu_item_call>
-        </context_menu>
-        <context_menu
-         label="HUD"
-         layout="topleft"
-         name="Object Detach HUD" />
-        <context_menu
-         label="Detach"
-         layout="topleft"
-         name="Object Detach" />
-        <menu_item_call
-         label="Detach All"
-         layout="topleft"
-         name="Detach All">
-            <menu_item_call.on_click
-             function="Self.RemoveAllAttachments"
-             parameter="" />
-            <menu_item_call.on_enable
-             function="Self.EnableRemoveAllAttachments" />
-        </menu_item_call>
-    </context_menu>
-     <menu_item_call
-     label="My Appearance"
+     label="My Outfits..."
      layout="topleft"
      name="Chenge Outfit">
         <menu_item_call.on_click
@@ -213,66 +20,250 @@
         <menu_item_call.on_enable
          function="Edit.EnableCustomizeAvatar" />
     </menu_item_call>
-    <menu_item_call label="Edit My Outfit" 
-    layout="topleft"
-    name="Edit Outfit">
-       <menu_item_call.on_click
-        function="EditOutfit" />
-       <menu_item_call.on_enable
-        function="Edit.EnableCustomizeAvatar" />
+   <menu_item_call label="Hover height..."
+     layout="topleft"
+     name="Hover Height">
+     <menu_item_call.on_click
+      function="HoverHeight" />
+     <menu_item_call.on_enable
+      function="Edit.EnableHoverHeight" />
    </menu_item_call>
-    <menu_item_call label="Edit My Shape" 
+   <menu_item_call label="Shape..." 
     layout="topleft"
-    name="Edit My Shape">
+    name="Edit Shape">
        <menu_item_call.on_click
         function="EditShape" />
        <menu_item_call.on_enable
         function="Edit.EnableEditShape" />
    </menu_item_call>
-   <menu_item_call label="Hover Height"
-     layout="topleft"
-     name="Hover Height">
-     <menu_item_call.on_click
-      function="HoverHeight" />
-     <menu_item_call.on_enable
-      function="Edit.EnableHoverHeight" />
+   <menu_item_call
+      label="Edit outfit parts..." 
+      layout="topleft"
+      name="Edit Outfit">
+       <menu_item_call.on_click
+        function="EditOutfit" />
+       <menu_item_call.on_enable
+        function="Edit.EnableCustomizeAvatar" />
    </menu_item_call>
-   <menu_item_call label="Reset Skeleton"
+  <context_menu
+    label="Take off"
+    layout="topleft"
+    name="Take Off &gt;">
+    <context_menu
+     label="Clothes"
+     layout="topleft"
+     name="Clothes &gt;">
+      <menu_item_call
+       enabled="false"
+       label="Shirt"
+       layout="topleft"
+       name="Shirt">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="shirt" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="shirt" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Pants"
+       layout="topleft"
+       name="Pants">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="pants" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="pants" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Skirt"
+       layout="topleft"
+       name="Skirt">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="skirt" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="skirt" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Shoes"
+       layout="topleft"
+       name="Shoes">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="shoes" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="shoes" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Socks"
+       layout="topleft"
+       name="Socks">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="socks" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="socks" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Jacket"
+       layout="topleft"
+       name="Jacket">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="jacket" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="jacket" />
+      </menu_item_call>
+      <menu_item_call
+       enabled="false"
+       label="Gloves"
+       layout="topleft"
+       name="Gloves">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="gloves" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="gloves" />
+      </menu_item_call>
+      <menu_item_call
+            enabled="false"
+            label="Undershirt"
+            layout="topleft"
+            name="Self Undershirt">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="undershirt" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="undershirt" />
+      </menu_item_call>
+      <menu_item_call
+        enabled="false"
+        label="Underpants"
+        layout="topleft"
+        name="Self Underpants">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="underpants" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="underpants" />
+      </menu_item_call>
+      <menu_item_call
+        enabled="false"
+        label="Tattoo"
+        layout="topleft"
+        name="Self Tattoo">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="tattoo" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="tattoo" />
+      </menu_item_call>
+      <menu_item_call
+        enabled="false"
+        label="Physics"
+        layout="topleft"
+        name="Self Physics">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="physics" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="physics" />
+      </menu_item_call>
+      <menu_item_call
+        enabled="false"
+        label="Alpha"
+        layout="topleft"
+        name="Self Alpha">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="alpha" />
+        <menu_item_call.on_enable
+         function="Edit.EnableTakeOff"
+         parameter="alpha" />
+      </menu_item_call>
+      <menu_item_separator
+       layout="topleft" />
+      <menu_item_call
+       label="All Clothes"
+       layout="topleft"
+       name="All Clothes">
+        <menu_item_call.on_click
+         function="Edit.TakeOff"
+         parameter="all" />
+      </menu_item_call>
+    </context_menu>
+    <context_menu
+     label="HUD"
+     layout="topleft"
+     name="Object Detach HUD" />
+    <context_menu
+     label="Detach"
+     layout="topleft"
+     name="Object Detach" />
+    <menu_item_call
+     label="Detach All"
+     layout="topleft"
+     name="Detach All">
+      <menu_item_call.on_click
+       function="Self.RemoveAllAttachments"
+       parameter="" />
+      <menu_item_call.on_enable
+       function="Self.EnableRemoveAllAttachments" />
+    </menu_item_call>
+  </context_menu>
+  <menu_item_separator/>
+  <menu_item_call
+    label="Sit / stand"
+    layout="topleft"
+    name="Sit stand">
+      <menu_item_call.on_click
+       function="Self.ToggleSitStand"/>
+      <menu_item_call.on_enable
+       function="Self.EnableSitStand" />
+  </menu_item_call>
+  <menu_item_call
+     label="Fly / land"
+     name="Fly land">
+      <menu_item_call.on_click
+       function="Agent.toggleFlying" />
+      <menu_item_call.on_enable
+       function="Agent.enableFlyLand" />
+  </menu_item_call>
+  <menu_item_call
+     label="Stop animations"
+     name="Stop Animating My Avatar">
+        <menu_item_call.on_click
+         function="Tools.StopAllAnimations" />
+  </menu_item_call>
+  <menu_item_separator/>
+  <menu_item_call label="Reset skeleton"
      layout="topleft"
      name="Reset Skeleton">
      <menu_item_call.on_click
       function="Avatar.ResetSkeleton" />
-   </menu_item_call>
-  <menu_item_call label="Reset Skeleton And Animations"
+  </menu_item_call>
+  <menu_item_call label="Reset skeleton and animations"
        layout="topleft"
        name="Reset Skeleton And Animations">
        <menu_item_call.on_click
         function="Avatar.ResetSkeletonAndAnimations" />
   </menu_item_call>
-   <menu_item_call
-     label="My Friends"
-     layout="topleft"
-     name="Friends...">
-        <menu_item_call.on_click
-         function="SideTray.PanelPeopleTab"
-         parameter="friends_panel" />
-    </menu_item_call>
-    <menu_item_call
-     label="My Groups"
-     layout="topleft"
-     name="Groups...">
-        <menu_item_call.on_click
-         function="SideTray.PanelPeopleTab"
-         parameter="groups_panel" />
-    </menu_item_call>
-   <menu_item_call
-     label="My Profile"
-     layout="topleft"
-     name="Profile...">
-        <menu_item_call.on_click
-         function="ShowAgentProfile"
-         parameter="agent" />
-    </menu_item_call>
     <menu_item_call
 		 label="Debug Textures"
          name="Debug...">
@@ -289,8 +280,6 @@
             <menu_item_call.on_visible
              function="Advanced.EnableAppearanceToXML"/>
     </menu_item_call>
-  <menu_item_separator
-       layout="topleft" />
   <menu_item_call
      enabled="false"
      label="Block Particle Owner"
@@ -298,7 +287,7 @@
     <menu_item_call.on_click
      function="Particle.Mute" />
 
-    <menu_item_call.on_enable
+    <menu_item_call.on_visible
      function="EnableMuteParticle" />
   </menu_item_call>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_favorites.xml b/indra/newview/skins/default/xui/en/menu_favorites.xml
index be380e11e56291d854b285f447d9c641efe831a8..0eab7c451b8656de6ed4f584978c585b2f539f2b 100644
--- a/indra/newview/skins/default/xui/en/menu_favorites.xml
+++ b/indra/newview/skins/default/xui/en/menu_favorites.xml
@@ -21,12 +21,12 @@
          parameter="about" />
     </menu_item_call>
     <menu_item_call
-     label="Copy SLurl"
+     label="Move to Landmarks"
      layout="topleft"
-     name="Copy slurl">
+     name="Move to Landmarks">
         <menu_item_call.on_click
          function="Favorites.DoToSelected"
-         parameter="copy_slurl" />
+         parameter="move_to_landmarks" />
     </menu_item_call>
     <menu_item_call
      label="Show on Map"
@@ -36,6 +36,25 @@
          function="Favorites.DoToSelected"
          parameter="show_on_map" />
     </menu_item_call>
+    <menu_item_call
+     label="Copy SLurl"
+     layout="topleft"
+     name="Copy slurl">
+        <menu_item_call.on_click
+         function="Favorites.DoToSelected"
+         parameter="copy_slurl" />
+    </menu_item_call>
+    <menu_item_call
+     label="Create Pick"
+     layout="topleft"
+     name="create_pick">
+        <menu_item_call.on_click
+         function="Favorites.DoToSelected"
+         parameter="create_pick" />
+        <menu_item_call.on_enable
+         function="Favorites.EnableSelected"
+         parameter="create_pick" />
+    </menu_item_call>
 
     <menu_item_separator
      layout="topleft" />
@@ -59,10 +78,14 @@
          function="Favorites.EnableSelected"
          parameter="can_paste" />
     </menu_item_call>
-
-    <menu_item_separator
-     layout="topleft" />
-
+    <menu_item_call
+     label="Rename"
+     layout="topleft"
+     name="rename">
+        <menu_item_call.on_click
+         function="Favorites.DoToSelected"
+         parameter="rename" />
+    </menu_item_call>
     <menu_item_call
      label="Delete"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml b/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml
new file mode 100644
index 0000000000000000000000000000000000000000..46193f4a7a98ba5a2c4dbbc37d2365ec141557f4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_inventory_search_visibility.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ bottom="806"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="menu_search_visibility"
+ visible="false">
+  <menu_item_check
+   label="Search Trash"
+   layout="topleft"
+   name="search_trash">
+    <on_click
+     function="Inventory.GearDefault.Custom.Action"
+     parameter="toggle_search_trash" />
+    <on_check
+     function="Inventory.GearDefault.Check"
+     parameter="toggle_search_trash" />
+  </menu_item_check>
+  <menu_item_check
+   label="Search Library"
+   layout="topleft"
+   name="search_library">
+    <on_click
+     function="Inventory.GearDefault.Custom.Action"
+     parameter="toggle_search_library" />
+    <on_check
+     function="Inventory.GearDefault.Check"
+     parameter="toggle_search_library" />
+  </menu_item_check>
+  <menu_item_separator
+   layout="topleft" />
+  <menu_item_check
+   label="Include links"
+   layout="topleft"
+   name="include_links">
+    <on_click
+     function="Inventory.GearDefault.Custom.Action"
+     parameter="include_links" />
+    <on_check
+     function="Inventory.GearDefault.Check"
+     parameter="include_links" />         
+  </menu_item_check>    
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 07b3cc3bd8d949d9ed9ab02d2c8dd67f3e7d6c5b..96fac1c6e845dbd8bbde3fc0c654c28f425f6c6a 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -57,19 +57,12 @@
      tear_off="true"
      name="Help">
         <menu_item_call
-         label="How to..."
+         label="Guidebook"
          name="How To"
          shortcut="F1">
             <menu_item_call.on_click
              function="Help.ToggleHowTo"
              parameter="" />
-        </menu_item_call>
-        <menu_item_call
-           label="Quickstart"
-           name="Quickstart">
-            <menu_item_call.on_click
-            function="Advanced.ShowURL"
-            parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Quickstart/ta-p/1087919"/>
         </menu_item_call>
 		<menu_item_separator/>
         <menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_picks.xml b/indra/newview/skins/default/xui/en/menu_picks.xml
index ebb49c900422eae22cadbcdee4a09b8e8fec2724..a408e6136c11fdced40ae309e5271e21c5a186a2 100644
--- a/indra/newview/skins/default/xui/en/menu_picks.xml
+++ b/indra/newview/skins/default/xui/en/menu_picks.xml
@@ -3,7 +3,17 @@
  layout="topleft"
  name="Picks">
     <menu_item_call
-     label="Info"
+     label="Teleport"
+     layout="topleft"
+     name="pick_teleport">
+        <menu_item_call.on_click
+         function="Pick.Teleport" />
+        <menu_item_call.on_enable
+         function="Pick.Enable" 
+         parameter="teleport" />
+    </menu_item_call>
+    <menu_item_call
+     label="View Pick"
      layout="topleft"
      name="pick_info">
         <menu_item_call.on_click
@@ -13,7 +23,7 @@
          parameter="info" />
     </menu_item_call>
     <menu_item_call
-     label="Edit"
+     label="Edit Pick"
      layout="topleft"
      name="pick_edit"
      visible="false">
@@ -24,17 +34,7 @@
          parameter="edit" />
     </menu_item_call>
     <menu_item_call
-     label="Teleport"
-     layout="topleft"
-     name="pick_teleport">
-        <menu_item_call.on_click
-         function="Pick.Teleport" />
-        <menu_item_call.on_enable
-         function="Pick.Enable" 
-         parameter="teleport" />
-    </menu_item_call>
-    <menu_item_call
-     label="Map"
+     label="Show on map"
      layout="topleft"
      name="pick_map">
         <menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_place_add_button.xml b/indra/newview/skins/default/xui/en/menu_place_add_button.xml
index bdd4e230b949b0327f107364c1ab29eabd5aae83..ad49f7c3a8581926a6f1327dd34b8b1eae876c98 100644
--- a/indra/newview/skins/default/xui/en/menu_place_add_button.xml
+++ b/indra/newview/skins/default/xui/en/menu_place_add_button.xml
@@ -1,30 +1,30 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu
+<toggleable_menu
  layout="topleft"
  left="0"
  mouse_opaque="false"
- name="menu_folder_gear"
+ name="menu_create"
  visible="false">
     <menu_item_call
-     label="Add Folder"
+     label="Landmark current location"
      layout="topleft"
-     name="add_folder">
+     name="add_landmark">
         <on_click
          function="Places.LandmarksGear.Add.Action"
-         parameter="category" />
+         parameter="add_landmark_root" />
         <on_enable
          function="Places.LandmarksGear.Enable"
-         parameter="category" />
+         parameter="add_landmark_root" />
     </menu_item_call>
     <menu_item_call
-     label="Add Landmark"
+     label="Create folder"
      layout="topleft"
-     name="add_landmark">
+     name="add_folder">
         <on_click
          function="Places.LandmarksGear.Add.Action"
-         parameter="add_landmark" />
+         parameter="category_root" />
         <on_enable
          function="Places.LandmarksGear.Enable"
-         parameter="add_landmark" />
+         parameter="category_root" />
     </menu_item_call>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
index 4d59ab06317bfc97007a222ff866d8a76d0aa63e..e9ada52a8f6aa1484f48663391be24a3b93cfd14 100644
--- a/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_folder.xml
@@ -7,7 +7,7 @@
  name="menu_folder_gear"
  visible="false">
     <menu_item_call
-     label="Add Landmark"
+     label="Landmark current location"
      layout="topleft"
      name="add_landmark">
         <on_click
@@ -18,7 +18,7 @@
          parameter="add_landmark" />
     </menu_item_call>
     <menu_item_call
-     label="Add Folder"
+     label="Create subfolder"
      layout="topleft"
      name="add_folder">
         <on_click
@@ -27,6 +27,9 @@
         <on_enable
          function="Places.LandmarksGear.Enable"
          parameter="category" />
+        <on_visible
+         function="Places.LandmarksGear.Enable"
+         parameter="category" />
     </menu_item_call>
     <menu_item_call
      label="Restore Item"
@@ -123,37 +126,4 @@
          function="Places.LandmarksGear.Enable"
          parameter="collapse" />
     </menu_item_call>
-    <menu_item_call
-     label="Expand all folders"
-     layout="topleft"
-     name="expand_all">
-        <on_click
-         function="Places.LandmarksGear.Folding.Action"
-         parameter="expand_all" />
-        <on_enable
-         function="Places.LandmarksGear.Enable"
-         parameter="expand_all" />
-    </menu_item_call>
-    <menu_item_call
-     label="Collapse all folders"
-     layout="topleft"
-     name="collapse_all">
-        <on_click
-         function="Places.LandmarksGear.Folding.Action"
-         parameter="collapse_all" />
-        <on_enable
-         function="Places.LandmarksGear.Enable"
-         parameter="collapse_all" />
-    </menu_item_call>
-    <menu_item_check
-     label="Sort by Date"
-     layout="topleft"
-     name="sort_by_date">
-        <on_check
-         function="Places.LandmarksGear.Check"
-         parameter="sort_by_date" />
-        <on_click
-         function="Places.LandmarksGear.Folding.Action"
-         parameter="sort_by_date" />
-    </menu_item_check>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
index 28c74a3d5d1813b75f8966bb9e51e2b9bfe0b95e..c89b498ddf8f934aabe304c72a7e7fc9b5c21371 100644
--- a/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_landmark.xml
@@ -18,7 +18,18 @@
          parameter="teleport" />
     </menu_item_call>
     <menu_item_call
-     label="More Information"
+     label="Share"
+     layout="topleft"
+     name="share">
+        <on_click
+         function="Places.LandmarksGear.Custom.Action"
+         parameter="share" />
+        <on_enable
+         function="Places.LandmarksGear.Enable"
+         parameter="share" />
+    </menu_item_call>
+    <menu_item_call
+     label="View/Edit Landmark"
      layout="topleft"
      name="more_info">
         <on_click
@@ -28,6 +39,28 @@
          function="Places.LandmarksGear.Enable"
          parameter="more_info" />
     </menu_item_call>
+    <menu_item_call
+       label="Move to Landmarks"
+       layout="topleft"
+       name="Move to Landmarks">
+      <menu_item_call.on_click
+       function="Places.LandmarksGear.Custom.Action"
+       parameter="move_to_landmarks" />
+      <menu_item_call.on_visible
+       function="Places.LandmarksGear.Enable"
+       parameter="move_to_landmarks" />
+    </menu_item_call>
+    <menu_item_call
+       label="Move to Favorites"
+       layout="topleft"
+       name="Move to Favorites">
+      <menu_item_call.on_click
+       function="Places.LandmarksGear.Custom.Action"
+       parameter="move_to_favorites" />
+      <menu_item_call.on_visible
+       function="Places.LandmarksGear.Enable"
+       parameter="move_to_favorites" />
+    </menu_item_call>
     <menu_item_call
      label="Show on Map"
      layout="topleft"
@@ -39,29 +72,27 @@
          function="Places.LandmarksGear.Enable"
          parameter="show_on_map" />
     </menu_item_call>
-    <menu_item_separator
-     layout="topleft" />
     <menu_item_call
-     label="Add Landmark"
+     label="Copy SLurl"
      layout="topleft"
-     name="add_landmark">
+     name="copy_slurl">
         <on_click
-         function="Places.LandmarksGear.Add.Action"
-         parameter="add_landmark" />
+         function="Places.LandmarksGear.CopyPaste.Action"
+         parameter="copy_slurl" />
         <on_enable
          function="Places.LandmarksGear.Enable"
-         parameter="add_landmark" />
-    </menu_item_call>
+         parameter="copy_slurl" />
+    </menu_item_call> 
     <menu_item_call
-     label="Add Folder"
+     label="Create Pick"
      layout="topleft"
-     name="add_folder">
+     name="create_pick">
         <on_click
-         function="Places.LandmarksGear.Add.Action"
-         parameter="category" />
+         function="Places.LandmarksGear.Custom.Action"
+         parameter="create_pick" />
         <on_enable
          function="Places.LandmarksGear.Enable"
-         parameter="category" />
+         parameter="create_pick" />
     </menu_item_call>
     <menu_item_call
      label="Restore Item"
@@ -85,24 +116,13 @@
          parameter="cut" />
     </menu_item_call>
     <menu_item_call
-     label="Copy Landmark"
+     label="Copy"
      layout="topleft"
      name="copy_landmark">
         <on_click
          function="Places.LandmarksGear.CopyPaste.Action"
          parameter="copy" />
     </menu_item_call>
-    <menu_item_call
-     label="Copy SLurl"
-     layout="topleft"
-     name="copy_slurl">
-        <on_click
-         function="Places.LandmarksGear.CopyPaste.Action"
-         parameter="copy_slurl" />
-        <on_enable
-         function="Places.LandmarksGear.Enable"
-         parameter="copy_slurl" />
-    </menu_item_call>
     <menu_item_call
      label="Paste"
      layout="topleft"
@@ -136,53 +156,4 @@
          function="Places.LandmarksGear.Enable"
          parameter="delete" />
     </menu_item_call>
-    <menu_item_separator
-     layout="topleft" />
-    <menu_item_call
-     label="Expand all folders"
-     layout="topleft"
-     name="expand_all">
-        <on_click
-         function="Places.LandmarksGear.Folding.Action"
-         parameter="expand_all" />
-        <on_enable
-         function="Places.LandmarksGear.Enable"
-         parameter="expand_all" />
-    </menu_item_call>
-    <menu_item_call
-     label="Collapse all folders"
-     layout="topleft"
-     name="collapse_all">
-        <on_click
-         function="Places.LandmarksGear.Folding.Action"
-         parameter="collapse_all" />
-        <on_enable
-         function="Places.LandmarksGear.Enable"
-         parameter="collapse_all" />
-    </menu_item_call>
-    <menu_item_check
-     label="Sort by Date"
-     layout="topleft"
-     name="sort_by_date">
-        <on_check
-         function="Places.LandmarksGear.Check"
-         parameter="sort_by_date" />
-        <on_click
-         function="Places.LandmarksGear.Folding.Action"
-         parameter="sort_by_date" />
-        <on_enable
-         function="Places.LandmarksGear.Enable"
-         parameter="sort_by_date" />
-    </menu_item_check>
-    <menu_item_call
-     label="Create Pick"
-     layout="topleft"
-     name="create_pick">
-        <on_click
-         function="Places.LandmarksGear.Custom.Action"
-         parameter="create_pick" />
-        <on_enable
-         function="Places.LandmarksGear.Enable"
-         parameter="create_pick" />
-    </menu_item_call>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml b/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4193a72e2e340defa04e8f68f925a018f4121f5d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_places_gear_sorting.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="menu_sorter_gear"
+ visible="false">
+    <menu_item_call
+     label="Expand all folders"
+     layout="topleft"
+     name="expand_all">
+        <on_click
+         function="Places.LandmarksGear.Folding.Action"
+         parameter="expand_all" />
+        <on_enable
+         function="Places.LandmarksGear.Enable"
+         parameter="expand_all" />
+    </menu_item_call>
+    <menu_item_call
+     label="Collapse all folders"
+     layout="topleft"
+     name="collapse_all">
+        <on_click
+         function="Places.LandmarksGear.Folding.Action"
+         parameter="collapse_all" />
+        <on_enable
+         function="Places.LandmarksGear.Enable"
+         parameter="collapse_all" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_check
+     label="Sort by Date"
+     layout="topleft"
+     name="sort_by_date">
+        <on_check
+         function="Places.LandmarksGear.Check"
+         parameter="sort_by_date" />
+        <on_click
+         function="Places.LandmarksGear.Folding.Action"
+         parameter="sort_by_date" />
+        <on_enable
+         function="Places.LandmarksGear.Enable"
+         parameter="sort_by_date" />
+    </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml
index bc7d4fe33be86e06a054b80fbf662d24280ade0e..c11d668698e2cbdacc895967b97da084d3739ca5 100644
--- a/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_gear.xml
@@ -12,7 +12,8 @@
      label="Expand all folders"
      name="Expand all folders">
         <menu_item_call.on_click
-         function="TeleportHistory.ExpandAllFolders" />
+         function="TeleportHistory.GearMenu.Action"
+         parameter="expand_all" />
         <on_enable
          function="TeleportHistory.GearMenu.Enable"
          parameter="expand_all" />
@@ -21,16 +22,10 @@
      label="Collapse all folders"
      name="Collapse all folders">
         <menu_item_call.on_click
-         function="TeleportHistory.CollapseAllFolders" />
+         function="TeleportHistory.GearMenu.Action"
+         parameter="collapse_all" />
         <on_enable
          function="TeleportHistory.GearMenu.Enable"
          parameter="collapse_all" />
     </menu_item_call>
-    <menu_item_separator layout="topleft" />
-    <menu_item_call
-     label="Clear Teleport History"
-     name="Clear Teleport History">
-        <menu_item_call.on_click
-         function="TeleportHistory.ClearTeleportHistory" />
-    </menu_item_call>    
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
index f939c3996d4d1a895f6d801b01e27ada5ca5525e..153e5a70a90904454127bbdd343a874d6d55d8d9 100644
--- a/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
+++ b/indra/newview/skins/default/xui/en/menu_teleport_history_item.xml
@@ -1,26 +1,52 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<context_menu
+<toggleable_menu
+ name="Teleport History Item Menu"
  layout="topleft"
- name="Teleport History Item Context Menu">
+ left="0"
+ mouse_opaque="false"
+ visible="false">
     <menu_item_call
      label="Teleport"
      layout="topleft"
      name="Teleport">
-        <menu_item_call.on_click
-         function="TeleportHistory.Teleport" />
+        <on_click
+         function="TeleportHistory.GearMenu.Action"
+         parameter="teleport" />
+        <on_enable
+         function="TeleportHistory.GearMenu.Enable"
+         parameter="teleport" />
     </menu_item_call>
     <menu_item_call
-     label="More Information"
+     label="View"
      layout="topleft"
      name="More Information">
-        <menu_item_call.on_click
-         function="TeleportHistory.MoreInformation" />
+        <on_click
+         function="TeleportHistory.GearMenu.Action"
+         parameter="view" />
+        <on_enable
+         function="TeleportHistory.GearMenu.Enable"
+         parameter="view" />
+    </menu_item_call>
+    <menu_item_call
+     label="Show on map"
+     layout="topleft"
+     name="show_on_map">
+        <on_click
+         function="TeleportHistory.GearMenu.Action"
+         parameter="show_on_map" />
+        <on_enable
+         function="TeleportHistory.GearMenu.Enable"
+         parameter="show_on_map" />
     </menu_item_call>
     <menu_item_call
      label="Copy SLurl"
      layout="topleft"
      name="CopyToClipboard">
-        <menu_item_call.on_click
-         function="TeleportHistory.CopyToClipboard" />
+        <on_click
+         function="TeleportHistory.GearMenu.Action"
+         parameter="copy_slurl" />
+        <on_enable
+         function="TeleportHistory.GearMenu.Enable"
+         parameter="copy_slurl" />
     </menu_item_call>
-</context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index b0162b9ed03fcea479221546f5d9f37e84f95b8b..820d77f75d090cbb8bd4720c54f669f56d737c0d 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -15,24 +15,6 @@
          function="ShowAgentProfile"
          parameter="agent" />
       </menu_item_call>
-      <menu_item_call
-       label="Appearance..."
-       name="ChangeOutfit"
-       shortcut="control|O">
-        <menu_item_call.on_click
-         function="Floater.ToggleOrBringToFront"
-         parameter="appearance" />
-        <menu_item_call.on_enable
-         function="Edit.EnableCustomizeAvatar" />
-      </menu_item_call>
-      <menu_item_call
-       label="Choose an avatar..."
-       name="Avatar Picker">
-        <menu_item_call.on_click
-         function="Floater.ToggleOrBringToFront"
-         parameter="avatar" />
-      </menu_item_call>
-      <menu_item_separator/>
       <menu_item_check
          label="Inventory..."
          name="Inventory"
@@ -56,10 +38,10 @@
       </menu_item_call>
       <menu_item_call
        label="Places..."
-       name="Places">
+       name="Places"
+       shortcut="control|L">
         <menu_item_call.on_click
-         function="Floater.ToggleOrBringToFront"
-         parameter="places" />
+         function="Tools.Link"/>
       </menu_item_call>
       <menu_item_call
        label="Picks..."
@@ -75,120 +57,32 @@
           function="Floater.ToggleOrBringToFront"
           parameter="experiences"/>
       </menu_item_call>
-      <menu_item_call
-        label="My Scripts..."
-        name="MyScripts">
-        <menu_item_call.on_click
-          function="Floater.ToggleOrBringToFront"
-          parameter="my_scripts"/>
-      </menu_item_call>
-      <menu_item_separator/>
       <menu_item_call
        label="Camera Controls..."
-       name="Camera Controls">
+       name="Camera Controls"
+       shortcut="control|K">
         <menu_item_call.on_click
          function="Floater.ToggleOrBringToFront"
          parameter="camera" />
       </menu_item_call>
-      <menu
-       create_jump_keys="true"
-       label="Movement"
-       name="Movement"
-       tear_off="true">
-        <menu_item_call
-         label="Sit Down"
-         layout="topleft"
-         shortcut="alt|shift|S"
-         name="Sit Down Here">
-          <menu_item_call.on_click
-           function="Self.SitDown"/>
-          <menu_item_call.on_visible
-           function="Self.ShowSitDown"/>
-          <menu_item_call.on_enable
-           function="Self.EnableSitDown" />
-        </menu_item_call>
-        <menu_item_call
-         label="Stand Up"
-         layout="topleft"
-         shortcut="alt|shift|S"
-         name="Stand up">
-          <menu_item_call.on_click
-           function="Self.StandUp"/>
-          <menu_item_call.on_visible
-           function="Self.EnableStandUp"/>
-          <menu_item_call.on_enable
-           function="Self.EnableStandUp" />
-        </menu_item_call>
-        <menu_item_check
-         label="Fly"
-         name="Fly"
-         shortcut="HOME">
-          <menu_item_check.on_check
-           function="Agent.getFlying" />
-          <menu_item_check.on_click
-           function="Agent.toggleFlying" />
-          <menu_item_check.on_enable
-           function="Agent.enableFlying" />
-        </menu_item_check>
-        <menu_item_call
-         label="Stop flying"
-         name="Stop flying"
-         shortcut="HOME">
-          <menu_item_call.on_click
-           function="Agent.toggleFlying" />
-          <menu_item_call.on_enable
-           function="Agent.getFlying" />
-        </menu_item_call>	
-        <menu_item_check
-         label="Always Run"
-         name="Always Run"
-         shortcut="control|R">
-          <menu_item_check.on_check
-           function="World.CheckAlwaysRun" />
-          <menu_item_check.on_click
-           function="World.AlwaysRun" />
-        </menu_item_check>
-        <menu_item_call
-         label="Stop Animating Me"
-         name="Stop Animating My Avatar">
-          <menu_item_call.on_click
-           function="Tools.StopAllAnimations" />
-        </menu_item_call>
-        <menu_item_check
-         label="Walk / run / fly..."
-         name="WalkRunFly">
-          <menu_item_check.on_check
-           function="Floater.Visible"
-           parameter="moveview" />
-          <menu_item_check.on_click
-           function="Floater.ToggleOrBringToFront"
-           parameter="moveview" />
-        </menu_item_check>
-      </menu>
 
-      <menu
-       create_jump_keys="true"
-       label="Status"
-       name="Status"
-       tear_off="true">
-        <menu_item_check
-         name="Away"
-         label="Away">
-          <menu_item_check.on_check
-           function="View.Status.CheckAway" />
-          <menu_item_check.on_click
-           function="World.SetAway" />
-        </menu_item_check>
-        <menu_item_check
-         name="Do Not Disturb"
-         label="Do Not Disturb">
-          <menu_item_check.on_check
-           function="View.Status.CheckDoNotDisturb" />
-          <menu_item_check.on_click
-           function="World.SetDoNotDisturb"/>
-        </menu_item_check>
-      
-    </menu>
+      <menu_item_separator/>
+      <menu_item_check
+       name="Away"
+       label="Away">
+        <menu_item_check.on_check
+         function="View.Status.CheckAway" />
+        <menu_item_check.on_click
+         function="World.SetAway" />
+      </menu_item_check>
+      <menu_item_check
+       name="Do Not Disturb"
+       label="Do Not Disturb">
+        <menu_item_check.on_check
+         function="View.Status.CheckDoNotDisturb" />
+        <menu_item_check.on_click
+         function="World.SetDoNotDisturb"/>
+      </menu_item_check>
 
       <menu_item_separator/>
 
@@ -213,6 +107,15 @@
          name="ManageMyAccount_url"
          parameter="WebLaunchJoinNow,http://secondlife.com/account/" />
       </menu_item_call>
+      <menu_item_call
+           label="[Membership]"
+           name="Membership">
+            <menu_item_call.on_click
+             function="Advanced.ShowURL"
+             parameter="https://secondlife.com/my/account/membership.php"/>
+            <menu_item_call.on_visible
+                 function="Membership.UpdateLabel"/>
+      </menu_item_call>
 
       <menu_item_separator/>
 
@@ -258,6 +161,334 @@
              function="File.Quit" />
         </menu_item_call>
     </menu>
+    <menu
+     create_jump_keys="true"
+     label="Avatar"
+     name="Avatar"
+     tear_off="true">
+       <menu_item_call
+         label="Now wearing..."
+         name="NowWearing"
+         shortcut="control|O">
+            <menu_item_call.on_click
+             function="NowWearing" />
+            <menu_item_call.on_enable
+             function="Edit.EnableCustomizeAvatar" />
+       </menu_item_call>
+       <menu_item_call
+         label="My outfits..."
+         name="ChangeOutfit">
+            <menu_item_call.on_click
+             function="CustomizeAvatar" />
+            <menu_item_call.on_enable
+             function="Edit.EnableCustomizeAvatar" />
+       </menu_item_call>
+       <menu_item_call label="Hover height..."
+         layout="topleft"
+         shortcut="alt|control|H"
+         name="Hover Height">
+            <menu_item_call.on_click
+             function="HoverHeight" />
+            <menu_item_call.on_enable
+             function="Edit.EnableHoverHeight" />
+      </menu_item_call>
+      <menu_item_call
+        label="Edit shape..."
+        layout="topleft"
+        name="Edit My Shape">
+            <menu_item_call.on_click
+             function="EditShape" />
+            <menu_item_call.on_enable
+             function="Edit.EnableEditShape" />
+      </menu_item_call>
+      <menu_item_call
+        label="Edit outfit parts..."
+        layout="topleft"
+        name="Edit Outfit">
+            <menu_item_call.on_click
+             function="EditOutfit" />
+            <menu_item_call.on_enable
+             function="Edit.EnableCustomizeAvatar" />
+      </menu_item_call>
+      <menu
+        label="Take off"
+        layout="topleft"
+        name="Take Off &gt;">
+        <menu
+         label="Clothes"
+         layout="topleft"
+         name="Clothes &gt;">
+          <menu_item_call
+           enabled="false"
+           label="Shirt"
+           layout="topleft"
+           name="Shirt">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="shirt" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="shirt" />
+          </menu_item_call>
+          <menu_item_call
+           enabled="false"
+           label="Pants"
+           layout="topleft"
+           name="Pants">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="pants" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="pants" />
+          </menu_item_call>
+          <menu_item_call
+           enabled="false"
+           label="Skirt"
+           layout="topleft"
+           name="Skirt">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="skirt" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="skirt" />
+          </menu_item_call>
+          <menu_item_call
+           enabled="false"
+           label="Shoes"
+           layout="topleft"
+           name="Shoes">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="shoes" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="shoes" />
+          </menu_item_call>
+          <menu_item_call
+           enabled="false"
+           label="Socks"
+           layout="topleft"
+           name="Socks">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="socks" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="socks" />
+          </menu_item_call>
+          <menu_item_call
+           enabled="false"
+           label="Jacket"
+           layout="topleft"
+           name="Jacket">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="jacket" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="jacket" />
+          </menu_item_call>
+          <menu_item_call
+           enabled="false"
+           label="Gloves"
+           layout="topleft"
+           name="Gloves">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="gloves" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="gloves" />
+          </menu_item_call>
+          <menu_item_call
+                enabled="false"
+                label="Undershirt"
+                layout="topleft"
+                name="Self Undershirt">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="undershirt" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="undershirt" />
+          </menu_item_call>
+          <menu_item_call
+            enabled="false"
+            label="Underpants"
+            layout="topleft"
+            name="Self Underpants">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="underpants" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="underpants" />
+          </menu_item_call>
+          <menu_item_call
+            enabled="false"
+            label="Tattoo"
+            layout="topleft"
+            name="Self Tattoo">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="tattoo" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="tattoo" />
+          </menu_item_call>
+          <menu_item_call
+            enabled="false"
+            label="Physics"
+            layout="topleft"
+            name="Self Physics">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="physics" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="physics" />
+          </menu_item_call>
+          <menu_item_call
+            enabled="false"
+            label="Alpha"
+            layout="topleft"
+            name="Self Alpha">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="alpha" />
+            <menu_item_call.on_enable
+             function="Edit.EnableTakeOff"
+             parameter="alpha" />
+          </menu_item_call>
+          <menu_item_separator
+           layout="topleft" />
+          <menu_item_call
+           label="All Clothes"
+           layout="topleft"
+           name="All Clothes">
+            <menu_item_call.on_click
+             function="Edit.TakeOff"
+             parameter="all" />
+          </menu_item_call>
+        </menu>
+        <menu
+         label="HUD"
+         layout="topleft"
+         name="Avatar Detach HUD" />
+        <menu
+         label="Detach"
+         layout="topleft"
+         name="Avatar Detach" />
+        <menu_item_call
+         label="Detach All"
+         layout="topleft"
+         name="Detach All">
+          <menu_item_call.on_click
+           function="Self.RemoveAllAttachments"
+           parameter="" />
+          <menu_item_call.on_enable
+           function="Self.EnableRemoveAllAttachments" />
+        </menu_item_call>
+      </menu>
+      <menu_item_separator/>
+      <menu_item_call
+        label="Complete avatars..."
+        name="Avatar Picker">
+        <menu_item_call.on_click
+         function="Floater.ToggleOrBringToFront"
+         parameter="avatar" />
+      </menu_item_call>
+      <menu_item_separator/>
+
+      <menu_item_call
+         label="Sit / stand"
+         layout="topleft"
+         shortcut="alt|shift|S"
+         name="Sit stand">
+          <menu_item_call.on_click
+           function="Self.ToggleSitStand"/>
+          <menu_item_call.on_enable
+           function="Self.EnableSitStand" />
+        </menu_item_call>
+        <menu_item_call
+         label="Fly / land"
+         name="Fly land"
+         shortcut="HOME">
+          <menu_item_call.on_click
+           function="Agent.toggleFlying" />
+          <menu_item_call.on_enable
+           function="Agent.enableFlyLand" />
+        </menu_item_call>       
+        <menu_item_call
+         label="Stop animations"
+         name="Stop Animating My Avatar">
+          <menu_item_call.on_click
+           function="Tools.StopAllAnimations" />
+        </menu_item_call>
+        <menu_item_check
+          label="Walk / run / fly..."
+          name="WalkRunFly">
+          <menu_item_check.on_check
+           function="Floater.Visible"
+           parameter="moveview" />
+          <menu_item_check.on_click
+           function="Floater.ToggleOrBringToFront"
+           parameter="moveview" />
+        </menu_item_check>
+        <menu_item_check
+          label="Always run"
+          name="Always Run"
+          shortcut="control|R">
+          <menu_item_check.on_check
+           function="World.CheckAlwaysRun" />
+          <menu_item_check.on_click
+           function="World.AlwaysRun" />
+        </menu_item_check>
+      <menu_item_separator/>
+      <menu_item_check
+       label="Gestures..."
+       name="Gestures"
+       shortcut="control|G">
+        <menu_item_check.on_check
+         function="Floater.Visible"
+         parameter="gestures" />
+        <menu_item_check.on_click
+         function="Floater.Toggle"
+         parameter="gestures" />
+      </menu_item_check>
+      <menu_item_separator/>
+      <menu_item_call 
+       label="Reset skeleton"
+       layout="topleft"
+       name="Reset Skeleton">
+        <menu_item_call.on_click
+         function="Avatar.ResetSkeleton" />
+      </menu_item_call>
+      <menu_item_call 
+       label="Reset skeleton and animations"
+       layout="topleft"
+       name="Reset Skeleton And Animations">
+        <menu_item_call.on_click
+         function="Avatar.ResetSkeletonAndAnimations" />
+      </menu_item_call>
+      <menu_item_call
+       label="Attachment scripts..."
+       name="MyScripts">
+        <menu_item_call.on_click
+         function="Floater.ToggleOrBringToFront"
+         parameter="my_scripts"/>
+      </menu_item_call>
+      <menu_item_separator/>
+      <menu_item_call
+     label="Help with avatars..."
+     name="Help with avatars">
+        <menu_item_call.on_click
+            function="Advanced.ShowURL"
+            parameter="https://community.secondlife.com/search/?type=cms_records3&amp;tags=avatar&amp;nodes=30&amp;search_and_or=or"/>
+      </menu_item_call>
+    </menu>
     <menu
      create_jump_keys="true"
      label="Communicate"
@@ -458,7 +689,8 @@
         </menu_item_check>
         <menu_item_call
              label="Events"
-             name="Events">
+             name="Events"
+             shortcut="control|E">
             <menu_item_call.on_click
              function="Advanced.ShowURL"
              parameter="https://secondlife.com/my/community/events"/>
@@ -532,12 +764,18 @@
              parameter="region_info" />
         </menu_item_call>
         <menu_item_call
-         label="My land holdings..."
-         name="My Land">
+         label="My Linden Home..."
+         name="Linden Home">
+            <menu_item_call.on_click
+             function="World.LindenHome"/>
+        </menu_item_call>
+        <menu_item_call
+             label="My land holdings..."
+             name="My Land">
             <menu_item_call.on_click
              function="Floater.Show"
              parameter="land_holdings" />
-        </menu_item_call>
+      </menu_item_call>
         <menu_item_call
          label="Buy this land"
          name="Buy Land">
@@ -614,8 +852,7 @@
           <menu_item_separator />
           <menu_item_check
              label="Advanced Menu"
-             name="Show Advanced Menu"
-             shortcut="control|alt|shift|D">
+             name="Show Advanced Menu">
             <on_check
                function="CheckControl"
                parameter="UseDebugMenus" />
@@ -655,7 +892,8 @@
          tear_off="true">
             <menu_item_check
              label="Sunrise"
-             name="Sunrise">
+             name="Sunrise"
+             shortcut="control|shift|O">
                 <menu_item_check.on_click
                  function="World.EnvSettings"
                  parameter="sunrise" />
@@ -696,7 +934,8 @@
             </menu_item_check>
             <menu_item_check
              label="Midnight"
-             name="Midnight">
+             name="Midnight"
+             shortcut="control|shift|Z">
                 <menu_item_check.on_click
                  function="World.EnvSettings"
                  parameter="midnight" />
@@ -1370,7 +1609,8 @@ function="World.EnvPreset"
             <menu_item_call
            label="Model..."
            layout="topleft"
-           name="Upload Model">
+           name="Upload Model"
+           shortcut="alt|control|U">
             <menu_item_call.on_click
              function="File.UploadModel"
              parameter="" />
@@ -1423,20 +1663,13 @@ function="World.EnvPreset"
      name="Help"
      tear_off="true">
         <menu_item_call
-         label="How to..."
+         label="Guidebook"
          name="How To"
          shortcut="F1">
             <menu_item_call.on_click
              function="Help.ToggleHowTo"
              parameter="" />
         </menu_item_call>
-        <menu_item_call
-           label="Quickstart"
-           name="Quickstart">
-            <menu_item_call.on_click
-            function="Advanced.ShowURL"
-            parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-Quickstart/ta-p/1087919"/>
-        </menu_item_call>
 <!--        <menu_item_call
          label="Tutorial"
          name="Tutorial">
@@ -2265,20 +2498,6 @@ function="World.EnvPreset"
          name="Shortcuts"
          tear_off="true"
          visible="false">
-            <!-- This second, alternative shortcut for Show Advanced Menu is for backward compatibility.  The main shortcut has been changed so it's Linux-friendly, where the old shortcut is typically eaten by the window manager. -->
-            <menu_item_check
-               label="Show Advanced Menu - legacy shortcut"
-               name="Show Advanced Menu - legacy shortcut"
-               shortcut="control|alt|D">
-              <on_check
-                 function="CheckControl"
-                 parameter="UseDebugMenus" />
-              <on_click
-                 function="ToggleControl"
-                 parameter="UseDebugMenus" />
-            </menu_item_check>
-
-            <menu_item_separator/>
 
             <menu_item_call
              label="Close Window"
@@ -3915,7 +4134,7 @@ function="World.EnvPreset"
             <menu_item_call
              label="Debug Avatar Textures"
              name="Debug Avatar Textures"
-             shortcut="control|alt|shift|A">
+             shortcut="control|alt|shift|K">
                 <menu_item_call.on_click
                  function="Advanced.DebugAvatarTextures" />
             </menu_item_call>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 93855f9d2a4e1dd6e219885d69c4c46f235002fd..a001ff21e28bdb36c159ded73a86bed8d33e20e5 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -1022,18 +1022,6 @@ The group no longer has open enrollment.
        yestext="OK"/>
   </notification>
 
-  <notification
-   icon="alertmodal.tga"
-   name="JoinGroupSuccess"
-   type="alertmodal">
-You have been added to the group
-    <tag>group_id</tag>
-    <tag>success</tag>
-    <usetemplate
-       name="okbutton"
-       yestext="OK"/>
-  </notification>
-  
   <notification
    icon="alertmodal.tga"
    name="JoinGroupInsufficientFunds"
@@ -2331,6 +2319,29 @@ You cannot create a landmark here because the owner of the land doesn&apos;t all
   <tag>fail</tag>
   </notification>
 
+  <notification
+ icon="alertmodal.tga"
+ label="Create folder"
+ name="CreateLandmarkFolder"
+ type="alertmodal">
+    <unique/>
+    Choose a name for the folder:
+    <tag>confirm</tag>
+    <form name="form">
+      <input name="message" type="text">
+      </input>
+      <button
+       default="true"
+       index="0"
+       name="OK"
+       text="OK"/>
+      <button
+       index="1"
+       name="Cancel"
+       text="Cancel"/>
+    </form>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="CannotRecompileSelectObjectsNoScripts"
@@ -2443,9 +2454,8 @@ Teleport failed.
    icon="alertmodal.tga"
    name="invalid_tport"
    type="alertmodal">
-Problem encountered processing your teleport request. You may need to log back in before you can teleport.
-If you continue to get this message, please check the [SUPPORT_SITE].
-  <tag>fail</tag>
+Teleport attempts are limited to 6 per minute. If you are having trouble, wait one minute and try teleporting again. If the problem persists, log out and log in again.
+    <tag>fail</tag>
   </notification>
   <notification
    icon="alertmodal.tga"
@@ -3153,7 +3163,30 @@ See https://wiki.secondlife.com/wiki/Adding_Spelling_Dictionaries
        text="Cancel"/>
     </form>
   </notification>
-  
+
+  <notification
+   icon="alertmodal.tga"
+   label="Rename Landmark"
+   name="RenameLandmark"
+   type="alertmodal">
+    Choose a new name for [NAME]
+    <tag>confirm</tag>
+    <form name="form">
+      <input name="new_name" type="text" width="300">
+        [NAME]
+      </input>
+      <button
+       default="true"
+       index="0"
+       name="OK"
+       text="OK"/>
+      <button
+       index="1"
+       name="Cancel"
+       text="Cancel"/>
+    </form>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="RemoveFromFriends"
@@ -4039,6 +4072,8 @@ Finished download of raw terrain file to:
 [DOWNLOAD_PATH].
   </notification>
 
+  <!-- RequiredUpdate does not display release notes URL because we don't get
+       that from login.cgi's login failure message. -->
   <notification
    icon="alertmodal.tga"
    name="RequiredUpdate"
@@ -4056,6 +4091,8 @@ Please download from https://secondlife.com/support/downloads/
    name="PauseForUpdate"
    type="alertmodal">
 Version [VERSION] is required for login.
+Release notes: [URL]
+
 Click OK to download and install.
     <tag>confirm</tag>
     <usetemplate
@@ -4068,6 +4105,8 @@ Click OK to download and install.
    name="OptionalUpdateReady"
    type="alertmodal">
 Version [VERSION] has been downloaded and is ready to install.
+Release notes: [URL]
+
 Click OK to install.
     <tag>confirm</tag>
     <usetemplate
@@ -4080,6 +4119,8 @@ Click OK to install.
    name="PromptOptionalUpdate"
    type="alertmodal">
 Version [VERSION] has been downloaded and is ready to install.
+Release notes: [URL]
+
 Proceed?
     <tag>confirm</tag>
     <usetemplate
@@ -4249,13 +4290,6 @@ Leave Group?
      yestext="OK"/>
   </notification>
 
-  <notification
-   icon="notify.tga"
-   name="GroupDepart"
-   type="notify">
-You have left the group &apos;&lt;nolink&gt;[group_name]&lt;/nolink&gt;&apos;.
-    <tag>group</tag>
-  </notification>
 
   <notification
    icon="alertmodal.tga"
@@ -5058,7 +5092,9 @@ Do you wish to proceed?
    name="RegionEntryAccessBlocked"
    type="alertmodal">
    <tag>fail</tag>
-    The region you're trying to visit contains content exceeding your current preferences.  You can change your preferences using Me &gt; Preferences &gt; General.
+    The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu &gt; Preferences &gt; General.
+
+Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].
     <usetemplate
      name="okbutton"
      yestext="OK"/>
@@ -5145,7 +5181,9 @@ The region you're trying to visit contains [REGIONMATURITY] content, but your cu
    name="TeleportEntryAccessBlocked"
    type="alertmodal">
     <tag>fail</tag>
-    The region you're trying to visit contains content exceeding your current preferences.  You can change your preferences using Me &gt; Preferences &gt; General.
+    The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu &gt; Preferences &gt; General.
+
+Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].
     <usetemplate
      name="okbutton"
      yestext="OK"/>
@@ -5294,6 +5332,8 @@ You won't receive any more notifications that you're about to visit a region wit
    name="LandClaimAccessBlocked"
    type="alertmodal">
     The land you're trying to claim has a maturity rating exceeding your current preferences.  You can change your preferences using Me &gt; Preferences &gt; General.
+
+Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].
     <tag>fail</tag>
     <usetemplate
      name="okbutton"
@@ -5363,6 +5403,8 @@ You won't receive any more notifications that you're about to visit a region wit
    name="LandBuyAccessBlocked"
    type="alertmodal">
     The land you're trying to buy has a maturity rating exceeding your current preferences.  You can change your preferences using Me &gt; Preferences &gt; General.
+
+Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].
     <tag>fail</tag>
     <usetemplate
      name="okbutton"
@@ -7239,8 +7281,10 @@ You can only claim public land in the Region you&apos;re in.
    name="RegionTPAccessBlocked"
    type="alertmodal">
    <tag>fail</tag>
-    The region you're trying to visit contains content exceeding your current preferences.  You can change your preferences using Me &gt; Preferences &gt; General.
-   <usetemplate
+    The region you’re trying to visit has a maturity rating exceeding your maximum maturity preference. Change this preference using Me menu &gt; Preferences &gt; General.
+
+Complete information on maturity ratings can be found [https://community.secondlife.com/knowledgebase/english/maturity-ratings-r52/ here].
+    <usetemplate
       name="okbutton"
       yestext="OK"/>
   </notification>
@@ -8686,7 +8730,7 @@ This upload will cost L$[PRICE], do you wish to continue with the upload?
    icon="alertmodal.tga"
    name="ConfirmClearTeleportHistory"
    type="alertmodal">
-Are you sure you want to delete your teleport history?
+This will delete the entire list of places you have visited, and cannot be undone. Continue?
   <tag>confirm</tag>
     <usetemplate
      name="okcancelbuttons"
@@ -9592,6 +9636,12 @@ You do not appear to have the proper hardware requirements for [APP_NAME]. [APP_
 If you continue to have problems, please visit the [SUPPORT_SITE].
   </global>
 
+  <global name="UnsupportedIntelDriver">
+The installed Intel graphics driver for [GPUNAME], version [VERSION], is significantly out of date and is known to cause excessive rates of program crashes. You are strongly advised to update to a current Intel driver
+
+Do you want to check the Intel driver website?
+  </global>
+
   <global name="UnsupportedCPUAmount">
 796
   </global>
@@ -11487,6 +11537,19 @@ Changes won't take effect until after you restart [APP_NAME].
      notext="Cancel"
      yestext="OK"/>
   </notification>
+  
+  <notification
+   icon="alertmodal.tga"
+   name="PreferenceControlsDefaults"
+   type="alertmodal">
+    Do you want to restore default values for controls?
+    <tag>confirm</tag>
+    <usetemplate
+       canceltext="Cancel"
+       name="yesnocancelbuttons"
+       notext="Current mode"
+       yestext="All modes"/>
+  </notification>
     
   <notification
    icon="alertmodal.tga"
@@ -11532,7 +11595,28 @@ Changes won't take effect until after you restart [APP_NAME].
      name="okbutton"
      yestext="OK"/>
   </notification>
-  
+
+  <notification
+   icon="alertmodal.tga"
+   name="AddPaymentMethod"
+   type="alertmodal">
+On the following page, choose a L$ amount
+and click a place Order button. You will be
+able to add a payment method at checkout.
+    <tag>confirm</tag>
+    <form name="form">
+      <button
+       default="true"
+       index="0"
+       width="120"
+       name="Continue"
+       text="Continue"/>
+      <button
+       index="1"
+       name="Cancel"
+       text="Cancel"/>
+    </form>
+  </notification>
   
   <notification
    icon="alert.tga"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index 553c112e6fc7025f6f24071d4c8a534b81f891a9..357a5559bf8545b347fc08ea1597ea64afff9e99 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -26,7 +26,7 @@
      name="back_btn"
      left="10"
      tab_stop="false"
-     top="2"
+     top="4"
      width="30"
      use_draw_context_alpha="false" />
    <text
@@ -39,17 +39,17 @@
      left_pad="4"
      name="title"
      text_color="LtGray"
-     top="2"
+     top="4"
      width="250">
         Edit Pick
     </text>
    <scroll_container
      color="DkGray2"
      follows="all"
-     height="502"
+     height="501"
      layout="topleft"
      left="8"
-     top_pad="10"
+     top_pad="9"
      name="profile_scroll"
      opaque="true"
      width="312">
diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
index dc1553e6a30757a83cbdde600761d6f6ff840c74..85d73ece48ab41ad1442b065c669e7462696a767 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
@@ -13,7 +13,7 @@
  width="333">
     <string
      name="edit_shape_title">
-        Editing Shape
+        Shape
     </string>
     <string
      name="edit_skin_title">
diff --git a/indra/newview/skins/default/xui/en/panel_favorites.xml b/indra/newview/skins/default/xui/en/panel_favorites.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1e8ea34ad289ae93bacaa3f765b044b0b28110e1
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_favorites.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+   name="Favorites"
+   layout="topleft" 
+   left="0"
+   border="false"
+   background_visible="true"
+   bg_alpha_color="DkGray"
+   follows="all">
+    <places_inventory_panel
+      allow_multi_select="true"
+      border="false"
+      top="1"
+      left="3"
+      bottom="0"
+      follows="all"
+      right="-3"
+      mouse_opaque="true"
+      name="favorites_list"
+      folder_view.use_ellipses="true"
+      start_folder.name="Favorites"/>        
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index 7935d66aee555f3bd3df75aca1c72c5d2d42c21f..e82305ef1722ab0461cc60e473e87158696369a1 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -67,7 +67,7 @@
      name="back_btn"
      tool_tip="Back"
      tab_stop="false"
-     top="4"
+     top="2"
      width="30"
      use_draw_context_alpha="false" />
     <text
@@ -78,20 +78,20 @@
      left_pad="7"
      name="title"
      text_color="LtGray"
-     top="3"
+     top="2"
      use_ellipses="true"
      value="Place Profile"
      width="280" />
     <scroll_container
      color="DkGray2"
      follows="all"
-     height="532"
+     height="534"
      layout="topleft"
      left="9"
      name="place_scroll"
      opaque="true"
-     top_pad="10"
-     width="310">
+     top_pad="9"
+     width="324">
         <panel
          bg_alpha_color="DkGray2"
          follows="left|top|right"
@@ -282,7 +282,6 @@
                  enabled="false"
                  use_bg_color="true"
                  bg_color="DkGray0"
-                 parse_urls="false"
                  follows="left|top|right"
                  height="22"
                  layout="topleft"
@@ -290,8 +289,18 @@
                  name="title_value"
                  text_color="white"
                  top_pad="5"
-                 use_ellipses="true"
-                 width="290" /> 
+                 width="200" /> 
+                <button
+                 follows="top|right"
+                 height="24"
+                 label="Edit"
+                 layout="topleft"
+                 left_pad="8"
+                 mouse_opaque="false"
+                 name="edit_btn"
+                 tool_tip="Edit landmark information"
+                 top_delta="-1"
+                 width="83" />
                 <line_editor
                  follows="left|top|right"
                  height="22"
@@ -301,8 +310,8 @@
                  name="title_editor"
                  prevalidate_callback="ascii"
                  text_readonly_color="white"
-                 top_delta="0"
-                 width="290" />
+                 top_delta="1"
+                 width="290"/>
                 <text
                  follows="left|top"
                  height="15"
@@ -344,17 +353,6 @@
                  name="folder_combo"
                  top_pad="5"
                  width="200" />
-                <button
-                 follows="bottom|left|right"
-                 height="23"
-                 label="Edit"
-                 layout="topleft"
-                 left="0"
-                 mouse_opaque="false"
-                 name="edit_btn"
-                 tool_tip="Edit landmark information"
-                 top_pad="-42"
-                 width="100" />
             </panel>
         </panel>
     </scroll_container>
diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index 67a09949ceaa59279b661925b6fbd4d3c3e052f7..10b925ec93e9fbf67ae4115c4e0e76d19a7df0f0 100644
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -1,198 +1,23 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
    name="Landmarks"
-   top="0"
-   height="400"
    layout="topleft" 
    left="0"
-   width="313"
    help_topic="panel_landmarks"
    border="false"
    background_visible="true"
    bg_alpha_color="DkGray"
    follows="all">
-    <accordion
-     background_visible="true"
-     bg_alpha_color="DkGray2"
-     bg_opaque_color="DkGray2"
-     follows="all"
-     height="373"
-     layout="topleft"
-     left="3"
-     name="landmarks_accordion"
-     top="0"
-     width="307">
-        <accordion_tab
-         layout="topleft"
-         name="tab_favorites"
-         title="Favorites bar">
-            <places_inventory_panel
-             allow_multi_select="true"
-             border="false"
-             bottom="0"
-             follows="all"
-             height="126"
-             left="0"
-             mouse_opaque="true"
-             name="favorites_list"
-             scroll.hide_scrollbar="true"
-             folder_view.use_ellipses="true"
-             start_folder.name="Favorites"
-             width="307"/>
-        </accordion_tab>
-        <accordion_tab
-         layout="topleft"
-         name="tab_landmarks"
-         title="My Landmarks">
-            <places_inventory_panel
-             allow_multi_select="true"
-             border="false"
-             bottom="0"
-             follows="all"
-             height="126"
-             left="0"
-             mouse_opaque="true"
-             name="landmarks_list"
-             scroll.hide_scrollbar="true"
-             folder_view.use_ellipses="true"
-             start_folder.name="Landmarks"
-             width="307"/>
-        </accordion_tab>
-        <accordion_tab
-         layout="topleft"
-         name="tab_inventory"
-         title="My Inventory">
-            <places_inventory_panel
-             allow_multi_select="true"
-             border="false"
-             bottom="0"
-             follows="all"
-             height="126"
-             left="0"
-             mouse_opaque="true"
-             name="my_inventory_list"
-             scroll.hide_scrollbar="true"
-             folder_view.use_ellipses="true"
-             start_folder.name="My Inventory"
-             width="307"/>
-          </accordion_tab>
-          <accordion_tab
-           layout="topleft"
-           name="tab_library"
-           title="Library">
-            <places_inventory_panel
-             allow_multi_select="true"
-             border="false"
-             bottom="0"
-             follows="all"
-             height="126"
-             left="0"
-             mouse_opaque="true"
-             name="library_list"
-             scroll.hide_scrollbar="true"
-             folder_view.use_ellipses="true"
-             start_folder.name="LIBRARY"
-             width="313"/>
-        </accordion_tab>
-    </accordion>
-    <panel
-       background_visible="true"
-     bevel_style="none"
-     bottom="0"
-     follows="left|right|bottom"
-     height="27"
-     layout="bottomleft"
-     left="3"
-     name="bottom_panel"
-     width="313">
-     	
-     	  <layout_stack
-		   animate="false"
-		   border_size="0"
-		   follows="left|right|bottom"
-		   height="25"
-		   layout="topleft"
-		   orientation="horizontal"
-		   top_pad="1"
-		   left="0"
-		   name="bottom_panel"
-		   width="307">
-		      <layout_panel
-		       auto_resize="false"
-		       height="25"
-		       layout="topleft"
-		       name="options_gear_btn_panel"
-		       width="32">
-		          <menu_button
-		           follows="bottom|left"
-		           tool_tip="Show additional options"
-		           height="25"
-		           image_hover_unselected="Toolbar_Left_Over"
-		           image_overlay="OptionsMenu_Off"
-		           image_selected="Toolbar_Left_Selected"
-		           image_unselected="Toolbar_Left_Off"
-		           layout="topleft"
-		           left="0"
-		           name="options_gear_btn"
-		           top="0"
-		           width="31" />
-		      </layout_panel>
-		      <layout_panel
-		       auto_resize="false"
-		       height="25"
-		       layout="topleft"
-		       name="add_btn_panel"
-		       width="32">
-		          <button
-		           follows="bottom|left"
-		           height="25"
-		           image_hover_unselected="Toolbar_Middle_Over"
-		           image_overlay="AddItem_Off"
-		           image_selected="Toolbar_Middle_Selected"
-		           image_unselected="Toolbar_Middle_Off"
-		           layout="topleft"
-		           left="0"
-		           name="add_btn"
-		           tool_tip="Add new landmark"
-		           top="0"
-		           width="31" />
-		      </layout_panel>
-		      <layout_panel
-		       auto_resize="true"
-		       height="25"
-		       layout="topleft"
-		       name="dummy_panel"
-		       width="212">
-		          <icon
-		           follows="bottom|left|right"
-		           height="25"
-		           image_name="Toolbar_Middle_Off"
-		           layout="topleft"
-		           left="0"
-		           top="0"
-		           name="dummy_icon"
-		           width="211" />
-		      </layout_panel>
-		      <layout_panel
-		       auto_resize="false"
-		       height="25"
-		       layout="topleft"
-		       name="trash_btn_panel"
-		       width="31">
-		          <dnd_button
-		           follows="bottom|left"
-		           height="25"
-		           image_hover_unselected="Toolbar_Right_Over"
-		           image_overlay="TrashItem_Off"
-		           image_selected="Toolbar_Right_Selected"
-		           image_unselected="Toolbar_Right_Off"
-		           left="0"
-		           layout="topleft"
-		           name="trash_btn"
-		           tool_tip="Remove selected landmark"
-		           top="0"
-		           width="31"/>
-		      </layout_panel>
-  	</layout_stack>
-   </panel>
+    <places_inventory_panel
+      allow_multi_select="true"
+      border="false"
+      top="1"
+      follows="all"
+      left="3"
+      bottom="0"
+      right="-3"
+      mouse_opaque="true"
+      name="landmarks_list"
+      folder_view.use_ellipses="true"
+      start_folder.name="Landmarks"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index d77fbdec0ac28dd95c9c4ddfdaa169e3fb02ed17..2ff58035ed8b0c4fb5bcf5d36d98cf76388c1388 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -32,30 +32,20 @@
     		 left="12"
 		     name="ItemcountText"
 		     font="SansSerifMedium"
-		     text_color="EmphasisColor"
+		     text_color="InventoryItemLinkColor"
 		     use_ellipses="true"
 		     top_pad="0"
 		     width="300">
     Items:
   </text>
-  <filter_editor
-   text_pad_left="10"
-   follows="left|top|right"
+  <combo_box
    height="23"
-   label="Enter search text"
    layout="topleft"
    left="10"
-   max_length_chars="300"
-   name="inventory search editor"
    top="18"
-   width="208" />
-  <combo_box
-   height="23"
-   layout="topleft"
-   left_pad="4"
    name="search_type"
-   follows="top|right"
-   width="90">
+   follows="top|left"
+   width="88">
     <item
      label="Name"
      name="Name"
@@ -72,7 +62,27 @@
      label="UUID"
      name="UUID"
      value="search_by_UUID"/>
-    </combo_box>
+  </combo_box>
+  <menu_button
+   follows="top|left"
+   tool_tip="Show search visibility options"
+   height="23"
+   image_overlay="Inv_Toolbar_SearchVisibility"
+   layout="topleft"
+   left_pad="3"
+   name="options_visibility_btn"
+   width="31" />
+  <filter_editor
+   text_pad_left="10"
+   follows="left|top|right"
+   height="23"
+   label="Enter search text"
+   layout="topleft"
+   left_pad="3"
+   max_length_chars="300"
+   highlight_text_field="true"
+   name="inventory search editor"
+   width="177" />
   <tab_container
      follows="all"
      halign="center"
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index c7edba21f85aa56e2ea2e084102ed0a56b7d3ef9..2dae2649a9dadc964996d4dc1e72fdcb196527fc 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -151,30 +151,43 @@
 	         layout="topleft"
            auto_resize="true"
            user_resize="true"
-           min_width="185"
+           min_width="254"
            name="favorites_layout_panel"
-           width="320">
+           width="342">
            <icon
              follows="top|left"
              height="25"
              image_name="ChatBarHandle"
              layout="topleft"
-             left="-323"
+             left="-345"
              name="resize_handle"
              top="4"
              width="5" />
-
+           <button
+             height="23"
+             width="32"
+             layout="topleft"
+             mouse_opaque="true"
+             follows="left|top"
+             name="landmarks_btn"
+             tool_tip="My Landmarks"
+             top_delta="1"
+             left_pad="8"
+             scale_image="false"
+             image_overlay="Landmarks_overlay"
+             image_hover_unselected="PushButton_Over">
+           </button>
            <favorites_bar
              follows="left|right|top"
              font="SansSerifSmall"
              height="20"
              layout="topleft"
-             left="0"
+             left_pad="0"
              top="4"
              name="favorite"
              image_drag_indication="Accordion_ArrowOpened_Off"
              tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"
-             width="320">
+             width="310">
             <label
              follows="left|top"
              height="13"
@@ -185,8 +198,8 @@
              tool_tip="Drag Landmarks here for quick access to your favorite places in Second Life!"
              top="13"
 	     valign="bottom"
-             width="102">
-              Favorites Bar
+             width="205">
+              Your saved locations will appear here.
             </label>
               <!-- More button actually is a text box. -->
               <more_button
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
index 3f7444dec358229a1cad7d9b01f3ae0e04bb5148..d625f89f3b87c30ecf2df1f38a56555f34e3c03c 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -81,7 +81,7 @@
             name="title"
             text_color="LtGray"
             top="0"
-            value="Edit Outfit"
+            value="Edit outfit parts"
             use_ellipses="true"
             width="275" />
 
@@ -510,27 +510,31 @@ It is calculated as border_size + 2*UIResizeBarOverlap
                 <button
                         follows="bottom|left|right"
                         height="23"
-                        label="Save"
+                        label="Save changes"
                         left="1"
                         layout="topleft"
                         name="save_btn"
                         top="0"
                         width="155" />
-                <button
-                        follows="bottom|right"
-                        height="23"
-                        name="save_flyout_btn"
-                        label=""
-                        layout="topleft"
-                        left_pad="-20"
-                        tab_stop="false"
-                        top="0"
-                        image_selected="SegmentedBtn_Right_Selected_Press"
-                        image_unselected="SegmentedBtn_Right_Off"
-                        image_pressed="SegmentedBtn_Right_Press"
-                        image_pressed_selected="SegmentedBtn_Right_Selected_Press"
-                        image_overlay="Arrow_Small_Up"
-                        width="20"/>
+            </layout_panel>
+            <layout_panel
+               follows="bottom|left|right"
+               height="23"
+               layout="bottomleft"
+               left_pad="3"
+               mouse_opaque="false"
+               name="save_as_btn_lp"
+               auto_resize="true"
+               width="156">
+              <button
+                   follows="bottom|left|right"
+                   height="23"
+                   label="Save as..."
+                   layout="topleft"
+                   name="save_as_btn"
+                   top="0"
+                   left="1"
+                   width="155" />
             </layout_panel>
             <layout_panel
                     follows="bottom|left|right"
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
index 6c8cc9d39a63be96b4427c822814dbadda9c03ef..7b898dbd7f9fef7fd5ffcad7a8133a504952c405 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_inventory.xml
@@ -100,28 +100,33 @@
                     <button
                          follows="bottom|left|right"
                          height="23"
-                         label="Save As"
+                         label="Save changes"
                          left="1"
                          layout="topleft"
                          name="save_btn"
                          top="0"
                          width="155" />
-                    <button
-                         follows="bottom|right"
-                         height="23"
-                         name="save_flyout_btn"
-                         label=""
-                         layout="topleft"
-                         left_pad="-20"
-                         tab_stop="false"
-                         image_selected="SegmentedBtn_Right_Selected_Press"
-                         image_unselected="SegmentedBtn_Right_Off"
-                         image_pressed="SegmentedBtn_Right_Press"
-                         image_pressed_selected="SegmentedBtn_Right_Selected_Press"
-                         image_overlay="Arrow_Small_Up"
-                         width="20"/>
-			    </layout_panel>
-			    <layout_panel
+          </layout_panel>
+          <layout_panel
+               follows="bottom|left|right"
+               height="23"
+               layout="bottomleft"
+               left_pad="3"
+               mouse_opaque="false"
+               name="save_as_btn_lp"
+               auto_resize="true"
+               width="156">
+              <button
+                   follows="bottom|left|right"
+                   height="23"
+                   label="Save as..."
+                   layout="topleft"
+                   name="save_as_btn"
+                   top="0"
+                   left="1"
+                   width="155" />
+          </layout_panel>
+          <layout_panel
                      follows="bottom|left|right"
                      height="23"
                      layout="bottomleft"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index fad9e2c5873f1718f77f80ce13d064939b1e1ff1..13f55c061b59c44bc0521a5d91cfc46b5b1d421c 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -12,7 +12,7 @@
  width="333">
     <string
      name="no_recent_people"
-     value="No recent people. Looking for people to hang out with? Try [secondlife:///app/search/people Search] or the [secondlife:///app/worldmap World Map]." />
+     value="No recent people." />
     <string
      name="no_filtered_recent_people"
      value="Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search]." />
@@ -30,8 +30,13 @@
      value="No friends" />
     <string
      name="no_friends_msg">
-         Find friends using [secondlife:///app/search/people Search] or right-click on a Resident to add them as a friend.
-Looking for people to hang out with? Try the [secondlife:///app/worldmap World Map].
+      To add someone as a friend, right-click on their avatar or their name.
+
+Looking for places with more people?
+
+[secondlife:///app/floater/destinations Destination Guide] has locations chosen by Second Life staff.
+
+[secondlife:///app/search/ Search] lets you search all of Second Life for certain keywords.
     </string>
     <string
      name="no_filtered_friends_msg">
@@ -45,8 +50,11 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
      name="no_filtered_groups_msg"
      value="Didn't find what you're looking for? Try [secondlife:///app/search/groups/[SEARCH_TERM] Search]." />
     <string
-     name="no_groups_msg"
-     value="Looking for Groups to join? Try [secondlife:///app/search/groups Search]." />
+     name="no_groups_msg">
+You are not a member of any groups.
+
+Learn about [https://community.secondlife.com/knowledgebase/joining-and-participating-in-groups-r51/ groups in Second Life.]
+  </string>
 	<string
 	 name="MiniMapToolTipMsg"
 	 value="[REGION](Double-click to open Map, shift-drag to pan)"/>
diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml
index 36b7b0501b8b402491f1d0af3cd5f9d1e0442dbc..bdde2cab203acc100180aff3a48be8d2eb7852af 100644
--- a/indra/newview/skins/default/xui/en/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml
@@ -172,7 +172,7 @@
      name="back_btn"
      tool_tip="Back"
      tab_stop="false"
-     top="4"
+     top="2"
      width="30"
      use_draw_context_alpha="false" />
     <text
@@ -183,20 +183,20 @@
      left_pad="10"
      name="title"
      text_color="LtGray"
-     top="4"
+     top="2"
      use_ellipses="true"
      value="Place Profile"
      width="280" />
     <scroll_container
      color="DkGray2"
      follows="all"
-     height="572"
+     height="575"
      layout="topleft"
      left="9"
      name="place_scroll"
      opaque="true"
-     top_pad="10"
-     width="310">
+     top_pad="9"
+     width="324">
         <panel
          bg_alpha_color="DkGray2"
          follows="left|top|right|bottom"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index 1f32ae53baec8591f3a5232df25c2819039de366..58be4d4c5ee4906356607728840952704d06d79a 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -11,30 +11,156 @@ background_visible="true"
  top="0"
  left="0"
  width="333">
-    <string
-     name="landmarks_tab_title"
-     value="MY LANDMARKS" />
-    <string
-     name="teleport_history_tab_title"
-     value="TELEPORT HISTORY" />
-    <filter_editor
-     text_pad_left="10"
-     follows="left|top|right"
-     font="SansSerifSmall"
-     height="23"
-     layout="topleft"
-     left="10"
-     label="Filter My Places"
-     max_length_chars="300"
-     name="Filter"
-     tab_group="1"
-     top="3"
-     width="303" />
+  <string
+   name="landmarks_tab_title"
+   value="LANDMARKS" />
+  <string
+   name="teleport_history_tab_title"
+   value="VISITED" />
+  <string
+   name="favorites_tab_title"
+   value="FAVORITES" />
+  <string
+   name="tooltip_trash_items"
+   value="Remove selected landmark or folder" />
+  <string
+   name="tooltip_trash_history"
+   value="Delete list of visited places" />
+  <layout_stack
+    animate="false"
+    border_size="0"
+    follows="all"
+    height="564"
+    layout="topleft"
+    orientation="vertical"
+    top="1"
+    left="0"
+    name="places_layout_panel"
+    width="333">
+    <layout_panel
+      auto_resize="true"
+      height="538"
+      layout="topleft"
+      name="main_panel"
+      width="333">
+    <layout_stack
+      animate="false"
+      border_size="0"
+      follows="left|top|right"
+      height="27"
+      layout="topleft"
+      orientation="horizontal"
+      top="0"
+      left="0"
+      name="top_menu_panel"
+      width="320">
+      <layout_panel
+        auto_resize="true"
+        layout="topleft"
+        name="filter_panel"
+        width="193">
+        <filter_editor
+          text_pad_left="10"
+          follows="left|top|right"
+          font="SansSerifSmall"
+          height="23"
+          layout="topleft"
+          left="10"
+          label="Filter My Places"
+          max_length_chars="300"
+          name="Filter"
+          tab_group="1"
+          top="3"
+          width="181" />
+      </layout_panel>
+      <layout_panel
+        auto_resize="false"
+        height="25"
+        layout="topleft"
+        name="options_gear_btn_panel"
+        width="32">
+        <menu_button
+          follows="bottom|left"
+          tool_tip="Show options"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="OptionsMenu_Off"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          menu_position="bottomleft"
+          layout="topleft"
+          left="0"
+          name="options_gear_btn"
+          top="0"
+          width="31" />
+      </layout_panel>
+      <layout_panel
+        auto_resize="false"
+        height="25"
+        layout="topleft"
+        name="options_sort_btn_panel"
+        width="32">
+        <menu_button
+          follows="bottom|left"
+          tool_tip="Show sorting options"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="Conv_toolbar_sort"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          menu_position="bottomleft"
+          layout="topleft"
+          left="0"
+          name="sorting_menu_btn"
+          top="0"
+          width="31" />
+      </layout_panel>
+      <layout_panel
+        auto_resize="false"
+        height="25"
+        layout="topleft"
+        name="add_btn_panel"
+        width="32">
+        <menu_button
+          follows="bottom|left"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="AddItem_Off"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          menu_position="bottomleft"
+          layout="topleft"
+          left="0"
+          name="add_menu_btn"
+          tool_tip="Add new landmark or folder"
+          top="0"
+          width="31" />
+      </layout_panel>
+      <layout_panel
+        auto_resize="false"
+        height="25"
+        layout="topleft"
+        name="trash_btn_panel"
+        width="31">
+        <dnd_button
+          follows="bottom|left"
+          height="25"
+          image_hover_unselected="Toolbar_Right_Over"
+          image_overlay="TrashItem_Off"
+          image_selected="Toolbar_Right_Selected"
+          image_unselected="Toolbar_Right_Off"
+          left="0"
+          layout="topleft"
+          name="trash_btn"
+          top="0"
+          width="31"/>
+      </layout_panel>
+    </layout_stack>
     <tab_container
      follows="all"
-     halign="center"
-     height="503"
      layout="topleft"
+     halign="center"
+     height="504"
      left="6"
      name="Places Tabs"
      tab_min_width="80"
@@ -42,40 +168,50 @@ background_visible="true"
      tab_height="30"
      tab_group="2"
      tab_position="top"
-     top_pad="10"
-     width="315" />
+     top_pad="7"
+     width="318"
+     visible="true"/>
     <panel
      class="panel_place_profile"
      filename="panel_place_profile.xml"
      follows="all"
-     height="533"
      layout="topleft"
+     height="533"
      left="0"
+     top="4"
      help_topic="place_profile"
      name="panel_place_profile"
-     top="5"
      visible="false"
-     width="315" />
+     width="318" />
     <panel
      class="panel_landmark_info"
      filename="panel_landmark_info.xml"
      follows="all"
-     height="533"
      layout="topleft"
+     height="533"
      left="0"
+     top="4"
      help_topic="landmark"
      name="panel_landmark_info"
-     top="5"
      visible="false"
-     width="315" />
+     width="318" />
+    </layout_panel>
+
+    <!--*********************** Button wrappers ***********************-->
+    <layout_panel
+     auto_resize="false"
+     layout="topleft"
+     height="25"
+     name="button_layout_panel">
     <panel
      follows="bottom|left|right"
      height="23"
      layout="topleft"
      left="4"
+     top="2"
      name="button_panel"
-     width="315">
-     
+     width="318">
+    
        <layout_stack
      	follows="bottom|left|right"
 		height="23"
@@ -186,41 +322,6 @@ background_visible="true"
 			name="lp2"
 			auto_resize="true"
 			width="116">
-
-		<!--*********************** Profile button ***********************-->		
-				
-				<layout_stack
-		     	follows="bottom|left|right"
-				height="23"
-				layout="topleft"
-				mouse_opaque="false"
-				name="bottom_bar_profile_ls"
-				left="0"
-				orientation="horizontal"
-				top="0"
-				width="110">		
-					<layout_panel
-					follows="bottom|left|right"
-					height="23"
-					layout="bottomleft"
-					left_pad="3"			
-					mouse_opaque="false"
-					name="profile_btn_lp"
-				    auto_resize="true"
-					width="102">
-						<button
-				         follows="bottom|left|right"
-				         height="23"
-				         label="Profile"
-				         layout="topleft"
-						 mouse_opaque="false"
-				         name="profile_btn"
-				         left="1"
-				         tool_tip="Show place profile"
-				         top="0"
-				         width="101" />		
-					</layout_panel>
-				</layout_stack>
 		
 		<!--*********************** Close button ***********************-->
 				
@@ -265,6 +366,7 @@ background_visible="true"
 		
 		<layout_stack
      	follows="bottom|left|right"
+      animate="false"
 		height="23"
 		layout="topleft"
 		mouse_opaque="false"
@@ -319,4 +421,6 @@ background_visible="true"
 			</layout_panel>		
 		</layout_stack>
     </panel>
+    </layout_panel>
+  </layout_stack>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_controls.xml b/indra/newview/skins/default/xui/en/panel_preferences_controls.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9dab7d34e6cf4a4054a9e73cc75620c831892885
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_preferences_controls.xml
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="utf-8"?>
+<panel
+ border="true"
+ follows="all"
+ height="408"
+ label="Controls"
+ layout="topleft"
+ left="102"
+ name="controls"
+ top="1"
+ width="517">
+  <combo_box
+   follows="top|left"
+   layout="topleft"
+   top="6"
+   left="10"
+   height="23"
+   width="232"
+   name="key_mode">
+    <combo_box.item
+     label="When in third person"
+     name="third_person"
+     value="1"/>
+    <combo_box.item
+     label="When in first person mode (Mouselook)"
+     name="first_person"
+     value="0"/>
+    <combo_box.item
+     label="When editing avatar"
+     name="edit_avatar"
+     value="2"/>
+    <combo_box.item
+     label="When sitting"
+     name="sitting"
+     value="3"/>
+  </combo_box>
+
+  <button
+   follows="top|left"
+   layout="topleft"
+   top="6"
+   right="-10"
+   height="23"
+   width="140"
+   label="Restore Defaults"
+   tool_tip="Restores default values for all control modes."
+   name="restore_defaults"/>
+
+  <scroll_list
+   draw_heading="true"
+   follows="all"
+   layout="topleft"
+   column_padding="0"
+   selection_type="header"
+   top="31"
+   left="3"
+   bottom="-3"
+   right="-3"
+   can_sort="false"
+   multi_select="false"
+   name="controls_list"
+   fg_disable_color="ScrollUnselectedColor"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index 65b9a6411182d38133ae47f55c27167a5d40b2e5..2ea20570b18e39da29a3e874ffc58667c90b5fac 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -463,52 +463,13 @@
   enabled_control="EnableVoiceChat"
   control_name="PushToTalkToggle"
   height="15"
-  label="Toggle speak on/off when I press:"
+  label="Toggle speak on/off when I press button in toolbar"
   layout="topleft"
   left="44"
   name="push_to_talk_toggle_check"
   width="237"
   tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."
   top_pad="3"/>
-  <line_editor
-   follows="top|left"
-   control_name="PushToTalkButton"
-   enabled="false"
-   enabled_control="EnableVoiceChat"
-   height="23"
-   left="80"
-   max_length_bytes="200"
-   name="modifier_combo"
-   label="Push-to-Speak trigger"
-   top_pad="3"
-   width="200" />
-  <button
-   layout="topleft"
-   follows="top|left"
-   enabled_control="EnableVoiceChat"
-   height="23"
-   label="Set Key"
-   left_pad="5"
-   name="set_voice_hotkey_button"
-   width="100">
-    <button.commit_callback
-    function="Pref.VoiceSetKey" />
-  </button>
-  <button
-     enabled_control="EnableVoiceChat"
-     follows="top|left"
-     halign="center"
-     height="23"
-     image_overlay="Refresh_Off"
-     layout="topleft"
-     tool_tip="Reset to Middle Mouse Button"
-     mouse_opaque="true"
-     name="set_voice_middlemouse_button"
-     left_pad="5"
-     width="25">
-    <button.commit_callback
-    function="Pref.VoiceSetMiddleMouse" />
-  </button>
   <button
    control_name="ShowDeviceSettings"
    follows="left|top"
diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml
index 0e3de821d19c8c34aa1f3734b968bcd29ff24897..1ad78dbb13bf9c89248e6ed727685f5dafaf46c7 100644
--- a/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml
+++ b/indra/newview/skins/default/xui/en/panel_settings_sky_sunmoon.xml
@@ -38,7 +38,7 @@
                     height="10"
                     layout="topleft"
                     left_delta="10"
-                    top_delta="30"
+                    top_delta="25"
                     width="100">
                 Position:
             </text>
@@ -93,7 +93,7 @@
                     follows="left|top"
                     height="10"
                     layout="topleft"
-                    left_delta="-5"
+                    left_delta="65"
                     top_delta="20"
                     width="80">
                 Color:
@@ -108,12 +108,58 @@
                     name="sun_moon_color"
                     top_pad="5"
                     width="60" />
+          <text
+            follows="left|top"
+            height="10"
+            layout="topleft"
+            left_delta="-235"
+            top_delta="-3"
+            width="200">
+            Azimuth:
+          </text>
+          <slider
+            decimal_digits="2"
+            follows="left|top"
+            height="16"
+            increment="0.01"
+            initial_value="0"
+            layout="topleft"
+            left_delta="5"
+            min_val="0"
+            max_val="359.99"
+            name="sun_azimuth"
+            top_delta="13"
+            width="215"
+            can_edit_text="true"/>
+          <text
+            follows="left|top"
+            height="10"
+            layout="topleft"
+            left_delta="-5"
+            top_delta="22"
+            width="200">
+            Elevation:
+          </text>
+          <slider
+            decimal_digits="2"
+            follows="left|top"
+            height="16"
+            increment="0.01"
+            initial_value="0"
+            layout="topleft"
+            left_delta="5"
+            min_val="-90"
+            max_val="90"
+            name="sun_elevation"
+            top_delta="13"
+            width="215"
+            can_edit_text="true"/>
             <text
                     follows="left|top"
                     height="10"
                     layout="topleft"
-                    left_delta="-160"
-                    top_delta="27"
+                    left_delta="-5"
+                    top_delta="22"
                     width="200">
                 Glow Focus:
             </text>
@@ -128,8 +174,8 @@
                     min_val="-2"
                     max_val="2"
                     name="glow_focus"
-                    top_delta="15"
-                    width="250"
+                    top_delta="13"
+                    width="215"
                     can_edit_text="true"/>
             <text
                     follows="left|top"
@@ -151,8 +197,8 @@
                     min_val="0"
                     max_val="1.99"
                     name="glow_size"
-                    top_delta="15"
-                    width="250"
+                    top_delta="13"
+                    width="215"
                     can_edit_text="true"/>
             <text
                     follows="left|top"
@@ -174,20 +220,20 @@
                     min_val="0"
                     max_val="500"
                     name="star_brightness"
-                    top_delta="15"
-                    width="250"
+                    top_delta="13"
+                    width="215"
                     can_edit_text="true"/>
                     
             <check_box
                     control_name="sunbeacon"
+                    follows="left|top"
+                    layout="topleft"
                     width="60"
                     height="16"
                     label="Show Beacon"
-                    layout="topleft"
-                    name="sunbeacon" 
-                    right="-50"
-                    bottom="-10"
-                    follows="bottom|right"/>
+                    name="sunbeacon"
+                    top_pad="5"
+                    left_delta="-8"/>
                     
         </layout_panel>
         <layout_panel
@@ -227,7 +273,7 @@
                             height="10"
                             layout="topleft"
                             left_delta="10"
-                            top_delta="30"
+                            top_delta="25"
                             width="100">
                         Position:
                     </text>
@@ -278,39 +324,85 @@
                             top_delta="15"
                             width="130"
                             can_edit_text="true"/>
-                    <text
-                            follows="left|top"
-                            height="10"
-                            layout="topleft"
-                            left_delta="-5"
-                            top_delta="22"
-                            width="200">
-                        Brightness:
-                    </text>
-                    <slider
-                            decimal_digits="2"
-                            follows="left|top"
-                            height="16"
-                            increment="0.01"
-                            initial_value="0"
-                            layout="topleft"
-                            left_delta="5"
-                            min_val="0.0"
-                            max_val="1.0"
-                            name="moon_brightness"
-                            top_delta="15"
-                            width="130"
-                            can_edit_text="true"/>
-                <check_box
+                  <text
+                    follows="left|top"
+                    height="10"
+                    layout="topleft"
+                    left_delta="-170"
+                    top_delta="32"
+                    width="200">
+                    Azimuth:
+                  </text>
+                  <slider
+                    decimal_digits="2"
+                    follows="left|top"
+                    height="16"
+                    increment="0.01"
+                    initial_value="0"
+                    layout="topleft"
+                    left_delta="5"
+                    min_val="0"
+                    max_val="359.99"
+                    name="moon_azimuth"
+                    top_delta="13"
+                    width="215"
+                    can_edit_text="true"/>
+                  <text
+                    follows="left|top"
+                    height="10"
+                    layout="topleft"
+                    left_delta="-5"
+                    top_delta="22"
+                    width="200">
+                    Elevation:
+                  </text>
+                  <slider
+                    decimal_digits="2"
+                    follows="left|top"
+                    height="16"
+                    increment="0.01"
+                    initial_value="0"
+                    layout="topleft"
+                    left_delta="5"
+                    min_val="-90"
+                    max_val="90"
+                    name="moon_elevation"
+                    top_delta="13"
+                    width="215"
+                    can_edit_text="true"/>
+                  <text
+                    follows="left|top"
+                    height="10"
+                    layout="topleft"
+                    left_delta="-5"
+                    top_delta="22"
+                    width="200">
+                    Brightness:
+                  </text>
+                  <slider
+                    decimal_digits="2"
+                    follows="left|top"
+                    height="16"
+                    increment="0.01"
+                    initial_value="0"
+                    layout="topleft"
+                    left_delta="5"
+                    min_val="0.0"
+                    max_val="1.0"
+                    name="moon_brightness"
+                    top_delta="13"
+                    width="215"
+                    can_edit_text="true"/>
+                  <check_box
                         control_name="moonbeacon"
+                        follows="left|top"
+                        layout="topleft"
                         width="60"
                         height="16"
                         label="Show Beacon"
-                        layout="topleft"
                         name="moonbeacon" 
-                        right="-50"
-                        bottom="-10"
-                        follows="bottom|right"/>
+                        top_pad="5"
+                        left_delta="-8"/>
                             
                 </layout_panel>
             </layout_stack>
diff --git a/indra/newview/skins/default/xui/en/panel_teleport_history.xml b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
index 768efc2f3f116098c3a1bd45191d549b546d272d..55c47c90a49c661e95f705a6af25f3e1e89cffc4 100644
--- a/indra/newview/skins/default/xui/en/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/en/panel_teleport_history.xml
@@ -6,7 +6,7 @@
      bg_alpha_color="DkGray">     
     <accordion
      follows="left|top|right|bottom"
-     height="373"
+     height="400"
      layout="topleft"
      left="3"
      top="0"
@@ -147,37 +147,4 @@
 	        </flat_list_view>
 	    </accordion_tab>
     </accordion>
-    <panel
-     background_visible="true"
-     bevel_style="none"
-     bottom="0"
-     follows="left|right|bottom"
-     height="27"
-     layout="bottomleft"
-     left="3"
-     name="bottom_panel"
-     width="313">
-        <menu_button
-         follows="bottom|left"
-         tool_tip="Show additional options"
-         height="25"
-         image_hover_unselected="Toolbar_Left_Over"
-         image_overlay="OptionsMenu_Off"
-         image_selected="Toolbar_Left_Selected"
-         image_unselected="Toolbar_Left_Off"
-         layout="topleft"
-         left="0"
-         name="gear_btn"
-         top="1"
-         width="31" />
-        <icon
-         follows="bottom|left|right"
-         height="25"
-         image_name="Toolbar_Right_Off"
-         layout="topleft"
-         left_pad="1"
-         name="dummy_icon"
-         width="273"
-        />
-    </panel>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/rlva_strings.xml b/indra/newview/skins/default/xui/en/rlva_strings.xml
index 3ffb3d90094faa6b79b16e959a6ecb84b45d39a9..95321f7ac68ba2b992279cda923d5bc8cbf01052 100644
--- a/indra/newview/skins/default/xui/en/rlva_strings.xml
+++ b/indra/newview/skins/default/xui/en/rlva_strings.xml
@@ -194,14 +194,25 @@
 			<key>customizable</key>
 			<boolean>1</boolean>
 		</map>
-		<key>blocked_tplurerequest_remote</key>
+		<key>blocked_tplure_remote</key>
 		<map>
 			<key>value</key>
 			<string>The Resident is currently prevented from accepting. Please try again later.</string>
 			<key>description</key>
-			<string>Sent to the remote party when their teleport offer or request was blocked</string>
+			<string>Sent to the remote party when their teleport offer was blocked</string>
 			<key>label</key>
-			<string>Blocked teleport offer/request (remote)</string>
+			<string>Blocked teleport offer (remote)</string>
+			<key>customizable</key>
+			<boolean>1</boolean>
+		</map>
+		<key>blocked_tprequest_remote</key>
+		<map>
+			<key>value</key>
+			<string>The Resident is currently prevented from accepting. Please try again later.</string>
+			<key>description</key>
+			<string>Sent to the remote party when their teleport request was blocked</string>
+			<key>label</key>
+			<string>Blocked teleport request (remote)</string>
 			<key>customizable</key>
 			<boolean>1</boolean>
 		</map>
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 97382b669e641e86a3350b1211676ca79170b59f..aa2868b877c79d463e9cc4f0a21502de290f5f26 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2302,9 +2302,10 @@ For AI Character: Get the closest navigable point to the point provided.
 
 	<!-- inventory -->
 	<string name="InventoryNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/all/[SEARCH_TERM] Search].</string>
-	<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>
-	<string name="PlacesNoMatchingItems">Didn't find what you're looking for? Try [secondlife:///app/search/places/[SEARCH_TERM] Search].</string>
-	<string name="FavoritesNoMatchingItems">Drag a landmark here to add it to your favorites.</string>
+	<string name="InventoryNoMatchingRecentItems">Didn't find what you're looking for? Try [secondlife:///app/inventory/filters Show filters].</string>	
+	<string name="PlacesNoMatchingItems">To add a place to your landmarks, click the star to the right of the location name.</string>
+	<string name="FavoritesNoMatchingItems">To add a place to your favorites bar, click the star to the right of the location name.</string>
+	<string name="MarketplaceNoListing">You have no listings yet.</string>
 	<string name="MarketplaceNoMatchingItems">No items found. Check the spelling of your search string and try again.</string>
 	<string name="InventoryNoTexture">You do not have a copy of this texture in your inventory</string>
 	<string name="InventoryInboxNoItems">Your Marketplace purchases will appear here. You may then drag them into your inventory to use them.</string>
@@ -2423,6 +2424,7 @@ If you continue to receive this message, please contact Second Life support for
 	<string name="Scripts"       value=" Scripts," />
 	<string name="Sounds"        value=" Sounds," />
 	<string name="Textures"      value=" Textures," />
+	<string name="Settings"      value=" Settings," />
 	<string name="Snapshots"     value=" Snapshots," />
 	<string name="No Filters"    value="No " />
 	<string name="Since Logoff"  value=" - Since Logoff" />
@@ -2840,7 +2842,6 @@ If you continue to receive this message, please contact Second Life support for
 	<string name="AcquiredItems">Acquired Items</string>
 	<string name="Cancel">Cancel</string>
 	<string name="UploadingCosts">Uploading [NAME] costs L$ [AMOUNT]</string>
-	<string name="BuyingCosts">Buying this costs L$ [AMOUNT]</string>
 	<string name="UnknownFileExtension">
 		Unknown file extension .%s
 Expected .wav, .tga, .bmp, .jpg, .jpeg, or .anim
@@ -3702,10 +3703,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
   Also there are some other places where "generic" is used.
   So, let add string with name="generic" with the same value as "generic_request_error" -->
   <string name="generic">
-    Error making request, please try again later.
+    Please close and reopen the conversation, or relog and try again.
   </string>
   <string name="generic_request_error">
-    Error making request, please try again later.
+    Please close and reopen the conversation, or relog and try again.
   </string>
   <string name="insufficient_perms_error">
     You do not have sufficient permissions.
@@ -3766,6 +3767,9 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
   </string>
   <string name="unread_chat_multiple">
     [SOURCES] have said something new
+  </string>
+  <string name="teleport_preamble_compact_chat">
+    You are now at
   </string>
 	<string name="session_initialization_timed_out_error">
 		The session initialization is timed out
@@ -3776,6 +3780,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
   <string name="voice_morphing_url">https://secondlife.com/destination/voice-island</string>
   <string name="premium_voice_morphing_url">https://secondlife.com/destination/voice-morphing-premium</string>
 
+  <string name="lindenhomes_get_home_url">https://secondlife.com/land/lindenhomes/member.php</string>
+  <string name="lindenhomes_my_home_url">https://land.secondlife.com/en-Us/lindenhomes/my-home.php</string>
+  <string name="membership_url">https://secondlife.com/my/account/membership.php</string>
+
   <!-- Financial operations strings -->
   <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT] [REASON].</string>
   <string name="paid_you_ldollars_gift">[NAME] paid you L$[AMOUNT]: [REASON]</string>
@@ -3799,11 +3807,12 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
   <string name="to upload">to upload</string>
   <string name="to publish a classified ad">to publish a classified ad</string>
 
-  <string name="giving">Giving L$ [AMOUNT]</string>
   <string name="uploading_costs">Uploading costs L$ [AMOUNT]</string>
   <string name="this_costs">This costs L$ [AMOUNT]</string>
-  <string name="buying_selected_land">Buying selected land for L$ [AMOUNT]</string>
-  <string name="this_object_costs">This object costs L$ [AMOUNT]</string>
+  
+  <string name="buying_selected_land">This land costs</string>
+  <string name="this_object_costs">This item costs</string>
+  <string name="giving">You want to give</string>
 
   <string name="group_role_everyone">Everyone</string>
   <string name="group_role_officers">Officers</string>
@@ -3966,6 +3975,9 @@ Please check http://status.secondlifegrid.net to see if there is a known problem
   <string name="Premium PlusMembership">Premium Plus</string>
   <string name="InternalMembership">Internal</string> <!-- No need to translate -->
 
+  <string name="MembershipUpgradeText">Upgrade to Premium</string>
+  <string name="MembershipPremiumText">My Premium membership</string>
+
   <!-- Question strings for delete items notifications -->
   <string name="DeleteItems">Delete selected items?</string>
   <string name="DeleteItem">Delete selected item?</string>
@@ -4099,6 +4111,15 @@ Try enclosing path to the editor with double quotes.
   <string name="Z">Z</string>
   <!-- Key names end -->
 
+  <!-- Mouse button names (short) begin -->
+  <string name="LMB">LMB</string>
+  <string name="MMB">MMB</string>
+  <string name="RMB">RMB</string>
+  <string name="MB4">MB4</string>
+  <string name="MB5">MB5</string>
+  <string name="Double LMB">Double LMB</string>
+  <!-- Mouse button names end -->
+
   <!-- llviewerwindow -->
   <string name="BeaconParticle">Viewing particle beacons (blue)</string>
   <string name="BeaconPhysical">Viewing physical object beacons (green)</string>
@@ -4113,8 +4134,8 @@ Try enclosing path to the editor with double quotes.
   <!-- commands -->
 
   <string name="Command_AboutLand_Label">About land</string>
-  <string name="Command_Appearance_Label">Appearance</string>
-  <string name="Command_Avatar_Label">Avatar</string>
+  <string name="Command_Appearance_Label">Outfits</string>
+  <string name="Command_Avatar_Label">Complete avatars</string>
   <string name="Command_Build_Label">Build</string>
   <string name="Command_Chat_Label">Chat</string>
   <string name="Command_Conversations_Label">Conversations</string>
@@ -4123,7 +4144,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_Environments_Label">My Environments</string>
   <string name="Command_Gestures_Label">Gestures</string>
   <string name="Command_Grid_Status_Label">Grid status</string>
-  <string name="Command_HowTo_Label">How to</string>
+  <string name="Command_HowTo_Label">Guidebook</string>
   <string name="Command_Inventory_Label">Inventory</string>
   <string name="Command_Map_Label">Map</string>
   <string name="Command_Marketplace_Label">Marketplace</string>
diff --git a/indra/newview/skins/default/xui/en/teleport_strings.xml b/indra/newview/skins/default/xui/en/teleport_strings.xml
index 57f8bb542de1fbde1d87885bc8471be964b50020..1456114b25a42ce1ea1239205ce3c738ee27f075 100644
--- a/indra/newview/skins/default/xui/en/teleport_strings.xml
+++ b/indra/newview/skins/default/xui/en/teleport_strings.xml
@@ -2,8 +2,7 @@
 <teleport_messages>
 	<message_set name="errors">
 		<message name="invalid_tport">
-			Problem encountered processing your teleport request. You may need to log back in before you can teleport.
-If you continue to get this message, please check the [SUPPORT_SITE].
+			Teleport attempts are limited to 6 per minute. If you are having trouble, wait one minute and try teleporting again. If the problem persists, log out and log in again.
 		</message>
 		<message name="invalid_region_handoff">
 			Problem encountered processing your region crossing. You may need to log back in before you can cross regions.
diff --git a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
index 2cc4abdd3038c32019e47d4aa5f9c0df60d2bb7c..1c4822b8d5be373e15eedf18e32c9ca677c2953e 100644
--- a/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/filter_editor.xml
@@ -6,9 +6,11 @@
   text_pad_left="7"
   select_on_focus="true"
   text_tentative_color="TextFgTentativeColor"
+  highlight_text_field="false"
   background_image="TextField_Search_Off"
   background_image_disabled="TextField_Search_Disabled"
-  background_image_focused="TextField_Search_Active">
+  background_image_focused="TextField_Search_Active"
+  background_image_highlight="TextField_Search_Highlight">
   <search_button label=""
     top_pad="4"
     left_pad="4"
diff --git a/indra/newview/skins/default/xui/en/widgets/search_editor.xml b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
index faa0404b3547251814d9900bae85c8c33af1e3f7..dc5a07bf4f40bed427dc297869ef542a5ddd13f0 100644
--- a/indra/newview/skins/default/xui/en/widgets/search_editor.xml
+++ b/indra/newview/skins/default/xui/en/widgets/search_editor.xml
@@ -7,9 +7,11 @@
   text_pad_right="6" 
   select_on_focus="true"
   text_tentative_color="TextFgTentativeColor"
+  highlight_text_field="false"
   background_image="TextField_Search_Off"
   background_image_disabled="TextField_Search_Disabled"
-  background_image_focused="TextField_Search_Active" >
+  background_image_focused="TextField_Search_Active"
+  background_image_highlight="TextField_Search_Highlight">
   <search_button 
     top_pad="4"
     left_pad="4" 
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 57f2d31eabe68f3da8940dac7a00cb21958ceb06..f9abc8b25d643a546dfacb841f377b51c23709d0 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -41,6 +41,7 @@
 #include "../test/lltut.h"
 #include "llevents.h"
 #include "llnotificationsutil.h"
+#include "lltrans.h"
 
 #if defined(LL_WINDOWS)
 #pragma warning(disable: 4355)      // using 'this' in base-class ctor initializer expr
@@ -77,6 +78,11 @@ void LLViewerWindow::setShowProgress(BOOL show) {}
 LLProgressView * LLViewerWindow::getProgressView(void) const { return 0; }
 
 LLViewerWindow* gViewerWindow;
+
+std::string LLTrans::getString(const std::string &xml_desc, const LLStringUtil::format_map_t& args, bool def_string)
+{
+    return std::string("test_trans");
+}
 	
 class LLLogin::Impl
 {
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 6d231040f77b21c2bc8fb1cd7dc6a67ebb3eb212..adac7af71235ea45c359ede17115d61058012093 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -533,6 +533,9 @@ def construct(self):
             # For textures
             self.path("openjpeg.dll")
 
+            # Uriparser
+            self.path("uriparser.dll")
+
             # These need to be installed as a SxS assembly, currently a 'private' assembly.
             # See http://msdn.microsoft.com/en-us/library/ms235291(VS.80).aspx
             self.path("msvcp140.dll")
@@ -1035,6 +1038,7 @@ def path_optional(src, dst):
                                 # libnghttp2.major.dylib, which is a symlink to
                                 # libnghttp2.version.dylib. Get all of them.
                                 "libnghttp2.*dylib",
+                                "liburiparser.*dylib",
                                 ):
                     dylibs += path_optional(os.path.join(relpkgdir, libfile), libfile)
 
diff --git a/scripts/content_tools/arche_tool.py b/scripts/content_tools/arche_tool.py
index 23c96fc64ef40b605dbeb19a3dc9a09434986e3d..f99d7be39ad7be65dfb47bce1223bcfee26e425f 100644
--- a/scripts/content_tools/arche_tool.py
+++ b/scripts/content_tools/arche_tool.py
@@ -79,15 +79,32 @@ def compare_trees(file_trees):
     print "Summary:"
     print summary
                 
-
+def dump_appearance_params(tree):
+    vals = []
+    for e in tree.getroot().iter():
+        if e.tag == "param":
+            g = int(e.get("group"))
+            if g in [0,3]:
+                vals.append("{" + e.get("id") + "," +e.get("u8") + "}")
+                #print e.get("id"), e.get("name"), e.get("group"), e.get("u8")
+    if len(vals)==253:
+        print ", ".join(vals)
+        
+    
 if __name__ == "__main__":
 
     parser = argparse.ArgumentParser(description="compare avatar XML archetype files")
     parser.add_argument("--verbose", help="verbose flag", action="store_true")
+    parser.add_argument("--compare", help="compare flag", action="store_true")
+    parser.add_argument("--appearance_params", help="compare flag", action="store_true")
     parser.add_argument("files", nargs="+", help="name of one or more archtype files")
     args = parser.parse_args()
 
 
     print "files",args.files
     file_trees = [etree.parse(filename) for filename in args.files]
-    compare_trees(file_trees)
+    print args
+    if args.compare:
+        compare_trees(file_trees)
+    if args.appearance_params:
+        dump_appearance_params(file_trees[0])