diff --git a/.hgtags b/.hgtags
index 47413e0553341bd8f4561f665b59a6b43cb13c17..a832521ac3898eb30ffcda90e907b053d083cc91 100755
--- a/.hgtags
+++ b/.hgtags
@@ -525,3 +525,4 @@ b41e1e7c7876f7656c505f552b5888b4e478f92b 5.0.0-release
 c9ce2295012995e3cf5c57bcffcb4870b94c649f 5.0.1-release
 cea1632c002c065985ebea15eeeb4aac90f50545 5.0.2-release
 02c24e9f4f7d8aa0de75f27817dda098582f4936 5.0.3-release
+022709ef76a331cac1ba6ef1a6da8a5e9ef63f5a 5.0.4-release
diff --git a/README.md b/README.md
index 6eddb9aa9ed727c28b7cea1e33e0a35a9ff6822f..b80277370a27e5ed3161490aeaf13bf9b824bdf8 100644
--- a/README.md
+++ b/README.md
@@ -14,4 +14,3 @@ To download the current default version, visit
 [the download page](https://secondlife.com/support/downloads). For
 even newer versions try
 [the Alternate Viewers page](https://wiki.secondlife.com/wiki/Linden_Lab_Official:Alternate_Viewers)
-
diff --git a/autobuild.xml b/autobuild.xml
index ce556357cec6bc644b23894cd2bb7b387b10e0df..a854a45e8436faf77b1a826d64f7793ccd91cb3e 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -76,9 +76,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>ae733dd8f2c83055030ea6e08c623306</string>
+              <string>f65774ebabb256f2d217a872b0cf2b5b</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/745/1534/apr_suite-1.4.5.500735-darwin64-500735.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4812/15284/apr_suite-1.4.5.504800-darwin64-504800.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -100,9 +100,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>bc8855c8253b8293c7e61af7b1ed0f05</string>
+              <string>84a1a140f20b25d714949185e854d14b</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/744/1545/apr_suite-1.4.5.500735-linux64-500735.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4811/15302/apr_suite-1.4.5.504800-linux64-504800.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux64</string>
@@ -112,9 +112,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7d97a3788ea4f89eccb7789e4f015bb3</string>
+              <string>dc80eca3d113b038b469003da8cd6638</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/747/1540/apr_suite-1.4.5.500735-windows-500735.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4813/15290/apr_suite-1.4.5.504800-windows-504800.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -124,16 +124,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>8820c4df1079a9af53f52485f50ff179</string>
+              <string>63146d3d3d5fe7aa6be1a1b0afed36dd</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/746/1537/apr_suite-1.4.5.500735-windows64-500735.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4814/15296/apr_suite-1.4.5.504800-windows64-504800.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.4.5.500735</string>
+        <string>1.4.5.504800</string>
       </map>
       <key>boost</key>
       <map>
@@ -526,9 +526,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>1517ca15cd1209b0910a8f6720c65cb4</string>
+              <string>da5c705fa4fae169cba26fba92dba1ef</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/3408/8552/dullahan-1.1.636_3.2987.1591.gd3e47f5-darwin64-503397.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4835/15404/dullahan-1.1.800_3.3029.1611.g44e39a8-darwin64-504824.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -538,9 +538,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>5dc1349abce3ccb04c6ac79a0ff19d59</string>
+              <string>17cd8f6e8f95df877d0c9c234f860324</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/3410/8559/dullahan-1.1.636_3.2987.1591.gd3e47f5-windows-503397.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4836/15410/dullahan-1.1.800_3.3029.1611.g44e39a8-windows-504824.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -550,16 +550,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>928db398436823aa804046de91339177</string>
+              <string>7a478f8f0e13f5f81cab657a8c351186</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/3409/8562/dullahan-1.1.636_3.2987.1591.gd3e47f5-windows64-503397.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4837/15415/dullahan-1.1.800_3.3029.1611.g44e39a8-windows64-504824.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.1.636_3.2987.1591.gd3e47f5</string>
+        <string>1.1.800_3.3029.1611.g44e39a8</string>
       </map>
       <key>elfio</key>
       <map>
@@ -1376,9 +1376,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>cbaa7619050123c3fd2a88959f88bd47</string>
+              <string>a0c4405c9e44d4a0135fe20ba8cfbace</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/749/1553/havok_source-2012.1-2-darwin64-500739.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4693/14627/havok_source-2012.1-2-darwin64-504680.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -1412,9 +1412,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>dab55cc0555d7126fda925e20af851ea</string>
+              <string>035572a1929be66f6c56468e0ef7fe74</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1194/2807/havok_source-2012.1-2-windows-501181.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4695/14637/havok_source-2012.1-2-windows-504680.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -1424,9 +1424,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>7bbc1c3512a5665b7576b4b0357a9eb7</string>
+              <string>d8525d2fbb9e0f7bc31427b47350e468</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1195/2816/havok_source-2012.1-2-windows64-501181.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4694/14634/havok_source-2012.1-2-windows64-504680.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
@@ -2182,9 +2182,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>e2b519ee7538b25877e34ede6864a250</string>
+              <string>162a3fc9b66626072ec8679361b174f5</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1691/3748/llphysicsextensions_source-1.0.501678-darwin64-501678.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4722/14837/llphysicsextensions_source-1.0.504710-darwin64-504710.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2194,9 +2194,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9b2c1f53f7f1add01af1e7cfa737e20e</string>
+              <string>c1b43e99c5ddccc18b0e9cb288bf75e1</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1689/3734/llphysicsextensions_source-1.0.501678-linux64-501678.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4721/14828/llphysicsextensions_source-1.0.504710-linux64-504710.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux64</string>
@@ -2206,16 +2206,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>5e8cb92ae79c9435b98e444322ec5798</string>
+              <string>dd85c9e0f5fa3ce483ea183db008c4bc</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/1696/3763/llphysicsextensions_source-1.0.501678-windows-501678.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/4726/14858/llphysicsextensions_source-1.0.504710-windows-504710.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.501678</string>
+        <string>1.0.504710</string>
       </map>
       <key>llphysicsextensions_stub</key>
       <map>
@@ -2234,9 +2234,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>32309a20161f54f42d08f7bc1e7fcf01</string>
+              <string>566aa2c6f5b2f40a8b0bedf90d9c6beb</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1692/3749/llphysicsextensions_stub-1.0.501679-darwin64-501679.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4723/14838/llphysicsextensions_stub-1.0.504712-darwin64-504712.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2246,9 +2246,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>58af530891721f3690a4dce9a8c73190</string>
+              <string>711f4ec769e4b5f59ba25ee43c11bcbc</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1690/3739/llphysicsextensions_stub-1.0.501679-linux64-501679.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4724/14846/llphysicsextensions_stub-1.0.504712-linux64-504712.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux64</string>
@@ -2258,16 +2258,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c59cb5d1dd96ab51f87cd0cf202304dd</string>
+              <string>d830aca10ea9396557b1e613c2736e49</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/1695/3757/llphysicsextensions_stub-1.0.501679-windows-501679.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/ct2/4725/14853/llphysicsextensions_stub-1.0.504712-windows-504712.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
           </map>
         </map>
         <key>version</key>
-        <string>1.0.501679</string>
+        <string>1.0.504712</string>
       </map>
       <key>mesa</key>
       <map>
@@ -3496,7 +3496,6 @@
                 <array>
                   <string>-G</string>
                   <string>Xcode</string>
-                  <string>-DHAVOK:BOOL=OFF</string>
                 </array>
               </map>
               <key>default</key>
@@ -3524,7 +3523,6 @@
                 <array>
                   <string>-G</string>
                   <string>Xcode</string>
-                  <string>-DHAVOK:BOOL=OFF</string>
                 </array>
               </map>
               <key>name</key>
@@ -3558,7 +3556,6 @@
                 <array>
                   <string>-G</string>
                   <string>Xcode</string>
-                  <string>-DHAVOK:BOOL=OFF</string>
                 </array>
               </map>
               <key>name</key>
@@ -3584,7 +3581,6 @@
                 <array>
                   <string>-G</string>
                   <string>Xcode</string>
-                  <string>-DHAVOK:BOOL=OFF</string>
                 </array>
               </map>
               <key>name</key>
diff --git a/build.sh b/build.sh
index 9ca130b5d53d1a76c7317f3f0a13fd323d687070..a8f4158bfff28ffd736f53bac70895688280f63d 100755
--- a/build.sh
+++ b/build.sh
@@ -97,14 +97,14 @@ pre_build()
 
     # nat 2016-12-20: disable HAVOK on Mac until we get a 64-bit Mac build.
     RELEASE_CRASH_REPORTING=ON
+    HAVOK=ON
     SIGNING=()
     if [ "$arch" == "Darwin" ]
-    then HAVOK=OFF
+    then
          if [ "$variant" == "Release" ]
          then SIGNING=("-DENABLE_SIGNING:BOOL=YES" \
                        "-DSIGNING_IDENTITY:STRING=Developer ID Application: Linden Research, Inc.")
          fi
-    else HAVOK=ON
     fi
 
     "$autobuild" configure --quiet -c $variant -- \
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index f925fdda5de7c2875cdc617784ba4287effe3c52..f79228065465a517d9fff849d2c019c1f1a2434a 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -19,7 +19,9 @@ set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
 include(Variables)
 
 # We go to some trouble to set LL_BUILD to the set of relevant compiler flags.
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}")
+set(CMAKE_CXX_FLAGS_RELEASE "$ENV{LL_BUILD_RELEASE}")
+set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "$ENV{LL_BUILD_RELWITHDEBINFO}")
+set(CMAKE_CXX_FLAGS_DEBUG "$ENV{LL_BUILD_DEBUG}")
 # Given that, all the flags you see added below are flags NOT present in
 # https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables.
 # Before adding new ones here, it's important to ask: can this flag really be
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 14510d654fc346afd6b480d2f54badd320f0294e..43188673eba6c95b10f5bae68cd1b5c5fc4e364b 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -67,8 +67,9 @@ if(WINDOWS)
     endif (MSVC80)
 
     # try to copy VS2010 redist independently of system version
-    list(APPEND LMSVC_VER 100)
-    list(APPEND LMSVC_VERDOT 10.0)
+    # maint-7360 CP
+    # list(APPEND LMSVC_VER 100)
+    # list(APPEND LMSVC_VERDOT 10.0)
     
     list(LENGTH LMSVC_VER count)
     math(EXPR count "${count}-1")
@@ -102,12 +103,17 @@ if(WINDOWS)
             unset(debug_msvc_redist_path CACHE)
         endif()
 
+        if(ADDRESS_SIZE EQUAL 32)
+            # this folder contains the 32bit DLLs.. (yes really!)
+            set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64")
+        else(ADDRESS_SIZE EQUAL 32)
+            # this folder contains the 64bit DLLs.. (yes really!)
+            set(registry_find_path "[HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32")
+        endif(ADDRESS_SIZE EQUAL 32)
+
         FIND_PATH(release_msvc_redist_path NAME msvcr${MSVC_VER}.dll
             PATHS            
-            [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\VisualStudio\\${MSVC_VERDOT}\\Setup\\VC;ProductDir]/redist/x86/Microsoft.VC${MSVC_VER}.CRT
-            [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/SysWOW64
-            [HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Control\\Windows;Directory]/System32
-            ${MSVC_REDIST_PATH}
+            ${registry_find_path}
             NO_DEFAULT_PATH
             )
 
diff --git a/indra/cmake/Havok.cmake b/indra/cmake/Havok.cmake
index 99e73341184d6791c43fecedb878b58e89cbc291..811a126b8fbc1407a650d74ffaf6b63bbc1b4142 100644
--- a/indra/cmake/Havok.cmake
+++ b/indra/cmake/Havok.cmake
@@ -8,6 +8,11 @@ use_prebuilt_binary(havok-source)
 set(Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Source)
 list(APPEND Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Demo)
 
+# HK_DISABLE_IMPLICIT_VVECTOR3_CONVERSION suppresses an intended conversion
+# function which Xcode scolds us will unconditionally enter infinite
+# recursion if called. This hides that function.
+add_definitions("-DHK_DISABLE_IMPLICIT_VVECTOR3_CONVERSION")
+
 set(HAVOK_DEBUG_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
 set(HAVOK_RELEASE_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
 
@@ -49,89 +54,74 @@ unset(HK_DEBUG_LIBRARIES)
 unset(HK_RELEASE_LIBRARIES)
 unset(HK_RELWITHDEBINFO_LIBRARIES)
 
+if (DEBUG_PREBUILT)
+  # DEBUG_MESSAGE() displays debugging message
+  function(DEBUG_MESSAGE)
+    # prints message args separated by semicolons rather than spaces,
+    # but making it pretty is a lot more work
+    message(STATUS "${ARGN}")
+  endfunction(DEBUG_MESSAGE)
+else (DEBUG_PREBUILT)
+  # without DEBUG_PREBUILT, DEBUG_MESSAGE() is a no-op
+  function(DEBUG_MESSAGE)
+  endfunction(DEBUG_MESSAGE)
+endif (DEBUG_PREBUILT)
+
+# DEBUG_EXEC() reports each execute_process() before invoking
+function(DEBUG_EXEC)
+  DEBUG_MESSAGE(${ARGN})
+  execute_process(COMMAND ${ARGN})
+endfunction(DEBUG_EXEC)
+
 # *TODO: Figure out why we need to extract like this...
 foreach(HAVOK_LIB ${HAVOK_LIBS})
-        find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
-        find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
-        find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
-        
-        if(LINUX)
-            set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
-            set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
-            set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
+  find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
+  find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
+  find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
+  
+  if(LINUX)
+    set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
+    set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
+    set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
 
     # Try to avoid extracting havok library each time we run cmake.
     if("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted")
       file(READ ${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted "havok_${HAVOK_LIB}_extracted")
-      if(DEBUG_PREBUILT)
-        message(STATUS "havok_${HAVOK_LIB}_extracted: \"${havok_${HAVOK_LIB}_extracted}\"")
-      endif(DEBUG_PREBUILT)
+      DEBUG_MESSAGE("havok_${HAVOK_LIB}_extracted: \"${havok_${HAVOK_LIB}_extracted}\"")
     endif("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted")
 
     if(${PREBUILD_TRACKING_DIR}/havok_source_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
-      if(DEBUG_PREBUILT)
-        MESSAGE(STATUS "Extracting ${HAVOK_LIB}...")
-      endif(DEBUG_PREBUILT)
-      set(cmd "mkdir")
-
-      if(DEBUG_PREBUILT)
-        MESSAGE(STATUS "${cmd} ${debug_dir}")
-      endif(DEBUG_PREBUILT)
-            exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
-
-      if(DEBUG_PREBUILT)
-        MESSAGE(STATUS "${cmd} ${release_dir}")
-      endif(DEBUG_PREBUILT)
-            exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
-
-      if(DEBUG_PREBUILT)
-        MESSAGE(STATUS "${cmd} ${relwithdebinfo_dir}")
-      endif(DEBUG_PREBUILT)
-            exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
-
-            set(cmd "ar")
-            set(arg " -xv")
-            set(arg "${arg} ../lib${HAVOK_LIB}.a")
-      if(DEBUG_PREBUILT)
-        MESSAGE(STATUS "cd ${debug_dir} && ${cmd} ${arg}")
-      endif(DEBUG_PREBUILT)
-            exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
-
-      if(DEBUG_PREBUILT)
-        MESSAGE(STATUS "cd ${release_dir} && ${cmd} ${arg}")
-      endif(DEBUG_PREBUILT)
-            exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
-
-      if(DEBUG_PREBUILT)
-        MESSAGE(STATUS "cd ${relwithdebinfo_dir} && ${cmd} ${arg}")
-      endif(DEBUG_PREBUILT)
-            exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+      DEBUG_MESSAGE("Extracting ${HAVOK_LIB}...")
+
+      foreach(lib ${debug_dir} ${release_dir} ${relwithdebinfo_dir})
+        DEBUG_EXEC("mkdir" ${lib})
+        DEBUG_EXEC("ar" "-xv" "../lib${HAVOK_LIB}.a"
+          WORKING_DIRECTORY ${lib})
+      endforeach(lib)
 
       # Just assume success for now.
       set(havok_${HAVOK_LIB}_extracted 0)
       file(WRITE ${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted "${havok_${HAVOK_LIB}_extracted}")
 
-    endif(${PREBUILD_TRACKING_DIR}/havok_source_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
-
-            file(GLOB extracted_debug "${debug_dir}/*.o")
-            file(GLOB extracted_release "${release_dir}/*.o")
-            file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
-
-    if(DEBUG_PREBUILT)
-      MESSAGE(STATUS "extracted_debug ${debug_dir}/*.o")
-      MESSAGE(STATUS "extracted_release ${release_dir}/*.o")
-      MESSAGE(STATUS "extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o")
-    endif(DEBUG_PREBUILT)
-
-            list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
-            list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
-            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
-        else(LINUX)
-        # Win32
-            list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
-            list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
-            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
-        endif (LINUX)
+    endif()
+
+    file(GLOB extracted_debug "${debug_dir}/*.o")
+    file(GLOB extracted_release "${release_dir}/*.o")
+    file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
+
+    DEBUG_MESSAGE("extracted_debug ${debug_dir}/*.o")
+    DEBUG_MESSAGE("extracted_release ${release_dir}/*.o")
+    DEBUG_MESSAGE("extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o")
+
+    list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
+    list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
+    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
+  else(LINUX)
+    # Win32
+    list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
+    list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
+    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
+  endif (LINUX)
 endforeach(HAVOK_LIB)
 
 endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/LLSharedLibs.cmake b/indra/cmake/LLSharedLibs.cmake
index a3c1c871aadd72e0aa7e9bcdfdf44a893ead818e..f69b45cd926193e04ce625a7ae2ed0c1674d2d81 100644
--- a/indra/cmake/LLSharedLibs.cmake
+++ b/indra/cmake/LLSharedLibs.cmake
@@ -3,35 +3,38 @@
 macro(ll_deploy_sharedlibs_command target_exe) 
   set(TARGET_LOCATION $<TARGET_FILE:${target_exe}>)
   get_filename_component(OUTPUT_PATH ${TARGET_LOCATION} PATH)
-  
-  if(DARWIN)
-    SET_TEST_PATH(SEARCH_DIRS)
-    get_target_property(IS_BUNDLE ${target_exe} MACOSX_BUNDLE)
-    if(IS_BUNDLE)
-      # If its a bundle the exe is not in the target location, this should find it.
-      get_filename_component(TARGET_FILE ${TARGET_LOCATION} NAME)
-      set(OUTPUT_PATH ${TARGET_LOCATION}.app/Contents/MacOS)
-      set(TARGET_LOCATION ${OUTPUT_PATH}/${TARGET_FILE})
-      set(OUTPUT_PATH ${OUTPUT_PATH}/../Resources)
-    endif(IS_BUNDLE)
-  elseif(WINDOWS)
-    SET_TEST_PATH(SEARCH_DIRS)
-    LIST(APPEND SEARCH_DIRS "$ENV{SystemRoot}/system32")
-  elseif(LINUX)
-    SET_TEST_PATH(SEARCH_DIRS)
-    set(OUTPUT_PATH ${OUTPUT_PATH}/lib)
-  endif(DARWIN)
 
-  add_custom_command(
-    TARGET ${target_exe} POST_BUILD
-    COMMAND ${CMAKE_COMMAND} 
-    ARGS
-    "-DBIN_NAME=\"${TARGET_LOCATION}\""
-    "-DSEARCH_DIRS=\"${SEARCH_DIRS}\""
-    "-DDST_PATH=\"${OUTPUT_PATH}\""
-    "-P"
-    "${CMAKE_SOURCE_DIR}/cmake/DeploySharedLibs.cmake"
-    )
+  # It's not clear that this does anything useful for us on Darwin. It has
+  # been broken for some time now; the BIN_NAME was being constructed as a
+  # ridiculous nonexistent path with duplicated segments. Fixing that only
+  # produces ominous spammy warnings: at the time the command below is run, we
+  # have not yet populated the nested mac-crash-logger.app/Contents/Resources
+  # with the .dylibs with which it was linked. Moreover, the form of the
+  # embedded @executable_path/../Resources/mumble.dylib pathname confuses the
+  # GetPrerequisites.cmake tool invoked by DeploySharedLibs.cmake. It seems
+  # clear that we have long since accomplished by other means what this was
+  # originally supposed to do. Skipping it only eliminates an annoying
+  # non-fatal error.
+  if(NOT DARWIN)
+    if(WINDOWS)
+      SET_TEST_PATH(SEARCH_DIRS)
+      LIST(APPEND SEARCH_DIRS "$ENV{SystemRoot}/system32")
+    elseif(LINUX)
+      SET_TEST_PATH(SEARCH_DIRS)
+      set(OUTPUT_PATH ${OUTPUT_PATH}/lib)
+    endif(WINDOWS)
+
+    add_custom_command(
+      TARGET ${target_exe} POST_BUILD
+      COMMAND ${CMAKE_COMMAND} 
+      ARGS
+      "-DBIN_NAME=\"${TARGET_LOCATION}\""
+      "-DSEARCH_DIRS=\"${SEARCH_DIRS}\""
+      "-DDST_PATH=\"${OUTPUT_PATH}\""
+      "-P"
+      "${CMAKE_SOURCE_DIR}/cmake/DeploySharedLibs.cmake"
+      )
+  endif(NOT DARWIN)
 
 endmacro(ll_deploy_sharedlibs_command)
 
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 439ff4e628e965da33163f1592d9b432eb16f331..2d665c611b47418f6594eff3cc5a57e1200ec27b 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -41,7 +41,6 @@ static LLTrace::ThreadRecorder* sMasterThreadRecorder = NULL;
 //static
 void LLCommon::initClass()
 {
-	LLMemory::initClass();
 	if (!sAprInitialized)
 	{
 		ll_init_apr();
@@ -70,5 +69,4 @@ void LLCommon::cleanupClass()
 		ll_cleanup_apr();
 		sAprInitialized = FALSE;
 	}
-	SUBSYSTEM_CLEANUP(LLMemory);
 }
diff --git a/indra/llcommon/llmemory.cpp b/indra/llcommon/llmemory.cpp
index 1e04044269ff6cc6a1bc41935261b6dc1a60ef19..9f9c3af8923b62498d96e7853afbaf50f6a3ce34 100644
--- a/indra/llcommon/llmemory.cpp
+++ b/indra/llcommon/llmemory.cpp
@@ -44,10 +44,10 @@
 #include "llsys.h"
 #include "llframetimer.h"
 #include "lltrace.h"
+#include "llerror.h"
 //----------------------------------------------------------------------------
 
 //static
-char* LLMemory::reserveMem = 0;
 U32Kilobytes LLMemory::sAvailPhysicalMemInKB(U32_MAX);
 U32Kilobytes LLMemory::sMaxPhysicalMemInKB(0);
 static LLTrace::SampleStatHandle<F64Megabytes> sAllocatedMem("allocated_mem", "active memory in use by application");
@@ -78,29 +78,6 @@ void ll_assert_aligned_func(uintptr_t ptr,U32 alignment)
 #endif
 }
 
-//static
-void LLMemory::initClass()
-{
-	if (!reserveMem)
-	{
-		reserveMem = new char[16*1024]; // reserve 16K for out of memory error handling
-	}
-}
-
-//static
-void LLMemory::cleanupClass()
-{
-	delete [] reserveMem;
-	reserveMem = NULL;
-}
-
-//static
-void LLMemory::freeReserve()
-{
-	delete [] reserveMem;
-	reserveMem = NULL;
-}
-
 //static 
 void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure)
 {
@@ -111,19 +88,18 @@ void LLMemory::initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_f
 //static 
 void LLMemory::updateMemoryInfo() 
 {
-#if LL_WINDOWS	
-	HANDLE self = GetCurrentProcess();
+#if LL_WINDOWS
 	PROCESS_MEMORY_COUNTERS counters;
-	
-	if (!GetProcessMemoryInfo(self, &counters, sizeof(counters)))
+
+	if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)))
 	{
 		LL_WARNS() << "GetProcessMemoryInfo failed" << LL_ENDL;
 		return ;
 	}
 
-	sAllocatedMemInKB = (U32Bytes)(counters.WorkingSetSize) ;
+	sAllocatedMemInKB = U64Bytes(counters.WorkingSetSize) ;
 	sample(sAllocatedMem, sAllocatedMemInKB);
-	sAllocatedPageSizeInKB = (U32Bytes)(counters.PagefileUsage) ;
+	sAllocatedPageSizeInKB = U64Bytes(counters.PagefileUsage) ;
 	sample(sVirtualMem, sAllocatedPageSizeInKB);
 
 	U32Kilobytes avail_phys, avail_virtual;
@@ -140,9 +116,9 @@ void LLMemory::updateMemoryInfo()
 	}
 #else
 	//not valid for other systems for now.
-	sAllocatedMemInKB = (U32Bytes)LLMemory::getCurrentRSS();
-	sMaxPhysicalMemInKB = (U32Bytes)U32_MAX ;
-	sAvailPhysicalMemInKB = (U32Bytes)U32_MAX ;
+	sAllocatedMemInKB = U64Bytes(LLMemory::getCurrentRSS());
+	sMaxPhysicalMemInKB = U64Bytes(U32_MAX);
+	sAvailPhysicalMemInKB = U64Bytes(U32_MAX);
 #endif
 
 	return ;
@@ -169,7 +145,7 @@ void* LLMemory::tryToAlloc(void* address, U32 size)
 	return address ;
 #else
 	return (void*)0x01 ; //skip checking
-#endif	
+#endif
 }
 
 //static 
@@ -183,7 +159,7 @@ void LLMemory::logMemoryInfo(BOOL update)
 
 	LL_INFOS() << "Current allocated physical memory(KB): " << sAllocatedMemInKB << LL_ENDL ;
 	LL_INFOS() << "Current allocated page size (KB): " << sAllocatedPageSizeInKB << LL_ENDL ;
-	LL_INFOS() << "Current availabe physical memory(KB): " << sAvailPhysicalMemInKB << LL_ENDL ;
+	LL_INFOS() << "Current available physical memory(KB): " << sAvailPhysicalMemInKB << LL_ENDL ;
 	LL_INFOS() << "Current max usable memory(KB): " << sMaxPhysicalMemInKB << LL_ENDL ;
 
 	LL_INFOS() << "--- private pool information -- " << LL_ENDL ;
@@ -263,12 +239,12 @@ U32Kilobytes LLMemory::getAllocatedMemKB()
 
 #if defined(LL_WINDOWS)
 
+//static 
 U64 LLMemory::getCurrentRSS()
 {
-	HANDLE self = GetCurrentProcess();
 	PROCESS_MEMORY_COUNTERS counters;
-	
-	if (!GetProcessMemoryInfo(self, &counters, sizeof(counters)))
+
+	if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters)))
 	{
 		LL_WARNS() << "GetProcessMemoryInfo failed" << LL_ENDL;
 		return 0;
@@ -277,35 +253,8 @@ U64 LLMemory::getCurrentRSS()
 	return counters.WorkingSetSize;
 }
 
-//static 
-U32 LLMemory::getWorkingSetSize()
-{
-    PROCESS_MEMORY_COUNTERS pmc ;
-	U32 ret = 0 ;
-
-    if (GetProcessMemoryInfo( GetCurrentProcess(), &pmc, sizeof(pmc)) )
-	{
-		ret = pmc.WorkingSetSize ;
-	}
-
-	return ret ;
-}
-
 #elif defined(LL_DARWIN)
 
-/* 
-	The API used here is not capable of dealing with 64-bit memory sizes, but is available before 10.4.
-	
-	Once we start requiring 10.4, we can use the updated API, which looks like this:
-	
-	task_basic_info_64_data_t basicInfo;
-	mach_msg_type_number_t  basicInfoCount = TASK_BASIC_INFO_64_COUNT;
-	if (task_info(mach_task_self(), TASK_BASIC_INFO_64, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
-	
-	Of course, this doesn't gain us anything unless we start building the viewer as a 64-bit executable, since that's the only way
-	for our memory allocation to exceed 2^32.
-*/
-
 // 	if (sysctl(ctl, 2, &page_size, &size, NULL, 0) == -1)
 // 	{
 // 		LL_WARNS() << "Couldn't get page size" << LL_ENDL;
@@ -318,9 +267,9 @@ U32 LLMemory::getWorkingSetSize()
 U64 LLMemory::getCurrentRSS()
 {
 	U64 residentSize = 0;
-	task_basic_info_data_t basicInfo;
-	mach_msg_type_number_t  basicInfoCount = TASK_BASIC_INFO_COUNT;
-	if (task_info(mach_task_self(), TASK_BASIC_INFO, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
+	task_basic_info_64_data_t basicInfo;
+	mach_msg_type_number_t  basicInfoCount = TASK_BASIC_INFO_64_COUNT;
+	if (task_info(mach_task_self(), TASK_BASIC_INFO_64, (task_info_t)&basicInfo, &basicInfoCount) == KERN_SUCCESS)
 	{
 		residentSize = basicInfo.resident_size;
 
@@ -337,11 +286,6 @@ U64 LLMemory::getCurrentRSS()
 	return residentSize;
 }
 
-U32 LLMemory::getWorkingSetSize()
-{
-	return 0 ;
-}
-
 #elif defined(LL_LINUX)
 
 U64 LLMemory::getCurrentRSS()
@@ -353,7 +297,7 @@ U64 LLMemory::getCurrentRSS()
 	if (fp == NULL)
 	{
 		LL_WARNS() << "couldn't open " << statPath << LL_ENDL;
-		goto bail;
+		return 0;
 	}
 
 	// Eee-yew!	 See Documentation/filesystems/proc.txt in your
@@ -372,15 +316,9 @@ U64 LLMemory::getCurrentRSS()
 	
 	fclose(fp);
 
-bail:
 	return rss;
 }
 
-U32 LLMemory::getWorkingSetSize()
-{
-	return 0 ;
-}
-
 #elif LL_SOLARIS
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -410,11 +348,6 @@ U64 LLMemory::getCurrentRSS()
 	return((U64)proc_psinfo.pr_rssize * 1024);
 }
 
-U32 LLMemory::getWorkingSetSize()
-{
-	return 0 ;
-}
-
 #else
 
 U64 LLMemory::getCurrentRSS()
@@ -422,11 +355,6 @@ U64 LLMemory::getCurrentRSS()
 	return 0;
 }
 
-U32 LLMemory::getWorkingSetSize()
-{
-	return 0;
-}
-
 #endif
 
 //--------------------------------------------------------------------------------------------------
diff --git a/indra/llcommon/llmemory.h b/indra/llcommon/llmemory.h
index 5a3c9bd762f45d8521044b3da09b5a9edf0aed87..c37967e10ebe32baaf7367ba54095397ff81d0d7 100644
--- a/indra/llcommon/llmemory.h
+++ b/indra/llcommon/llmemory.h
@@ -334,13 +334,9 @@ inline void ll_memcpy_nonaliased_aligned_16(char* __restrict dst, const char* __
 class LL_COMMON_API LLMemory
 {
 public:
-	static void initClass();
-	static void cleanupClass();
-	static void freeReserve();
 	// Return the resident set size of the current process, in bytes.
 	// Return value is zero if not known.
 	static U64 getCurrentRSS();
-	static U32 getWorkingSetSize();
 	static void* tryToAlloc(void* address, U32 size);
 	static void initMaxHeapSizeGB(F32Gigabytes max_heap_size, BOOL prevent_heap_failure);
 	static void updateMemoryInfo() ;
@@ -351,7 +347,6 @@ class LL_COMMON_API LLMemory
 	static U32Kilobytes getMaxMemKB() ;
 	static U32Kilobytes getAllocatedMemKB() ;
 private:
-	static char* reserveMem;
 	static U32Kilobytes sAvailPhysicalMemInKB ;
 	static U32Kilobytes sMaxPhysicalMemInKB ;
 	static U32Kilobytes sAllocatedMemInKB;
diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp
index 8c321d06b9eaecad730a9e080da4bfd3e80a4eea..5753efdc592d5081853c527ce7706ac01c77c3c2 100644
--- a/indra/llcommon/llprocess.cpp
+++ b/indra/llcommon/llprocess.cpp
@@ -517,6 +517,10 @@ LLProcessPtr LLProcess::create(const LLSDOrParams& params)
 
 LLProcess::LLProcess(const LLSDOrParams& params):
 	mAutokill(params.autokill),
+	// Because 'autokill' originally meant both 'autokill' and 'attached', to
+	// preserve existing semantics, we promise that mAttached defaults to the
+	// same setting as mAutokill.
+	mAttached(params.attached.isProvided()? params.attached : params.autokill),
 	mPipes(NSLOTS)
 {
 	// Hmm, when you construct a ptr_vector with a size, it merely reserves
@@ -625,9 +629,9 @@ LLProcess::LLProcess(const LLSDOrParams& params):
 	// std handles and the like, and that's a bit more detachment than we
 	// want. autokill=false just means not to implicitly kill the child when
 	// the parent terminates!
-//	chkapr(apr_procattr_detach_set(procattr, params.autokill? 0 : 1));
+//	chkapr(apr_procattr_detach_set(procattr, mAutokill? 0 : 1));
 
-	if (params.autokill)
+	if (mAutokill)
 	{
 #if ! defined(APR_HAS_PROCATTR_AUTOKILL_SET)
 		// Our special preprocessor symbol isn't even defined -- wrong APR
@@ -696,7 +700,7 @@ LLProcess::LLProcess(const LLSDOrParams& params):
 	// take steps to terminate the child. This is all suspenders-and-belt: in
 	// theory our destructor should kill an autokill child, but in practice
 	// that doesn't always work (e.g. VWR-21538).
-	if (params.autokill)
+	if (mAutokill)
 	{
 /*==========================================================================*|
 		// NO: There may be an APR bug, not sure -- but at least on Mac, when
@@ -799,7 +803,7 @@ LLProcess::~LLProcess()
 		sProcessListener.dropPoll(*this);
 	}
 
-	if (mAutokill)
+	if (mAttached)
 	{
 		kill("destructor");
 	}
diff --git a/indra/llcommon/llprocess.h b/indra/llcommon/llprocess.h
index bfac4567a50587f5816a0cfcf94ba6127b9d2501..e3386ad88e49a7af005dc31007853698d6ddc752 100644
--- a/indra/llcommon/llprocess.h
+++ b/indra/llcommon/llprocess.h
@@ -167,6 +167,7 @@ class LL_COMMON_API LLProcess: public boost::noncopyable
 			args("args"),
 			cwd("cwd"),
 			autokill("autokill", true),
+			attached("attached", true),
 			files("files"),
 			postend("postend"),
 			desc("desc")
@@ -183,9 +184,31 @@ class LL_COMMON_API LLProcess: public boost::noncopyable
 		Multiple<std::string> args;
 		/// current working directory, if need it changed
 		Optional<std::string> cwd;
-		/// implicitly kill process on destruction of LLProcess object
-		/// (default true)
+		/// implicitly kill child process on termination of parent, whether
+		/// voluntary or crash (default true)
 		Optional<bool> autokill;
+		/// implicitly kill process on destruction of LLProcess object
+		/// (default same as autokill)
+		///
+		/// Originally, 'autokill' conflated two concepts: kill child process on
+		/// - destruction of its LLProcess object, and
+		/// - termination of parent process, voluntary or otherwise.
+		///
+		/// It's useful to tease these apart. Some child processes are sent a
+		/// "clean up and terminate" message before the associated LLProcess
+		/// object is destroyed. A child process launched with attached=false
+		/// has an extra time window from the destruction of its LLProcess
+		/// until parent-process termination in which to perform its own
+		/// orderly shutdown, yet autokill=true still guarantees that we won't
+		/// accumulate orphan instances of such processes indefinitely. With
+		/// attached=true, if a child process cannot clean up between the
+		/// shutdown message and LLProcess destruction (presumably very soon
+		/// thereafter), it's forcibly killed anyway -- which can lead to
+		/// distressing user-visible crash indications.
+		///
+		/// (The usefulness of attached=true with autokill=false is less
+		/// clear, but we don't prohibit that combination.)
+		Optional<bool> attached;
 		/**
 		 * Up to three FileParam items: for child stdin, stdout, stderr.
 		 * Passing two FileParam entries means default treatment for stderr,
@@ -540,7 +563,7 @@ class LL_COMMON_API LLProcess: public boost::noncopyable
 	std::string mDesc;
 	std::string mPostend;
 	apr_proc_t mProcess;
-	bool mAutokill;
+	bool mAutokill, mAttached;
 	Status mStatus;
 	// explicitly want this ptr_vector to be able to store NULLs
 	typedef boost::ptr_vector< boost::nullable<BasePipe> > PipeVector;
diff --git a/indra/llcommon/llsafehandle.h b/indra/llcommon/llsafehandle.h
index af1c26dd4f59e716e36ac68be3292feb059ec4ce..9550e6253e8ff8f133bad890111a41c1cc0a899d 100644
--- a/indra/llcommon/llsafehandle.h
+++ b/indra/llcommon/llsafehandle.h
@@ -27,6 +27,30 @@
 #define LLSAFEHANDLE_H
 
 #include "llerror.h"	// *TODO: consider eliminating this
+#include "llsingleton.h"
+
+/*==========================================================================*|
+ ____   ___    _   _  ___ _____   _   _ ____  _____ _
+|  _ \ / _ \  | \ | |/ _ \_   _| | | | / ___|| ____| |
+| | | | | | | |  \| | | | || |   | | | \___ \|  _| | |
+| |_| | |_| | | |\  | |_| || |   | |_| |___) | |___|_|
+|____/ \___/  |_| \_|\___/ |_|    \___/|____/|_____(_)
+
+This handle class is deprecated. Unfortunately it is already in widespread use
+to reference the LLObjectSelection and LLParcelSelection classes, but do not
+apply LLSafeHandle to other classes, or declare new instances.
+
+Instead, use LLPointer or other smart pointer types with appropriate checks
+for NULL. If you're certain the reference cannot (or must not) be NULL,
+consider storing a C++ reference instead -- or use (e.g.) LLCheckedHandle.
+
+When an LLSafeHandle<T> containing NULL is dereferenced, it resolves to a
+canonical "null" T instance. This raises issues about the lifespan of the
+"null" instance. In addition to encouraging sloppy coding practices, it
+potentially masks bugs when code that performs some mutating operation
+inadvertently applies it to the "null" instance. That result might or might
+not ever affect subsequent computations.
+|*==========================================================================*/
 
 // Expands LLPointer to return a pointer to a special instance of class Type instead of NULL.
 // This is useful in instances where operations on NULL pointers are semantically safe and/or
@@ -146,15 +170,25 @@ class LLSafeHandle
 		}
 	}
 
-	static Type* nonNull(Type* ptr)
+	// Define an LLSingleton whose sole purpose is to hold a "null instance"
+	// of the subject Type: the canonical instance to dereference if this
+	// LLSafeHandle actually holds a null pointer. We use LLSingleton
+	// specifically so that the "null instance" can be cleaned up at a well-
+	// defined time, specifically LLSingletonBase::deleteAll().
+	// Of course, as with any LLSingleton, the "null instance" is only
+	// instantiated on demand -- in this case, if you actually try to
+	// dereference an LLSafeHandle containing null.
+	class NullInstanceHolder: public LLSingleton<NullInstanceHolder>
 	{
-		return ptr == NULL ? sNullFunc() : ptr;
-	}
+		LLSINGLETON_EMPTY_CTOR(NullInstanceHolder);
+		~NullInstanceHolder() {}
+	public:
+		Type mNullInstance;
+	};
 
-	static Type* sNullFunc()
+	static Type* nonNull(Type* ptr)
 	{
-		static Type sInstance;
-		return &sInstance;
+		return ptr? ptr : &NullInstanceHolder::instance().mNullInstance;
 	}
 
 protected:
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index 9025e53bb27a2d42d908f957a82242039e1cd170..18e1b96a5f35efb4b4c435e946f0e4abc39c07dc 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -369,62 +369,20 @@ void LLSingletonBase::deleteAll()
     }
 }
 
-/*------------------------ Final cleanup management ------------------------*/
-class LLSingletonBase::MasterRefcount
-{
-public:
-    // store a POD int so it will be statically initialized to 0
-    int refcount;
-};
-static LLSingletonBase::MasterRefcount sMasterRefcount;
-
-LLSingletonBase::ref_ptr_t LLSingletonBase::get_master_refcount()
-{
-    // Calling this method constructs a new ref_ptr_t, which implicitly calls
-    // intrusive_ptr_add_ref(MasterRefcount*).
-    return &sMasterRefcount;
-}
-
-void intrusive_ptr_add_ref(LLSingletonBase::MasterRefcount* mrc)
-{
-    // Count outstanding SingletonLifetimeManager instances.
-    ++mrc->refcount;
-}
-
-void intrusive_ptr_release(LLSingletonBase::MasterRefcount* mrc)
-{
-    // Notice when each SingletonLifetimeManager instance is destroyed.
-    if (! --mrc->refcount)
-    {
-        // The last instance was destroyed. Time to kill any remaining
-        // LLSingletons -- but in dependency order.
-        LLSingletonBase::deleteAll();
-    }
-}
-
 /*---------------------------- Logging helpers -----------------------------*/
 namespace {
 bool oktolog()
 {
     // See comments in log() below.
-    return sMasterRefcount.refcount && LLError::is_available();
+    return LLError::is_available();
 }
 
 void log(LLError::ELevel level,
          const char* p1, const char* p2, const char* p3, const char* p4)
 {
-    // Check whether we're in the implicit final LLSingletonBase::deleteAll()
-    // call. We've carefully arranged for deleteAll() to be called when the
-    // last SingletonLifetimeManager instance is destroyed -- in other words,
-    // when the last translation unit containing an LLSingleton instance
-    // cleans up static data. That could happen after std::cerr is destroyed!
     // The is_available() test below ensures that we'll stop logging once
     // LLError has been cleaned up. If we had a similar portable test for
-    // std::cerr, this would be a good place to use it. As we do not, just
-    // don't log anything during implicit final deleteAll(). Detect that by
-    // the master refcount having gone to zero.
-    if (sMasterRefcount.refcount == 0)
-        return;
+    // std::cerr, this would be a good place to use it.
 
     // Check LLError::is_available() because some of LLError's infrastructure
     // is itself an LLSingleton. If that LLSingleton has not yet been
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 0d4a1f34f8726d511716d52e10fcb05130a43f75..859e271e26c661a88a726456bcaf128d61f83672 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -27,7 +27,6 @@
 
 #include <boost/noncopyable.hpp>
 #include <boost/unordered_set.hpp>
-#include <boost/intrusive_ptr.hpp>
 #include <list>
 #include <vector>
 #include <typeinfo>
@@ -36,8 +35,6 @@ class LLSingletonBase: private boost::noncopyable
 {
 public:
     class MasterList;
-    class MasterRefcount;
-    typedef boost::intrusive_ptr<MasterRefcount> ref_ptr_t;
 
 private:
     // All existing LLSingleton instances are tracked in this master list.
@@ -119,9 +116,6 @@ class LLSingletonBase: private boost::noncopyable
                          const char* p3="", const char* p4="");
     static std::string demangle(const char* mangled);
 
-    // obtain canonical ref_ptr_t
-    static ref_ptr_t get_master_refcount();
-
     // Default methods in case subclass doesn't declare them.
     virtual void initSingleton() {}
     virtual void cleanupSingleton() {}
@@ -175,10 +169,6 @@ class LLSingletonBase: private boost::noncopyable
     static void deleteAll();
 };
 
-// support ref_ptr_t
-void intrusive_ptr_add_ref(LLSingletonBase::MasterRefcount*);
-void intrusive_ptr_release(LLSingletonBase::MasterRefcount*);
-
 // Most of the time, we want LLSingleton_manage_master() to forward its
 // methods to real LLSingletonBase methods.
 template <class T>
@@ -298,8 +288,7 @@ class LLSingleton : public LLSingletonBase
     // stores pointer to singleton instance
     struct SingletonLifetimeManager
     {
-        SingletonLifetimeManager():
-            mMasterRefcount(LLSingletonBase::get_master_refcount())
+        SingletonLifetimeManager()
         {
             construct();
         }
@@ -317,17 +306,14 @@ class LLSingleton : public LLSingletonBase
             // of static-object destruction, mean that we DO NOT WANT this
             // destructor to delete this LLSingleton. This destructor will run
             // without regard to any other LLSingleton whose cleanup might
-            // depend on its existence. What we really want is to count the
-            // runtime's attempts to cleanup LLSingleton static data -- and on
-            // the very last one, call LLSingletonBase::deleteAll(). That
-            // method will properly honor cross-LLSingleton dependencies. This
-            // is why we store an intrusive_ptr to a MasterRefcount: our
-            // ref_ptr_t member counts SingletonLifetimeManager instances.
-            // Once the runtime destroys the last of these, THEN we can delete
-            // every remaining LLSingleton.
+            // depend on its existence. If you want to clean up LLSingletons,
+            // call LLSingletonBase::deleteAll() sometime before static-object
+            // destruction begins. That method will properly honor cross-
+            // LLSingleton dependencies. Otherwise we simply leak LLSingleton
+            // instances at shutdown. Since the whole process is terminating
+            // anyway, that's not necessarily a bad thing; it depends on what
+            // resources your LLSingleton instances are managing.
         }
-
-        LLSingletonBase::ref_ptr_t mMasterRefcount;
     };
 
 protected:
diff --git a/indra/llcommon/llsys.cpp b/indra/llcommon/llsys.cpp
index 1a66612e8785a22a792c505e8fd0bc494cef09d8..265c637b696e9e1dec9484a67e979cc92fa88c15 100644
--- a/indra/llcommon/llsys.cpp
+++ b/indra/llcommon/llsys.cpp
@@ -914,22 +914,6 @@ U32Kilobytes LLMemoryInfo::getPhysicalMemoryKB() const
 #endif
 }
 
-U32Bytes LLMemoryInfo::getPhysicalMemoryClamped() const
-{
-	// Return the total physical memory in bytes, but clamp it
-	// to no more than U32_MAX
-	
-	U32Kilobytes phys_kb = getPhysicalMemoryKB();
-	if (phys_kb >= U32Gigabytes(4))
-	{
-		return U32Bytes(U32_MAX);
-	}
-	else
-	{
-		return phys_kb;
-	}
-}
-
 //static
 void LLMemoryInfo::getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb)
 {
diff --git a/indra/llcommon/llsys.h b/indra/llcommon/llsys.h
index 962367f69fe37a5af9af741e73d8f7017611218e..95ef4cf06571dd47b10e46126f18f5a35523cf8e 100644
--- a/indra/llcommon/llsys.h
+++ b/indra/llcommon/llsys.h
@@ -113,11 +113,6 @@ class LL_COMMON_API LLMemoryInfo
 	void stream(std::ostream& s) const;	///< output text info to s
 
 	U32Kilobytes getPhysicalMemoryKB() const; 
-	
-	/*! Memory size in bytes, if total memory is >= 4GB then U32_MAX will
-	**  be returned.
-	*/
-	U32Bytes getPhysicalMemoryClamped() const; ///< Memory size in clamped bytes
 
 	//get the available memory infomation in KiloBytes.
 	static void getAvailableMemoryKB(U32Kilobytes& avail_physical_mem_kb, U32Kilobytes& avail_virtual_mem_kb);
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index 5ba343b183b16e9f548210fc1dc5a89f8ec7ae4f..b27e125d2ecd824aab7bd2421424bf8bb81ed359 100644
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -788,6 +788,69 @@ namespace tut
 
     template<> template<>
     void object::test<10>()
+    {
+        set_test_name("attached=false");
+        // almost just like autokill=false, except set autokill=true with
+        // attached=false.
+        NamedTempFile from("from", "not started");
+        NamedTempFile to("to", "");
+        LLProcess::handle phandle(0);
+        {
+            PythonProcessLauncher py(get_test_name(),
+                                     "from __future__ import with_statement\n"
+                                     "import sys, time\n"
+                                     "with open(sys.argv[1], 'w') as f:\n"
+                                     "    f.write('ok')\n"
+                                     "# wait for 'go' from test program\n"
+                                     "for i in xrange(60):\n"
+                                     "    time.sleep(1)\n"
+                                     "    with open(sys.argv[2]) as f:\n"
+                                     "        go = f.read()\n"
+                                     "    if go == 'go':\n"
+                                     "        break\n"
+                                     "else:\n"
+                                     "    with open(sys.argv[1], 'w') as f:\n"
+                                     "        f.write('never saw go')\n"
+                                     "    sys.exit(1)\n"
+                                     "# okay, saw 'go', write 'ack'\n"
+                                     "with open(sys.argv[1], 'w') as f:\n"
+                                     "    f.write('ack')\n");
+            py.mParams.args.add(from.getName());
+            py.mParams.args.add(to.getName());
+            py.mParams.autokill = true;
+            py.mParams.attached = false;
+            py.launch();
+            // Capture handle for later
+            phandle = py.mPy->getProcessHandle();
+            // Wait for the script to wake up and do its first write
+            int i = 0, timeout = 60;
+            for ( ; i < timeout; ++i)
+            {
+                yield();
+                if (readfile(from.getName(), "from autokill script") == "ok")
+                    break;
+            }
+            // If we broke this loop because of the counter, something's wrong
+            ensure("script never started", i < timeout);
+            // Now destroy the LLProcess, which should NOT kill the child!
+        }
+        // If the destructor killed the child anyway, give it time to die
+        yield(2);
+        // How do we know it's not terminated? By making it respond to
+        // a specific stimulus in a specific way.
+        {
+            std::ofstream outf(to.getName().c_str());
+            outf << "go";
+        } // flush and close.
+        // now wait for the script to terminate... one way or another.
+        waitfor(phandle, "autokill script");
+        // If the LLProcess destructor implicitly called kill(), the
+        // script could not have written 'ack' as we expect.
+        ensure_equals(get_test_name() + " script output", readfile(from.getName()), "ack");
+    }
+
+    template<> template<>
+    void object::test<11>()
     {
         set_test_name("'bogus' test");
         CaptureLog recorder;
@@ -801,7 +864,7 @@ namespace tut
     }
 
     template<> template<>
-    void object::test<11>()
+    void object::test<12>()
     {
         set_test_name("'file' test");
         // Replace this test with one or more real 'file' tests when we
@@ -815,7 +878,7 @@ namespace tut
     }
 
     template<> template<>
-    void object::test<12>()
+    void object::test<13>()
     {
         set_test_name("'tpipe' test");
         // Replace this test with one or more real 'tpipe' tests when we
@@ -832,7 +895,7 @@ namespace tut
     }
 
     template<> template<>
-    void object::test<13>()
+    void object::test<14>()
     {
         set_test_name("'npipe' test");
         // Replace this test with one or more real 'npipe' tests when we
@@ -850,7 +913,7 @@ namespace tut
     }
 
     template<> template<>
-    void object::test<14>()
+    void object::test<15>()
     {
         set_test_name("internal pipe name warning");
         CaptureLog recorder;
@@ -914,7 +977,7 @@ namespace tut
     } while (0)
 
     template<> template<>
-    void object::test<15>()
+    void object::test<16>()
     {
         set_test_name("get*Pipe() validation");
         PythonProcessLauncher py(get_test_name(),
@@ -934,7 +997,7 @@ namespace tut
     }
 
     template<> template<>
-    void object::test<16>()
+    void object::test<17>()
     {
         set_test_name("talk to stdin/stdout");
         PythonProcessLauncher py(get_test_name(),
@@ -992,7 +1055,7 @@ namespace tut
     }
 
     template<> template<>
-    void object::test<17>()
+    void object::test<18>()
     {
         set_test_name("listen for ReadPipe events");
         PythonProcessLauncher py(get_test_name(),
@@ -1052,7 +1115,7 @@ namespace tut
     }
 
     template<> template<>
-    void object::test<18>()
+    void object::test<19>()
     {
         set_test_name("ReadPipe \"eof\" event");
         PythonProcessLauncher py(get_test_name(),
@@ -1078,7 +1141,7 @@ namespace tut
     }
 
     template<> template<>
-    void object::test<19>()
+    void object::test<20>()
     {
         set_test_name("setLimit()");
         PythonProcessLauncher py(get_test_name(),
@@ -1107,7 +1170,7 @@ namespace tut
     }
 
     template<> template<>
-    void object::test<20>()
+    void object::test<21>()
     {
         set_test_name("peek() ReadPipe data");
         PythonProcessLauncher py(get_test_name(),
@@ -1160,7 +1223,7 @@ namespace tut
     }
 
     template<> template<>
-    void object::test<21>()
+    void object::test<22>()
     {
         set_test_name("bad postend");
         std::string pumpname("postend");
@@ -1185,7 +1248,7 @@ namespace tut
     }
 
     template<> template<>
-    void object::test<22>()
+    void object::test<23>()
     {
         set_test_name("good postend");
         PythonProcessLauncher py(get_test_name(),
@@ -1241,7 +1304,7 @@ namespace tut
     };
 
     template<> template<>
-    void object::test<23>()
+    void object::test<24>()
     {
         set_test_name("all data visible at postend");
         PythonProcessLauncher py(get_test_name(),
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 004db546b701191145d178c48e46c4b462786737..5a112b543297fb8c0a26d5439af5f5d845db494c 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -755,6 +755,28 @@ void LLAvatarNameCache::insert(const LLUUID& agent_id, const LLAvatarName& av_na
 	sCache[agent_id] = av_name;
 }
 
+LLUUID LLAvatarNameCache::findIdByName(const std::string& name)
+{
+    std::map<LLUUID, LLAvatarName>::iterator it;
+    std::map<LLUUID, LLAvatarName>::iterator end = sCache.end();
+    for (it = sCache.begin(); it != end; ++it)
+    {
+        if (it->second.getUserName() == name)
+        {
+            return it->first;
+        }
+    }
+
+    // Legacy method
+    LLUUID id;
+    if (gCacheName->getUUID(name, id))
+    {
+        return id;
+    }
+
+    return LLUUID::null;
+}
+
 #if 0
 F64 LLAvatarNameCache::nameExpirationFromHeaders(LLCore::HttpHeaders *headers)
 {
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index bd2715e9567607d7f15d57124c63190dea6d5513..63e067c939f502871dafece78e69dfaf8da002dc 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -84,7 +84,15 @@ namespace LLAvatarNameCache
 	void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
 	void erase(const LLUUID& agent_id);
 
-    /// Provide some fallback for agents that return errors.
+	// A way to find agent id by UUID, very slow, also unreliable
+	// since it doesn't request names, just serch exsisting ones
+	// that are likely not in cache.
+	//
+	// Todo: Find a way to remove this.
+	// Curently this method is used for chat history and in some cases notices.
+	LLUUID findIdByName(const std::string& name);
+
+	/// Provide some fallback for agents that return errors.
 	void handleAgentError(const LLUUID& agent_id);
 
 	// Compute name expiration time from HTTP Cache-Control header,
diff --git a/indra/llmessage/llexperiencecache.cpp b/indra/llmessage/llexperiencecache.cpp
index 779d1d9d994dcea03009b458bfbcbf9e26fc6b8c..aa7b3c1260f7146522f8368c42bfbdfe78d76932 100644
--- a/indra/llmessage/llexperiencecache.cpp
+++ b/indra/llmessage/llexperiencecache.cpp
@@ -540,18 +540,34 @@ void LLExperienceCache::fetchAssociatedExperience(const LLUUID& objectId, const
     }
 
     LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Fetch Associated",
-        boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, objectId, itemId, fn));
+        boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, objectId, itemId,  std::string(), fn));
 }
 
-void LLExperienceCache::fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, LLUUID objectId, LLUUID itemId, ExperienceGetFn_t fn)
+void LLExperienceCache::fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn)
+{
+    if (mCapability.empty())
+    {
+        LL_WARNS("ExperienceCache") << "Capability query method not set." << LL_ENDL;
+        return;
+    }
+
+    LLCoprocedureManager::instance().enqueueCoprocedure("ExpCache", "Fetch Associated",
+        boost::bind(&LLExperienceCache::fetchAssociatedExperienceCoro, this, _1, objectId, itemId, url, fn));
+}
+
+void LLExperienceCache::fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, LLUUID objectId, LLUUID itemId, std::string url, ExperienceGetFn_t fn)
 {
     LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest());
-    std::string url = mCapability("GetMetadata");
 
     if (url.empty())
     {
-        LL_WARNS("ExperienceCache") << "No Metadata capability." << LL_ENDL;
-        return;
+        url = mCapability("GetMetadata");
+
+        if (url.empty())
+        {
+            LL_WARNS("ExperienceCache") << "No Metadata capability." << LL_ENDL;
+            return;
+        }
     }
 
     LLSD fields;
diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h
index 8ee7080d3822ae52b9c288877c845540fccb9fd3..f9ff69c2b6690ebddb9ab59e4555db9bfadbb73e 100644
--- a/indra/llmessage/llexperiencecache.h
+++ b/indra/llmessage/llexperiencecache.h
@@ -64,6 +64,7 @@ class LLExperienceCache: public LLSingleton < LLExperienceCache >
 
     //-------------------------------------------
     void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, ExperienceGetFn_t fn);
+    void fetchAssociatedExperience(const LLUUID& objectId, const LLUUID& itemId, std::string url, ExperienceGetFn_t fn);
     void findExperienceByName(const std::string text, int page, ExperienceGetFn_t fn);
     void getGroupExperiences(const LLUUID &groupId, ExperienceGetFn_t fn);
 
@@ -148,7 +149,7 @@ class LLExperienceCache: public LLSingleton < LLExperienceCache >
     void requestExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, std::string, RequestQueue_t);
     void requestExperiences();
 
-    void fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, LLUUID, LLUUID, ExperienceGetFn_t);
+    void fetchAssociatedExperienceCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, LLUUID, LLUUID, std::string, ExperienceGetFn_t);
     void findExperienceByNameCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, std::string, int, ExperienceGetFn_t);
     void getGroupExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, LLUUID , ExperienceGetFn_t);
     void regionExperiencesCoro(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &httpAdapter, CapabilityQuery_t regioncaps, bool update, LLSD experiences, ExperienceGetFn_t fn);
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index 5c6b3d5fab165b60bdf4d78f3414733731483e2f..6675e12649bf3a66246f4391ae4548ec9b7e7dfd 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -618,6 +618,7 @@ char const* const _PREHASH_GroupAccountSummaryRequest = LLMessageStringTable::ge
 char const* const _PREHASH_GroupVoteHistoryRequest = LLMessageStringTable::getInstance()->getString("GroupVoteHistoryRequest");
 char const* const _PREHASH_ParamValue = LLMessageStringTable::getInstance()->getString("ParamValue");
 char const* const _PREHASH_MaxAgents = LLMessageStringTable::getInstance()->getString("MaxAgents");
+char const* const _PREHASH_HardMaxAgents = LLMessageStringTable::getInstance()->getString("HardMaxAgents");
 char const* const _PREHASH_CreateNewOutfitAttachments = LLMessageStringTable::getInstance()->getString("CreateNewOutfitAttachments");
 char const* const _PREHASH_RegionHandle = LLMessageStringTable::getInstance()->getString("RegionHandle");
 char const* const _PREHASH_TeleportProgress = LLMessageStringTable::getInstance()->getString("TeleportProgress");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index e696c3b0cae394faa12b8dd2ff2791cdb8682ea5..a510b4498f5482621a22330cde43d2bb8e76a1f3 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -618,6 +618,7 @@ extern char const* const _PREHASH_GroupAccountSummaryRequest;
 extern char const* const _PREHASH_GroupVoteHistoryRequest;
 extern char const* const _PREHASH_ParamValue;
 extern char const* const _PREHASH_MaxAgents;
+extern char const* const _PREHASH_HardMaxAgents;
 extern char const* const _PREHASH_CreateNewOutfitAttachments;
 extern char const* const _PREHASH_RegionHandle;
 extern char const* const _PREHASH_TeleportProgress;
diff --git a/indra/llplugin/llpluginmessagepipe.cpp b/indra/llplugin/llpluginmessagepipe.cpp
index 7e2bf90ad15360bb3b115a7463b083275521a48e..9468696507b31e98be7b947a4badad5024ee9c56 100644
--- a/indra/llplugin/llpluginmessagepipe.cpp
+++ b/indra/llplugin/llpluginmessagepipe.cpp
@@ -215,7 +215,7 @@ bool LLPluginMessagePipe::pumpOutput()
 			else if(APR_STATUS_IS_EOF(status))
 			{
 				// This is what we normally expect when a plugin exits.
-				LL_INFOS() << "Got EOF from plugin socket. " << LL_ENDL;
+				//LL_INFOS() << "Got EOF from plugin socket. " << LL_ENDL;
 
 				if(mOwner)
 				{
@@ -329,7 +329,7 @@ bool LLPluginMessagePipe::pumpInput(F64 timeout)
 				else if(APR_STATUS_IS_EOF(status))
 				{
 					// This is what we normally expect when a plugin exits.
-					LL_INFOS("PluginSocket") << "Got EOF from plugin socket. " << LL_ENDL;
+					//LL_INFOS("PluginSocket") << "Got EOF from plugin socket. " << LL_ENDL;
 
 					if(mOwner)
 					{
diff --git a/indra/llplugin/llpluginprocesschild.cpp b/indra/llplugin/llpluginprocesschild.cpp
index be80d38305807f18640a8acb351df5e12fefff29..e24d222cb66e8eaf7063e1a4c785c74dcf7f7544 100644
--- a/indra/llplugin/llpluginprocesschild.cpp
+++ b/indra/llplugin/llpluginprocesschild.cpp
@@ -1,30 +1,30 @@
-/** 
- * @file llpluginprocesschild.cpp
- * @brief LLPluginProcessChild handles the child side of the external-process plugin API. 
- *
- * @cond
- * $LicenseInfo:firstyear=2008&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$
- * @endcond
- */
+/**
+* @file llpluginprocesschild.cpp
+* @brief LLPluginProcessChild handles the child side of the external-process plugin API.
+*
+* @cond
+* $LicenseInfo:firstyear=2008&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$
+* @endcond
+*/
 
 #include "linden_common.h"
 
@@ -50,7 +50,7 @@ LLPluginProcessChild::LLPluginProcessChild()
 
 LLPluginProcessChild::~LLPluginProcessChild()
 {
-	if(mInstance != NULL)
+	if (mInstance != NULL)
 	{
 		sendMessageToPlugin(LLPluginMessage("base", "cleanup"));
 
@@ -58,7 +58,7 @@ LLPluginProcessChild::~LLPluginProcessChild()
 		// appears to fail and lock up which means that a given instance of the slplugin process never exits. 
 		// This is bad, especially when users try to update their version of SL - it fails because the slplugin 
 		// process as well as a bunch of plugin specific files are locked and cannot be overwritten.
-		exit( 0 );
+		exit(0);
 		//delete mInstance;
 		//mInstance = NULL;
 	}
@@ -81,166 +81,173 @@ void LLPluginProcessChild::idle(void)
 	bool idle_again;
 	do
 	{
-		if(APR_STATUS_IS_EOF(mSocketError))
-		{
-			// Plugin socket was closed.  This covers both normal plugin termination and host crashes.
-			setState(STATE_ERROR);
-		}
-		else if(mSocketError != APR_SUCCESS)
-		{
-			LL_INFOS("Plugin") << "message pipe is in error state (" << mSocketError << "), moving to STATE_ERROR"<< LL_ENDL;
-			setState(STATE_ERROR);
-		}	
+		if (mState < STATE_SHUTDOWNREQ)
+		{   // Once we have hit the shutdown request state checking for errors might put us in a spurious 
+			// error state... don't do that.
 
-		if((mState > STATE_INITIALIZED) && (mMessagePipe == NULL))
-		{
-			// The pipe has been closed -- we're done.
-			// TODO: This could be slightly more subtle, but I'm not sure it needs to be.
-			LL_INFOS("Plugin") << "message pipe went away, moving to STATE_ERROR"<< LL_ENDL;
-			setState(STATE_ERROR);
+			if (APR_STATUS_IS_EOF(mSocketError))
+			{
+				// Plugin socket was closed.  This covers both normal plugin termination and host crashes.
+				setState(STATE_ERROR);
+			}
+			else if (mSocketError != APR_SUCCESS)
+			{
+				LL_INFOS("Plugin") << "message pipe is in error state (" << mSocketError << "), moving to STATE_ERROR" << LL_ENDL;
+				setState(STATE_ERROR);
+			}
+
+			if ((mState > STATE_INITIALIZED) && (mMessagePipe == NULL))
+			{
+				// The pipe has been closed -- we're done.
+				// TODO: This could be slightly more subtle, but I'm not sure it needs to be.
+				LL_INFOS("Plugin") << "message pipe went away, moving to STATE_ERROR" << LL_ENDL;
+				setState(STATE_ERROR);
+			}
 		}
-	
+
 		// If a state needs to go directly to another state (as a performance enhancement), it can set idle_again to true after calling setState().
 		// USE THIS CAREFULLY, since it can starve other code.  Specifically make sure there's no way to get into a closed cycle and never return.
 		// When in doubt, don't do it.
 		idle_again = false;
-		
-		if(mInstance != NULL)
+
+		if (mInstance != NULL)
 		{
 			// Provide some time to the plugin
 			mInstance->idle();
 		}
-		
-		switch(mState)
+
+		switch (mState)
 		{
-			case STATE_UNINITIALIZED:
+		case STATE_UNINITIALIZED:
 			break;
 
-			case STATE_INITIALIZED:
-				if(mSocket->blockingConnect(mLauncherHost))
+		case STATE_INITIALIZED:
+			if (mSocket->blockingConnect(mLauncherHost))
+			{
+				// This automatically sets mMessagePipe
+				new LLPluginMessagePipe(this, mSocket);
+
+				setState(STATE_CONNECTED);
+			}
+			else
+			{
+				// connect failed
+				setState(STATE_ERROR);
+			}
+			break;
+
+		case STATE_CONNECTED:
+			sendMessageToParent(LLPluginMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "hello"));
+			setState(STATE_PLUGIN_LOADING);
+			break;
+
+		case STATE_PLUGIN_LOADING:
+			if (!mPluginFile.empty())
+			{
+				mInstance = new LLPluginInstance(this);
+				if (mInstance->load(mPluginDir, mPluginFile) == 0)
 				{
-					// This automatically sets mMessagePipe
-					new LLPluginMessagePipe(this, mSocket);
-					
-					setState(STATE_CONNECTED);
+					mHeartbeat.start();
+					mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
+					mCPUElapsed = 0.0f;
+					setState(STATE_PLUGIN_LOADED);
 				}
 				else
 				{
-					// connect failed
 					setState(STATE_ERROR);
 				}
+			}
 			break;
-			
-			case STATE_CONNECTED:
-				sendMessageToParent(LLPluginMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "hello"));
-				setState(STATE_PLUGIN_LOADING);
+
+		case STATE_PLUGIN_LOADED:
+		{
+			setState(STATE_PLUGIN_INITIALIZING);
+			LLPluginMessage message("base", "init");
+			sendMessageToPlugin(message);
+		}
+		break;
+
+		case STATE_PLUGIN_INITIALIZING:
+			// waiting for init_response...
 			break;
-						
-			case STATE_PLUGIN_LOADING:
-				if(!mPluginFile.empty())
+
+		case STATE_RUNNING:
+			if (mInstance != NULL)
+			{
+				// Provide some time to the plugin
+				LLPluginMessage message("base", "idle");
+				message.setValueReal("time", PLUGIN_IDLE_SECONDS);
+				sendMessageToPlugin(message);
+
+				mInstance->idle();
+
+				if (mHeartbeat.hasExpired())
 				{
-					mInstance = new LLPluginInstance(this);
-					if(mInstance->load(mPluginDir, mPluginFile) == 0)
-					{
-						mHeartbeat.start();
-						mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
-						mCPUElapsed = 0.0f;
-						setState(STATE_PLUGIN_LOADED);
-					}
-					else
-					{
-						setState(STATE_ERROR);
-					}
+
+					// This just proves that we're not stuck down inside the plugin code.
+					LLPluginMessage heartbeat(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat");
+
+					// Calculate the approximage CPU usage fraction (floating point value between 0 and 1) used by the plugin this heartbeat cycle.
+					// Note that this will not take into account any threads or additional processes the plugin spawns, but it's a first approximation.
+					// If we could write OS-specific functions to query the actual CPU usage of this process, that would be a better approximation.
+					heartbeat.setValueReal("cpu_usage", mCPUElapsed / mHeartbeat.getElapsedTimeF64());
+
+					sendMessageToParent(heartbeat);
+
+					mHeartbeat.reset();
+					mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
+					mCPUElapsed = 0.0f;
 				}
+			}
+			// receivePluginMessage will transition to STATE_UNLOADING
 			break;
-			
-			case STATE_PLUGIN_LOADED:
-				{
-					setState(STATE_PLUGIN_INITIALIZING);
-					LLPluginMessage message("base", "init");
-					sendMessageToPlugin(message);
-				}
+
+		case STATE_SHUTDOWNREQ:
+			// set next state first thing in case "cleanup" message advances state.
+			setState(STATE_UNLOADING);
+			mWaitGoodbye.setTimerExpirySec(GOODBYE_SECONDS);
+
+			if (mInstance != NULL)
+			{
+				sendMessageToPlugin(LLPluginMessage("base", "cleanup"));
+			}
 			break;
-			
-			case STATE_PLUGIN_INITIALIZING:
-				// waiting for init_response...
+
+		case STATE_UNLOADING:
+			// waiting for goodbye from plugin.
+			if (mWaitGoodbye.hasExpired())
+			{
+				LL_WARNS() << "Wait for goodbye expired.  Advancing to UNLOADED" << LL_ENDL;
+				setState(STATE_UNLOADED);
+			}
+			break;
+
+		case STATE_UNLOADED:
+			killSockets();
+			delete mInstance;
+			mInstance = NULL;
+			setState(STATE_DONE);
+			break;
+
+		case STATE_ERROR:
+			// Close the socket to the launcher
+			killSockets();
+			// TODO: Where do we go from here?  Just exit()?
+			setState(STATE_DONE);
+			break;
+
+		case STATE_DONE:
+			// just sit here.
 			break;
-			
-			case STATE_RUNNING:
-				if(mInstance != NULL)
-				{
-					// Provide some time to the plugin
-					LLPluginMessage message("base", "idle");
-					message.setValueReal("time", PLUGIN_IDLE_SECONDS);
-					sendMessageToPlugin(message);
-					
-					mInstance->idle();
-					
-					if(mHeartbeat.hasExpired())
-					{
-						
-						// This just proves that we're not stuck down inside the plugin code.
-						LLPluginMessage heartbeat(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "heartbeat");
-						
-						// Calculate the approximage CPU usage fraction (floating point value between 0 and 1) used by the plugin this heartbeat cycle.
-						// Note that this will not take into account any threads or additional processes the plugin spawns, but it's a first approximation.
-						// If we could write OS-specific functions to query the actual CPU usage of this process, that would be a better approximation.
-						heartbeat.setValueReal("cpu_usage", mCPUElapsed / mHeartbeat.getElapsedTimeF64());
-						
-						sendMessageToParent(heartbeat);
-
-						mHeartbeat.reset();
-						mHeartbeat.setTimerExpirySec(HEARTBEAT_SECONDS);
-						mCPUElapsed = 0.0f;
-					}
-				}
-				// receivePluginMessage will transition to STATE_UNLOADING
-			    break;
-
-            case STATE_SHUTDOWNREQ:
-                if (mInstance != NULL)
-                {
-                    sendMessageToPlugin(LLPluginMessage("base", "cleanup"));
-                    delete mInstance;
-                    mInstance = NULL;
-                }
-                setState(STATE_UNLOADING);
-                mWaitGoodbye.setTimerExpirySec(GOODBYE_SECONDS);
-                break;
-
-			case STATE_UNLOADING:
-                // waiting for goodbye from plugin.
-                if (mWaitGoodbye.hasExpired())
-                {
-                    LL_WARNS() << "Wait for goodbye expired.  Advancing to UNLOADED" << LL_ENDL;
-                    setState(STATE_UNLOADED);
-                }
-			    break;
-			
-			case STATE_UNLOADED:
-				killSockets();
-				setState(STATE_DONE);
-			    break;
-
-			case STATE_ERROR:
-				// Close the socket to the launcher
-				killSockets();				
-				// TODO: Where do we go from here?  Just exit()?
-				setState(STATE_DONE);
-			    break;
-			
-			case STATE_DONE:
-				// just sit here.
-			    break;
 		}
-	
+
 	} while (idle_again);
 }
 
 void LLPluginProcessChild::sleep(F64 seconds)
 {
 	deliverQueuedMessages();
-	if(mMessagePipe)
+	if (mMessagePipe)
 	{
 		mMessagePipe->pump(seconds);
 	}
@@ -253,7 +260,7 @@ void LLPluginProcessChild::sleep(F64 seconds)
 void LLPluginProcessChild::pump(void)
 {
 	deliverQueuedMessages();
-	if(mMessagePipe)
+	if (mMessagePipe)
 	{
 		mMessagePipe->pump(0.0f);
 	}
@@ -267,26 +274,26 @@ void LLPluginProcessChild::pump(void)
 bool LLPluginProcessChild::isRunning(void)
 {
 	bool result = false;
-	
-	if(mState == STATE_RUNNING)
+
+	if (mState == STATE_RUNNING)
 		result = true;
-		
+
 	return result;
 }
 
 bool LLPluginProcessChild::isDone(void)
 {
 	bool result = false;
-	
-	switch(mState)
+
+	switch (mState)
 	{
-		case STATE_DONE:
+	case STATE_DONE:
 		result = true;
 		break;
-		default:
+	default:
 		break;
 	}
-		
+
 	return result;
 }
 
@@ -295,12 +302,12 @@ void LLPluginProcessChild::sendMessageToPlugin(const LLPluginMessage &message)
 	if (mInstance)
 	{
 		std::string buffer = message.generate();
-		
+
 		LL_DEBUGS("Plugin") << "Sending to plugin: " << buffer << LL_ENDL;
 		LLTimer elapsed;
-		
+
 		mInstance->sendMessage(buffer);
-		
+
 		mCPUElapsed += elapsed.getElapsedTimeF64();
 	}
 	else
@@ -328,11 +335,11 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
 	LLPluginMessage parsed;
 	parsed.parse(message);
 
-	if(mBlockingRequest)
+	if (mBlockingRequest)
 	{
 		// We're blocking the plugin waiting for a response.
 
-		if(parsed.hasValue("blocking_response"))
+		if (parsed.hasValue("blocking_response"))
 		{
 			// This is the message we've been waiting for -- fall through and send it immediately. 
 			mBlockingResponseReceived = true;
@@ -344,34 +351,34 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
 			return;
 		}
 	}
-	
+
 	bool passMessage = true;
-	
+
 	// FIXME: how should we handle queueing here?
-	
+
 	{
 		std::string message_class = parsed.getClass();
-		if(message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
+		if (message_class == LLPLUGIN_MESSAGE_CLASS_INTERNAL)
 		{
 			passMessage = false;
-			
+
 			std::string message_name = parsed.getName();
-			if(message_name == "load_plugin")
+			if (message_name == "load_plugin")
 			{
 				mPluginFile = parsed.getValue("file");
 				mPluginDir = parsed.getValue("dir");
 			}
-            else if (message_name == "shutdown_plugin")
-            {
-                setState(STATE_SHUTDOWNREQ);
-            }
-			else if(message_name == "shm_add")
+			else if (message_name == "shutdown_plugin")
+			{
+				setState(STATE_SHUTDOWNREQ);
+			}
+			else if (message_name == "shm_add")
 			{
 				std::string name = parsed.getValue("name");
 				size_t size = (size_t)parsed.getValueS32("size");
-				
+
 				sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
-				if(iter != mSharedMemoryRegions.end())
+				if (iter != mSharedMemoryRegions.end())
 				{
 					// Need to remove the old region first
 					LL_WARNS("Plugin") << "Adding a duplicate shared memory segment!" << LL_ENDL;
@@ -380,20 +387,20 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
 				{
 					// This is a new region
 					LLPluginSharedMemory *region = new LLPluginSharedMemory;
-					if(region->attach(name, size))
+					if (region->attach(name, size))
 					{
 						mSharedMemoryRegions.insert(sharedMemoryRegionsType::value_type(name, region));
-						
+
 						std::stringstream addr;
 						addr << region->getMappedAddress();
-						
+
 						// Send the add notification to the plugin
 						LLPluginMessage message("base", "shm_added");
 						message.setValue("name", name);
 						message.setValueS32("size", (S32)size);
 						message.setValuePointer("address", region->getMappedAddress());
 						sendMessageToPlugin(message);
-						
+
 						// and send the response to the parent
 						message.setMessage(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_add_response");
 						message.setValue("name", name);
@@ -405,13 +412,13 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
 						delete region;
 					}
 				}
-				
+
 			}
-			else if(message_name == "shm_remove")
+			else if (message_name == "shm_remove")
 			{
 				std::string name = parsed.getValue("name");
 				sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
-				if(iter != mSharedMemoryRegions.end())
+				if (iter != mSharedMemoryRegions.end())
 				{
 					// forward the remove request to the plugin -- its response will trigger us to detach the segment.
 					LLPluginMessage message("base", "shm_remove");
@@ -423,20 +430,20 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
 					LL_WARNS("Plugin") << "shm_remove for unknown memory segment!" << LL_ENDL;
 				}
 			}
-			else if(message_name == "sleep_time")
+			else if (message_name == "sleep_time")
 			{
 				mSleepTime = llmax(parsed.getValueReal("time"), 1.0 / 100.0); // clamp to maximum of 100Hz
 			}
-			else if(message_name == "crash")
+			else if (message_name == "crash")
 			{
 				// Crash the plugin
 				LL_ERRS("Plugin") << "Plugin crash requested." << LL_ENDL;
 			}
-			else if(message_name == "hang")
+			else if (message_name == "hang")
 			{
 				// Hang the plugin
 				LL_WARNS("Plugin") << "Plugin hang requested." << LL_ENDL;
-				while(1)
+				while (1)
 				{
 					// wheeeeeeeee......
 				}
@@ -447,8 +454,8 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
 			}
 		}
 	}
-	
-	if(passMessage && mInstance != NULL)
+
+	if (passMessage && mInstance != NULL)
 	{
 		LLTimer elapsed;
 
@@ -458,50 +465,50 @@ void LLPluginProcessChild::receiveMessageRaw(const std::string &message)
 	}
 }
 
-/* virtual */ 
+/* virtual */
 void LLPluginProcessChild::receivePluginMessage(const std::string &message)
 {
 	LL_DEBUGS("Plugin") << "Received from plugin: " << message << LL_ENDL;
-	
-	if(mBlockingRequest)
+
+	if (mBlockingRequest)
 	{
 		// 
 		LL_ERRS("Plugin") << "Can't send a message while already waiting on a blocking request -- aborting!" << LL_ENDL;
 	}
-	
+
 	// Incoming message from the plugin instance
 	bool passMessage = true;
 
 	// FIXME: how should we handle queueing here?
-	
+
 	// Intercept certain base messages (responses to ones sent by this class)
 	{
 		// Decode this message
 		LLPluginMessage parsed;
 		parsed.parse(message);
-		
-		if(parsed.hasValue("blocking_request"))
+
+		if (parsed.hasValue("blocking_request"))
 		{
 			mBlockingRequest = true;
 		}
 
 		std::string message_class = parsed.getClass();
-		if(message_class == "base")
+		if (message_class == "base")
 		{
 			std::string message_name = parsed.getName();
-			if(message_name == "init_response")
+			if (message_name == "init_response")
 			{
 				// The plugin has finished initializing.
 				setState(STATE_RUNNING);
 
 				// Don't pass this message up to the parent
 				passMessage = false;
-				
+
 				LLPluginMessage new_message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "load_plugin_response");
 				LLSD versions = parsed.getValueLLSD("versions");
 				new_message.setValueLLSD("versions", versions);
-				
-				if(parsed.hasValue("plugin_version"))
+
+				if (parsed.hasValue("plugin_version"))
 				{
 					std::string plugin_version = parsed.getValue("plugin_version");
 					new_message.setValueLLSD("plugin_version", plugin_version);
@@ -510,25 +517,25 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
 				// Let the parent know it's loaded and initialized.
 				sendMessageToParent(new_message);
 			}
-            else if (message_name == "goodbye")
-            {
-                setState(STATE_UNLOADED);
-            }
-			else if(message_name == "shm_remove_response")
+			else if (message_name == "goodbye")
+			{
+				setState(STATE_UNLOADED);
+			}
+			else if (message_name == "shm_remove_response")
 			{
 				// Don't pass this message up to the parent
 				passMessage = false;
 
 				std::string name = parsed.getValue("name");
-				sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);				
-				if(iter != mSharedMemoryRegions.end())
+				sharedMemoryRegionsType::iterator iter = mSharedMemoryRegions.find(name);
+				if (iter != mSharedMemoryRegions.end())
 				{
 					// detach the shared memory region
 					iter->second->detach();
-					
+
 					// and remove it from our map
 					mSharedMemoryRegions.erase(iter);
-					
+
 					// Finally, send the response to the parent.
 					LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "shm_remove_response");
 					message.setValue("name", name);
@@ -541,19 +548,19 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
 			}
 		}
 	}
-	
-	if(passMessage)
+
+	if (passMessage)
 	{
 		LL_DEBUGS("Plugin") << "Passing through to parent: " << message << LL_ENDL;
 		writeMessageRaw(message);
 	}
-	
-	while(mBlockingRequest)
+
+	while (mBlockingRequest)
 	{
 		// The plugin wants to block and wait for a response to this message.
 		sleep(mSleepTime);	// this will pump the message pipe and process messages
 
-		if(mBlockingResponseReceived || mSocketError != APR_SUCCESS || (mMessagePipe == NULL))
+		if (mBlockingResponseReceived || mSocketError != APR_SUCCESS || (mMessagePipe == NULL))
 		{
 			// Response has been received, or we've hit an error state.  Stop waiting.
 			mBlockingRequest = false;
@@ -566,14 +573,14 @@ void LLPluginProcessChild::receivePluginMessage(const std::string &message)
 void LLPluginProcessChild::setState(EState state)
 {
 	LL_DEBUGS("Plugin") << "setting state to " << state << LL_ENDL;
-	mState = state; 
+	mState = state;
 };
 
 void LLPluginProcessChild::deliverQueuedMessages()
 {
-	if(!mBlockingRequest)
+	if (!mBlockingRequest)
 	{
-		while(!mMessageQueue.empty())
+		while (!mMessageQueue.empty())
 		{
 			receiveMessageRaw(mMessageQueue.front());
 			mMessageQueue.pop();
diff --git a/indra/llplugin/slplugin/slplugin.cpp b/indra/llplugin/slplugin/slplugin.cpp
index 684bcf1207fff878300a57f7fb858a6f567ccaee..b96056541628b9c2d4dc5bd75760b9b4a3746585 100644
--- a/indra/llplugin/slplugin/slplugin.cpp
+++ b/indra/llplugin/slplugin/slplugin.cpp
@@ -100,33 +100,8 @@ LPTOP_LEVEL_EXCEPTION_FILTER WINAPI MyDummySetUnhandledExceptionFilter(
 
 BOOL PreventSetUnhandledExceptionFilter()
 {
-// WARNING: This won't work on 64-bit Windows systems so we turn it off it.
-//          It should work for any flavor of 32-bit Windows we care about.
-//          If it's off, sometimes you will see an OS message when a plugin crashes
-#ifndef _WIN64
-	HMODULE hKernel32 = LoadLibraryA( "kernel32.dll" );
-	if ( NULL == hKernel32 )
-		return FALSE;
-
-	void *pOrgEntry = GetProcAddress( hKernel32, "SetUnhandledExceptionFilter" );
-	if( NULL == pOrgEntry )
-		return FALSE;
-
-	unsigned char newJump[ 100 ];
-	DWORD dwOrgEntryAddr = (DWORD)pOrgEntry;
-	dwOrgEntryAddr += 5; // add 5 for 5 op-codes for jmp far
-	void *pNewFunc = &MyDummySetUnhandledExceptionFilter;
-	DWORD dwNewEntryAddr = (DWORD) pNewFunc;
-	DWORD dwRelativeAddr = dwNewEntryAddr - dwOrgEntryAddr;
-
-	newJump[ 0 ] = 0xE9;  // JMP absolute
-	memcpy( &newJump[ 1 ], &dwRelativeAddr, sizeof( pNewFunc ) );
-	SIZE_T bytesWritten;
-	BOOL bRet = WriteProcessMemory( GetCurrentProcess(), pOrgEntry, newJump, sizeof( pNewFunc ) + 1, &bytesWritten );
-	return bRet;
-#else
-	return FALSE;
-#endif
+	// remove the scary stuff that also isn't supported on 64 bit Windows
+	return TRUE;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 186716609ccb9e8ae0c5ca7e966165426dc08cfe..bfa65666b5e839e6d22c6168e6df8670049cb8dd 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -172,7 +172,7 @@ LLPrimitive::~LLPrimitive()
 {
 	clearTextureList();
 	// Cleanup handled by volume manager
-	if (mVolumep)
+	if (mVolumep && sVolumeManager)
 	{
 		sVolumeManager->unrefVolume(mVolumep);
 	}
diff --git a/indra/llui/lleditmenuhandler.h b/indra/llui/lleditmenuhandler.h
index 0932f094ef95eeb6c0028c151e46c417e7e0b72a..cd4fea8c526b7c1b2dc359a115d0ac0af4907ef4 100644
--- a/indra/llui/lleditmenuhandler.h
+++ b/indra/llui/lleditmenuhandler.h
@@ -58,9 +58,6 @@ class LLEditMenuHandler
 	
 	virtual void	deselect() {};
 	virtual BOOL	canDeselect() const { return FALSE; }
-	
-	virtual void	duplicate() {};
-	virtual BOOL	canDuplicate() const { return FALSE; }
 
 	// TODO: Instead of being a public data member, it would be better to hide it altogether
 	// and have a "set" method and then a bunch of static versions of the cut, copy, paste
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 8425774d465fcde4df07ab030cfffd0a0b199df2..022f814bbc8fde66ff07e3ae2dda26ed33643cd1 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3342,6 +3342,12 @@ BOOL LLMenuBarGL::handleAcceleratorKey(KEY key, MASK mask)
 		return TRUE;
 	}
 
+	if (result && !getHighlightedItem() && LLMenuGL::sMenuContainer->hasVisibleMenu())
+	{
+		// close menus originating from other menu bars
+		LLMenuGL::sMenuContainer->hideMenus();
+	}
+
 	return result;
 }
 
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index db8fdc46b71c80318833c07ebdb9b96883f26946..0afa8d43f1c891149856e530ac6ee3f6c932c45e 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1808,6 +1808,7 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
 			registrar.add("Url.ShowProfile", boost::bind(&LLScrollListCtrl::showProfile, id, is_group));
 			registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id));
 			registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));
+			registrar.add("Url.RemoveFriend", boost::bind(&LLScrollListCtrl::removeFriend, id));
 			registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));
 			registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));
 			registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group));
@@ -1852,6 +1853,12 @@ void LLScrollListCtrl::addFriend(std::string id)
 	LLUrlAction::addFriend(slurl);
 }
 
+void LLScrollListCtrl::removeFriend(std::string id)
+{
+	std::string slurl = "secondlife:///app/agent/" + id + "/about";
+	LLUrlAction::removeFriend(slurl);
+}
+
 void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
 {
 	// open the resident's details or the group details
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 6325a79cd5ed36a4d03266b64d959d6d3fe6f947..8343750a540b43e0523f97a610a944f2291a9bf3 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -432,6 +432,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	static void		showProfile(std::string id, bool is_group);
 	static void		sendIM(std::string id);
 	static void		addFriend(std::string id);
+	static void		removeFriend(std::string id);
 	static void		showNameDetails(std::string id, bool is_group);
 	static void		copyNameToClipboard(std::string id, bool is_group);
 	static void		copySLURLToClipboard(std::string id, bool is_group);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 88a5c3a58735695e1ecf3e33c3a9d40761f64bf9..f3a99dcef2656d7b1f2e054e3556056d168d0923 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1522,7 +1522,7 @@ void LLTextBase::reflow()
 		}
 
 		S32 line_height = 0;
-		S32 seg_line_offset = line_count;
+		S32 seg_line_offset = line_count + 1;
 
 		while(seg_iter != mSegments.end())
 		{
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 73f961b36b517c80f26838619ca072ae129c0f2d..1a49b94c236538270a29cc2699a36678fc984655 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1459,6 +1459,10 @@ void LLTextEditor::pasteHelper(bool is_primary)
 // Clean up string (replace tabs and remove characters that our fonts don't support).
 void LLTextEditor::cleanStringForPaste(LLWString & clean_string)
 {
+	std::string clean_string_utf = wstring_to_utf8str(clean_string);
+	std::replace( clean_string_utf.begin(), clean_string_utf.end(), '\r', '\n');
+	clean_string = utf8str_to_wstring(clean_string_utf);
+
 	LLWStringUtil::replaceTabsWithSpaces(clean_string, SPACES_PER_TAB);
 	if( mAllowEmbeddedItems )
 	{
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 301ae7f9c4ee7d2c0620ce2f46134a935332306d..5ec0ada6eb7cdd9889dd3e95ff7d87cecf046209 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -3800,7 +3800,7 @@ LLWindowCallbacks::DragNDropResult LLWindowWin32::completeDragNDropRequest( cons
 // When it handled the message, the value to be returned from
 // the Window Procedure is set to *result.
 
-BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
+BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *result)
 {
 	if ( mPreeditor )
 	{
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 39ef9b31a4e1ca8f16881e0fbd60c931c01fd867..059a008c45023f17df218405906d29f11104d85d 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -148,7 +148,7 @@ class LLWindowWin32 : public LLWindow
 	U32		fillReconvertString(const LLWString &text, S32 focus, S32 focus_length, RECONVERTSTRING *reconvert_string);
 	void	handleStartCompositionMessage();
 	void	handleCompositionMessage(U32 indexes);
-	BOOL	handleImeRequests(U32 request, U32 param, LRESULT *result);
+	BOOL	handleImeRequests(WPARAM request, LPARAM param, LRESULT *result);
 
 protected:
 	//
diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt
index 1eadce825e580dc0bc84ba9bc0818d1e8a2c4c35..1a5cc8ec9a44af8014a042eaece49c7722d26895 100644
--- a/indra/media_plugins/CMakeLists.txt
+++ b/indra/media_plugins/CMakeLists.txt
@@ -5,14 +5,17 @@ add_subdirectory(base)
 if (LINUX)
     add_subdirectory(gstreamer010)
     add_subdirectory(libvlc)
+    add_subdirectory(example)
 endif (LINUX)
 
 if (DARWIN)
     add_subdirectory(cef)
     add_subdirectory(libvlc)
+    add_subdirectory(example)
 endif (DARWIN)
 
 if (WINDOWS)
     add_subdirectory(cef)
     add_subdirectory(libvlc)
+    add_subdirectory(example)
 endif (WINDOWS)
diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index 201fb44847239bb856cf4c1d222264b8c812795d..5452fd9d1eb8f196be5efb627d8d6008c66cd23a 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -46,6 +46,10 @@ set(media_plugin_cef_SOURCE_FILES
     media_plugin_cef.cpp
     )
 
+set(media_plugin_cef_HEADER_FILES
+    volume_catcher.h
+    )
+
 set (media_plugin_cef_LINK_LIBRARIES
   ${LLPLUGIN_LIBRARIES}
   ${MEDIA_PLUGIN_BASE_LIBRARIES}
@@ -53,7 +57,21 @@ set (media_plugin_cef_LINK_LIBRARIES
   ${LLCOMMON_LIBRARIES}
   ${PLUGIN_API_WINDOWS_LIBRARIES})
 
-
+# Select which VolumeCatcher implementation to use
+if (LINUX)
+  message(FATAL_ERROR "CEF plugin has been enabled for a Linux compile.\n"
+    "  Please create a volume_catcher implementation for this platform.")
+elseif (DARWIN)
+  list(APPEND media_plugin_cef_SOURCE_FILES mac_volume_catcher_null.cpp)
+  find_library(CORESERVICES_LIBRARY CoreServices)
+  find_library(AUDIOUNIT_LIBRARY AudioUnit)
+  list(APPEND media_plugin_cef_LINK_LIBRARIES
+       ${CORESERVICES_LIBRARY}     # for Component Manager calls
+       ${AUDIOUNIT_LIBRARY}        # for AudioUnit calls
+       )
+elseif (WINDOWS)
+  list(APPEND media_plugin_cef_SOURCE_FILES windows_volume_catcher.cpp)
+endif (LINUX)
 
 set_source_files_properties(${media_plugin_cef_HEADER_FILES}
                             PROPERTIES HEADER_FILE_ONLY TRUE)
diff --git a/indra/media_plugins/cef/mac_volume_catcher_null.cpp b/indra/media_plugins/cef/mac_volume_catcher_null.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f4fcef71aa17f0f128c76250787f0b5393695173
--- /dev/null
+++ b/indra/media_plugins/cef/mac_volume_catcher_null.cpp
@@ -0,0 +1,95 @@
+/** 
+ * @file windows_volume_catcher.cpp
+ * @brief A null implementation of volume level control of all audio channels opened by a process.
+ *        We are using this for the macOS version for now until we can understand how to make the 
+ *        exitising mac_volume_catcher.cpp work without the (now, non-existant) QuickTime dependency
+ *
+ * @cond
+ * $LicenseInfo:firstyear=2010&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$
+ * @endcond
+ */
+
+#include "volume_catcher.h"
+#include "llsingleton.h"
+class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl>
+{
+	LLSINGLETON(VolumeCatcherImpl);
+	// This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
+	~VolumeCatcherImpl();
+
+public:
+
+	void setVolume(F32 volume);
+	void setPan(F32 pan);
+	
+private:
+	F32 	mVolume;
+	F32 	mPan;
+	bool mSystemIsVistaOrHigher;
+};
+
+VolumeCatcherImpl::VolumeCatcherImpl()
+:	mVolume(1.0f),			// default volume is max
+	mPan(0.f)				// default pan is centered
+{
+}
+
+VolumeCatcherImpl::~VolumeCatcherImpl()
+{
+}
+
+void VolumeCatcherImpl::setVolume(F32 volume)
+{
+	mVolume = volume;
+}
+
+void VolumeCatcherImpl::setPan(F32 pan)
+{	// remember pan for calculating individual channel levels later
+	mPan = pan;
+}
+
+/////////////////////////////////////////////////////
+
+VolumeCatcher::VolumeCatcher()
+{
+	pimpl = VolumeCatcherImpl::getInstance();
+}
+
+VolumeCatcher::~VolumeCatcher()
+{
+	// Let the instance persist until exit.
+}
+
+void VolumeCatcher::setVolume(F32 volume)
+{
+	pimpl->setVolume(volume);
+}
+
+void VolumeCatcher::setPan(F32 pan)
+{
+	pimpl->setPan(pan);
+}
+
+void VolumeCatcher::pump()
+{
+	// No periodic tasks are necessary for this implementation.
+}
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 906a5ff6e74d365f699315ffe523db5805b30d0f..796e262d6fbf8f54917196bbb1915ef392be88d2 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -34,6 +34,7 @@
 #include "llplugininstance.h"
 #include "llpluginmessage.h"
 #include "llpluginmessageclasses.h"
+#include "volume_catcher.h"
 #include "media_plugin_base.h"
 
 #include <functional>
@@ -55,7 +56,7 @@ class MediaPluginCEF :
 private:
 	bool init();
 
-	void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height, bool is_popup);
+	void onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height);
 	void onCustomSchemeURLCallback(std::string url);
 	void onConsoleMessageCallback(std::string message, std::string source, int line);
 	void onStatusMessageCallback(std::string value);
@@ -77,13 +78,14 @@ class MediaPluginCEF :
 	void unicodeInput(LLSD native_key_data);
 
 	void checkEditState();
-    void setVolume(F32 vol);
+    void setVolume();
 
 	bool mEnableMediaPluginDebugging;
 	std::string mHostLanguage;
 	bool mCookiesEnabled;
 	bool mPluginsEnabled;
 	bool mJavascriptEnabled;
+	bool mDisableGPU;
 	std::string mUserAgentSubtring;
 	std::string mAuthUsername;
 	std::string mAuthPassword;
@@ -94,13 +96,9 @@ class MediaPluginCEF :
 	std::string mCachePath;
 	std::string mCookiePath;
 	std::string mPickedFile;
+	VolumeCatcher mVolumeCatcher;
+	F32 mCurVolume;
 	dullahan* mCEFLib;
-
-	U8 *mPopupBuffer;
-	U32 mPopupW;
-	U32 mPopupH;
-	U32 mPopupX;
-	U32 mPopupY;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -117,6 +115,7 @@ MediaPluginBase(host_send_func, host_user_data)
 	mCookiesEnabled = true;
 	mPluginsEnabled = false;
 	mJavascriptEnabled = true;
+	mDisableGPU = true;
 	mUserAgentSubtring = "";
 	mAuthUsername = "";
 	mAuthPassword = "";
@@ -127,20 +126,18 @@ MediaPluginBase(host_send_func, host_user_data)
 	mCachePath = "";
 	mCookiePath = "";
 	mPickedFile = "";
+	mCurVolume = 0.0;
+
 	mCEFLib = new dullahan();
 
-	mPopupBuffer = NULL;
-	mPopupW = 0;
-	mPopupH = 0;
-	mPopupX = 0;
-	mPopupY = 0;
+	setVolume();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //
 MediaPluginCEF::~MediaPluginCEF()
 {
-	delete[] mPopupBuffer;
+	mCEFLib->shutdown();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -161,56 +158,13 @@ void MediaPluginCEF::postDebugMessage(const std::string& msg)
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-void MediaPluginCEF::onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height, bool is_popup)
+void MediaPluginCEF::onPageChangedCallback(const unsigned char* pixels, int x, int y, const int width, const int height)
 {
-	if( is_popup )
-	{
-		delete mPopupBuffer;
-		mPopupBuffer = NULL;
-		mPopupH = 0;
-		mPopupW = 0;
-		mPopupX = 0;
-		mPopupY = 0;
-	}
-
 	if( mPixels && pixels )
 	{
-		if (is_popup)
+		if (mWidth == width && mHeight == height)
 		{
-			if( width > 0 && height> 0 )
-			{
-				mPopupBuffer = new U8[ width * height * mDepth ];
-				memcpy( mPopupBuffer, pixels, width * height * mDepth );
-				mPopupH = height;
-				mPopupW = width;
-				mPopupX = x;
-				mPopupY = mHeight - y - height;
-			}
-		}
-		else
-		{
-			if (mWidth == width && mHeight == height)
-			{
-				memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
-			}
-			if( mPopupBuffer && mPopupH && mPopupW )
-			{
-				U32 bufferSize = mWidth * mHeight * mDepth;
-				U32 popupStride = mPopupW * mDepth;
-				U32 bufferStride = mWidth * mDepth;
-				int dstY = mPopupY;
-
-				int src = 0;
-				int dst = dstY  * mWidth * mDepth + mPopupX * mDepth;
-
-				for( int line = 0; dst + popupStride < bufferSize && line < mPopupH; ++line )
-				{
-					memcpy( mPixels + dst, mPopupBuffer + src, popupStride );
-					src += popupStride;
-					dst += bufferStride;
-				}
-			}
-
+			memcpy(mPixels, pixels, mWidth * mHeight * mDepth);
 		}
 		setDirty(0, 0, mWidth, mHeight);
 	}
@@ -258,10 +212,10 @@ void MediaPluginCEF::onLoadStartCallback()
 //
 void MediaPluginCEF::onRequestExitCallback()
 {
-	mCEFLib->shutdown();
-
 	LLPluginMessage message("base", "goodbye");
 	sendMessage(message);
+
+	mDeleteMe = true;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -477,7 +431,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			if (message_name == "init")
 			{
 				// event callbacks from Dullahan
-				mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5, std::placeholders::_6));
+				mCEFLib->setOnPageChangedCallback(std::bind(&MediaPluginCEF::onPageChangedCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, std::placeholders::_4, std::placeholders::_5));
 				mCEFLib->setOnCustomSchemeURLCallback(std::bind(&MediaPluginCEF::onCustomSchemeURLCallback, this, std::placeholders::_1));
 				mCEFLib->setOnConsoleMessageCallback(std::bind(&MediaPluginCEF::onConsoleMessageCallback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));
 				mCEFLib->setOnStatusMessageCallback(std::bind(&MediaPluginCEF::onStatusMessageCallback, this, std::placeholders::_1));
@@ -499,10 +453,12 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				settings.cache_path = mCachePath;
 				settings.cookie_store_path = mCookiePath;
 				settings.cookies_enabled = mCookiesEnabled;
+				settings.disable_gpu = mDisableGPU;
 				settings.flash_enabled = mPluginsEnabled;
 				settings.flip_mouse_y = false;
 				settings.flip_pixels_y = true;
 				settings.frame_rate = 60;
+				settings.force_wave_audio = true;
 				settings.initial_height = 1024;
 				settings.initial_width = 1024;
 				settings.java_enabled = false;
@@ -755,13 +711,18 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 			{
 				mJavascriptEnabled = message_in.getValueBoolean("enable");
 			}
+			else if (message_name == "gpu_disabled")
+			{
+				mDisableGPU = message_in.getValueBoolean("disable");
+			}
 		}
         else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_TIME)
         {
             if (message_name == "set_volume")
             {
-                F32 volume = (F32)message_in.getValueReal("volume");
-                setVolume(volume);
+				F32 volume = (F32)message_in.getValueReal("volume");
+				mCurVolume = volume;
+                setVolume();
             }
         }
         else
@@ -840,8 +801,9 @@ void MediaPluginCEF::checkEditState()
 	}
 }
 
-void MediaPluginCEF::setVolume(F32 vol)
+void MediaPluginCEF::setVolume()
 {
+	mVolumeCatcher.setVolume(mCurVolume);
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt
index d2a17b1d76727eb1a5950367ac54c0a08ce3c18b..6f5b28b8e91bcf4a355aad26363461ba08953750 100644
--- a/indra/media_plugins/example/CMakeLists.txt
+++ b/indra/media_plugins/example/CMakeLists.txt
@@ -60,14 +60,16 @@ target_link_libraries(media_plugin_example
 add_dependencies(media_plugin_example
   ${LLPLUGIN_LIBRARIES}
   ${MEDIA_PLUGIN_BASE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
+  # Using ${LLCOMMON_LIBRARIES} here drags in a whole bunch of Boost stuff
+  # that only produces CMake warnings about nonexistent dependencies.
+  llcommon
 )
 
 if (WINDOWS)
   set_target_properties(
     media_plugin_example
     PROPERTIES
-    LINK_FLAGS "/MANIFEST:NO"
+    LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /LTCG /NODEFAULTLIB:LIBCMT"
     )
 endif (WINDOWS)
 
diff --git a/indra/media_plugins/example/media_plugin_example.cpp b/indra/media_plugins/example/media_plugin_example.cpp
index 66c00cd58cd0e534eae65819b4cb4149e21de475..c296a0413de5daaea3c4e3a4b0629a131a838270 100644
--- a/indra/media_plugins/example/media_plugin_example.cpp
+++ b/indra/media_plugins/example/media_plugin_example.cpp
@@ -1,30 +1,30 @@
 /**
- * @file media_plugin_example.cpp
- * @brief Example plugin for LLMedia API plugin system
- *
- * @cond
- * $LicenseInfo:firstyear=2008&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$
- * @endcond
- */
+* @file media_plugin_example.cpp
+* @brief Example plugin for LLMedia API plugin system
+*
+* @cond
+* $LicenseInfo:firstyear=2008&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$
+* @endcond
+*/
 
 #include "linden_common.h"
 
@@ -38,375 +38,354 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-class MediaPluginExample :
-        public MediaPluginBase
+class mediaPluginExample :
+	public MediaPluginBase
 {
-    public:
-        MediaPluginExample( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data );
-        ~MediaPluginExample();
-
-        /*virtual*/ void receiveMessage( const char* message_string );
-
-    private:
-        bool init();
-        void update( F64 milliseconds );
-        void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b );
-        bool mFirstTime;
-
-        time_t mLastUpdateTime;
-        enum Constants { ENumObjects = 10 };
-        unsigned char* mBackgroundPixels;
-        int mColorR[ ENumObjects ];
-        int mColorG[ ENumObjects ];
-        int mColorB[ ENumObjects ];
-        int mXpos[ ENumObjects ];
-        int mYpos[ ENumObjects ];
-        int mXInc[ ENumObjects ];
-        int mYInc[ ENumObjects ];
-        int mBlockSize[ ENumObjects ];
-        bool mMouseButtonDown;
-        bool mStopAction;
+public:
+	mediaPluginExample(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data);
+	~mediaPluginExample();
+
+	/*virtual*/ void receiveMessage(const char* message_string);
+
+private:
+	bool init();
+	void update(F64 milliseconds);
+	bool mFirstTime;
+
+	time_t mLastUpdateTime;
+	enum Constants { ENumObjects = 64 };
+	unsigned char* mBackgroundPixels;
+	int mColorR[ENumObjects];
+	int mColorG[ENumObjects];
+	int mColorB[ENumObjects];
+	int mXpos[ENumObjects];
+	int mYpos[ENumObjects];
+	int mXInc[ENumObjects];
+	int mYInc[ENumObjects];
+	int mBlockSize[ENumObjects];
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-MediaPluginExample::MediaPluginExample( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) :
-    MediaPluginBase( host_send_func, host_user_data )
+mediaPluginExample::mediaPluginExample(LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data) :
+MediaPluginBase(host_send_func, host_user_data)
 {
-    mFirstTime = true;
-    mWidth = 0;
-    mHeight = 0;
-    mDepth = 4;
-    mPixels = 0;
-    mMouseButtonDown = false;
-    mStopAction = false;
-    mLastUpdateTime = 0;
+	mFirstTime = true;
+	mTextureWidth = 0;
+	mTextureHeight = 0;
+	mWidth = 0;
+	mHeight = 0;
+	mDepth = 4;
+	mPixels = 0;
+	mLastUpdateTime = 0;
+	mBackgroundPixels = 0;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-MediaPluginExample::~MediaPluginExample()
+mediaPluginExample::~mediaPluginExample()
 {
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-void MediaPluginExample::receiveMessage( const char* message_string )
+void mediaPluginExample::receiveMessage(const char* message_string)
 {
-//  std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
-    LLPluginMessage message_in;
-
-    if(message_in.parse(message_string) >= 0)
-    {
-        std::string message_class = message_in.getClass();
-        std::string message_name = message_in.getName();
-        if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
-        {
-            if(message_name == "init")
-            {
-                LLPluginMessage message("base", "init_response");
-                LLSD versions = LLSD::emptyMap();
-                versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
-                versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
-                versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
-                message.setValueLLSD("versions", versions);
-
-                std::string plugin_version = "Example plugin 1.0..0";
-                message.setValue("plugin_version", plugin_version);
-                sendMessage(message);
-            }
-            else if(message_name == "idle")
-            {
-                // no response is necessary here.
-                F64 time = message_in.getValueReal("time");
-
-                // Convert time to milliseconds for update()
-                update((int)(time * 1000.0f));
-            }
-            else if(message_name == "cleanup")
-            {
-            }
-            else if(message_name == "shm_added")
-            {
-                SharedSegmentInfo info;
-                info.mAddress = message_in.getValuePointer("address");
-                info.mSize = (size_t)message_in.getValueS32("size");
-                std::string name = message_in.getValue("name");
-
-                mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
-
-            }
-            else if(message_name == "shm_remove")
-            {
-                std::string name = message_in.getValue("name");
-
-                SharedSegmentMap::iterator iter = mSharedSegments.find(name);
-                if(iter != mSharedSegments.end())
-                {
-                    if(mPixels == iter->second.mAddress)
-                    {
-                        // This is the currently active pixel buffer.  Make sure we stop drawing to it.
-                        mPixels = NULL;
-                        mTextureSegmentName.clear();
-                    }
-                    mSharedSegments.erase(iter);
-                }
-                else
-                {
-//                  std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
-                }
-
-                // Send the response so it can be cleaned up.
-                LLPluginMessage message("base", "shm_remove_response");
-                message.setValue("name", name);
-                sendMessage(message);
-            }
-            else
-            {
-//              std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
-            }
-        }
-        else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
-        {
-            if(message_name == "init")
-            {
-                // Plugin gets to decide the texture parameters to use.
-                mDepth = 4;
-                LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
-                message.setValueS32("default_width", 1024);
-                message.setValueS32("default_height", 1024);
-                message.setValueS32("depth", mDepth);
-                message.setValueU32("internalformat", GL_RGBA);
-                message.setValueU32("format", GL_RGBA);
-                message.setValueU32("type", GL_UNSIGNED_BYTE);
-                message.setValueBoolean("coords_opengl", true);
-                sendMessage(message);
-            }
-            else if(message_name == "size_change")
-            {
-                std::string name = message_in.getValue("name");
-                S32 width = message_in.getValueS32("width");
-                S32 height = message_in.getValueS32("height");
-                S32 texture_width = message_in.getValueS32("texture_width");
-                S32 texture_height = message_in.getValueS32("texture_height");
-
-                if(!name.empty())
-                {
-                    // Find the shared memory region with this name
-                    SharedSegmentMap::iterator iter = mSharedSegments.find(name);
-                    if(iter != mSharedSegments.end())
-                    {
-                        mPixels = (unsigned char*)iter->second.mAddress;
-                        mWidth = width;
-                        mHeight = height;
-
-                        mTextureWidth = texture_width;
-                        mTextureHeight = texture_height;
-                    };
-                };
-
-                LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
-                message.setValue("name", name);
-                message.setValueS32("width", width);
-                message.setValueS32("height", height);
-                message.setValueS32("texture_width", texture_width);
-                message.setValueS32("texture_height", texture_height);
-                sendMessage(message);
-
-            }
-            else if(message_name == "load_uri")
-            {
-            }
-            else if(message_name == "mouse_event")
-            {
-                std::string event = message_in.getValue("event");
-                if(event == "down")
-                {
-
-                }
-                else if(event == "up")
-                {
-                }
-                else if(event == "double_click")
-                {
-                }
-            }
-        }
-        else
-        {
-//          std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
-        };
-    }
+	//  std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+	LLPluginMessage message_in;
+
+	if (message_in.parse(message_string) >= 0)
+	{
+		std::string message_class = message_in.getClass();
+		std::string message_name = message_in.getName();
+		if (message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
+		{
+			if (message_name == "init")
+			{
+				LLPluginMessage message("base", "init_response");
+				LLSD versions = LLSD::emptyMap();
+				versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
+				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
+				versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
+				message.setValueLLSD("versions", versions);
+
+				std::string plugin_version = "Example plugin 0.0.0";
+				message.setValue("plugin_version", plugin_version);
+				sendMessage(message);
+			}
+			else if (message_name == "idle")
+			{
+				// no response is necessary here.
+				F64 time = message_in.getValueReal("time");
+
+				// Convert time to milliseconds for update()
+				update((int)(time * 1000.0f));
+			}
+			else if (message_name == "cleanup")
+			{
+				LLPluginMessage message("base", "goodbye");
+				sendMessage(message);
+
+				mDeleteMe = true;
+			}
+			else if (message_name == "shm_added")
+			{
+				SharedSegmentInfo info;
+				info.mAddress = message_in.getValuePointer("address");
+				info.mSize = (size_t)message_in.getValueS32("size");
+				std::string name = message_in.getValue("name");
+
+				mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
+
+			}
+			else if (message_name == "shm_remove")
+			{
+				std::string name = message_in.getValue("name");
+
+				SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+				if (iter != mSharedSegments.end())
+				{
+					if (mPixels == iter->second.mAddress)
+					{
+						// This is the currently active pixel buffer.  Make sure we stop drawing to it.
+						mPixels = NULL;
+						mTextureSegmentName.clear();
+					}
+					mSharedSegments.erase(iter);
+				}
+				else
+				{
+					//                  std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
+				}
+
+				// Send the response so it can be cleaned up.
+				LLPluginMessage message("base", "shm_remove_response");
+				message.setValue("name", name);
+				sendMessage(message);
+			}
+			else
+			{
+				//              std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
+			}
+		}
+		else if (message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+		{
+			if (message_name == "init")
+			{
+				// Plugin gets to decide the texture parameters to use.
+				mDepth = 4;
+				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
+				message.setValueS32("default_width", 1024);
+				message.setValueS32("default_height", 1024);
+				message.setValueS32("depth", mDepth);
+				message.setValueU32("internalformat", GL_RGB);
+				message.setValueU32("format", GL_RGBA);
+				message.setValueU32("type", GL_UNSIGNED_BYTE);
+				message.setValueBoolean("coords_opengl", true);
+				sendMessage(message);
+			}
+			else if (message_name == "size_change")
+			{
+				std::string name = message_in.getValue("name");
+				S32 width = message_in.getValueS32("width");
+				S32 height = message_in.getValueS32("height");
+				S32 texture_width = message_in.getValueS32("texture_width");
+				S32 texture_height = message_in.getValueS32("texture_height");
+
+				if (!name.empty())
+				{
+					// Find the shared memory region with this name
+					SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+					if (iter != mSharedSegments.end())
+					{
+						mPixels = (unsigned char*)iter->second.mAddress;
+						mWidth = width;
+						mHeight = height;
+
+						mTextureWidth = texture_width;
+						mTextureHeight = texture_height;
+					};
+				};
+
+				LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
+				message.setValue("name", name);
+				message.setValueS32("width", width);
+				message.setValueS32("height", height);
+				message.setValueS32("texture_width", texture_width);
+				message.setValueS32("texture_height", texture_height);
+				sendMessage(message);
+
+				mFirstTime = true;
+				mLastUpdateTime = 0;
+
+			}
+			else if (message_name == "load_uri")
+			{
+			}
+			else if (message_name == "mouse_event")
+			{
+				std::string event = message_in.getValue("event");
+				if (event == "down")
+				{
+
+				}
+				else if (event == "up")
+				{
+				}
+				else if (event == "double_click")
+				{
+				}
+			}
+		}
+		else
+		{
+		};
+	}
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-void MediaPluginExample::write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b )
+void mediaPluginExample::update(F64 milliseconds)
 {
-    // make sure we don't write outside the buffer
-    if ( ( x < 0 ) || ( x >= mWidth ) || ( y < 0 ) || ( y >= mHeight ) )
-        return;
-
-    if ( mBackgroundPixels != NULL )
-    {
-        unsigned char *pixel = mBackgroundPixels;
-        pixel += y * mWidth * mDepth;
-        pixel += ( x * mDepth );
-        pixel[ 0 ] = b;
-        pixel[ 1 ] = g;
-        pixel[ 2 ] = r;
-
-        setDirty( x, y, x + 1, y + 1 );
-    };
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void MediaPluginExample::update( F64 milliseconds )
-{
-    if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 )
-        return;
-
-    if ( mPixels == 0 )
-            return;
-
-    if ( mFirstTime )
-    {
-        for( int n = 0; n < ENumObjects; ++n )
-        {
-            mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 );
-            mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 );
-
-            mColorR[ n ] = rand() % 0x60 + 0x60;
-            mColorG[ n ] = rand() % 0x60 + 0x60;
-            mColorB[ n ] = rand() % 0x60 + 0x60;
-
-            mXInc[ n ] = 0;
-            while ( mXInc[ n ] == 0 )
-                mXInc[ n ] = rand() % 7 - 3;
-
-            mYInc[ n ] = 0;
-            while ( mYInc[ n ] == 0 )
-                mYInc[ n ] = rand() % 9 - 4;
-
-            mBlockSize[ n ] = rand() % 0x30 + 0x10;
-        };
-
-        delete [] mBackgroundPixels;
-
-        mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ];
-
-        mFirstTime = false;
-    };
-
-    if ( mStopAction )
-        return;
-
-    if ( time( NULL ) > mLastUpdateTime + 3 )
-    {
-        const int num_squares = rand() % 20 + 4;
-        int sqr1_r = rand() % 0x80 + 0x20;
-        int sqr1_g = rand() % 0x80 + 0x20;
-        int sqr1_b = rand() % 0x80 + 0x20;
-        int sqr2_r = rand() % 0x80 + 0x20;
-        int sqr2_g = rand() % 0x80 + 0x20;
-        int sqr2_b = rand() % 0x80 + 0x20;
-
-        for ( int y1 = 0; y1 < num_squares; ++y1 )
-        {
-            for ( int x1 = 0; x1 < num_squares; ++x1 )
-            {
-                int px_start = mWidth * x1 / num_squares;
-                int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares;
-                int py_start = mHeight * y1 / num_squares;
-                int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares;
-
-                for( int y2 = py_start; y2 < py_end; ++y2 )
-                {
-                    for( int x2 = px_start; x2 < px_end; ++x2 )
-                    {
-                        int rowspan = mWidth * mDepth;
-
-                        if ( ( y1 % 2 ) ^ ( x1 % 2 ) )
-                        {
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r;
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g;
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b;
-                        }
-                        else
-                        {
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r;
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g;
-                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b;
-                        };
-                    };
-                };
-            };
-        };
-
-        time( &mLastUpdateTime );
-    };
-
-    memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth );
-
-    for( int n = 0; n < ENumObjects; ++n )
-    {
-        if ( rand() % 50 == 0 )
-        {
-                mXInc[ n ] = 0;
-                while ( mXInc[ n ] == 0 )
-                    mXInc[ n ] = rand() % 7 - 3;
-
-                mYInc[ n ] = 0;
-                while ( mYInc[ n ] == 0 )
-                    mYInc[ n ] = rand() % 9 - 4;
-        };
-
-        if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] )
-            mXInc[ n ]= -mXInc[ n ];
-
-        if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] )
-            mYInc[ n ]= -mYInc[ n ];
-
-        mXpos[ n ] += mXInc[ n ];
-        mYpos[ n ] += mYInc[ n ];
-
-        for( int y = 0; y < mBlockSize[ n ]; ++y )
-        {
-            for( int x = 0; x < mBlockSize[ n ]; ++x )
-            {
-                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ];
-                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ];
-                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ];
-            };
-        };
-    };
-
-    setDirty( 0, 0, mWidth, mHeight );
+	if (mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048)
+		return;
+
+	if (mPixels == 0)
+		return;
+
+	if (mFirstTime)
+	{
+		for (int n = 0; n < ENumObjects; ++n)
+		{
+			mXpos[n] = (mWidth / 2) + rand() % (mWidth / 16) - (mWidth / 32);
+			mYpos[n] = (mHeight / 2) + rand() % (mHeight / 16) - (mHeight / 32);
+
+			mColorR[n] = rand() % 0x60 + 0x60;
+			mColorG[n] = rand() % 0x60 + 0x60;
+			mColorB[n] = rand() % 0x60 + 0x60;
+
+			mXInc[n] = 0;
+			while (mXInc[n] == 0)
+				mXInc[n] = rand() % 7 - 3;
+
+			mYInc[n] = 0;
+			while (mYInc[n] == 0)
+				mYInc[n] = rand() % 9 - 4;
+
+			mBlockSize[n] = rand() % 0x30 + 0x10;
+		};
+
+		delete[] mBackgroundPixels;
+
+		mBackgroundPixels = new unsigned char[mWidth * mHeight * mDepth];
+
+		mFirstTime = false;
+	};
+
+	if (time(NULL) > mLastUpdateTime + 3)
+	{
+		const int num_squares = rand() % 20 + 4;
+		int sqr1_r = rand() % 0x80 + 0x20;
+		int sqr1_g = rand() % 0x80 + 0x20;
+		int sqr1_b = rand() % 0x80 + 0x20;
+		int sqr2_r = rand() % 0x80 + 0x20;
+		int sqr2_g = rand() % 0x80 + 0x20;
+		int sqr2_b = rand() % 0x80 + 0x20;
+
+		for (int y1 = 0; y1 < num_squares; ++y1)
+		{
+			for (int x1 = 0; x1 < num_squares; ++x1)
+			{
+				int px_start = mWidth * x1 / num_squares;
+				int px_end = (mWidth * (x1 + 1)) / num_squares;
+				int py_start = mHeight * y1 / num_squares;
+				int py_end = (mHeight * (y1 + 1)) / num_squares;
+
+				for (int y2 = py_start; y2 < py_end; ++y2)
+				{
+					for (int x2 = px_start; x2 < px_end; ++x2)
+					{
+						int rowspan = mWidth * mDepth;
+
+						if ((y1 % 2) ^ (x1 % 2))
+						{
+							mBackgroundPixels[y2 * rowspan + x2 * mDepth + 0] = sqr1_r;
+							mBackgroundPixels[y2 * rowspan + x2 * mDepth + 1] = sqr1_g;
+							mBackgroundPixels[y2 * rowspan + x2 * mDepth + 2] = sqr1_b;
+						}
+						else
+						{
+							mBackgroundPixels[y2 * rowspan + x2 * mDepth + 0] = sqr2_r;
+							mBackgroundPixels[y2 * rowspan + x2 * mDepth + 1] = sqr2_g;
+							mBackgroundPixels[y2 * rowspan + x2 * mDepth + 2] = sqr2_b;
+						};
+					};
+				};
+			};
+		};
+
+		time(&mLastUpdateTime);
+	};
+
+	memcpy(mPixels, mBackgroundPixels, mWidth * mHeight * mDepth);
+
+	for (int n = 0; n < ENumObjects; ++n)
+	{
+		if (rand() % 50 == 0)
+		{
+			mXInc[n] = 0;
+			while (mXInc[n] == 0)
+				mXInc[n] = rand() % 7 - 3;
+
+			mYInc[n] = 0;
+			while (mYInc[n] == 0)
+				mYInc[n] = rand() % 9 - 4;
+		};
+
+		if (mXpos[n] + mXInc[n] < 0 || mXpos[n] + mXInc[n] >= mWidth - mBlockSize[n])
+			mXInc[n] = -mXInc[n];
+
+		if (mYpos[n] + mYInc[n] < 0 || mYpos[n] + mYInc[n] >= mHeight - mBlockSize[n])
+			mYInc[n] = -mYInc[n];
+
+		mXpos[n] += mXInc[n];
+		mYpos[n] += mYInc[n];
+
+		for (int y = 0; y < mBlockSize[n]; ++y)
+		{
+			for (int x = 0; x < mBlockSize[n]; ++x)
+			{
+				mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 0] = mColorR[n];
+				mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 1] = mColorG[n];
+				mPixels[(mXpos[n] + x) * mDepth + (mYpos[n] + y) * mDepth * mWidth + 2] = mColorB[n];
+			};
+		};
+	};
+
+	setDirty(0, 0, mWidth, mHeight);
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-bool MediaPluginExample::init()
+bool mediaPluginExample::init()
 {
-    LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text" );
-    message.setValue( "name", "Example Plugin" );
-    sendMessage( message );
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text");
+	message.setValue("name", "Example Plugin");
+	sendMessage(message);
 
-    return true;
+	return true;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 //
-int init_media_plugin( LLPluginInstance::sendMessageFunction host_send_func,
-                        void* host_user_data,
-                        LLPluginInstance::sendMessageFunction *plugin_send_func,
-                        void **plugin_user_data )
+int init_media_plugin(LLPluginInstance::sendMessageFunction host_send_func,
+	void* host_user_data,
+	LLPluginInstance::sendMessageFunction *plugin_send_func,
+	void **plugin_user_data)
 {
-    MediaPluginExample* self = new MediaPluginExample( host_send_func, host_user_data );
-    *plugin_send_func = MediaPluginExample::staticReceiveMessage;
-    *plugin_user_data = ( void* )self;
+	mediaPluginExample* self = new mediaPluginExample(host_send_func, host_user_data);
+	*plugin_send_func = mediaPluginExample::staticReceiveMessage;
+	*plugin_user_data = (void*)self;
 
-    return 0;
+	return 0;
 }
-
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index fa53b5a45d3acaefe097ee664de8fdf62b44832f..821f46edd24c77eb7e0802add7585ed71694ef74 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -204,6 +204,7 @@ set(viewer_SOURCE_FILES
     llfloaterautoreplacesettings.cpp
     llfloateravatar.cpp
     llfloateravatarpicker.cpp
+    llfloateravatarrendersettings.cpp
     llfloateravatartextures.cpp
     llfloaterbeacons.cpp
     llfloaterbigpreview.cpp
@@ -237,6 +238,7 @@ set(viewer_SOURCE_FILES
     llfloatergesture.cpp
     llfloatergodtools.cpp
     llfloatergotoline.cpp
+    llfloatergridstatus.cpp
     llfloatergroupbulkban.cpp
     llfloatergroupinvite.cpp
     llfloatergroups.cpp
@@ -820,6 +822,7 @@ set(viewer_HEADER_FILES
     llfloaterautoreplacesettings.h
     llfloateravatar.h
     llfloateravatarpicker.h
+    llfloateravatarrendersettings.h
     llfloateravatartextures.h
     llfloaterbeacons.h
     llfloaterbigpreview.h
@@ -853,6 +856,7 @@ set(viewer_HEADER_FILES
     llfloatergesture.h
     llfloatergodtools.h
     llfloatergotoline.h
+    llfloatergridstatus.h
     llfloatergroupbulkban.h
     llfloatergroupinvite.h
     llfloatergroups.h
@@ -1747,6 +1751,7 @@ if (WINDOWS)
       SLPlugin
       media_plugin_cef
       media_plugin_libvlc
+      media_plugin_example
       winmm_shim
       windows-crash-logger
       )
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 9bc0a7c70142365f29126c67a38aae447ea8e500..412d3a53b327fc5dccb9951a033606039a6e1023 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -292,4 +292,15 @@
            is_running_function="Floater.IsOpen"
            is_running_parameters="reporter"
            />
+  <command name="gridstatus"
+           available_in_toybox="true"
+           is_flashing_allowed="true"
+           icon="Command_Grid_Status_Icon"
+           label_ref="Command_Grid_Status_Label"
+           tooltip_ref="Command_Grid_Status_Tooltip"
+           execute_function="Floater.ToggleOrBringToFront"
+           execute_parameters="grid_status"
+           is_running_function="Floater.IsOpen"
+           is_running_parameters="grid_status"
+           />
 </commands>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 51f3d3332b6c0e34f1d562def52b8459875722d7..4a6f30b5a9934e09d24095aaa2235006170ad4b6 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -5163,6 +5163,39 @@
       <key>Value</key>
       <string>http://wiki.secondlife.com/wiki/[LSL_STRING]</string>
     </map>
+    <key>GridStatusRSS</key>
+    <map>
+      <key>Comment</key>
+      <string>URL that points to SL Grid Status RSS</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>https://secondlife-status.statuspage.io/history.atom</string>
+    </map>
+    <key>GridStatusUpdateDelay</key>
+    <map>
+      <key>Comment</key>
+      <string>Timer delay for updating Grid Status RSS.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>60.0</real>
+    </map>
+    <key>TestGridStatusRSSFromFile</key>
+    <map>
+      <key>Comment</key>
+      <string>For testing only: Don't update rss xml file from server.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>LagMeterShrunk</key>
     <map>
       <key>Comment</key>
@@ -8382,6 +8415,17 @@
         <key>Value</key>
             <integer>1</integer>
         </map>
+  <key>AlwaysRenderFriends</key>
+    <map>
+      <key>Comment</key>
+      <string>Always render friends regardless of max complexity</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
   <key>RenderAvatar</key>
     <map>
       <key>Comment</key>
@@ -15114,6 +15158,22 @@
         <integer>0</integer>
         </array>
         </map>
+    <key>GridStatusFloaterRect</key>
+    <map>
+        <key>Comment</key>
+        <string>Web profile floater dimensions</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>Rect</string>
+        <key>Value</key>
+        <array>
+            <integer>0</integer>
+            <integer>520</integer>
+            <integer>625</integer>
+            <integer>0</integer>
+        </array>
+    </map>
     <key>HelpFloaterOpen</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index bb7e15bcf6a51cd9c3a0f875d11d899fe997c7ce..1377cd7f21ca0fe3f31c024dcbc71f78cc659daf 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -90,8 +90,11 @@ InstProgressFlags smooth colored		# New colored smooth look
 SetOverwrite on							# Overwrite files by default
 AutoCloseWindow true					# After all files install, close window
 
-InstallDir "%%$PROGRAMFILES%%\${INSTNAME}"
-InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" ""
+# initial location of install (default when not already installed)
+#   note: Now we defer looking for existing install until onInit when we
+#   are able to engage the 32/64 registry function
+InstallDir "%%PROGRAMFILES%%\${INSTNAME}"
+
 UninstallText $(UninstallTextMsg)
 DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup)
 Page directory dirPre
@@ -119,6 +122,8 @@ Var DO_UNINSTALL_V2     # If non-null, path to a previous Viewer 2 installation
 !insertmacro GetParameters
 !insertmacro GetOptions
 !include WinVer.nsh			# For OS and SP detection
+!include 'LogicLib.nsh'     # for value comparison
+!include "x64.nsh"			# for 64bit detection
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Pre-directory page callback
@@ -137,7 +142,21 @@ FunctionEnd
 ;; entry to the language ID selector below
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Function .onInit
+
 %%ENGAGEREGISTRY%%
+
+# read the current location of the install for this version
+# if $0 is empty, this is the first time for this viewer name
+ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\\Linden Research, Inc.\\${INSTNAME}" ""
+
+# viewer with this name not installed before
+${If} $0 == ""
+    # nothing to do here
+${Else}
+	# use the value we got from registry as install location
+    StrCpy $INSTDIR $0
+${EndIf}
+
 Call CheckCPUFlags							# Make sure we have SSE2 support
 Call CheckWindowsVersion					# Don't install On unsupported systems
     Push $0
@@ -196,7 +215,9 @@ FunctionEnd
 ;; Prep Uninstaller Section
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Function un.onInit
+
 %%ENGAGEREGISTRY%%
+
 # Read language from registry and set for uninstaller. Key will be removed on successful uninstall
 	ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage"
     IfErrors lbl_end
@@ -321,6 +342,10 @@ WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninst
 WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "UninstallString" '"$INSTDIR\uninst.exe"'
 WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayVersion" "${VERSION_LONG}"
 WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "EstimatedSize" "0x0001D500"		# ~117 MB
+
+# from FS:Ansariel
+WriteRegStr HKEY_LOCAL_MACHINE "Software\Microsoft\Windows\CurrentVersion\Uninstall\$INSTPROG" "DisplayIcon" '"$INSTDIR\$INSTEXE"'
+
 # BUG-2707 Disable SEHOP for installed viewer.
 WriteRegDWORD HKEY_LOCAL_MACHINE "Software\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\$INSTEXE" "DisableExceptionChainValidation" 1
 
@@ -566,7 +591,7 @@ FunctionEnd
 Function RemoveProgFilesOnInst
 
 # Remove old SecondLife.exe to invalidate any old shortcuts to it that may be in non-standard locations. See MAINT-3575
-Delete "$INSTDIR\SecondLife.exe"
+Delete "$INSTDIR\$INSTEXE"
 
 # Remove old shader files first so fallbacks will work. See DEV-5663
 RMDir /r "$INSTDIR\app_settings\shaders"
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index e335eabd1af7bf29e8d2aa217228e6affc5f2386..5b9f1b9d4fd31d45c0736e7a6832ade9d08e5add 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -1537,6 +1537,14 @@ LLVector3d LLAgentCamera::calcFocusPositionTargetGlobal()
 	}
 	else if (mCameraMode == CAMERA_MODE_CUSTOMIZE_AVATAR)
 	{
+		if (mFocusOnAvatar)
+		{
+			LLVector3 focus_target = isAgentAvatarValid()
+				? gAgentAvatarp->mHeadp->getWorldPosition()
+				: gAgent.getPositionAgent();
+			LLVector3d focus_target_global = gAgent.getPosGlobalFromAgent(focus_target);
+			mFocusTargetGlobal = focus_target_global;
+		}
 		return mFocusTargetGlobal;
 	}
 	else if (!mFocusOnAvatar)
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 5e1658590d77c15f639c87558484be158dfe4b41..0f3a8890070f1b77393322a28397d368d559dff1 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1083,7 +1083,7 @@ bool LLAppViewer::init()
 			minSpecs += "\n";
 			unsupported = true;
 		}
-		if(gSysMemory.getPhysicalMemoryClamped() < minRAM)
+		if(gSysMemory.getPhysicalMemoryKB() < minRAM)
 		{
 			minSpecs += LLNotifications::instance().getGlobalString("UnsupportedRAM");
 			minSpecs += "\n";
@@ -2098,13 +2098,6 @@ bool LLAppViewer::cleanup()
 	// This calls every remaining LLSingleton's deleteSingleton() method.
 	// No class destructor should perform any cleanup that might take
 	// significant realtime, or throw an exception.
-	// LLSingleton machinery includes a last-gasp implicit deleteAll() call,
-	// so this explicit call shouldn't strictly be necessary. However, by the
-	// time the runtime engages that implicit call, it may already have
-	// destroyed things like std::cerr -- so the implicit deleteAll() refrains
-	// from logging anything. Since both cleanupAll() and deleteAll() call
-	// their respective cleanup methods in computed dependency order, it's
-	// probably useful to be able to log that order.
 	LLSingletonBase::deleteAll();
 
 	removeDumpDir();
@@ -3076,7 +3069,12 @@ LLSD LLAppViewer::getViewerInfo() const
 	std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
 	if (! LLStringUtil::endsWith(url, "/"))
 		url += "/";
-	url += LLURI::escape(LLVersionInfo::getChannel()) + "/";
+	std::string channel = LLVersionInfo::getChannel();
+	if (LLStringUtil::endsWith(boost::to_lower_copy(channel), " edu")) // Release Notes url shouldn't include the EDU parameter
+	{
+		boost::erase_tail(channel, 4);
+	}
+	url += LLURI::escape(channel) + "/";
 	url += LLURI::escape(LLVersionInfo::getVersion());
 
 	info["VIEWER_RELEASE_NOTES_URL"] = url;
@@ -3504,11 +3502,10 @@ void LLAppViewer::handleViewerCrash()
 	{
 		gDebugInfo["Dynamic"]["ParcelMediaURL"] = parcel->getMediaURL();
 	}
-	
-	
+
 	gDebugInfo["Dynamic"]["SessionLength"] = F32(LLFrameTimer::getElapsedSeconds());
-	gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = (LLSD::Integer) LLMemory::getCurrentRSS() >> 10;
-	
+	gDebugInfo["Dynamic"]["RAMInfo"]["Allocated"] = LLSD::Integer(LLMemory::getCurrentRSS() / 1024);
+
 	if(gLogoutInProgress)
 	{
 		gDebugInfo["Dynamic"]["LastExecEvent"] = LAST_EXEC_LOGOUT_CRASH;
@@ -5364,6 +5361,8 @@ void LLAppViewer::forceErrorBreakpoint()
    	LL_WARNS() << "Forcing a deliberate breakpoint" << LL_ENDL;
 #ifdef LL_WINDOWS
     DebugBreak();
+#else
+    asm ("int $3");
 #endif
     return;
 }
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index c81733d107f59fb247f5387fa311f1753e5ae3cf..d0093e695193da060e302ab21df967390067e6ce 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -491,7 +491,8 @@ bool LLAppViewerWin32::init()
 	disableWinErrorReporting();
 
 #ifndef LL_RELEASE_FOR_DOWNLOAD
-	LLWinDebug::instance().init();
+	// Merely requesting the LLSingleton instance initializes it.
+	LLWinDebug::instance();
 #endif
 
 #if LL_WINDOWS
@@ -515,10 +516,6 @@ bool LLAppViewerWin32::cleanup()
 
 	gDXHardware.cleanup();
 
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LLWinDebug::instance().cleanup();
-#endif
-
 	if (mIsConsoleAllocated)
 	{
 		FreeConsole();
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 36e95c07f4d3ae2edd2d14b85395987b287e02c2..2045c3e29714b9a61063a8d3c5e364a3297319b4 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -478,15 +478,14 @@ void LLAvatarActions::kick(const LLUUID& id)
 // static
 void LLAvatarActions::freezeAvatar(const LLUUID& id)
 {
-	std::string fullname;
-	gCacheName->getFullName(id, fullname);
+	LLAvatarName av_name;
 	LLSD payload;
 	payload["avatar_id"] = id;
 
-	if (!fullname.empty())
+	if (LLAvatarNameCache::get(id, &av_name))
 	{
 		LLSD args;
-		args["AVATAR_NAME"] = fullname;
+		args["AVATAR_NAME"] = av_name.getUserName();
 		LLNotificationsUtil::add("FreezeAvatarFullname", args, payload, handleFreezeAvatar);
 	}
 	else
@@ -498,15 +497,15 @@ void LLAvatarActions::freezeAvatar(const LLUUID& id)
 // static
 void LLAvatarActions::ejectAvatar(const LLUUID& id, bool ban_enabled)
 {
-	std::string fullname;
-	gCacheName->getFullName(id, fullname);
+	LLAvatarName av_name;
 	LLSD payload;
 	payload["avatar_id"] = id;
 	payload["ban_enabled"] = ban_enabled;
 	LLSD args;
-	if (!fullname.empty())
+	bool has_name = LLAvatarNameCache::get(id, &av_name);
+	if (has_name)
 	{
-		args["AVATAR_NAME"] = fullname;
+		args["AVATAR_NAME"] = av_name.getUserName();
 	}
 
 	if (ban_enabled)
@@ -515,7 +514,7 @@ void LLAvatarActions::ejectAvatar(const LLUUID& id, bool ban_enabled)
 	}
 	else
 	{
-		if (!fullname.empty())
+		if (has_name)
 		{
 			LLNotificationsUtil::add("EjectAvatarFullnameNoBan", args, payload, handleEjectAvatar);
 		}
@@ -991,10 +990,10 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 // static
 void LLAvatarActions::toggleBlock(const LLUUID& id)
 {
-	std::string name;
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(id, &av_name);
 
-	gCacheName->getFullName(id, name); // needed for mute
-	LLMute mute(id, name, LLMute::AGENT);
+	LLMute mute(id, av_name.getUserName(), LLMute::AGENT);
 
 	if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
 	{
@@ -1009,13 +1008,13 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
 // static
 void LLAvatarActions::toggleMuteVoice(const LLUUID& id)
 {
-	std::string name;
-	gCacheName->getFullName(id, name); // needed for mute
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(id, &av_name);
 
 	LLMuteList* mute_list = LLMuteList::getInstance();
 	bool is_muted = mute_list->isMuted(id, LLMute::flagVoiceChat);
 
-	LLMute mute(id, name, LLMute::AGENT);
+	LLMute mute(id, av_name.getUserName(), LLMute::AGENT);
 	if (!is_muted)
 	{
 		mute_list->add(mute, LLMute::flagVoiceChat);
@@ -1329,9 +1328,9 @@ bool LLAvatarActions::isFriend(const LLUUID& id)
 // static
 bool LLAvatarActions::isBlocked(const LLUUID& id)
 {
-	std::string name;
-	gCacheName->getFullName(id, name); // needed for mute
-	return LLMuteList::getInstance()->isMuted(id, name);
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(id, &av_name);
+	return LLMuteList::getInstance()->isMuted(id, av_name.getUserName());
 }
 
 // static
@@ -1343,8 +1342,10 @@ bool LLAvatarActions::isVoiceMuted(const LLUUID& id)
 // static
 bool LLAvatarActions::canBlock(const LLUUID& id)
 {
-	std::string full_name;
-	gCacheName->getFullName(id, full_name); // needed for mute
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(id, &av_name);
+
+	std::string full_name = av_name.getUserName();
 	bool is_linden = (full_name.find("Linden") != std::string::npos);
 	bool is_self = id == gAgentID;
 	return !is_self && !is_linden;
diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
index 272a68bdf7dacfb9d32df8ffeef35b30d29996f8..1eab2d8e232c67b8de0b6aa2206960ffb9729b7c 100644
--- a/indra/newview/llblocklist.cpp
+++ b/indra/newview/llblocklist.cpp
@@ -55,7 +55,9 @@ LLBlockList::LLBlockList(const Params& p)
 
 	registrar.add		("Block.Action",	boost::bind(&LLBlockList::onCustomAction,	this, _2));
 	enable_registrar.add("Block.Enable",	boost::bind(&LLBlockList::isActionEnabled,	this, _2));
-
+	enable_registrar.add("Block.Check",     boost::bind(&LLBlockList::isMenuItemChecked, this, _2));
+	enable_registrar.add("Block.Visible",   boost::bind(&LLBlockList::isMenuItemVisible, this, _2));
+	
 	LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
 									"menu_people_blocked_gear.xml",
 									gMenuHolder,
@@ -128,7 +130,14 @@ BOOL LLBlockList::handleRightMouseDown(S32 x, S32 y, MASK mask)
 
 void LLBlockList::removeListItem(const LLMute* mute)
 {
-	removeItemByUUID(mute->mID);
+	if (mute->mID.notNull())
+	{
+		removeItemByUUID(mute->mID);
+	}
+	else
+	{
+		removeItemByValue(mute->mName);
+	}
 }
 
 void LLBlockList::hideListItem(LLBlockedListItem* item, bool show)
@@ -176,7 +185,14 @@ void LLBlockList::addNewItem(const LLMute* mute)
 	{
 		item->highlightName(mNameFilter);
 	}
-	addItem(item, item->getUUID(), ADD_BOTTOM);
+	if (item->getUUID().notNull())
+	{
+		addItem(item, item->getUUID(), ADD_BOTTOM);
+	}
+	else
+	{
+		addItem(item, item->getName(), ADD_BOTTOM);
+	}
 }
 
 void LLBlockList::refresh()
@@ -184,7 +200,8 @@ void LLBlockList::refresh()
 	bool have_filter = !mNameFilter.empty();
 
 	// save selection to restore it after list rebuilt
-	LLUUID selected = getSelectedUUID(), next_selected;
+	LLSD selected = getSelectedValue();
+	LLSD next_selected;
 
 	if(mShouldAddAll)	// creating list of blockers
 	{
@@ -202,14 +219,15 @@ void LLBlockList::refresh()
 		}
 		else if(mActionType == REMOVE)
 		{
-			if(selected == mute.mID)
+			if ((mute.mID.notNull() && selected.isUUID() && selected.asUUID() == mute.mID)
+				|| (mute.mID.isNull() && selected.isString() && selected.asString() == mute.mName))
 			{
 				// we are going to remove currently selected item, so select next item and save the selection to restore it
-	if (!selectNextItemPair(false, true))
-	{
-		selectNextItemPair(true, true);
-	}
-				next_selected = getSelectedUUID();
+				if (!selectNextItemPair(false, true))
+				{
+					selectNextItemPair(true, true);
+				}
+				next_selected = getSelectedValue();
 			}
 			removeListItem(&mute);
 		}
@@ -235,15 +253,18 @@ void LLBlockList::refresh()
 	}
 	mPrevNameFilter = mNameFilter;
 
-	if (getItemPair(selected))
-	{
-		// restore previously selected item
-		selectItemPair(getItemPair(selected), true);
-	}
-	else if (getItemPair(next_selected))
+	if (selected.isDefined())
 	{
-		// previously selected item was removed, so select next item
-		selectItemPair(getItemPair(next_selected), true);
+		if (getItemPair(selected))
+		{
+			// restore previously selected item
+			selectItemPair(getItemPair(selected), true);
+		}
+		else if (next_selected.isDefined() && getItemPair(next_selected))
+		{
+			// previously selected item was removed, so select next item
+			selectItemPair(getItemPair(next_selected), true);
+		}
 	}
 	mMuteListSize = LLMuteList::getInstance()->getMutes().size();
 
@@ -272,7 +293,11 @@ bool LLBlockList::isActionEnabled(const LLSD& userdata)
 
 	const std::string command_name = userdata.asString();
 
-	if ("profile_item" == command_name)
+	if ("profile_item" == command_name 
+		|| "block_voice" == command_name
+		|| "block_text" == command_name
+		|| "block_particles" == command_name
+		|| "block_obj_sounds" == command_name)
 	{
 		LLBlockedListItem* item = getBlockedItem();
 		action_enabled = item && (LLMute::AGENT == item->getType());
@@ -314,6 +339,83 @@ void LLBlockList::onCustomAction(const LLSD& userdata)
 			break;
 		}
 	}
+	else if ("block_voice" == command_name)
+	{
+		toggleMute(LLMute::flagVoiceChat);
+	}
+	else if ("block_text" == command_name)
+	{
+		toggleMute(LLMute::flagTextChat);
+	}
+	else if ("block_particles" == command_name)
+	{
+		toggleMute(LLMute::flagParticles);
+	}
+	else if ("block_obj_sounds" == command_name)
+	{
+		toggleMute(LLMute::flagObjectSounds);
+	}
+}
+
+bool LLBlockList::isMenuItemChecked(const LLSD& userdata)
+{
+	LLBlockedListItem* item = getBlockedItem();
+	if (!item)
+	{
+		return false;
+	}
+
+	const std::string command_name = userdata.asString();
+
+	if ("block_voice" == command_name)
+	{
+		return LLMuteList::getInstance()->isMuted(item->getUUID(), LLMute::flagVoiceChat);
+	}
+	else if ("block_text" == command_name)
+	{
+		return LLMuteList::getInstance()->isMuted(item->getUUID(), LLMute::flagTextChat);
+	}
+	else if ("block_particles" == command_name)
+	{
+		return LLMuteList::getInstance()->isMuted(item->getUUID(), LLMute::flagParticles);
+	}
+	else if ("block_obj_sounds" == command_name)
+	{
+		return LLMuteList::getInstance()->isMuted(item->getUUID(), LLMute::flagObjectSounds);
+	}
+
+	return false;
+}
+
+bool LLBlockList::isMenuItemVisible(const LLSD& userdata)
+{
+	LLBlockedListItem* item = getBlockedItem();
+	const std::string command_name = userdata.asString();
+
+	if ("block_voice" == command_name
+		|| "block_text" == command_name
+		|| "block_particles" == command_name
+		|| "block_obj_sounds" == command_name)
+	{
+		return item && (LLMute::AGENT == item->getType());
+	}
+
+	return false;
+}
+
+void LLBlockList::toggleMute(U32 flags)
+{
+	LLBlockedListItem* item = getBlockedItem();
+	LLMute mute(item->getUUID(), item->getName(), item->getType());
+
+	if (!LLMuteList::getInstance()->isMuted(item->getUUID(), flags))
+	{
+		LLMuteList::getInstance()->add(mute, flags);
+	}
+	else
+	{
+		LLMuteList::getInstance()->remove(mute, flags);
+	}
 }
 
 bool LLBlockListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
diff --git a/indra/newview/llblocklist.h b/indra/newview/llblocklist.h
index 96af8d898e6d89e10f375f2689a6a95192dda701..ac0729c61051e91536639ea11f70530be45d19ea 100644
--- a/indra/newview/llblocklist.h
+++ b/indra/newview/llblocklist.h
@@ -79,6 +79,9 @@ class LLBlockList: public LLFlatListViewEx, public LLMuteListObserver
 
 	bool isActionEnabled(const LLSD& userdata);
 	void onCustomAction (const LLSD& userdata);
+	bool isMenuItemChecked(const LLSD& userdata);
+	bool isMenuItemVisible(const LLSD& userdata);
+	void toggleMute(U32 flags);
 	void createList();
 
 	BlockListActionType getCurrentMuteListActionType();
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index f79d1aa609a2af5c31a01b044f170b481518372b..6d20b23e9f9b4a733ee936d60561c54f2fa5ac42 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -243,7 +243,6 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
 	using namespace std;
 
 	U32 new_buddy_count = 0;
-	std::string full_name;
 	LLUUID agent_id;
 	for(buddy_map_t::const_iterator itr = buds.begin(); itr != buds.end(); ++itr)
 	{
@@ -253,8 +252,11 @@ S32 LLAvatarTracker::addBuddyList(const LLAvatarTracker::buddy_map_t& buds)
 		{
 			++new_buddy_count;
 			mBuddyInfo[agent_id] = (*itr).second;
-			// IDEVO: is this necessary?  name is unused?
-			gCacheName->getFullName(agent_id, full_name);
+
+			// pre-request name for notifications?
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(agent_id, &av_name);
+
 			addChangedMask(LLFriendObserver::ADD, agent_id);
 			LL_DEBUGS() << "Added buddy " << agent_id
 					<< ", " << (mBuddyInfo[agent_id]->isOnline() ? "Online" : "Offline")
@@ -889,7 +891,9 @@ bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship
 
 bool LLCollectOnlineBuddies::operator()(const LLUUID& buddy_id, LLRelationship* buddy)
 {
-	gCacheName->getFullName(buddy_id, mFullName);
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(buddy_id, &av_name);
+	mFullName = av_name.getUserName();
 	buddy_map_t::value_type value(buddy_id, mFullName);
 	if(buddy->isOnline())
 	{
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 5d2997688fc2a0f172a4ed43d78263c260f45e88..9798ef352940c3d4009f93bf9e6afdd81fe7f276 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -271,9 +271,9 @@ class LLChatHistoryHeader: public LLPanel
 	void mute(const LLUUID& participant_id, U32 flags)
 	{
 		BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags);
-		std::string name;
-		gCacheName->getFullName(participant_id, name);
-		LLMute mute(participant_id, name, LLMute::AGENT);
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(participant_id, &av_name);
+		LLMute mute(participant_id, av_name.getUserName(), LLMute::AGENT);
 
 		if (!is_muted)
 		{
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
index 328a638f2fba5aac35bde2b3dc0f243b8ad58458..ebbbf23deee3961e1a9e15b664630e918ca38084 100644
--- a/indra/newview/llconversationmodel.cpp
+++ b/indra/newview/llconversationmodel.cpp
@@ -602,12 +602,12 @@ bool LLConversationItemParticipant::isVoiceMuted()
 
 void LLConversationItemParticipant::muteVoice(bool mute_voice)
 {
-	std::string name;
-	gCacheName->getFullName(mUUID, name);
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(mUUID, &av_name);
 	LLMuteList * mute_listp = LLMuteList::getInstance();
-	bool voice_already_muted = mute_listp->isMuted(mUUID, name);
+	bool voice_already_muted = mute_listp->isMuted(mUUID, av_name.getUserName());
 
-	LLMute mute(mUUID, name, LLMute::AGENT);
+	LLMute mute(mUUID, av_name.getUserName(), LLMute::AGENT);
 	if (voice_already_muted && !mute_voice)
 	{
 		mute_listp->remove(mute);
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 499cf76bffe384fa463faecfd4344f3122609fa4..b221221f16e7bd0d45c051405f36c631bb0e061c 100644
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -2063,7 +2063,9 @@ void LLDrawPoolAvatar::removeRiggedFace(LLFace* facep)
 			}
 			else
 			{
-				LL_ERRS() << "Face reference data corrupt for rigged type " << i << LL_ENDL;
+				LL_ERRS() << "Face reference data corrupt for rigged type " << i
+					<< ((mRiggedFace[i].size() <= index) ? "; wrong index (out of bounds)" : (mRiggedFace[i][index] != facep) ? "; wrong face pointer" : "")
+					<< LL_ENDL;
 			}
 		}
 	}
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index d4ba230feb24e60ead6609a40c539e332fef5657..ad048f6668f3df8873dc9c900e1e240138dcdb05 100644
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -789,7 +789,7 @@ void LLFeatureManager::applyBaseMasks()
 	maskFeatures(gpustr);
 
 	// now mask cpu type ones
-	if (gSysMemory.getPhysicalMemoryClamped() <= U32Megabytes(256))
+	if (gSysMemory.getPhysicalMemoryKB() <= U32Megabytes(256))
 	{
 		maskFeatures("RAM256MB");
 	}
diff --git a/indra/newview/llfilteredwearablelist.cpp b/indra/newview/llfilteredwearablelist.cpp
index f2af9b530061f1febd67dbbc28898b6f399a29f8..e67a6a2b77a1f8c1cfaa570744ea7f2345bcebf2 100644
--- a/indra/newview/llfilteredwearablelist.cpp
+++ b/indra/newview/llfilteredwearablelist.cpp
@@ -37,6 +37,7 @@
 LLFilteredWearableListManager::LLFilteredWearableListManager(LLInventoryItemsList* list, LLInventoryCollectFunctor* collector)
 : mWearableList(list)
 , mCollector(collector)
+, mListStale(true)
 {
 	llassert(mWearableList);
 	gInventory.addObserver(this);
@@ -64,7 +65,16 @@ void LLFilteredWearableListManager::changed(U32 mask)
 		return;
 	}
 
-	populateList();
+	if (mWearableList->isInVisibleChain() || mWearableList->getForceRefresh())
+	{
+		// Todo: current populateList() is time consuming and changed() is time-sensitive,
+		// either move from here or optimize
+		populateList();
+	}
+	else
+	{
+		mListStale = true;
+	}
 }
 
 void LLFilteredWearableListManager::setFilterCollector(LLInventoryCollectFunctor* collector)
@@ -73,13 +83,31 @@ void LLFilteredWearableListManager::setFilterCollector(LLInventoryCollectFunctor
 	populateList();
 }
 
+void LLFilteredWearableListManager::populateIfNeeded()
+{
+	if (mListStale)
+	{
+		populateList();
+	}
+}
+
+LLTrace::BlockTimerStatHandle FTM_MANAGER_LIST_POPULATION("Manager List Population");
+
 void LLFilteredWearableListManager::populateList()
 {
+	LL_RECORD_BLOCK_TIME(FTM_MANAGER_LIST_POPULATION);
+
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t item_array;
 
 	if(mCollector)
 	{
+		// Too slow with large inventory!
+		// Consider refactoring into "request once, append ids on changed()", since
+		// Inventory observer provides ids of changed items this should be possible,
+		// but will likely require modifying LLInventoryItemsList to avoid code-repeats.
+		// Or make something like "gather everything and filter manually on idle"
+		mListStale = false;
 		gInventory.collectDescendentsIf(
 				gInventory.getRootFolderID(),
 				cat_array,
diff --git a/indra/newview/llfilteredwearablelist.h b/indra/newview/llfilteredwearablelist.h
index f44ab1466f486422709d4239a5e1cdcae74eb8a9..197302f41dc4e925bb0bf6e21615b8afc4b36ed3 100644
--- a/indra/newview/llfilteredwearablelist.h
+++ b/indra/newview/llfilteredwearablelist.h
@@ -52,9 +52,9 @@ class LLFilteredWearableListManager : public LLInventoryObserver
 	void setFilterCollector(LLInventoryCollectFunctor* collector);
 
 	/**
-	 * Populates wearable list with filtered data.
-	 */
-	void populateList();
+	* Populates wearable list with filtered data in case there were any updates.
+	*/
+	void populateIfNeeded();
 
 	/**
 	 * Drop operation
@@ -62,8 +62,14 @@ class LLFilteredWearableListManager : public LLInventoryObserver
 	void holdProgress();
 
 private:
+	/**
+	* Populates wearable list with filtered data.
+	*/
+	void populateList();
+
 	LLInventoryItemsList* mWearableList;
 	LLInventoryCollectFunctor* mCollector;
+	bool mListStale;
 };
 
 #endif //LL_LLFILTEREDWEARABLELIST_H
diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e7ac3f273760048c300ccf723c9fcde8a1d44887
--- /dev/null
+++ b/indra/newview/llfloateravatarrendersettings.cpp
@@ -0,0 +1,286 @@
+/**
+ * @file llfloateravatarrendersettings.cpp
+ * @brief Shows the list of avatars with non-default rendering settings
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2017, 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 "llfloateravatarrendersettings.h"
+
+#include "llavatarnamecache.h"
+#include "llfloateravatarpicker.h"
+#include "llfiltereditor.h"
+#include "llfloaterreg.h"
+#include "llnamelistctrl.h"
+#include "llmenugl.h"
+#include "llviewerobjectlist.h"
+#include "llvoavatar.h"
+
+class LLSettingsContextMenu : public LLListContextMenu
+
+{
+public:
+    LLSettingsContextMenu(LLFloaterAvatarRenderSettings* floater_settings)
+        :   mFloaterSettings(floater_settings)
+    {}
+protected:
+    LLContextMenu* createMenu()
+    {
+        LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+        LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+        registrar.add("Settings.SetRendering", boost::bind(&LLFloaterAvatarRenderSettings::onCustomAction, mFloaterSettings, _2, mUUIDs.front()));
+        enable_registrar.add("Settings.IsSelected", boost::bind(&LLFloaterAvatarRenderSettings::isActionChecked, mFloaterSettings, _2, mUUIDs.front()));
+        LLContextMenu* menu = createFromFile("menu_avatar_rendering_settings.xml");
+
+        return menu;
+    }
+
+    LLFloaterAvatarRenderSettings* mFloaterSettings;
+};
+
+class LLAvatarRenderMuteListObserver : public LLMuteListObserver
+{
+    /* virtual */ void onChange()  { LLFloaterAvatarRenderSettings::setNeedsUpdate();}
+};
+
+static LLAvatarRenderMuteListObserver sAvatarRenderMuteListObserver;
+
+LLFloaterAvatarRenderSettings::LLFloaterAvatarRenderSettings(const LLSD& key)
+:   LLFloater(key),
+	mAvatarSettingsList(NULL),
+	mNeedsUpdate(false)
+{
+    mContextMenu = new LLSettingsContextMenu(this);
+    LLRenderMuteList::getInstance()->addObserver(&sAvatarRenderMuteListObserver);
+    mCommitCallbackRegistrar.add("Settings.AddNewEntry", boost::bind(&LLFloaterAvatarRenderSettings::onClickAdd, this, _2));
+}
+
+LLFloaterAvatarRenderSettings::~LLFloaterAvatarRenderSettings()
+{
+    delete mContextMenu;
+    LLRenderMuteList::getInstance()->removeObserver(&sAvatarRenderMuteListObserver);
+}
+
+BOOL LLFloaterAvatarRenderSettings::postBuild()
+{
+    LLFloater::postBuild();
+    mAvatarSettingsList = getChild<LLNameListCtrl>("render_settings_list");
+    mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3));
+    this->setVisibleCallback(boost::bind(&LLFloaterAvatarRenderSettings::removePicker, this));
+    getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2));
+
+	return TRUE;
+}
+
+void LLFloaterAvatarRenderSettings::removePicker()
+{
+    if(mPicker.get())
+    {
+        mPicker.get()->closeFloater();
+    }
+}
+
+void LLFloaterAvatarRenderSettings::draw()
+{
+    if(mNeedsUpdate)
+    {
+        updateList();
+        mNeedsUpdate = false;
+    }
+
+    LLFloater::draw();
+}
+
+void LLFloaterAvatarRenderSettings::onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
+{
+    LLNameListCtrl* list = dynamic_cast<LLNameListCtrl*>(ctrl);
+    if (!list) return;
+    list->selectItemAt(x, y, MASK_NONE);
+    uuid_vec_t selected_uuids;
+
+    if(list->getCurrentID().notNull())
+    {
+        selected_uuids.push_back(list->getCurrentID());
+        mContextMenu->show(ctrl, selected_uuids, x, y);
+    }
+}
+
+void LLFloaterAvatarRenderSettings::onOpen(const LLSD& key)
+{
+    updateList();
+}
+
+void LLFloaterAvatarRenderSettings::updateList()
+{
+    mAvatarSettingsList->deleteAllItems();
+    LLAvatarName av_name;
+    LLNameListCtrl::NameItem item_params;
+    for (std::map<LLUUID, S32>::iterator iter = LLRenderMuteList::getInstance()->sVisuallyMuteSettingsMap.begin(); iter != LLRenderMuteList::getInstance()->sVisuallyMuteSettingsMap.end(); iter++)
+    {
+        item_params.value = iter->first;
+        LLAvatarNameCache::get(iter->first, &av_name);
+        if(!isHiddenRow(av_name.getCompleteName()))
+        {
+            item_params.columns.add().value(av_name.getCompleteName()).column("name");
+            std::string setting = getString(iter->second == 1 ? "av_never_render" : "av_always_render");
+            item_params.columns.add().value(setting).column("setting");
+            mAvatarSettingsList->addNameItemRow(item_params);
+        }
+    }
+}
+
+void LLFloaterAvatarRenderSettings::onFilterEdit(const std::string& search_string)
+{
+    std::string filter_upper = search_string;
+    LLStringUtil::toUpper(filter_upper);
+    if (mNameFilter != filter_upper)
+    {
+        mNameFilter = filter_upper;
+        mNeedsUpdate = true;
+    }
+}
+
+bool LLFloaterAvatarRenderSettings::isHiddenRow(const std::string& av_name)
+{
+    if (mNameFilter.empty()) return false;
+    std::string upper_name = av_name;
+    LLStringUtil::toUpper(upper_name);
+    return std::string::npos == upper_name.find(mNameFilter);
+}
+
+static LLVOAvatar* find_avatar(const LLUUID& id)
+{
+    LLViewerObject *obj = gObjectList.findObject(id);
+    while (obj && obj->isAttachment())
+    {
+        obj = (LLViewerObject *)obj->getParent();
+    }
+
+    if (obj && obj->isAvatar())
+    {
+        return (LLVOAvatar*)obj;
+    }
+    else
+    {
+        return NULL;
+    }
+}
+
+
+void LLFloaterAvatarRenderSettings::onCustomAction (const LLSD& userdata, const LLUUID& av_id)
+{
+    const std::string command_name = userdata.asString();
+
+    S32 new_setting = 0;
+    if ("default" == command_name)
+    {
+        new_setting = S32(LLVOAvatar::AV_RENDER_NORMALLY);
+    }
+    else if ("never" == command_name)
+    {
+        new_setting = S32(LLVOAvatar::AV_DO_NOT_RENDER);
+    }
+    else if ("always" == command_name)
+    {
+        new_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER);
+    }
+
+    LLVOAvatar *avatarp = find_avatar(av_id);
+    if (avatarp)
+    {
+        avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(new_setting));
+    }
+    else
+    {
+        LLRenderMuteList::getInstance()->saveVisualMuteSetting(av_id, new_setting);
+    }
+}
+
+
+bool LLFloaterAvatarRenderSettings::isActionChecked(const LLSD& userdata, const LLUUID& av_id)
+{
+    const std::string command_name = userdata.asString();
+
+    S32 visual_setting = LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(av_id);
+    if ("default" == command_name)
+    {
+        return (visual_setting == S32(LLVOAvatar::AV_RENDER_NORMALLY));
+    }
+    else if ("never" == command_name)
+    {
+        return (visual_setting == S32(LLVOAvatar::AV_DO_NOT_RENDER));
+    }
+    else if ("always" == command_name)
+    {
+        return (visual_setting == S32(LLVOAvatar::AV_ALWAYS_RENDER));
+    }
+    return false;
+}
+
+void LLFloaterAvatarRenderSettings::setNeedsUpdate()
+{
+    LLFloaterAvatarRenderSettings* instance = LLFloaterReg::getTypedInstance<LLFloaterAvatarRenderSettings>("avatar_render_settings");
+    if(!instance) return;
+    instance->mNeedsUpdate = true;
+}
+
+void LLFloaterAvatarRenderSettings::onClickAdd(const LLSD& userdata)
+{
+    const std::string command_name = userdata.asString();
+    S32 visual_setting = 0;
+    if ("never" == command_name)
+    {
+        visual_setting = S32(LLVOAvatar::AV_DO_NOT_RENDER);
+    }
+    else if ("always" == command_name)
+    {
+        visual_setting = S32(LLVOAvatar::AV_ALWAYS_RENDER);
+    }
+
+    LLView * button = findChild<LLButton>("plus_btn", TRUE);
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+    LLFloaterAvatarPicker * picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterAvatarRenderSettings::callbackAvatarPicked, this, _1, visual_setting),
+                                                                    FALSE, TRUE, FALSE, root_floater->getName(), button);
+
+    if (root_floater)
+    {
+        root_floater->addDependentFloater(picker);
+    }
+
+    mPicker = picker->getHandle();
+}
+
+void LLFloaterAvatarRenderSettings::callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting)
+{
+    if (ids.empty()) return;
+
+    LLVOAvatar *avatarp = find_avatar(ids[0]);
+    if (avatarp)
+    {
+        avatarp->setVisualMuteSettings(LLVOAvatar::VisualMuteSettings(visual_setting));
+    }
+    else
+    {
+        LLRenderMuteList::getInstance()->saveVisualMuteSetting(ids[0], visual_setting);
+    }
+}
diff --git a/indra/newview/llfloateravatarrendersettings.h b/indra/newview/llfloateravatarrendersettings.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe727bcf3279b0bbbcf8b8768a0578b03f0efa60
--- /dev/null
+++ b/indra/newview/llfloateravatarrendersettings.h
@@ -0,0 +1,71 @@
+/**
+ * @file llfloateravatarrendersettings.h
+ * @brief Shows the list of avatars with non-default rendering settings
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2017, 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_LLFLOATERAVATARRENDERSETTINGS_H
+#define LL_LLFLOATERAVATARRENDERSETTINGS_H
+
+#include "llfloater.h"
+#include "lllistcontextmenu.h"
+#include "llmutelist.h"
+
+class LLNameListCtrl;
+
+class LLFloaterAvatarRenderSettings : public LLFloater
+{
+public:
+
+    LLFloaterAvatarRenderSettings(const LLSD& key);
+    virtual ~LLFloaterAvatarRenderSettings();
+
+    /*virtual*/ BOOL postBuild();
+    /*virtual*/ void onOpen(const LLSD& key);
+    /*virtual*/ void draw();
+
+    void onAvatarListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
+
+    void updateList();
+    void onFilterEdit(const std::string& search_string);
+    void onCustomAction (const LLSD& userdata, const LLUUID& av_id);
+    bool isActionChecked(const LLSD& userdata, const LLUUID& av_id);
+    void onClickAdd(const LLSD& userdata);
+
+    static void setNeedsUpdate();
+
+private:
+    bool isHiddenRow(const std::string& av_name);
+    void callbackAvatarPicked(const uuid_vec_t& ids, S32 visual_setting);
+    void removePicker();
+
+    bool mNeedsUpdate;
+    LLListContextMenu* mContextMenu;
+    LLNameListCtrl* mAvatarSettingsList;
+    LLHandle<LLFloater> mPicker;
+
+    std::string mNameFilter;
+};
+
+
+#endif //LL_LLFLOATERAVATARRENDERSETTINGS_H
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
index a358b7c10b62a17fcfd25fe5e39c90233e1fdaef..b48ecc8f31a11aa81b925ee6abb783cbe1835567 100644
--- a/indra/newview/llfloaterconversationpreview.cpp
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -25,6 +25,7 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include "llavatarnamecache.h"
 #include "llconversationlog.h"
 #include "llfloaterconversationpreview.h"
 #include "llimview.h"
@@ -220,7 +221,7 @@ void LLFloaterConversationPreview::showHistory()
 		else
  		{
 			std::string legacy_name = gCacheName->buildLegacyName(from);
- 			gCacheName->getUUID(legacy_name, from_id);
+			from_id = LLAvatarNameCache::findIdByName(legacy_name);
  		}
 
 		LLChat chat;
diff --git a/indra/newview/llfloatergridstatus.cpp b/indra/newview/llfloatergridstatus.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c47ff1c1d926197b4b16b4f9f9b08715da5630e8
--- /dev/null
+++ b/indra/newview/llfloatergridstatus.cpp
@@ -0,0 +1,184 @@
+/** 
+ * @file llfloatergridstatus.cpp
+ * @brief Grid status floater - uses an embedded web browser to show Grid status info
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2017, 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 "llfloatergridstatus.h"
+
+#include "llcallbacklist.h"
+#include "llcorehttputil.h"
+#include "llfloaterreg.h"
+#include "llhttpconstants.h"
+#include "llmediactrl.h"
+#include "llsdserialize.h"
+#include "lltoolbarview.h"
+#include "llviewercontrol.h"
+#include "llxmltree.h"
+
+std::map<std::string, std::string> LLFloaterGridStatus::sItemsMap;
+const std::string DEFAULT_GRID_STATUS_URL = "http://secondlife-status.statuspage.io/";
+
+LLFloaterGridStatus::LLFloaterGridStatus(const Params& key) :
+    LLFloaterWebContent(key),
+    mIsFirstUpdate(TRUE)
+{
+}
+
+BOOL LLFloaterGridStatus::postBuild()
+{
+    LLFloaterWebContent::postBuild();
+    mWebBrowser->addObserver(this);
+
+    return TRUE;
+}
+
+void LLFloaterGridStatus::onOpen(const LLSD& key)
+{
+    Params p(key);
+    p.trusted_content = true;
+    p.allow_address_entry = false;
+
+    LLFloaterWebContent::onOpen(p);
+    applyPreferredRect();
+    if (mWebBrowser)
+    {
+        mWebBrowser->navigateTo(DEFAULT_GRID_STATUS_URL, HTTP_CONTENT_TEXT_HTML);
+    }
+}
+
+void LLFloaterGridStatus::startGridStatusTimer()
+{
+    checkGridStatusRSS();
+    doPeriodically(boost::bind(&LLFloaterGridStatus::checkGridStatusRSS), gSavedSettings.getF32("GridStatusUpdateDelay"));
+}
+
+bool LLFloaterGridStatus::checkGridStatusRSS()
+{
+    if(gToolBarView->hasCommand(LLCommandId("gridstatus")))
+    {
+        LLCoros::instance().launch("LLFloaterGridStatus::getGridStatusRSSCoro",
+                boost::bind(&LLFloaterGridStatus::getGridStatusRSSCoro));
+    }
+    return false;
+}
+
+void LLFloaterGridStatus::getGridStatusRSSCoro()
+{
+
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+    httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getGridStatusRSSCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+    LLCore::HttpHeaders::ptr_t httpHeaders(new LLCore::HttpHeaders);
+
+    httpHeaders->append(HTTP_OUT_HEADER_CONTENT_TYPE, HTTP_CONTENT_TEXT_XML);
+    std::string url = gSavedSettings.getString("GridStatusRSS");
+
+    LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts, httpHeaders);
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+    if (!status)
+    {
+        return;
+    }
+
+    const LLSD::Binary &rawBody = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
+    std::string body(rawBody.begin(), rawBody.end());
+
+    std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,"grid_status_rss.xml");
+    if(!gSavedSettings.getBOOL("TestGridStatusRSSFromFile"))
+    {
+        llofstream custom_file_out(fullpath.c_str(), std::ios::trunc);
+        if (custom_file_out.is_open())
+        {
+            custom_file_out << body;
+            custom_file_out.close();
+        }
+    }
+    LLXmlTree grid_status_xml;
+    if (!grid_status_xml.parseFile(fullpath))
+    {
+        return ;
+    }
+    bool new_entries = false;
+    LLXmlTreeNode* rootp = grid_status_xml.getRoot();
+    for (LLXmlTreeNode* item = rootp->getChildByName( "entry" ); item; item = rootp->getNextNamedChild())
+    {
+        LLXmlTreeNode* id_node = item->getChildByName("id");
+        LLXmlTreeNode* updated_node = item->getChildByName("updated");
+        if (!id_node || !updated_node)
+        {
+            continue;
+        }
+        std::string guid = id_node->getContents();
+        std::string date = updated_node->getContents();
+        if(sItemsMap.find( guid ) == sItemsMap.end())
+        {
+            new_entries = true;
+        }
+        else
+        {
+            if(sItemsMap[guid] != date)
+            {
+                new_entries = true;
+            }
+        }
+        sItemsMap[guid] = date;
+    }
+    if(new_entries && !getInstance()->isFirstUpdate())
+    {
+        gToolBarView->flashCommand(LLCommandId("gridstatus"), true);
+    }
+    getInstance()->setFirstUpdate(FALSE);
+}
+
+// virtual
+void LLFloaterGridStatus::handleReshape(const LLRect& new_rect, bool by_user)
+{
+    if (by_user && !isMinimized())
+    {
+        gSavedSettings.setRect("GridStatusFloaterRect", new_rect);
+    }
+
+    LLFloaterWebContent::handleReshape(new_rect, by_user);
+}
+
+void LLFloaterGridStatus::applyPreferredRect()
+{
+    const LLRect preferred_rect = gSavedSettings.getRect("GridStatusFloaterRect");
+
+    LLRect new_rect = getRect();
+    new_rect.setLeftTopAndSize(
+        new_rect.mLeft, new_rect.mTop,
+        preferred_rect.getWidth(), preferred_rect.getHeight());
+    setShape(new_rect);
+}
+
+LLFloaterGridStatus* LLFloaterGridStatus::getInstance()
+{
+    return LLFloaterReg::getTypedInstance<LLFloaterGridStatus>("grid_status");
+}
diff --git a/indra/newview/llfloatergridstatus.h b/indra/newview/llfloatergridstatus.h
new file mode 100644
index 0000000000000000000000000000000000000000..0c3deb7d4c8d7adba06c0e5790d90c2f44b9cba9
--- /dev/null
+++ b/indra/newview/llfloatergridstatus.h
@@ -0,0 +1,71 @@
+/** 
+ * @file llfloatergridstatus.h
+ * @brief Grid status floater - uses an embedded web browser to show Grid status info
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2017, 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_LLFLOATERGRIDSTATUS_H
+#define LL_LLFLOATERGRIDSTATUS_H
+
+#include "llfloaterwebcontent.h"
+#include "llviewermediaobserver.h"
+
+#include <string>
+
+class LLMediaCtrl;
+
+
+class LLFloaterGridStatus :
+    public LLFloaterWebContent
+{
+public:
+    typedef LLSDParamAdapter<_Params> Params;
+
+    LLFloaterGridStatus(const Params& key);
+
+    /*virtual*/ void onOpen(const LLSD& key);
+    /*virtual*/ void handleReshape(const LLRect& new_rect, bool by_user = false);
+
+    static bool checkGridStatusRSS();
+    static void getGridStatusRSSCoro();
+
+    void startGridStatusTimer();
+    BOOL isFirstUpdate() { return mIsFirstUpdate; }
+    void setFirstUpdate(BOOL first_update) { mIsFirstUpdate = first_update; }
+
+    static LLFloaterGridStatus* getInstance();
+
+
+private:
+    /*virtual*/ BOOL postBuild();
+
+    void applyPreferredRect();
+
+    static std::map<std::string, std::string> sItemsMap;
+
+    LLFrameTimer    mGridStatusTimer;
+    BOOL            mIsFirstUpdate;
+};
+
+#endif  // LL_LLFLOATERGRIDSTATUS_H
+
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 7007c58b3c82408bd68b3b82aab02b4b6149fc9c..3522932d03df0c3a8faad669b46a5f9c9e0a930f 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -2099,9 +2099,10 @@ void LLFloaterIMContainer::toggleAllowTextChat(const LLUUID& participant_uuid)
 void LLFloaterIMContainer::toggleMute(const LLUUID& participant_id, U32 flags)
 {
         BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags);
-        std::string name;
-        gCacheName->getFullName(participant_id, name);
-        LLMute mute(participant_id, name, LLMute::AGENT);
+
+        LLAvatarName av_name;
+        LLAvatarNameCache::get(participant_id, &av_name);
+        LLMute mute(participant_id, av_name.getUserName(), LLMute::AGENT);
 
         if (!is_muted)
         {
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 981d837b8a7bdc9061c1012b545926a0402ac263..d18f03d8e9316d624d64e8fe117332a6f9d8d318 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -218,7 +218,7 @@ void LLFloaterIMNearbyChat::loadHistory()
 		else
  		{
 			std::string legacy_name = gCacheName->buildLegacyName(from);
- 			gCacheName->getUUID(legacy_name, from_id);
+			from_id = LLAvatarNameCache::findIdByName(legacy_name);
  		}
 
 		LLChat chat;
diff --git a/indra/newview/llfloatermarketplacelistings.cpp b/indra/newview/llfloatermarketplacelistings.cpp
index 18f0bc4498e10c9a6355e70d45dc04da2a141cdb..889d01738931f4ed4e7eae31c913840b8ecea1bf 100644
--- a/indra/newview/llfloatermarketplacelistings.cpp
+++ b/indra/newview/llfloatermarketplacelistings.cpp
@@ -603,6 +603,7 @@ void LLFloaterMarketplaceListings::updateView()
             text = LLTrans::getString("InventoryMarketplaceError", subs);
             title = LLTrans::getString("InventoryOutboxErrorTitle");
             tooltip = LLTrans::getString("InventoryOutboxErrorTooltip");
+            LL_WARNS() << "Marketplace status code: " << mkt_status << LL_ENDL;
         }
     
         mInventoryText->setValue(text);
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index df4bc043e5c671042df2f24ad9d19a7186bd207d..1f460c05ec2b47645c45b5aab167f649c7cfc174 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -360,6 +360,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.ClickEnablePopup",		boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
 	mCommitCallbackRegistrar.add("Pref.ClickDisablePopup",		boost::bind(&LLFloaterPreference::onClickDisablePopup, this));	
 	mCommitCallbackRegistrar.add("Pref.LogPath",				boost::bind(&LLFloaterPreference::onClickLogPath, this));
+	mCommitCallbackRegistrar.add("Pref.RenderExceptions",       boost::bind(&LLFloaterPreference::onClickRenderExceptions, this));
 	mCommitCallbackRegistrar.add("Pref.HardwareDefaults",		boost::bind(&LLFloaterPreference::setHardwareDefaults, this));
 	mCommitCallbackRegistrar.add("Pref.AvatarImpostorsEnable",	boost::bind(&LLFloaterPreference::onAvatarImpostorsEnable, this));
 	mCommitCallbackRegistrar.add("Pref.UpdateIndirectMaxComplexity",	boost::bind(&LLFloaterPreference::updateMaxComplexity, this));
@@ -385,7 +386,7 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged,  _2));
-	
+
 	gSavedSettings.getControl("AppearanceCameraMovement")->getCommitSignal()->connect(boost::bind(&handleAppearanceCameraMovementChanged,  _2));
 
 	LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
@@ -786,10 +787,12 @@ void LLFloaterPreference::onOpen(const LLSD& key)
 	LLButton* load_btn = findChild<LLButton>("PrefLoadButton");
 	LLButton* save_btn = findChild<LLButton>("PrefSaveButton");
 	LLButton* delete_btn = findChild<LLButton>("PrefDeleteButton");
+	LLButton* exceptions_btn = findChild<LLButton>("RenderExceptionsButton");
 
 	load_btn->setEnabled(started);
 	save_btn->setEnabled(started);
 	delete_btn->setEnabled(started);
+	exceptions_btn->setEnabled(started);
 }
 
 void LLFloaterPreference::onVertexShaderEnable()
@@ -2075,6 +2078,11 @@ void LLFloaterPreference::onClickSpellChecker()
     LLFloaterReg::showInstance("prefs_spellchecker");
 }
 
+void LLFloaterPreference::onClickRenderExceptions()
+{
+    LLFloaterReg::showInstance("avatar_render_settings");
+}
+
 void LLFloaterPreference::onClickAdvanced()
 {
 	LLFloaterReg::showInstance("prefs_graphics_advanced");
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index ea199cf034c37a67459aab1b339e865405b47400..2bb2e7e9ff8dab201cad85458428167fb965e007 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -171,6 +171,7 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver,
 	void onClickPermsDefault();
 	void onClickAutoReplace();
 	void onClickSpellChecker();
+	void onClickRenderExceptions();
 	void onClickAdvanced();
 	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
 	void getUIColor(LLUICtrl* ctrl, const LLSD& param);
diff --git a/indra/newview/llfloaterproperties.cpp b/indra/newview/llfloaterproperties.cpp
index 6bfc7807224dcda602d4b6ef060c24832964954f..1310a60638ba699ce0dd263258ab916f1ffe9083 100644
--- a/indra/newview/llfloaterproperties.cpp
+++ b/indra/newview/llfloaterproperties.cpp
@@ -30,6 +30,7 @@
 #include <algorithm>
 #include <functional>
 #include "llcachename.h"
+#include "llavatarnamecache.h"
 #include "lldbstrings.h"
 #include "llfloaterreg.h"
 
@@ -274,12 +275,12 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
 
 	if (item->getCreatorUUID().notNull())
 	{
-		std::string name;
-		gCacheName->getFullName(item->getCreatorUUID(), name);
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(item->getCreatorUUID(), &av_name);
 		getChildView("BtnCreator")->setEnabled(TRUE);
 		getChildView("LabelCreatorTitle")->setEnabled(TRUE);
 		getChildView("LabelCreatorName")->setEnabled(TRUE);
-		getChild<LLUICtrl>("LabelCreatorName")->setValue(name);
+		getChild<LLUICtrl>("LabelCreatorName")->setValue(av_name.getUserName());
 	}
 	else
 	{
@@ -301,7 +302,9 @@ void LLFloaterProperties::refreshFromItem(LLInventoryItem* item)
 		}
 		else
 		{
-			gCacheName->getFullName(perm.getOwner(), name);
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(perm.getOwner(), &av_name);
+			name = av_name.getUserName();
 		}
 		getChildView("BtnOwner")->setEnabled(TRUE);
 		getChildView("LabelOwnerTitle")->setEnabled(TRUE);
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 843dbbf25efd7038b0e353a76cab74187d75217c..75d7d787b1f28d8a1bfa86b5a90fe0c82547dea0 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -357,6 +357,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	std::string sim_type = LLTrans::getString("land_type_unknown");
 	U64 region_flags;
 	U8 agent_limit;
+	S32 hard_agent_limit;
 	F32 object_bonus_factor;
 	U8 sim_access;
 	F32 water_height;
@@ -366,6 +367,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	F32 sun_hour;
 	msg->getString("RegionInfo", "SimName", sim_name);
 	msg->getU8("RegionInfo", "MaxAgents", agent_limit);
+	msg->getS32("RegionInfo2", "HardMaxAgents", hard_agent_limit);
 	msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor);
 	msg->getU8("RegionInfo", "SimAccess", sim_access);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
@@ -412,6 +414,8 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	panel->getChild<LLUICtrl>("object_bonus_spin")->setValue(LLSD(object_bonus_factor) );
 	panel->getChild<LLUICtrl>("access_combo")->setValue(LLSD(sim_access) );
 
+	panel->getChild<LLSpinCtrl>("agent_limit_spin")->setMaxValue(hard_agent_limit);
+
 	LLPanelRegionGeneralInfo* panel_general = LLFloaterRegionInfo::getPanelGeneral();
 	if (panel)
 	{
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index c14bb4e7ae4cf2ea1b8840e8512ea8b8e3a4a46b..5f0587a286d00569f1d8db5728c8b4a3d88fdaac 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -390,6 +390,14 @@ void LLPanelScriptLimitsRegionMemory::setErrorStatus(S32 status, const std::stri
 	LL_WARNS() << "Can't handle remote parcel request."<< " Http Status: "<< status << ". Reason : "<< reason<<LL_ENDL;
 }
 
+// callback from the name cache with an owner name to add to the list
+void LLPanelScriptLimitsRegionMemory::onAvatarNameCache(
+    const LLUUID& id,
+    const LLAvatarName& av_name)
+{
+    onNameCache(id, av_name.getUserName());
+}
+
 // callback from the name cache with an owner name to add to the list
 void LLPanelScriptLimitsRegionMemory::onNameCache(
 						 const LLUUID& id,
@@ -503,7 +511,9 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
 				}
 				else
 				{
-					name_is_cached = gCacheName->getFullName(owner_id, owner_buf);  // username
+					LLAvatarName av_name;
+					name_is_cached = LLAvatarNameCache::get(owner_id, &av_name);
+					owner_buf = av_name.getUserName();
 					owner_buf = LLCacheName::buildUsername(owner_buf);
 				}
 				if(!name_is_cached)
@@ -511,9 +521,18 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
 					if(std::find(names_requested.begin(), names_requested.end(), owner_id) == names_requested.end())
 					{
 						names_requested.push_back(owner_id);
-						gCacheName->get(owner_id, is_group_owned,  // username
-							boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache,
-							    this, _1, _2));
+						if (is_group_owned)
+						{
+							gCacheName->getGroup(owner_id,
+								boost::bind(&LLPanelScriptLimitsRegionMemory::onNameCache,
+								    this, _1, _2));
+						}
+						else
+						{
+							LLAvatarNameCache::get(owner_id,
+								boost::bind(&LLPanelScriptLimitsRegionMemory::onAvatarNameCache,
+								    this, _1, _2));
+						}
 					}
 				}
 			}
diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h
index 2ac3862b4f3507f66c89bcc0bfa02234a71549f3..16450c652733f370b366ede4e12b76ead37106e5 100644
--- a/indra/newview/llfloaterscriptlimits.h
+++ b/indra/newview/llfloaterscriptlimits.h
@@ -38,6 +38,7 @@
 
 class LLPanelScriptLimitsInfo;
 class LLTabContainer;
+class LLAvatarName;
 
 class LLPanelScriptLimitsRegionMemory;
 
@@ -116,6 +117,8 @@ class LLPanelScriptLimitsRegionMemory : public LLPanelScriptLimitsInfo, LLRemote
 	void checkButtonsEnabled();
 
 private:
+	void onAvatarNameCache(const LLUUID& id,
+						 const LLAvatarName& av_name);
 	void onNameCache(const LLUUID& id,
 						 const std::string& name);
 
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index c0980719bb8fdcf9bb007c309a6d426a765e46d1..ba3106913c7b76800a83e6392036f59467da3879 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -653,10 +653,6 @@ void LLFloaterSnapshot::Impl::setFinished(bool finished, bool ok, const std::str
 		LLUICtrl* finished_lbl = mFloater->getChild<LLUICtrl>(ok ? "succeeded_lbl" : "failed_lbl");
 		std::string result_text = mFloater->getString(msg + "_" + (ok ? "succeeded_str" : "failed_str"));
 		finished_lbl->setValue(result_text);
-
-		LLSideTrayPanelContainer* panel_container = mFloater->getChild<LLSideTrayPanelContainer>("panel_container");
-		panel_container->openPreviousPanel();
-		panel_container->getCurrentPanel()->onOpen(LLSD());
 	}
 }
 
diff --git a/indra/newview/llgiveinventory.cpp b/indra/newview/llgiveinventory.cpp
index a9bf8a9a508e73ec6b431fdad3ec92089a26de85..3ab8fed2c6de93dab3a283993e9ac73afa603fc7 100644
--- a/indra/newview/llgiveinventory.cpp
+++ b/indra/newview/llgiveinventory.cpp
@@ -36,6 +36,7 @@
 #include "llagentdata.h"
 #include "llagentui.h"
 #include "llagentwearables.h"
+#include "llavatarnamecache.h"
 #include "llfloatertools.h" // for gFloaterTool
 #include "llhudeffecttrail.h"
 #include "llhudmanager.h"
@@ -306,32 +307,36 @@ bool LLGiveInventory::doGiveInventoryCategory(const LLUUID& to_agent,
 //////////////////////////////////////////////////////////////////////////
 
 //static
-void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im_session_id)
+void LLGiveInventory::logInventoryOffer(const LLUUID& to_agent, const LLUUID &im_session_id, const std::string& item_name, bool is_folder)
 {
 	// compute id of possible IM session with agent that has "to_agent" id
 	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, to_agent);
 	// If this item was given by drag-and-drop into an IM panel, log this action in the IM panel chat.
 	LLSD args;
 	args["user_id"] = to_agent;
+	args["ITEM_NAME"] = item_name;
+	std::string message_name = is_folder ? "inventory_folder_offered" : "inventory_item_offered";
 	if (im_session_id.notNull())
 	{
-		gIMMgr->addSystemMessage(im_session_id, "inventory_item_offered", args);
+		gIMMgr->addSystemMessage(im_session_id, message_name, args);
 	}
 	// If this item was given by drag-and-drop on avatar while IM panel was open, log this action in the IM panel chat.
 	else if (LLIMModel::getInstance()->findIMSession(session_id))
 	{
-		gIMMgr->addSystemMessage(session_id, "inventory_item_offered", args);
+		gIMMgr->addSystemMessage(session_id, message_name, args);
 	}
 	// If this item was given by drag-and-drop on avatar while IM panel wasn't open, log this action to IM history.
 	else
 	{
-		std::string full_name;
-		if (gCacheName->getFullName(to_agent, full_name))
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(to_agent, &av_name))
 		{
 			// Build a new format username or firstname_lastname for legacy names
 			// to use it for a history log filename.
-			full_name = LLCacheName::buildUsername(full_name);
-			LLIMModel::instance().logToFile(full_name, LLTrans::getString("SECOND_LIFE"), im_session_id, LLTrans::getString("inventory_item_offered-im"));
+			std::string full_name = LLCacheName::buildUsername(av_name.getUserName());
+			LLUIString message = LLTrans::getString(message_name + "-im");
+			message.setArgs(args);
+			LLIMModel::instance().logToFile(full_name, LLTrans::getString("SECOND_LIFE"), im_session_id, message.getString());
 		}
 	}
 }
@@ -385,6 +390,7 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
 {
 	if (!item) return;
 	std::string name;
+	std::string item_name = item->getName();
 	LLAgentUI::buildFullname(name);
 	LLUUID transaction_id;
 	transaction_id.generate();
@@ -399,7 +405,7 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
 		gAgentSessionID,
 		to_agent,
 		name,
-		item->getName(),
+		item_name,
 		IM_ONLINE,
 		IM_INVENTORY_OFFERED,
 		transaction_id,
@@ -421,7 +427,7 @@ void LLGiveInventory::commitGiveInventoryItem(const LLUUID& to_agent,
 
 	LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);
 
-	logInventoryOffer(to_agent, im_session_id);
+	logInventoryOffer(to_agent, im_session_id, item_name);
 
 	// add buddy to recent people list
 	LLRecentPeople::instance().add(to_agent);
@@ -501,7 +507,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
 		items,
 		LLInventoryModel::EXCLUDE_TRASH,
 		giveable);
-
+	std::string cat_name = cat->getName();
 	bool give_successful = true;
 	// MAX ITEMS is based on (sizeof(uuid)+2) * count must be <
 	// MTUBYTES or 18 * count < 1200 => count < 1200/18 =>
@@ -556,7 +562,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
 			gAgent.getSessionID(),
 			to_agent,
 			name,
-			cat->getName(),
+			cat_name,
 			IM_ONLINE,
 			IM_INVENTORY_OFFERED,
 			transaction_id,
@@ -579,7 +585,7 @@ bool LLGiveInventory::commitGiveInventoryCategory(const LLUUID& to_agent,
 
 		LLMuteList::getInstance()->autoRemove(to_agent, LLMuteList::AR_INVENTORY);
 
-		logInventoryOffer(to_agent, im_session_id);
+		logInventoryOffer(to_agent, im_session_id, cat_name, true);
 	}
 
 	return give_successful;
diff --git a/indra/newview/llgiveinventory.h b/indra/newview/llgiveinventory.h
index 85bc1ed49c84f4109f096ac992f0c16890bf2ceb..20e6df76e5c7add2d46fade4f917b319e522e43a 100644
--- a/indra/newview/llgiveinventory.h
+++ b/indra/newview/llgiveinventory.h
@@ -78,7 +78,9 @@ class LLGiveInventory
 	 * logs "Inventory item offered" to IM
 	 */
 	static void logInventoryOffer(const LLUUID& to_agent,
-									const LLUUID &im_session_id = LLUUID::null);
+									const LLUUID &im_session_id = LLUUID::null,
+									const std::string& item_name = std::string(),
+									bool is_folder = false);
 
 	static void commitGiveInventoryItem(const LLUUID& to_agent,
 									const LLInventoryItem* item,
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 7545112ab9c234c26d3ff376488c8dcd0cc4c69e..152d0eddcd19202664dcc718e4d5048a0a9232a3 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -38,6 +38,7 @@
 
 #include "llappviewer.h"
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llui.h"
 #include "message.h"
 #include "roles_constants.h"
@@ -54,6 +55,7 @@
 #include <boost/regex.hpp>
 #include "llcorehttputil.h"
 
+
 #if LL_MSVC
 #pragma warning(push)   
 // disable boost::lexical_cast warning
@@ -819,9 +821,9 @@ void LLGroupMgrGroupData::banMemberById(const LLUUID& participant_uuid)
 	LLGroupMgr::getInstance()->sendGroupMemberEjects(mID, ids);
 	LLGroupMgr::getInstance()->sendGroupMembersRequest(mID);
 	LLSD args;
-	std::string name;
-	gCacheName->getFullName(participant_uuid, name);
-	args["AVATAR_NAME"] = name;
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(participant_uuid, &av_name);
+	args["AVATAR_NAME"] = av_name.getUserName();
 	args["GROUP_NAME"] = mName;
 	LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args));
 }
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 2e9332c3552b2f61d1b95c1cb6d985090261be13..ff8b8b0403b09a05b3366db4e23953158706c484 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -646,6 +646,7 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
 	std::string you_joined_call = LLTrans::getString("you_joined_call");
 	std::string you_started_call = LLTrans::getString("you_started_call");
 	std::string other_avatar_name = "";
+	LLAvatarName av_name;
 
 	std::string message;
 
@@ -655,7 +656,8 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
 		// no text notifications
 		break;
 	case P2P_SESSION:
-		gCacheName->getFullName(mOtherParticipantID, other_avatar_name); // voice
+		LLAvatarNameCache::get(mOtherParticipantID, &av_name);
+		other_avatar_name = av_name.getUserName();
 
 		if(direction == LLVoiceChannel::INCOMING_CALL)
 		{
@@ -806,7 +808,7 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
 		{
 			// convert it to a legacy name if we have a complete name
 			std::string legacy_name = gCacheName->buildLegacyName(from);
- 			gCacheName->getUUID(legacy_name, from_id);
+			from_id = LLAvatarNameCache::findIdByName(legacy_name);
 		}
 
 		std::string timestamp = msg[LL_IM_TIME];
@@ -2765,10 +2767,10 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 
 		else
 		{
-			std::string session_name;
+			LLAvatarName av_name;
 			// since we select user to share item with - his name is already in cache
-			gCacheName->getFullName(args["user_id"], session_name);
-			session_name = LLCacheName::buildUsername(session_name);
+			LLAvatarNameCache::get(args["user_id"], &av_name);
+			std::string session_name = LLCacheName::buildUsername(av_name.getUserName());
 			LLIMModel::instance().logToFile(session_name, SYSTEM_FROM, LLUUID::null, message.getString());
 		}
 	}
@@ -3075,8 +3077,8 @@ void LLIMMgr::inviteToSession(
 	{
 		if (caller_name.empty())
 		{
-			gCacheName->get(caller_id, false,  // voice
-				boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2, _3));
+			LLAvatarNameCache::get(caller_id, 
+				boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2));
 		}
 		else
 		{
@@ -3095,9 +3097,9 @@ void LLIMMgr::inviteToSession(
 	}
 }
 
-void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group)
+void LLIMMgr::onInviteNameLookup(LLSD payload, const LLUUID& id, const LLAvatarName& av_name)
 {
-	payload["caller_name"] = name;
+	payload["caller_name"] = av_name.getUserName();
 	payload["session_name"] = payload["caller_name"].asString();
 
 	std::string notify_box_type = payload["notify_box_type"].asString();
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index da40ac83931f38e3258516b4412e8732ac562052..e3851a56e0c1826bfa0cc5842f655434abb27710 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -473,7 +473,7 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 
 	void processIMTypingCore(const LLIMInfo* im_info, BOOL typing);
 
-	static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group);
+	static void onInviteNameLookup(LLSD payload, const LLUUID& id, const LLAvatarName& name);
 
 	void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg);
     //Triggers when a session has already been added
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index b7f5424f255c03132f7a6e9b1a902b60bcf84dc5..555c19baac4fcd146cd7f46dd3b6e56b619c4841 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -275,8 +275,10 @@ BOOL LLInvFVBridge::cutToClipboard()
         if (cut_from_marketplacelistings && (LLMarketplaceData::instance().isInActiveFolder(mUUID) ||
                                              LLMarketplaceData::instance().isListedAndActive(mUUID)))
         {
-            // Prompt the user if cutting from a marketplace active listing
-            LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLInvFVBridge::callback_cutToClipboard, this, _1, _2));
+            LLUUID parent_uuid = obj->getParentUUID();
+            BOOL result = perform_cutToClipboard();
+            gInventory.addChangedMask(LLInventoryObserver::STRUCTURE, parent_uuid);
+            return result;
         }
         else
         {
@@ -303,11 +305,7 @@ BOOL LLInvFVBridge::callback_cutToClipboard(const LLSD& notification, const LLSD
     S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
     if (option == 0) // YES
     {
-		const LLInventoryObject* obj = gInventory.getObject(mUUID);
-		LLUUID parent_uuid = obj->getParentUUID();
-		BOOL result = perform_cutToClipboard();
-		gInventory.addChangedMask(LLInventoryObserver::STRUCTURE, parent_uuid);
-		return result;
+		return perform_cutToClipboard();
     }
     return FALSE;
 }
@@ -3471,7 +3469,24 @@ void LLFolderBridge::pasteFromClipboard()
         const LLUUID &marketplacelistings_id = model->findCategoryUUIDForType(LLFolderType::FT_MARKETPLACE_LISTINGS, false);
         const BOOL paste_into_marketplacelistings = model->isObjectDescendentOf(mUUID, marketplacelistings_id);
         
-        if (paste_into_marketplacelistings && !LLMarketplaceData::instance().isListed(mUUID) && LLMarketplaceData::instance().isInActiveFolder(mUUID))
+        BOOL cut_from_marketplacelistings = FALSE;
+        if (LLClipboard::instance().isCutMode())
+        {
+            //Items are not removed from folder on "cut", so we need update listing folder on "paste" operation
+            std::vector<LLUUID> objects;
+            LLClipboard::instance().pasteFromClipboard(objects);
+            for (std::vector<LLUUID>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter)
+            {
+                const LLUUID& item_id = (*iter);
+                if(gInventory.isObjectDescendentOf(item_id, marketplacelistings_id) && (LLMarketplaceData::instance().isInActiveFolder(item_id) ||
+                    LLMarketplaceData::instance().isListedAndActive(item_id)))
+                {
+                    cut_from_marketplacelistings = TRUE;
+                    break;
+                }
+            }
+        }
+        if (cut_from_marketplacelistings || (paste_into_marketplacelistings && !LLMarketplaceData::instance().isListed(mUUID) && LLMarketplaceData::instance().isInActiveFolder(mUUID)))
         {
             // Prompt the user if pasting in a marketplace active version listing (note that pasting right under the listing folder root doesn't need a prompt)
             LLNotificationsUtil::add("ConfirmMerchantActiveChange", LLSD(), LLSD(), boost::bind(&LLFolderBridge::callback_pasteFromClipboard, this, _1, _2));
@@ -3490,7 +3505,20 @@ void LLFolderBridge::callback_pasteFromClipboard(const LLSD& notification, const
     S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
     if (option == 0) // YES
     {
+        std::vector<LLUUID> objects;
+        std::set<LLUUID> parent_folders;
+        LLClipboard::instance().pasteFromClipboard(objects);
+        for (std::vector<LLUUID>::const_iterator iter = objects.begin(); iter != objects.end(); ++iter)
+        {
+            const LLInventoryObject* obj = gInventory.getObject(*iter);
+            parent_folders.insert(obj->getParentUUID());
+        }
         perform_pasteFromClipboard();
+        for (std::set<LLUUID>::const_iterator iter = parent_folders.begin(); iter != parent_folders.end(); ++iter)
+        {
+            gInventory.addChangedMask(LLInventoryObserver::STRUCTURE, *iter);
+        }
+
     }
 }
 
@@ -3913,6 +3941,37 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
 			mWearables=TRUE;
 		}
 	}
+	else
+	{
+		// Mark wearables and allow copy from library
+		LLInventoryModel* model = getInventoryModel();
+		if(!model) return;
+		const LLInventoryCategory* category = model->getCategory(mUUID);
+		if (!category) return;
+		LLFolderType::EType type = category->getPreferredType();
+		const bool is_system_folder = LLFolderType::lookupIsProtectedType(type);
+
+		LLFindWearables is_wearable;
+		LLIsType is_object(LLAssetType::AT_OBJECT);
+		LLIsType is_gesture(LLAssetType::AT_GESTURE);
+
+		if (checkFolderForContentsOfType(model, is_wearable) ||
+			checkFolderForContentsOfType(model, is_object) ||
+			checkFolderForContentsOfType(model, is_gesture))
+		{
+			mWearables = TRUE;
+		}
+
+		if (!is_system_folder)
+		{
+			items.push_back(std::string("Copy"));
+			if (!isItemCopyable())
+			{
+				// For some reason there are items in library that can't be copied directly
+				disabled_items.push_back(std::string("Copy"));
+			}
+		}
+	}
 
 	// Preemptively disable system folder removal if more than one item selected.
 	if ((flags & FIRST_SELECTED_ITEM) == 0)
@@ -3920,7 +3979,7 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
 		disabled_items.push_back(std::string("Delete System Folder"));
 	}
 
-	if (!isMarketplaceListingsFolder())
+	if (isAgentInventory() && !isMarketplaceListingsFolder())
 	{
 		items.push_back(std::string("Share"));
 		if (!canShare())
@@ -3928,6 +3987,9 @@ void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items
 			disabled_items.push_back(std::string("Share"));
 		}
 	}
+
+	
+
 	// Add menu items that are dependent on the contents of the folder.
 	LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
 	if (category && (marketplace_listings_id != mUUID))
@@ -3965,7 +4027,6 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 	const LLUUID trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 	if (trash_id == mUUID) return;
 	if (isItemInTrash()) return;
-	if (!isAgentInventory()) return;
     
 	if (!isItemRemovable())
 	{
@@ -3978,9 +4039,10 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 	// BAP change once we're no longer treating regular categories as ensembles.
 	const bool is_ensemble = (type == LLFolderType::FT_NONE ||
 		LLFolderType::lookupIsEnsembleType(type));
+	const bool is_agent_inventory = isAgentInventory();
 
 	// Only enable calling-card related options for non-system folders.
-	if (!is_system_folder)
+	if (!is_system_folder && is_agent_inventory)
 	{
 		LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
 		if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
@@ -3992,7 +4054,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 	}
 
 #ifndef LL_RELEASE_FOR_DOWNLOAD
-	if (LLFolderType::lookupIsProtectedType(type))
+	if (LLFolderType::lookupIsProtectedType(type) && is_agent_inventory)
 	{
 		items.push_back(std::string("Delete System Folder"));
 	}
@@ -4009,8 +4071,6 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 		checkFolderForContentsOfType(model, is_object) ||
 		checkFolderForContentsOfType(model, is_gesture) )
 	{
-		items.push_back(std::string("Folder Wearables Separator"));
-
 		// Only enable add/replace outfit for non-system folders.
 		if (!is_system_folder)
 		{
@@ -4021,25 +4081,30 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t&
 			}
 
 			items.push_back(std::string("Replace Outfit"));
+
+			if (is_agent_inventory)
+			{
+				items.push_back(std::string("Folder Wearables Separator"));
+				if (is_ensemble)
+				{
+					items.push_back(std::string("Wear As Ensemble"));
+				}
+				items.push_back(std::string("Remove From Outfit"));
+				if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
+				{
+					disabled_items.push_back(std::string("Remove From Outfit"));
+				}
+			}
+			if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
+			{
+				disabled_items.push_back(std::string("Replace Outfit"));
+			}
+			if (!LLAppearanceMgr::instance().getCanAddToCOF(mUUID))
+			{
+				disabled_items.push_back(std::string("Add To Outfit"));
+			}
+			items.push_back(std::string("Outfit Separator"));
 		}
-		if (is_ensemble)
-		{
-			items.push_back(std::string("Wear As Ensemble"));
-		}
-		items.push_back(std::string("Remove From Outfit"));
-		if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
-		{
-			disabled_items.push_back(std::string("Remove From Outfit"));
-		}
-		if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
-		{
-			disabled_items.push_back(std::string("Replace Outfit"));
-		}
-		if (!LLAppearanceMgr::instance().getCanAddToCOF(mUUID))
-		{
-			disabled_items.push_back(std::string("Add To Outfit"));
-		}
-		items.push_back(std::string("Outfit Separator"));
 	}
 }
 
@@ -4276,9 +4341,18 @@ void LLFolderBridge::modifyOutfit(BOOL append)
 		return;
 	}
 
-	LLAppearanceMgr::instance().wearInventoryCategory( cat, FALSE, append );
+	if (isAgentInventory())
+	{
+		LLAppearanceMgr::instance().wearInventoryCategory(cat, FALSE, append);
+	}
+	else
+	{
+		// Library, we need to copy content first
+		LLAppearanceMgr::instance().wearInventoryCategory(cat, TRUE, append);
+	}
 }
 
+
 // +=================================================+
 // |        LLMarketplaceFolderBridge                |
 // +=================================================+
diff --git a/indra/newview/llinventoryitemslist.h b/indra/newview/llinventoryitemslist.h
index fe05c2ed7c25ac0211a9d80009bbfba90e82adef..ce41105f989f28d3117ceb792e0f0f60848a8ad9 100644
--- a/indra/newview/llinventoryitemslist.h
+++ b/indra/newview/llinventoryitemslist.h
@@ -61,6 +61,11 @@ class LLInventoryItemsList : public LLFlatListViewEx
 	 */
 	void setForceRefresh(bool force_refresh){ mForceRefresh = force_refresh; }
 
+	/**
+	* If refreshes when invisible.
+	*/
+	bool getForceRefresh(){ return mForceRefresh;  }
+
 	virtual bool selectItemByValue(const LLSD& value, bool select = true);
 
 	void updateSelection();
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index 06017964365eed2b2d0b57e5ddda5271ddcf21e4..12bb609df8c5cc4c1776ffd5861407415419912f 100644
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -182,10 +182,10 @@ void LLPanelInventoryListItemBase::setValue(const LLSD& value)
 	mSelected = value["selected"];
 }
 
-void LLPanelInventoryListItemBase::onMouseEnter(S32 x, S32 y, MASK mask)
+BOOL LLPanelInventoryListItemBase::handleHover(S32 x, S32 y, MASK mask)
 {
 	mHovered = true;
-	LLPanel::onMouseEnter(x, y, mask);
+	return LLPanel::handleHover(x, y, mask);
 }
 
 void LLPanelInventoryListItemBase::onMouseLeave(S32 x, S32 y, MASK mask)
diff --git a/indra/newview/llinventorylistitem.h b/indra/newview/llinventorylistitem.h
index b1ef6c74ee83244f40ed7eb633603f4dd43e561f..d4dd212cc3e4e5fa60faff8049ca03f262f453aa 100644
--- a/indra/newview/llinventorylistitem.h
+++ b/indra/newview/llinventorylistitem.h
@@ -129,8 +129,8 @@ class LLPanelInventoryListItemBase : public LLPanel
 	 */
 	/*virtual*/ S32  notify(const LLSD& info);
 
-	 /* Highlights item */
-	/*virtual*/ void onMouseEnter(S32 x, S32 y, MASK mask);
+	/* Highlights item */
+	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
 	/* Removes item highlight */
 	/*virtual*/ void onMouseLeave(S32 x, S32 y, MASK mask);
 
@@ -153,6 +153,7 @@ class LLPanelInventoryListItemBase : public LLPanel
 	LLViewerInventoryItem* getItem() const;
 
 	void setSeparatorVisible(bool visible) { mSeparatorVisible = visible; }
+	void resetHighlight() { mHovered = FALSE; }
 
 	virtual ~LLPanelInventoryListItemBase(){}
 
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 287fa4c45ba5c083ee208fc58deba9cdcb6e8706..855f7c750e6ebc5f061236062351e50489151eaf 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -34,6 +34,7 @@
 #include "llagent.h"
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
+#include "llavatarnamecache.h"
 #include "llclipboard.h"
 #include "llinventorypanel.h"
 #include "llinventorybridge.h"
@@ -1022,19 +1023,19 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
 		{
 			// Valid UUID; set the item UUID and rename it
 			new_item->setCreator(id);
-			std::string avatar_name;
+			LLAvatarName av_name;
 
-			if (gCacheName->getFullName(id, avatar_name))
+			if (LLAvatarNameCache::get(id, &av_name))
 			{
-				new_item->rename(avatar_name);
+				new_item->rename(av_name.getUserName());
 				mask |= LLInventoryObserver::LABEL;
 			}
 			else
 			{
 				// Fetch the current name
-				gCacheName->get(id, FALSE,
+				LLAvatarNameCache::get(id,
 					boost::bind(&LLViewerInventoryItem::onCallingCardNameLookup, new_item.get(),
-					_1, _2, _3));
+					_1, _2));
 			}
 
 		}
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index 4a77edc56503499648d1883cc4983aeb4d2fbdcd..a8919db828f09d7bd2de86a1291b155242b40236 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -360,9 +360,12 @@ void LLInventoryModelBackgroundFetch::incrFetchCount(S32 fetching)
 	}
 }
 
+static LLTrace::BlockTimerStatHandle FTM_BULK_FETCH("Bulk Fetch");
+
 // Bundle up a bunch of requests to send all at once.
 void LLInventoryModelBackgroundFetch::bulkFetch()
 {
+	LL_RECORD_BLOCK_TIME(FTM_BULK_FETCH);
 	//Background fetch is called from gIdleCallbacks in a loop until background fetch is stopped.
 	//If there are items in mFetchQueue, we want to check the time since the last bulkFetch was 
 	//sent.  If it exceeds our retry time, go ahead and fire off another batch.  
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 374efa2986ba24c9b45ba8adf995280bc7a494fa..229703bb3977ef0a5f8f3945fa22713e3b438993 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -209,6 +209,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
 	request_params["channel"] = LLVersionInfo::getChannel();
 	request_params["platform"] = mPlatform;
 	request_params["platform_version"] = mPlatformVersion;
+	request_params["address_size"] = ADDRESS_SIZE;
 	request_params["id0"] = mSerialNumber;
 	request_params["host_id"] = gSavedSettings.getString("HostID");
 	request_params["extended_errors"] = true; // request message_id and message_args
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 54f95520db263353364d6c29deac6689c69255b7..a0e19f2d1965f6d6f6a5b3cb895edc7d3ffa378f 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -121,7 +121,6 @@ namespace {
         {
             // Prompt the user with the warning (so they know why things are failing)
             LLSD subs;
-            subs["[ERROR_REASON]"] = reason;
             // We do show long descriptions in the alert (unlikely to be readable). The description string will be in the log though.
             std::string description;
             if (result.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT))
@@ -145,6 +144,16 @@ namespace {
             {
                 description = result.asString();
             }
+            std::string reason_lc = reason;
+            LLStringUtil::toLower(reason_lc);
+            if (!description.empty() && reason_lc.find("unknown") != std::string::npos)
+            {
+                subs["[ERROR_REASON]"] = "";
+            }
+            else
+            {
+                subs["[ERROR_REASON]"] = "'" + reason +"'\n";
+            }
             subs["[ERROR_DESCRIPTION]"] = description;
             LLNotificationsUtil::add("MerchantTransactionFailed", subs);
         }
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index c3dd08c327fb55a7489c1688f54f55f1a0e5ec3e..4999318973cb7b6b0503de346ae9ea55e283ddcb 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -730,9 +730,16 @@ void LLPanelStandStopFlying::updatePosition()
 		panel_ssf_container->setOrigin(0, y_pos);
 	}
 
-	S32 x_pos = bottom_tb_center-getRect().getWidth()/2 - left_tb_width;
-
-	setOrigin( x_pos, 0);
+	if (gToolBarView != NULL && gToolBarView->getToolbar(LLToolBarEnums::TOOLBAR_LEFT)->hasButtons())
+	{
+		S32 x_pos = bottom_tb_center - getRect().getWidth() / 2 - left_tb_width;
+		setOrigin( x_pos, 0);
+	}
+	else 
+	{
+		S32 x_pos = bottom_tb_center - getRect().getWidth() / 2;
+		setOrigin( x_pos, 0);
+	}
 }
 
 // EOF
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 0f70c9d13f9c83dea08e925d31f4049b55686668..02b28a2bf8e6486cc7a9f9e0b93966ba93279390 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -53,6 +53,7 @@
 #include "llxfermanager.h"
 
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llviewergenericmessage.h"	// for gGenericDispatcher
 #include "llworld.h" //for particle system banning
 #include "llimview.h"
@@ -456,7 +457,7 @@ void LLMuteList::updateRemove(const LLMute& mute)
 	gAgent.sendReliableMessage();
 }
 
-void notify_automute_callback(const LLUUID& agent_id, const std::string& full_name, bool is_group, LLMuteList::EAutoReason reason)
+void notify_automute_callback(const LLUUID& agent_id, const LLAvatarName& full_name, LLMuteList::EAutoReason reason)
 {
 	std::string notif_name;
 	switch (reason)
@@ -474,7 +475,7 @@ void notify_automute_callback(const LLUUID& agent_id, const std::string& full_na
 	}
 
 	LLSD args;
-	args["NAME"] = full_name;
+	args["NAME"] = full_name.getUserName();
     
 	LLNotificationPtr notif_ptr = LLNotifications::instance().add(notif_name, args, LLSD());
 	if (notif_ptr)
@@ -499,17 +500,17 @@ BOOL LLMuteList::autoRemove(const LLUUID& agent_id, const EAutoReason reason)
 		removed = TRUE;
 		remove(automute);
 
-		std::string full_name;
-		if (gCacheName->getFullName(agent_id, full_name))
-			{
-				// name in cache, call callback directly
-			notify_automute_callback(agent_id, full_name, false, reason);
-			}
-			else
-			{
-				// not in cache, lookup name from cache
-			gCacheName->get(agent_id, false,
-				boost::bind(&notify_automute_callback, _1, _2, _3, reason));
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(agent_id, &av_name))
+		{
+			// name in cache, call callback directly
+			notify_automute_callback(agent_id, av_name, reason);
+		}
+		else
+		{
+			// not in cache, lookup name from cache
+			LLAvatarNameCache::get(agent_id,
+				boost::bind(&notify_automute_callback, _1, _2, reason));
 		}
 	}
 
@@ -811,3 +812,99 @@ void LLMuteList::notifyObserversDetailed(const LLMute& mute)
 		it = mObservers.upper_bound(observer);
 	}
 }
+
+LLRenderMuteList::LLRenderMuteList()
+{}
+
+bool LLRenderMuteList::saveToFile()
+{
+    std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "render_mute_settings.txt");
+    LLFILE* fp = LLFile::fopen(filename, "wb");
+    if (!fp)
+    {
+        LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL;
+        return false;
+    }
+    for (std::map<LLUUID, S32>::iterator it = sVisuallyMuteSettingsMap.begin(); it != sVisuallyMuteSettingsMap.end(); ++it)
+    {
+        if (it->second != 0)
+        {
+            std::string id_string;
+            it->first.toString(id_string);
+            fprintf(fp, "%d %s\n", (S32)it->second, id_string.c_str());
+        }
+    }
+    fclose(fp);
+    return true;
+}
+
+bool LLRenderMuteList::loadFromFile()
+{
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "render_mute_settings.txt");
+	LLFILE* fp = LLFile::fopen(filename, "rb");
+	if (!fp)
+	{
+		LL_WARNS() << "Couldn't open render mute list file: " << filename << LL_ENDL;
+		return false;
+	}
+
+	char id_buffer[MAX_STRING];
+	char buffer[MAX_STRING];
+	while (!feof(fp) && fgets(buffer, MAX_STRING, fp))
+	{
+		id_buffer[0] = '\0';
+		S32 setting = 0;
+		sscanf(buffer, " %d %254s\n", &setting, id_buffer);
+		sVisuallyMuteSettingsMap[LLUUID(id_buffer)] = setting;
+	}
+	fclose(fp);
+    return true;
+}
+
+void LLRenderMuteList::saveVisualMuteSetting(const LLUUID& agent_id, S32 setting)
+{
+    if(setting == 0)
+    {
+        sVisuallyMuteSettingsMap.erase(agent_id);
+    }
+    else
+    {
+        sVisuallyMuteSettingsMap[agent_id] = setting;
+    }
+    saveToFile();
+    notifyObservers();
+}
+
+S32 LLRenderMuteList::getSavedVisualMuteSetting(const LLUUID& agent_id)
+{
+    std::map<LLUUID, S32>::iterator iter = sVisuallyMuteSettingsMap.find(agent_id);
+    if (iter != sVisuallyMuteSettingsMap.end())
+    {
+        return iter->second;
+    }
+
+    return 0;
+}
+
+void LLRenderMuteList::addObserver(LLMuteListObserver* observer)
+{
+    mObservers.insert(observer);
+}
+
+void LLRenderMuteList::removeObserver(LLMuteListObserver* observer)
+{
+    mObservers.erase(observer);
+}
+
+void LLRenderMuteList::notifyObservers()
+{
+    for (observer_set_t::iterator it = mObservers.begin();
+        it != mObservers.end();
+        )
+    {
+        LLMuteListObserver* observer = *it;
+        observer->onChange();
+        // In case onChange() deleted an entry.
+        it = mObservers.upper_bound(observer);
+    }
+}
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 4ceddc97fd81f3d00d7fe58215a8b5817d181af7..9ab978353bb45fe51817a7d8558ac1143f6cce39 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -175,5 +175,25 @@ class LLMuteListObserver
 	virtual void onChangeDetailed(const LLMute& ) { }
 };
 
+class LLRenderMuteList : public LLSingleton<LLRenderMuteList>
+{
+    LLSINGLETON(LLRenderMuteList);
+public:
+	bool loadFromFile();
+	bool saveToFile();
+	S32 getSavedVisualMuteSetting(const LLUUID& agent_id);
+	void saveVisualMuteSetting(const LLUUID& agent_id, S32 setting);
+
+	void addObserver(LLMuteListObserver* observer);
+	void removeObserver(LLMuteListObserver* observer);
+
+	std::map<LLUUID, S32> sVisuallyMuteSettingsMap;
+
+private:
+	void notifyObservers();
+	typedef std::set<LLMuteListObserver*> observer_set_t;
+	observer_set_t mObservers;
+};
+
 
 #endif //LL_MUTELIST_H
diff --git a/indra/newview/llnamebox.cpp b/indra/newview/llnamebox.cpp
index 1099316a19ab64f18fbbcfe51f7188c4295cf63f..8d32fb1d5cce3879c19db04dfd7b9fd228338236 100644
--- a/indra/newview/llnamebox.cpp
+++ b/indra/newview/llnamebox.cpp
@@ -35,6 +35,7 @@
 #include "lluuid.h"
 
 #include "llcachename.h"
+#include "llavatarnamecache.h"
 
 // statics
 std::set<LLNameBox*> LLNameBox::sInstances;
@@ -67,7 +68,9 @@ void LLNameBox::setNameID(const LLUUID& name_id, BOOL is_group)
 
 	if (!is_group)
 	{
-		got_name = gCacheName->getFullName(name_id, name);
+		LLAvatarName av_name;
+		got_name = LLAvatarNameCache::get(name_id, &av_name);
+		name = av_name.getUserName();
 	}
 	else
 	{
diff --git a/indra/newview/llnameeditor.cpp b/indra/newview/llnameeditor.cpp
index b3b1ff7c06f2385ba992597f3ef49e36051aaa82..055754f27026d5e40a0b8a1091856cbd77e0599b 100644
--- a/indra/newview/llnameeditor.cpp
+++ b/indra/newview/llnameeditor.cpp
@@ -28,6 +28,7 @@
  
 #include "llnameeditor.h"
 #include "llcachename.h"
+#include "llavatarnamecache.h"
 
 #include "llfontgl.h"
 
@@ -65,7 +66,9 @@ void LLNameEditor::setNameID(const LLUUID& name_id, BOOL is_group)
 
 	if (!is_group)
 	{
-		gCacheName->getFullName(name_id, name);
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(name_id, &av_name);
+		name = av_name.getUserName();
 	}
 	else
 	{
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index a078889d46569a576ecec0e343585c229cc20d52..4a3923ef6eb1289a6e30571bec2a184a1646c573 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -114,11 +114,11 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
 	}
 }
 
-void log_name_callback(const std::string& full_name, const std::string& from_name, 
+void log_name_callback(const LLAvatarName& av_name, const std::string& from_name, 
 					   const std::string& message, const LLUUID& from_id)
 
 {
-	LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, full_name, from_name, message,
+	LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, av_name.getUserName(), from_name, message,
 					from_id, LLUUID());
 }
 
@@ -141,11 +141,11 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi
 
 	if(to_file_only)
 	{
-		gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
+		LLAvatarNameCache::get(from_id, boost::bind(&log_name_callback, _2, "", notification->getMessage(), LLUUID()));
 	}
 	else
 	{
-		gCacheName->get(from_id, false, 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, notification->getMessage(), from_id));
 	}
 }
 
@@ -167,9 +167,18 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
 	const std::string group_name = groupData.mName;
 	const std::string sender_name = payload["sender_name"].asString();
 
-	// we can't retrieve sender id from group notice system message, so try to lookup it from cache
 	LLUUID sender_id;
-	gCacheName->getUUID(sender_name, sender_id);
+	if (payload.has("sender_id"))
+	{
+		sender_id = payload["sender_id"].asUUID();
+	}
+	
+	if (sender_id.notNull())
+	{
+		// Legacy support and fallback method
+		// if we can't retrieve sender id from group notice system message, try to lookup it from cache
+		sender_id = LLAvatarNameCache::findIdByName(sender_name);
+	}
 
 	logToIM(IM_SESSION_GROUP_START, group_name, sender_name, payload["message"],
 			payload["group_id"], sender_id);
@@ -219,7 +228,12 @@ std::string LLHandlerUtil::getSubstitutionName(const LLNotificationPtr& notifica
 		{
 			from_id = notification->getPayload()["from_id"];
 		}
-		if(!gCacheName->getFullName(from_id, res))
+		LLAvatarName av_name;
+		if(LLAvatarNameCache::get(from_id, &av_name))
+		{
+			res = av_name.getUserName();
+		}
+		else
 		{
 			res = "";
 		}
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index 00c204e702a9fa809a1fc249a61ea788c0bfd58e..8440e9ee500dc380c73cd2895296cdeec0eaf61b 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1168,9 +1168,9 @@ void LLPanelGroupMembersSubTab::confirmEjectMembers()
 	if (selection_count == 1)
 	{
 		LLSD args;
-		std::string fullname;
-		gCacheName->getFullName(mMembersList->getValue(), fullname);
-		args["AVATAR_NAME"] = fullname;
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(mMembersList->getValue(), &av_name);
+		args["AVATAR_NAME"] = av_name.getUserName();
 		LLSD payload;
 		LLNotificationsUtil::add("EjectGroupMemberWarning",
 				 	 	 	 	 args,
@@ -1231,7 +1231,7 @@ void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, c
 		for (uuid_vec_t::const_iterator i = selected_members.begin(); i != selected_members.end(); ++i)
 		{
 			LLSD args;
-			args["AVATAR_NAME"] = LLSLURL("agent", *i, "displayname").getSLURLString();
+			args["AVATAR_NAME"] = LLSLURL("agent", *i, "completename").getSLURLString();
 			args["GROUP_NAME"] = group_data->mName;
 			
 			LLNotifications::instance().add(LLNotification::Params("EjectAvatarFromGroup").substitutions(args));
@@ -1862,9 +1862,9 @@ void LLPanelGroupMembersSubTab::confirmBanMembers()
 	if (selection_count == 1)
 	{
 		LLSD args;
-		std::string fullname;
-		gCacheName->getFullName(mMembersList->getValue(), fullname);
-		args["AVATAR_NAME"] = fullname;
+		LLAvatarName av_name;
+		LLAvatarNameCache::get(mMembersList->getValue(), &av_name);
+		args["AVATAR_NAME"] = av_name.getUserName();
 		LLSD payload;
 		LLNotificationsUtil::add("BanGroupMemberWarning",
 				 	 	 	 	 args,
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 208ee77f2d69899b4f3af2e800dd9e37725fc362..3f6bdde127683ce7a521aefbffb43f81e3d0addb 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -578,7 +578,6 @@ void LLPanelOutfitEdit::onOpen(const LLSD& key)
 		// *TODO: this method is called even panel is not visible to user because its parent layout panel is hidden.
 		// So, we can defer initializing a bit.
 		mWearableListManager = new LLFilteredWearableListManager(mWearableItemsList, mListViewItemTypes[LVIT_ALL]->collector);
-		mWearableListManager->populateList();
 		displayCurrentOutfit();
 		mInitialized = true;
 	}
@@ -632,6 +631,10 @@ void LLPanelOutfitEdit::showAddWearablesPanel(bool show_add_wearables)
 		// Reset mWearableItemsList position to top. See EXT-8180.
 		mWearableItemsList->goToTop();
 	}
+	else
+	{
+		mWearableListManager->populateIfNeeded();
+	}
 
 	//switching button bars
 	getChildView("no_add_wearables_button_bar")->setVisible( !show_add_wearables);
@@ -661,6 +664,7 @@ void LLPanelOutfitEdit::showWearablesListView()
 	{
 		updateWearablesPanelVerbButtons();
 		updateFiltersVisibility();
+		mWearableListManager->populateIfNeeded();
 	}
 	mListViewBtn->setToggleState(TRUE);
 }
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index 55c09d85ead7ef8b7b95495a0a0f48fcb7c1da0a..77bc99da832c181857448174524e8fae58f040bb 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -384,9 +384,9 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
 		LLAvatarPicks* avatar_picks = static_cast<LLAvatarPicks*>(data);
 		if(avatar_picks && getAvatarId() == avatar_picks->target_id)
 		{
-			std::string full_name;
-			gCacheName->getFullName(getAvatarId(), full_name);
-			getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", full_name);
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(getAvatarId(), &av_name);
+			getChild<LLUICtrl>("pick_title")->setTextArg("[NAME]", av_name.getUserName());
 			
 			// Save selection, to be able to edit same item after saving changes. See EXT-3023.
 			LLUUID selected_id = mPicksList->getSelectedValue()[PICK_ID];
diff --git a/indra/newview/llpanelsnapshotlocal.cpp b/indra/newview/llpanelsnapshotlocal.cpp
index 3652c10586d51cf18eea686fc53625b4bd185030..51ec964ace38e88b406e5dd438f66b7c4d327011 100644
--- a/indra/newview/llpanelsnapshotlocal.cpp
+++ b/indra/newview/llpanelsnapshotlocal.cpp
@@ -168,12 +168,11 @@ void LLPanelSnapshotLocal::onSaveFlyoutCommit(LLUICtrl* ctrl)
 	if (saved)
 	{
 		mSnapshotFloater->postSave();
-		goBack();
 		floater->notify(LLSD().with("set-finished", LLSD().with("ok", true).with("msg", "local")));
 	}
 	else
 	{
-		cancel();
+		floater->notify(LLSD().with("set-finished", LLSD().with("ok", false).with("msg", "local")));
 	}
 }
 
diff --git a/indra/newview/llpanelsnapshotpostcard.cpp b/indra/newview/llpanelsnapshotpostcard.cpp
index ebf9153da9da2289f8655d0e002c0cda2304cd24..3d18e837afc39c85e90882d7d4bdc43cd8e59968 100644
--- a/indra/newview/llpanelsnapshotpostcard.cpp
+++ b/indra/newview/llpanelsnapshotpostcard.cpp
@@ -106,6 +106,14 @@ BOOL LLPanelSnapshotPostcard::postBuild()
 // virtual
 void LLPanelSnapshotPostcard::onOpen(const LLSD& key)
 {
+	LLUICtrl* name_form = getChild<LLUICtrl>("name_form");
+	if (name_form && name_form->getValue().asString().empty())
+	{
+		std::string name_string;
+		LLAgentUI::buildFullname(name_string);
+		getChild<LLUICtrl>("name_form")->setValue(LLSD(name_string));
+	}
+
 	LLPanelSnapshot::onOpen(key);
 }
 
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index f28ffce602b677b0d52b887f285cec421db4513a..5cdc5dfd38a0639fee2cf58e5b64a71606b2637f 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -1870,8 +1870,14 @@ void LLLiveLSLEditor::loadAsset()
 
 			if(item)
 			{
-                LLExperienceCache::instance().fetchAssociatedExperience(item->getParentUUID(), item->getUUID(),
-                        boost::bind(&LLLiveLSLEditor::setAssociatedExperience, getDerivedHandle<LLLiveLSLEditor>(), _1));
+				LLViewerRegion* region = object->getRegion();
+				std::string url = std::string();
+				if(region)
+				{
+					url = region->getCapability("GetMetadata");
+				}
+				LLExperienceCache::instance().fetchAssociatedExperience(item->getParentUUID(), item->getUUID(), url,
+					boost::bind(&LLLiveLSLEditor::setAssociatedExperience, getDerivedHandle<LLLiveLSLEditor>(), _1));
 
 				bool isGodlike = gAgent.isGodlike();
 				bool copyManipulate = gAgent.allowOperation(PERM_COPY, item->getPermissions(), GP_OBJECT_MANIPULATE);
diff --git a/indra/newview/llregioninfomodel.cpp b/indra/newview/llregioninfomodel.cpp
index 25c576468b6395301bc69f40ebe50221233a337a..25d7be831f6de31599f3c6a9ea525a0349dff981 100644
--- a/indra/newview/llregioninfomodel.cpp
+++ b/indra/newview/llregioninfomodel.cpp
@@ -40,6 +40,7 @@ void LLRegionInfoModel::reset()
 {
 	mSimAccess			= 0;
 	mAgentLimit			= 0;
+	mHardAgentLimit		= 100;
 
 	mRegionFlags		= 0;
 	mEstateID			= 0;
@@ -143,6 +144,7 @@ void LLRegionInfoModel::update(LLMessageSystem* msg)
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, mParentEstateID);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, mSimAccess);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, mAgentLimit);
+
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, mObjectBonusFactor);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor, mBillableFactor);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, mWaterHeight);
@@ -158,6 +160,8 @@ void LLRegionInfoModel::update(LLMessageSystem* msg)
 	msg->getF32(_PREHASH_RegionInfo, _PREHASH_SunHour, mSunHour);
 	LL_DEBUGS("Windlight Sync") << "Got region sun hour: " << mSunHour << LL_ENDL;
 
+	msg->getS32Fast(_PREHASH_RegionInfo2, _PREHASH_HardMaxAgents, mHardAgentLimit);
+
 	if (msg->has(_PREHASH_RegionInfo3))
 	{
 		msg->getU64Fast(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended, mRegionFlags);
diff --git a/indra/newview/llregioninfomodel.h b/indra/newview/llregioninfomodel.h
index ea9640efda99e81461f2df77fa5c3fee7df53b4e..baeff82fefbf841a95718258638ea1cc96027af0 100644
--- a/indra/newview/llregioninfomodel.h
+++ b/indra/newview/llregioninfomodel.h
@@ -53,6 +53,8 @@ class LLRegionInfoModel : public LLSingleton<LLRegionInfoModel>
 	U8			mSimAccess;
 	U8			mAgentLimit;
 
+	S32			mHardAgentLimit;
+
 	U64			mRegionFlags;
 	U32			mEstateID;
 	U32			mParentEstateID;
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index cbcd905ab6e5d0a0790912e79fd8d97cc26a3f10..c44aca6fa500ad3c0b9031fd9cff1169a7f816c6 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -33,6 +33,7 @@
 
 // library includes
 #include "llcachename.h"
+#include "llavatarnamecache.h"
 #include "lldbstrings.h"
 #include "lleconomy.h"
 #include "llgl.h"
@@ -596,6 +597,12 @@ bool LLSelectMgr::linkObjects()
 		return true;
 	}
 
+	if (!LLSelectMgr::getInstance()->selectGetSameRegion())
+	{
+		LLNotificationsUtil::add("CannotLinkAcrossRegions");
+		return true;
+	}
+
 	LLSelectMgr::getInstance()->sendLink();
 
 	return true;
@@ -2760,6 +2767,35 @@ BOOL LLSelectMgr::selectGetRootsModify()
 	return TRUE;
 }
 
+//-----------------------------------------------------------------------------
+// selectGetSameRegion() - return TRUE if all objects are in same region
+//-----------------------------------------------------------------------------
+BOOL LLSelectMgr::selectGetSameRegion()
+{
+    if (getSelection()->isEmpty())
+    {
+        return TRUE;
+    }
+    LLViewerObject* object = getSelection()->getFirstObject();
+    if (!object)
+    {
+        return FALSE;
+    }
+    LLViewerRegion* current_region = object->getRegion();
+
+    for (LLObjectSelection::root_iterator iter = getSelection()->root_begin();
+        iter != getSelection()->root_end(); iter++)
+    {
+        LLSelectNode* node = *iter;
+        object = node->getObject();
+        if (!node->mValid || !object || current_region != object->getRegion())
+        {
+            return FALSE;
+        }
+    }
+
+    return TRUE;
+}
 
 //-----------------------------------------------------------------------------
 // selectGetNonPermanentEnforced() - return TRUE if all objects are not
@@ -5368,9 +5404,9 @@ void LLSelectMgr::processObjectPropertiesFamily(LLMessageSystem* msg, void** use
 		LLFloaterReporter *reporterp = LLFloaterReg::findTypedInstance<LLFloaterReporter>("reporter");
 		if (reporterp)
 		{
-			std::string fullname;
-			gCacheName->getFullName(owner_id, fullname);
-			reporterp->setPickedObjectProperties(name, fullname, owner_id);
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(owner_id, &av_name);
+			reporterp->setPickedObjectProperties(name, av_name.getUserName(), owner_id);
 		}
 	}
 	else if (request_flags & OBJECT_PAY_REQUEST)
@@ -6601,7 +6637,7 @@ void LLSelectMgr::updateSelectionCenter()
 	{
 		mSelectedObjects->mSelectType = getSelectTypeForObject(object);
 
-		if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid())
+		if (mSelectedObjects->mSelectType == SELECT_TYPE_ATTACHMENT && isAgentAvatarValid() && object->getParent() != NULL)
 		{
 			mPauseRequest = gAgentAvatarp->requestPause();
 		}
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index fbf889b2f1908f5ed12944430211f9ce2ed9ff00..e965dd80d5859135ed09f96d5601ae68e995e700 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -625,6 +625,9 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 	BOOL selectGetRootsModify();
 	BOOL selectGetModify();
 
+	// returns TRUE if all objects are in same region
+	BOOL selectGetSameRegion();
+
 	// returns TRUE if is all objects are non-permanent-enforced
 	BOOL selectGetRootsNonPermanentEnforced();
 	BOOL selectGetNonPermanentEnforced();
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 3e95811bb8bdb34af38f038e19e4124266369532..d6bf2164a0b6e03e47f26912b567718849422086 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -388,7 +388,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearab
 		return;
 	}
 
-	if (mEditWearable->getVisible() == visible && (!visible || mEditWearable->getWearable() != wearable))
+	if (mEditWearable->getVisible() == visible && (!visible || mEditWearable->getWearable() == wearable))
 	{
 		// visibility isn't changing and panel doesn't need an update, hence nothing to do
 		return;
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index af2173dd171da620bbbca184ad885fcf9bd700ef..3c58dd71946c225cd7bea922b63ca1c4df386fb8 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -46,6 +46,7 @@
 #include "llviewerobjectlist.h"
 #include "llexperiencecache.h"
 #include "lltrans.h"
+#include "llviewerregion.h"
 
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -327,9 +328,13 @@ void LLSidepanelItemInfo::refreshFromItem(LLViewerInventoryItem* item)
         LLTextBox* tb = getChild<LLTextBox>("LabelItemExperience");
         tb->setText(getString("loading_experience"));
         tb->setVisible(TRUE);
-
-        LLExperienceCache::instance().fetchAssociatedExperience(item->getParentUUID(), item->getUUID(), 
-            boost::bind(&LLSidepanelItemInfo::setAssociatedExperience, getDerivedHandle<LLSidepanelItemInfo>(), _1));
+        std::string url = std::string();
+        if(object && object->getRegion())
+        {
+            url = object->getRegion()->getCapability("GetMetadata");
+        }
+        LLExperienceCache::instance().fetchAssociatedExperience(item->getParentUUID(), item->getUUID(), url,
+                boost::bind(&LLSidepanelItemInfo::setAssociatedExperience, getDerivedHandle<LLSidepanelItemInfo>(), _1));
     }
     
 	//////////////////////
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index e7971028bf905ac32424926277034314ca29915e..19d1af34f9761ed1779590cb1cc7e572a4451913 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -29,6 +29,7 @@
 #include "llspeakers.h"
 
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llappviewer.h"
 #include "llimview.h"
 #include "llgroupmgr.h"
@@ -75,13 +76,13 @@ void LLSpeaker::lookupName()
 {
 	if (mDisplayName.empty())
 	{
-		gCacheName->get(mID, false, boost::bind(&LLSpeaker::onNameCache, this, _1, _2, _3));
+		LLAvatarNameCache::get(mID, boost::bind(&LLSpeaker::onNameCache, this, _1, _2)); // todo: can be group???
 	}
 }
 
-void LLSpeaker::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group)
+void LLSpeaker::onNameCache(const LLUUID& id, const LLAvatarName& av_name)
 {
-	mDisplayName = full_name;
+	mDisplayName = av_name.getUserName();
 }
 
 bool LLSpeaker::isInVoiceChannel()
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 617bae39844c3a3880031ab703ed7f87ea3ba8cf..d1dbf72fe9e9c363fbfe79c595c3d0118446e7d9 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -34,6 +34,7 @@
 #include "llcoros.h"
 
 class LLSpeakerMgr;
+class LLAvatarName;
 
 // data for a given participant in a voice channel
 class LLSpeaker : public LLRefCount, public LLOldEvents::LLObservable, public LLHandleProvider<LLSpeaker>, public boost::signals2::trackable
@@ -61,7 +62,7 @@ class LLSpeaker : public LLRefCount, public LLOldEvents::LLObservable, public LL
 	~LLSpeaker() {};
 	void lookupName();
 
-	void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
+	void onNameCache(const LLUUID& id, const LLAvatarName& full_name);
 
 	bool isInVoiceChannel();
 
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 19ec03f8375ebb126564d02d5743fe4a034f35aa..c3a3af091cd6232b51d2585bd3594d51e40e3937 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -56,6 +56,7 @@
 #include "llerrorcontrol.h"
 #include "llfloaterreg.h"
 #include "llfocusmgr.h"
+#include "llfloatergridstatus.h"
 #include "llfloaterimsession.h"
 #include "lllocationhistory.h"
 #include "llimageworker.h"
@@ -966,6 +967,8 @@ bool idle_startup()
 		// Load media plugin cookies
 		LLViewerMedia::loadCookieFile();
 
+		LLRenderMuteList::getInstance()->loadFromFile();
+
 		//-------------------------------------------------
 		// Handle startup progress screen
 		//-------------------------------------------------
@@ -1874,6 +1877,8 @@ bool idle_startup()
 
 		LLFloaterReg::showInitialVisibleInstances();
 
+		LLFloaterGridStatus::getInstance()->startGridStatusTimer();
+
 		display_startup();
 
 		display_startup();
diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp
index 78d9e92b5c68f3e977e1eb9d64d2a7eae18fb7f5..776ae2ece9d2200d9f72ce9d43d81a58cc82324d 100644
--- a/indra/newview/lltoastscripttextbox.cpp
+++ b/indra/newview/lltoastscripttextbox.cpp
@@ -28,31 +28,21 @@
 
 #include "lltoastscripttextbox.h"
 
-#include "llfocusmgr.h"
-
-#include "llbutton.h"
+#include "lllslconstants.h"
 #include "llnotifications.h"
-#include "llviewertexteditor.h"
-
-#include "llavatarnamecache.h"
-#include "lluiconstants.h"
-#include "llui.h"
-#include "llviewercontrol.h"
-#include "lltrans.h"
 #include "llstyle.h"
+#include "lluiconstants.h"
+#include "llviewertexteditor.h"
 
-#include "llglheaders.h"
-#include "llagent.h"
-
-const S32 LLToastScriptTextbox::DEFAULT_MESSAGE_MAX_LINE_COUNT= 7;
+const S32 LLToastScriptTextbox::DEFAULT_MESSAGE_MAX_LINE_COUNT= 14;
 
 LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification)
 :	LLToastPanel(notification)
 {
 	buildFromFile( "panel_notify_textbox.xml");
 
-	LLTextEditor* text_editorp = getChild<LLTextEditor>("text_editor_box");
-	text_editorp->setValue(notification->getMessage());
+	mInfoText = getChild<LLTextBox>("text_editor_box");
+	mInfoText->setValue(notification->getMessage());
 
 	getChild<LLButton>("ignore_btn")->setClickedCallback(boost::bind(&LLToastScriptTextbox::onClickIgnore, this));
 
@@ -73,13 +63,7 @@ LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification
 	pSubmitBtn->setClickedCallback((boost::bind(&LLToastScriptTextbox::onClickSubmit, this)));
 	setDefaultBtn(pSubmitBtn);
 
-	S32 maxLinesCount;
-	std::istringstream ss( getString("message_max_lines_count") );
-	if (!(ss >> maxLinesCount))
-	{
-		maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT;
-	}
-	//snapToMessageHeight(pMessageText, maxLinesCount);
+	snapToMessageHeight();
 }
 
 // virtual
@@ -92,7 +76,6 @@ void LLToastScriptTextbox::close()
 	die();
 }
 
-#include "lllslconstants.h"
 void LLToastScriptTextbox::onClickSubmit()
 {
 	LLViewerTextEditor* pMessageText = getChild<LLViewerTextEditor>("message");
@@ -119,3 +102,29 @@ void LLToastScriptTextbox::onClickIgnore()
 	mNotification->respond(response);
 	close();
 }
+
+void LLToastScriptTextbox::snapToMessageHeight()
+{
+	LLPanel* info_pan = getChild<LLPanel>("info_panel");
+	if (!info_pan)
+	{
+		return;
+	}
+
+	S32 maxLinesCount;
+	std::istringstream ss( getString("message_max_lines_count") );
+	if (!(ss >> maxLinesCount))
+	{
+		maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT;
+	}
+
+
+	S32 maxTextHeight = (mInfoText->getFont()->getLineHeight() * maxLinesCount);
+	S32 oldTextHeight = mInfoText->getRect().getHeight();
+	S32 newTextHeight = llmin(mInfoText->getTextBoundingRect().getHeight(), maxTextHeight);
+
+	S32 heightDelta = newTextHeight - oldTextHeight;
+
+	reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT));
+	info_pan->reshape(info_pan->getRect().getWidth(),newTextHeight);
+}
diff --git a/indra/newview/lltoastscripttextbox.h b/indra/newview/lltoastscripttextbox.h
index 7d334462483a317d09c9d5ed717115431b57c288..7aee02dd00e4265c7d2f776a02bdd83a867975ed 100644
--- a/indra/newview/lltoastscripttextbox.h
+++ b/indra/newview/lltoastscripttextbox.h
@@ -48,9 +48,12 @@ class LLToastScriptTextbox
 
 private:
 
+	LLTextBox* mInfoText;
+
 	void onClickSubmit();
 	void onClickIgnore();
 
+	void snapToMessageHeight();
 	static const S32 DEFAULT_MESSAGE_MAX_LINE_COUNT;
 };
 
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 27c4c9085752400890e5ab5c5d118dba5a64ba43..49436ee4066a6f78f753896ba24e42cfaa4261b9 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1584,12 +1584,12 @@ static void show_object_sharing_confirmation(const std::string name,
 }
 
 static void get_name_cb(const LLUUID& id,
-						const std::string& full_name,
+						const LLAvatarName& av_name,
 						LLInventoryObject* inv_obj,
 						const LLSD& dest,
 						const LLUUID& dest_agent)
 {
-	show_object_sharing_confirmation(full_name,
+	show_object_sharing_confirmation(av_name.getUserName(),
 								     inv_obj,
 								     dest,
 						  		     id,
@@ -1634,17 +1634,17 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_
 				// If no IM session found get the destination agent's name by id.
 				if (NULL == session)
 				{
-					std::string fullname;
+					LLAvatarName av_name;
 
 					// If destination agent's name is found in cash proceed to showing the confirmation dialog.
 					// Otherwise set up a callback to show the dialog when the name arrives.
-					if (gCacheName->getFullName(dest_agent, fullname))
+					if (LLAvatarNameCache::get(dest_agent, &av_name))
 					{
-						show_object_sharing_confirmation(fullname, inv_obj, dest, dest_agent, LLUUID::null);
+						show_object_sharing_confirmation(av_name.getUserName(), inv_obj, dest, dest_agent, LLUUID::null);
 					}
 					else
 					{
-						gCacheName->get(dest_agent, false, boost::bind(&get_name_cb, _1, _2, inv_obj, dest, dest_agent));
+						LLAvatarNameCache::get(dest_agent, boost::bind(&get_name_cb, _1, _2, inv_obj, dest, dest_agent));
 					}
 
 					return true;
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index e79ce55854c90173c41247c376f531bd78f0f184..fc052ae3aaa445bd7ced8e998dfa67fbe2e8beb0 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -893,14 +893,19 @@ BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
 				line.append(LLTrans::getString("RetrievingData"));
 			}
 		}
-		else if(gCacheName->getFullName(owner, name))
-		{
-			line.append(name);
-		}
-		else
-		{
-			line.append(LLTrans::getString("RetrievingData"));
-		}
+        else
+        {
+            LLAvatarName av_name;
+            if (LLAvatarNameCache::get(owner, &av_name))
+            {
+                name = av_name.getUserName();
+                line.append(name);
+            }
+            else
+            {
+                line.append(LLTrans::getString("RetrievingData"));
+            }
+        }
 	}
 	else
 	{
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 13eccaefc1c422044624fb10307e74a9941e7fd9..960a36a251a717b81532962985937f6bf645467f 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -220,9 +220,9 @@ void display_stats()
 	F32 mem_log_freq = gSavedSettings.getF32("MemoryLogFrequency");
 	if (mem_log_freq > 0.f && gRecentMemoryTime.getElapsedTimeF32() >= mem_log_freq)
 	{
-		gMemoryAllocated = (U64Bytes)LLMemory::getCurrentRSS();
+		gMemoryAllocated = U64Bytes(LLMemory::getCurrentRSS());
 		U32Megabytes memory = gMemoryAllocated;
-		LL_INFOS() << llformat("MEMORY: %d MB", memory.value()) << LL_ENDL;
+		LL_INFOS() << "MEMORY: " << memory << LL_ENDL;
 		LLMemory::logMemoryInfo(TRUE) ;
 		gRecentMemoryTime.reset();
 	}
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index ec7a81584aa6fa0fa9126d4917d24b28de257aaa..cf18299b0b54b931a1797d7937811c097dbca8f3 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -38,6 +38,7 @@
 #include "llfloaterautoreplacesettings.h"
 #include "llfloateravatar.h"
 #include "llfloateravatarpicker.h"
+#include "llfloateravatarrendersettings.h"
 #include "llfloateravatartextures.h"
 #include "llfloaterbigpreview.h"
 #include "llfloaterbeacons.h"
@@ -70,6 +71,7 @@
 #include "llfloaterfonttest.h"
 #include "llfloatergesture.h"
 #include "llfloatergodtools.h"
+#include "llfloatergridstatus.h"
 #include "llfloatergroups.h"
 #include "llfloaterhelpbrowser.h"
 #include "llfloaterhoverheight.h"
@@ -193,6 +195,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("auction", "floater_auction.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAuction>);
 	LLFloaterReg::add("avatar", "floater_avatar.xml",  (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatar>);
 	LLFloaterReg::add("avatar_picker", "floater_avatar_picker.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarPicker>);
+	LLFloaterReg::add("avatar_render_settings", "floater_avatar_render_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarRenderSettings>);
 	LLFloaterReg::add("avatar_textures", "floater_avatar_textures.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterAvatarTextures>);
 
 	LLFloaterReg::add("beacons", "floater_beacons.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBeacons>);
@@ -231,6 +234,7 @@ void LLViewerFloaterReg::registerFloaters()
 
 	LLFloaterReg::add("gestures", "floater_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGesture>);
 	LLFloaterReg::add("god_tools", "floater_god_tools.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGodTools>);
+	LLFloaterReg::add("grid_status", "floater_grid_status.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGridStatus>);
 	LLFloaterReg::add("group_picker", "floater_choose_group.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterGroupPicker>);
 
 	LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index caffeadb73f61d508e8f0602fd60bb581f582b19..bf79a0595ce31e5862777bbf525137370919b9f8 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1126,10 +1126,10 @@ void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
 void create_inventory_callingcard(const LLUUID& avatar_id, const LLUUID& parent /*= LLUUID::null*/, LLPointer<LLInventoryCallback> cb/*=NULL*/)
 {
 	std::string item_desc = avatar_id.asString();
-	std::string item_name;
-	gCacheName->getFullName(avatar_id, item_name);
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(avatar_id, &av_name);
 	create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
-						  parent, LLTransactionID::tnull, item_name, item_desc, LLAssetType::AT_CALLINGCARD,
+						  parent, LLTransactionID::tnull, av_name.getUserName(), item_desc, LLAssetType::AT_CALLINGCARD,
 						  LLInventoryType::IT_CALLINGCARD, NOT_WEARABLE, PERM_MOVE | PERM_TRANSFER, cb);
 }
 
@@ -2071,9 +2071,9 @@ PermissionMask LLViewerInventoryItem::getPermissionMask() const
 
 //----------
 
-void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const std::string& name, bool is_group)
+void LLViewerInventoryItem::onCallingCardNameLookup(const LLUUID& id, const LLAvatarName& name)
 {
-	rename(name);
+	rename(name.getUserName());
 	gInventory.addChangedMask(LLInventoryObserver::LABEL, getUUID());
 	gInventory.notifyObservers();
 }
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 074d51b8b3661bba68920ad485de44b94fabb947..b3053e365bd2ce49a052338b9947b8636486bbe7 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -39,6 +39,7 @@ class LLFolderView;
 class LLFolderBridge;
 class LLViewerInventoryCategory;
 class LLInventoryCallback;
+class LLAvatarName;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLViewerInventoryItem
@@ -158,7 +159,7 @@ class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::tr
 	PermissionMask getPermissionMask() const;
 
 	// callback
-	void onCallingCardNameLookup(const LLUUID& id, const std::string& name, bool is_group);
+	void onCallingCardNameLookup(const LLUUID& id, const LLAvatarName& name);
 
 	// If this is a broken link, try to fix it and any other identical link.
 	BOOL regenerateLink();
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 9f05ee61bde4c3ddd0f52586842890ef8efc7be2..900075488f4fe776150998ef78dcb197e2e1f286 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -604,7 +604,9 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 	LLPluginProcessParent::setUseReadThread(gSavedSettings.getBOOL("PluginUseReadThread"));
 
 	// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
-	createSpareBrowserMediaSource();
+	// 2017-04-19 Removed CP - this doesn't appear to buy us much and consumes a lot of resources so
+	// removing it for now.
+	//createSpareBrowserMediaSource();
 
 	sAnyMediaShowing = false;
 	sAnyMediaPlaying = false;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index b00caf55920eb5bdf29b00bd234d9fd66de4e494..f346f48ef5ff102d6c2211cc527be2d48684c3ae 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -4161,27 +4161,6 @@ class LLViewToggleUI : public view_listener_t
 	}
 };
 
-class LLEditDuplicate : public view_listener_t
-{
-	bool handleEvent(const LLSD& userdata)
-	{
-		if(LLEditMenuHandler::gEditMenuHandler)
-		{
-			LLEditMenuHandler::gEditMenuHandler->duplicate();
-		}
-		return true;
-	}
-};
-
-class LLEditEnableDuplicate : public view_listener_t
-{
-	bool handleEvent(const LLSD& userdata)
-	{
-		bool new_value = LLEditMenuHandler::gEditMenuHandler && LLEditMenuHandler::gEditMenuHandler->canDuplicate();
-		return new_value;
-	}
-};
-
 void handle_duplicate_in_place(void*)
 {
 	LL_INFOS() << "handle_duplicate_in_place" << LL_ENDL;
@@ -6544,10 +6523,10 @@ class LLMuteParticle : public view_listener_t
 		
 		if (id.notNull())
 		{
-			std::string name;
-			gCacheName->getFullName(id, name);
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(id, &av_name);
 
-			LLMute mute(id, name, LLMute::AGENT);
+			LLMute mute(id, av_name.getUserName(), LLMute::AGENT);
 			if (LLMuteList::getInstance()->isMuted(mute.mID))
 			{
 				LLMuteList::getInstance()->remove(mute);
@@ -8386,6 +8365,15 @@ class LLToolsSelectTool : public view_listener_t
 		{
 			LLToolMgr::getInstance()->getCurrentToolset()->selectToolByIndex(5);
 		}
+
+		// Note: if floater is not visible LLViewerWindow::updateLayout() will
+		// attempt to open it, but it won't bring it to front or de-minimize.
+		if (gFloaterTools && (gFloaterTools->isMinimized() || !gFloaterTools->isShown() || !gFloaterTools->isFrontmost()))
+		{
+			gFloaterTools->setMinimized(FALSE);
+			gFloaterTools->openFloater();
+			gFloaterTools->setVisibleAndFrontmost(TRUE);
+		}
 		return true;
 	}
 };
@@ -8602,7 +8590,12 @@ class LLUploadCostCalculator : public view_listener_t
 
 void handle_voice_morphing_subscribe()
 {
-	LLWeb::loadURLExternal(LLTrans::getString("voice_morphing_url"));
+	LLWeb::loadURL(LLTrans::getString("voice_morphing_url"));
+}
+
+void handle_premium_voice_morphing_subscribe()
+{
+	LLWeb::loadURL(LLTrans::getString("premium_voice_morphing_url"));
 }
 
 class LLToggleUIHints : public view_listener_t
@@ -8680,7 +8673,6 @@ void initialize_edit_menu()
 	view_listener_t::addMenu(new LLEditDelete(), "Edit.Delete");
 	view_listener_t::addMenu(new LLEditSelectAll(), "Edit.SelectAll");
 	view_listener_t::addMenu(new LLEditDeselect(), "Edit.Deselect");
-	view_listener_t::addMenu(new LLEditDuplicate(), "Edit.Duplicate");
 	view_listener_t::addMenu(new LLEditTakeOff(), "Edit.TakeOff");
 	view_listener_t::addMenu(new LLEditEnableUndo(), "Edit.EnableUndo");
 	view_listener_t::addMenu(new LLEditEnableRedo(), "Edit.EnableRedo");
@@ -8690,7 +8682,6 @@ void initialize_edit_menu()
 	view_listener_t::addMenu(new LLEditEnableDelete(), "Edit.EnableDelete");
 	view_listener_t::addMenu(new LLEditEnableSelectAll(), "Edit.EnableSelectAll");
 	view_listener_t::addMenu(new LLEditEnableDeselect(), "Edit.EnableDeselect");
-	view_listener_t::addMenu(new LLEditEnableDuplicate(), "Edit.EnableDuplicate");
 
 }
 
@@ -8798,6 +8789,8 @@ void initialize_menus()
 
 	// Communicate > Voice morphing > Subscribe...
 	commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe));
+	// Communicate > Voice morphing > Premium perk...
+	commit.add("Communicate.VoiceMorphing.PremiumPerk", boost::bind(&handle_premium_voice_morphing_subscribe));
 	LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance();
 	enable.add("Communicate.VoiceMorphing.NoVoiceMorphing.Check"
 		, boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing"));
@@ -9098,6 +9091,7 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLObjectAttachToAvatar(true), "Object.AttachToAvatar");
 	view_listener_t::addMenu(new LLObjectAttachToAvatar(false), "Object.AttachAddToAvatar");
 	view_listener_t::addMenu(new LLObjectReturn(), "Object.Return");
+	commit.add("Object.Duplicate", boost::bind(&LLSelectMgr::duplicate, LLSelectMgr::getInstance()));
 	view_listener_t::addMenu(new LLObjectReportAbuse(), "Object.ReportAbuse");
 	view_listener_t::addMenu(new LLObjectMute(), "Object.Mute");
 
@@ -9119,6 +9113,7 @@ void initialize_menus()
 	enable.add("Object.EnableSit", boost::bind(&enable_object_sit, _1));
 
 	view_listener_t::addMenu(new LLObjectEnableReturn(), "Object.EnableReturn");
+	enable.add("Object.EnableDuplicate", boost::bind(&LLSelectMgr::canDuplicate, LLSelectMgr::getInstance()));
 	view_listener_t::addMenu(new LLObjectEnableReportAbuse(), "Object.EnableReportAbuse");
 
 	enable.add("Avatar.EnableMute", boost::bind(&enable_object_mute));
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 2ab59037e1d55d605162fdd0902210a34386cedf..992470cb3ae59162bf7a8fcb7c065fea36a18743 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1390,6 +1390,14 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
 			gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id));
 }
 
+
+void inventory_offer_mute_avatar_callback(const LLUUID& blocked_id,
+    const LLAvatarName& av_name)
+{
+    inventory_offer_mute_callback(blocked_id, av_name.getUserName(), false);
+}
+
+
 std::string LLOfferInfo::mResponderType = "offer_info";
 
 LLOfferInfo::LLOfferInfo()
@@ -1538,7 +1546,14 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 	{
 		if (notification_ptr != NULL)
 		{
-			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
+			if (mFromGroup)
+			{
+				gCacheName->getGroup(mFromID, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
+			}
+			else
+			{
+				LLAvatarNameCache::get(mFromID, boost::bind(&inventory_offer_mute_avatar_callback, _1, _2));
+			}
 		}
 	}
 
@@ -1695,7 +1710,14 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 		llassert(notification_ptr != NULL);
 		if (notification_ptr != NULL)
 		{
-			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
+			if (mFromGroup)
+			{
+				gCacheName->getGroup(mFromID, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
+			}
+			else
+			{
+				LLAvatarNameCache::get(mFromID, boost::bind(&inventory_offer_mute_avatar_callback, _1, _2));
+			}
 		}
 	}
 	
@@ -1744,12 +1766,12 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 		}
 		else
 		{
-			std::string full_name;
-			if (gCacheName->getFullName(mFromID, full_name))
+			LLAvatarName av_name;
+			if (LLAvatarNameCache::get(mFromID, &av_name))
 			{
 				from_string = LLTrans::getString("InvOfferAnObjectNamed") + " "+ LLTrans::getString("'") + mFromName 
-					+ LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + full_name;
-				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + full_name;
+					+ LLTrans::getString("'")+" " + LLTrans::getString("InvOfferOwnedBy") + av_name.getUserName();
+				chatHistory_string = mFromName + " " + LLTrans::getString("InvOfferOwnedBy") + " " + av_name.getUserName();
 			}
 			else
 			{
@@ -2601,9 +2623,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			{
 				original_name = original_name.substr(0, index);
 			}
+
 			std::string legacy_name = gCacheName->buildLegacyName(original_name);
-			LLUUID agent_id;
-			gCacheName->getUUID(legacy_name, agent_id);
+			LLUUID agent_id = LLAvatarNameCache::findIdByName(legacy_name);
 
 			if (agent_id.isNull())
 			{
@@ -2662,6 +2684,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				payload["subject"] = subj;
 				payload["message"] = mes;
 				payload["sender_name"] = name;
+				payload["sender_id"] = agent_id;
 				payload["group_id"] = group_id;
 				payload["inventory_name"] = item_name;
  				payload["received_time"] = LLDate::now();
@@ -3038,16 +3061,17 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			{ 
 				return;
 			}
-			else if (is_do_not_disturb) 
-			{
-				send_do_not_disturb_message(msg, from_id);
-			}
 			else if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL))
 			{
 				return;
 			}
 			else
 			{
+				if (is_do_not_disturb)
+				{
+					send_do_not_disturb_message(msg, from_id);
+				}
+
 				LLVector3 pos, look_at;
 				U64 region_handle(0);
 				U8 region_access(SIM_ACCESS_MIN);
@@ -6182,7 +6206,7 @@ void handle_show_mean_events(void *)
 	//LLFloaterBump::showInstance();
 }
 
-void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_group)
+void mean_name_callback(const LLUUID &id, const LLAvatarName& av_name)
 {
 	static const U32 max_collision_list_size = 20;
 	if (gMeanCollisionList.size() > max_collision_list_size)
@@ -6199,7 +6223,7 @@ void mean_name_callback(const LLUUID &id, const std::string& full_name, bool is_
 		LLMeanCollisionData *mcd = *iter;
 		if (mcd->mPerp == id)
 		{
-			mcd->mFullName = full_name;
+			mcd->mFullName = av_name.getUserName();
 		}
 	}
 }
@@ -6253,7 +6277,7 @@ void process_mean_collision_alert_message(LLMessageSystem *msgsystem, void **use
 		{
 			LLMeanCollisionData *mcd = new LLMeanCollisionData(gAgentID, perp, time, type, mag);
 			gMeanCollisionList.push_front(mcd);
-			gCacheName->get(perp, false, boost::bind(&mean_name_callback, _1, _2, _3));
+			LLAvatarNameCache::get(perp, boost::bind(&mean_name_callback, _1, _2));
 		}
 	}
 	LLFloaterBump* bumps_floater = LLFloaterBump::getInstance();
@@ -7030,10 +7054,10 @@ void send_lures(const LLSD& notification, const LLSD& response)
 
 		// Record the offer.
 		{
-			std::string target_name;
-			gCacheName->getFullName(target_id, target_name);  // for im log filenames
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(target_id, &av_name);  // for im log filenames
 			LLSD args;
-			args["TO_NAME"] = LLSLURL("agent", target_id, "displayname").getSLURLString();;
+			args["TO_NAME"] = LLSLURL("agent", target_id, "completename").getSLURLString();;
 	
 			LLSD payload;
 				
@@ -7116,10 +7140,10 @@ bool teleport_request_callback(const LLSD& notification, const LLSD& response)
 		return false;
 	}
 
-	std::string from_name;
-	gCacheName->getFullName(from_id, from_name);
+	LLAvatarName av_name;
+	LLAvatarNameCache::get(from_id, &av_name);
 
-	if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::getInstance()->isLinden(from_name))
+	if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::getInstance()->isLinden(av_name.getUserName()))
 	{
 		return false;
 	}
@@ -7394,8 +7418,7 @@ bool callback_load_url(const LLSD& notification, const LLSD& response)
 }
 static LLNotificationFunctorRegistration callback_load_url_reg("LoadWebPage", callback_load_url);
 
-
-// We've got the name of the person who owns the object hurling the url.
+// We've got the name of the person or group that owns the object hurling the url.
 // Display confirmation dialog.
 void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool is_group)
 {
@@ -7437,6 +7460,12 @@ void callback_load_url_name(const LLUUID& id, const std::string& full_name, bool
 	}
 }
 
+// We've got the name of the person who owns the object hurling the url.
+void callback_load_url_avatar_name(const LLUUID& id, const LLAvatarName& av_name)
+{
+    callback_load_url_name(id, av_name.getUserName(), false);
+}
+
 void process_load_url(LLMessageSystem* msg, void**)
 {
 	LLUUID object_id;
@@ -7474,8 +7503,14 @@ void process_load_url(LLMessageSystem* msg, void**)
 	// Add to list of pending name lookups
 	gLoadUrlList.push_back(payload);
 
-	gCacheName->get(owner_id, owner_is_group,
-		boost::bind(&callback_load_url_name, _1, _2, _3));
+	if (owner_is_group)
+	{
+		gCacheName->getGroup(owner_id, boost::bind(&callback_load_url_name, _1, _2, _3));
+	}
+	else
+	{
+		LLAvatarNameCache::get(owner_id, boost::bind(&callback_load_url_avatar_name, _1, _2));
+	}
 }
 
 
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index f52c82dab7db50ecd37f3d104264ff20e3df3fc0..b907783b1fdedf938a830d3bf92b8d5eeb948eba 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -491,6 +491,7 @@ void send_stats()
 	system["ram"] = (S32) gSysMemory.getPhysicalMemoryKB().value();
 	system["os"] = LLAppViewer::instance()->getOSInfo().getOSStringSimple();
 	system["cpu"] = gSysCPU.getCPUString();
+	system["address_size"] = ADDRESS_SIZE;
 	unsigned char MACAddress[MAC_ADDRESS_BYTES];
 	LLUUID::getNodeID(MACAddress);
 	std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x",
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index d7080051dabdfd007643cabff951e9c19b9bb19c..0a3012ffefe568fc644fc688bd0ac27166c9a4a6 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1341,9 +1341,9 @@ LLPointer<LLImageJ2C> LLViewerTextureList::convertToUploadFile(LLPointer<LLImage
 // Returns min setting for TextureMemory (in MB)
 S32Megabytes LLViewerTextureList::getMinVideoRamSetting()
 {
-	S32Megabytes system_ram = gSysMemory.getPhysicalMemoryClamped();
+	U32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB();
 	//min texture mem sets to 64M if total physical mem is more than 1.5GB
-	return (system_ram > S32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ;
+	return (system_ram > U32Megabytes(1500)) ? S32Megabytes(64) : gMinVideoRam ;
 }
 
 //static
@@ -1386,7 +1386,7 @@ S32Megabytes LLViewerTextureList::getMaxVideoRamSetting(bool get_recommended, fl
 		LL_WARNS() << "VRAM amount not detected, defaulting to " << max_texmem << " MB" << LL_ENDL;
 	}
 
-	S32Megabytes system_ram = gSysMemory.getPhysicalMemoryClamped(); // In MB
+	S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB(); // In MB
 	//LL_INFOS() << "*** DETECTED " << system_ram << " MB of system memory." << LL_ENDL;
 	if (get_recommended)
 		max_texmem = llmin(max_texmem, system_ram/2);
@@ -1439,7 +1439,7 @@ void LLViewerTextureList::updateMaxResidentTexMem(S32Megabytes mem)
 	}
 
 	//system mem
-	S32Megabytes system_ram = gSysMemory.getPhysicalMemoryClamped();
+	S32Megabytes system_ram = gSysMemory.getPhysicalMemoryKB();
 
 	//minimum memory reserved for non-texture use.
 	//if system_raw >= 1GB, reserve at least 512MB for non-texture use;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 7a60a8e9ac330c1d3dd53dd7297cac467f9b1fc1..feed5ba43dd1bf7e9c017b929e7a349036212ff5 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -53,6 +53,7 @@
 #include "llrender.h"
 
 #include "llvoiceclient.h"	// for push-to-talk button handling
+#include "stringize.h"
 
 //
 // TODO: Many of these includes are unnecessary.  Remove them.
@@ -394,7 +395,8 @@ class LLDebugText
 #if LL_WINDOWS
 		if (gSavedSettings.getBOOL("DebugShowMemory"))
 		{
-			addText(xpos, ypos, llformat("Memory: %d (KB)", LLMemory::getWorkingSetSize() / 1024)); 
+			addText(xpos, ypos,
+					STRINGIZE("Memory: " << (LLMemory::getCurrentRSS() / 1024) << " (KB)"));
 			ypos += y_inc;
 		}
 #endif
@@ -2724,8 +2726,16 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 			return TRUE;
 		}
 
-		if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
-			||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)))
+		if (gAgent.isInitialized()
+			&& (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL)
+			&& gMenuBarView
+			&& gMenuBarView->handleAcceleratorKey(key, mask))
+		{
+			LLViewerEventRecorder::instance().logKeyEvent(key, mask);
+			return TRUE;
+		}
+
+		if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))
 		{
 			LLViewerEventRecorder::instance().logKeyEvent(key,mask);
 			return TRUE;
@@ -2855,8 +2865,16 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	}
 
 	// give menus a chance to handle unmodified accelerator keys
-	if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
-		||(gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask)))
+	if (gAgent.isInitialized()
+		&& (gAgent.getTeleportState() == LLAgent::TELEPORT_NONE || gAgent.getTeleportState() == LLAgent::TELEPORT_LOCAL)
+		&& gMenuBarView
+		&& gMenuBarView->handleAcceleratorKey(key, mask))
+	{
+		LLViewerEventRecorder::instance().logKeyEvent(key, mask);
+		return TRUE;
+	}
+
+	if (gLoginMenuBarView && gLoginMenuBarView->handleAcceleratorKey(key, mask))
 	{
 		return TRUE;
 	}
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 8888879b8a93c7d71a1e44dbf4a764849f166a70..f6a16f7da1af3d400fd6ec8828ab0d54c5b70149 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -727,6 +727,8 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	{
 	    LLSceneMonitor::getInstance()->freezeAvatar((LLCharacter*)this);
 	}
+
+	mVisuallyMuteSetting = LLVOAvatar::VisualMuteSettings(LLRenderMuteList::getInstance()->getSavedVisualMuteSetting(getID()));
 }
 
 std::string LLVOAvatar::avString() const
@@ -7074,7 +7076,9 @@ BOOL LLVOAvatar::isFullyLoaded() const
 bool LLVOAvatar::isTooComplex() const
 {
 	bool too_complex;
-	if (isSelf() || mVisuallyMuteSetting == AV_ALWAYS_RENDER)
+	bool render_friend =  (LLAvatarTracker::instance().isBuddy(getID()) && gSavedSettings.getBOOL("AlwaysRenderFriends"));
+
+	if (isSelf() || render_friend || mVisuallyMuteSetting == AV_ALWAYS_RENDER)
 	{
 		too_complex = false;
 	}
@@ -9232,8 +9236,9 @@ void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)
 {
     mVisuallyMuteSetting = set;
     mNeedsImpostorUpdate = TRUE;
-}
 
+    LLRenderMuteList::getInstance()->saveVisualMuteSetting(getID(), S32(set));
+}
 
 void LLVOAvatar::calcMutedAVColor()
 {
diff --git a/indra/newview/llwindebug.cpp b/indra/newview/llwindebug.cpp
index eff70ca0b2853bd3aab295aa6356cea3a0370aef..92c80ce53412f744d83ae4c66922eb01d528e7c2 100644
--- a/indra/newview/llwindebug.cpp
+++ b/indra/newview/llwindebug.cpp
@@ -90,7 +90,7 @@ LONG NTAPI vectoredHandler(PEXCEPTION_POINTERS exception_infop)
 }
 
 // static
-void  LLWinDebug::init()
+void  LLWinDebug::initSingleton()
 {
 	static bool s_first_run = true;
 	// Load the dbghelp dll now, instead of waiting for the crash.
@@ -135,7 +135,7 @@ void  LLWinDebug::init()
 	}
 }
 
-void LLWinDebug::cleanup ()
+void LLWinDebug::cleanupSingleton()
 {
 	gEmergencyMemoryReserve.release();
 }
diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h
index 90882cf04a099baf97a8afb396f73f5ac90c5f9a..7e5818ba1c1d6bf4992e137a99972b3023f451a3 100644
--- a/indra/newview/llwindebug.h
+++ b/indra/newview/llwindebug.h
@@ -36,9 +36,9 @@ class LLWinDebug:
 {
 	LLSINGLETON_EMPTY_CTOR(LLWinDebug);
 public:
-	static void init();
+	void initSingleton();
 	static void generateMinidump(struct _EXCEPTION_POINTERS *pExceptionInfo = NULL);
-	static void cleanup();
+	void cleanupSingleton();
 private:
 	static void writeDumpToFile(MINIDUMP_TYPE type, MINIDUMP_EXCEPTION_INFORMATION *ExInfop, const std::string& filename);
 };
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 760c294f9019b3d2675743a89a2b6d3cc55f229c..d757e393669b1b582f2d1644bd4bff0eef43e419 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -136,6 +136,7 @@ with the same filename but different name
   <texture name="Command_Facebook_Icon"     file_name="toolbar_icons/facebook.png"     preload="true" />
   <texture name="Command_Flickr_Icon"       file_name="toolbar_icons/flickr.png"       preload="true" />
   <texture name="Command_Gestures_Icon"     file_name="toolbar_icons/gestures.png"     preload="true" />
+  <texture name="Command_Grid_Status_Icon"  file_name="toolbar_icons/grid_status.png"  preload="true" />
   <texture name="Command_HowTo_Icon"        file_name="toolbar_icons/howto.png"        preload="true" />
   <texture name="Command_Inventory_Icon"    file_name="toolbar_icons/inventory.png"    preload="true" />
   <texture name="Command_Map_Icon"          file_name="toolbar_icons/map.png"          preload="true" />
diff --git a/indra/newview/skins/default/textures/toolbar_icons/grid_status.png b/indra/newview/skins/default/textures/toolbar_icons/grid_status.png
new file mode 100644
index 0000000000000000000000000000000000000000..b92b93cfb443f47237149ed001bc6386ad851865
Binary files /dev/null and b/indra/newview/skins/default/textures/toolbar_icons/grid_status.png differ
diff --git a/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..03e812d36d04612b89056f3d49dc6aa1f3863ae7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_avatar_render_settings.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+<floater
+ can_resize="true"
+ positioning="cascading"
+ height="200"
+ min_height="100"
+ min_width="230"
+ layout="topleft"
+ name="floater_avatar_render_settings"
+ save_rect="true"
+ single_instance="true"
+ reuse_instance="true"
+ title="AVATAR RENDER SETTINGS"
+ width="300">
+    <string
+     name="av_never_render"
+     value="Never"/>
+    <string
+     name="av_always_render"
+     value="Always"/>
+    <filter_editor
+     follows="left|top|right"
+     height="23"
+     layout="topleft"
+     left="8"
+     right="-47"
+     label="Filter People"
+     max_length_chars="300"
+     name="people_filter_input"
+     text_color="Black"
+     text_pad_left="10"
+     top="4" />
+    <menu_button
+     follows="top|right"
+     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_pad="7"
+     menu_filename="menu_avatar_rendering_settings_add.xml"
+     menu_position="bottomleft"
+     name="plus_btn"
+     tool_tip="Actions on selected person"
+     top="3"
+     width="31" />
+    <name_list
+     bottom="-8"
+     draw_heading="true"
+     follows="all"
+     left="8"
+     multi_select="false"
+     name="render_settings_list"
+     right="-8"
+     top="32">
+        <name_list.columns
+         label="Name"
+         name="name"
+         relative_width="0.65" />
+        <name_list.columns
+         label="Render setting"
+         name="setting"
+         relative_width="0.35" />
+     </name_list>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_flickr.xml b/indra/newview/skins/default/xui/en/floater_flickr.xml
index 52ef16c7e8b51114681d1c9741f5511cbfc18294..3b9c4894c17076fb3bfe3d525f57a3e5d2ca29c0 100644
--- a/indra/newview/skins/default/xui/en/floater_flickr.xml
+++ b/indra/newview/skins/default/xui/en/floater_flickr.xml
@@ -9,7 +9,7 @@
   save_rect="true"
   single_instance="true"
   reuse_instance="true"
-  title="UPLOAD TO FLICKR"
+  title="SHARE TO FLICKR"
   height="590"
   width="272">
   <panel
diff --git a/indra/newview/skins/default/xui/en/floater_grid_status.xml b/indra/newview/skins/default/xui/en/floater_grid_status.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b97bd8056dc5e347707c332e61bd5e572a15309d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_grid_status.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+  positioning="cascading"
+  legacy_header_height="18"
+  can_resize="true"
+  height="775"
+  layout="topleft"
+  min_height="485"
+  min_width="485"
+  name="floater_grid_status"
+  help_topic="floater_grid_status"
+  save_rect="true"
+  save_visibility="true"
+  title=""
+  initial_mime_type="text/html"
+  width="780"
+  tab_stop="true"
+  filename="floater_web_content.xml"/>
diff --git a/indra/newview/skins/default/xui/en/floater_tos.xml b/indra/newview/skins/default/xui/en/floater_tos.xml
index 590d9d18442715467bcc13462aa9af770e2990cb..612c894b590c67f91676036b8497ad22d424d532 100644
--- a/indra/newview/skins/default/xui/en/floater_tos.xml
+++ b/indra/newview/skins/default/xui/en/floater_tos.xml
@@ -70,7 +70,7 @@
      top="32"
      word_wrap="true"
      width="552">
-       You will need to go to my.secondlife.com and log in to accept the Terms of Service before you can proceed. Thank you!
+       You will need to go to https://my.secondlife.com and log in to accept the Terms of Service before you can proceed. Thank you!
      </text>
     <web_browser
       trusted_content="true" 
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index 2f60bab0b7e7fa36ca63455994e8d8cf90b49d52..49b9ac273d9fa7415dcc8b28aff154f50af7c601 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -130,10 +130,13 @@
    </menu_item_call>
 
    <menu_item_separator />
-    
+      <context_menu
+       label="Render Avatar"
+       layout="topleft"
+        name="Render Avatar">
       <menu_item_check
         name="RenderNormally"
-        label="Render Normally">
+        label="Default">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
           parameter="0" />
@@ -142,26 +145,26 @@
 	      parameter="0" />
       </menu_item_check>
       <menu_item_check
-        name="DoNotRender"
-        label="Do Not Render">
+        name="AlwaysRenderFully"
+        label="Always">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
-          parameter="1" />
+          parameter="2" />
 	    <menu_item_check.on_click
 	      function="Avatar.SetImpostorMode"
-	      parameter="1" />
+	      parameter="2" />
       </menu_item_check>
       <menu_item_check
-        name="AlwaysRenderFully"
-        label="Render Fully">
+        name="DoNotRender"
+        label="Never">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
-          parameter="2" />
+          parameter="1" />
 	    <menu_item_check.on_click
 	      function="Avatar.SetImpostorMode"
-	      parameter="2" />
+	      parameter="1" />
       </menu_item_check>
-
+      </context_menu>
   <menu_item_separator
        layout="topleft" name="Impostor seperator"/>
 
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 ddfff234100b30cd41e99d8459ac4e66419ab714..c5426cb232da89b557ad14a1c517444f9c2df8b4 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -121,9 +121,13 @@
 
    <menu_item_separator />
     
+ <context_menu
+       label="Render Avatar"
+       layout="topleft"
+        name="Render Avatar">
       <menu_item_check
         name="RenderNormally"
-        label="Render Normally">
+        label="Default">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
           parameter="0" />
@@ -132,25 +136,26 @@
 	      parameter="0" />
       </menu_item_check>
       <menu_item_check
-        name="DoNotRender"
-        label="Do Not Render">
+        name="AlwaysRenderFully"
+        label="Always">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
-          parameter="1" />
+          parameter="2" />
 	    <menu_item_check.on_click
 	      function="Avatar.SetImpostorMode"
-	      parameter="1" />
+	      parameter="2" />
       </menu_item_check>
       <menu_item_check
-        name="AlwaysRenderFully"
-        label="Render Fully">
+        name="DoNotRender"
+        label="Never">
         <menu_item_check.on_check
           function="Avatar.CheckImpostorMode"
-          parameter="2" />
+          parameter="1" />
 	    <menu_item_check.on_click
 	      function="Avatar.SetImpostorMode"
-	      parameter="2" />
+	      parameter="1" />
       </menu_item_check>
+      </context_menu>
 
   <menu_item_separator 
     layout="topleft"  name="Impostor seperator"/>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5163cd3115b35bf4695c89501ed8a77fb694e2db
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<context_menu
+ layout="topleft"
+ name="Settings">
+    <menu_item_check
+     label="Default"
+     layout="topleft"
+     name="default">
+        <on_click function="Settings.SetRendering" parameter="default"/>
+	<on_check function="Settings.IsSelected" parameter="default" />  
+    </menu_item_check>
+    <menu_item_check
+     label="Always render"
+     layout="topleft"
+     name="always_render">
+        <on_click function="Settings.SetRendering" parameter="always"/>
+	<on_check function="Settings.IsSelected" parameter="always" />  
+    </menu_item_check>
+    <menu_item_check
+     label="Never render"
+     layout="topleft"
+     name="never_render">
+        <on_click function="Settings.SetRendering" parameter="never"/>
+	<on_check function="Settings.IsSelected" parameter="never" />  
+    </menu_item_check>  
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml
new file mode 100644
index 0000000000000000000000000000000000000000..c64b24ed70c0b35608ca902b1311f00860f63502
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_avatar_rendering_settings_add.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_settings_add.xml"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_call
+   label="Always Render a Resident..."
+   name="add_avatar_always_render">
+      <on_click
+       function="Settings.AddNewEntry" parameter="always"/>
+  </menu_item_call>
+  <menu_item_call
+   label="Never Render a Resident..."
+   name="add_avatar_never_render">
+      <on_click
+       function="Settings.AddNewEntry"  parameter="never"/>
+  </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_edit.xml b/indra/newview/skins/default/xui/en/menu_edit.xml
index 99061e089a9cff5136b5309758476430853bcc24..6f83756f838eedf4116fccf5d66a7565e8e8ee3b 100644
--- a/indra/newview/skins/default/xui/en/menu_edit.xml
+++ b/indra/newview/skins/default/xui/en/menu_edit.xml
@@ -62,15 +62,6 @@
     <menu_item_call.on_enable
      function="Edit.EnableDelete" />
   </menu_item_call>
-  <menu_item_call
-   label="Duplicate"
-   name="Duplicate"
-   shortcut="control|D">
-    <menu_item_call.on_click
-     function="Edit.Duplicate" />
-    <menu_item_call.on_enable
-     function="Edit.EnableDuplicate" />
-  </menu_item_call>
   <menu_item_separator/>
   <menu_item_call
    label="Select All"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
index 61cc9dfe77f50045b03e377f85038f265bdc2fcb..d95541df805ad1562efce96461dd4b2ed4928120 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
@@ -9,6 +9,7 @@
     <menu_item_call
      label="New Inventory Window"
      layout="topleft"
+     shortcut="control|shift|I"
      name="new_window">
         <on_click
          function="Inventory.GearDefault.Custom.Action"
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
index 63295ea27bbfda362d82113f046ef47146e47ddd..01ca38f51aff486ba9773690735076d2b76b6afd 100644
--- a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
@@ -13,6 +13,80 @@
        function="Block.Enable"
        parameter="unblock_item" /> 
   </menu_item_call>
+
+  <menu_item_check
+   label="Block Voice"
+   layout="topleft"
+   name="BlockVoice">
+      <on_check
+       function="Block.Check"
+       parameter="block_voice" />
+      <on_click
+       function="Block.Action"
+       parameter="block_voice" />
+      <on_enable
+       function="Block.Enable"
+       parameter="block_voice" />
+      <on_visible
+       function="Block.Visible"
+       parameter="block_voice" />
+  </menu_item_check>
+
+  <menu_item_check
+   label="Block Text"
+   layout="topleft"
+   name="MuteText">
+      <on_check
+       function="Block.Check"
+       parameter="block_text" />
+      <on_click
+       function="Block.Action"
+       parameter="block_text" />
+     <on_enable
+       function="Block.Enable"
+       parameter="block_text" />
+     <on_visible
+       function="Block.Visible"
+       parameter="block_text" />
+  </menu_item_check>
+
+  <menu_item_check
+   label="Block Particles"
+   layout="topleft"
+   name="MuteText">
+      <on_check
+       function="Block.Check"
+       parameter="block_particles" />
+      <on_click
+       function="Block.Action" 
+       parameter="block_particles" />
+      <on_enable
+       function="Block.Enable"
+       parameter="block_particles" />
+      <on_visible
+       function="Block.Visible"
+       parameter="block_particles" />
+  </menu_item_check>
+
+  <menu_item_check
+   label="Block Object Sounds"
+   layout="topleft"
+   name="BlockObjectSounds">
+      <on_check
+       function="Block.Check"
+       parameter="block_obj_sounds" />
+      <on_click
+       function="Block.Action"
+       parameter="block_obj_sounds" />
+      <on_enable
+       function="Block.Enable"
+       parameter="block_obj_sounds" />
+      <on_visible
+       function="Block.Visible"
+       parameter="block_obj_sounds" />
+  </menu_item_check>
+
+  <menu_item_separator />
   <menu_item_call
    label="Profile..."
    name="profile">
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 332d79e1eac64c47009426e149f7211e7f369458..12df3749f6a03c94135692f3cfbdc7c2516174bb 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -337,6 +337,12 @@
                 <menu_item_call.on_click
                  function="Communicate.VoiceMorphing.Subscribe" />
             </menu_item_call>
+            <menu_item_call
+             label="Premium perk..."
+             name="PremiumPerk">
+                <menu_item_call.on_click
+                 function="Communicate.VoiceMorphing.PremiumPerk" />
+            </menu_item_call>
         </menu>
         <menu_item_check
          label="Gestures..."
@@ -1018,6 +1024,15 @@
                function="Object.Return" />
 			<menu_item_call.on_enable
                function="Object.EnableReturn" />
+          </menu_item_call>
+          <menu_item_call
+           label="Duplicate"
+           name="DuplicateObject"
+           shortcut="control|D">
+            <menu_item_call.on_click
+               function="Object.Duplicate" />
+            <menu_item_call.on_enable
+               function="Object.EnableDuplicate" />
           </menu_item_call>
 		</menu>
         <menu
diff --git a/indra/newview/skins/default/xui/en/mime_types.xml b/indra/newview/skins/default/xui/en/mime_types.xml
index 8d8d546b249b2c0c4ae2c3513f9aafa91356b688..8a810f32a63c4ea981480500fffb9cd570d2045f 100644
--- a/indra/newview/skins/default/xui/en/mime_types.xml
+++ b/indra/newview/skins/default/xui/en/mime_types.xml
@@ -133,18 +133,29 @@
 			media_plugin_libvlc
 		</impl>
 	</scheme>
-  <scheme name="libvlc">
-    <label name="libvlc_label">
-      LibVLC supported media
-    </label>
-    <widgettype>
-      movie
-    </widgettype>
-    <impl>
-      media_plugin_libvlc
-    </impl>
-  </scheme>
-  <mimetype name="blank">
+	<scheme name="example">
+		<label name="example_label">
+			Example Plugin scheme trigger
+		</label>
+		<widgettype>
+			movie
+		</widgettype>
+		<impl>
+			media_plugin_example
+		</impl>
+	</scheme>
+	<scheme name="libvlc">
+		<label name="libvlc_label">
+			LibVLC supported media
+		</label>
+		<widgettype>
+			movie
+		</widgettype>
+		<impl>
+			media_plugin_libvlc
+		</impl>
+	</scheme>
+	<mimetype name="blank">
 		<label name="blank_label">
 			- None -
 		</label>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 2a320c84fbaa894a00533e88b5cbde17c76fc226..3042041a1371b5e4dd9df401ade01f05f59d0b32 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -341,8 +341,7 @@ Initialization with the Marketplace failed because of a system or network error.
         type="alertmodal">
         The transaction with the Marketplace failed with the following error :
         
-        Reason : &apos;[ERROR_REASON]&apos;
-        [ERROR_DESCRIPTION]
+        [ERROR_REASON][ERROR_DESCRIPTION]
         
         <usetemplate
         name="okbutton"
@@ -1938,6 +1937,14 @@ Please make sure none are locked, and that you own all of them.
     <tag>fail</tag>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="CannotLinkAcrossRegions"
+   type="alertmodal">
+Objects cannot be linked across region boundaries.
+    <tag>fail</tag>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="CannotLinkDifferentOwners"
@@ -4325,7 +4332,6 @@ Cannot offer friendship at this time. Please try again in a moment.
 Do Not Disturb is on.  You will not be notified of incoming communications.
 
 - Other residents will receive your Do Not Disturb response (set in Preferences &gt; General).
-- Teleportation offers will be declined.
 - Voice calls will be rejected.
     <usetemplate
      ignoretext="I change my status to Do Not Disturb mode"
diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
index e31695645d03abe387be40b01d4f54bfae356776..6074ab9ef6c4e0fe07e6500fef5de1c58e26883b 100644
--- a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
+++ b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml
@@ -237,7 +237,7 @@ Use "" for multi-word tags
            top_pad="7"
            left="10"
            height="23"
-           label="Upload"
+           label="Share"
            name="post_photo_btn"
            width="100">
             <button.commit_callback
diff --git a/indra/newview/skins/default/xui/en/panel_notify_textbox.xml b/indra/newview/skins/default/xui/en/panel_notify_textbox.xml
index d5b6057233086b3289d54b5e68ebc8830547974d..a679ca7f8cbfd4b4cbdac710b683a6ecb1bcae67 100644
--- a/indra/newview/skins/default/xui/en/panel_notify_textbox.xml
+++ b/indra/newview/skins/default/xui/en/panel_notify_textbox.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
    background_visible="true"
-   height="220"
+   height="215"
    label="instant_message"
    layout="topleft"
    left="0"
@@ -10,21 +10,19 @@
    width="305">
   <string
      name="message_max_lines_count"
-     value="7" />
+     value="14" />
   <panel
-   bevel_style="none"
-   follows="left|right|top"
-   height="185"
-   label="info_panel"
-   layout="topleft"
-   left="0"
-   name="info_panel"
-   top="0"
-   width="305">    
-    <text_editor
-     bg_readonly_color="0.0 0.0 0.0 0"
-     enabled="false"
-     follows="left|right|top|bottom"
+     bevel_style="none"
+     follows="all"
+     height="120"
+     label="info_panel"
+     layout="topleft"
+     left="0"
+     name="info_panel"
+     top="0"
+     width="305">
+    <text
+     follows="all"
      font="SansSerif"
      height="110" 
      layout="topleft"
@@ -34,30 +32,40 @@
      read_only="true"
      text_color="white"
      text_readonly_color="white"
-     top="10"
+     top="0"
      width="285"
      wrap="true"
      parse_highlights="true"
      parse_urls="true"/>
-    <text_editor
-     parse_urls="true"
-     enabled="true"
-     follows="all"
-     height="50"
+  </panel> 
+  <panel
+     bevel_style="none"
+     follows="left|right|bottom"
+     height="55"
+     label="info_panel"
      layout="topleft"
-     left="10"
-     max_length="250"
-     name="message"
-     parse_highlights="true"
-     read_only="false"
-     top_pad="10"
-     type="string"
-     use_ellipses="true"
-     value="message"
-     width="285"
-     word_wrap="true"
-     parse_url="false" >
-    </text_editor>
+     left="0"
+     name="textbox_panel"
+     top_pad="5"
+     width="305">  
+     <text_editor
+      parse_urls="true"
+      enabled="true"
+      follows="all"
+      height="50"
+      layout="topleft"
+      left="10"
+      max_length="250"
+      name="message"
+      parse_highlights="true"
+      read_only="false"
+      top ="0"
+      type="string"
+      use_ellipses="true"
+      value="message"
+      width="285"
+      word_wrap="true">
+     </text_editor>
   </panel>
   <panel
      background_visible="false"
@@ -68,7 +76,7 @@
      layout="topleft"
      left="10"
      name="control_panel"
-     top_pad="0">
+     top_pad="5">
     <!-- 
 	 Notes:
 	 This panel holds the Ignore button and possibly other buttons of notification.
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 8d55e311f6cb44a2071961aae3eb77fc0dc639be..440c6613d56ecdf329051b3d3ee75f368994aed8 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -432,18 +432,16 @@
         top_pad="6"
         name="inventory_offer"
         width="150" />
-
+    <view_border
+        bevel_style="none"
+        height="0"
+        layout="topleft"
+        left="0"
+        name="cost_text_border"
+        top_pad="7"
+        width="492"/>
   </panel>
 
-  <view_border
-      bevel_style="none"
-      height="0"
-      layout="topleft"
-      left="13"
-      name="cost_text_border"
-      top_pad="5"
-      width="495"/>
-
   <panel
       height="50"
       layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 32cbbff8b772cb5280241dff48ce6be9888c3a2c..4692a226d90bfe6b31eaa1bf310aea44d62279ed 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -231,6 +231,34 @@
      m
   </text>
 
+  <check_box
+    control_name="WindLightUseAtmosShaders"
+    height="16"
+    initial_value="true"
+    label="Atmospheric shaders"
+    layout="topleft"
+    left="30"
+    name="WindLightUseAtmosShaders"
+    top_delta="24"
+    width="280">
+    <check_box.commit_callback
+      function="Pref.VertexShaderEnable" />
+  </check_box>
+
+  <check_box
+    control_name="RenderDeferred"
+    height="16"
+    initial_value="true"
+    label="Advanced Lighting Model"
+    layout="topleft"
+    left="30"
+    name="UseLightShaders"
+    top_delta="24"
+    width="256">
+    <check_box.commit_callback
+      function="Pref.VertexShaderEnable" />
+  </check_box>
+  
   <slider
     control_name="IndirectMaxComplexity"
     tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
@@ -246,7 +274,7 @@
     max_val="101"
     name="IndirectMaxComplexity"
     show_text="false"
-    top_delta="24"
+    top_delta="60"
     width="300">
     <slider.commit_callback
       function="Pref.UpdateIndirectMaxComplexity"
@@ -265,34 +293,28 @@
     width="65">
        0
   </text>
-
   <check_box
-    control_name="WindLightUseAtmosShaders"
+    control_name="AlwaysRenderFriends"
     height="16"
     initial_value="true"
-    label="Atmospheric shaders"
+    label="Always Render Friends"
     layout="topleft"
     left="30"
-    name="WindLightUseAtmosShaders"
+    name="AlwaysRenderFriends"
     top_delta="24"
-    width="280">
-    <check_box.commit_callback
-      function="Pref.VertexShaderEnable" />
+    width="256">
   </check_box>
-
-  <check_box
-    control_name="RenderDeferred"
-    height="16"
-    initial_value="true"
-    label="Advanced Lighting Model"
+  <button
+    height="23"
+    label="Exceptions..."
     layout="topleft"
-    left="30"
-    name="UseLightShaders"
+    left="48"
+    name="RenderExceptionsButton"
     top_delta="24"
-    width="256">
-    <check_box.commit_callback
-      function="Pref.VertexShaderEnable" />
-  </check_box>
+    width="100">
+    <button.commit_callback
+      function="Pref.RenderExceptions"/>
+  </button>
 
 <!-- End of Basic Settings block -->
 
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
index 487da54fdf293d516bef211ae23c3f6563847c38..343c2db2f11aaa62fe3b9cf248826275cbbb36d4 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_uploads.xml
@@ -38,13 +38,14 @@
    type="string"
    use_ellipses="true"
    follows="left|top"
-   height="23"
+   height="27"
    layout="topleft"
    font.style="BOLD"
    left="37"
    name="upload_textures"
    top_pad="5"
-   width="350" />
+   width="370"
+   word_wrap="true"/>
   
   <text
    type="string"
@@ -62,13 +63,14 @@
    type="string"
    use_ellipses="true"
    follows="left|top"
-   height="23"
+   height="27"
    layout="topleft"
    font.style="BOLD"
    left="37"
    name="upload_sounds"
    top_pad="5"
-   width="350" />
+   width="370"
+   word_wrap="true"/>
   
   <text
    type="string"
@@ -86,13 +88,14 @@
    type="string"
    use_ellipses="true"
    follows="left|top"
-   height="23"
+   height="27"
    layout="topleft"
    font.style="BOLD"
    left="37"
    name="upload_animation"
    top_pad="5"
-   width="350" />
+   width="370"
+   word_wrap="true"/>
 
   <text
    type="string"
@@ -110,13 +113,14 @@
    type="string"
    use_ellipses="true"
    follows="left|top"
-   height="23"
+   height="27"
    layout="topleft"
    font.style="BOLD"
    left="37"
    name="upload_models"
    top_pad="5"
-   width="350" />
+   width="370"
+   word_wrap="true"/>
 
   <text
    type="string"
diff --git a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
index 265217ef605b3debeb9ce50f383714053ef1c1ed..305cce1cbe722f7ecabd4cb4ed3be344dd98516a 100644
--- a/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
+++ b/indra/newview/skins/default/xui/en/panel_snapshot_options.xml
@@ -48,7 +48,7 @@
    image_overlay_alignment="left"
    image_top_pad="-1"
    imgoverlay_label_space="10"
-   label="Upload to Profile"
+   label="Share to Profile Feed"
    layout="topleft"
    name="save_to_profile_btn"
    left_delta="0"
@@ -65,7 +65,7 @@
    image_overlay_alignment="left"
    image_top_pad="0"
    imgoverlay_label_space="10"
-   label="Upload to Facebook"
+   label="Share to Facebook"
    layout="topleft"
    left_delta="0"
    name="send_to_facebook_btn"
@@ -82,7 +82,7 @@
    image_overlay_alignment="left"
    image_top_pad="0"
    imgoverlay_label_space="10"
-   label="Upload to Twitter"
+   label="Share to Twitter"
    layout="topleft"
    left_delta="0"
    name="send_to_twitter_btn"
@@ -99,7 +99,7 @@
    image_overlay_alignment="left"
    image_top_pad="0"
    imgoverlay_label_space="10"
-   label="Upload to Flickr"
+   label="Share to Flickr"
    layout="topleft"
    left_delta="0"
    name="send_to_flickr_btn"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 9533407c518055a53f51735a6fcbeeb89742419a..f8bbda320afe1ade120530335f6c1821fbde42fb 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2312,7 +2312,8 @@ We are accessing your account on the [[MARKETPLACE_CREATE_STORE_URL] Marketplace
 The [[MARKETPLACE_CREATE_STORE_URL] Marketplace store] is returning errors.
 	</string>
 	<string name="InventoryMarketplaceError">
-This feature is currently in Beta. Please add your name to this [http://goo.gl/forms/FCQ7UXkakz Google form] if you would like to participate.
+An error occurred while opening Marketplace Listings.
+If you continue to receive this message, please contact Second Life support for assistance at http://support.secondlife.com
 	</string>
 	<string name="InventoryMarketplaceListingsNoItemsTitle">Your Marketplace Listings folder is empty.</string>
 	<string name="InventoryMarketplaceListingsNoItemsTooltip"></string>
@@ -3628,7 +3629,10 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
     Conference with [AGENT_NAME]
   </string>
   <string name="inventory_item_offered-im">
-    Inventory item offered
+    Inventory item '[ITEM_NAME]' offered
+  </string>
+  <string name="inventory_folder_offered-im">
+    Inventory folder '[ITEM_NAME]' offered
   </string>
   <string name="share_alert">
     Drag items from inventory here
@@ -3736,7 +3740,8 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
 
   <string name="Home position set.">Home position set.</string>
 
-  <string name="voice_morphing_url">http://secondlife.com/landing/voicemorphing</string>
+  <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>
 
   <!-- Financial operations strings -->
   <string name="paid_you_ldollars">[NAME] paid you L$[AMOUNT] [REASON].</string>
@@ -3879,9 +3884,9 @@ Abuse Report</string>
   <string name="words_separator" value=", "/>
 
   <string name="server_is_down">
-	Despite our best efforts, something unexpected has gone wrong.
+  Despite our best efforts, something unexpected has gone wrong.
 
-	Please check status.secondlifegrid.net to see if there is a known problem with the service.
+Please check http://status.secondlifegrid.net to see if there is a known problem with the service.
         If you continue to experience problems, please check your network and firewall setup.
   </string>
 
@@ -4070,6 +4075,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_Facebook_Label">Facebook</string>
   <string name="Command_Flickr_Label">Flickr</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_Inventory_Label">Inventory</string>
   <string name="Command_Map_Label">Map</string>
@@ -4102,6 +4108,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_Facebook_Tooltip">Post to Facebook</string>
   <string name="Command_Flickr_Tooltip">Upload to Flickr</string>
   <string name="Command_Gestures_Tooltip">Gestures for your avatar</string>
+  <string name="Command_Grid_Status_Tooltip">Show current Grid status</string>
   <string name="Command_HowTo_Tooltip">How to do common tasks</string>
   <string name="Command_Inventory_Tooltip">View and use your belongings</string>
   <string name="Command_Map_Tooltip">Map of the world</string>
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 06ac62d3539c0f6281fde55c62722b5a6f438d42..e806a4fdadf3877f3e19a51b296ebd0ce50efa18 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -489,6 +489,12 @@ def construct(self):
             self.path("media_plugin_libvlc.dll")
             self.end_prefix()
 
+        # Media plugins - Example (useful for debugging - not shipped with release viewer)
+        if self.channel_type() != 'release':
+            if self.prefix(src='../media_plugins/example/%s' % self.args['configuration'], dst="llplugin"):
+                self.path("media_plugin_example.dll")
+                self.end_prefix()
+
         # CEF runtime files - debug
         if self.args['configuration'].lower() == 'debug':
             if self.prefix(src=os.path.join(os.pardir, 'packages', 'bin', 'debug'), dst="llplugin"):
@@ -699,7 +705,7 @@ def package_finish(self):
                 "%%SOURCE%%":self.get_src_prefix(),
                 "%%INST_VARS%%":inst_vars_template % substitution_strings,
                 "%%INSTALL_FILES%%":self.nsi_file_commands(True),
-                "%%$PROGRAMFILES%%":program_files,
+                "%%PROGRAMFILES%%":program_files,
                 "%%ENGAGEREGISTRY%%":engage_registry,
                 "%%DELETE_FILES%%":self.nsi_file_commands(False)})
 
@@ -1067,7 +1073,7 @@ def package_finish(self):
         # make sure we don't have stale files laying about
         self.remove(sparsename, finalname)
 
-        self.run_command('hdiutil create %(sparse)r -volname %(vol)r -fs HFS+ -type SPARSE -megabytes 1000 -layout SPUD' % {
+        self.run_command('hdiutil create %(sparse)r -volname %(vol)r -fs HFS+ -type SPARSE -megabytes 1300 -layout SPUD' % {
                 'sparse':sparsename,
                 'vol':volname})