diff --git a/.gitignore b/.gitignore
index e9b544a6ce86890c25db16c585fe80953f0256b0..d9b0b9eb200035d883af599c0ac1f2632300d6b1 100755
--- a/.gitignore
+++ b/.gitignore
@@ -33,11 +33,8 @@ indra/packages/*
 build-vc80/
 build-vc100/
 build-vc120/
-build-vc120-32/
-build-vc120-64/
-build-vc150-32/
-build-vc150-64/
-build-vc160-64/
+build-vc*-32/
+build-vc*-64/
 indra/CMakeFiles
 indra/build-vc[0-9]*
 indra/lib/mono/1.0/*.dll
diff --git a/autobuild.xml b/autobuild.xml
index 64de949e31ea5d44974ac534e0caea5ded8a56b7..40a40bba3cefb616462c98f9ea2b8891fc036c82 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -236,9 +236,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>4699b8389dfb754da0393ddb5d325722</string>
+              <string>a880dfc15fcb330baf548a85324cd88a</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95882/856117/colladadom-2.3.569219-darwin64-569219.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104133/913090/colladadom-2.3.574693-darwin64-574693.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -260,9 +260,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>343e46ea49a08ad6596d3dc702d5b812</string>
+              <string>7e84441d9c7cf019a7bdc7b818b16c27</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95883/856128/colladadom-2.3.569219-windows-569219.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104112/912957/colladadom-2.3.574693-windows-574693.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -272,16 +272,16 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>de5bdfb61b31db56c5fe7d0962ad11e2</string>
+              <string>2eaffbb8a93b03a732d3c47055a8efcb</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/95884/856129/colladadom-2.3.569219-windows64-569219.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104135/913103/colladadom-2.3.574693-windows64-574693.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows64</string>
           </map>
         </map>
         <key>version</key>
-        <string>2.3.569219</string>
+        <string>2.3.574693</string>
       </map>
       <key>cubemaptoequirectangular</key>
       <map>
@@ -331,6 +331,16 @@
             <key>name</key>
             <string>windows64</string>
           </map>
+          <key>linux64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>ac54672e0b38f52726f5c99047c913e4</string>
+              <key>url</key>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89306/815431/cubemaptoequirectangular-1.1.0-windows64-564841.tar.bz2</string>
+            </map>
+          </map>
         </map>
         <key>version</key>
         <string>1.1.0</string>
@@ -1041,6 +1051,16 @@
             <key>name</key>
             <string>windows64</string>
           </map>
+          <key>linux64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>e70898903475d8ac2e81ff33278fc987</string>
+              <key>url</key>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89309/815433/jpegencoderbasic-1.0-windows64-564842.tar.bz2</string>
+            </map>
+          </map>
         </map>
         <key>version</key>
         <string>1.0</string>
@@ -1603,9 +1623,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>da57838d80cf332f4a3026713a13f086</string>
+              <string>e51c6f5dfd76eb148348a44ff57e66c2</string>
               <key>url</key>
-              <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/90708/824484/llphysicsextensions_source-1.0.565754-darwin64-565754.tar.bz2</string>
+              <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/104810/918016/llphysicsextensions_source-1.0.575107-darwin64-575107.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -1627,9 +1647,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>28ad884012aa0bb70cf4101853af2f9a</string>
+              <string>dbbe4cc568ac149d862e421cdda4dd48</string>
               <key>url</key>
-              <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/90733/824570/llphysicsextensions_source-1.0.565768-windows-565768.tar.bz2</string>
+              <string>https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/104809/918011/llphysicsextensions_source-1.0.575107-windows-575107.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -2508,6 +2528,16 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>name</key>
             <string>windows64</string>
           </map>
+          <key>linux64</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>46edf0f55417f8ef0d33a5c007bc3644</string>
+              <key>url</key>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/89310/815451/threejs-0.132.2-windows64-564843.tar.bz2</string>
+            </map>
+          </map>
         </map>
         <key>version</key>
         <string>0.132.2</string>
@@ -2727,9 +2757,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>2e8d817e7837dd6f4284b13fa3f5c15e</string>
+              <string>9e1b5515ab59b4e9cfeef6626d65d03d</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104765/917714/viewer_manager-3.0.575083-darwin64-575083.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/108609/945996/viewer_manager-3.0.577252-darwin64-577252.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin64</string>
@@ -2739,9 +2769,9 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>3efa80faaf537e39a77218cd6efa9409</string>
+              <string>a3c599595ecc8fb987a5499fca42520a</string>
               <key>url</key>
-              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/104766/917721/viewer_manager-3.0.575083-windows-575083.tar.bz2</string>
+              <string>https://automated-builds-secondlife-com.s3.amazonaws.com/ct2/108610/946003/viewer_manager-3.0.577252-windows-577252.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
@@ -2752,7 +2782,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>source_type</key>
         <string>hg</string>
         <key>version</key>
-        <string>3.0.575083</string>
+        <string>3.0.577252</string>
       </map>
       <key>vlc-bin</key>
       <map>
@@ -3133,6 +3163,68 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
           <key>name</key>
           <string>common</string>
         </map>
+        <key>linux64</key>
+        <map>
+          <key>build_directory</key>
+          <string>build-linux-x86_64</string>
+          <key>configurations</key>
+          <map>
+            <key>Release</key>
+            <map>
+              <key>build</key>
+              <map>
+                <key>command</key>
+                <string>ninja</string>
+              </map>
+              <key>configure</key>
+              <map>
+                <key>arguments</key>
+                <array>
+                  <string>../indra</string>
+                </array>
+                <key>options</key>
+                <array>
+                  <string>-G</string>
+                  <string>Ninja</string>
+                  <string>-DLL_TESTS=Off</string>
+                </array>
+              </map>
+              <key>default</key>
+              <string>True</string>
+              <key>name</key>
+              <string>Release</string>
+            </map>
+            <key>ReleaseOS</key>
+            <map>
+              <key>build</key>
+              <map>
+                <key>command</key>
+                <string>ninja</string>
+              </map>
+              <key>configure</key>
+              <map>
+                <key>options</key>
+                <array>
+                  <string>-G</string>
+                  <string>Ninja</string>
+                  <string>-DLL_TESTS=Off</string>
+                </array>
+              </map>
+              <key>name</key>
+              <string>ReleaseOS</string>
+            </map>
+            <key>default</key>
+            <map>
+              <key>build</key>
+              <map>
+              </map>
+              <key>name</key>
+              <string>default</string>
+            </map>
+          </map>
+          <key>name</key>
+          <string>linux64</string>
+        </map>
         <key>darwin64</key>
         <map>
           <key>build_directory</key>
@@ -3256,7 +3348,7 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
         <key>windows</key>
         <map>
           <key>build_directory</key>
-          <string>build-vc${AUTOBUILD_VSVER|150}-$AUTOBUILD_ADDRSIZE</string>
+          <string>build-vc${AUTOBUILD_VSVER|170}-$AUTOBUILD_ADDRSIZE</string>
           <key>configurations</key>
           <map>
             <key>RelWithDebInfo</key>
@@ -3285,6 +3377,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                 <array>
                   <string>-G</string>
                   <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string>
+                  <string>-A</string>
+                  <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
                 </array>
               </map>
               <key>default</key>
@@ -3323,9 +3417,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                 <array>
                   <string>-G</string>
                   <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string>
+                  <string>-A</string>
+                  <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
-                  <string>-DOPENAL:BOOL=ON</string>
+                  <string>-DUSE_OPENAL:BOOL=ON</string>
                 </array>
               </map>
               <key>name</key>
@@ -3357,6 +3453,8 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                 <array>
                   <string>-G</string>
                   <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string>
+                  <string>-A</string>
+                  <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
                 </array>
               </map>
               <key>name</key>
@@ -3393,10 +3491,12 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors</string>
                 <array>
                   <string>-G</string>
                   <string>${AUTOBUILD_WIN_CMAKE_GEN|NOTWIN}</string>
+                  <string>-A</string>
+                  <string>${AUTOBUILD_WIN_VSPLATFORM|NOTWIN}</string>
                   <string>-DUNATTENDED:BOOL=ON</string>
                   <string>-DINSTALL_PROPRIETARY=FALSE</string>
                   <string>-DUSE_KDU=FALSE</string>
-                  <string>-DOPENAL:BOOL=ON</string>
+                  <string>-DUSE_OPENAL:BOOL=ON</string>
                 </array>
               </map>
               <key>name</key>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 99c2242275d84c359d00313e68eadb5c830005fb..6e08cba599a4c2af8cd0f228622634e072619fe3 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1130,6 +1130,7 @@ Nicky Dasmijn
 	SL-14541
 	SL-16438
 	SL-17218
+	SL-17238
 	SL-17585
 Nicky Perian
 	OPEN-1
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 68f6e962efed0dd73ed23706e4efe6b9ec280550..205ce402a0be785dafe16ce1982d3c7866976c65 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -4,22 +4,43 @@
 # other commands to guarantee full compatibility
 # with the version specified
 ## 3.8 added VS_DEBUGGER_WORKING_DIRECTORY support
-cmake_minimum_required(VERSION 3.8.0 FATAL_ERROR)
+## 3.13/12 is needed for add_link_options/add_compile_definitions
+## 3.14 added FILE CREATE_LINK
+## 3.16 is needed for target_precompile_headers
+## Nicky: Ideally we want at least 3.21 for good preset support
+##   We're not there yet, but once done, there is a kludge in Linking.cmake
+#    "if(${CMAKE_VERSION} VERSION_LESS "3.20.0")" that can also be removed
+cmake_minimum_required(VERSION 3.16.0 FATAL_ERROR)
 
 set(ROOT_PROJECT_NAME "SecondLife" CACHE STRING
     "The root project/makefile/solution name. Defaults to SecondLife.")
 project(${ROOT_PROJECT_NAME})
 
-set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
+set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake"  "${CMAKE_CURRENT_BINARY_DIR}")
+
+include(conanbuildinfo OPTIONAL RESULT_VARIABLE USE_CONAN )
+if( USE_CONAN )
+    set( USE_CONAN ON )
+    set( USE_AUTOBUILD_3P OFF )
+    conan_basic_setup(TARGETS NO_OUTPUT_DIRS)
+    add_compile_definitions(LL_USESYSTEMLIBS USE_CONAN NO_AUTOBUILD_3P)
+else()
+  set( USE_CONAN OFF )
+  set( USE_AUTOBUILD_3P ON )
+endif()
+
+# The viewer code base can now be successfully compiled with -std=c++14. But
+# turning that on in the generic viewer-build-variables/variables file would
+# potentially require tweaking each of our ~50 third-party library builds.
+# Until we decide to set -std=c++14 in viewer-build-variables/variables, set
+# it locally here: we want to at least prevent inadvertently reintroducing
+# viewer code that would fail with C++14.
+set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
 include(Variables)
 include(BuildVersion)
 
-set(LEGACY_STDIO_LIBS)
-if (WINDOWS)
-      set(LEGACY_STDIO_LIBS legacy_stdio_definitions)
-endif (WINDOWS)
-
 if (NOT CMAKE_BUILD_TYPE)
   set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
       "Build type.  One of: Debug Release RelWithDebInfo" FORCE)
@@ -59,8 +80,10 @@ add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
 add_subdirectory(${LIBS_OPEN_PREFIX}llui)
 add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
 
+if( LL_TESTS )
 # Legacy C++ tests. Build always, run if LL_TESTS is true.
 add_subdirectory(${VIEWER_PREFIX}test)
+endif()
 
 if (ENABLE_MEDIA_PLUGINS)
 # viewer media plugins
@@ -72,7 +95,6 @@ if (LINUX)
       include(LLAppearanceUtility)
       add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
   endif (INSTALL_PROPRIETARY)
-  add_dependencies(viewer linux-crash-logger-strip-target)
 elseif (WINDOWS)
   # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
   if (EXISTS ${VIEWER_DIR}win_setup)
@@ -87,12 +109,6 @@ if (WINDOWS)
     endif (EXISTS ${VIEWER_DIR}win_setup)
 endif (WINDOWS)
 
-# sets the 'startup project' for debugging from visual studio.
-set_property(
-    DIRECTORY ${VIEWER_PREFIX}
-    PROPERTY VS_STARTUP_PROJECT secondlife-bin
-    )
-
 if (USE_BUGSPLAT)
     if (BUGSPLAT_DB)
         message(STATUS "Building with BugSplat; database '${BUGSPLAT_DB}'")
@@ -108,6 +124,12 @@ add_dependencies(viewer secondlife-bin)
 
 add_subdirectory(${VIEWER_PREFIX}doxygen EXCLUDE_FROM_ALL)
 
+# sets the 'startup project' for debugging from visual studio.
+set_property(
+        DIRECTORY ${VIEWER_PREFIX}
+        PROPERTY VS_STARTUP_PROJECT ${VIEWER_BINARY_NAME}
+        )
+
 if (LL_TESTS)
   # Define after the custom targets are created so
   # individual apps can add themselves as dependencies
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index d81d3ac1f08e477bdb0a8f31688bbc26db0cede1..9535e62e8fbb19ad4a654279c5bc28abcfd7232d 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -12,9 +12,7 @@
 #   Also realize that CMAKE_CXX_FLAGS may already be partially populated on
 #   entry to this file.
 #*****************************************************************************
-
-if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
-set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+include_guard()
 
 include(Variables)
 
@@ -27,25 +25,22 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} $ENV{LL_BUILD}")
 # as well?
 
 # Portable compilation flags.
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DADDRESS_SIZE=${ADDRESS_SIZE}")
+add_compile_definitions( ADDRESS_SIZE=${ADDRESS_SIZE})
 
 # Configure crash reporting
 set(RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in release builds")
 set(NON_RELEASE_CRASH_REPORTING OFF CACHE BOOL "Enable use of crash reporting in developer builds")
 
 if(RELEASE_CRASH_REPORTING)
-  set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DLL_SEND_CRASH_REPORTS=1")
+  add_compile_definitions( LL_SEND_CRASH_REPORTS=1)
 endif()
 
 if(NON_RELEASE_CRASH_REPORTING)
-  set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} -DLL_SEND_CRASH_REPORTS=1")
-  set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DLL_SEND_CRASH_REPORTS=1")
-endif()  
-
-# Don't bother with MinSizeRel or Debug builds.
-set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release" CACHE STRING
-    "Supported build types." FORCE)
+  add_compile_definitions( LL_SEND_CRASH_REPORTS=1)
+endif()
 
+# Don't bother with a MinSizeRel or Debug builds.
+set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release" CACHE STRING "Supported build types." FORCE)
 
 # Platform-specific compilation flags.
 
@@ -66,98 +61,94 @@ if (WINDOWS)
   # CP changed to only append the flag for 32bit builds - on 64bit builds,
   # locally at least, the build output is spammed with 1000s of 'D9002'
   # warnings about this switch being ignored.
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP")  
   if( ADDRESS_SIZE EQUAL 32 )
     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /p:PreferredToolArchitecture=x64")  
   endif()
-  # Preserve first-pass-through versions (ie no FORCE overwrite). Prevents recursive addition of /Zo (04/2021)
-  set(OG_CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE} CACHE STRING "OG_CXX_FLAGS_RELEASE")
-  set(OG_CMAKE_CXX_FLAGS_RELWITHDEBINFO ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} CACHE STRING "OG_CXX_FLAGS_RELWITHDEBINFO")
-
-  set(CMAKE_CXX_FLAGS_RELWITHDEBINFO 
-      "${OG_CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Zo"
-      CACHE STRING "C++ compiler release-with-debug options" FORCE)
-  set(CMAKE_CXX_FLAGS_RELEASE
-      "${OG_CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /Zo"
-      CACHE STRING "C++ compiler release options" FORCE)
-  
   # zlib has assembly-language object files incompatible with SAFESEH
-  set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /LARGEADDRESSAWARE /SAFESEH:NO /NODEFAULTLIB:LIBCMT /IGNORE:4099")
-
-  set(CMAKE_CXX_STANDARD_LIBRARIES "")
-  set(CMAKE_C_STANDARD_LIBRARIES "")
+  add_link_options(/LARGEADDRESSAWARE
+          /SAFESEH:NO
+          /NODEFAULTLIB:LIBCMT
+          /IGNORE:4099)
 
   add_definitions(
-      /DNOMINMAX
+      -DNOMINMAX
 #      /DDOM_DYNAMIC            # For shared library colladadom
       )
   add_compile_options(
-      /GS
-      /TP
-      /W3
-      /c
-      /Zc:forScope
-      /nologo
-      /Oy-
-#      /arch:SSE2
-      /fp:fast
+          /Zo
+          /GS
+          /TP
+          /W3
+          /c
+          /Zc:forScope
+          /nologo
+          /Oy-
+          /fp:fast
+          /MP
       )
 
   # Nicky: x64 implies SSE2
   if( ADDRESS_SIZE EQUAL 32 )
-    add_definitions( /arch:SSE2 )
+    add_compile_options( /arch:SSE2 )
   endif()
      
   # Are we using the crummy Visual Studio KDU build workaround?
   if (NOT VS_DISABLE_FATAL_WARNINGS)
-    add_definitions(/WX)
+    add_compile_options(/WX)
   endif (NOT VS_DISABLE_FATAL_WARNINGS)
+
+  #ND: When using something like buildcache (https://github.com/mbitsnbites/buildcache)
+  # to make those wrappers work /Zi must be changed to /Z7, as /Zi due to it's nature is not compatible with caching
+  if( ${CMAKE_CXX_COMPILER_LAUNCHER} MATCHES ".*cache.*")
+    add_compile_options( /Z7 )
+    string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
+    string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
+    string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
+    string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
+    string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
+  endif()
 endif (WINDOWS)
 
 
 if (LINUX)
   set(CMAKE_SKIP_RPATH TRUE)
 
-  add_definitions(-D_FORTIFY_SOURCE=2)
-
-  set(CMAKE_CXX_FLAGS "-Wno-deprecated -Wno-unused-but-set-variable -Wno-unused-variable ${CMAKE_CXX_FLAGS}")
-
-  # gcc 4.3 and above don't like the LL boost and also
-  # cause warnings due to our use of deprecated headers
-  add_definitions(-Wno-parentheses)
-
-  add_definitions(
-      -D_REENTRANT
-      )
+   # EXTERNAL_TOS
+   # force this platform to accept TOS via external browser
+
+   # LL_IGNORE_SIGCHLD
+   # don't catch SIGCHLD in our base application class for the viewer - some of
+   # our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The
+   # viewer doesn't need to catch SIGCHLD anyway.
+
+  add_compile_definitions(
+          _REENTRANT
+          _FORTIFY_SOURCE=2
+          EXTERNAL_TOS
+          APPID=secondlife
+          LL_IGNORE_SIGCHLD
+  )
   add_compile_options(
-      -fexceptions
-      -fno-math-errno
-      -fno-strict-aliasing
-      -fsigned-char
-      -msse2
-      -mfpmath=sse
-      -pthread
-      )
-
-  # force this platform to accept TOS via external browser
-  add_definitions(-DEXTERNAL_TOS)
+          -fexceptions
+          -fno-math-errno
+          -fno-strict-aliasing
+          -fsigned-char
+          -msse2
+          -mfpmath=sse
+          -pthread
+          -Wno-parentheses
+          -Wno-deprecated
+          -fvisibility=hidden
+  )
 
-  add_definitions(-DAPPID=secondlife)
-  add_compile_options(-fvisibility=hidden)
-  # don't catch SIGCHLD in our base application class for the viewer - some of
-  # our 3rd party libs may need their *own* SIGCHLD handler to work. Sigh! The
-  # viewer doesn't need to catch SIGCHLD anyway.
-  add_definitions(-DLL_IGNORE_SIGCHLD)
   if (ADDRESS_SIZE EQUAL 32)
     add_compile_options(-march=pentium4)
   endif (ADDRESS_SIZE EQUAL 32)
-  #add_compile_options(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2
-  if (NOT USESYSTEMLIBS)
-    # this stops us requiring a really recent glibc at runtime
-    add_compile_options(-fno-stack-protector)
-    # linking can be very memory-hungry, especially the final viewer link
-    set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory")
-  endif (NOT USESYSTEMLIBS)
+
+  # this stops us requiring a really recent glibc at runtime
+  add_compile_options(-fno-stack-protector)
+  # linking can be very memory-hungry, especially the final viewer link
+  set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory")
 
   set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
 endif (LINUX)
@@ -173,13 +164,7 @@ if (DARWIN)
   # see Variables.cmake.
   string(REPLACE "-gdwarf-2" "-g${CMAKE_XCODE_ATTRIBUTE_DEBUG_INFORMATION_FORMAT}"
     CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
-  # The viewer code base can now be successfully compiled with -std=c++14. But
-  # turning that on in the generic viewer-build-variables/variables file would
-  # potentially require tweaking each of our ~50 third-party library builds.
-  # Until we decide to set -std=c++14 in viewer-build-variables/variables, set
-  # it locally here: we want to at least prevent inadvertently reintroducing
-  # viewer code that would fail with C++14.
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags} -std=c++14")
+  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags}")
   set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}  ${DARWIN_extra_cstar_flags}")
   # NOTE: it's critical that the optimization flag is put in front.
   # NOTE: it's critical to have both CXX_FLAGS and C_FLAGS covered.
@@ -188,48 +173,18 @@ if (DARWIN)
 ##set(SIGNING_IDENTITY "Developer ID Application: Linden Research, Inc.")
 endif (DARWIN)
 
-
 if (LINUX OR DARWIN)
-  if (CMAKE_CXX_COMPILER MATCHES ".*clang")
-    set(CMAKE_COMPILER_IS_CLANGXX 1)
-  endif (CMAKE_CXX_COMPILER MATCHES ".*clang")
-
-  if (CMAKE_COMPILER_IS_GNUCXX)
-    set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs")
-  elseif (CMAKE_COMPILER_IS_CLANGXX)
-    set(GCC_WARNINGS "-Wall -Wno-sign-compare -Wno-trigraphs")
-  endif()
+  set(GCC_WARNINGS -Wall -Wno-sign-compare -Wno-trigraphs)
 
   if (NOT GCC_DISABLE_FATAL_WARNINGS)
-    set(GCC_WARNINGS "${GCC_WARNINGS} -Werror")
+    list(APPEND GCC_WARNINGS -Werror)
   endif (NOT GCC_DISABLE_FATAL_WARNINGS)
 
-  set(GCC_CXX_WARNINGS "${GCC_WARNINGS} -Wno-reorder -Wno-non-virtual-dtor")
+  list(APPEND GCC_WARNINGS -Wno-reorder -Wno-non-virtual-dtor )
 
-  set(CMAKE_C_FLAGS "${GCC_WARNINGS} ${CMAKE_C_FLAGS}")
-  set(CMAKE_CXX_FLAGS "${GCC_CXX_WARNINGS} ${CMAKE_CXX_FLAGS}")
-
-  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m${ADDRESS_SIZE}")
-  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m${ADDRESS_SIZE}")
+  add_compile_options(${GCC_WARNINGS})
+  add_compile_options(-m${ADDRESS_SIZE})
 endif (LINUX OR DARWIN)
 
 
-if (USESYSTEMLIBS)
-  add_definitions(-DLL_USESYSTEMLIBS=1)
-
-  if (LINUX AND ADDRESS_SIZE EQUAL 32)
-    add_definitions(-march=pentiumpro)
-  endif (LINUX AND ADDRESS_SIZE EQUAL 32)
-
-else (USESYSTEMLIBS)
-  set(${ARCH}_linux_INCLUDES
-      atk-1.0
-      glib-2.0
-      gstreamer-0.10
-      gtk-2.0
-      pango-1.0
-      )
-endif (USESYSTEMLIBS)
-
-endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
 
diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake
index 9b64bc6160c6c13236e12957f10421911c055b95..8a0939c92c96698ec4809f16e815d1a850633a73 100644
--- a/indra/cmake/APR.cmake
+++ b/indra/cmake/APR.cmake
@@ -1,54 +1,45 @@
 include(Linking)
 include(Prebuilt)
 
-set(APR_FIND_QUIETLY ON)
-set(APR_FIND_REQUIRED ON)
+include_guard()
 
-set(APRUTIL_FIND_QUIETLY ON)
-set(APRUTIL_FIND_REQUIRED ON)
+add_library( ll::apr INTERFACE IMPORTED )
 
-if (USESYSTEMLIBS)
-  include(FindAPR)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(apr_suite)
-  if (WINDOWS)
-    if (LLCOMMON_LINK_SHARED)
-      set(APR_selector "lib")
-    else (LLCOMMON_LINK_SHARED)
-      set(APR_selector "")
-    endif (LLCOMMON_LINK_SHARED)
-    set(APR_LIBRARIES 
-      debug ${ARCH_PREBUILT_DIRS_DEBUG}/${APR_selector}apr-1.lib
-      optimized ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apr-1.lib
-      )
-    set(APRICONV_LIBRARIES 
-      debug ${ARCH_PREBUILT_DIRS_DEBUG}/${APR_selector}apriconv-1.lib
-      optimized ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apriconv-1.lib
-      )
-    set(APRUTIL_LIBRARIES 
-      debug ${ARCH_PREBUILT_DIRS_DEBUG}/${APR_selector}aprutil-1.lib ${APRICONV_LIBRARIES}
-      optimized ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}aprutil-1.lib ${APRICONV_LIBRARIES}
-      )
-  elseif (DARWIN)
-    if (LLCOMMON_LINK_SHARED)
-      set(APR_selector     "0.dylib")
-      set(APRUTIL_selector "0.dylib")
-    else (LLCOMMON_LINK_SHARED)
-      set(APR_selector     "a")
-      set(APRUTIL_selector "a")
-    endif (LLCOMMON_LINK_SHARED)
-    set(APR_LIBRARIES libapr-1.${APR_selector})
-    set(APRUTIL_LIBRARIES libaprutil-1.${APRUTIL_selector})
-    set(APRICONV_LIBRARIES iconv)
-  else (WINDOWS)
-    set(APR_LIBRARIES apr-1)
-    set(APRUTIL_LIBRARIES aprutil-1)
-    set(APRICONV_LIBRARIES iconv)
-  endif (WINDOWS)
-  set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/apr-1)
+use_system_binary( apr apr-util )
+use_prebuilt_binary(apr_suite)
 
-  if (LINUX)
-      list(APPEND APRUTIL_LIBRARIES uuid)
-      list(APPEND APRUTIL_LIBRARIES rt)
-  endif (LINUX)
-endif (USESYSTEMLIBS)
+if (WINDOWS)
+  if (LLCOMMON_LINK_SHARED)
+    set(APR_selector "lib")
+  else (LLCOMMON_LINK_SHARED)
+    set(APR_selector "")
+  endif (LLCOMMON_LINK_SHARED)
+  target_link_libraries( ll::apr INTERFACE
+          ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apr-1.lib
+          ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}apriconv-1.lib
+          ${ARCH_PREBUILT_DIRS_RELEASE}/${APR_selector}aprutil-1.lib
+          )
+elseif (DARWIN)
+  if (LLCOMMON_LINK_SHARED)
+    set(APR_selector     "0.dylib")
+    set(APRUTIL_selector "0.dylib")
+  else (LLCOMMON_LINK_SHARED)
+    set(APR_selector     "a")
+    set(APRUTIL_selector "a")
+  endif (LLCOMMON_LINK_SHARED)
+
+  target_link_libraries( ll::apr INTERFACE
+          libapr-1.${APR_selector}
+          libaprutil-1.${APRUTIL_selector}
+          iconv
+          )
+else (WINDOWS)
+  target_link_libraries( ll::apr INTERFACE
+          apr-1
+          aprutil-1
+          iconv
+          uuid
+          rt
+          )
+endif (WINDOWS)
+target_include_directories( ll::apr SYSTEM INTERFACE  ${LIBS_PREBUILT_DIR}/include/apr-1 )
diff --git a/indra/cmake/Atmosphere.cmake b/indra/cmake/Atmosphere.cmake
deleted file mode 100644
index 9c14df2a11cc8e6167c76f4d846327d4f842d063..0000000000000000000000000000000000000000
--- a/indra/cmake/Atmosphere.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-# -*- cmake -*-
-include(Prebuilt)
-use_prebuilt_binary(libatmosphere)
-set(LIBATMOSPHERE_LIBRARIES atmosphere)
-set(LIBATMOSPHERE_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/atmosphere)
diff --git a/indra/cmake/Audio.cmake b/indra/cmake/Audio.cmake
index f95439245aa28ee287abff7d45e132c286b0a1d3..38547bb0172ba15cb75fa3ae8af294059b35bb22 100644
--- a/indra/cmake/Audio.cmake
+++ b/indra/cmake/Audio.cmake
@@ -1,42 +1,16 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-if (USESYSTEMLIBS)
-  include(FindPkgConfig)
-  pkg_check_modules(OGG REQUIRED ogg)
-  pkg_check_modules(VORBIS REQUIRED vorbis)
-  pkg_check_modules(VORBISENC REQUIRED vorbisenc)
-  pkg_check_modules(VORBISFILE REQUIRED vorbisfile)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(ogg_vorbis)
-  set(VORBIS_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
-  set(VORBISENC_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS})
-  set(VORBISFILE_INCLUDE_DIRS ${VORBIS_INCLUDE_DIRS})
+include_guard()
+add_library( ll::vorbis INTERFACE IMPORTED )
 
-  if (WINDOWS)
-    set(OGG_LIBRARIES
-        optimized ogg_static
-        debug ogg_static_d)
-    set(VORBIS_LIBRARIES
-        optimized vorbis_static
-        debug vorbis_static_d)
-    set(VORBISENC_LIBRARIES
-        optimized vorbisenc_static
-        debug vorbisenc_static_d)
-    set(VORBISFILE_LIBRARIES
-        optimized vorbisfile_static
-        debug vorbisfile_static_d)
-  else (WINDOWS)
-    set(OGG_LIBRARIES ogg)
-    set(VORBIS_LIBRARIES vorbis)
-    set(VORBISENC_LIBRARIES vorbisenc)
-    set(VORBISFILE_LIBRARIES vorbisfile)
-  endif (WINDOWS)
-endif (USESYSTEMLIBS)
+use_system_binary(vorbis)
+use_prebuilt_binary(ogg_vorbis)
+target_include_directories( ll::vorbis SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include )
+
+if (WINDOWS)
+  target_link_libraries(ll::vorbis INTERFACE ogg_static vorbis_static vorbisenc_static vorbisfile_static )
+else (WINDOWS)
+  target_link_libraries(ll::vorbis INTERFACE ogg vorbis vorbisenc vorbisfile )
+endif (WINDOWS)
 
-link_directories(
-    ${VORBIS_LIBRARY_DIRS}
-    ${VORBISENC_LIBRARY_DIRS}
-    ${VORBISFILE_LIBRARY_DIRS}
-    ${OGG_LIBRARY_DIRS}
-    )
diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake
index e79dc332450d13b98e422eab4273834e5af4288b..601a23a86db2591b39258ae2616fcb88208a4141 100644
--- a/indra/cmake/Boost.cmake
+++ b/indra/cmake/Boost.cmake
@@ -1,105 +1,50 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-set(Boost_FIND_QUIETLY ON)
-set(Boost_FIND_REQUIRED ON)
+include_guard()
 
-if (USESYSTEMLIBS)
-  include(FindBoost)
+add_library( ll::boost INTERFACE IMPORTED )
+if( USE_CONAN )
+  target_link_libraries( ll::boost INTERFACE CONAN_PKG::boost )
+  target_compile_definitions( ll::boost INTERFACE BOOST_ALLOW_DEPRECATED_HEADERS BOOST_BIND_GLOBAL_PLACEHOLDERS )
+  return()
+endif()
 
-  set(BOOST_CONTEXT_LIBRARY boost_context-mt)
-  set(BOOST_FIBER_LIBRARY boost_fiber-mt)
-  set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt)
-  set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
-  set(BOOST_REGEX_LIBRARY boost_regex-mt)
-  set(BOOST_SIGNALS_LIBRARY boost_signals-mt)
-  set(BOOST_SYSTEM_LIBRARY boost_system-mt)
-  set(BOOST_THREAD_LIBRARY boost_thread-mt)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(boost)
-  set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
+use_prebuilt_binary(boost)
 
-  # As of sometime between Boost 1.67 and 1.72, Boost libraries are suffixed
-  # with the address size.
-  set(addrsfx "-x${ADDRESS_SIZE}")
+# As of sometime between Boost 1.67 and 1.72, Boost libraries are suffixed
+# with the address size.
+set(addrsfx "-x${ADDRESS_SIZE}")
 
-  if (WINDOWS)
-    set(BOOST_CONTEXT_LIBRARY
-        optimized libboost_context-mt${addrsfx}
-        debug libboost_context-mt${addrsfx}-gd)
-    set(BOOST_FIBER_LIBRARY
-        optimized libboost_fiber-mt${addrsfx}
-        debug libboost_fiber-mt${addrsfx}-gd)
-    set(BOOST_FILESYSTEM_LIBRARY
-        optimized libboost_filesystem-mt${addrsfx}
-        debug libboost_filesystem-mt${addrsfx}-gd)
-    set(BOOST_PROGRAM_OPTIONS_LIBRARY
-        optimized libboost_program_options-mt${addrsfx}
-        debug libboost_program_options-mt${addrsfx}-gd)
-    set(BOOST_REGEX_LIBRARY
-        optimized libboost_regex-mt${addrsfx}
-        debug libboost_regex-mt${addrsfx}-gd)
-    set(BOOST_SIGNALS_LIBRARY
-        optimized libboost_signals-mt${addrsfx}
-        debug libboost_signals-mt${addrsfx}-gd)
-    set(BOOST_SYSTEM_LIBRARY
-        optimized libboost_system-mt${addrsfx}
-        debug libboost_system-mt${addrsfx}-gd)
-    set(BOOST_THREAD_LIBRARY
-        optimized libboost_thread-mt${addrsfx}
-        debug libboost_thread-mt${addrsfx}-gd)
-  elseif (LINUX)
-    set(BOOST_CONTEXT_LIBRARY
-        optimized boost_context-mt${addrsfx}
-        debug boost_context-mt${addrsfx}-d)
-    set(BOOST_FIBER_LIBRARY
-        optimized boost_fiber-mt${addrsfx}
-        debug boost_fiber-mt${addrsfx}-d)
-    set(BOOST_FILESYSTEM_LIBRARY
-        optimized boost_filesystem-mt${addrsfx}
-        debug boost_filesystem-mt${addrsfx}-d)
-    set(BOOST_PROGRAM_OPTIONS_LIBRARY
-        optimized boost_program_options-mt${addrsfx}
-        debug boost_program_options-mt${addrsfx}-d)
-    set(BOOST_REGEX_LIBRARY
-        optimized boost_regex-mt${addrsfx}
-        debug boost_regex-mt${addrsfx}-d)
-    set(BOOST_SIGNALS_LIBRARY
-        optimized boost_signals-mt${addrsfx}
-        debug boost_signals-mt${addrsfx}-d)
-    set(BOOST_SYSTEM_LIBRARY
-        optimized boost_system-mt${addrsfx}
-        debug boost_system-mt${addrsfx}-d)
-    set(BOOST_THREAD_LIBRARY
-        optimized boost_thread-mt${addrsfx}
-        debug boost_thread-mt${addrsfx}-d)
-  elseif (DARWIN)
-    set(BOOST_CONTEXT_LIBRARY
-        optimized boost_context-mt${addrsfx}
-        debug boost_context-mt${addrsfx})
-    set(BOOST_FIBER_LIBRARY
-        optimized boost_fiber-mt${addrsfx}
-        debug boost_fiber-mt${addrsfx})
-    set(BOOST_FILESYSTEM_LIBRARY
-        optimized boost_filesystem-mt${addrsfx}
-        debug boost_filesystem-mt${addrsfx})
-    set(BOOST_PROGRAM_OPTIONS_LIBRARY
-        optimized boost_program_options-mt${addrsfx}
-        debug boost_program_options-mt${addrsfx})
-    set(BOOST_REGEX_LIBRARY
-        optimized boost_regex-mt${addrsfx}
-        debug boost_regex-mt${addrsfx})
-    set(BOOST_SIGNALS_LIBRARY
-        optimized boost_signals-mt${addrsfx}
-        debug boost_signals-mt${addrsfx})
-    set(BOOST_SYSTEM_LIBRARY
-        optimized boost_system-mt${addrsfx}
-        debug boost_system-mt${addrsfx})
-    set(BOOST_THREAD_LIBRARY
-        optimized boost_thread-mt${addrsfx}
-        debug boost_thread-mt${addrsfx})
-  endif (WINDOWS)
-endif (USESYSTEMLIBS)
+if (WINDOWS)
+  target_link_libraries( ll::boost INTERFACE
+          libboost_context-mt${addrsfx}
+          libboost_fiber-mt${addrsfx}
+          libboost_filesystem-mt${addrsfx}
+          libboost_program_options-mt${addrsfx}
+          libboost_regex-mt${addrsfx}
+          libboost_system-mt${addrsfx}
+          libboost_thread-mt${addrsfx})
+elseif (LINUX)
+  target_link_libraries( ll::boost INTERFACE
+          boost_context-mt${addrsfx}
+          boost_fiber-mt${addrsfx}
+          boost_filesystem-mt${addrsfx}
+          boost_program_options-mt${addrsfx}
+          boost_regex-mt${addrsfx}
+          boost_signals-mt${addrsfx}
+          boost_system-mt${addrsfx}
+          boost_thread-mt${addrsfx})
+elseif (DARWIN)
+  target_link_libraries( ll::boost INTERFACE
+          boost_context-mt${addrsfx}
+          boost_fiber-mt${addrsfx}
+          boost_filesystem-mt${addrsfx}
+          boost_program_options-mt${addrsfx}
+          boost_regex-mt${addrsfx}
+          boost_system-mt${addrsfx}
+          boost_thread-mt${addrsfx})
+endif (WINDOWS)
 
 if (LINUX)
     set(BOOST_SYSTEM_LIBRARY ${BOOST_SYSTEM_LIBRARY} rt)
diff --git a/indra/cmake/BuildPackagesInfo.cmake b/indra/cmake/BuildPackagesInfo.cmake
index 8f8b6b23300d21e1995347fbfa60dd0091cecaeb..659ba9d5795dbaa193f9431b092843602b40b948 100644
--- a/indra/cmake/BuildPackagesInfo.cmake
+++ b/indra/cmake/BuildPackagesInfo.cmake
@@ -16,5 +16,5 @@ add_custom_command(OUTPUT packages-info.txt
   COMMAND ${PYTHON_EXECUTABLE}
           ${CMAKE_SOURCE_DIR}/cmake/run_build_test.py -DAUTOBUILD_ADDRSIZE=${ADDRESS_SIZE} -DAUTOBUILD=${AUTOBUILD_EXECUTABLE}
           ${PYTHON_EXECUTABLE}
-          ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py "${VIEWER_CHANNEL}" "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}" > packages-info.txt
+          ${CMAKE_SOURCE_DIR}/../scripts/packages-formatter.py "${VIEWER_CHANNEL}" "${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}" "${AUTOBUILD_INSTALL_DIR}" > packages-info.txt
   )
diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake
index 157fdd07e4c19f5ee97e5d25ac91dcd92a4bc4a2..b531f29ee2fadc154b2ca054496d623db9587c7a 100644
--- a/indra/cmake/BuildVersion.cmake
+++ b/indra/cmake/BuildVersion.cmake
@@ -19,33 +19,23 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
            message(STATUS "Revision (from autobuild environment): ${VIEWER_VERSION_REVISION}")
 
         else (DEFINED ENV{revision})
-          find_program(MERCURIAL
-                       NAMES hg
-                       PATHS [HKEY_LOCAL_MACHINE\\Software\\TortoiseHG]
-                       PATH_SUFFIXES Mercurial)
-          mark_as_advanced(MERCURIAL)
-          if (MERCURIAL)
-            execute_process(COMMAND ${MERCURIAL} identify --num --rev tip
-                            WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
-                            RESULT_VARIABLE hg_id_result
-                            ERROR_VARIABLE hg_id_error
-                            OUTPUT_VARIABLE VIEWER_VERSION_REVISION
-                            OUTPUT_STRIP_TRAILING_WHITESPACE)
-            if (NOT ${hg_id_result} EQUAL 0)
-              message(SEND_ERROR "Revision number generation failed with output:\n${hg_id_error}")
-            else (NOT ${hg_id_result} EQUAL 0)
-              string(REGEX REPLACE "[^0-9a-f]" "" VIEWER_VERSION_REVISION ${VIEWER_VERSION_REVISION})
-            endif (NOT ${hg_id_result} EQUAL 0)
-            if ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
-              message(STATUS "Revision (from hg) ${VIEWER_VERSION_REVISION}")
-            else ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
-              message(STATUS "Revision not set (repository not found?); using 0")
-              set(VIEWER_VERSION_REVISION 0 )
-            endif ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
-           else (MERCURIAL)
-              message(STATUS "Revision not set: mercurial not found; using 0")
-              set(VIEWER_VERSION_REVISION 0)
-           endif (MERCURIAL)
+            find_program(GIT git)
+            if (DEFINED GIT )
+                execute_process(
+                        COMMAND ${GIT} rev-list --count HEAD
+                        OUTPUT_VARIABLE VIEWER_VERSION_REVISION
+                        OUTPUT_STRIP_TRAILING_WHITESPACE
+                )
+                if ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
+                    message(STATUS "Revision (from git) ${VIEWER_VERSION_REVISION}")
+                else ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
+                    message(STATUS "Revision not set (repository not found?); using 0")
+                    set(VIEWER_VERSION_REVISION 0 )
+                endif ("${VIEWER_VERSION_REVISION}" MATCHES "^[0-9]+$")
+            else (DEFINED GIT )
+                message(STATUS "Revision not set: 'git' found; using 0")
+                set(VIEWER_VERSION_REVISION 0)
+            endif (DEFINED GIT)
         endif (DEFINED ENV{revision})
         message(STATUS "Building '${VIEWER_CHANNEL}' Version ${VIEWER_SHORT_VERSION}.${VIEWER_VERSION_REVISION}")
     else ( EXISTS ${VIEWER_VERSION_BASE_FILE} )
diff --git a/indra/cmake/CEFPlugin.cmake b/indra/cmake/CEFPlugin.cmake
index 7d8bfb1b0f95b39e2fcae5955b39f85bc274d381..9b77becf29ff96ca69a46d41408fce84e498bf20 100644
--- a/indra/cmake/CEFPlugin.cmake
+++ b/indra/cmake/CEFPlugin.cmake
@@ -2,18 +2,14 @@
 include(Linking)
 include(Prebuilt)
 
-if (USESYSTEMLIBS)
-    set(CEFPLUGIN OFF CACHE BOOL
-        "CEFPLUGIN support for the llplugin/llmedia test apps.")
-else (USESYSTEMLIBS)
-    use_prebuilt_binary(dullahan)
-    set(CEFPLUGIN ON CACHE BOOL
-        "CEFPLUGIN support for the llplugin/llmedia test apps.")
-        set(CEF_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/cef)
-endif (USESYSTEMLIBS)
+include_guard()
+add_library( ll::cef INTERFACE IMPORTED )
+
+use_prebuilt_binary(dullahan)
+target_include_directories( ll::cef SYSTEM INTERFACE  ${LIBS_PREBUILT_DIR}/include/cef)
 
 if (WINDOWS)
-    set(CEF_PLUGIN_LIBRARIES
+    target_link_libraries( ll::cef INTERFACE
         libcef.lib
         libcef_dll_wrapper.lib
         dullahan.lib
@@ -29,7 +25,7 @@ elseif (DARWIN)
         message(FATAL_ERROR "CEF not found")
     endif()
 
-    set(CEF_PLUGIN_LIBRARIES
+    target_link_libraries( ll::cef INTERFACE
         ${ARCH_PREBUILT_DIRS_RELEASE}/libcef_dll_wrapper.a
         ${ARCH_PREBUILT_DIRS_RELEASE}/libdullahan.a
         ${APPKIT_LIBRARY}
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index fb3c7216c723ba4cc98acbee2533e72d0b408b2e..1fd83eadff3bb9509152d7b9c40d802076e5d815 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -5,109 +5,79 @@ include(00-Common)
 project(cmake)
 
 set(cmake_SOURCE_FILES
-    CMakeLists.txt
-
-    00-Common.cmake
-    APR.cmake
-    Audio.cmake
-    Boost.cmake
-    bugsplat.cmake
-    BuildVersion.cmake
-    CEFPlugin.cmake
-    CEFPlugin.cmake
-    CMakeCopyIfDifferent.cmake
-    ConfigurePkgConfig.cmake
-    CURL.cmake
-    Copy3rdPartyLibs.cmake
-    DBusGlib.cmake
-    DeploySharedLibs.cmake
-    DragDrop.cmake
-    EXPAT.cmake
-    FindAPR.cmake
-    FindAutobuild.cmake
-    FindGLH.cmake
-    FindHUNSPELL.cmake
-    FindJsonCpp.cmake
-    FindNDOF.cmake
-    FindOpenJPEG.cmake
-    FindSCP.cmake
-    FindURIPARSER.cmake
-    FindXmlRpcEpi.cmake
-    FindZLIBNG.cmake
-    FMODSTUDIO.cmake
-    FreeType.cmake
-    GLEXT.cmake
-    GLH.cmake
-##  GStreamer010Plugin.cmake
-    GoogleMock.cmake
-    Havok.cmake
-    Hunspell.cmake
-    JPEG.cmake
-    JsonCpp.cmake
-    LLAddBuildTest.cmake
-    LLAppearance.cmake
-    LLAudio.cmake
-    LLCharacter.cmake
-    LLCommon.cmake
-    LLCrashLogger.cmake
-    LLImage.cmake
-    LLImageJ2COJ.cmake
-    LLInventory.cmake
-    LLKDU.cmake
-    LLLogin.cmake
-    LLMath.cmake
-    LLMeshOptimizer.cmake
-    LLMessage.cmake
-    LLPhysicsExtensions.cmake
-    LLPlugin.cmake
-    LLPrimitive.cmake
-    LLRender.cmake
-    LLSharedLibs.cmake
-    LLTestCommand.cmake
-    LLUI.cmake
-    LLFileSystem.cmake
-    LLWindow.cmake
-    LLXML.cmake
-    Linking.cmake
-    MediaPluginBase.cmake
-    MESHOPTIMIZER.cmake
-    NDOF.cmake
-    OPENAL.cmake
-    OpenGL.cmake
-    OpenJPEG.cmake
-    OpenSSL.cmake
-    PNG.cmake
-    PluginAPI.cmake
-    Prebuilt.cmake
-    PulseAudio.cmake
-    Python.cmake
-    TemplateCheck.cmake
-    Tut.cmake
-    UI.cmake
-    UnixInstall.cmake
-    URIPARSER.cmake
-    Variables.cmake
-    ViewerMiscLibs.cmake
-    VisualLeakDetector.cmake
-    LibVLCPlugin.cmake
-    XmlRpcEpi.cmake
+        CMakeLists.txt
+        00-Common.cmake
+        APR.cmake
+        Audio.cmake
+        Boost.cmake
+        bugsplat.cmake
+        BuildVersion.cmake
+        CEFPlugin.cmake
+        CEFPlugin.cmake
+        CMakeCopyIfDifferent.cmake
+        ConfigurePkgConfig.cmake
+        CURL.cmake
+        Copy3rdPartyLibs.cmake
+        DBusGlib.cmake
+        DeploySharedLibs.cmake
+        DragDrop.cmake
+        EXPAT.cmake
+        FindAutobuild.cmake
+        FMODSTUDIO.cmake
+        FreeType.cmake
+        GLEXT.cmake
+        GLH.cmake
+        GoogleMock.cmake
+        Havok.cmake
+        Hunspell.cmake
+        JsonCpp.cmake
+        LLAddBuildTest.cmake
+        LLAppearance.cmake
+        LLAudio.cmake
+        LLCommon.cmake
+        LLImage.cmake
+        LLKDU.cmake
+        LLPhysicsExtensions.cmake
+        LLPrimitive.cmake
+        LLSharedLibs.cmake
+        LLTestCommand.cmake
+        LLWindow.cmake
+        Linking.cmake
+        Meshoptimizer.cmake
+        NDOF.cmake
+        OPENAL.cmake
+        OpenGL.cmake
+        OpenJPEG.cmake
+        OpenSSL.cmake
+        PNG.cmake
+        PluginAPI.cmake
+        Prebuilt.cmake
+        PulseAudio.cmake
+        Python.cmake
+        TemplateCheck.cmake
+        Tut.cmake
+        UI.cmake
+        UnixInstall.cmake
+        URIPARSER.cmake
+        Variables.cmake
+        ViewerMiscLibs.cmake
+        VisualLeakDetector.cmake
+        LibVLCPlugin.cmake
+        XmlRpcEpi.cmake
     xxHash.cmake
-    ZLIBNG.cmake
-    )
+        ZLIBNG.cmake
+        )
 
 source_group("Shared Rules" FILES ${cmake_SOURCE_FILES})
 
 set(master_SOURCE_FILES
-    ../CMakeLists.txt
-    )
+        ../CMakeLists.txt
+        )
 
 source_group("Master Rules" FILES ${master_SOURCE_FILES})
 
-set_source_files_properties(${cmake_SOURCE_FILES} ${master_SOURCE_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 add_library(cmake
-            cmake_dummy.cpp
-            ${cmake_SOURCE_FILES}
-            ${master_SOURCE_FILES}
-            )
+        cmake_dummy.cpp
+        ${cmake_SOURCE_FILES}
+        ${master_SOURCE_FILES}
+        )
diff --git a/indra/cmake/CURL.cmake b/indra/cmake/CURL.cmake
index 04afae594dd58ac3f21302502c628e72c615e190..b9f685f37bf52545c23fe54c65ac39d78924e151 100644
--- a/indra/cmake/CURL.cmake
+++ b/indra/cmake/CURL.cmake
@@ -1,19 +1,14 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-set(CURL_FIND_QUIETLY ON)
-set(CURL_FIND_REQUIRED ON)
+include_guard()
+add_library( ll::libcurl INTERFACE IMPORTED )
 
-if (USESYSTEMLIBS)
-  include(FindCURL)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(curl)
-  if (WINDOWS)
-    set(CURL_LIBRARIES 
-    debug libcurld.lib
-    optimized libcurl.lib)
-  else (WINDOWS)
-    set(CURL_LIBRARIES libcurl.a)
-  endif (WINDOWS)
-  set(CURL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
-endif (USESYSTEMLIBS)
+use_system_binary(libcurl)
+use_prebuilt_binary(curl)
+if (WINDOWS)
+  target_link_libraries(ll::libcurl INTERFACE libcurl.lib)
+else (WINDOWS)
+  target_link_libraries(ll::libcurl INTERFACE libcurl.a)
+endif (WINDOWS)
+target_include_directories( ll::libcurl SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index 04b4202ca3de688a2af9aaea9f41c4da30d4d240..1ee2a621f2e8d81f3c63fa1f3041de6643182689 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -6,6 +6,8 @@
 
 include(CMakeCopyIfDifferent)
 include(Linking)
+include(OPENAL)
+include(FMODSTUDIO)
 
 # When we copy our dependent libraries, we almost always want to copy them to
 # both the Release and the RelWithDebInfo staging directories. This has
@@ -13,27 +15,27 @@ include(Linking)
 # copy_if_different commands. Encapsulate that usage.
 # Pass FROM_DIR, TARGETS and the files to copy. TO_DIR is implicit.
 # to_staging_dirs diverges from copy_if_different in that it appends to TARGETS.
-MACRO(to_staging_dirs from_dir targets)
-  foreach(staging_dir
-          "${SHARED_LIB_STAGING_DIR_RELEASE}"
-          "${SHARED_LIB_STAGING_DIR_RELWITHDEBINFO}")
-    copy_if_different("${from_dir}" "${staging_dir}" out_targets ${ARGN})
+macro(to_staging_dirs from_dir targets)
+    set( targetDir "${SHARED_LIB_STAGING_DIR}")
+    copy_if_different("${from_dir}" "${targetDir}" out_targets ${ARGN})
+
     list(APPEND "${targets}" "${out_targets}")
-  endforeach()
-ENDMACRO(to_staging_dirs from_dir to_dir targets)
+endmacro()
 
 ###################################################################
 # set up platform specific lists of files that need to be copied
 ###################################################################
 if(WINDOWS)
-    set(SHARED_LIB_STAGING_DIR_DEBUG            "${SHARED_LIB_STAGING_DIR}/Debug")
-    set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO   "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo")
-    set(SHARED_LIB_STAGING_DIR_RELEASE          "${SHARED_LIB_STAGING_DIR}/Release")
-
     #*******************************
     # VIVOX - *NOTE: no debug version
     set(vivox_lib_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
-    set(slvoice_src_dir "${ARCH_PREBUILT_BIN_RELEASE}")    
+
+    # ND, it seems there is no such thing defined. At least when building a viewer
+    # Does this maybe matter on some LL buildserver? Otherwise this and the snippet using slvoice_src_dir
+    # can all go
+    if( ARCH_PREBUILT_BIN_RELEASE )
+        set(slvoice_src_dir "${ARCH_PREBUILT_BIN_RELEASE}")
+    endif()
     set(slvoice_files SLVoice.exe )
     if (ADDRESS_SIZE EQUAL 64)
         list(APPEND vivox_libs
@@ -84,14 +86,14 @@ if(WINDOWS)
       endif(ADDRESS_SIZE EQUAL 32)
     endif (USE_BUGSPLAT)
 
-    if (FMODSTUDIO)
+    if (TARGET ll::fmodstudio)
         set(debug_files ${debug_files} fmodL.dll)
         set(release_files ${release_files} fmod.dll)
-    endif (FMODSTUDIO)
+    endif ()
 
-    if (OPENAL)
+    if (TARGET ll::openal)
         list(APPEND release_files openal32.dll alut.dll)
-    endif (OPENAL)
+    endif ()
 
     #*******************************
     # Copy MS C runtime dlls, required for packaging.
@@ -105,6 +107,8 @@ if(WINDOWS)
         set(MSVC_VER 140)
     elseif (MSVC_VERSION GREATER_EQUAL 1920 AND MSVC_VERSION LESS 1930) # Visual Studio 2019
         set(MSVC_VER 140)
+    elseif (MSVC_VERSION GREATER_EQUAL 1930 AND MSVC_VERSION LESS 1940) # Visual Studio 2022
+        set(MSVC_VER 140)
     else (MSVC80)
         MESSAGE(WARNING "New MSVC_VERSION ${MSVC_VERSION} of MSVC: adapt Copy3rdPartyLibs.cmake")
     endif (MSVC80)
@@ -148,10 +152,6 @@ if(WINDOWS)
     endforeach()
 
 elseif(DARWIN)
-    set(SHARED_LIB_STAGING_DIR_DEBUG            "${SHARED_LIB_STAGING_DIR}/Debug/Resources")
-    set(SHARED_LIB_STAGING_DIR_RELWITHDEBINFO   "${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/Resources")
-    set(SHARED_LIB_STAGING_DIR_RELEASE          "${SHARED_LIB_STAGING_DIR}/Release/Resources")
-
     set(vivox_lib_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
     set(slvoice_files SLVoice)
     set(vivox_libs
@@ -178,10 +178,10 @@ elseif(DARWIN)
         liburiparser.1.0.27.dylib
        )
 
-    if (FMODSTUDIO)
+    if (TARGET ll::fmodstudio)
       set(debug_files ${debug_files} libfmodL.dylib)
       set(release_files ${release_files} libfmod.dylib)
-    endif (FMODSTUDIO)
+    endif ()
 
 elseif(LINUX)
     # linux is weird, multiple side by side configurations aren't supported
@@ -209,28 +209,30 @@ elseif(LINUX)
     set(release_src_dir "${ARCH_PREBUILT_DIRS_RELEASE}")
     # *FIX - figure out what to do with duplicate libalut.so here -brad
     set(release_files
-        libapr-1.so.0
-        libaprutil-1.so.0
-        libatk-1.0.so
-        libdb-5.1.so
-        ${EXPAT_COPY}
-        libfreetype.so.6.6.2
-        libfreetype.so.6
-        libgmodule-2.0.so
-        libgobject-2.0.so
-        libhunspell-1.3.so.0.0.0
-        libopenal.so
-        libopenjp2.so
-        libuuid.so.16
-        libuuid.so.16.0.22
-        libfontconfig.so.1.8.0
-        libfontconfig.so.1
-       )
+            ${EXPAT_COPY}
+            )
+
+     if( USE_AUTOBUILD_3P )
+         list( APPEND release_files
+                 libapr-1.so.0
+                 libaprutil-1.so.0
+                 libatk-1.0.so
+                 libfreetype.so.6.6.2
+                 libfreetype.so.6
+                 libhunspell-1.3.so.0.0.0
+                 libuuid.so.16
+                 libuuid.so.16.0.22
+                 libfontconfig.so.1.8.0
+                 libfontconfig.so.1
+                 libgmodule-2.0.so
+                 libgobject-2.0.so
+                 )
+     endif()
 
-    if (FMODSTUDIO)
+    if (TARGET ll::fmodstudio)
       set(debug_files ${debug_files} "libfmodL.so")
       set(release_files ${release_files} "libfmod.so")
-    endif (FMODSTUDIO)
+    endif ()
 
 else(WINDOWS)
     message(STATUS "WARNING: unrecognized platform for staging 3rd party libs, skipping...")
@@ -260,13 +262,16 @@ endif(WINDOWS)
 # Curiously, slvoice_files are only copied to SHARED_LIB_STAGING_DIR_RELEASE.
 # It's unclear whether this is oversight or intentional, but anyway leave the
 # single copy_if_different command rather than using to_staging_dirs.
-copy_if_different(
-    ${slvoice_src_dir}
-    "${SHARED_LIB_STAGING_DIR_RELEASE}"
-    out_targets
-    ${slvoice_files}
+
+if( slvoice_src_dir )
+    copy_if_different(
+            ${slvoice_src_dir}
+            "${SHARED_LIB_STAGING_DIR_RELEASE}"
+            out_targets
+            ${slvoice_files}
     )
-list(APPEND third_party_targets ${out_targets})
+    list(APPEND third_party_targets ${out_targets})
+endif()
 
 to_staging_dirs(
     ${vivox_lib_dir}
@@ -280,9 +285,16 @@ to_staging_dirs(
     ${release_files}
     )
 
-if(NOT USESYSTEMLIBS)
-  add_custom_target(
-      stage_third_party_libs ALL
-      DEPENDS ${third_party_targets}
-      )
-endif(NOT USESYSTEMLIBS)
+add_custom_target(
+        stage_third_party_libs ALL
+        DEPENDS ${third_party_targets}
+)
+
+if(DARWIN)
+    # Support our "@executable_path/../Resources" load path for executables
+    # that end up in any of the above SHARED_LIB_STAGING_DIR_MUMBLE
+    # directories.
+    add_custom_command( TARGET stage_third_party_libs POST_BUILD
+            COMMAND cmake -E create_symlink ${SHARED_LIB_STAGING_DIR} ${CMAKE_BINARY_DIR}/sharedlibs/Resources
+            )
+endif()
diff --git a/indra/cmake/DBusGlib.cmake b/indra/cmake/DBusGlib.cmake
index 5e46b6711a1363856fa425684dcec40865a9aa7c..c9b727ca9df7acec98b7dd28b3e5c43855df7a25 100644
--- a/indra/cmake/DBusGlib.cmake
+++ b/indra/cmake/DBusGlib.cmake
@@ -1,29 +1,14 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-if (USESYSTEMLIBS)
-  include(FindPkgConfig)
+add_library( ll::dbus INTERFACE IMPORTED)
 
-  pkg_check_modules(DBUSGLIB REQUIRED dbus-glib-1)
+if( LINUX )
+  # Only define this when not using the prebuild 3ps, lls prebuild is broken
+  if( NOT USE_AUTOBUILD_3P )
+    target_compile_definitions( ll::dbus INTERFACE LL_DBUS_ENABLED )
+  endif()
+  use_system_binary(dbus)
 
-elseif (LINUX)
   use_prebuilt_binary(dbus_glib)
-  set(DBUSGLIB_FOUND ON FORCE BOOL)
-  set(DBUSGLIB_INCLUDE_DIRS
-      ${LIBS_PREBUILT_DIR}/include/dbus
-      )
-  # We don't need to explicitly link against dbus-glib itself, because
-  # the viewer probes for the system's copy at runtime.
-  set(DBUSGLIB_LIBRARIES
-      gobject-2.0
-      glib-2.0
-      )
-endif (USESYSTEMLIBS)
-
-if (DBUSGLIB_FOUND)
-  set(DBUSGLIB ON CACHE BOOL "Build with dbus-glib message bus support.")
-endif (DBUSGLIB_FOUND)
-
-if (DBUSGLIB)
-  add_definitions(-DLL_DBUS_ENABLED=1)
-endif (DBUSGLIB)
+endif()
diff --git a/indra/cmake/DragDrop.cmake b/indra/cmake/DragDrop.cmake
index 73ef59b18fc35724c94e0b8d4a5ade89e63aa246..26e7828830d75c6d4321de07767de2b92db2450e 100644
--- a/indra/cmake/DragDrop.cmake
+++ b/indra/cmake/DragDrop.cmake
@@ -1,20 +1,16 @@
 # -*- cmake -*-
 
-  set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
-
-  if (OS_DRAG_DROP)
+set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
 
+if (OS_DRAG_DROP)
     if (WINDOWS)
-      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
+        add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
     endif (WINDOWS)
-
     if (DARWIN)
-      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
+        add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
     endif (DARWIN)
-
     if (LINUX)
-      add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
+        add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
     endif (LINUX)
-
-  endif (OS_DRAG_DROP)
+endif (OS_DRAG_DROP)
 
diff --git a/indra/cmake/EXPAT.cmake b/indra/cmake/EXPAT.cmake
index cddc71b227525f1d4f6b18879c92b59d2c371f33..327fe8aa72b2cade6c516c9437de703779e19e29 100644
--- a/indra/cmake/EXPAT.cmake
+++ b/indra/cmake/EXPAT.cmake
@@ -1,23 +1,20 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-set(EXPAT_FIND_QUIETLY ON)
-set(EXPAT_FIND_REQUIRED ON)
+include_guard()
+add_library( ll::expat INTERFACE IMPORTED )
 
-if (USESYSTEMLIBS)
-  include(FindEXPAT)
-else (USESYSTEMLIBS)
-    use_prebuilt_binary(expat)
-    if (WINDOWS)
-        set(EXPAT_LIBRARIES libexpatMT)
-        set(EXPAT_COPY libexpatMT.dll)
-    else (WINDOWS)
-        set(EXPAT_LIBRARIES expat)
-        if (DARWIN)
-            set(EXPAT_COPY libexpat.1.dylib libexpat.dylib)
-        else ()
-            set(EXPAT_COPY libexpat.so.1 libexpat.so)
-        endif ()
-    endif (WINDOWS)
-    set(EXPAT_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
-endif (USESYSTEMLIBS)
+use_system_binary(expat)
+use_prebuilt_binary(expat)
+if (WINDOWS)
+    target_link_libraries( ll::expat  INTERFACE libexpatMT )
+    set(EXPAT_COPY libexpatMT.dll)
+else (WINDOWS)
+    target_link_libraries( ll::expat INTERFACE expat )
+    if (DARWIN)
+        set(EXPAT_COPY libexpat.1.dylib libexpat.dylib)
+    else ()
+        set(EXPAT_COPY libexpat.so.1 libexpat.so)
+    endif ()
+endif (WINDOWS)
+target_include_directories( ll::expat SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include )
diff --git a/indra/cmake/ExamplePlugin.cmake b/indra/cmake/ExamplePlugin.cmake
index 5d826c1f66f5eb8c4b5cf57a93463b8fb456b90d..62340354749812d51c7d5e143cc93c8de4d540b2 100644
--- a/indra/cmake/ExamplePlugin.cmake
+++ b/indra/cmake/ExamplePlugin.cmake
@@ -2,15 +2,5 @@
 include(Linking)
 include(Prebuilt)
 
-if (USESYSTEMLIBS)
-    set(EXAMPLEPLUGIN OFF CACHE BOOL
+set(EXAMPLEPLUGIN ON CACHE BOOL
         "EXAMPLEPLUGIN support for the llplugin/llmedia test apps.")
-else (USESYSTEMLIBS)
-    set(EXAMPLEPLUGIN ON CACHE BOOL
-        "EXAMPLEPLUGIN support for the llplugin/llmedia test apps.")
-endif (USESYSTEMLIBS)
-
-if (WINDOWS)
-elseif (DARWIN)
-elseif (LINUX)
-endif (WINDOWS)
diff --git a/indra/cmake/FMODSTUDIO.cmake b/indra/cmake/FMODSTUDIO.cmake
index 8840354ac6c3d53d7d46040f65019fcc7903d66d..c5b21ac4e5acd23d951bb31379b2a18675fce063 100644
--- a/indra/cmake/FMODSTUDIO.cmake
+++ b/indra/cmake/FMODSTUDIO.cmake
@@ -1,16 +1,30 @@
 # -*- cmake -*-
 
+include_guard()
+
 # FMODSTUDIO can be set when launching the make using the argument -DFMODSTUDIO:BOOL=ON
 # When building using proprietary binaries though (i.e. having access to LL private servers),
 # we always build with FMODSTUDIO.
 if (INSTALL_PROPRIETARY)
-  set(FMODSTUDIO ON CACHE BOOL "Using FMODSTUDIO sound library.")
+  set(USE_FMODSTUDIO ON CACHE BOOL "Using FMODSTUDIO sound library.")
 endif (INSTALL_PROPRIETARY)
 
-if (FMODSTUDIO)
+# ND: To streamline arguments passed, switch from FMODSTUDIO to USE_FMODSTUDIO
+# To not break all old build scripts convert old arguments but warn about it
+if(FMODSTUDIO)
+  message( WARNING "Use of the FMODSTUDIO argument is deprecated, please switch to USE_FMODSTUDIO")
+  set(USE_FMODSTUDIO ${FMODSTUDIO})
+endif()
+
+if (USE_FMODSTUDIO)
+  add_library( ll::fmodstudio INTERFACE IMPORTED )
+  target_compile_definitions( ll::fmodstudio INTERFACE LL_FMODSTUDIO=1)
+
   if (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
     # If the path have been specified in the arguments, use that
-    set(FMODSTUDIO_LIBRARIES ${FMODSTUDIO_LIBRARY})
+
+    target_link_libraries(ll::fmodstudio INTERFACE ${FMODSTUDIO_LIBRARY})
+    target_include_directories( ll::fmodstudio SYSTEM INTERFACE  ${FMODSTUDIO_INCLUDE_DIR})
   else (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
     # If not, we're going to try to get the package listed in autobuild.xml
     # Note: if you're not using INSTALL_PROPRIETARY, the package URL should be local (file:/// URL)
@@ -18,21 +32,17 @@ if (FMODSTUDIO)
     include(Prebuilt)
     use_prebuilt_binary(fmodstudio)
     if (WINDOWS)
-      set(FMODSTUDIO_LIBRARY
-          debug fmodL_vc
-          optimized fmod_vc)
+      target_link_libraries( ll::fmodstudio INTERFACE  fmod_vc)
     elseif (DARWIN)
       #despite files being called libfmod.dylib, we are searching for fmod
-      set(FMODSTUDIO_LIBRARY
-          debug fmodL
-          optimized fmod)
+      target_link_libraries( ll::fmodstudio INTERFACE  fmod)
     elseif (LINUX)
-      set(FMODSTUDIO_LIBRARY
-          debug fmodL
-          optimized fmod)
+      target_link_libraries( ll::fmodstudio INTERFACE  fmod)
     endif (WINDOWS)
-    set(FMODSTUDIO_LIBRARIES ${FMODSTUDIO_LIBRARY})
-    set(FMODSTUDIO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/fmodstudio)
+
+    target_include_directories( ll::fmodstudio SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/fmodstudio)
   endif (FMODSTUDIO_LIBRARY AND FMODSTUDIO_INCLUDE_DIR)
-endif (FMODSTUDIO)
+else()
+  set( USE_FMODSTUDIO "OFF")
+endif ()
 
diff --git a/indra/cmake/FindAPR.cmake b/indra/cmake/FindAPR.cmake
deleted file mode 100644
index 906b6c945204ba3b3dc7d078673308c9bbecb83c..0000000000000000000000000000000000000000
--- a/indra/cmake/FindAPR.cmake
+++ /dev/null
@@ -1,94 +0,0 @@
-# -*- cmake -*-
-
-# - Find Apache Portable Runtime
-# Find the APR includes and libraries
-# This module defines
-#  APR_INCLUDE_DIR and APRUTIL_INCLUDE_DIR, where to find apr.h, etc.
-#  APR_LIBRARIES and APRUTIL_LIBRARIES, the libraries needed to use APR.
-#  APR_FOUND and APRUTIL_FOUND, If false, do not try to use APR.
-# also defined, but not for general use are
-#  APR_LIBRARY and APRUTIL_LIBRARY, where to find the APR library.
-
-# APR first.
-
-FIND_PATH(APR_INCLUDE_DIR apr.h
-/usr/local/include/apr-1
-/usr/local/include/apr-1.0
-/usr/include/apr-1
-/usr/include/apr-1.0
-)
-
-SET(APR_NAMES ${APR_NAMES} apr-1)
-FIND_LIBRARY(APR_LIBRARY
-  NAMES ${APR_NAMES}
-  PATHS /usr/lib /usr/local/lib
-  )
-
-IF (APR_LIBRARY AND APR_INCLUDE_DIR)
-    SET(APR_LIBRARIES ${APR_LIBRARY})
-    SET(APR_FOUND "YES")
-ELSE (APR_LIBRARY AND APR_INCLUDE_DIR)
-  SET(APR_FOUND "NO")
-ENDIF (APR_LIBRARY AND APR_INCLUDE_DIR)
-
-
-IF (APR_FOUND)
-   IF (NOT APR_FIND_QUIETLY)
-      MESSAGE(STATUS "Found APR: ${APR_LIBRARIES}")
-   ENDIF (NOT APR_FIND_QUIETLY)
-ELSE (APR_FOUND)
-   IF (APR_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find APR library")
-   ENDIF (APR_FIND_REQUIRED)
-ENDIF (APR_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_APR_INCLUDE_PATH ${APR_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_APR_LIB_PATH ${APR_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  APR_LIBRARY
-  APR_INCLUDE_DIR
-  )
-
-# Next, APRUTIL.
-
-FIND_PATH(APRUTIL_INCLUDE_DIR apu.h
-/usr/local/include/apr-1
-/usr/local/include/apr-1.0
-/usr/include/apr-1
-/usr/include/apr-1.0
-)
-
-SET(APRUTIL_NAMES ${APRUTIL_NAMES} aprutil-1)
-FIND_LIBRARY(APRUTIL_LIBRARY
-  NAMES ${APRUTIL_NAMES}
-  PATHS /usr/lib /usr/local/lib
-  )
-
-IF (APRUTIL_LIBRARY AND APRUTIL_INCLUDE_DIR)
-    SET(APRUTIL_LIBRARIES ${APRUTIL_LIBRARY})
-    SET(APRUTIL_FOUND "YES")
-ELSE (APRUTIL_LIBRARY AND APRUTIL_INCLUDE_DIR)
-  SET(APRUTIL_FOUND "NO")
-ENDIF (APRUTIL_LIBRARY AND APRUTIL_INCLUDE_DIR)
-
-
-IF (APRUTIL_FOUND)
-   IF (NOT APRUTIL_FIND_QUIETLY)
-      MESSAGE(STATUS "Found APRUTIL: ${APRUTIL_LIBRARIES}")
-   ENDIF (NOT APRUTIL_FIND_QUIETLY)
-ELSE (APRUTIL_FOUND)
-   IF (APRUTIL_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find APRUTIL library")
-   ENDIF (APRUTIL_FIND_REQUIRED)
-ENDIF (APRUTIL_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_APRUTIL_INCLUDE_PATH ${APRUTIL_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_APRUTIL_LIB_PATH ${APRUTIL_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  APRUTIL_LIBRARY
-  APRUTIL_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindGLH.cmake b/indra/cmake/FindGLH.cmake
deleted file mode 100644
index 3d16adaf03d399784f6bb1478472ead07d9b1dd4..0000000000000000000000000000000000000000
--- a/indra/cmake/FindGLH.cmake
+++ /dev/null
@@ -1,30 +0,0 @@
-# -*- cmake -*-
-
-# - Find GLH
-# Find the Graphic Library Helper includes.
-# This module defines
-#  GLH_INCLUDE_DIR, where to find glh/glh_linear.h.
-#  GLH_FOUND, If false, do not try to use GLH.
-
-find_path(GLH_INCLUDE_DIR glh/glh_linear.h
-    NO_SYSTEM_ENVIRONMENT_PATH
-    )
-
-if (GLH_INCLUDE_DIR)
-  set(GLH_FOUND "YES")
-else (GLH_INCLUDE_DIR)
-  set(GLH_FOUND "NO")
-endif (GLH_INCLUDE_DIR)
-
-if (GLH_FOUND)
-  if (NOT GLH_FIND_QUIETLY)
-    message(STATUS "Found GLH: ${GLH_INCLUDE_DIR}")
-    set(GLH_FIND_QUIETLY TRUE) # Only alert us the first time
-  endif (NOT GLH_FIND_QUIETLY)
-else (GLH_FOUND)
-  if (GLH_FIND_REQUIRED)
-    message(FATAL_ERROR "Could not find GLH")
-  endif (GLH_FIND_REQUIRED)
-endif (GLH_FOUND)
-
-mark_as_advanced(GLH_INCLUDE_DIR)
diff --git a/indra/cmake/FindGooglePerfTools.cmake b/indra/cmake/FindGooglePerfTools.cmake
deleted file mode 100644
index bb125d538e04a7a5e45cac165ed407efb7fcf081..0000000000000000000000000000000000000000
--- a/indra/cmake/FindGooglePerfTools.cmake
+++ /dev/null
@@ -1,66 +0,0 @@
-# -*- cmake -*-
-
-# - Find Google perftools
-# Find the Google perftools includes and libraries
-# This module defines
-#  GOOGLE_PERFTOOLS_INCLUDE_DIR, where to find heap-profiler.h, etc.
-#  GOOGLE_PERFTOOLS_FOUND, If false, do not try to use Google perftools.
-# also defined for general use are
-#  TCMALLOC_LIBRARIES, where to find the tcmalloc library.
-#  STACKTRACE_LIBRARIES, where to find the stacktrace library.
-#  PROFILER_LIBRARIES, where to find the profiler library.
-
-FIND_PATH(GOOGLE_PERFTOOLS_INCLUDE_DIR google/heap-profiler.h
-/usr/local/include
-/usr/include
-)
-
-SET(TCMALLOC_NAMES ${TCMALLOC_NAMES} tcmalloc)
-FIND_LIBRARY(TCMALLOC_LIBRARY
-  NAMES ${TCMALLOC_NAMES}
-  PATHS /usr/lib /usr/local/lib
-  )
-
-IF (TCMALLOC_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR)
-    SET(TCMALLOC_LIBRARIES ${TCMALLOC_LIBRARY})
-    SET(GOOGLE_PERFTOOLS_FOUND "YES")
-ELSE (TCMALLOC_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR)
-  SET(GOOGLE_PERFTOOLS_FOUND "NO")
-ENDIF (TCMALLOC_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR)
-
-SET(STACKTRACE_NAMES ${STACKTRACE_NAMES} stacktrace)
-FIND_LIBRARY(STACKTRACE_LIBRARY
-  NAMES ${STACKTRACE_LIBRARY}
-  PATHS /usr/lib /usr/local/lib
-  )
-
-IF (STACKTRACE_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR)
-    SET(STACKTRACE_LIBRARIES ${STACKTRACE_LIBRARY})
-ENDIF (STACKTRACE_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR)
-
-SET(PROFILER_NAMES ${PROFILER_NAMES} profiler)
-FIND_LIBRARY(PROFILER_LIBRARY
-  NAMES ${PROFILER_LIBRARY}
-  PATHS /usr/lib /usr/local/lib
-  )
-
-IF (PROFILER_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR)
-    SET(PROFILER_LIBRARIES ${PROFILER_LIBRARY})
-ENDIF (PROFILER_LIBRARY AND GOOGLE_PERFTOOLS_INCLUDE_DIR)
-
-IF (GOOGLE_PERFTOOLS_FOUND)
-   IF (NOT GOOGLE_PERFTOOLS_FIND_QUIETLY)
-      MESSAGE(STATUS "Found Google perftools: ${GOOGLE_PERFTOOLS_LIBRARIES}")
-   ENDIF (NOT GOOGLE_PERFTOOLS_FIND_QUIETLY)
-ELSE (GOOGLE_PERFTOOLS_FOUND)
-   IF (GOOGLE_PERFTOOLS_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find Google perftools library")
-   ENDIF (GOOGLE_PERFTOOLS_FIND_REQUIRED)
-ENDIF (GOOGLE_PERFTOOLS_FOUND)
-
-MARK_AS_ADVANCED(
-  TCMALLOC_LIBRARY
-  STACKTRACE_LIBRARY
-  PROFILER_LIBRARY
-  GOOGLE_PERFTOOLS_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindHUNSPELL.cmake b/indra/cmake/FindHUNSPELL.cmake
deleted file mode 100644
index d411bdb9e5eba98c57ecca9f96c0cefc7f11a7f1..0000000000000000000000000000000000000000
--- a/indra/cmake/FindHUNSPELL.cmake
+++ /dev/null
@@ -1,38 +0,0 @@
-# -*- cmake -*-
-
-# - Find HUNSPELL
-# This module defines
-#  HUNSPELL_INCLUDE_DIR, where to find libhunspell.h, etc.
-#  HUNSPELL_LIBRARY, the library needed to use HUNSPELL.
-#  HUNSPELL_FOUND, If false, do not try to use HUNSPELL.
-
-find_path(HUNSPELL_INCLUDE_DIR hunspell.h
-  PATH_SUFFIXES hunspell
-  )
-
-set(HUNSPELL_NAMES ${HUNSPELL_NAMES} libhunspell-1.3 libhunspell)
-find_library(HUNSPELL_LIBRARY
-  NAMES ${HUNSPELL_NAMES}
-  )
-
-if (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
-  set(HUNSPELL_FOUND "YES")
-else (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
-  set(HUNSPELL_FOUND "NO")
-endif (HUNSPELL_LIBRARY AND HUNSPELL_INCLUDE_DIR)
-
-
-if (HUNSPELL_FOUND)
-  if (NOT HUNSPELL_FIND_QUIETLY)
-    message(STATUS "Found Hunspell: Library in '${HUNSPELL_LIBRARY}' and header in '${HUNSPELL_INCLUDE_DIR}' ")
-  endif (NOT HUNSPELL_FIND_QUIETLY)
-else (HUNSPELL_FOUND)
-  if (HUNSPELL_FIND_REQUIRED)
-    message(FATAL_ERROR " * * *\nCould not find HUNSPELL library! * * *")
-  endif (HUNSPELL_FIND_REQUIRED)
-endif (HUNSPELL_FOUND)
-
-mark_as_advanced(
-  HUNSPELL_LIBRARY
-  HUNSPELL_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindJsonCpp.cmake b/indra/cmake/FindJsonCpp.cmake
deleted file mode 100644
index 9398779cff9a87fe885337d7eba4b605f4325b94..0000000000000000000000000000000000000000
--- a/indra/cmake/FindJsonCpp.cmake
+++ /dev/null
@@ -1,60 +0,0 @@
-# -*- cmake -*-
-
-# - Find JSONCpp
-# Find the JSONCpp includes and library
-# This module defines
-#  JSONCPP_INCLUDE_DIR, where to find json.h, etc.
-#  JSONCPP_LIBRARIES, the libraries needed to use jsoncpp.
-#  JSONCPP_FOUND, If false, do not try to use jsoncpp.
-#  also defined, but not for general use are
-#  JSONCPP_LIBRARY, where to find the jsoncpp library.
-
-FIND_PATH(JSONCPP_INCLUDE_DIR jsoncpp/json.h
-/usr/local/include
-/usr/include
-)
-
-# Get the GCC compiler version
-EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
-            ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion
-            OUTPUT_VARIABLE _gcc_COMPILER_VERSION
-            OUTPUT_STRIP_TRAILING_WHITESPACE
-            )
-
-# Try to find a library that was compiled with the same compiler version as we currently use.
-SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson_linux-gcc-${_gcc_COMPILER_VERSION}_libmt.so)
-IF (USESYSTEMLIBS)
-    # On standalone, assume that the system installed library was compiled with the used compiler.
-    SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson.so)
-ENDIF (USESYSTEMLIBS)
-FIND_LIBRARY(JSONCPP_LIBRARY
-  NAMES ${JSONCPP_NAMES}
-  PATHS /usr/lib /usr/local/lib
-  )
-
-IF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
-    SET(JSONCPP_LIBRARIES ${JSONCPP_LIBRARY})
-    SET(JSONCPP_FOUND "YES")
-ELSE (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
-  SET(JSONCPP_FOUND "NO")
-ENDIF (JSONCPP_LIBRARY AND JSONCPP_INCLUDE_DIR)
-
-
-IF (JSONCPP_FOUND)
-   IF (NOT JSONCPP_FIND_QUIETLY)
-      MESSAGE(STATUS "Found JSONCpp: ${JSONCPP_LIBRARIES}")
-   ENDIF (NOT JSONCPP_FIND_QUIETLY)
-ELSE (JSONCPP_FOUND)
-   IF (JSONCPP_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find JSONCpp library")
-   ENDIF (JSONCPP_FIND_REQUIRED)
-ENDIF (JSONCPP_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_JSONCPP_INCLUDE_PATH ${JSONCPP_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_JSONCPP_LIB_PATH ${JSONCPP_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  JSONCPP_LIBRARY
-  JSONCPP_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindNDOF.cmake b/indra/cmake/FindNDOF.cmake
deleted file mode 100644
index 6dcf590a53d5f77cb6614752d8f78f0ef0336f30..0000000000000000000000000000000000000000
--- a/indra/cmake/FindNDOF.cmake
+++ /dev/null
@@ -1,39 +0,0 @@
-# -*- cmake -*-
-
-# - Find NDOF
-# Find the NDOF includes and library
-# This module defines
-#  NDOF_INCLUDE_DIR, where to find ndofdev_external.h, etc.
-#  NDOF_LIBRARY, the library needed to use NDOF.
-#  NDOF_FOUND, If false, do not try to use NDOF.
-
-find_path(NDOF_INCLUDE_DIR ndofdev_external.h
-  PATH_SUFFIXES ndofdev
-  )
-
-set(NDOF_NAMES ${NDOF_NAMES} ndofdev libndofdev)
-find_library(NDOF_LIBRARY
-  NAMES ${NDOF_NAMES}
-  )
-
-if (NDOF_LIBRARY AND NDOF_INCLUDE_DIR)
-  set(NDOF_FOUND "YES")
-else (NDOF_LIBRARY AND NDOF_INCLUDE_DIR)
-  set(NDOF_FOUND "NO")
-endif (NDOF_LIBRARY AND NDOF_INCLUDE_DIR)
-
-
-if (NDOF_FOUND)
-  if (NOT NDOF_FIND_QUIETLY)
-    message(STATUS "Found NDOF: Library in '${NDOF_LIBRARY}' and header in '${NDOF_INCLUDE_DIR}' ")
-  endif (NOT NDOF_FIND_QUIETLY)
-else (NDOF_FOUND)
-  if (NDOF_FIND_REQUIRED)
-    message(FATAL_ERROR " * * *\nCould not find NDOF library!\nIf you don't need Space Navigator Joystick support you can skip this test by configuring with -DNDOF:BOOL=OFF\n * * *")
-  endif (NDOF_FIND_REQUIRED)
-endif (NDOF_FOUND)
-
-mark_as_advanced(
-  NDOF_LIBRARY
-  NDOF_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindOpenJPEG.cmake b/indra/cmake/FindOpenJPEG.cmake
deleted file mode 100644
index 2d4353b54f991881e9620da269c8a86aee1433d5..0000000000000000000000000000000000000000
--- a/indra/cmake/FindOpenJPEG.cmake
+++ /dev/null
@@ -1,51 +0,0 @@
-# -*- cmake -*-
-
-# - Find OpenJPEG
-# Find the OpenJPEG includes and library
-# This module defines
-#  OPENJPEG_INCLUDE_DIR, where to find openjpeg.h, etc.
-#  OPENJPEG_LIBRARIES, the libraries needed to use OpenJPEG.
-#  OPENJPEG_FOUND, If false, do not try to use OpenJPEG.
-# also defined, but not for general use are
-#  OPENJPEG_LIBRARY, where to find the OpenJPEG library.
-
-FIND_PATH(OPENJPEG_INCLUDE_DIR openjpeg.h
-/usr/local/include/openjpeg
-/usr/local/include
-/usr/include/openjpeg
-/usr/include
-include/openjpeg
-)
-
-SET(OPENJPEG_NAMES ${OPENJPEG_NAMES} openjp2)
-FIND_LIBRARY(OPENJPEG_LIBRARY
-  NAMES ${OPENJPEG_NAMES}
-  PATHS /usr/lib /usr/local/lib
-  )
-
-IF (OPENJPEG_LIBRARY AND OPENJPEG_INCLUDE_DIR)
-    SET(OPENJPEG_LIBRARIES ${OPENJPEG_LIBRARY})
-    SET(OPENJPEG_FOUND "YES")
-ELSE (OPENJPEG_LIBRARY AND OPENJPEG_INCLUDE_DIR)
-  SET(OPENJPEG_FOUND "NO")
-ENDIF (OPENJPEG_LIBRARY AND OPENJPEG_INCLUDE_DIR)
-
-
-IF (OPENJPEG_FOUND)
-   IF (NOT OPENJPEG_FIND_QUIETLY)
-      MESSAGE(STATUS "Found OpenJPEG: ${OPENJPEG_LIBRARIES}")
-   ENDIF (NOT OPENJPEG_FIND_QUIETLY)
-ELSE (OPENJPEG_FOUND)
-   IF (OPENJPEG_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find OpenJPEG library")
-   ENDIF (OPENJPEG_FIND_REQUIRED)
-ENDIF (OPENJPEG_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_OPENJPEG_INCLUDE_PATH ${OPENJPEG_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_OPENJPEG_LIB_PATH ${OPENJPEG_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  OPENJPEG_LIBRARY
-  OPENJPEG_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindURIPARSER.cmake b/indra/cmake/FindURIPARSER.cmake
deleted file mode 100644
index 8ab9f0f4ed267302b6e7b71b08c3edb903ebd556..0000000000000000000000000000000000000000
--- a/indra/cmake/FindURIPARSER.cmake
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- cmake -*-
-
-# - Find uriparser
-# Find the URIPARSER includes and library
-# This module defines
-#  URIPARSER_INCLUDE_DIRS, where to find uriparser.h, etc.
-#  URIPARSER_LIBRARIES, the libraries needed to use uriparser.
-#  URIPARSER_FOUND, If false, do not try to use uriparser.
-#
-# This FindURIPARSER is about 43 times as fast the one provided with cmake (2.8.x),
-# because it doesn't look up the version of uriparser, resulting in a dramatic
-# speed up for configure (from 4 minutes 22 seconds to 6 seconds).
-#
-# Note: Since this file is only used for standalone, the windows
-# specific parts were left out.
-
-FIND_PATH(URIPARSER_INCLUDE_DIR uriparser/uri.h
-  NO_SYSTEM_ENVIRONMENT_PATH
-  )
-
-FIND_LIBRARY(URIPARSER_LIBRARY uriparser)
-
-if (URIPARSER_LIBRARY AND URIPARSER_INCLUDE_DIR)
-  SET(URIPARSER_INCLUDE_DIRS ${URIPARSER_INCLUDE_DIR})
-  SET(URIPARSER_LIBRARIES ${URIPARSER_LIBRARY})
-  SET(URIPARSER_FOUND "YES")
-else (URIPARSER_LIBRARY AND URIPARSER_INCLUDE_DIR)
-  SET(URIPARSER_FOUND "NO")
-endif (URIPARSER_LIBRARY AND URIPARSER_INCLUDE_DIR)
-
-if (URIPARSER_FOUND)
-  if (NOT URIPARSER_FIND_QUIETLY)
-    message(STATUS "Found URIPARSER: ${URIPARSER_LIBRARIES}")
-    SET(URIPARSER_FIND_QUIETLY TRUE)
-  endif (NOT URIPARSER_FIND_QUIETLY)
-else (URIPARSER_FOUND)
-  if (URIPARSER_FIND_REQUIRED)
-    message(FATAL_ERROR "Could not find URIPARSER library")
-  endif (URIPARSER_FIND_REQUIRED)
-endif (URIPARSER_FOUND)
-
-mark_as_advanced(
-  URIPARSER_LIBRARY
-  URIPARSER_INCLUDE_DIR
-  )
-
diff --git a/indra/cmake/FindXmlRpcEpi.cmake b/indra/cmake/FindXmlRpcEpi.cmake
deleted file mode 100644
index ba217e74676f636b16403c9cd82a93952159a13a..0000000000000000000000000000000000000000
--- a/indra/cmake/FindXmlRpcEpi.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- cmake -*-
-
-# - Find XMLRPC-EPI
-# Find the XMLRPC-EPI includes and library
-# This module defines
-#  XMLRPCEPI_INCLUDE_DIR, where to find jpeglib.h, etc.
-#  XMLRPCEPI_LIBRARIES, the libraries needed to use XMLRPC-EPI.
-#  XMLRPCEPI_FOUND, If false, do not try to use XMLRPC-EPI.
-# also defined, but not for general use are
-#  XMLRPCEPI_LIBRARY, where to find the XMLRPC-EPI library.
-
-FIND_PATH(XMLRPCEPI_INCLUDE_DIR xmlrpc-epi/xmlrpc.h
-/usr/local/include
-/usr/include
-)
-
-SET(XMLRPCEPI_NAMES ${XMLRPCEPI_NAMES} xmlrpc-epi)
-FIND_LIBRARY(XMLRPCEPI_LIBRARY
-  NAMES ${XMLRPCEPI_NAMES}
-  PATHS /usr/lib /usr/local/lib
-  )
-
-IF (XMLRPCEPI_LIBRARY AND XMLRPCEPI_INCLUDE_DIR)
-    SET(XMLRPCEPI_LIBRARIES ${XMLRPCEPI_LIBRARY})
-    SET(XMLRPCEPI_FOUND "YES")
-ELSE (XMLRPCEPI_LIBRARY AND XMLRPCEPI_INCLUDE_DIR)
-  SET(XMLRPCEPI_FOUND "NO")
-ENDIF (XMLRPCEPI_LIBRARY AND XMLRPCEPI_INCLUDE_DIR)
-
-
-IF (XMLRPCEPI_FOUND)
-   IF (NOT XMLRPCEPI_FIND_QUIETLY)
-      MESSAGE(STATUS "Found XMLRPC-EPI: ${XMLRPCEPI_LIBRARIES}")
-   ENDIF (NOT XMLRPCEPI_FIND_QUIETLY)
-ELSE (XMLRPCEPI_FOUND)
-   IF (XMLRPCEPI_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find XMLRPC-EPI library")
-   ENDIF (XMLRPCEPI_FIND_REQUIRED)
-ENDIF (XMLRPCEPI_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_XMLRPCEPI_INCLUDE_PATH ${XMLRPCEPI_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_XMLRPCEPI_LIB_PATH ${XMLRPCEPI_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  XMLRPCEPI_LIBRARY
-  XMLRPCEPI_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindZLIBNG.cmake b/indra/cmake/FindZLIBNG.cmake
deleted file mode 100644
index 6e3c8cdddbfe283f10da559e345655f8dafe055e..0000000000000000000000000000000000000000
--- a/indra/cmake/FindZLIBNG.cmake
+++ /dev/null
@@ -1,46 +0,0 @@
-# -*- cmake -*-
-
-# - Find zlib-ng
-# Find the ZLIB includes and library
-# This module defines
-#  ZLIBNG_INCLUDE_DIRS, where to find zlib.h, etc.
-#  ZLIBNG_LIBRARIES, the libraries needed to use zlib.
-#  ZLIBNG_FOUND, If false, do not try to use zlib.
-#
-# This FindZLIBNG is about 43 times as fast the one provided with cmake (2.8.x),
-# because it doesn't look up the version of zlib, resulting in a dramatic
-# speed up for configure (from 4 minutes 22 seconds to 6 seconds).
-#
-# Note: Since this file is only used for standalone, the windows
-# specific parts were left out.
-
-FIND_PATH(ZLIBNG_INCLUDE_DIR zlib.h
-  NO_SYSTEM_ENVIRONMENT_PATH
-  )
-
-FIND_LIBRARY(ZLIBNG_LIBRARY z)
-
-if (ZLIBNG_LIBRARY AND ZLIBNG_INCLUDE_DIR)
-  SET(ZLIBNG_INCLUDE_DIRS ${ZLIBNG_INCLUDE_DIR})
-  SET(ZLIBNG_LIBRARIES ${ZLIBNG_LIBRARY})
-  SET(ZLIBNG_FOUND "YES")
-else (ZLIBNG_LIBRARY AND ZLIBNG_INCLUDE_DIR)
-  SET(ZLIBNG_FOUND "NO")
-endif (ZLINGB_LIBRARY AND ZLIBNG_INCLUDE_DIR)
-
-if (ZLIBNG_FOUND)
-  if (NOT ZLIBNG_FIND_QUIETLY)
-    message(STATUS "Found ZLIBNG: ${ZLIBNG_LIBRARIES}")
-    SET(ZLIBNG_FIND_QUIETLY TRUE)
-  endif (NOT ZLIBNG_FIND_QUIETLY)
-else (ZLIBNG_FOUND)
-  if (ZLIBNG_FIND_REQUIRED)
-    message(FATAL_ERROR "Could not find ZLIBNG library")
-  endif (ZLIBNG_FIND_REQUIRED)
-endif (ZLIBNG_FOUND)
-
-mark_as_advanced(
-  ZLIBNG_LIBRARY
-  ZLIBNG_INCLUDE_DIR
-  )
-
diff --git a/indra/cmake/FreeType.cmake b/indra/cmake/FreeType.cmake
index a36485f6d0fb6cf4f2c5a768cbb98d316f193336..77140af6413c2a7150e448216bc8a9e4087f74c7 100644
--- a/indra/cmake/FreeType.cmake
+++ b/indra/cmake/FreeType.cmake
@@ -1,14 +1,11 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-if (USESYSTEMLIBS)
-  include(FindPkgConfig)
+include_guard()
+add_library( ll::freetype INTERFACE IMPORTED )
 
-  pkg_check_modules(FREETYPE REQUIRED freetype2)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(freetype)
-  set(FREETYPE_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/freetype2/)
-  set(FREETYPE_LIBRARIES freetype)
-endif (USESYSTEMLIBS)
+use_system_binary(freetype)
+use_prebuilt_binary(freetype)
+target_include_directories( ll::freetype SYSTEM INTERFACE  ${LIBS_PREBUILT_DIR}/include/freetype2/)
+target_link_libraries( ll::freetype INTERFACE freetype )
 
-link_directories(${FREETYPE_LIBRARY_DIRS})
diff --git a/indra/cmake/GLEXT.cmake b/indra/cmake/GLEXT.cmake
index a74964420240ead615aadbcc10394b59cd1ccf8e..a780966f0c2e6c02b94dcee210e6b08fa87f8307 100644
--- a/indra/cmake/GLEXT.cmake
+++ b/indra/cmake/GLEXT.cmake
@@ -1,8 +1,9 @@
 # -*- cmake -*-
 include(Prebuilt)
+include(GLH)
+
+add_library( ll::glext INTERFACE IMPORTED )
+use_system_binary(glext)
+use_prebuilt_binary(glext)
+
 
-if (NOT USESYSTEMLIBS)
-  use_prebuilt_binary(glext)
-  use_prebuilt_binary(glh_linear)
-  set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-endif (NOT USESYSTEMLIBS)
diff --git a/indra/cmake/GLH.cmake b/indra/cmake/GLH.cmake
index d5262f2efa79acafca6fa6661a2bd81d6dcbbdd1..0cefc3543ad158a9c30899620ad2680acfc1d248 100644
--- a/indra/cmake/GLH.cmake
+++ b/indra/cmake/GLH.cmake
@@ -1,11 +1,7 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-set(GLH_FIND_REQUIRED TRUE)
-set(GLH_FIND_QUIETLY TRUE)
+add_library( ll::glh_linear INTERFACE IMPORTED )
 
-if (USESYSTEMLIBS)
-  include(FindGLH)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(glh_linear)
-endif (USESYSTEMLIBS)
+use_system_binary( glh_linear )
+use_prebuilt_binary(glh_linear)
diff --git a/indra/cmake/GStreamer010Plugin.cmake b/indra/cmake/GStreamer010Plugin.cmake
index 3fbc40ef8f2f7bdaabc1c24e4666684c61acfbad..61f6f7403360ab62348f485d8135ab7b212234dc 100644
--- a/indra/cmake/GStreamer010Plugin.cmake
+++ b/indra/cmake/GStreamer010Plugin.cmake
@@ -1,38 +1,12 @@
 # -*- cmake -*-
 include(Prebuilt)
+if (NOT LINUX)
+  return()
+endif()
 
-if (USESYSTEMLIBS)
-  include(FindPkgConfig)
+add_library( ll::gstreamer INTERFACE IMPORTED )
+target_compile_definitions( ll::gstreamer INTERFACE LL_GSTREAMER010_ENABLED=1)
+use_system_binary(gstreamer)
 
-  pkg_check_modules(GSTREAMER010 REQUIRED gstreamer-0.10)
-  pkg_check_modules(GSTREAMER010_PLUGINS_BASE REQUIRED gstreamer-plugins-base-0.10)
-elseif (LINUX)
-  use_prebuilt_binary(gstreamer)
-  # possible libxml2 should have its own .cmake file instead
-  use_prebuilt_binary(libxml2)
-  set(GSTREAMER010_FOUND ON FORCE BOOL)
-  set(GSTREAMER010_PLUGINS_BASE_FOUND ON FORCE BOOL)
-  set(GSTREAMER010_INCLUDE_DIRS
-      ${LIBS_PREBUILT_DIR}/include/gstreamer-0.10
-      ${LIBS_PREBUILT_DIR}/include/glib-2.0
-      ${LIBS_PREBUILT_DIR}/include/libxml2
-      )
-  # We don't need to explicitly link against gstreamer itself, because
-  # LLMediaImplGStreamer probes for the system's copy at runtime.
-  set(GSTREAMER010_LIBRARIES
-      gobject-2.0
-      gmodule-2.0
-      dl
-      gthread-2.0
-      glib-2.0
-      )
-endif (USESYSTEMLIBS)
-
-if (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND)
-  set(GSTREAMER010 ON CACHE BOOL "Build with GStreamer-0.10 streaming media support.")
-endif (GSTREAMER010_FOUND AND GSTREAMER010_PLUGINS_BASE_FOUND)
-
-if (GSTREAMER010)
-  add_definitions(-DLL_GSTREAMER010_ENABLED=1)
-endif (GSTREAMER010)
+use_prebuilt_binary(gstreamer)
 
diff --git a/indra/cmake/GoogleMock.cmake b/indra/cmake/GoogleMock.cmake
index 5a00546927d401e7a861bfab473178998fc7984a..e4520fe96ebe973d99f1fd42edd2f4a82c718fea 100644
--- a/indra/cmake/GoogleMock.cmake
+++ b/indra/cmake/GoogleMock.cmake
@@ -2,27 +2,31 @@
 include(Prebuilt)
 include(Linking)
 
+include_guard()
+
+add_library( ll::googlemock INTERFACE IMPORTED )
+if(USE_CONAN)
+  target_link_libraries( ll::googlemock INTERFACE  CONAN_PKG::gtest )
+
+  #Not very nice, but for the moment we need this for tut.hpp
+  target_include_directories( ll::googlemock SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include ) 
+  return()
+endif()
+
 use_prebuilt_binary(googlemock)
 
-set(GOOGLEMOCK_INCLUDE_DIRS
-    ${LIBS_PREBUILT_DIR}/include)
+target_include_directories( ll::googlemock SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include )
 
 if (LINUX)
     # VWR-24366: gmock is underlinked, it needs gtest.
-    set(GOOGLEMOCK_LIBRARIES
-        gmock -Wl,--no-as-needed
-        gtest -Wl,--as-needed)
+    target_link_libraries( ll::googlemock INTERFACE gmock gtest)
 elseif(WINDOWS)
-    set(GOOGLEMOCK_LIBRARIES
-        gmock)
-    set(GOOGLEMOCK_INCLUDE_DIRS
-        ${LIBS_PREBUILT_DIR}/include
-        ${LIBS_PREBUILT_DIR}/include/gmock
-        ${LIBS_PREBUILT_DIR}/include/gmock/boost/tr1/tr1)
+    target_link_libraries( ll::googlemock INTERFACE gmock)
+    target_include_directories( ll::googlemock SYSTEM INTERFACE
+            ${LIBS_PREBUILT_DIR}/include
+            ${LIBS_PREBUILT_DIR}/include/gmock)
 elseif(DARWIN)
-    set(GOOGLEMOCK_LIBRARIES
-        gmock
-        gtest)
+    target_link_libraries( ll::googlemock INTERFACE gmock gtest)
 endif(LINUX)
 
 
diff --git a/indra/cmake/Havok.cmake b/indra/cmake/Havok.cmake
index 811a126b8fbc1407a650d74ffaf6b63bbc1b4142..652760e626c227fe0a4ab3f5d985dbf56044b534 100644
--- a/indra/cmake/Havok.cmake
+++ b/indra/cmake/Havok.cmake
@@ -1,7 +1,6 @@
 # -*- cmake -*-
 include(Prebuilt)
-if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
-set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+include_guard()
 
 use_prebuilt_binary(havok-source)
 
@@ -124,4 +123,3 @@ foreach(HAVOK_LIB ${HAVOK_LIBS})
   endif (LINUX)
 endforeach(HAVOK_LIB)
 
-endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/Hunspell.cmake b/indra/cmake/Hunspell.cmake
index 06227b3fe2336190d3277444c9b1623ac95d1d34..bb037c0237b995c1b5e014c6278034e0e86ad4fd 100644
--- a/indra/cmake/Hunspell.cmake
+++ b/indra/cmake/Hunspell.cmake
@@ -1,22 +1,17 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-set(HUNSPELL_FIND_QUIETLY ON)
-set(HUNSPELL_FIND_REQUIRED ON)
+include_guard()
+use_prebuilt_binary(dictionaries)
 
-if (USESYSTEMLIBS)
-  include(FindHUNSPELL)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(libhunspell)
-  if (WINDOWS)
-    set(HUNSPELL_LIBRARY libhunspell)
-  elseif(DARWIN)
-    set(HUNSPELL_LIBRARY hunspell-1.3)
-  elseif(LINUX)
-    set(HUNSPELL_LIBRARY hunspell-1.3)
-  else()
-    message(FATAL_ERROR "Invalid platform")
-  endif()
-  set(HUNSPELL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/hunspell)
-  use_prebuilt_binary(dictionaries)
-endif (USESYSTEMLIBS)
+add_library( ll::hunspell INTERFACE IMPORTED )
+use_system_binary(hunspell)
+use_prebuilt_binary(libhunspell)
+if (WINDOWS)
+  target_link_libraries( ll::hunspell INTERFACE libhunspell)
+elseif(DARWIN)
+  target_link_libraries( ll::hunspell INTERFACE hunspell-1.3)
+elseif(LINUX)
+  target_link_libraries( ll::hunspell INTERFACE hunspell-1.3)
+endif()
+target_include_directories( ll::hunspell SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/hunspell)
diff --git a/indra/cmake/JPEG.cmake b/indra/cmake/JPEG.cmake
index d6da22aecc1f0c58e144b32ced8a31626a8ad095..252d7852d4efc1b408414874a30cffbc99a194df 100644
--- a/indra/cmake/JPEG.cmake
+++ b/indra/cmake/JPEG.cmake
@@ -2,19 +2,17 @@
 include(Prebuilt)
 
 include(Linking)
-set(JPEG_FIND_QUIETLY ON)
-set(JPEG_FIND_REQUIRED ON)
 
-if (USESYSTEMLIBS)
-  include(FindJPEG)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(jpeglib)
-  if (LINUX)
-    set(JPEG_LIBRARIES jpeg)
-  elseif (DARWIN)
-    set(JPEG_LIBRARIES jpeg)
-  elseif (WINDOWS)
-    set(JPEG_LIBRARIES jpeglib)
-  endif (LINUX)
-  set(JPEG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
-endif (USESYSTEMLIBS)
+include_guard()
+add_library( ll::libjpeg INTERFACE IMPORTED )
+
+use_system_binary(libjpeg)
+use_prebuilt_binary(jpeglib)
+if (LINUX)
+  target_link_libraries( ll::libjpeg INTERFACE jpeg)
+elseif (DARWIN)
+  target_link_libraries( ll::libjpeg INTERFACE jpeg)
+elseif (WINDOWS)
+  target_link_libraries( ll::libjpeg INTERFACE jpeglib)
+endif (LINUX)
+target_include_directories( ll::libjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
diff --git a/indra/cmake/JsonCpp.cmake b/indra/cmake/JsonCpp.cmake
index 079619adf867605e2a9147544beb31db9c6bfbc4..17f8e47a978f76b025786ebcd41d788d4c008880 100644
--- a/indra/cmake/JsonCpp.cmake
+++ b/indra/cmake/JsonCpp.cmake
@@ -1,22 +1,17 @@
 # -*- cmake -*-
 
 include(Prebuilt)
+include_guard()
+add_library( ll::jsoncpp INTERFACE IMPORTED )
 
-set(JSONCPP_FIND_QUIETLY ON)
-set(JSONCPP_FIND_REQUIRED ON)
+use_system_binary(jsoncpp)
 
-if (USESYSTEMLIBS)
-  include(FindJsonCpp)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(jsoncpp)
-  if (WINDOWS)
-    set(JSONCPP_LIBRARIES 
-      debug json_libmdd.lib
-      optimized json_libmd.lib)
-  elseif (DARWIN)
-    set(JSONCPP_LIBRARIES libjson_darwin_libmt.a)
-  elseif (LINUX)
-    set(JSONCPP_LIBRARIES libjson_linux-gcc-4.1.3_libmt.a)
-  endif (WINDOWS)
-  set(JSONCPP_INCLUDE_DIR "${LIBS_PREBUILT_DIR}/include/jsoncpp" "${LIBS_PREBUILT_DIR}/include/json")
-endif (USESYSTEMLIBS)
+use_prebuilt_binary(jsoncpp)
+if (WINDOWS)
+  target_link_libraries( ll::jsoncpp INTERFACE json_libmd.lib )
+elseif (DARWIN)
+  target_link_libraries( ll::jsoncpp INTERFACE libjson_darwin_libmt.a )
+elseif (LINUX)
+  target_link_libraries( ll::jsoncpp INTERFACE libjson_linux-gcc-4.1.3_libmt.a )
+endif (WINDOWS)
+target_include_directories( ll::jsoncpp SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 4937c2a9d7735a5cb78933e970e6987ccab80275..bf569e5d992dcbef8bd8a5385f24beaa9a4ec126 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -18,100 +18,86 @@ MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
   # * properties for each sourcefile passed in indicate what libs to link that file with (MAKE NO ASSUMPTIONS ASIDE FROM TUT)
   #
   # More info and examples at: https://wiki.secondlife.com/wiki/How_to_add_unit_tests_to_indra_code
-  #
-  # WARNING: do NOT modify this code without working with poppy -
-  # there is another branch that will conflict heavily with any changes here.
-INCLUDE(GoogleMock)
 
-  IF(LL_TEST_VERBOSE)
-    MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}")
-  ENDIF(LL_TEST_VERBOSE)
+  # This here looks weird, but is needed. It will inject GoogleMock into projects that forgot to include `this` (LLAddBuildTest.cmake)
+  # But through some other means have access to this macro
+  include(GoogleMock)
+
+  if(LL_TEST_VERBOSE)
+    message("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} sources: ${sources}")
+  endif()
 
   # Start with the header and project-wide setup before making targets
   #project(UNITTEST_PROJECT_${project})
   # Setup includes, paths, etc
-  SET(alltest_SOURCE_FILES
-    ${CMAKE_SOURCE_DIR}/test/test.cpp
-    ${CMAKE_SOURCE_DIR}/test/lltut.cpp
-    )
-  SET(alltest_DEP_TARGETS
-    # needed by the test harness itself
-    ${APRUTIL_LIBRARIES}
-    ${APR_LIBRARIES}
-    llcommon
-    )
-  IF(NOT "${project}" STREQUAL "llmath")
+  set(alltest_SOURCE_FILES
+          ${CMAKE_SOURCE_DIR}/test/test.cpp
+          ${CMAKE_SOURCE_DIR}/test/lltut.cpp
+          )
+  set(alltest_DEP_TARGETS
+          # needed by the test harness itself
+          llcommon
+          )
+
+  set(alltest_LIBRARIES
+          llcommon
+          ll::googlemock
+          )
+  if(NOT "${project}" STREQUAL "llmath")
     # add llmath as a dep unless the tested module *is* llmath!
-    LIST(APPEND alltest_DEP_TARGETS
-      llmath
-      )
-  ENDIF(NOT "${project}" STREQUAL "llmath")
-  SET(alltest_INCLUDE_DIRS
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LIBS_OPEN_DIR}/test
-    ${GOOGLEMOCK_INCLUDE_DIRS}
-    )
-  SET(alltest_LIBRARIES
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    ${BOOST_SYSTEM_LIBRARY}
-    ${GOOGLEMOCK_LIBRARIES}
-    ${PTHREAD_LIBRARY}
-    ${WINDOWS_LIBRARIES}
-    )
+    list(APPEND alltest_DEP_TARGETS llmath)
+    list(APPEND alltest_LIBRARIES llmath )
+  endif()
+
   # Headers, for convenience in targets.
-  SET(alltest_HEADER_FILES
-    ${CMAKE_SOURCE_DIR}/test/test.h
-    )
+  set(alltest_HEADER_FILES ${CMAKE_SOURCE_DIR}/test/test.h)
 
   # start the source test executable definitions
-  SET(${project}_TEST_OUTPUT "")
-  FOREACH (source ${sources})
-    STRING( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} )
-    STRING( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} )
-    IF(LL_TEST_VERBOSE)
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})")
-    ENDIF(LL_TEST_VERBOSE)
+  set(${project}_TEST_OUTPUT "")
+  foreach (source ${sources})
+    string( REGEX REPLACE "(.*)\\.[^.]+$" "\\1" name ${source} )
+    string( REGEX REPLACE ".*\\.([^.]+)$" "\\1" extension ${source} )
+    if(LL_TEST_VERBOSE)
+      message("LL_ADD_PROJECT_UNIT_TESTS UNITTEST_PROJECT_${project} individual source: ${source} (${name}.${extension})")
+    endif()
 
     #
     # Per-codefile additional / external source, header, and include dir property extraction
     #
     # Source
     GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES)
-    SET(${name}_test_SOURCE_FILES
-      ${source}
-      tests/${name}_test.${extension}
-      ${alltest_SOURCE_FILES}
-      ${${name}_test_additional_SOURCE_FILES} )
-    IF(LL_TEST_VERBOSE)
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
-    ENDIF(LL_TEST_VERBOSE)
-
-    if (USE_BUGSPLAT)
-      SET_PROPERTY(SOURCE ${${name}_test_SOURCE_FILES}
-          APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
-    endif (USE_BUGSPLAT)
+    set(${name}_test_SOURCE_FILES
+            ${source}
+            tests/${name}_test.${extension}
+            ${alltest_SOURCE_FILES}
+            ${${name}_test_additional_SOURCE_FILES} )
+    if(LL_TEST_VERBOSE)
+      message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_SOURCE_FILES ${${name}_test_SOURCE_FILES}")
+    endif()
 
     # Headers
     GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
-    SET(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
-    set_source_files_properties(${${name}_test_HEADER_FILES} PROPERTIES HEADER_FILE_ONLY TRUE)
-    LIST(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES})
-    IF(LL_TEST_VERBOSE)
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}")
-    ENDIF(LL_TEST_VERBOSE)
-    # Include dirs
+    set(${name}_test_HEADER_FILES ${name}.h ${${name}_test_additional_HEADER_FILES})
+    list(APPEND ${name}_test_SOURCE_FILES ${${name}_test_HEADER_FILES})
+    if(LL_TEST_VERBOSE)
+      message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_HEADER_FILES ${${name}_test_HEADER_FILES}")
+    endif()
+
+    # Setup target
+    add_executable(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES})
+
+    # Cannot declare a dependency on ${project} because the executable create above will later declare
+    # add_dependencies( ${project} ${project}_tests)
+    # as such grab ${project}'s interface include dirs and inject them here
+    get_property( ${name}_test_additional_INCLUDE_DIRS TARGET ${project} PROPERTY INTERFACE_INCLUDE_DIRECTORIES )
+    target_include_directories (PROJECT_${project}_TEST_${name} PRIVATE ${${name}_test_additional_INCLUDE_DIRS} )
+
     GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS)
-    INCLUDE_DIRECTORIES(${alltest_INCLUDE_DIRS} ${${name}_test_additional_INCLUDE_DIRS} )
-    IF(LL_TEST_VERBOSE)
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_INCLUDE_DIRS ${${name}_test_additional_INCLUDE_DIRS}")
-    ENDIF(LL_TEST_VERBOSE)
+    target_include_directories (PROJECT_${project}_TEST_${name} PRIVATE ${${name}_test_additional_INCLUDE_DIRS} )
 
+    target_include_directories (PROJECT_${project}_TEST_${name} PRIVATE ${LIBS_OPEN_DIR}/test )
 
-    # Setup target
-    ADD_EXECUTABLE(PROJECT_${project}_TEST_${name} ${${name}_test_SOURCE_FILES})
-    SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
+    set_target_properties(PROJECT_${project}_TEST_${name} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}")
 
     #
     # Per-codefile additional / external project dep and lib dep property extraction
@@ -121,142 +107,133 @@ INCLUDE(GoogleMock)
     GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS)
     # Libraries
     GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES)
-    IF(LL_TEST_VERBOSE)
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}")
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}")
-    ENDIF(LL_TEST_VERBOSE)
+
+    if(LL_TEST_VERBOSE)
+      message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_PROJECTS ${${name}_test_additional_PROJECTS}")
+      message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_LIBRARIES ${${name}_test_additional_LIBRARIES}")
+    endif()
+
     # Add to project
-    TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} )
+    target_link_libraries(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} )
+    add_dependencies( PROJECT_${project}_TEST_${name} ${alltest_DEP_TARGETS})
     # Compile-time Definitions
     GET_OPT_SOURCE_FILE_PROPERTY(${name}_test_additional_CFLAGS ${source} LL_TEST_ADDITIONAL_CFLAGS)
-    SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name}
-      PROPERTIES
-      COMPILE_FLAGS "${${name}_test_additional_CFLAGS}"
-      COMPILE_DEFINITIONS "LL_TEST=${name};LL_TEST_${name}")
-    IF(LL_TEST_VERBOSE)
-      MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
-    ENDIF(LL_TEST_VERBOSE)
-     
+    set_target_properties(PROJECT_${project}_TEST_${name}
+            PROPERTIES
+            COMPILE_FLAGS "${${name}_test_additional_CFLAGS}"
+            COMPILE_DEFINITIONS "LL_TEST=${name};LL_TEST_${name}")
+    if(LL_TEST_VERBOSE)
+      message("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
+    endif()
+
     #
     # Setup test targets
     #
-    SET(TEST_EXE $<TARGET_FILE:PROJECT_${project}_TEST_${name}>)
-    SET(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt)
-    SET(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR})
+    set(TEST_EXE $<TARGET_FILE:PROJECT_${project}_TEST_${name}>)
+    set(TEST_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/PROJECT_${project}_TEST_${name}_ok.txt)
+    set(TEST_CMD ${TEST_EXE} --touch=${TEST_OUTPUT} --sourcedir=${CMAKE_CURRENT_SOURCE_DIR})
 
     # daveh - what configuration does this use? Debug? it's cmake-time, not build time. + poppy 2009-04-19
-    IF(LL_TEST_VERBOSE)
-      MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd  = ${TEST_CMD}")
-    ENDIF(LL_TEST_VERBOSE)
+    if(LL_TEST_VERBOSE)
+      message(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_cmd  = ${TEST_CMD}")
+    endif()
 
     SET_TEST_PATH(LD_LIBRARY_PATH)
     LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${TEST_CMD})
-    IF(LL_TEST_VERBOSE)
-      MESSAGE(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script  = ${TEST_SCRIPT_CMD}")
-    ENDIF(LL_TEST_VERBOSE)
-    # Add test 
-    ADD_CUSTOM_COMMAND(
-        OUTPUT ${TEST_OUTPUT}
-        COMMAND ${TEST_SCRIPT_CMD}
-        DEPENDS PROJECT_${project}_TEST_${name}
-        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
-        )
+    if(LL_TEST_VERBOSE)
+      message(STATUS "LL_ADD_PROJECT_UNIT_TESTS ${name} test_script  = ${TEST_SCRIPT_CMD}")
+    endif()
+
+    # Add test
+    add_custom_command(
+            OUTPUT ${TEST_OUTPUT}
+            COMMAND ${TEST_SCRIPT_CMD}
+            DEPENDS PROJECT_${project}_TEST_${name}
+            WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
+    )
     # Why not add custom target and add POST_BUILD command?
     # Slightly less uncertain behavior
     # (OUTPUT commands run non-deterministically AFAIK) + poppy 2009-04-19
-    # > I did not use a post build step as I could not make it notify of a 
+    # > I did not use a post build step as I could not make it notify of a
     # > failure after the first time you build and fail a test. - daveh 2009-04-20
-    LIST(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT})
-  ENDFOREACH (source)
+    list(APPEND ${project}_TEST_OUTPUT ${TEST_OUTPUT})
+  endforeach (source)
 
   # Add the test runner target per-project
   # (replaces old _test_ok targets all over the place)
-  ADD_CUSTOM_TARGET(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT})
-  ADD_DEPENDENCIES(${project} ${project}_tests)
+  add_custom_target(${project}_tests ALL DEPENDS ${${project}_TEST_OUTPUT})
+  add_dependencies(${project} ${project}_tests)
 ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
 
 #*****************************************************************************
 #   GET_OPT_SOURCE_FILE_PROPERTY
 #*****************************************************************************
 MACRO(GET_OPT_SOURCE_FILE_PROPERTY var filename property)
-  GET_SOURCE_FILE_PROPERTY(${var} "${filename}" "${property}")
-  IF("${${var}}" MATCHES NOTFOUND)
-    SET(${var} "")
-  ENDIF("${${var}}" MATCHES NOTFOUND)
+  get_source_file_property(${var} "${filename}" "${property}")
+  if("${${var}}" MATCHES NOTFOUND)
+    set(${var} "")
+  endif()
 ENDMACRO(GET_OPT_SOURCE_FILE_PROPERTY)
 
 #*****************************************************************************
 #   LL_ADD_INTEGRATION_TEST
 #*****************************************************************************
-FUNCTION(LL_ADD_INTEGRATION_TEST 
-    testname
-    additional_source_files
-    library_dependencies
-# variable args
-    )
+FUNCTION(LL_ADD_INTEGRATION_TEST
+        testname
+        additional_source_files
+        library_dependencies
+        # variable args
+        )
   if(TEST_DEBUG)
     message(STATUS "Adding INTEGRATION_TEST_${testname} - debug output is on")
-  endif(TEST_DEBUG)
+  endif()
 
-  SET(source_files
-    tests/${testname}_test.cpp
-    ${CMAKE_SOURCE_DIR}/test/test.cpp
-    ${CMAKE_SOURCE_DIR}/test/lltut.cpp
-    ${additional_source_files}
-    )
+  set(source_files
+          tests/${testname}_test.cpp
+          ${CMAKE_SOURCE_DIR}/test/test.cpp
+          ${CMAKE_SOURCE_DIR}/test/lltut.cpp
+          ${additional_source_files}
+          )
 
-  SET(libraries
-    ${LEGACY_STDIO_LIBS}
-    ${library_dependencies}
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    ${BOOST_SYSTEM_LIBRARY}
-    ${GOOGLEMOCK_LIBRARIES}
-    ${PTHREAD_LIBRARY}
-    )
+  set(libraries
+          ${library_dependencies}
+          ll::googlemock
+          )
 
   # Add test executable build target
   if(TEST_DEBUG)
     message(STATUS "ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})")
-  endif(TEST_DEBUG)
-  ADD_EXECUTABLE(INTEGRATION_TEST_${testname} ${source_files})
-  SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname}
-    PROPERTIES
-    RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
-    COMPILE_DEFINITIONS "LL_TEST=${testname};LL_TEST_${testname}"
-    )
-
-  if(USESYSTEMLIBS)
-    SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
-  endif(USESYSTEMLIBS)
+  endif()
 
-  if (USE_BUGSPLAT)
-      SET_PROPERTY(SOURCE ${source_files}
-          APPEND PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
-  endif (USE_BUGSPLAT)
+  add_executable(INTEGRATION_TEST_${testname} ${source_files})
+  set_target_properties(INTEGRATION_TEST_${testname}
+          PROPERTIES
+          RUNTIME_OUTPUT_DIRECTORY "${EXE_STAGING_DIR}"
+          COMPILE_DEFINITIONS "LL_TEST=${testname};LL_TEST_${testname}"
+          )
 
-  # The following was copied to llcorehttp/CMakeLists.txt's texture_load target. 
+  # The following was copied to llcorehttp/CMakeLists.txt's texture_load target.
   # Any changes made here should be replicated there.
   if (WINDOWS)
-    SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname}
-        PROPERTIES
-        LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:CONSOLE"
-        LINK_FLAGS_DEBUG "/NODEFAULTLIB:\"LIBCMT;LIBCMTD;MSVCRT\" /INCREMENTAL:NO"
-        LINK_FLAGS_RELEASE ""
-        )
-  endif (WINDOWS)
+    set_target_properties(INTEGRATION_TEST_${testname}
+            PROPERTIES
+            LINK_FLAGS "/debug /NODEFAULTLIB:LIBCMT /SUBSYSTEM:CONSOLE"
+            )
+  endif ()
 
   # Add link deps to the executable
   if(TEST_DEBUG)
     message(STATUS "TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})")
-  endif(TEST_DEBUG)
-  TARGET_LINK_LIBRARIES(INTEGRATION_TEST_${testname} ${libraries})
+  endif()
+
+  target_link_libraries(INTEGRATION_TEST_${testname} ${libraries})
+  target_include_directories (INTEGRATION_TEST_${testname} PRIVATE ${LIBS_OPEN_DIR}/test )
 
   # Create the test running command
-  SET(test_command ${ARGN})
-  SET(TEST_EXE $<TARGET_FILE:INTEGRATION_TEST_${testname}>)
-  LIST(FIND test_command "{}" test_exe_pos)
-  IF(test_exe_pos LESS 0)
+  set(test_command ${ARGN})
+  set(TEST_EXE $<TARGET_FILE:INTEGRATION_TEST_${testname}>)
+  list(FIND test_command "{}" test_exe_pos)
+  if(test_exe_pos LESS 0)
     # The {} marker means "the full pathname of the test executable."
     # test_exe_pos -1 means we didn't find it -- so append the test executable
     # name to $ARGN, the variable part of the arg list. This is convenient
@@ -265,26 +242,26 @@ FUNCTION(LL_ADD_INTEGRATION_TEST
     # pathname of the test program as the last of its args. You need specify
     # {} only if the test program's pathname isn't the last argument in the
     # desired command line.
-    LIST(APPEND test_command "${TEST_EXE}")
-  ELSE (test_exe_pos LESS 0)
+    list(APPEND test_command "${TEST_EXE}")
+  else (test_exe_pos LESS 0)
     # Found {} marker at test_exe_pos. Remove the {}...
-    LIST(REMOVE_AT test_command test_exe_pos)
+    list(REMOVE_AT test_command test_exe_pos)
     # ...and replace it with the actual name of the test executable.
-    LIST(INSERT test_command test_exe_pos "${TEST_EXE}")
-  ENDIF (test_exe_pos LESS 0)
+    list(INSERT test_command test_exe_pos "${TEST_EXE}")
+  endif()
 
   SET_TEST_PATH(LD_LIBRARY_PATH)
   LL_TEST_COMMAND(TEST_SCRIPT_CMD "${LD_LIBRARY_PATH}" ${test_command})
 
   if(TEST_DEBUG)
     message(STATUS "TEST_SCRIPT_CMD: ${TEST_SCRIPT_CMD}")
-  endif(TEST_DEBUG)
+  endif()
 
-  ADD_CUSTOM_COMMAND(
-    TARGET INTEGRATION_TEST_${testname}
-    POST_BUILD
-    COMMAND ${TEST_SCRIPT_CMD}
-    )
+  add_custom_command(
+          TARGET INTEGRATION_TEST_${testname}
+          POST_BUILD
+          COMMAND ${TEST_SCRIPT_CMD}
+  )
 
   # Use CTEST? Not sure how to yet...
   # ADD_TEST(INTEGRATION_TEST_RUNNER_${testname} ${TEST_SCRIPT_CMD})
@@ -299,18 +276,14 @@ MACRO(SET_TEST_PATH LISTVAR)
     # We typically build/package only Release variants of third-party
     # libraries, so append the Release staging dir in case the library being
     # sought doesn't have a debug variant.
-    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR} ${SHARED_LIB_STAGING_DIR}/Release)
+    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} ${SHARED_LIB_STAGING_DIR}/Release)
   ELSEIF(DARWIN)
     # We typically build/package only Release variants of third-party
     # libraries, so append the Release staging dir in case the library being
     # sought doesn't have a debug variant.
-    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib)
+    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} ${SHARED_LIB_STAGING_DIR}/Release/Resources /usr/lib)
   ELSE(WINDOWS)
     # Linux uses a single staging directory anyway.
-    IF (USESYSTEMLIBS)
-      set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib)
-    ELSE (USESYSTEMLIBS)
-      set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib)
-    ENDIF (USESYSTEMLIBS)
+    set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib)
   ENDIF(WINDOWS)
 ENDMACRO(SET_TEST_PATH)
diff --git a/indra/cmake/LLAppearance.cmake b/indra/cmake/LLAppearance.cmake
index 675330ec72b59f2d1049ec7811f3e896b95b1863..bf34b13714a0d53b02023d259c3b6a47e43a5f63 100644
--- a/indra/cmake/LLAppearance.cmake
+++ b/indra/cmake/LLAppearance.cmake
@@ -2,26 +2,9 @@
 
 include(Variables)
 include(Boost)
-include(LLMessage)
 include(LLCoreHttp)
 
-set(LLAPPEARANCE_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llappearance
-    )
 
-if (BUILD_HEADLESS)
-  set(LLAPPEARANCE_HEADLESS_LIBRARIES
-    llappearanceheadless
-    )
-endif (BUILD_HEADLESS)
-
-set(LLAPPEARANCE_LIBRARIES llappearance
-    llmessage
-    llcorehttp
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    ${BOOST_SYSTEM_LIBRARY}
-    )
 
 
 
diff --git a/indra/cmake/LLAudio.cmake b/indra/cmake/LLAudio.cmake
index 7c248dfc7205231fc563e3ea0fffea88fb849cf1..c842c69bfeca8b96238d5386c3d341ab6fe44ef1 100644
--- a/indra/cmake/LLAudio.cmake
+++ b/indra/cmake/LLAudio.cmake
@@ -1,10 +1,3 @@
 # -*- cmake -*-
 
 include(Audio)
-
-set(LLAUDIO_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llaudio
-    )
-
-# be exhaustive here
-set(LLAUDIO_LIBRARIES llaudio ${VORBISFILE_LIBRARIES} ${VORBIS_LIBRARIES} ${VORBISENC_LIBRARIES} ${OGG_LIBRARIES} ${OPENAL_LIBRARIES})
diff --git a/indra/cmake/LLCharacter.cmake b/indra/cmake/LLCharacter.cmake
deleted file mode 100644
index 9b2f5c4956ac9d005334e8a6485b16bfef7cb194..0000000000000000000000000000000000000000
--- a/indra/cmake/LLCharacter.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLCHARACTER_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llcharacter
-    )
-
-set(LLCHARACTER_LIBRARIES llcharacter)
diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake
index 0d73270d63ca42ecd6a7ef939b062de5cd0d0f0d..869d5805f26ffc05548fe9da5cf57604f6b2c28e 100644
--- a/indra/cmake/LLCommon.cmake
+++ b/indra/cmake/LLCommon.cmake
@@ -6,39 +6,6 @@ include(EXPAT)
 include(Tracy)
 include(xxHash)
 include(ZLIBNG)
+include(JsonCpp)
 
-set(LLCOMMON_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llcommon
-    ${APRUTIL_INCLUDE_DIR}
-    ${APR_INCLUDE_DIR}
-    ${TRACY_INCLUDE_DIR}
-    )
-set(LLCOMMON_SYSTEM_INCLUDE_DIRS
-    ${Boost_INCLUDE_DIRS}
-    )
-
-if (LINUX)
-    # In order to support using ld.gold on linux, we need to explicitely
-    # specify all libraries that llcommon uses.
-    # llcommon uses `clock_gettime' which is provided by librt on linux.
-    set(LLCOMMON_LIBRARIES llcommon 
-        ${BOOST_FIBER_LIBRARY} 
-        ${BOOST_CONTEXT_LIBRARY} 
-        ${BOOST_THREAD_LIBRARY} 
-        ${BOOST_SYSTEM_LIBRARY} 
-        rt
-        )
-else (LINUX)
-    set(LLCOMMON_LIBRARIES llcommon
-        ${BOOST_FIBER_LIBRARY} 
-        ${BOOST_CONTEXT_LIBRARY} 
-        ${BOOST_THREAD_LIBRARY} 
-        ${BOOST_SYSTEM_LIBRARY}
-        ${TRACY_LIBRARY}
-        )
-endif (LINUX)
-
-set(LLCOMMON_LINK_SHARED OFF CACHE BOOL "Build the llcommon target as a static library.")
-if(LLCOMMON_LINK_SHARED)
-  add_definitions(-DLL_COMMON_LINK_SHARED=1)
-endif(LLCOMMON_LINK_SHARED)
+include(XmlRpcEpi)
diff --git a/indra/cmake/LLCoreHttp.cmake b/indra/cmake/LLCoreHttp.cmake
index 613453ab5d58dcffb5bb44f96f8435958627662d..22ed5fef9cbda11aea6f71ee031554595ba2c521 100644
--- a/indra/cmake/LLCoreHttp.cmake
+++ b/indra/cmake/LLCoreHttp.cmake
@@ -2,16 +2,4 @@
 
 include(CURL)
 include(OpenSSL)
-include(Boost)
-
-set(LLCOREHTTP_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llcorehttp
-    ${CURL_INCLUDE_DIRS}
-    ${OPENSSL_INCLUDE_DIRS}
-    ${BOOST_INCLUDE_DIRS}
-    )
-
-set(LLCOREHTTP_LIBRARIES llcorehttp
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    ${BOOST_SYSTEM_LIBRARY})
+include(NGHTTP2)
diff --git a/indra/cmake/LLCrashLogger.cmake b/indra/cmake/LLCrashLogger.cmake
deleted file mode 100644
index f2cb83eb8bbd61d2e3554ff74f9cb57701e1df63..0000000000000000000000000000000000000000
--- a/indra/cmake/LLCrashLogger.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLCRASHLOGGER_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llcrashlogger
-    )
-
-set(LLCRASHLOGGER_LIBRARIES llcrashlogger)
diff --git a/indra/cmake/LLFileSystem.cmake b/indra/cmake/LLFileSystem.cmake
deleted file mode 100644
index 2e6c42c30c229028e0e5a9dc2c46081aa99088f9..0000000000000000000000000000000000000000
--- a/indra/cmake/LLFileSystem.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLFILESYSTEM_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llfilesystem
-    )
-
-set(LLFILESYSTEM_LIBRARIES llfilesystem)
diff --git a/indra/cmake/LLImage.cmake b/indra/cmake/LLImage.cmake
index ec3da890811e8b27a1d41e0bef4f816bd10a3e72..8e0b44dfe491e3c93669ea9dccd62807dc272a99 100644
--- a/indra/cmake/LLImage.cmake
+++ b/indra/cmake/LLImage.cmake
@@ -1,11 +1,4 @@
 # -*- cmake -*-
 
-include(JPEG)
+#include(JPEG)
 include(PNG)
-
-set(LLIMAGE_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llimage
-    ${JPEG_INCLUDE_DIRS}
-    )
-
-set(LLIMAGE_LIBRARIES llimage)
diff --git a/indra/cmake/LLImageJ2COJ.cmake b/indra/cmake/LLImageJ2COJ.cmake
deleted file mode 100644
index 1bcf205f2dbae7d92bbc41a94301b9eac292cbab..0000000000000000000000000000000000000000
--- a/indra/cmake/LLImageJ2COJ.cmake
+++ /dev/null
@@ -1,5 +0,0 @@
-# -*- cmake -*-
-
-include(OpenJPEG)
-
-set(LLIMAGEJ2COJ_LIBRARIES llimagej2coj)
diff --git a/indra/cmake/LLInventory.cmake b/indra/cmake/LLInventory.cmake
deleted file mode 100644
index c3dc077a2bab4e41dd00b10fd5f5e74e10f58c31..0000000000000000000000000000000000000000
--- a/indra/cmake/LLInventory.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLINVENTORY_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llinventory
-    )
-
-set(LLINVENTORY_LIBRARIES llinventory)
diff --git a/indra/cmake/LLKDU.cmake b/indra/cmake/LLKDU.cmake
index e478b01f84ae872422c3c073dda80d9d6a6dd7a1..fda25610da3d3978e5c5811173ca67bc8a2eb7a0 100644
--- a/indra/cmake/LLKDU.cmake
+++ b/indra/cmake/LLKDU.cmake
@@ -7,15 +7,20 @@ if (INSTALL_PROPRIETARY)
   set(USE_KDU ON CACHE BOOL "Use Kakadu library.")
 endif (INSTALL_PROPRIETARY)
 
+include_guard()
+add_library( ll::kdu INTERFACE IMPORTED )
+
 if (USE_KDU)
   include(Prebuilt)
   use_prebuilt_binary(kdu)
   if (WINDOWS)
-    set(KDU_LIBRARY kdu.lib)
+    target_link_libraries( ll::kdu INTERFACE kdu.lib)
   else (WINDOWS)
-    set(KDU_LIBRARY libkdu.a)
+    target_link_libraries( ll::kdu INTERFACE libkdu.a)
   endif (WINDOWS)
-  set(KDU_INCLUDE_DIR ${AUTOBUILD_INSTALL_DIR}/include/kdu)
-  set(LLKDU_INCLUDE_DIRS ${LIBS_OPEN_DIR}/llkdu)
-  set(LLKDU_LIBRARIES llkdu)
+
+  target_include_directories( ll::kdu SYSTEM INTERFACE
+          ${AUTOBUILD_INSTALL_DIR}/include/kdu
+          ${LIBS_OPEN_DIR}/llkdu
+          )
 endif (USE_KDU)
diff --git a/indra/cmake/LLLogin.cmake b/indra/cmake/LLLogin.cmake
deleted file mode 100644
index 47d171876a00df3fea3bf61a794cb3ff81fcd07b..0000000000000000000000000000000000000000
--- a/indra/cmake/LLLogin.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLLOGIN_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/viewer_components/login
-    )
-
-set(LLLOGIN_LIBRARIES lllogin)
diff --git a/indra/cmake/LLMath.cmake b/indra/cmake/LLMath.cmake
index 513ff9f81d30382ed3ae2e5f942e46d67634de1e..e841d2ac78e4cb76e529136c66b21b8ce3d50e4f 100644
--- a/indra/cmake/LLMath.cmake
+++ b/indra/cmake/LLMath.cmake
@@ -2,10 +2,4 @@
 
 include(Variables)
 include(Mikktspace)
-include(MESHOPTIMIZER)
 
-set(LLMATH_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llmath
-    )
-
-set(LLMATH_LIBRARIES llmath)
diff --git a/indra/cmake/LLMeshOptimizer.cmake b/indra/cmake/LLMeshOptimizer.cmake
deleted file mode 100644
index b79944f61875a2cffef4f51e06a531fc5d4479c2..0000000000000000000000000000000000000000
--- a/indra/cmake/LLMeshOptimizer.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLMESHOPTIMIZER_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llmeshoptimizer
-    )
-
-set(LLMESHOPTIMIZER_LIBRARIES llmeshoptimizer)
diff --git a/indra/cmake/LLMessage.cmake b/indra/cmake/LLMessage.cmake
deleted file mode 100644
index 7be53ec0ec3441a7534b27f70af158f88c69757d..0000000000000000000000000000000000000000
--- a/indra/cmake/LLMessage.cmake
+++ /dev/null
@@ -1,13 +0,0 @@
-# -*- cmake -*-
-
-include(CURL)
-include(OpenSSL)
-include(XmlRpcEpi)
-
-set(LLMESSAGE_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llmessage
-    ${CURL_INCLUDE_DIRS}
-    ${OPENSSL_INCLUDE_DIRS}
-    )
-
-set(LLMESSAGE_LIBRARIES llmessage)
diff --git a/indra/cmake/LLPhysicsExtensions.cmake b/indra/cmake/LLPhysicsExtensions.cmake
index e6afee762eca581b88130add82e6c7031d9e6edc..36821447c9dbf70d3867c9b911b166aa72212d21 100644
--- a/indra/cmake/LLPhysicsExtensions.cmake
+++ b/indra/cmake/LLPhysicsExtensions.cmake
@@ -10,6 +10,9 @@ if (INSTALL_PROPRIETARY)
    set(HAVOK ON CACHE BOOL "Use Havok physics library")
 endif (INSTALL_PROPRIETARY)
 
+include_guard()
+add_library( llphysicsextensions_impl INTERFACE IMPORTED )
+
 
 # Note that the use_prebuilt_binary macros below do not in fact include binaries;
 # the llphysicsextensions_* packages are source only and are built here.
@@ -19,17 +22,14 @@ if (HAVOK)
    include(Havok)
    use_prebuilt_binary(llphysicsextensions_source)
    set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/src)
-   set(LLPHYSICSEXTENSIONS_LIBRARIES    llphysicsextensions)
-
+   target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensions)
 elseif (HAVOK_TPV)
    use_prebuilt_binary(llphysicsextensions_tpv)
-   set(LLPHYSICSEXTENSIONS_LIBRARIES    llphysicsextensions_tpv)
-
+   target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensions_tpv)
 else (HAVOK)
    use_prebuilt_binary(llphysicsextensions_stub)
    set(LLPHYSICSEXTENSIONS_SRC_DIR ${LIBS_PREBUILT_DIR}/llphysicsextensions/stub)
-   set(LLPHYSICSEXTENSIONS_LIBRARIES    llphysicsextensionsstub)
-
+   target_link_libraries( llphysicsextensions_impl INTERFACE llphysicsextensionsstub)
 endif (HAVOK)
 
-set(LLPHYSICSEXTENSIONS_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/llphysicsextensions)
+target_include_directories( llphysicsextensions_impl INTERFACE   ${LIBS_PREBUILT_DIR}/include/llphysicsextensions)
diff --git a/indra/cmake/LLPlugin.cmake b/indra/cmake/LLPlugin.cmake
deleted file mode 100644
index 399cb332dd4a3c911ab063d156f98fd22f16fbb8..0000000000000000000000000000000000000000
--- a/indra/cmake/LLPlugin.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-# -*- cmake -*-
-
-
-set(LLPLUGIN_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llplugin
-    )
-
-if (LINUX)
-    # In order to support using ld.gold on linux, we need to explicitely
-    # specify all libraries that llplugin uses.
-    set(LLPLUGIN_LIBRARIES llplugin pthread)
-else (LINUX)
-    set(LLPLUGIN_LIBRARIES llplugin)
-endif (LINUX)
diff --git a/indra/cmake/LLPrimitive.cmake b/indra/cmake/LLPrimitive.cmake
index 4e349512156f4d90bead5bd97099ec663c3f3a83..3d8499cbc3a17c11acd2b8dc31b51061322bdc44 100644
--- a/indra/cmake/LLPrimitive.cmake
+++ b/indra/cmake/LLPrimitive.cmake
@@ -4,49 +4,49 @@
 include(Prebuilt)
 include(Boost)
 
+include_guard()
+
+add_library( ll::pcre INTERFACE IMPORTED )
+add_library( ll::minizip-ng INTERFACE IMPORTED )
+add_library( ll::libxml INTERFACE IMPORTED )
+add_library( ll::colladadom INTERFACE IMPORTED )
+
+# ND, needs fixup in collada conan pkg
+if( USE_CONAN )
+  target_include_directories( ll::colladadom SYSTEM INTERFACE
+    "${CONAN_INCLUDE_DIRS_COLLADADOM}/collada-dom/" 
+    "${CONAN_INCLUDE_DIRS_COLLADADOM}/collada-dom/1.4/" )
+endif()
+
+use_system_binary( colladadom )
+
 use_prebuilt_binary(colladadom)
 use_prebuilt_binary(minizip-ng) # needed for colladadom
 use_prebuilt_binary(pcre)
 use_prebuilt_binary(libxml2)
 
-set(LLPRIMITIVE_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llprimitive
-    )
+target_link_libraries( ll::pcre INTERFACE pcrecpp pcre )
+
+if (WINDOWS)
+    target_link_libraries( ll::minizip-ng INTERFACE libminizip )
+else()
+    target_link_libraries( ll::minizip-ng INTERFACE minizip )
+endif()
+
 if (WINDOWS)
-    set(LLPRIMITIVE_LIBRARIES 
-        debug llprimitive
-        optimized llprimitive
-        debug libcollada14dom23-sd
-        optimized libcollada14dom23-s
-        libxml2_a
-        debug pcrecppd
-        optimized pcrecpp
-        debug pcred
-        optimized pcre
-        debug libminizip
-        optimized libminizip
-        ${BOOST_SYSTEM_LIBRARIES}
+    target_link_libraries( ll::libxml INTERFACE libxml2_a)
+else()
+    target_link_libraries( ll::libxml INTERFACE xml2)
+endif()
+
+target_include_directories( ll::colladadom SYSTEM INTERFACE
+        ${LIBS_PREBUILT_DIR}/include/collada
+        ${LIBS_PREBUILT_DIR}/include/collada/1.4
         )
+if (WINDOWS)
+    target_link_libraries(ll::colladadom INTERFACE libcollada14dom23-s ll::libxml ll::minizip-ng )
 elseif (DARWIN)
-    set(LLPRIMITIVE_LIBRARIES 
-        llprimitive
-        debug collada14dom-d
-        optimized collada14dom
-        minizip           # for collada libminizip.a
-        xml2
-        pcrecpp
-        pcre
-        iconv           # Required by libxml2
-        )
+    target_link_libraries(ll::colladadom INTERFACE collada14dom ll::libxml ll::minizip-ng)
 elseif (LINUX)
-    set(LLPRIMITIVE_LIBRARIES 
-        llprimitive
-        debug collada14dom-d
-        optimized collada14dom
-        minizip
-        xml2
-        pcrecpp
-        pcre
-        )
-endif (WINDOWS)
-
+    target_link_libraries(ll::colladadom INTERFACE collada14dom ll::libxml ll::minizip-ng)
+endif()
diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake
deleted file mode 100644
index 2d9d3725ad236b829705d3fd78ebbf6ab20fb171..0000000000000000000000000000000000000000
--- a/indra/cmake/LLRender.cmake
+++ /dev/null
@@ -1,22 +0,0 @@
-# -*- cmake -*-
-
-include(Variables)
-include(FreeType)
-include(GLH)
-include(GLEXT)
-
-set(LLRENDER_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llrender
-    ${GLH_INCLUDE_DIR}
-    ${GLEXT_INCLUDE_DIR}
-    )
-
-if (BUILD_HEADLESS)
-  set(LLRENDER_HEADLESS_LIBRARIES
-      llrenderheadless
-      )
-endif (BUILD_HEADLESS)
-set(LLRENDER_LIBRARIES
-    llrender
-    )
-
diff --git a/indra/cmake/LLSharedLibs.cmake b/indra/cmake/LLSharedLibs.cmake
index f69b45cd926193e04ce625a7ae2ed0c1674d2d81..e3e2a3b0c60090f5f39fe41aeb9d3442e8a06d3d 100644
--- a/indra/cmake/LLSharedLibs.cmake
+++ b/indra/cmake/LLSharedLibs.cmake
@@ -37,40 +37,3 @@ macro(ll_deploy_sharedlibs_command target_exe)
   endif(NOT DARWIN)
 
 endmacro(ll_deploy_sharedlibs_command)
-
-# ll_stage_sharedlib
-# Performs config and adds a copy command for a sharedlib target.
-macro(ll_stage_sharedlib DSO_TARGET)
-  # target gets written to the DLL staging directory.
-  # Also this directory is shared with RunBuildTest.cmake, y'know, for the tests.
-  set_target_properties(${DSO_TARGET} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${SHARED_LIB_STAGING_DIR})
-  if(NOT WINDOWS)
-    get_target_property(DSO_PATH ${DSO_TARGET} LOCATION)
-    get_filename_component(DSO_FILE ${DSO_PATH} NAME)
-    if(DARWIN)
-      set(SHARED_LIB_STAGING_DIR_CONFIG ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/Resources)
-    else(DARWIN)
-      set(SHARED_LIB_STAGING_DIR_CONFIG ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR})
-    endif(DARWIN)
-
-      # *TODO - maybe make this a symbolic link? -brad
-      add_custom_command(
-        TARGET ${DSO_TARGET} POST_BUILD
-        COMMAND ${CMAKE_COMMAND}
-        ARGS
-          -E
-          copy_if_different
-          ${DSO_PATH}
-          ${SHARED_LIB_STAGING_DIR_CONFIG}/${DSO_FILE}
-          COMMENT "Copying llcommon to the staging folder."
-        )
-    endif(NOT WINDOWS)
-
-  if (DARWIN)
-    set_target_properties(${DSO_TARGET} PROPERTIES
-      BUILD_WITH_INSTALL_RPATH 1
-      INSTALL_NAME_DIR "@executable_path/../Resources"
-      )
-  endif(DARWIN)
-
-endmacro(ll_stage_sharedlib)
diff --git a/indra/cmake/LLUI.cmake b/indra/cmake/LLUI.cmake
deleted file mode 100644
index 34de57108b787ff468f77ebae346030a49d7ff83..0000000000000000000000000000000000000000
--- a/indra/cmake/LLUI.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLUI_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llui
-    )
-
-set(LLUI_LIBRARIES llui)
diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake
index 80af7ff2ab2a6d1676404910ab75b55079a6f91f..b36e97056074515b9e1637af9686a8fa992e1b37 100644
--- a/indra/cmake/LLWindow.cmake
+++ b/indra/cmake/LLWindow.cmake
@@ -4,39 +4,19 @@ include(Variables)
 include(GLEXT)
 include(Prebuilt)
 
-if (USESYSTEMLIBS)
-  include(FindSDL)
+include_guard()
+add_library( ll::SDL INTERFACE IMPORTED )
 
-  # This should be done by FindSDL.  Sigh.
-  mark_as_advanced(
-      SDLMAIN_LIBRARY
-      SDL_INCLUDE_DIR
-      SDL_LIBRARY
-      )
-else (USESYSTEMLIBS)
-  if (LINUX)
-    use_prebuilt_binary(SDL)
-    set (SDL_FOUND TRUE)
-    set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/i686-linux)
-    set (SDL_LIBRARY SDL directfb fusion direct X11)
-  endif (LINUX)
-endif (USESYSTEMLIBS)
 
-if (SDL_FOUND)
-  include_directories(${SDL_INCLUDE_DIR})
-endif (SDL_FOUND)
+if (LINUX)
+  #Must come first as use_system_binary can exit this file early
+  target_compile_definitions( ll::SDL INTERFACE LL_SDL=1)
 
-set(LLWINDOW_INCLUDE_DIRS
-    ${GLEXT_INCLUDE_DIR}
-    ${LIBS_OPEN_DIR}/llwindow
-    )
+  use_system_binary(SDL)
+  use_prebuilt_binary(SDL)
+  
+  target_include_directories( ll::SDL SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
+  target_link_libraries( ll::SDL INTERFACE SDL directfb fusion direct X11)
+endif (LINUX)
 
-if (BUILD_HEADLESS)
-  set(LLWINDOW_HEADLESS_LIBRARIES
-      llwindowheadless
-      )
-endif (BUILD_HEADLESS)
 
-  set(LLWINDOW_LIBRARIES
-      llwindow
-      )
diff --git a/indra/cmake/LLXML.cmake b/indra/cmake/LLXML.cmake
deleted file mode 100644
index b093c762975efc4771464bc6e6efcadf28faff7f..0000000000000000000000000000000000000000
--- a/indra/cmake/LLXML.cmake
+++ /dev/null
@@ -1,14 +0,0 @@
-# -*- cmake -*-
-
-include(Boost)
-include(EXPAT)
-
-set(LLXML_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llxml
-    ${EXPAT_INCLUDE_DIRS}
-    )
-set(LLXML_SYSTEM_INCLUDE_DIRS
-    ${Boost_INCLUDE_DIRS}
-    )
-
-set(LLXML_LIBRARIES llxml)
diff --git a/indra/cmake/LibVLCPlugin.cmake b/indra/cmake/LibVLCPlugin.cmake
index df829b615aa8fbb2defb8805a9cf9a36587bd78b..599ce0284450300deb7817937f4b59287647b461 100644
--- a/indra/cmake/LibVLCPlugin.cmake
+++ b/indra/cmake/LibVLCPlugin.cmake
@@ -2,29 +2,26 @@
 include(Linking)
 include(Prebuilt)
 
-if (USESYSTEMLIBS)
-    set(LIBVLCPLUGIN OFF CACHE BOOL
-        "LIBVLCPLUGIN support for the llplugin/llmedia test apps.")
-else (USESYSTEMLIBS)
-    use_prebuilt_binary(vlc-bin)
-    set(LIBVLCPLUGIN ON CACHE BOOL
+include_guard()
+add_library( ll::libvlc INTERFACE IMPORTED )
+
+use_prebuilt_binary(vlc-bin)
+set(LIBVLCPLUGIN ON CACHE BOOL
         "LIBVLCPLUGIN support for the llplugin/llmedia test apps.")
-        set(VLC_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/vlc)
-endif (USESYSTEMLIBS)
 
 if (WINDOWS)
-    set(VLC_PLUGIN_LIBRARIES
-        libvlc.lib
-        libvlccore.lib
+    target_link_libraries( ll::libvlc INTERFACE
+            libvlc.lib
+            libvlccore.lib
     )
 elseif (DARWIN)
-    set(VLC_PLUGIN_LIBRARIES
-        libvlc.dylib
-        libvlccore.dylib
+    target_link_libraries( ll::libvlc INTERFACE
+            libvlc.dylib
+            libvlccore.dylib
     )
 elseif (LINUX)
     # Specify a full path to make sure we get a static link
-    set(VLC_PLUGIN_LIBRARIES
+    target_link_libraries( ll::libvlc INTERFACE
         ${LIBS_PREBUILT_DIR}/lib/libvlc.a
         ${LIBS_PREBUILT_DIR}/lib/libvlccore.a
     )
diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index 3cb235a9d58775166c57cb0f70878829a824dae8..4a501f420b52a43fab584dab105bc5ad872ddcba 100644
--- a/indra/cmake/Linking.cmake
+++ b/indra/cmake/Linking.cmake
@@ -1,24 +1,34 @@
 # -*- cmake -*-
 
-if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
-set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
-
+include_guard()
 include(Variables)
 
 set(ARCH_PREBUILT_DIRS ${AUTOBUILD_INSTALL_DIR}/lib)
 set(ARCH_PREBUILT_DIRS_PLUGINS ${AUTOBUILD_INSTALL_DIR}/plugins)
 set(ARCH_PREBUILT_DIRS_RELEASE ${AUTOBUILD_INSTALL_DIR}/lib/release)
 set(ARCH_PREBUILT_DIRS_DEBUG ${AUTOBUILD_INSTALL_DIR}/lib/debug)
-if (WINDOWS)
-  set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs)
-  set(EXE_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs)
+if (WINDOWS OR DARWIN )
+  # Kludge for older cmake versions, 3.20+ is needed to use a genex in add_custom_command( OUTPUT <var> ... )
+  # Using this will work okay-ish, as Debug is not supported anyway. But for property multi config and also
+  # ninja support the genex version is preferred.
+  if(${CMAKE_VERSION} VERSION_LESS "3.20.0")  
+    if(CMAKE_BUILD_TYPE MATCHES Release)
+      set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/Release)
+    elseif (CMAKE_BUILD_TYPE MATCHES RelWithDebInfo)
+      set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/RelWithDebInfo)
+    endif()
+  else()
+    set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>)
+  endif()
+
+  if( DARWIN )
+    set( SHARED_LIB_STAGING_DIR ${SHARED_LIB_STAGING_DIR}/Resources)
+  endif()
+  set(EXE_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>)
 elseif (LINUX)
   set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/lib)
   set(EXE_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs/bin)
-elseif (DARWIN)
-  set(SHARED_LIB_STAGING_DIR ${CMAKE_BINARY_DIR}/sharedlibs)
-  set(EXE_STAGING_DIR "${CMAKE_BINARY_DIR}/sharedlibs")
-endif (WINDOWS)
+endif ()
 
 # Autobuild packages must provide 'release' versions of libraries, but may provide versions for
 # specific build types.  AUTOBUILD_LIBS_INSTALL_DIRS lists first the build type directory and then
@@ -27,52 +37,54 @@ endif (WINDOWS)
 # windows) and CMAKE_BUILD_TYPE on Makefile based generators (like linux).  The reason for this is
 # that CMAKE_BUILD_TYPE is essentially meaningless at configuration time for IDE generators and
 # CMAKE_CFG_INTDIR is meaningless at build time for Makefile generators
-if(WINDOWS OR DARWIN)
-  # the cmake xcode and VS generators implicitly append ${CMAKE_CFG_INTDIR} to the library paths for us
-  # fortunately both windows and darwin are case insensitive filesystems so this works.
-  set(AUTOBUILD_LIBS_INSTALL_DIRS "${AUTOBUILD_INSTALL_DIR}/lib/")
-else(WINDOWS OR DARWIN)
-  # else block is for linux and any other makefile based generators
-  string(TOLOWER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_LOWER)
-  set(AUTOBUILD_LIBS_INSTALL_DIRS ${AUTOBUILD_INSTALL_DIR}/lib/${CMAKE_BUILD_TYPE_LOWER})
-endif(WINDOWS OR DARWIN)
 
-if (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
-  # When we're building something other than Release, append the
-  # packages/lib/release directory to deal with autobuild packages that don't
-  # provide (e.g.) lib/debug libraries.
-  list(APPEND AUTOBUILD_LIBS_INSTALL_DIRS ${ARCH_PREBUILT_DIRS_RELEASE})
-endif (NOT "${CMAKE_BUILD_TYPE}" STREQUAL "Release")
+link_directories(${AUTOBUILD_INSTALL_DIR}/lib/$<LOWER_CASE:$<CONFIG>>)
+link_directories(${AUTOBUILD_INSTALL_DIR}/lib/release)
 
-link_directories(${AUTOBUILD_LIBS_INSTALL_DIRS})
+add_library( ll::oslibraries INTERFACE IMPORTED )
 
 if (LINUX)
-  set(DL_LIBRARY dl)
-  set(PTHREAD_LIBRARY pthread)
-else (LINUX)
-  set(DL_LIBRARY "")
-  set(PTHREAD_LIBRARY "")
-endif (LINUX)
+  target_link_libraries( ll::oslibraries INTERFACE
+          dl
+          pthread
+          rt)
+elseif (WINDOWS)
+  target_link_libraries( ll::oslibraries INTERFACE
+          advapi32
+          shell32
+          ws2_32
+          mswsock
+          psapi
+          winmm
+          netapi32
+          wldap32
+          gdi32
+          user32
+          ole32
+          dbghelp
+          legacy_stdio_definitions
+          )
+else()
+  include(CMakeFindFrameworks)
+  find_library(COREFOUNDATION_LIBRARY CoreFoundation)
+  find_library(CARBON_LIBRARY Carbon)
+  find_library(COCOA_LIBRARY Cocoa)
+  find_library(IOKIT_LIBRARY IOKit)
+
+  find_library(AGL_LIBRARY AGL)
+  find_library(APPKIT_LIBRARY AppKit)
+  find_library(COREAUDIO_LIBRARY CoreAudio)
+
+  target_link_libraries( ll::oslibraries INTERFACE
+          ${COCOA_LIBRARY}
+          ${IOKIT_LIBRARY}
+          ${COREFOUNDATION_LIBRARY}
+          ${CARBON_LIBRARY}
+          ${AGL_LIBRARY}
+          ${APPKIT_LIBRARY}
+          ${COREAUDIO_LIBRARY}
+          )
+endif()
+
 
-if (WINDOWS)
-  set(WINDOWS_LIBRARIES
-      advapi32
-      shell32
-      ws2_32
-      mswsock
-      psapi
-      winmm
-      netapi32
-      wldap32
-      gdi32
-      user32
-      ole32
-      dbghelp
-      )
-else (WINDOWS)
-  set(WINDOWS_LIBRARIES "")
-endif (WINDOWS)
-    
-mark_as_advanced(DL_LIBRARY PTHREAD_LIBRARY WINDOWS_LIBRARIES)
 
-endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/MESHOPTIMIZER.cmake b/indra/cmake/MESHOPTIMIZER.cmake
deleted file mode 100644
index 1c5b47b9bddfd81c28eb840b2dae6361eed97d42..0000000000000000000000000000000000000000
--- a/indra/cmake/MESHOPTIMIZER.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- cmake -*-
-
-include(Linking)
-include(Prebuilt)
-
-use_prebuilt_binary(meshoptimizer)
-
-if (WINDOWS)
-  set(MESHOPTIMIZER_LIBRARIES meshoptimizer.lib)
-elseif (LINUX)
-  set(MESHOPTIMIZER_LIBRARIES meshoptimizer.o)
-elseif (DARWIN)
-  set(MESHOPTIMIZER_LIBRARIES libmeshoptimizer.a)
-endif (WINDOWS)
-
-set(MESHOPTIMIZER_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/meshoptimizer)
diff --git a/indra/cmake/MediaPluginBase.cmake b/indra/cmake/MediaPluginBase.cmake
deleted file mode 100644
index 2be035b641450bd3a7b16adfd205b77685a1a2f0..0000000000000000000000000000000000000000
--- a/indra/cmake/MediaPluginBase.cmake
+++ /dev/null
@@ -1,8 +0,0 @@
-# -*- cmake -*-
-
-
-set(MEDIA_PLUGIN_BASE_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/media_plugins/base/
-    )
-
-set(MEDIA_PLUGIN_BASE_LIBRARIES media_plugin_base)
diff --git a/indra/cmake/Meshoptimizer.cmake b/indra/cmake/Meshoptimizer.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..fd144d2b97ca253c382df907c6c5732129b78031
--- /dev/null
+++ b/indra/cmake/Meshoptimizer.cmake
@@ -0,0 +1,20 @@
+# -*- cmake -*-
+
+include(Linking)
+include(Prebuilt)
+
+include_guard()
+add_library( ll::meshoptimizer INTERFACE IMPORTED )
+
+use_system_binary(meshoptimizer)
+use_prebuilt_binary(meshoptimizer)
+
+if (WINDOWS)
+  target_link_libraries( ll::meshoptimizer INTERFACE meshoptimizer.lib)
+elseif (LINUX)
+  target_link_libraries( ll::meshoptimizer INTERFACE meshoptimizer.o)
+elseif (DARWIN)
+  target_link_libraries( ll::meshoptimizer INTERFACE libmeshoptimizer.a)
+endif (WINDOWS)
+
+target_include_directories( ll::meshoptimizer SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/meshoptimizer)
diff --git a/indra/cmake/NDOF.cmake b/indra/cmake/NDOF.cmake
index 388df16a5260e4cb5bf5a07ca7922432dac06a4a..b88fbccf2a1cb376b81c98804e6945b10debd844 100644
--- a/indra/cmake/NDOF.cmake
+++ b/indra/cmake/NDOF.cmake
@@ -3,34 +3,22 @@ include(Prebuilt)
 
 set(NDOF ON CACHE BOOL "Use NDOF space navigator joystick library.")
 
-if (NDOF)
-  if (USESYSTEMLIBS)
-    set(NDOF_FIND_REQUIRED ON)
-    include(FindNDOF)
-  else (USESYSTEMLIBS)
-    if (WINDOWS OR DARWIN)
-      use_prebuilt_binary(libndofdev)
-    elseif (LINUX)
-      use_prebuilt_binary(open-libndofdev)
-    endif (WINDOWS OR DARWIN)
+include_guard()
+add_library( ll::ndof INTERFACE IMPORTED )
 
-    if (WINDOWS)
-      set(NDOF_LIBRARY libndofdev)
-    elseif (DARWIN OR LINUX)
-      set(NDOF_LIBRARY ndofdev)
-    endif (WINDOWS)
+if (NDOF)
+  if (WINDOWS OR DARWIN)
+    use_prebuilt_binary(libndofdev)
+  elseif (LINUX)
+    use_prebuilt_binary(open-libndofdev)
+  endif (WINDOWS OR DARWIN)
 
-    set(NDOF_INCLUDE_DIR ${ARCH_PREBUILT_DIRS}/include/ndofdev)
-    set(NDOF_FOUND 1)
-  endif (USESYSTEMLIBS)
+  if (WINDOWS)
+    target_link_libraries( ll::ndof INTERFACE libndofdev)
+  elseif (DARWIN OR LINUX)
+    target_link_libraries( ll::ndof INTERFACE ndofdev)
+  endif (WINDOWS)
+  target_compile_definitions( ll::ndof INTERFACE LIB_NDOF=1)
 endif (NDOF)
 
-if (NDOF_FOUND)
-  add_definitions(-DLIB_NDOF=1)
-  include_directories(${NDOF_INCLUDE_DIR})
-else (NDOF_FOUND)
-  message(STATUS "Building without N-DoF joystick support")
-  set(NDOF_INCLUDE_DIR "")
-  set(NDOF_LIBRARY "")
-endif (NDOF_FOUND)
 
diff --git a/indra/cmake/NGHTTP2.cmake b/indra/cmake/NGHTTP2.cmake
index df191ff3c136eb08a6af83960070005800e3bb7b..6396a5bd016655773d66e6611906912db493f08f 100644
--- a/indra/cmake/NGHTTP2.cmake
+++ b/indra/cmake/NGHTTP2.cmake
@@ -1,20 +1,16 @@
+include(Linking)
 include(Prebuilt)
 
-set(NGHTTP2_FIND_QUIETLY ON)
-set(NGHTTP2_FIND_REQUIRED ON)
+include_guard()
+add_library( ll::nghttp2 INTERFACE IMPORTED )
 
-if (USESYSTEMLIBS)
-  include(FindNGHTTP2)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(nghttp2)
-  if (WINDOWS)
-    set(NGHTTP2_LIBRARIES 
-      ${ARCH_PREBUILT_DIRS_RELEASE}/nghttp2.lib
-      )
-  elseif (DARWIN)
-    set(NGHTTP2_LIBRARIES libnghttp2.dylib)
-  else (WINDOWS)
-    set(NGHTTP2_LIBRARIES libnghttp2.a)
-  endif (WINDOWS)
-  set(NGHTTP2_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/nghttp2)
-endif (USESYSTEMLIBS)
+use_system_binary(nghttp2)
+use_prebuilt_binary(nghttp2)
+if (WINDOWS)
+  target_link_libraries( ll::nghttp2 INTERFACE ${ARCH_PREBUILT_DIRS_RELEASE}/nghttp2.lib)
+elseif (DARWIN)
+  target_link_libraries( ll::nghttp2 INTERFACE libnghttp2.dylib)
+else (WINDOWS)
+  target_link_libraries( ll::nghttp2 INTERFACE libnghttp2.a )
+endif (WINDOWS)
+target_include_directories( ll::nghttp2 SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/nghttp2)
diff --git a/indra/cmake/NVAPI.cmake b/indra/cmake/NVAPI.cmake
index 105f442a30f701cbcc97cb164122f7e8c364e1e9..ff5a5428e098774d6a4cb6564dffc2e8908eae22 100644
--- a/indra/cmake/NVAPI.cmake
+++ b/indra/cmake/NVAPI.cmake
@@ -5,12 +5,9 @@ set(NVAPI ON CACHE BOOL "Use NVAPI.")
 
 if (NVAPI)
   if (WINDOWS)
+    add_library( ll::nvapi INTERFACE IMPORTED )
+    target_link_libraries( ll::nvapi INTERFACE nvapi)
     use_prebuilt_binary(nvapi)
-    set(NVAPI_LIBRARY nvapi)
-  else (WINDOWS)
-    set(NVAPI_LIBRARY "")
   endif (WINDOWS)
-else (NVAPI)
-  set(NVAPI_LIBRARY "")
 endif (NVAPI)
 
diff --git a/indra/cmake/OPENAL.cmake b/indra/cmake/OPENAL.cmake
index 1bbfff6f9853328805c77fbe5a9bbaf72d918380..0b6a7c2853bcba8ddba496cd2e3d9bf9ee05537c 100644
--- a/indra/cmake/OPENAL.cmake
+++ b/indra/cmake/OPENAL.cmake
@@ -2,31 +2,37 @@
 include(Linking)
 include(Prebuilt)
 
-if (LINUX)
-  set(OPENAL ON CACHE BOOL "Enable OpenAL")
-else (LINUX)
-  set(OPENAL OFF CACHE BOOL "Enable OpenAL")
-endif (LINUX)
+include_guard()
+
+# ND: Turn this off by default, the openal code in the viewer isn't very well maintained, seems
+# to have memory leaks, has no option to play music streams
+# It probably makes sense to to completely remove it
+
+set(USE_OPENAL OFF CACHE BOOL "Enable OpenAL")
+# ND: To streamline arguments passed, switch from OPENAL to USE_OPENAL
+# To not break all old build scripts convert old arguments but warn about it
+if(OPENAL)
+  message( WARNING "Use of the OPENAL argument is deprecated, please switch to USE_OPENAL")
+  set(USE_OPENAL ${OPENAL})
+endif()
+
+if (USE_OPENAL)
+  add_library( ll::openal INTERFACE IMPORTED )
+  target_include_directories( ll::openal SYSTEM INTERFACE "${LIBS_PREBUILT_DIR}/include/AL")
+  target_compile_definitions( ll::openal INTERFACE LL_OPENAL=1)
+  use_prebuilt_binary(openal)
 
-if (OPENAL)
-  set(OPENAL_LIB_INCLUDE_DIRS "${LIBS_PREBUILT_DIR}/include/AL")
-  if (USESYSTEMLIBS)
-    include(FindPkgConfig)
-    include(FindOpenAL)
-    pkg_check_modules(OPENAL_LIB REQUIRED openal)
-    pkg_check_modules(FREEALUT_LIB REQUIRED freealut)
-  else (USESYSTEMLIBS)
-    use_prebuilt_binary(openal)
-  endif (USESYSTEMLIBS)
   if(WINDOWS)
-    set(OPENAL_LIBRARIES 
-      OpenAL32
-      alut
-    )
+    target_link_libraries( ll::openal INTERFACE
+            OpenAL32
+            alut
+            )
+  elseif(LINUX)
+    target_link_libraries( ll::openal INTERFACE
+            openal
+            alut
+            )
   else()
-    set(OPENAL_LIBRARIES 
-      openal
-      alut
-    )
+    message(FATAL_ERROR "OpenAL is not available for this platform")
   endif()
-endif (OPENAL)
+endif ()
diff --git a/indra/cmake/OpenGL.cmake b/indra/cmake/OpenGL.cmake
index 2259c992935ff42dbbf46eb4105467a7ec7584d8..bf7cd8366a98aa18073715469fa0e06d41e271f1 100644
--- a/indra/cmake/OpenGL.cmake
+++ b/indra/cmake/OpenGL.cmake
@@ -2,11 +2,5 @@
 
 include(Variables)
 include(Prebuilt)
-
-if (BUILD_HEADLESS)
-  SET(OPENGL_glu_LIBRARY GLU)
-  SET(OPENGL_HEADLESS_LIBRARIES OSMesa16 dl GLU)
-endif (BUILD_HEADLESS)
-
 include(FindOpenGL)
 
diff --git a/indra/cmake/OpenJPEG.cmake b/indra/cmake/OpenJPEG.cmake
index a078c97cb8fd209fc88bc9ff739d2eb4cabb841a..c4aab2e9e53ee9c41df49ff59df2724498226850 100644
--- a/indra/cmake/OpenJPEG.cmake
+++ b/indra/cmake/OpenJPEG.cmake
@@ -1,14 +1,11 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-set(OPENJPEG_FIND_QUIETLY ON)
-set(OPENJPEG_FIND_REQUIRED ON)
+include_guard()
+add_library( ll::openjpeg INTERFACE IMPORTED )
 
-if (USESYSTEMLIBS)
-  include(FindOpenJPEG)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(openjpeg)
+use_system_binary(openjpeg)
+use_prebuilt_binary(openjpeg)
 
-  set(OPENJPEG_LIBRARIES openjp2)
-  set(OPENJPEG_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/openjpeg)
-endif (USESYSTEMLIBS)
+target_link_libraries(ll::openjpeg INTERFACE openjp2 )
+target_include_directories( ll::openjpeg SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/openjpeg)
diff --git a/indra/cmake/OpenSSL.cmake b/indra/cmake/OpenSSL.cmake
index 32400f5e4e579bdd680627434ae8231329b895ec..3387c74f453c09e6379b667d755ae4bd0c8c1a67 100644
--- a/indra/cmake/OpenSSL.cmake
+++ b/indra/cmake/OpenSSL.cmake
@@ -1,23 +1,17 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-set(OpenSSL_FIND_QUIETLY ON)
-set(OpenSSL_FIND_REQUIRED ON)
+include_guard()
+add_library( ll::openssl INTERFACE IMPORTED )
 
-if (USESYSTEMLIBS)
-  include(FindOpenSSL)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(openssl)
-  if (WINDOWS)
-    set(OPENSSL_LIBRARIES libssl libcrypto)
-  else (WINDOWS)
-    set(OPENSSL_LIBRARIES ssl crypto)
-  endif (WINDOWS)
-  set(OPENSSL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
-endif (USESYSTEMLIBS)
+use_system_binary(openssl)
+use_prebuilt_binary(openssl)
+if (WINDOWS)
+  target_link_libraries(ll::openssl INTERFACE libssl libcrypto)
+elseif (LINUX)
+  target_link_libraries(ll::openssl INTERFACE ssl crypto dl)
+else()
+  target_link_libraries(ll::openssl INTERFACE ssl crypto)
+endif (WINDOWS)
+target_include_directories( ll::openssl SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
 
-if (LINUX)
-  set(CRYPTO_LIBRARIES crypto dl)
-elseif (DARWIN)
-  set(CRYPTO_LIBRARIES crypto)
-endif (LINUX)
diff --git a/indra/cmake/PNG.cmake b/indra/cmake/PNG.cmake
index 248a875a19bd6bfd451f9d8ec1d6ee3967e09c51..044262bc8d8607e262be9a7f8e4f1531cd08baa8 100644
--- a/indra/cmake/PNG.cmake
+++ b/indra/cmake/PNG.cmake
@@ -1,34 +1,14 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-set(PNG_FIND_QUIETLY ON)
-set(PNG_FIND_REQUIRED ON)
+include_guard()
+add_library( ll::libpng INTERFACE IMPORTED )
 
-if (USESYSTEMLIBS)
-  include(FindPNG)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(libpng)
-  if (WINDOWS)
-    set(PNG_LIBRARIES libpng16)
-    set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng16)
-  elseif(DARWIN)
-    set(PNG_LIBRARIES png16)
-    set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng16)
-  else()
-    #
-    # When we have updated static libraries in competition with older
-    # shared libraries and we want the former to win, we need to do some
-    # extra work.  The *_PRELOAD_ARCHIVES settings are invoked early
-    # and will pull in the entire archive to the binary giving it 
-    # priority in symbol resolution.  Beware of cmake moving the
-    # achive load itself to another place on the link command line.  If
-    # that happens, you can try something like -Wl,-lpng16 here to hide
-    # the archive.  Also be aware that the linker will not tolerate a
-    # second whole-archive load of the archive.  See viewer's
-    # CMakeLists.txt for more information.
-    #
-    set(PNG_PRELOAD_ARCHIVES -Wl,--whole-archive png16 -Wl,--no-whole-archive)
-    set(PNG_LIBRARIES png16)
-    set(PNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/libpng16)
-  endif()
-endif (USESYSTEMLIBS)
+use_system_binary(libpng)
+use_prebuilt_binary(libpng)
+if (WINDOWS)
+  target_link_libraries(ll::libpng INTERFACE libpng16)
+else()
+  target_link_libraries(ll::libpng INTERFACE png16 )
+endif()
+target_include_directories( ll::libpng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/libpng16)
diff --git a/indra/cmake/PluginAPI.cmake b/indra/cmake/PluginAPI.cmake
index d1649e824868ee702d07f0510fe927aae9cf7692..114415e514bd30ff3c928ae9f5ce263946e1672d 100644
--- a/indra/cmake/PluginAPI.cmake
+++ b/indra/cmake/PluginAPI.cmake
@@ -1,7 +1,9 @@
 # -*- cmake -*-
 
+add_library( ll::pluginlibraries INTERFACE IMPORTED )
+
 if (WINDOWS)
-  set(PLUGIN_API_WINDOWS_LIBRARIES
+  target_link_libraries( ll::pluginlibraries INTERFACE
       wsock32
       ws2_32
       psapi
@@ -9,8 +11,6 @@ if (WINDOWS)
       advapi32
       user32
       )
-else (WINDOWS)
-  set(PLUGIN_API_WINDOWS_LIBRARIES "")
 endif (WINDOWS)
 
 
diff --git a/indra/cmake/Prebuilt.cmake b/indra/cmake/Prebuilt.cmake
index 33a6d769167542a4294b4f8abbb017a0e5e2af93..634cc15c21c64bc6947066037038bccfbb6c7024 100644
--- a/indra/cmake/Prebuilt.cmake
+++ b/indra/cmake/Prebuilt.cmake
@@ -1,7 +1,5 @@
 # -*- cmake -*-
-
-if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
-set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+include_guard()
 
 include(FindAutobuild)
 if(INSTALL_PROPRIETARY)
@@ -25,40 +23,50 @@ endif ("${CMAKE_SOURCE_DIR}/../autobuild.xml" IS_NEWER_THAN "${PREBUILD_TRACKING
 # of previous attempts is serialized in the file
 # ${PREBUILD_TRACKING_DIR}/${_binary}_installed)
 macro (use_prebuilt_binary _binary)
-  if (NOT DEFINED USESYSTEMLIBS_${_binary})
-    set(USESYSTEMLIBS_${_binary} ${USESYSTEMLIBS})
-  endif (NOT DEFINED USESYSTEMLIBS_${_binary})
+    if( NOT DEFINED ${_binary}_installed )
+        set( ${_binary}_installed "")
+    endif()
 
-  if (NOT USESYSTEMLIBS_${_binary})
     if("${${_binary}_installed}" STREQUAL "" AND EXISTS "${PREBUILD_TRACKING_DIR}/${_binary}_installed")
-      file(READ ${PREBUILD_TRACKING_DIR}/${_binary}_installed "${_binary}_installed")
-      if(DEBUG_PREBUILT)
-        message(STATUS "${_binary}_installed: \"${${_binary}_installed}\"")
-      endif(DEBUG_PREBUILT)
+        file(READ ${PREBUILD_TRACKING_DIR}/${_binary}_installed "${_binary}_installed")
+        if(DEBUG_PREBUILT)
+            message(STATUS "${_binary}_installed: \"${${_binary}_installed}\"")
+        endif(DEBUG_PREBUILT)
     endif("${${_binary}_installed}" STREQUAL "" AND EXISTS "${PREBUILD_TRACKING_DIR}/${_binary}_installed")
 
     if(${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/${_binary}_installed OR NOT ${${_binary}_installed} EQUAL 0)
-      if(DEBUG_PREBUILT)
-        message(STATUS "cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install
+        if(DEBUG_PREBUILT)
+            message(STATUS "cd ${CMAKE_SOURCE_DIR} && ${AUTOBUILD_EXECUTABLE} install
         --install-dir=${AUTOBUILD_INSTALL_DIR}
         ${_binary} ")
-      endif(DEBUG_PREBUILT)
-      execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}"
-        install
-        --install-dir=${AUTOBUILD_INSTALL_DIR}
-        ${_binary}
-        WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
-        RESULT_VARIABLE ${_binary}_installed
-        )
-      file(WRITE ${PREBUILD_TRACKING_DIR}/${_binary}_installed "${${_binary}_installed}")
+        endif(DEBUG_PREBUILT)
+        execute_process(COMMAND "${AUTOBUILD_EXECUTABLE}"
+                install
+                --install-dir=${AUTOBUILD_INSTALL_DIR}
+                ${_binary}
+                WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
+                RESULT_VARIABLE ${_binary}_installed
+                )
+        file(WRITE ${PREBUILD_TRACKING_DIR}/${_binary}_installed "${${_binary}_installed}")
     endif(${PREBUILD_TRACKING_DIR}/sentinel_installed IS_NEWER_THAN ${PREBUILD_TRACKING_DIR}/${_binary}_installed OR NOT ${${_binary}_installed} EQUAL 0)
 
     if(NOT ${_binary}_installed EQUAL 0)
-      message(FATAL_ERROR
-              "Failed to download or unpack prebuilt '${_binary}'."
-              " Process returned ${${_binary}_installed}.")
+        message(FATAL_ERROR
+                "Failed to download or unpack prebuilt '${_binary}'."
+                " Process returned ${${_binary}_installed}.")
     endif (NOT ${_binary}_installed EQUAL 0)
-  endif (NOT USESYSTEMLIBS_${_binary})
 endmacro (use_prebuilt_binary _binary)
 
-endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+#Sadly we need a macro here, otherwise the return() will not properly work
+macro ( use_system_binary package )
+  if( USE_CONAN )
+    target_link_libraries( ll::${package} INTERFACE CONAN_PKG::${package} )
+    foreach( extra_pkg "${ARGN}" )
+      if( extra_pkg )
+        target_link_libraries( ll::${package} INTERFACE CONAN_PKG::${extra_pkg} )
+      endif()
+    endforeach()
+    return()
+  endif()
+endmacro()
+
diff --git a/indra/cmake/PulseAudio.cmake b/indra/cmake/PulseAudio.cmake
index cce27f1bdd12afb10e018f9d530d93512fd92126..303db97db6c7967ec52f80283208ea961abb3009 100644
--- a/indra/cmake/PulseAudio.cmake
+++ b/indra/cmake/PulseAudio.cmake
@@ -1,28 +1,4 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-set(PULSEAUDIO OFF CACHE BOOL "Build with PulseAudio support, if available.")
-
-if (PULSEAUDIO)
-  if (USESYSTEMLIBS)
-    include(FindPkgConfig)
-
-    pkg_check_modules(PULSEAUDIO libpulse)
-
-  elseif (LINUX)
-    use_prebuilt_binary(pulseaudio)
-    set(PULSEAUDIO_FOUND ON FORCE BOOL)
-    set(PULSEAUDIO_INCLUDE_DIRS
-        ${LIBS_PREBUILT_DIR}/include
-        )
-    # We don't need to explicitly link against pulseaudio itself, because
-    # the viewer probes for the system's copy at runtime.
-    set(PULSEAUDIO_LIBRARIES
-      # none needed!
-      )
-  endif (USESYSTEMLIBS)
-endif (PULSEAUDIO)
-
-if (PULSEAUDIO_FOUND)
-  add_definitions(-DLL_PULSEAUDIO_ENABLED=1)
-endif (PULSEAUDIO_FOUND)
+message( FATAL_ERROR "Pulseaudio cmake file is broken" )
diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake
index ed595f6966c6af33e72b985fcdf0a60e7574f4b9..dbf5033ce574fef8f25c457ab5b64ac62f917d66 100644
--- a/indra/cmake/Python.cmake
+++ b/indra/cmake/Python.cmake
@@ -5,32 +5,49 @@ set(PYTHONINTERP_FOUND)
 if (WINDOWS)
   # On Windows, explicitly avoid Cygwin Python.
 
-  find_program(PYTHON_EXECUTABLE
-    NAMES python.exe
+  # if the user has their own version of Python installed, prefer that
+  foreach(hive HKEY_CURRENT_USER HKEY_LOCAL_MACHINE)
+    # prefer more recent Python versions to older ones, if multiple versions
+    # are installed
+    foreach(pyver 3.11 3.10 3.9 3.8 3.7)
+      list(APPEND regpaths "[${hive}\\SOFTWARE\\Python\\PythonCore\\${pyver}\\InstallPath]")
+    endforeach()
+  endforeach()
+
+  # TODO: This logic has the disadvantage that if you have multiple versions
+  # of Python installed, the selected path won't necessarily be the newest -
+  # e.g. this GLOB will prefer Python310 to Python311. But since pymaybe is
+  # checked AFTER the registry entries, this will only surface as a problem if
+  # no installed Python appears in the registry.
+  file(GLOB pymaybe
+    "$ENV{PROGRAMFILES}/Python*"
+##  "$ENV{PROGRAMFILES(X86)}/Python*"
+    # The Windows environment variable is in fact as shown above, but CMake
+    # disallows querying an environment variable containing parentheses -
+    # thanks, Windows. Fudge by just appending " (x86)" to $PROGRAMFILES and
+    # hoping for the best.
+    "$ENV{PROGRAMFILES} (x86)/Python*"
+    "c:/Python*")
+
+  find_program(python
+    NAMES python3.exe python.exe
     NO_DEFAULT_PATH # added so that cmake does not find cygwin python
     PATHS
-    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.7\\InstallPath]
-    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.8\\InstallPath]
-    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.9\\InstallPath]
-    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.10\\InstallPath]
-    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.11\\InstallPath]
-    [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.7\\InstallPath]
-    [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.8\\InstallPath]
-    [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.9\\InstallPath]
-    [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\3.10\\InstallPath]
-    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\3.11\\InstallPath]
+    ${regpaths}
+    ${pymaybe}
     )
     include(FindPythonInterp)
 else()
-  find_program(PYTHON_EXECUTABLE python3)
+  find_program(python python3)
 
-  if (PYTHON_EXECUTABLE)
+  if (python)
     set(PYTHONINTERP_FOUND ON)
-  endif (PYTHON_EXECUTABLE)
+  endif (python)
 endif (WINDOWS)
 
-if (NOT PYTHON_EXECUTABLE)
+if (NOT python)
   message(FATAL_ERROR "No Python interpreter found")
-endif (NOT PYTHON_EXECUTABLE)
+endif (NOT python)
 
+set(PYTHON_EXECUTABLE "${python}" CACHE FILEPATH "Python interpreter for builds")
 mark_as_advanced(PYTHON_EXECUTABLE)
diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake
index a29d4021a3329cde05ba19d3e68f611fb1a91b94..0bf3bd85ff19c61cc4c5b33ea4cbc48b40357075 100644
--- a/indra/cmake/Tracy.cmake
+++ b/indra/cmake/Tracy.cmake
@@ -1,32 +1,18 @@
 # -*- cmake -*-
 include(Prebuilt)
 
+include_guard()
+add_library( ll::tracy INTERFACE IMPORTED )
+
 set(USE_TRACY OFF CACHE BOOL "Use Tracy profiler.")
 
 if (USE_TRACY)
-  set(TRACY_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tracy) 
-
-# See: indra/llcommon/llprofiler.h
-  add_definitions(-DLL_PROFILER_CONFIGURATION=3)
+  use_system_binary(tracy)
   use_prebuilt_binary(tracy)
 
-  if (WINDOWS)
-    MESSAGE(STATUS "Including Tracy for Windows: '${TRACY_INCLUDE_DIR}'")
-    set(TRACY_LIBRARY "TracyClient")
-  endif (WINDOWS)
-
-  if (DARWIN)
-    MESSAGE(STATUS "Including Tracy for Darwin: '${TRACY_INCLUDE_DIR}'")
-    set(TRACY_LIBRARY "TracyClient")
-  endif (DARWIN)
+  target_include_directories( ll::tracy SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/tracy)
 
-  if (LINUX)
-    MESSAGE(STATUS "Including Tracy for Linux: '${TRACY_INCLUDE_DIR}'")
-    set(TRACY_LIBRARY "TracyClient")
-  endif (LINUX)
-else (USE_TRACY)
-  # Tracy.cmake should not set LLCOMMON_INCLUDE_DIRS, let LLCommon.cmake do that
-  set(TRACY_INCLUDE_DIR "")
-  set(TRACY_LIBRARY "")
+  # See: indra/llcommon/llprofiler.h
+  add_compile_definitions(LL_PROFILER_CONFIGURATION=3)
 endif (USE_TRACY)
 
diff --git a/indra/cmake/Tut.cmake b/indra/cmake/Tut.cmake
index e11a3c3314c2862ecb4025d903ad1664bd651c7a..ad938308033e3fab73d43f2a533c4aa3d9a2536c 100644
--- a/indra/cmake/Tut.cmake
+++ b/indra/cmake/Tut.cmake
@@ -1,6 +1,4 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-if (NOT USESYSTEMLIBS)
-  use_prebuilt_binary(tut)
-endif(NOT USESYSTEMLIBS)
+use_prebuilt_binary(tut)
diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake
index 77fd505df361c70c3e47c9d880cafb44a268828c..8b70192efc802c7ab5dcb18480deb21cba4241ff 100644
--- a/indra/cmake/UI.cmake
+++ b/indra/cmake/UI.cmake
@@ -2,68 +2,53 @@
 include(Prebuilt)
 include(FreeType)
 
-if (USESYSTEMLIBS)
-  include(FindPkgConfig)
-    
-  if (LINUX)
-    set(PKGCONFIG_PACKAGES
-        atk
-        cairo
-        gdk-2.0
-        gdk-pixbuf-2.0
-        glib-2.0
-        gmodule-2.0
-        gtk+-2.0
-        gthread-2.0
-        libpng
-        pango
-        pangoft2
-        pangox
-        pangoxft
-        sdl
-        )
-  endif (LINUX)
+add_library( ll::uilibraries INTERFACE IMPORTED )
 
-  foreach(pkg ${PKGCONFIG_PACKAGES})
-    pkg_check_modules(${pkg} REQUIRED ${pkg})
-    include_directories(${${pkg}_INCLUDE_DIRS})
-    link_directories(${${pkg}_LIBRARY_DIRS})
-    list(APPEND UI_LIBRARIES ${${pkg}_LIBRARIES})
-    add_definitions(${${pkg}_CFLAGS_OTHERS})
-  endforeach(pkg)
-else (USESYSTEMLIBS)
-  if (LINUX)
-    use_prebuilt_binary(gtk-atk-pango-glib)
-  endif (LINUX)
+if (LINUX)
+  target_compile_definitions(ll::uilibraries INTERFACE LL_GTK=1 LL_X11=1 )
 
-  if (LINUX)
-    set(UI_LIBRARIES
-        atk-1.0
-        gdk-x11-2.0
-        gdk_pixbuf-2.0
-        Xinerama
-        glib-2.0
-        gmodule-2.0
-        gobject-2.0
-        gthread-2.0
-        gtk-x11-2.0
-        pango-1.0
-        pangoft2-1.0
-        pangox-1.0
-        pangoxft-1.0
-        ${FREETYPE_LIBRARIES}
-        )
-  endif (LINUX)
+  if( USE_CONAN )
+    target_link_libraries( ll::uilibraries INTERFACE CONAN_PKG::gtk )
+    return()
+  endif()
+  use_prebuilt_binary(gtk-atk-pango-glib)
+  
+  target_link_libraries( ll::uilibraries INTERFACE
+          atk-1.0
+          gdk-x11-2.0
+          gdk_pixbuf-2.0
+          Xinerama
+          glib-2.0
+          gmodule-2.0
+          gobject-2.0
+          gthread-2.0
+          gtk-x11-2.0
+          pango-1.0
+          pangoft2-1.0
+          pangox-1.0
+          pangoxft-1.0
+          Xinerama
+          ll::freetype
+          )
+endif (LINUX)
+if( WINDOWS )
+  target_link_libraries( ll::uilibraries INTERFACE
+          opengl32
+          comdlg32
+          dxguid
+          kernel32
+          odbc32
+          odbccp32
+          oleaut32
+          shell32
+          Vfw32
+          wer
+          winspool
+          imm32
+          )
+endif()
 
-  include_directories (
-      ${LIBS_PREBUILT_DIR}/include
-      ${LIBS_PREBUILT_DIR}/include
-      )
-  foreach(include ${${LL_ARCH}_INCLUDES})
-      include_directories(${LIBS_PREBUILT_DIR}/include/${include})
-  endforeach(include)
-endif (USESYSTEMLIBS)
+target_include_directories( ll::uilibraries SYSTEM INTERFACE
+        ${LIBS_PREBUILT_DIR}/include
+        )
 
-if (LINUX)
-  add_definitions(-DLL_GTK=1 -DLL_X11=1)
-endif (LINUX)
diff --git a/indra/cmake/URIPARSER.cmake b/indra/cmake/URIPARSER.cmake
index ecc5b74ef10eb07deec5ea1b88bab5e6d0238303..6c33ff70e1046d262f651369459025ea9534c057 100644
--- a/indra/cmake/URIPARSER.cmake
+++ b/indra/cmake/URIPARSER.cmake
@@ -1,35 +1,19 @@
 # -*- cmake -*-
 
-set(URIPARSER_FIND_QUIETLY ON)
-set(URIPARSER_FIND_REQUIRED ON)
+include_guard()
 
 include(Prebuilt)
 
-if (USESYSTEMLIBS)
-  include(FindURIPARSER)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(uriparser)
-  if (WINDOWS)
-    set(URIPARSER_LIBRARIES
-      debug uriparserd
-      optimized uriparser)
-  elseif (LINUX)
-    #
-    # When we have updated static libraries in competition with older
-    # shared libraries and we want the former to win, we need to do some
-    # extra work.  The *_PRELOAD_ARCHIVES settings are invoked early
-    # and will pull in the entire archive to the binary giving it.
-    # priority in symbol resolution.  Beware of cmake moving the
-    # achive load itself to another place on the link command line.  If
-    # that happens, you can try something like -Wl,-luriparser here to hide
-    # the archive.  Also be aware that the linker will not tolerate a
-    # second whole-archive load of the archive.  See viewer's
-    # CMakeLists.txt for more information.
-    #
-    set(URIPARSER_PRELOAD_ARCHIVES -Wl,--whole-archive uriparser -Wl,--no-whole-archive)
-    set(URIPARSER_LIBRARIES uriparser)
-  elseif (DARWIN)
-    set(URIPARSER_LIBRARIES liburiparser.dylib)
-  endif (WINDOWS)
-  set(URIPARSER_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/uriparser)
-endif (USESYSTEMLIBS)
+add_library( ll::uriparser INTERFACE IMPORTED )
+
+use_system_binary( uriparser )
+
+use_prebuilt_binary(uriparser)
+if (WINDOWS)
+  target_link_libraries( ll::uriparser INTERFACE uriparser)
+elseif (LINUX)
+  target_link_libraries( ll::uriparser INTERFACE uriparser)
+elseif (DARWIN)
+  target_link_libraries( ll::uriparser INTERFACE liburiparser.dylib)
+endif (WINDOWS)
+target_include_directories( ll::uriparser SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/uriparser)
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index e72475cbc4c09195b2d973b493b63624b22e5e3a..653db2069ab1e4ad0d519b6104ded9314792ad52 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -12,15 +12,18 @@
 # Switches set here and in 00-Common.cmake must agree with
 # https://bitbucket.org/lindenlab/viewer-build-variables/src/tip/variables
 # Reading $LL_BUILD is an attempt to directly use those switches.
-if ("$ENV{LL_BUILD}" STREQUAL "")
+if ("$ENV{LL_BUILD}" STREQUAL "" AND "${LL_BUILD_ENV}" STREQUAL "" )
   message(FATAL_ERROR "Environment variable LL_BUILD must be set")
+elseif("$ENV{LL_BUILD}" STREQUAL "")
+  set( ENV{LL_BUILD} "${LL_BUILD_ENV}" )
+  message( "Setting ENV{LL_BUILD} to cached variable ${LL_BUILD_ENV}" )
+else()
+  set( LL_BUILD_ENV "$ENV{LL_BUILD}" CACHE STRING "Save environment" FORCE )
 endif ()
+include_guard()
 
 # Relative and absolute paths to subtrees.
 
-if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
-set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
-
 if(NOT DEFINED COMMON_CMAKE_DIR)
     set(COMMON_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake")
 endif(NOT DEFINED COMMON_CMAKE_DIR)
@@ -70,39 +73,36 @@ endif (NOT CMAKE_BUILD_TYPE)
 # If someone has specified an address size, use that to determine the
 # architecture.  Otherwise, let the architecture specify the address size.
 if (ADDRESS_SIZE EQUAL 32)
-  #message(STATUS "ADDRESS_SIZE is 32")
   set(ARCH i686)
 elseif (ADDRESS_SIZE EQUAL 64)
-  #message(STATUS "ADDRESS_SIZE is 64")
   set(ARCH x86_64)
 else (ADDRESS_SIZE EQUAL 32)
-  #message(STATUS "ADDRESS_SIZE is UNRECOGNIZED: '${ADDRESS_SIZE}'")
-  # Use Python's platform.machine() since uname -m isn't available everywhere.
-  # Even if you can assume cygwin uname -m, the answer depends on whether
-  # you're running 32-bit cygwin or 64-bit cygwin! But even 32-bit Python will
-  # report a 64-bit processor.
-  execute_process(COMMAND
-                  "${PYTHON_EXECUTABLE}" "-c"
-                  "import platform; print platform.machine()"
-                  OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
-  # We expect values of the form i386, i686, x86_64, AMD64.
-  # In CMake, expressing ARCH.endswith('64') is awkward:
-  string(LENGTH "${ARCH}" ARCH_LENGTH)
-  math(EXPR ARCH_LEN_2 "${ARCH_LENGTH} - 2")
-  string(SUBSTRING "${ARCH}" ${ARCH_LEN_2} 2 ARCH_LAST_2)
-  if (ARCH_LAST_2 STREQUAL 64)
-    #message(STATUS "ARCH is detected as 64; ARCH is ${ARCH}")
+  # Note we cannot use if(DARWIN) here, this variable is set way lower
+  if( ${CMAKE_SYSTEM_NAME} MATCHES "Darwin" )
     set(ADDRESS_SIZE 64)
-  else ()
-    #message(STATUS "ARCH is detected as 32; ARCH is ${ARCH}")
-    set(ADDRESS_SIZE 32)
-  endif ()
+    set(ARCH x86_64)
+  else()
+    # Use Python's platform.machine() since uname -m isn't available everywhere.
+    # Even if you can assume cygwin uname -m, the answer depends on whether
+    # you're running 32-bit cygwin or 64-bit cygwin! But even 32-bit Python will
+    # report a 64-bit processor.
+    execute_process(COMMAND
+            "${PYTHON_EXECUTABLE}" "-c"
+            "import platform; print( platform.machine() )"
+            OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
+    string( REGEX MATCH ".*(64)$" RE_MATCH "${ARCH}" )
+    if( RE_MATCH AND ${CMAKE_MATCH_1} STREQUAL "64" )
+      set(ADDRESS_SIZE 64)
+      set(ARCH x86_64)
+    else()
+      set(ADDRESS_SIZE 32)
+      set(ARCH i686)
+    endif()
+  endif()
 endif (ADDRESS_SIZE EQUAL 32)
 
 if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
   set(WINDOWS ON BOOL FORCE)
-  set(LL_ARCH ${ARCH}_win32)
-  set(LL_ARCH_DIR ${ARCH}-win32)
 endif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
 
 if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
@@ -129,9 +129,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 
   include(ConfigurePkgConfig)
 
-  set(LL_ARCH ${ARCH}_linux)
-  set(LL_ARCH_DIR ${ARCH}-linux)
-
   if (INSTALL_PROPRIETARY)
     # Only turn on headless if we can find osmesa libraries.
     include(FindPkgConfig)
@@ -200,9 +197,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
   set(CMAKE_OSX_ARCHITECTURES "${ARCH}")
   string(REPLACE "i686"  "i386"   CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}")
   string(REPLACE "AMD64" "x86_64" CMAKE_OSX_ARCHITECTURES "${CMAKE_OSX_ARCHITECTURES}")
-
-  set(LL_ARCH ${ARCH}_darwin)
-  set(LL_ARCH_DIR universal-darwin)
 endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
 
 # Default deploy grid
@@ -214,10 +208,10 @@ set(ENABLE_SIGNING OFF CACHE BOOL "Enable signing the viewer")
 set(SIGNING_IDENTITY "" CACHE STRING "Specifies the signing identity to use, if necessary.")
 
 set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
-set(USESYSTEMLIBS OFF CACHE BOOL "Use libraries from your system rather than Linden-supplied prebuilt libraries.")
 
 set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
 
 source_group("CMake Rules" FILES CMakeLists.txt)
 
-endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+get_property(LL_GENERATOR_IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
+
diff --git a/indra/cmake/ViewerMiscLibs.cmake b/indra/cmake/ViewerMiscLibs.cmake
index fc5bdedb5afb3a5a3a23b3146c9500e582fe4119..00f8b77106c705f4c52e5e019db3ddac1f6137bc 100644
--- a/indra/cmake/ViewerMiscLibs.cmake
+++ b/indra/cmake/ViewerMiscLibs.cmake
@@ -1,12 +1,20 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-if (NOT USESYSTEMLIBS)
-  if (LINUX)
-    use_prebuilt_binary(libuuid)
+if (LINUX)
+  #use_prebuilt_binary(libuuid)
+  add_library( ll::fontconfig INTERFACE IMPORTED )
+
+  if( NOT USE_CONAN )
     use_prebuilt_binary(fontconfig)
-  endif (LINUX)
+  else()
+    target_link_libraries( ll::fontconfig INTERFACE CONAN_PKG::fontconfig )
+  endif()
+endif (LINUX)
+
+if( NOT USE_CONAN )
   use_prebuilt_binary(libhunspell)
-  use_prebuilt_binary(slvoice)
-endif(NOT USESYSTEMLIBS)
+endif()
+
+use_prebuilt_binary(slvoice)
 
diff --git a/indra/cmake/XmlRpcEpi.cmake b/indra/cmake/XmlRpcEpi.cmake
index 8c3790ea89f846784ecd233fb2f66c6645ff7851..6409f9d6e2638ce8b98332aacdf793569786c131 100644
--- a/indra/cmake/XmlRpcEpi.cmake
+++ b/indra/cmake/XmlRpcEpi.cmake
@@ -1,20 +1,11 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-set(XMLRPCEPI_FIND_QUIETLY ON)
-set(XMLRPCEPI_FIND_REQUIRED ON)
+include_guard()
+add_library( ll::xmlrpc-epi INTERFACE IMPORTED )
 
-if (USESYSTEMLIBS)
-  include(FindXmlRpcEpi)
-else (USESYSTEMLIBS)
-    use_prebuilt_binary(xmlrpc-epi)
-    if (WINDOWS)
-        set(XMLRPCEPI_LIBRARIES
-            debug xmlrpc-epid
-            optimized xmlrpc-epi
-        )
-    else (WINDOWS)
-        set(XMLRPCEPI_LIBRARIES xmlrpc-epi)
-    endif (WINDOWS)
-    set(XMLRPCEPI_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
-endif (USESYSTEMLIBS)
+use_system_binary( xmlrpc-epi )
+
+use_prebuilt_binary(xmlrpc-epi)
+target_link_libraries(ll::xmlrpc-epi INTERFACE xmlrpc-epi )
+target_include_directories( ll::xmlrpc-epi SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include)
diff --git a/indra/cmake/ZLIBNG.cmake b/indra/cmake/ZLIBNG.cmake
index 1f46a23d92c9ffc8e5081d8c82e857cb853b2d0d..5d99cd97099a77f8164443c89178cd2162631301 100644
--- a/indra/cmake/ZLIBNG.cmake
+++ b/indra/cmake/ZLIBNG.cmake
@@ -1,35 +1,22 @@
 # -*- cmake -*-
 
-set(ZLIBNG_FIND_QUIETLY ON)
-set(ZLIBNG_FIND_REQUIRED ON)
-
 include(Prebuilt)
 
-if (USESYSTEMLIBS)
-  include(FindZLIBNG)
-else (USESYSTEMLIBS)
-  use_prebuilt_binary(zlib-ng)
-  if (WINDOWS)
-    set(ZLIBNG_LIBRARIES 
-      debug zlib
-      optimized zlib)
-  elseif (LINUX)
-    #
-    # When we have updated static libraries in competition with older
-    # shared libraries and we want the former to win, we need to do some
-    # extra work.  The *_PRELOAD_ARCHIVES settings are invoked early
-    # and will pull in the entire archive to the binary giving it 
-    # priority in symbol resolution.  Beware of cmake moving the
-    # achive load itself to another place on the link command line.  If
-    # that happens, you can try something like -Wl,-lz here to hide
-    # the archive.  Also be aware that the linker will not tolerate a
-    # second whole-archive load of the archive.  See viewer's
-    # CMakeLists.txt for more information.
-    #
-    set(ZLIBNG_PRELOAD_ARCHIVES -Wl,--whole-archive z -Wl,--no-whole-archive)
-    set(ZLIBNG_LIBRARIES z)
-  elseif (DARWIN)
-    set(ZLIBNG_LIBRARIES z)
-  endif (WINDOWS)
-  set(ZLIBNG_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/zlib-ng)
-endif (USESYSTEMLIBS)
+include_guard()
+add_library( ll::zlib-ng INTERFACE IMPORTED )
+
+if(USE_CONAN )
+  target_link_libraries( ll::zlib-ng INTERFACE CONAN_PKG::zlib )
+  return()
+endif()
+
+use_prebuilt_binary(zlib-ng)
+if (WINDOWS)
+  target_link_libraries( ll::zlib-ng INTERFACE zlib )
+else()
+  target_link_libraries( ll::zlib-ng INTERFACE z )
+endif (WINDOWS)
+
+if( NOT LINUX )
+  target_include_directories( ll::zlib-ng SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/zlib-ng)
+endif()
diff --git a/indra/cmake/bugsplat.cmake b/indra/cmake/bugsplat.cmake
index 4edc4c59cdb630c08a4bf8bb7368979dc5e273fc..509981d72cd8a4d30f9a0499a03ac7b64317e93a 100644
--- a/indra/cmake/bugsplat.cmake
+++ b/indra/cmake/bugsplat.cmake
@@ -9,29 +9,33 @@ else (INSTALL_PROPRIETARY)
     set(USE_BUGSPLAT OFF CACHE BOOL "Use the BugSplat crash reporting system")
 endif (INSTALL_PROPRIETARY)
 
+include_guard()
+add_library( ll::bugsplat INTERFACE IMPORTED )
+
 if (USE_BUGSPLAT)
-    if (NOT USESYSTEMLIBS)
-        include(Prebuilt)
-        use_prebuilt_binary(bugsplat)
-        if (WINDOWS)
-            set(BUGSPLAT_LIBRARIES 
+    include(Prebuilt)
+    use_prebuilt_binary(bugsplat)
+    if (WINDOWS)
+        target_link_libraries( ll::bugsplat INTERFACE
                 ${ARCH_PREBUILT_DIRS_RELEASE}/bugsplat.lib
                 )
-        elseif (DARWIN)
-            find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED
+        target_include_directories( ll::bugsplat SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/bugsplat)
+    elseif (DARWIN)
+        find_library(BUGSPLAT_LIBRARIES BugsplatMac REQUIRED
                 NO_DEFAULT_PATH PATHS "${ARCH_PREBUILT_DIRS_RELEASE}")
-        else (WINDOWS)
-            message(FATAL_ERROR "BugSplat is not supported; add -DUSE_BUGSPLAT=OFF")
-        endif (WINDOWS)
-    else (NOT USESYSTEMLIBS)
-        set(BUGSPLAT_FIND_QUIETLY ON)
-        set(BUGSPLAT_FIND_REQUIRED ON)
-        include(FindBUGSPLAT)
-    endif (NOT USESYSTEMLIBS)
+        target_link_libraries( ll::bugsplat INTERFACE
+                ${BUGSPLAT_LIBRARIES}
+                )
+    else (WINDOWS)
+        message(FATAL_ERROR "BugSplat is not supported; add -DUSE_BUGSPLAT=OFF")
+    endif (WINDOWS)
 
-    set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name")
+    if( NOT BUGSPLAT_DB )
+        message( FATAL_ERROR "You need to set BUGSPLAT_DB when setting USE_BUGSPLAT" )
+    endif()
 
-    set(BUGSPLAT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/bugsplat)
-    set(BUGSPLAT_DEFINE "LL_BUGSPLAT")
+    set_property( TARGET ll::bugsplat APPEND PROPERTY INTERFACE_COMPILE_DEFINITIONS LL_BUGSPLAT)
+else()
+    set(BUGSPLAT_DB "" CACHE STRING "BugSplat crash database name")
 endif (USE_BUGSPLAT)
 
diff --git a/indra/cmake/run_build_test.py b/indra/cmake/run_build_test.py
index 1e92868ae76fdfbad51d94e418d784b865ced85c..1f040bded519f85d81ac0ee7a5210f581b5113ea 100755
--- a/indra/cmake/run_build_test.py
+++ b/indra/cmake/run_build_test.py
@@ -73,7 +73,7 @@ def main(command, arguments=[], libpath=[], vars={}):
     if sys.platform == "win32":
         lpvars = ["PATH"]
     elif sys.platform == "darwin":
-        lpvars = ["LD_LIBRARY_PATH", "DYLD_LIBRARY_PATH"]
+        lpvars = ["LD_LIBRARY_PATH"] # , "DYLD_LIBRARY_PATH"]
     elif sys.platform.startswith("linux"):
         lpvars = ["LD_LIBRARY_PATH"]
     else:
diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt
index bd59f57e492948c12ef39b88737a405f0514bdec..ee2890778b45ce72e2bde5a68bf33362ca20b494 100644
--- a/indra/integration_tests/llimage_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt
@@ -12,16 +12,6 @@ include(LLImageJ2COJ)
 include(LLKDU)
 include(LLFileSystem)
 
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    )
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    )
-
 set(llimage_libtest_SOURCE_FILES
     llimage_libtest.cpp
     )
@@ -31,9 +21,6 @@ set(llimage_libtest_HEADER_FILES
     llimage_libtest.h
     )
 
-set_source_files_properties(${llimage_libtest_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llimage_libtest_SOURCE_FILES ${llimage_libtest_HEADER_FILES})
 
 add_executable(llimage_libtest
@@ -48,37 +35,21 @@ set_target_properties(llimage_libtest
     FALSE
 )
 
-# OS-specific libraries
-if (DARWIN)
-  include(CMakeFindFrameworks)
-  find_library(COREFOUNDATION_LIBRARY CoreFoundation)
-  set(OS_LIBRARIES ${COREFOUNDATION_LIBRARY})
-elseif (WINDOWS)
-  set(OS_LIBRARIES)
-elseif (LINUX)
-  set(OS_LIBRARIES)
-else (DARWIN)
-  message(FATAL_ERROR "Unknown platform")
-endif (DARWIN)
-
 # Libraries on which this application depends on
 # Sort by high-level to low-level
 target_link_libraries(llimage_libtest
-    ${LEGACY_STDIO_LIBS}
-    ${LLCOMMON_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLIMAGE_LIBRARIES}
-    ${LLKDU_LIBRARIES}
-    ${KDU_LIBRARY}
-    ${LLIMAGEJ2COJ_LIBRARIES}
-    ${OS_LIBRARIES}
-    )
+        llcommon
+        llfilesystem
+        llmath
+        llimage
+        llkdu
+        llimagej2coj
+        )
     
 if (DARWIN)
   # Path inside the app bundle where we'll need to copy libraries
   set(LLIMAGE_LIBTEST_DESTINATION_DIR
-    ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/llimage_libtest.app/Contents/Resources
+    ${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/llimage_libtest.app/Contents/Resources
   )
   # Create the Contents/Resources directory
   add_custom_command(
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index 3957ede77f01d49af6eabc3cd7d389c223c4d8d8..d603e57aab87fab8bd8203bda2dbcd8df5750cd6 100644
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -22,23 +22,6 @@ include(Hunspell)
 include(Linking)
 # include(Tut)
 
-include_directories(
-    ${FREETYPE_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLUI_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    ${LIBS_PREBUILD_DIR}/include/hunspell
-    )
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLXML_SYSTEM_INCLUDE_DIRS}
-    )
-
 set(llui_libtest_SOURCE_FILES
     llui_libtest.cpp
     llwidgetreg.cpp
@@ -50,50 +33,26 @@ set(llui_libtest_HEADER_FILES
     llwidgetreg.h
     )
 
-set_source_files_properties(${llui_libtest_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llui_libtest_SOURCE_FILES ${llui_libtest_HEADER_FILES})
 
 add_executable(llui_libtest ${llui_libtest_SOURCE_FILES})
 
-# Link with OS-specific libraries for LLWindow dependency
-if (DARWIN)
-  find_library(COCOA_LIBRARY Cocoa)
-  find_library(IOKIT_LIBRARY IOKit)
-  set(OS_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY})
-elseif (WINDOWS)
-  #ll_stack_trace needs this now...
-  list(APPEND WINDOWS_LIBRARIES dbghelp)
-  set(OS_LIBRARIES ${WINDOWS_LIBRARIES})
-elseif (LINUX)
-  set(OS_LIBRARIES)
-else (DARWIN)
-  message(FATAL_ERROR "unknown platform")
-endif (DARWIN)
-
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 target_link_libraries(llui_libtest
-    ${LEGACY_STDIO_LIBS}
-    llui
-    llinventory
-    llmessage
-    ${LLRENDER_LIBRARIES}
-    ${LLIMAGE_LIBRARIES}
-    ${LLKDU_LIBRARIES}
-    ${KDU_LIBRARY}
-    ${LLIMAGEJ2COJ_LIBRARIES}
-    ${OS_LIBRARIES}
-    ${GOOGLE_PERFTOOLS_LIBRARIES}
-    ${HUNSPELL_LIBRARY}
-    )
+        llui
+        llinventory
+        llmessage
+        llrender
+        llimage
+        llkdu
+        llimagej2coj
+        )
 
 if (WINDOWS)
     set_target_properties(llui_libtest
         PROPERTIES 
         LINK_FLAGS "/NODEFAULTLIB:LIBCMT"
-        LINK_FLAGS_DEBUG "/NODEFAULTLIB:MSVCRT /NODEFAULTLIB:LIBCMTD"
         )
 
     # Copy over OpenJPEG.dll
@@ -101,7 +60,7 @@ if (WINDOWS)
     set(OPENJPEG_RELEASE
         "${ARCH_PREBUILT_DIRS_RELEASE}/openjp2.dll")
     add_custom_command( TARGET llui_libtest POST_BUILD
-        COMMAND ${CMAKE_COMMAND} -E copy_if_different 
+            COMMAND ${CMAKE_COMMAND} -E copy_if_different
             ${OPENJPEG_RELEASE} ${CMAKE_CURRENT_BINARY_DIR}
         COMMENT "Copying OpenJPEG DLLs to binary directory"
         )
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 5b277846b750e79f765267217415e0f2b4fccf1e..820f356daec25e5816bc2f8772f365931a1acfdc 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -125,7 +125,7 @@ def get_default_platform(dummy):
          but not application name (used internally)""",
          default=None),
     dict(name='configuration',
-         description="""The build configuration used.""",
+         description="""The build configurations sub directory used.""",
          default="Release"),
     dict(name='dest', description='Destination directory.', default=DEFAULT_SRCTREE),
     dict(name='grid',
diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
index aa82ed12cc2d8c23a6710709c2d065f92c8f122b..1793aa82b991646ec52ae3e24c63f8722001db77 100644
--- a/indra/linux_crash_logger/CMakeLists.txt
+++ b/indra/linux_crash_logger/CMakeLists.txt
@@ -45,9 +45,6 @@ set(linux_crash_logger_HEADER_FILES
     llcrashloggerlinux.h
     )
 
-set_source_files_properties(${linux_crash_logger_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND linux_crash_logger_SOURCE_FILES
      ${linux_crash_logger_HEADER_FILES}
      )
@@ -61,19 +58,14 @@ set(LIBRT_LIBRARY rt)
 
 
 target_link_libraries(linux-crash-logger
-    ${LLCRASHLOGGER_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLXML_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLCOREHTTP_LIBRARIES}
-    ${LLCOMMON_LIBRARIES}
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    ${UI_LIBRARIES}
-    ${DB_LIBRARIES}
-    ${FREETYPE_LIBRARIES}
-    ${LIBRT_LIBRARY}
+        llcrashlogger
+        llfilesystem
+        llxml
+        llmessage
+        llmath
+        llcorehttp
+        llcommon
+        ll::uilibraries
     )
 
 add_custom_target(linux-crash-logger-target ALL
diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt
index 268849ad74b6e2dfb78b16f1ef8803b5f61fae96..75c0e276eba8c6265253d19cdd66f443455d9135 100644
--- a/indra/llappearance/CMakeLists.txt
+++ b/indra/llappearance/CMakeLists.txt
@@ -4,30 +4,11 @@ project(llappearance)
 
 include(00-Common)
 include(LLCommon)
-include(LLCharacter)
 include(LLImage)
-include(LLInventory)
-include(LLMath)
-include(LLMessage)
 include(LLCoreHttp)
-include(LLRender)
-include(LLFileSystem)
 include(LLWindow)
-include(LLXML)
 include(Linking)
 
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLCHARACTER_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLINVENTORY_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    )
-
 set(llappearance_SOURCE_FILES
     llavatarappearance.cpp
     llavatarjoint.cpp
@@ -71,41 +52,37 @@ set(llappearance_HEADER_FILES
     llavatarappearancedefines.h
     )
 
-set_source_files_properties(${llappearance_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES})
 
 add_library (llappearance ${llappearance_SOURCE_FILES})
 
 target_link_libraries(llappearance
-    ${LLCHARACTER_LIBRARIES}
-    ${LLINVENTORY_LIBRARIES}
-    ${LLIMAGE_LIBRARIES}
-    ${LLRENDER_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLXML_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLCOREHTTP_LIBRARIES}
-    ${LLCOMMON_LIBRARIES}
+        llcharacter
+        llinventory
+        llimage
+        llrender
+        llfilesystem
+        llmath
+        llxml
+        llmessage
+        llcorehttp
+        llcommon
     )
+target_include_directories( llappearance  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
 
 if (BUILD_HEADLESS)
   add_library (llappearanceheadless ${llappearance_SOURCE_FILES})
-  
+  target_include_directories( llappearanceheadless  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
+
   target_link_libraries(llappearanceheadless
-      ${LLCHARACTER_LIBRARIES}
-      ${LLINVENTORY_LIBRARIES}
-      ${LLIMAGE_LIBRARIES}
-      ${LLRENDERHEADLESS_LIBRARIES}
-      ${LLFILESYSTEM_LIBRARIES}
-      ${LLMATH_LIBRARIES}
-      ${LLXML_LIBRARIES}
-      ${LLMATH_LIBRARIES}
-      ${LLMESSAGE_LIBRARIES}
-      ${LLCOREHTTP_LIBRARIES}
-      ${LLCOMMON_LIBRARIES}
+          llcharacter
+          llinventory
+          llimage
+          llfilesystem
+          llmath
+          llxml
+          llmessage
+          llcorehttp
+          llcommon
       )
 endif (BUILD_HEADLESS)
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt
index 92a5cfe22fc169e4e0223061c1f27fa926756935..4f469b9bb5145ab61be98c71e703655b0fe8e709 100644
--- a/indra/llaudio/CMakeLists.txt
+++ b/indra/llaudio/CMakeLists.txt
@@ -7,23 +7,6 @@ include(LLAudio)
 include(FMODSTUDIO)
 include(OPENAL)
 include(LLCommon)
-include(LLMath)
-include(LLMessage)
-include(LLFileSystem)
-
-include_directories(
-    ${LLAUDIO_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${OGG_INCLUDE_DIRS}
-    ${VORBISENC_INCLUDE_DIRS}
-    ${VORBISFILE_INCLUDE_DIRS}
-    ${VORBIS_INCLUDE_DIRS}
-    ${OPENAL_LIB_INCLUDE_DIRS}
-    ${FREEAULT_LIB_INCLUDE_DIRS}
-    )
 
 set(llaudio_SOURCE_FILES
     llaudioengine.cpp
@@ -42,10 +25,7 @@ set(llaudio_HEADER_FILES
     llwindgen.h
     )
 
-if (FMODSTUDIO)
-    include_directories(
-        ${FMODSTUDIO_INCLUDE_DIR}
-        )
+if (TARGET ll::fmodstudio)
     list(APPEND llaudio_SOURCE_FILES
          llaudioengine_fmodstudio.cpp
          lllistener_fmodstudio.cpp
@@ -57,13 +37,9 @@ if (FMODSTUDIO)
          lllistener_fmodstudio.h
          llstreamingaudio_fmodstudio.h
          )
-endif (FMODSTUDIO)
-
-if (OPENAL)
-  include_directories(
-    ${OPENAL_LIBRARIES}
-    )
+endif ()
 
+if (TARGET ll::openal)
   list(APPEND llaudio_SOURCE_FILES
     llaudioengine_openal.cpp
     lllistener_openal.cpp
@@ -73,22 +49,23 @@ if (OPENAL)
     llaudioengine_openal.h
     lllistener_openal.h
     )
-endif (OPENAL)
-
-set_source_files_properties(${llaudio_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
+endif ()
 
 list(APPEND llaudio_SOURCE_FILES ${llaudio_HEADER_FILES})
 
 add_library (llaudio ${llaudio_SOURCE_FILES})
-target_link_libraries(
-    llaudio
-    ${LLCOMMON_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${VORBISENC_LIBRARIES}
-    ${VORBISFILE_LIBRARIES}
-    ${VORBIS_LIBRARIES}
-    ${OGG_LIBRARIES}
+target_include_directories( llaudio  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries( llaudio
+        llcommon
+        llmath
+        llmessage
+        llfilesystem
+        ll::vorbis
     )
+
+if( TARGET ll::openal )
+    target_link_libraries( llaudio ll::openal )
+endif()
+if( TARGET ll::fmodstudio )
+    target_link_libraries( llaudio ll::fmodstudio )
+endif()
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt
index d90ffb55434611dcd8d64d41b6d01ee9a076b77d..bc45eb474a4a7bb6660494b747c90cf5dad16959 100644
--- a/indra/llcharacter/CMakeLists.txt
+++ b/indra/llcharacter/CMakeLists.txt
@@ -4,22 +4,6 @@ project(llcharacter)
 
 include(00-Common)
 include(LLCommon)
-include(LLMath)
-include(LLMessage)
-include(LLFileSystem)
-include(LLXML)
-
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    )
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLXML_SYSTEM_INCLUDE_DIRS}
-    )
 
 set(llcharacter_SOURCE_FILES
     llanimationstates.cpp
@@ -73,18 +57,16 @@ set(llcharacter_HEADER_FILES
     llvisualparam.h
     )
 
-set_source_files_properties(${llcharacter_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES})
 
 add_library (llcharacter ${llcharacter_SOURCE_FILES})
+target_include_directories( llcharacter  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
 
 target_link_libraries(
-    llcharacter
-    ${LLCOMMON_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLXML_LIBRARIES}
+        llcharacter
+        llcommon
+        llmath
+        llmessage
+        llfilesystem
+        llxml
     )
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index fab7550c9a0b7e76194797827aa35afcdb3a0429..516813aae1e30b5ab897136036f08b91a02a4f0d 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -14,19 +14,6 @@ include(ZLIBNG)
 include(URIPARSER)
 include(Tracy)
 
-include_directories(
-    ${EXPAT_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${JSONCPP_INCLUDE_DIR}
-    ${ZLIBNG_INCLUDE_DIRS}
-    ${URIPARSER_INCLUDE_DIRS}
-    ${TRACY_INCLUDE_DIR}
-    )
-
-# add_executable(lltreeiterators lltreeiterators.cpp)
-# 
-# target_link_libraries(lltreeiterators
-#     ${LLCOMMON_LIBRARIES})
 
 set(llcommon_SOURCE_FILES
     commoncontrol.cpp
@@ -277,52 +264,25 @@ if (DARWIN)
   list(APPEND llcommon_SOURCE_FILES llsys_objc.mm)
 endif (DARWIN)
 
-set_source_files_properties(${llcommon_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
-if (USE_BUGSPLAT)
-  set_source_files_properties(${llcommon_SOURCE_FILES}
-    PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
-endif (USE_BUGSPLAT)
-
 list(APPEND llcommon_SOURCE_FILES ${llcommon_HEADER_FILES})
 
-if(LLCOMMON_LINK_SHARED)
-  add_library (llcommon SHARED ${llcommon_SOURCE_FILES})
-  if(NOT ADDRESS_SIZE EQUAL 32)
-    if(WINDOWS)
-      ##add_definitions(/FIXED:NO)
-    else(WINDOWS) # not windows therefore gcc LINUX and DARWIN
-      add_definitions(-fPIC)
-    endif(WINDOWS)
-  endif(NOT ADDRESS_SIZE EQUAL 32)
-  if(WINDOWS)
-    # always generate llcommon.pdb, even for "Release" builds
-    set_target_properties(llcommon PROPERTIES LINK_FLAGS "/DEBUG")
-  endif(WINDOWS)
-  ll_stage_sharedlib(llcommon)
-else(LLCOMMON_LINK_SHARED)
-    add_library (llcommon ${llcommon_SOURCE_FILES})
-endif(LLCOMMON_LINK_SHARED)
+add_library (llcommon ${llcommon_SOURCE_FILES})
 
 target_link_libraries(
-    llcommon
-    ${APRUTIL_LIBRARIES}
-    ${APR_LIBRARIES}
-    ${EXPAT_LIBRARIES}
-    ${JSONCPP_LIBRARIES}
-    ${ZLIBNG_LIBRARIES}
-    ${WINDOWS_LIBRARIES}
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    ${BOOST_PROGRAM_OPTIONS_LIBRARY}
-    ${BOOST_REGEX_LIBRARY}
-    ${BOOST_SYSTEM_LIBRARY}
-    ${GOOGLE_PERFTOOLS_LIBRARIES}
-    ${URIPARSER_LIBRARIES}
-    ${TRACY_LIBRARY}
+        llcommon
+        ll::apr
+        ll::expat
+        ll::jsoncpp
+        ll::zlib-ng
+        ll::boost
+        ll::uriparser
+        ll::oslibraries
+        ll::tracy
     )
 
+target_include_directories(llcommon INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+target_include_directories(llcommon PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
+
 add_dependencies(llcommon stage_third_party_libs)
 
 if (LL_TESTS)
@@ -333,14 +293,7 @@ if (LL_TESTS)
   LL_ADD_PROJECT_UNIT_TESTS(llcommon "${llcommon_TEST_SOURCE_FILES}")
 
   #set(TEST_DEBUG on)
-  set(test_libs llcommon 
-      ${LLCOMMON_LIBRARIES} 
-      ${WINDOWS_LIBRARIES} 
-      ${GOOGLEMOCK_LIBRARIES} 
-      ${BOOST_FIBER_LIBRARY} 
-      ${BOOST_CONTEXT_LIBRARY} 
-      ${BOOST_THREAD_LIBRARY} 
-      ${BOOST_SYSTEM_LIBRARY})
+  set(test_libs llcommon)
   LL_ADD_INTEGRATION_TEST(bitpack "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(classic_callback "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(commonmisc "" "${test_libs}")
diff --git a/indra/llcommon/apply.h b/indra/llcommon/apply.h
new file mode 100644
index 0000000000000000000000000000000000000000..7c58d63bc03f4a45aac4db3fe1b20177ade5b652
--- /dev/null
+++ b/indra/llcommon/apply.h
@@ -0,0 +1,115 @@
+/**
+ * @file   apply.h
+ * @author Nat Goodspeed
+ * @date   2022-06-18
+ * @brief  C++14 version of std::apply()
+ * 
+ * $LicenseInfo:firstyear=2022&license=viewerlgpl$
+ * Copyright (c) 2022, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_APPLY_H)
+#define LL_APPLY_H
+
+#include <boost/type_traits/function_traits.hpp>
+#include <tuple>
+
+namespace LL
+{
+
+/**
+ * USAGE NOTE:
+ * https://stackoverflow.com/a/40523474/5533635
+ *
+ * If you're trying to pass apply() a variadic function, the compiler
+ * complains that it can't deduce the callable type, presumably because it
+ * doesn't know which arity to reify to pass.
+ *
+ * But it works to wrap the variadic function in a generic lambda, e.g.:
+ *
+ * @CODE
+ * LL::apply(
+ *     [](auto&&... args)
+ *     {
+ *         return variadic(std::forward<decltype(args)>(args)...);
+ *     },
+ *     args);
+ * @ENDCODE
+ *
+ * Presumably this is because there's only one instance of the generic lambda
+ * @em type, with a variadic <tt>operator()()</tt>.
+ *
+ * It's pointless to provide a wrapper @em function that implicitly supplies
+ * the generic lambda. You couldn't pass your variadic function to our wrapper
+ * function, for the same original reason!
+ *
+ * Instead we provide a wrapper @em macro. Sorry, Dr. Stroustrup.
+ */
+#define VAPPLY(FUNC, ARGS)                                          \
+    LL::apply(                                                      \
+        [](auto&&... args)                                          \
+        {                                                           \
+            return (FUNC)(std::forward<decltype(args)>(args)...);   \
+        },                                                          \
+        (ARGS))
+
+#if __cplusplus >= 201703L
+
+// C++17 implementation
+using std::apply;
+
+#else // C++14
+
+// Derived from https://stackoverflow.com/a/20441189
+// and https://en.cppreference.com/w/cpp/utility/apply
+template <typename CALLABLE, typename TUPLE, std::size_t... I>
+auto apply_impl(CALLABLE&& func, TUPLE&& args, std::index_sequence<I...>)
+{
+    // call func(unpacked args)
+    return std::forward<CALLABLE>(func)(std::move(std::get<I>(args))...);
+}
+
+template <typename CALLABLE, typename... ARGS>
+auto apply(CALLABLE&& func, const std::tuple<ARGS...>& args)
+{
+    // std::index_sequence_for is the magic sauce here, generating an argument
+    // pack of indexes for each entry in args. apply_impl() can then pass
+    // those to std::get() to unpack args into individual arguments.
+    return apply_impl(std::forward<CALLABLE>(func),
+                      args,
+                      std::index_sequence_for<ARGS...>{});
+}
+
+// per https://stackoverflow.com/a/57510428/5533635
+template <typename CALLABLE, typename T, size_t SIZE>
+auto apply(CALLABLE&& func, const std::array<T, SIZE>& args)
+{
+    return apply(std::forward<CALLABLE>(func), std::tuple_cat(args));
+}
+
+// per https://stackoverflow.com/a/28411055/5533635
+template <typename CALLABLE, typename T, std::size_t... I>
+auto apply_impl(CALLABLE&& func, const std::vector<T>& args, std::index_sequence<I...>)
+{
+    return apply_impl(std::forward<CALLABLE>(func),
+                      std::make_tuple(std::forward<T>(args[I])...),
+                      I...);
+}
+
+// this goes beyond C++17 std::apply()
+template <typename CALLABLE, typename T>
+auto apply(CALLABLE&& func, const std::vector<T>& args)
+{
+    constexpr auto arity = boost::function_traits<CALLABLE>::arity;
+    assert(args.size() == arity);
+    return apply_impl(std::forward<CALLABLE>(func),
+                      args,
+                      std::make_index_sequence<arity>());
+}
+
+#endif // C++14
+
+} // namespace LL
+
+#endif /* ! defined(LL_APPLY_H) */
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index 8ddd13279398cc5b51d3cb77b97f41e7477dc91d..3ff8d16bbb35d8e858e2ef10edf0e9b9edc35431 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -68,10 +68,6 @@ void setup_signals();
 void default_unix_signal_handler(int signum, siginfo_t *info, void *);
 
 #if LL_LINUX
-#include "google_breakpad/minidump_descriptor.h"
-static bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, 
-                                   void* context, 
-                                   bool succeeded);
 #else
 // Called by breakpad exception handler after the minidump has been generated.
 bool unix_post_minidump_callback(const char *dump_dir,
@@ -856,47 +852,8 @@ void default_unix_signal_handler(int signum, siginfo_t *info, void *)
 }
 
 #if LL_LINUX
-bool unix_minidump_callback(const google_breakpad::MinidumpDescriptor& minidump_desc, void* context, bool succeeded)
-{
-	// Copy minidump file path into fixed buffer in the app instance to avoid
-	// heap allocations in a crash handler.
-	
-	// path format: <dump_dir>/<minidump_id>.dmp
-	
-	//HACK:  *path points to the buffer in getMiniDumpFilename which has already allocated space
-	//to avoid doing allocation during crash.
-	char * path = LLApp::instance()->getMiniDumpFilename();
-	int dir_path_len = strlen(path);
-	
-	// The path must not be truncated.
-	S32 remaining =  LLApp::MAX_MINDUMP_PATH_LENGTH - dir_path_len;
-
-	llassert( (remaining - strlen(minidump_desc.path())) > 5);
-	
-	path += dir_path_len;
-
-	if (dir_path_len > 0 && path[-1] != '/')
-	{
-		*path++ = '/';
-		--remaining;
-	}
-
-	strncpy(path, minidump_desc.path(), remaining);
-	
-	LL_INFOS("CRASHREPORT") << "generated minidump: " << LLApp::instance()->getMiniDumpFilename() << LL_ENDL;
-	LLApp::runErrorHandler();
-	
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	clear_signals();
-	return false;
-#else
-	return true;
 #endif
 
-}
-#endif
-
-
 bool unix_post_minidump_callback(const char *dump_dir,
 					  const char *minidump_id,
 					  void *context, bool succeeded)
diff --git a/indra/llcommon/llprocess.cpp b/indra/llcommon/llprocess.cpp
index 23936f0526e5cc5c0050f8839e7b12637653a4a6..97a38ea99253b9ed4cda572523dce6516f8b0e7f 100644
--- a/indra/llcommon/llprocess.cpp
+++ b/indra/llcommon/llprocess.cpp
@@ -272,6 +272,14 @@ class ReadPipeImpl: public LLProcess::ReadPipe
 					boost::bind(&ReadPipeImpl::tick, this, _1));
 	}
 
+    ~ReadPipeImpl()
+    {
+        if (mConnection.connected())
+        {
+            mConnection.disconnect();
+        }
+    }
+
 	// Much of the implementation is simply connecting the abstract virtual
 	// methods with implementation data concealed from the base class.
 	virtual std::istream& get_istream() { return mStream; }
diff --git a/indra/llcommon/llsd.h b/indra/llcommon/llsd.h
index 24cb9bbce170d0f358f9e7ed3b2d5ca8eec1b38f..3daaef44fc8412865c7d5fbcf93ff1a13f4db00e 100644
--- a/indra/llcommon/llsd.h
+++ b/indra/llcommon/llsd.h
@@ -421,42 +421,42 @@ class LL_COMMON_API LLSD
 	static std::string		typeString(Type type);		// Return human-readable type as a string
 };
 
-struct llsd_select_bool : public std::unary_function<LLSD, LLSD::Boolean>
+struct llsd_select_bool
 {
 	LLSD::Boolean operator()(const LLSD& sd) const
 	{
 		return sd.asBoolean();
 	}
 };
-struct llsd_select_integer : public std::unary_function<LLSD, LLSD::Integer>
+struct llsd_select_integer
 {
 	LLSD::Integer operator()(const LLSD& sd) const
 	{
 		return sd.asInteger();
 	}
 };
-struct llsd_select_real : public std::unary_function<LLSD, LLSD::Real>
+struct llsd_select_real
 {
 	LLSD::Real operator()(const LLSD& sd) const
 	{
 		return sd.asReal();
 	}
 };
-struct llsd_select_float : public std::unary_function<LLSD, F32>
+struct llsd_select_float
 {
 	F32 operator()(const LLSD& sd) const
 	{
 		return (F32)sd.asReal();
 	}
 };
-struct llsd_select_uuid : public std::unary_function<LLSD, LLSD::UUID>
+struct llsd_select_uuid
 {
 	LLSD::UUID operator()(const LLSD& sd) const
 	{
 		return sd.asUUID();
 	}
 };
-struct llsd_select_string : public std::unary_function<LLSD, LLSD::String>
+struct llsd_select_string
 {
 	LLSD::String operator()(const LLSD& sd) const
 	{
diff --git a/indra/llcommon/llsdjson.h b/indra/llcommon/llsdjson.h
index 2be711240487c9d1c878f07f887161cf7c85b04a..e56cf03b45dbd57973e18adf0aa87410a34978a4 100644
--- a/indra/llcommon/llsdjson.h
+++ b/indra/llcommon/llsdjson.h
@@ -34,7 +34,7 @@
 #include "stdtypes.h"
 
 #include "llsd.h"
-#include "value.h"
+#include "json/value.h"
 
 /// Convert a parsed JSON structure into LLSD maintaining member names and 
 /// array indexes.
diff --git a/indra/llcommon/llstl.h b/indra/llcommon/llstl.h
index a90c2c7e087a0593f1194662eff34b15c841aaef..25131291f9146a9806ecc6e0aaf64862188bf1d5 100644
--- a/indra/llcommon/llstl.h
+++ b/indra/llcommon/llstl.h
@@ -142,7 +142,7 @@ struct DeletePairedPointerArray
 //                     llselect2nd<map_type::value_type>()));
 
 template<typename T>
-struct DeletePointerFunctor : public std::unary_function<T*, bool>
+struct DeletePointerFunctor
 {
 	bool operator()(T* ptr) const
 	{
@@ -153,7 +153,7 @@ struct DeletePointerFunctor : public std::unary_function<T*, bool>
 
 // See notes about DeleteArray for why you should consider avoiding this.
 template<typename T>
-struct DeleteArrayFunctor : public std::unary_function<T*, bool>
+struct DeleteArrayFunctor
 {
 	bool operator()(T* ptr) const
 	{
@@ -395,16 +395,17 @@ OutputIter ll_transform_n(
 // select... with the stl. Look up usage on the sgi website.
 
 template <class _Pair>
-struct _LLSelect1st : public std::unary_function<_Pair, typename _Pair::first_type> {
-  const typename _Pair::first_type& operator()(const _Pair& __x) const {
+struct _LLSelect1st
+{
+  const auto& operator()(const _Pair& __x) const {
     return __x.first;
   }
 };
 
 template <class _Pair>
-struct _LLSelect2nd : public std::unary_function<_Pair, typename _Pair::second_type>
+struct _LLSelect2nd
 {
-  const typename _Pair::second_type& operator()(const _Pair& __x) const {
+  const auto& operator()(const _Pair& __x) const {
     return __x.second;
   }
 };
@@ -416,9 +417,7 @@ template <class _Pair> struct llselect2nd : public _LLSelect2nd<_Pair> {};
 // compose... with the stl. Look up usage on the sgi website.
 
 template <class _Operation1, class _Operation2>
-class ll_unary_compose :
-	public std::unary_function<typename _Operation2::argument_type,
-							   typename _Operation1::result_type>
+class ll_unary_compose
 {
 protected:
   _Operation1 __op1;
@@ -426,8 +425,9 @@ class ll_unary_compose :
 public:
   ll_unary_compose(const _Operation1& __x, const _Operation2& __y)
     : __op1(__x), __op2(__y) {}
-  typename _Operation1::result_type
-  operator()(const typename _Operation2::argument_type& __x) const {
+  template <typename _Op2Arg>
+  auto
+  operator()(const _Op2Arg& __x) const {
     return __op1(__op2(__x));
   }
 };
@@ -441,8 +441,7 @@ llcompose1(const _Operation1& __op1, const _Operation2& __op2)
 
 template <class _Operation1, class _Operation2, class _Operation3>
 class ll_binary_compose
-  : public std::unary_function<typename _Operation2::argument_type,
-							   typename _Operation1::result_type> {
+{
 protected:
   _Operation1 _M_op1;
   _Operation2 _M_op2;
@@ -451,8 +450,9 @@ class ll_binary_compose
   ll_binary_compose(const _Operation1& __x, const _Operation2& __y,
 					const _Operation3& __z)
     : _M_op1(__x), _M_op2(__y), _M_op3(__z) { }
-  typename _Operation1::result_type
-  operator()(const typename _Operation2::argument_type& __x) const {
+  template<typename OP2ARG>
+  auto
+  operator()(const OP2ARG& __x) const {
     return _M_op1(_M_op2(__x), _M_op3(__x));
   }
 };
@@ -468,54 +468,51 @@ llcompose2(const _Operation1& __op1, const _Operation2& __op2,
 
 // helpers to deal with the fact that MSDev does not package
 // bind... with the stl. Again, this is from sgi.
-template <class _Operation>
-class llbinder1st :
-	public std::unary_function<typename _Operation::second_argument_type,
-							   typename _Operation::result_type> {
+template <class _Operation, typename _Arg1>
+class llbinder1st
+{
 protected:
   _Operation op;
-  typename _Operation::first_argument_type value;
+  _Arg1 value;
 public:
-  llbinder1st(const _Operation& __x,
-			  const typename _Operation::first_argument_type& __y)
+  llbinder1st(const _Operation& __x, const _Arg1& __y)
       : op(__x), value(__y) {}
-	typename _Operation::result_type
-	operator()(const typename _Operation::second_argument_type& __x) const {
-		return op(value, __x);
-	}
+    template <typename _Arg2>
+    auto
+    operator()(const _Arg2& __x) const {
+        return op(value, __x);
+    }
 };
 
 template <class _Operation, class _Tp>
-inline llbinder1st<_Operation>
+inline auto
 llbind1st(const _Operation& __oper, const _Tp& __x)
 {
-  typedef typename _Operation::first_argument_type _Arg1_type;
-  return llbinder1st<_Operation>(__oper, _Arg1_type(__x));
+  return llbinder1st<_Operation, _Tp>(__oper, __x);
 }
 
-template <class _Operation>
+template <class _Operation, typename _Arg2>
 class llbinder2nd
-	: public std::unary_function<typename _Operation::first_argument_type,
-								 typename _Operation::result_type> {
+{
 protected:
 	_Operation op;
-	typename _Operation::second_argument_type value;
+	_Arg2 value;
 public:
 	llbinder2nd(const _Operation& __x,
-				const typename _Operation::second_argument_type& __y)
+				const _Arg2& __y)
 		: op(__x), value(__y) {}
-	typename _Operation::result_type
-	operator()(const typename _Operation::first_argument_type& __x) const {
+	template <typename _Arg1>
+	auto
+	operator()(const _Arg1& __x) const {
 		return op(__x, value);
 	}
 };
 
 template <class _Operation, class _Tp>
-inline llbinder2nd<_Operation>
+inline auto
 llbind2nd(const _Operation& __oper, const _Tp& __x)
 {
-  typedef typename _Operation::second_argument_type _Arg2_type;
-  return llbinder2nd<_Operation>(__oper, _Arg2_type(__x));
+  return llbinder2nd<_Operation, _Tp>(__oper, __x);
 }
 
 /**
@@ -548,8 +545,7 @@ bool before(const std::type_info* lhs, const std::type_info* rhs)
 namespace std
 {
 	template <>
-	struct less<const std::type_info*>:
-		public std::binary_function<const std::type_info*, const std::type_info*, bool>
+	struct less<const std::type_info*>
 	{
 		bool operator()(const std::type_info* lhs, const std::type_info* rhs) const
 		{
@@ -558,8 +554,7 @@ namespace std
 	};
 
 	template <>
-	struct less<std::type_info*>:
-		public std::binary_function<std::type_info*, std::type_info*, bool>
+	struct less<std::type_info*>
 	{
 		bool operator()(std::type_info* lhs, std::type_info* rhs) const
 		{
diff --git a/indra/llcommon/stringize.h b/indra/llcommon/stringize.h
index 12df6939108e47b3f0e05c8ccfa40ffae7f8f5c4..c0b13135f9e5d1668407b49b193b4d250aab3419 100644
--- a/indra/llcommon/stringize.h
+++ b/indra/llcommon/stringize.h
@@ -30,7 +30,7 @@
 #define LL_STRINGIZE_H
 
 #include <sstream>
-#include <llstring.h>
+#include "llstring.h"
 #include <boost/call_traits.hpp>
 
 /**
diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp
index 9754353ab0ab7d9acfa7f9387e4b80225d56836d..7ee36a9ea6ace696a16c22c078cb6574c1174b60 100644
--- a/indra/llcommon/tests/llleap_test.cpp
+++ b/indra/llcommon/tests/llleap_test.cpp
@@ -15,10 +15,10 @@
 #include "llleap.h"
 // STL headers
 // std headers
+#include <functional>
 // external library headers
 #include <boost/assign/list_of.hpp>
 #include <boost/phoenix/core/argument.hpp>
-#include <boost/foreach.hpp>
 // other Linden headers
 #include "../test/lltut.h"
 #include "../test/namedtempfile.h"
@@ -29,7 +29,6 @@
 #include "llstring.h"
 #include "stringize.h"
 #include "StringVec.h"
-#include <functional>
 
 using boost::assign::list_of;
 
@@ -110,11 +109,6 @@ namespace tut
                    "import os\n"
                    "import sys\n"
                    "\n"
-                   // Don't forget that this Python script is written to some
-                   // temp directory somewhere! Its __file__ is useless in
-                   // finding indra/lib/python. Use our __FILE__, with
-                   // raw-string syntax to deal with Windows pathnames.
-                   "mydir = os.path.dirname(r'" << __FILE__ << "')\n"
                    "from llbase import llsd\n"
                    "\n"
                    "class ProtocolError(Exception):\n"
@@ -241,9 +235,9 @@ namespace tut
                              "import sys\n"
                              "sys.stderr.write('''Hello from Python!\n"
                              "note partial line''')\n");
+        StringVec vcommand{ PYTHON, script.getName() };
         CaptureLog log(LLError::LEVEL_INFO);
-        waitfor(LLLeap::create(get_test_name(),
-                               sv(list_of(PYTHON)(script.getName()))));
+        waitfor(LLLeap::create(get_test_name(), vcommand));
         log.messageWith("Hello from Python!");
         log.messageWith("note partial line");
     }
@@ -531,7 +525,7 @@ namespace tut
         result.ensure();
     }
 
-    struct TestLargeMessage: public std::binary_function<size_t, size_t, bool>
+    struct TestLargeMessage
     {
         TestLargeMessage(const std::string& PYTHON_, const std::string& reader_module_,
                          const std::string& test_name_):
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index c591680250b220f196e425c7977f15c499f91a0b..87796abd3c631615bc7cd72d612b841add0cfc87 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -10,19 +10,10 @@ include(NGHTTP2)
 include(ZLIBNG)
 include(LLCoreHttp)
 include(LLAddBuildTest)
-include(LLMessage)
 include(LLCommon)
 include(Tut)
 include(bugsplat)
 
-include_directories (${CMAKE_CURRENT_SOURCE_DIR})
-
-include_directories(
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLCOREHTTP_INCLUDE_DIRS}
-    )
-
 set(llcorehttp_SOURCE_FILES
     bufferarray.cpp
     bufferstream.cpp
@@ -80,8 +71,6 @@ set(llcorehttp_HEADER_FILES
     _thread.h
     )
 
-set_source_files_properties(${llcorehttp_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
 if (DARWIN OR LINUX)
   # Boost headers define unused members in condition_variable so...
   set_source_files_properties(${llcorehttp_SOURCE_FILES}
@@ -92,14 +81,17 @@ list(APPEND llcorehttp_SOURCE_FILES ${llcorehttp_HEADER_FILES})
 
 add_library (llcorehttp ${llcorehttp_SOURCE_FILES})
 target_link_libraries(
-  llcorehttp
-  ${CURL_LIBRARIES}
-  ${OPENSSL_LIBRARIES}
-  ${CRYPTO_LIBRARIES}
-  ${NGHTTP2_LIBRARIES}
-  ${BOOST_THREAD_LIBRARY}
-  ${BOOST_SYSTEM_LIBRARY}
+        llcorehttp
+        llcommon
+        ll::libcurl
+        ll::openssl
+        ll::nghttp2
   )
+target_include_directories( llcorehttp INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+# llmessage depends on llcorehttp, yet llcorehttp also depends on llmessage (at least for includes).
+# Cannot/Should not use target_link_libraries here to add llmessage to the dependencies, as that would
+# lead to circular dependencies (or in case of cmake, the first project declaring it's dependencies wins)
+target_include_directories( llcorehttp PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/../llmessage)
 
 # tests
 set(LLCOREHTTP_TESTS ON CACHE BOOL
@@ -119,26 +111,15 @@ if (LL_TESTS AND LLCOREHTTP_TESTS)
       tests/test_bufferstream.hpp
       )
 
-  set_source_files_properties(${llcorehttp_TEST_HEADER_FILES}
-                              PROPERTIES HEADER_FILE_ONLY TRUE)
-
   list(APPEND llcorehttp_TEST_SOURCE_FILES ${llcorehttp_TEST_HEADER_FILES})
 
   # LL_ADD_PROJECT_UNIT_TESTS(llcorehttp "${llcorehttp_TEST_SOURCE_FILES}")
 
   #    set(TEST_DEBUG on)
   set(test_libs
-      ${LLCOREHTTP_LIBRARIES}
-      ${WINDOWS_LIBRARIES}
-      ${LLMESSAGE_LIBRARIES}
-      ${LLCOMMON_LIBRARIES}
-      ${GOOGLEMOCK_LIBRARIES}
-      ${CURL_LIBRARIES}
-      ${OPENSSL_LIBRARIES}
-      ${CRYPTO_LIBRARIES}
-      ${NGHTTP2_LIBRARIES}
-      ${BOOST_THREAD_LIBRARY}
-      ${BOOST_SYSTEM_LIBRARY}
+          llcorehttp
+          llmessage
+          llcommon
       )
 
   # If http_proxy is in the current environment (e.g. to fetch s3-proxy
@@ -155,7 +136,7 @@ if (LL_TESTS AND LLCOREHTTP_TESTS)
 if (DARWIN)
   # Path inside the app bundle where we'll need to copy libraries
   set(LL_TEST_DESTINATION_DIR
-    ${CMAKE_BINARY_DIR}/sharedlibs/Resources
+    ${CMAKE_BINARY_DIR}/sharedlibs/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,,../>Resources
   )
 
   # Create the Contents/Resources directory
@@ -200,18 +181,9 @@ endif (DARWIN)
       )
 
   set(example_libs
-      ${LEGACY_STDIO_LIBS}
-      ${LLCOREHTTP_LIBRARIES}
-      ${WINDOWS_LIBRARIES}
-      ${LLMESSAGE_LIBRARIES}
-      ${LLCOMMON_LIBRARIES}
-      ${GOOGLEMOCK_LIBRARIES}
-      ${CURL_LIBRARIES}
-      ${OPENSSL_LIBRARIES}
-      ${CRYPTO_LIBRARIES}
-      ${NGHTTP2_LIBRARIES}
-      ${BOOST_THREAD_LIBRARY}
-      ${BOOST_SYSTEM_LIBRARY}
+          llcorehttp
+          llmessage
+          llcommon
       )
 
   add_executable(http_texture_load
diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt
index d70a1e0fb006cc0b3bf3efd69353926b1013c615..6ac73c0d322879fbbdc508340b6bfe3a1dba755b 100644
--- a/indra/llcrashlogger/CMakeLists.txt
+++ b/indra/llcrashlogger/CMakeLists.txt
@@ -5,23 +5,6 @@ project(llcrashlogger)
 include(00-Common)
 include(LLCoreHttp)
 include(LLCommon)
-include(LLMath)
-include(LLMessage)
-include(LLFileSystem)
-include(LLXML)
-
-include_directories(
-    ${LLCOREHTTP_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    )
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLXML_SYSTEM_INCLUDE_DIRS}
-    )
 
 set(llcrashlogger_SOURCE_FILES
     llcrashlogger.cpp
@@ -30,14 +13,11 @@ set(llcrashlogger_SOURCE_FILES
 
 set(llcrashlogger_HEADER_FILES
     CMakeLists.txt
-
     llcrashlogger.h
     llcrashlock.h
     )
 
-set_source_files_properties(${llcrashlogger_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llcrashlogger_SOURCE_FILES ${llcrashlogger_HEADER_FILES})
 
 add_library(llcrashlogger ${llcrashlogger_SOURCE_FILES})
+target_link_libraries( llcrashlogger llcommon llmessage llcorehttp llxml llfilesystem )
diff --git a/indra/llfilesystem/CMakeLists.txt b/indra/llfilesystem/CMakeLists.txt
index 09c4c33ebf3d3bb16c0e675759054bc49a1e9de8..9f24f75eabc2116e50e2674983543ceb1e44aeb1 100644
--- a/indra/llfilesystem/CMakeLists.txt
+++ b/indra/llfilesystem/CMakeLists.txt
@@ -4,12 +4,6 @@ project(llfilesystem)
 
 include(00-Common)
 include(LLCommon)
-include(UnixInstall)
-
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    )
 
 set(llfilesystem_SOURCE_FILES
     lldir.cpp
@@ -53,29 +47,14 @@ if (WINDOWS)
   LIST(APPEND llfilesystem_HEADER_FILES lldir_win32.h)
 endif (WINDOWS)
 
-set_source_files_properties(${llfilesystem_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llfilesystem_SOURCE_FILES ${llfilesystem_HEADER_FILES})
 
 add_library (llfilesystem ${llfilesystem_SOURCE_FILES})
 
-set(cache_BOOST_LIBRARIES
-    ${BOOST_FILESYSTEM_LIBRARY}
-    ${BOOST_SYSTEM_LIBRARY}
-    )
-
 target_link_libraries(llfilesystem
-    ${LLCOMMON_LIBRARIES}
-    ${cache_BOOST_LIBRARIES}
+        llcommon
     )
-
-if (DARWIN)
-  include(CMakeFindFrameworks)
-  find_library(COCOA_LIBRARY Cocoa)
-  target_link_libraries(llfilesystem ${COCOA_LIBRARY})
-endif (DARWIN)
-
+target_include_directories( llfilesystem  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
 
 # Add tests
 if (LL_TESTS)
@@ -85,14 +64,10 @@ if (LL_TESTS)
     lldiriterator.cpp
     )
 
-    set_source_files_properties(lldiriterator.cpp
-    PROPERTIES
-    LL_TEST_ADDITIONAL_LIBRARIES "${cache_BOOST_LIBRARIES}"
-    )
     LL_ADD_PROJECT_UNIT_TESTS(llfilesystem "${llfilesystem_TEST_SOURCE_FILES}")
 
     # INTEGRATION TESTS
-    set(test_libs llmath llcommon llfilesystem ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
+    set(test_libs llmath llcommon llfilesystem )
 
     # TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests.
     LL_ADD_INTEGRATION_TEST(lldir "" "${test_libs}")
diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp
index dd3852fb93f3c5b7eaad17b2c26fac46afb28dc9..54e49ebcb8525a01f2b8022738eb344b9c968d17 100644
--- a/indra/llfilesystem/lldiskcache.cpp
+++ b/indra/llfilesystem/lldiskcache.cpp
@@ -35,7 +35,6 @@
 #include "llassettype.h"
 #include "lldir.h"
 #include <boost/filesystem.hpp>
-#include <boost/range/iterator_range.hpp>
 #include <chrono>
 
 #include "lldiskcache.h"
@@ -100,19 +99,20 @@ void LLDiskCache::purge()
 #endif
     if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
     {
-        for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
+        boost::filesystem::directory_iterator iter(cache_path, ec);
+        while (iter != boost::filesystem::directory_iterator() && !ec.failed())
         {
-            if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
+            if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
             {
-                if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
+                if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos)
                 {
-                    uintmax_t file_size = boost::filesystem::file_size(entry, ec);
+                    uintmax_t file_size = boost::filesystem::file_size(*iter, ec);
                     if (ec.failed())
                     {
                         continue;
                     }
-                    const std::string file_path = entry.path().string();
-                    const std::time_t file_time = boost::filesystem::last_write_time(entry, ec);
+                    const std::string file_path = (*iter).path().string();
+                    const std::time_t file_time = boost::filesystem::last_write_time(*iter, ec);
                     if (ec.failed())
                     {
                         continue;
@@ -121,6 +121,7 @@ void LLDiskCache::purge()
                     file_info.push_back(file_info_t(file_time, { file_size, file_path }));
                 }
             }
+            iter.increment(ec);
         }
     }
 
@@ -349,19 +350,21 @@ void LLDiskCache::clearCache()
 #endif
     if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
     {
-        for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
+        boost::filesystem::directory_iterator iter(cache_path, ec);
+        while (iter != boost::filesystem::directory_iterator() && !ec.failed())
         {
-            if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
+            if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
             {
-                if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
+                if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos)
                 {
-                    boost::filesystem::remove(entry, ec);
+                    boost::filesystem::remove(*iter, ec);
                     if (ec.failed())
                     {
-                        LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
+                        LL_WARNS() << "Failed to delete cache file " << *iter << ": " << ec.message() << LL_ENDL;
                     }
                 }
             }
+            iter.increment(ec);
         }
     }
 }
@@ -380,20 +383,22 @@ void LLDiskCache::removeOldVFSFiles()
 #endif
     if (boost::filesystem::is_directory(cache_path, ec) && !ec.failed())
     {
-        for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(cache_path, ec), {}))
+        boost::filesystem::directory_iterator iter(cache_path, ec);
+        while (iter != boost::filesystem::directory_iterator() && !ec.failed())
         {
-            if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
+            if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
             {
-                if ((entry.path().string().find(CACHE_FORMAT) != std::string::npos) ||
-                    (entry.path().string().find(DB_FORMAT) != std::string::npos))
+                if (((*iter).path().string().find(CACHE_FORMAT) != std::string::npos) ||
+                    ((*iter).path().string().find(DB_FORMAT) != std::string::npos))
                 {
-                    boost::filesystem::remove(entry, ec);
+                    boost::filesystem::remove(*iter, ec);
                     if (ec.failed())
                     {
-                        LL_WARNS() << "Failed to delete cache file " << entry << ": " << ec.message() << LL_ENDL;
+                        LL_WARNS() << "Failed to delete cache file " << *iter << ": " << ec.message() << LL_ENDL;
                     }
                 }
             }
+            iter.increment(ec);
         }
     }
 }
@@ -419,19 +424,21 @@ uintmax_t LLDiskCache::dirFileSize(const std::string dir)
 #endif
     if (boost::filesystem::is_directory(dir_path, ec) && !ec.failed())
     {
-        for (auto& entry : boost::make_iterator_range(boost::filesystem::directory_iterator(dir_path, ec), {}))
+        boost::filesystem::directory_iterator iter(dir_path, ec);
+        while (iter != boost::filesystem::directory_iterator() && !ec.failed())
         {
-            if (boost::filesystem::is_regular_file(entry, ec) && !ec.failed())
+            if (boost::filesystem::is_regular_file(*iter, ec) && !ec.failed())
             {
-                if (entry.path().string().find(mCacheFilenamePrefix) != std::string::npos)
+                if ((*iter).path().string().find(mCacheFilenamePrefix) != std::string::npos)
                 {
-                    uintmax_t file_size = boost::filesystem::file_size(entry, ec);
+                    uintmax_t file_size = boost::filesystem::file_size(*iter, ec);
                     if (!ec.failed())
                     {
                         total_file_size += file_size;
                     }
                 }
             }
+            iter.increment(ec);
         }
     }
 
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index 436b8dd1a251a8d4fbf8021a2ed50efe8a284d25..cc75c463bc67d68baac7759ee07b9c2f291e3974 100644
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -5,24 +5,13 @@ project(llimage)
 include(00-Common)
 include(LLCommon)
 include(LLImage)
-include(LLMath)
-include(LLFileSystem)
+include(JPEG)
 include(LLKDU)
-include(LLImageJ2COJ)
 include(ZLIBNG)
 include(LLAddBuildTest)
 include(bugsplat)
 include(Tut)
 
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${PNG_INCLUDE_DIRS}
-    ${ZLIBNG_INCLUDE_DIRS}
-    )
-
 set(llimage_SOURCE_FILES
     llimagebmp.cpp
     llimage.cpp
@@ -54,27 +43,24 @@ set(llimage_HEADER_FILES
     llpngwrapper.h
     )
 
-set_source_files_properties(${llimage_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llimage_SOURCE_FILES ${llimage_HEADER_FILES})
 
 add_library (llimage ${llimage_SOURCE_FILES})
+target_include_directories( llimage  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 if (USE_KDU)
-    target_link_libraries(llimage ${LLKDU_LIBRARIES})
+    target_link_libraries(llimage llkdu)
 else (USE_KDU)
-    target_link_libraries(llimage ${LLIMAGEJ2COJ_LIBRARIES})
+    target_link_libraries(llimage llimagej2coj)
 endif (USE_KDU)
 
 target_link_libraries(llimage
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLCOMMON_LIBRARIES}
-    ${JPEG_LIBRARIES}
-    ${PNG_LIBRARIES}
-    ${ZLIBNG_LIBRARIES}
+        llfilesystem
+        llmath
+        llcommon
+        ll::libpng
+        ll::libjpeg
     )
 
 # Add tests
diff --git a/indra/llimagej2coj/CMakeLists.txt b/indra/llimagej2coj/CMakeLists.txt
index c9423d50dd618e91a593edc0222a99c63bca44cb..93e85668dd61c0109ff62670c17ae929b27fc582 100644
--- a/indra/llimagej2coj/CMakeLists.txt
+++ b/indra/llimagej2coj/CMakeLists.txt
@@ -7,12 +7,6 @@ include(LLCommon)
 include(LLImage)
 include(OpenJPEG)
 
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${OPENJPEG_INCLUDE_DIR}
-    )
-
 set(llimagej2coj_SOURCE_FILES
     llimagej2coj.cpp
     )
@@ -23,15 +17,13 @@ set(llimagej2coj_HEADER_FILES
     llimagej2coj.h
     )
 
-set_source_files_properties(${llimagej2coj_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llimagej2coj_SOURCE_FILES ${llimagej2coj_HEADER_FILES})
 
 add_library (llimagej2coj ${llimagej2coj_SOURCE_FILES})
 
-target_link_libraries(
-    llimagej2coj
-    ${OPENJPEG_LIBRARIES}
+target_link_libraries( llimagej2coj
+        llcommon
+        llimage
+        ll::openjpeg
     )
 
diff --git a/indra/llinventory/CMakeLists.txt b/indra/llinventory/CMakeLists.txt
index 04975940aa4898047460c7d128300b3f577a5a94..93a586759f70318a80393f6b997475c1466525d2 100644
--- a/indra/llinventory/CMakeLists.txt
+++ b/indra/llinventory/CMakeLists.txt
@@ -5,17 +5,6 @@ project(llinventory)
 include(00-Common)
 include(LLCommon)
 include(LLCoreHttp)
-include(LLMath)
-include(LLMessage)
-include(LLFileSystem)
-include(LLXML)
-
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    )
 
 set(llinventory_SOURCE_FILES
     llcategory.cpp
@@ -63,14 +52,12 @@ set(llinventory_HEADER_FILES
     lluserrelations.h
     )
 
-set_source_files_properties(${llinventory_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llinventory_SOURCE_FILES ${llinventory_HEADER_FILES})
 
 add_library (llinventory ${llinventory_SOURCE_FILES})
 
-
+target_link_libraries( llinventory llcommon llmath llmessage llxml )
+target_include_directories( llinventory  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
 
 #add unit tests
 if (LL_TESTS)
@@ -81,7 +68,7 @@ if (LL_TESTS)
     LL_ADD_PROJECT_UNIT_TESTS(llinventory "${llinventory_TEST_SOURCE_FILES}")
 
     #set(TEST_DEBUG on)
-    set(test_libs llinventory ${LLMESSAGE_LIBRARIES} ${LLFILESYSTEM_LIBRARIES} ${LLCOREHTTP_LIBRARIES} ${LLMATH_LIBRARIES} ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
+    set(test_libs llinventory llmath llcorehttp llfilesystem )
     LL_ADD_INTEGRATION_TEST(inventorymisc "" "${test_libs}")
     LL_ADD_INTEGRATION_TEST(llparcel "" "${test_libs}")
 endif (LL_TESTS)
diff --git a/indra/llinventory/llparcel.cpp b/indra/llinventory/llparcel.cpp
index 134e7830531277e622af3c815f80631b6ccfcf87..bba2e2505d5be30a6e54485dbae7f9eb06402bf5 100644
--- a/indra/llinventory/llparcel.cpp
+++ b/indra/llinventory/llparcel.cpp
@@ -1271,5 +1271,5 @@ U32 LLParcel::countExperienceKeyType( U32 type )
 	return std::count_if(
 		boost::begin(mExperienceKeys | boost::adaptors::map_values), 
 		boost::end(mExperienceKeys | boost::adaptors::map_values), 
-		std::bind2nd(std::equal_to<U32>(), type));
+		[type](U32 key){ return (key == type); });
 }
diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt
index cb0e204e91a6f2eb26c839727cd6b8d20e08380d..7cd9f5eb2470f3e9001923a405b43eba15704c40 100644
--- a/indra/llkdu/CMakeLists.txt
+++ b/indra/llkdu/CMakeLists.txt
@@ -13,15 +13,6 @@ include(00-Common)
 include(LLCommon)
 include(LLImage)
 include(LLKDU)
-include(LLMath)
-
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${KDU_INCLUDE_DIR}
-    ${LLKDU_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    )
 
 set(llkdu_SOURCE_FILES
     llimagej2ckdu.cpp
@@ -30,14 +21,10 @@ set(llkdu_SOURCE_FILES
 
 set(llkdu_HEADER_FILES
     CMakeLists.txt
-    
     llimagej2ckdu.h
     llkdumem.h
     )
 
-set_source_files_properties(${llkdu_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES})
 
 # Our KDU package is built with KDU_X86_INTRINSICS in its .vcxproj file.
@@ -51,11 +38,14 @@ set_source_files_properties(${llkdu_SOURCE_FILES}
 if (USE_KDU)
   add_library (llkdu ${llkdu_SOURCE_FILES})
 
-  target_link_libraries(llkdu
-    ${KDU_LIBRARY})
-  
+  target_link_libraries(llkdu ll::kdu llimage llcommon)
+  target_include_directories( llkdu  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
+
   # Add tests
-  if (LL_TESTS)
+  # ND: llkdu tests are very strange as they include stubs for KDU classes/methods
+  # if not having access to the right KDU version this test will fail to compile, incidentally I do not
+  # have access to a matching version of KDU and thus cannot get this tests to compile
+  if (LL_TESTS_KDU)
     include(LLAddBuildTest)
     include(Tut)
     SET(llkdu_TEST_SOURCE_FILES
@@ -66,11 +56,12 @@ if (USE_KDU)
       llkdumem.h
       lltut.h
       )
-    SET(llkdu_test_additional_INCLUDE_DIRS
-      ${KDU_INCLUDE_DIR}
-      ${LLKDU_INCLUDE_DIRS}
-    )
+
+    get_property( llimage_include_dir TARGET llimage PROPERTY INTERFACE_INCLUDE_DIRECTORIES )
+    set_property( SOURCE ${llkdu_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_LIBRARIES  ll::kdu llcommon)
+    set_property( SOURCE ${llkdu_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_INCLUDE_DIRS ${llimage_include_dir})
+
     LL_ADD_PROJECT_UNIT_TESTS(llkdu "${llkdu_TEST_SOURCE_FILES}")
-  endif (LL_TESTS)
+  endif (LL_TESTS_KDU)
 
 endif (USE_KDU)
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 4617309606dfc3c17d27015dd83b1f9875cd474b..eb29df245a6d4b86eb2daf1538d808b3652f9dd1 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -4,16 +4,9 @@ project(llmath)
 
 include(00-Common)
 include(LLCommon)
-include(LLMeshOptimizer)
 include(bugsplat)
 include(Boost)
 
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLMESHOPTIMIZER_INCLUDE_DIRS}
-    )
-
 set(llmath_SOURCE_FILES
     llbbox.cpp
     llbboxlocal.cpp
@@ -102,17 +95,12 @@ set(llmath_HEADER_FILES
     xform.h
     )
 
-set_source_files_properties(${llmath_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES})
 
 add_library (llmath ${llmath_SOURCE_FILES})
 
-target_link_libraries(llmath
-    ${LLCOMMON_LIBRARIES}
-    ${LLMESHOPTIMIZER_LIBRARIES}
-    )
+target_link_libraries(llmath llcommon llmeshoptimizer)
+target_include_directories( llmath  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
 
 # Add tests
 if (LL_TESTS)
@@ -127,15 +115,11 @@ if (LL_TESTS)
     v4color.cpp
     v4coloru.cpp
     )
-  set_source_files_properties(
-    ${llmath_TEST_SOURCE_FILES}
-    PROPERTIES
-    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_THREAD_LIBRARY}"
-  )
+
   LL_ADD_PROJECT_UNIT_TESTS(llmath "${llmath_TEST_SOURCE_FILES}")
 
   # INTEGRATION TESTS
-  set(test_libs llmath llcommon ${LLCOMMON_LIBRARIES} ${WINDOWS_LIBRARIES})
+  set(test_libs llmath llcommon)
   # TODO: Some of these need refactoring to be proper Unit tests rather than Integration tests.
   LL_ADD_INTEGRATION_TEST(alignment "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llbbox llbbox.cpp "${test_libs}")
diff --git a/indra/llmath/llcalcparser.h b/indra/llmath/llcalcparser.h
index e2388d6702d92b1087d276a13429986f73823db9..dff5bf3af329139cbd6e363897c4296dd305aa18 100644
--- a/indra/llmath/llcalcparser.h
+++ b/indra/llmath/llcalcparser.h
@@ -81,28 +81,28 @@ struct LLCalcParser : grammar<LLCalcParser>
 			;
 
 			unary_func =
-				((str_p("SIN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_sin)(self,arg1)]) |
-				 (str_p("COS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_cos)(self,arg1)]) |
-				 (str_p("TAN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_tan)(self,arg1)]) |
-				 (str_p("ASIN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_asin)(self,arg1)]) |
-				 (str_p("ACOS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_acos)(self,arg1)]) |
-				 (str_p("ATAN") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_atan)(self,arg1)]) |
-				 (str_p("SQRT") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_sqrt)(self,arg1)]) |
-				 (str_p("LOG") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_log)(self,arg1)]) |
-				 (str_p("EXP") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_exp)(self,arg1)]) |
-				 (str_p("ABS") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_fabs)(self,arg1)]) |
-				 (str_p("FLR") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_floor)(self,arg1)]) |
-				 (str_p("CEIL") >> '(' >> expression[unary_func.value = bind(&LLCalcParser::_ceil)(self,arg1)])
+				((str_p("SIN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_sin)(self,arg1)]) |
+				 (str_p("COS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_cos)(self,arg1)]) |
+				 (str_p("TAN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_tan)(self,arg1)]) |
+				 (str_p("ASIN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_asin)(self,arg1)]) |
+				 (str_p("ACOS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_acos)(self,arg1)]) |
+				 (str_p("ATAN") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_atan)(self,arg1)]) |
+				 (str_p("SQRT") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_sqrt)(self,arg1)]) |
+				 (str_p("LOG") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_log)(self,arg1)]) |
+				 (str_p("EXP") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_exp)(self,arg1)]) |
+				 (str_p("ABS") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_fabs)(self,arg1)]) |
+				 (str_p("FLR") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_floor)(self,arg1)]) |
+				 (str_p("CEIL") >> '(' >> expression[unary_func.value = phoenix::bind(&LLCalcParser::_ceil)(self,arg1)])
 				) >> assert_syntax(ch_p(')'))
 			;
 			
 			binary_func =
 				((str_p("ATAN2") >> '(' >> expression[binary_func.value = arg1] >> ',' >>
-				  expression[binary_func.value = bind(&LLCalcParser::_atan2)(self, binary_func.value, arg1)]) |
+				  expression[binary_func.value = phoenix::bind(&LLCalcParser::_atan2)(self, binary_func.value, arg1)]) |
 				 (str_p("MIN") >> '(' >> expression[binary_func.value = arg1] >> ',' >> 
-				  expression[binary_func.value = bind(&LLCalcParser::_min)(self, binary_func.value, arg1)]) |
+				  expression[binary_func.value = phoenix::bind(&LLCalcParser::_min)(self, binary_func.value, arg1)]) |
 				 (str_p("MAX") >> '(' >> expression[binary_func.value = arg1] >> ',' >> 
-				  expression[binary_func.value = bind(&LLCalcParser::_max)(self, binary_func.value, arg1)])
+				  expression[binary_func.value = phoenix::bind(&LLCalcParser::_max)(self, binary_func.value, arg1)])
 				) >> assert_syntax(ch_p(')'))
 			;
 			
@@ -118,10 +118,10 @@ struct LLCalcParser : grammar<LLCalcParser>
 				 // Lookup throws an Unknown Symbol error if it is unknown, while this works fine,
 				 // would be "neater" to handle symbol lookup from here with an assertive parser.
 //				 constants_p[factor.value = arg1]|
-				 identifier[factor.value = bind(&LLCalcParser::lookup)(self, arg1, arg2)]
+				 identifier[factor.value = phoenix::bind(&LLCalcParser::lookup)(self, arg1, arg2)]
 				) >>
 				// Detect and throw math errors.
-				assert_domain(eps_p(bind(&LLCalcParser::checkNaN)(self, factor.value)))
+				assert_domain(eps_p(phoenix::bind(&LLCalcParser::checkNaN)(self, factor.value)))
 			;
 
 			unary_expr =
@@ -131,14 +131,14 @@ struct LLCalcParser : grammar<LLCalcParser>
 			
 			power =
 				unary_expr[power.value = arg1] >>
-				*('^' >> assert_syntax(unary_expr[power.value = bind(&powf)(power.value, arg1)]))
+				*('^' >> assert_syntax(unary_expr[power.value = phoenix::bind(&powf)(power.value, arg1)]))
 			;
 			
 			term =
 				power[term.value = arg1] >>
 				*(('*' >> assert_syntax(power[term.value *= arg1])) |
 				  ('/' >> assert_syntax(power[term.value /= arg1])) |
-				  ('%' >> assert_syntax(power[term.value = bind(&fmodf)(term.value, arg1)]))
+				  ('%' >> assert_syntax(power[term.value = phoenix::bind(&fmodf)(term.value, arg1)]))
 				)
 			;
 			
diff --git a/indra/llmeshoptimizer/CMakeLists.txt b/indra/llmeshoptimizer/CMakeLists.txt
index 016794cfad5783c23a5ae99f8958e9fd375b94cd..dfac44c296bdfb787df000e39ed1fa52818daa19 100644
--- a/indra/llmeshoptimizer/CMakeLists.txt
+++ b/indra/llmeshoptimizer/CMakeLists.txt
@@ -2,43 +2,33 @@
 
 project(llmeshoptimizer)
 
-include(MESHOPTIMIZER)
+include(Meshoptimizer)
 
 include(00-Common)
 include(LLCommon)
 include(LLMath)
 
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESHOPTIMIZER_INCLUDE_DIR}
-    ${MESHOPTIMIZER_INCLUDE_DIRS}
-    ${LIBS_PREBUILT_DIR}/include  #access to boost headers, needed for LLError
-    )
-
 set(llmeshoptimizer_SOURCE_FILES
-    llmeshoptimizer.cpp
-    )
+        llmeshoptimizer.cpp
+        )
 
 set(llmeshoptimizer_HEADER_FILES
-    CMakeLists.txt
-
-    llmeshoptimizer.h
-    )
+        CMakeLists.txt
+        llmeshoptimizer.h
+        )
 
 set_source_files_properties(${llmeshoptimizer_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
+        PROPERTIES HEADER_FILE_ONLY TRUE)
 
 list(APPEND llmeshoptimizer_SOURCE_FILES ${llmeshoptimizer_HEADER_FILES})
 
-#if (USE_MESHOPT)
-  add_library (llmeshoptimizer ${llmeshoptimizer_SOURCE_FILES})
+add_library (llmeshoptimizer ${llmeshoptimizer_SOURCE_FILES})
+target_include_directories( llmeshoptimizer INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
+
+target_link_libraries(llmeshoptimizer
+        llcommon
+        llmath
+        ll::meshoptimizer)
 
-  target_link_libraries(llmeshoptimizer
-    ${LLCOMMON_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${MESHOPTIMIZER_LIBRARIES})
-  
-  # Add tests
+# Add tests
 
-#endif (USE_MESHOPT)
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index f0a1dfe9401a00f633e0bf4cf7a975ed7aa92120..4786956e85f20957cd6c76ac9768232057b27ef2 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -7,26 +7,12 @@ include(GoogleMock)
 include(LLAddBuildTest)
 include(LLCommon)
 include(LLCoreHttp)
-include(LLMath)
-include(LLMessage)
-include(LLFileSystem)
 include(LLAddBuildTest)
 include(Python)
 include(Tut)
 include(Python)
 include(JsonCpp)
 
-include_directories (${CMAKE_CURRENT_SOURCE_DIR})
-
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLCOREHTTP_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${JSONCPP_INCLUDE_DIR}
-    )
-
 set(llmessage_SOURCE_FILES
     llassetstorage.cpp
     llavatarname.cpp
@@ -197,49 +183,19 @@ set(llmessage_HEADER_FILES
     sound_ids.h
     )
 
-set_source_files_properties(${llmessage_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llmessage_SOURCE_FILES ${llmessage_HEADER_FILES})
 
 add_library (llmessage ${llmessage_SOURCE_FILES})
 
-if (LINUX)
-target_link_libraries(
-  llmessage
-  ${CURL_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-  ${LLFILESYSTEM_LIBRARIES}
-  ${LLMATH_LIBRARIES}
-  ${JSONCPP_LIBRARIES}
-  ${OPENSSL_LIBRARIES}
-  ${CRYPTO_LIBRARIES}
-  ${NGHTTP2_LIBRARIES}
-  ${XMLRPCEPI_LIBRARIES}
-  ${LLCOREHTTP_LIBRARIES}
-  ${BOOST_FIBER_LIBRARY}
-  ${BOOST_CONTEXT_LIBRARY}
-  ${BOOST_SYSTEM_LIBRARY}
-  rt
-  )
-else (LINUX)
 target_link_libraries(
-  llmessage
-  ${CURL_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-  ${LLFILESYSTEM_LIBRARIES}
-  ${LLMATH_LIBRARIES}
-  ${JSONCPP_LIBRARIES}
-  ${OPENSSL_LIBRARIES}
-  ${CRYPTO_LIBRARIES}
-  ${NGHTTP2_LIBRARIES}
-  ${XMLRPCEPI_LIBRARIES}
-  ${LLCOREHTTP_LIBRARIES}
-  ${BOOST_FIBER_LIBRARY}
-  ${BOOST_CONTEXT_LIBRARY}
-  ${BOOST_SYSTEM_LIBRARY}
-  )
-endif(LINUX)
+        llmessage
+        llcommon
+        llfilesystem
+        llmath
+        llcorehttp
+        ll::xmlrpc-epi
+)
+target_include_directories( llmessage  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
 
 # tests
 if (LL_TESTS)
@@ -249,43 +205,18 @@ if (LL_TESTS)
     lltrustedmessageservice.cpp
     lltemplatemessagedispatcher.cpp
     )
+  set_property( SOURCE ${llmessage_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_LIBRARIES llmath llcorehttp)
   LL_ADD_PROJECT_UNIT_TESTS(llmessage "${llmessage_TEST_SOURCE_FILES}")
 
-  
   #    set(TEST_DEBUG on)
-  
-if (LINUX)
-  set(test_libs
-    ${WINDOWS_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${CURL_LIBRARIES}
-    ${NGHTTP2_LIBRARIES}
-    ${LLCOMMON_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLCOREHTTP_LIBRARIES}
-    ${JSONCPP_LIBRARIES}
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    rt
-    ${GOOGLEMOCK_LIBRARIES}
-    )
-else (LINUX)
+
   set(test_libs
-    ${WINDOWS_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${CURL_LIBRARIES}
-    ${NGHTTP2_LIBRARIES}
-    ${LLCOMMON_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLCOREHTTP_LIBRARIES}
-    ${JSONCPP_LIBRARIES}
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    ${GOOGLEMOCK_LIBRARIES}
-    )
-endif(LINUX)
+          llfilesystem
+          llmath
+          llcorehttp
+          llmessage
+          llcommon
+          )
 
   #LL_ADD_INTEGRATION_TEST(llavatarnamecache "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llhost "" "${test_libs}")
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index 96af8bacee57a9ceaedf2aa0514e3e4c95e1bf4a..02f273b2040fa949c794f97051683d8cbe2e2eb5 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -35,8 +35,8 @@
 #include "llsd.h"
 #include "llsdjson.h"
 #include "llsdserialize.h"
-#include "reader.h" // JSON
-#include "writer.h" // JSON
+#include "json/reader.h" // JSON
+#include "json/writer.h" // JSON
 #include "llfilesystem.h"
 
 #include "message.h" // for getting the port
diff --git a/indra/llmessage/llfiltersd2xmlrpc.cpp b/indra/llmessage/llfiltersd2xmlrpc.cpp
index 0abdafbdfcd73212bf3ae3d20aea4bc73e647f97..c63ce5f44101e97915d8700aba6b2a031fddeca0 100644
--- a/indra/llmessage/llfiltersd2xmlrpc.cpp
+++ b/indra/llmessage/llfiltersd2xmlrpc.cpp
@@ -75,7 +75,13 @@
 
 #include <sstream>
 #include <iterator>
+
+#ifdef LL_USESYSTEMLIBS
+#include <xmlrpc.h>
+#else
 #include <xmlrpc-epi/xmlrpc.h>
+#endif
+
 #include "apr_base64.h"
 
 #include "llbuffer.h"
diff --git a/indra/llmessage/llioutil.h b/indra/llmessage/llioutil.h
index e8d245f530bdf0deb829fb4b8b7ac731def1f7bb..c404a98bed3cf298fbacb5848e679beef2625e98 100644
--- a/indra/llmessage/llioutil.h
+++ b/indra/llmessage/llioutil.h
@@ -147,7 +147,7 @@ class LLIOAddChain : public LLIOPipe
  * }
  * </code>
  */
-class LLChangeChannel //: public unary_function<T, void>
+class LLChangeChannel
 {
 public:
 	/** 
diff --git a/indra/llmessage/llmessagethrottle.cpp b/indra/llmessage/llmessagethrottle.cpp
index 579d6d718788a0f43515ea6280ed1124cdb3ff8a..14582aaf320ed98635a7e594b6dc2fb50ca078b4 100644
--- a/indra/llmessage/llmessagethrottle.cpp
+++ b/indra/llmessage/llmessagethrottle.cpp
@@ -32,18 +32,8 @@
 #include "llframetimer.h"
 
 // This is used for the stl search_n function.
-#if _MSC_VER >= 1500 // VC9 has a bug in search_n
-struct eq_message_throttle_entry : public std::binary_function< LLMessageThrottleEntry, LLMessageThrottleEntry, bool >
-{
-	bool operator()(const LLMessageThrottleEntry& a, const LLMessageThrottleEntry& b) const
-	{
-		return a.getHash() == b.getHash();
-	}
-};
-#else
 bool eq_message_throttle_entry(LLMessageThrottleEntry a, LLMessageThrottleEntry b)
  		{ return a.getHash() == b.getHash(); }
-#endif
 
 const U64 SEC_TO_USEC = 1000000;
 		
@@ -118,14 +108,8 @@ BOOL LLMessageThrottle::addViewerAlert(const LLUUID& to, const std::string& mesg
 	LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());
 
 	// Check if this message is already in the list.
-#if _MSC_VER >= 1500 // VC9 has a bug in search_n
-	// SJB: This *should* work but has not been tested yet *TODO: Test!
-	message_list_iterator_t found = std::find_if(message_list->begin(), message_list->end(),
-												 std::bind2nd(eq_message_throttle_entry(), entry));
-#else
  	message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(),
  												  1, entry, eq_message_throttle_entry);
-#endif
 	if (found == message_list->end())
 	{
 		// This message was not found.  Add it to the list.
@@ -152,15 +136,8 @@ BOOL LLMessageThrottle::addAgentAlert(const LLUUID& agent, const LLUUID& task, c
 	LLMessageThrottleEntry entry(hash, LLFrameTimer::getTotalTime());
 
 	// Check if this message is already in the list.
-#if _MSC_VER >= 1500 // VC9 has a bug in search_n
-	// SJB: This *should* work but has not been tested yet *TODO: Test!
-	message_list_iterator_t found = std::find_if(message_list->begin(), message_list->end(),
-												 std::bind2nd(eq_message_throttle_entry(), entry));
-#else
 	message_list_iterator_t found = std::search_n(message_list->begin(), message_list->end(),
 												  1, entry, eq_message_throttle_entry);
-#endif
-	
 	if (found == message_list->end())
 	{
 		// This message was not found.  Add it to the list.
diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h
index c13f39df9bda93e0cc263e72e1e3cc24252840d5..8548ed51e74b6cd455c189dc6a9bb8371bd94a62 100644
--- a/indra/llmessage/llregionflags.h
+++ b/indra/llmessage/llregionflags.h
@@ -89,6 +89,8 @@ const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
 const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);
 const U64 REGION_FLAGS_DENY_AGEUNVERIFIED	= (1 << 30);
 
+const U64 REGION_FLAGS_DENY_BOTS = (1 << 31);
+
 const U64 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |
 								 REGION_FLAGS_ALLOW_SET_HOME |
                                  REGION_FLAGS_ALLOW_PARCEL_CHANGES |
diff --git a/indra/llmessage/llthrottle.cpp b/indra/llmessage/llthrottle.cpp
index 935af2aa5a551b04c45b54cc6d8bc637c296d664..e659414e8c7bbbf258f0ab00aa01c0137865e44c 100644
--- a/indra/llmessage/llthrottle.cpp
+++ b/indra/llmessage/llthrottle.cpp
@@ -435,12 +435,6 @@ BOOL LLThrottleGroup::dynamicAdjust()
 		{
 			channel_over_nominal[i] = FALSE;
 		}
-
-		//if (total)
-		//{
-		//	LL_INFOS() << i << ": B" << channel_busy[i] << " I" << channel_idle[i] << " N" << channel_over_nominal[i];
-		//	LL_CONT << " Nom: " << mNominalBPS[i] << " Cur: " << mCurrentBPS[i] << " BS: " << mBitsSentHistory[i] << LL_ENDL;
-		//}
 	}
 
 	if (channels_busy)
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 5cc129a2677fffb80c5e27a67e07a63f733a26b3..14a69afe6eb11e946889e2f1b8dadff6332ebfb1 100644
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -6,26 +6,7 @@ include(00-Common)
 include(CURL)
 include(LLCommon)
 include(LLImage)
-include(LLMath)
-include(LLMessage)
-include(LLRender)
-include(LLXML)
 include(LLWindow)
-include(Boost)
-
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-    )
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLXML_SYSTEM_INCLUDE_DIRS}
-    )
 
 set(llplugin_SOURCE_FILES
     llpluginclassmedia.cpp
@@ -39,7 +20,6 @@ set(llplugin_SOURCE_FILES
 
 set(llplugin_HEADER_FILES
     CMakeLists.txt
-
     llpluginclassmedia.h
     llpluginclassmediaowner.h
     llplugininstance.h
@@ -51,9 +31,6 @@ set(llplugin_HEADER_FILES
     llpluginsharedmemory.h
     )
 
-set_source_files_properties(${llplugin_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 if(NOT ADDRESS_SIZE EQUAL 32)
   if(WINDOWS)
     ##add_definitions(/FIXED:NO)
@@ -65,6 +42,7 @@ endif(NOT ADDRESS_SIZE EQUAL 32)
 list(APPEND llplugin_SOURCE_FILES ${llplugin_HEADER_FILES})
 
 add_library (llplugin ${llplugin_SOURCE_FILES})
-
+target_include_directories( llplugin  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
+target_link_libraries( llplugin llcommon llmath llrender llmessage )
 add_subdirectory(slplugin)
 
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 1fbbad06d478ca19d9cd7d27150bcba76bb0bf83..756d0b5db8e171aff785eb619cc43ccd82ecb055 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -162,6 +162,11 @@ LLPluginProcessParent::~LLPluginProcessParent()
     {   // If we are quitting, the network sockets will already have been destroyed.
         killSockets();
     }
+
+    if (mPolling.connected())
+    {
+        mPolling.disconnect();
+    }
 }
 
 /*static*/
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index e4f64448c559bee55ac3f136d4a8be68fb3ae9f5..0ea6495eaca9b0fc8dc1ac49883fad93ffcb2f23 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -2,25 +2,8 @@ project(SLPlugin)
 
 include(00-Common)
 include(LLCommon)
-include(LLPlugin)
 include(Linking)
 include(PluginAPI)
-include(LLMessage)
-
-include_directories(
-    ${LLPLUGIN_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-)
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    )
-
-if (DARWIN)
-    include(CMakeFindFrameworks)
-    find_library(COCOA_LIBRARY Cocoa)
-endif (DARWIN)
-
 
 ### SLPlugin
 
@@ -37,9 +20,6 @@ if (DARWIN)
   )
 endif (DARWIN)
 
-set_source_files_properties(${SLPlugin_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 if (SLPlugin_HEADER_FILES)
   list(APPEND SLPlugin_SOURCE_FILES ${SLPlugin_HEADER_FILES})
 endif (SLPlugin_HEADER_FILES)
@@ -63,23 +43,20 @@ set_target_properties(SLPlugin
 endif ()
 
 target_link_libraries(SLPlugin
-  ${LEGACY_STDIO_LIBS}
-  ${LLPLUGIN_LIBRARIES}
-  ${LLMESSAGE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-  ${PLUGIN_API_WINDOWS_LIBRARIES}
-)
+        llplugin
+        llmessage
+        llcommon
+        ll::pluginlibraries
+        )
 
 if (DARWIN)
-  # Mac version needs to link against Carbon
-  target_link_libraries(SLPlugin ${COCOA_LIBRARY})
   # Make sure the app bundle has a Resources directory (it will get populated by viewer-manifest.py later)
   add_custom_command(
     TARGET SLPlugin POST_BUILD
     COMMAND mkdir
     ARGS
       -p
-      ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/SLPlugin.app/Contents/Resources
+      ${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/SLPlugin.app/Contents/Resources
   )
 endif (DARWIN)
 
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index dd25c197132d97517aa41b9792b5918cf792e4c4..76d261ab3e4e6a67f6d74454d3088da5619264cf 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -4,32 +4,12 @@ project(llprimitive)
 
 include(00-Common)
 include(LLCommon)
-include(LLMath)
-include(LLMessage)
 include(LLCoreHttp)
-include(LLXML)
 include(LLPhysicsExtensions)
-include(LLCharacter)
-include(LLRender)
+include(LLPrimitive)
+include(GLH)
 include(TinyGLTF)
 
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LIBS_PREBUILT_DIR}/include/collada
-    ${LIBS_PREBUILT_DIR}/include/collada/1.4
-    ${LLCHARACTER_INCLUDE_DIRS}
-    ${TINYGLTF_INCLUDE_DIR}
-    )
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLXML_SYSTEM_INCLUDE_DIRS}
-    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
-    )
-
 set(llprimitive_SOURCE_FILES
     lldaeloader.cpp
     llgltfloader.cpp
@@ -72,26 +52,25 @@ set(llprimitive_HEADER_FILES
     material_codes.h
     object_flags.h
     )
-        
-set_source_files_properties(${llprimitive_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
 
 list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})
 
 add_library (llprimitive ${llprimitive_SOURCE_FILES})
+target_include_directories( llprimitive  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
 
 target_link_libraries(llprimitive
-    ${LLCOMMON_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLCOREHTTP_LIBRARIES}
-    ${LLXML_LIBRARIES}
-    ${LLPHYSICSEXTENSIONS_LIBRARIES}
-    ${LLCHARACTER_LIBRARIES}
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    )
-
+        llcommon
+        llmath
+        llmessage
+        llcorehttp
+        llxml
+        llcharacter
+        llrender
+        llphysicsextensions_impl
+        ll::colladadom
+        ll::pcre
+        ll::glh_linear
+        )
 
 #add unit tests
 if (LL_TESTS)
@@ -101,6 +80,7 @@ if (LL_TESTS)
       llprimitive.cpp
       llgltfmaterial.cpp
       )
-    
+
+    set_property(SOURCE llprimitive.cpp PROPERTY LL_TEST_ADDITIONAL_LIBRARIES llmessage)
     LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}")
 endif (LL_TESTS)
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index a30f47f1d9e7f1e8ecaf9e7af8fb5c63aea3aae6..92ebdb9490407bf3a967c92df1887e73a8f82110 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -7,26 +7,7 @@ include(OpenGL)
 include(FreeType)
 include(LLCommon)
 include(LLImage)
-include(LLMath)
-include(LLRender)
 include(LLWindow)
-include(LLXML)
-include(LLFileSystem)
-
-include_directories(
-    ${FREETYPE_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    )
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLXML_SYSTEM_INCLUDE_DIRS}
-    )
 
 set(llrender_SOURCE_FILES
     llatmosphere.cpp
@@ -85,9 +66,6 @@ set(llrender_HEADER_FILES
     llglcommonfunc.h
     )
 
-set_source_files_properties(${llrender_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llrender_SOURCE_FILES ${llrender_HEADER_FILES})
 
 if (BUILD_HEADLESS)
@@ -100,34 +78,29 @@ if (BUILD_HEADLESS)
       )
 
   target_link_libraries(llrenderheadless
-    ${LLCOMMON_LIBRARIES}
-    ${LLIMAGE_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLRENDER_HEADLESS_LIBRARIES}
-    ${LLXML_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLWINDOW_HEADLESS_LIBRARIES}
-    ${OPENGL_HEADLESS_LIBRARIES})
-
+          llcommon
+          llimage
+          llmath
+          llrender
+          llxml
+          llfilesystem
+          )
 endif (BUILD_HEADLESS)
 
 add_library (llrender ${llrender_SOURCE_FILES})
-
-if (SDL_FOUND)
-  set_property(TARGET llrender
-    PROPERTY COMPILE_DEFINITIONS LL_SDL=1
-    )
-endif (SDL_FOUND)
+target_include_directories( llrender  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
 
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
-target_link_libraries(llrender 
-    ${LLCOMMON_LIBRARIES}
-    ${LLIMAGE_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLXML_LIBRARIES}
-    ${LLWINDOW_LIBRARIES}
-    ${FREETYPE_LIBRARIES}
-    ${OPENGL_LIBRARIES})
+target_link_libraries(llrender
+        llcommon
+        llimage
+        llmath
+        llfilesystem
+        llxml
+        llwindow
+        ll::freetype
+        OpenGL::GL
+        OpenGL::GLU
+        )
 
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index bc1a2f888709813f5b31dccb90aa57c4f5112525..9750bd4fa1e8e30173cdaa37fd47486ec7ae1c61 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -239,7 +239,7 @@ std::string currentOsName()
 	return "Windows";
 #elif LL_DARWIN
 	return "Mac";
-#elif LL_SDL || LL_MESA_HEADLESS
+#elif LL_LINUX
 	return "Linux";
 #else
 	return "";
diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp
index 59e8e86fbbc812f159abe451c98c8cdb00210eee..95a100a8e6d59168e09aaf3f27b24d79886d05bd 100644
--- a/indra/llrender/llglslshader.cpp
+++ b/indra/llrender/llglslshader.cpp
@@ -267,10 +267,10 @@ void LLGLSLShader::readProfileQuery()
         glEndQuery(GL_SAMPLES_PASSED);
         glEndQuery(GL_PRIMITIVES_GENERATED);
 
-        U64 time_elapsed = 0;
+        GLuint64 time_elapsed = 0;
         glGetQueryObjectui64v(mTimerQuery, GL_QUERY_RESULT, &time_elapsed);
 
-        U64 samples_passed = 0;
+        GLuint64 samples_passed = 0;
         glGetQueryObjectui64v(mSamplesQuery, GL_QUERY_RESULT, &samples_passed);
 
         U64 primitives_generated = 0;
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index e0579352d3b55d082a0f8e3a039255011f2d443c..9108c6143ca1cf9d0a57e59a58685ec28842f1eb 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -6,33 +6,9 @@ include(00-Common)
 include(Hunspell)
 include(LLCommon)
 include(LLImage)
-include(LLInventory)
-include(LLMath)
-include(LLMessage)
 include(LLCoreHttp)
-include(LLRender)
 include(LLWindow)
 include(LLCoreHttp)
-include(LLFileSystem)
-include(LLXML)
-
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLCOREHTTP_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLINVENTORY_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    ${LIBS_PREBUILD_DIR}/include/hunspell
-    )
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLXML_SYSTEM_INCLUDE_DIRS}
-    )
 
 set(llui_SOURCE_FILES
     llaccordionctrl.cpp
@@ -260,9 +236,6 @@ set(llui_HEADER_FILES
     llxyvector.h
     )
 
-set_source_files_properties(${llui_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 SET(llurlentry_TEST_DEPENDENCIES
     llurlmatch.cpp
     llurlregistry.cpp
@@ -276,42 +249,37 @@ set_source_files_properties(llurlentry.cpp
 list(APPEND llui_SOURCE_FILES ${llui_HEADER_FILES})
 
 add_library (llui ${llui_SOURCE_FILES})
+target_include_directories( llui  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 target_link_libraries(llui
-    ${LLRENDER_LIBRARIES}
-    ${LLWINDOW_LIBRARIES}
-    ${LLIMAGE_LIBRARIES}
-    ${LLINVENTORY_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLCOREHTTP_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLXUIXML_LIBRARIES}
-    ${LLXML_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${HUNSPELL_LIBRARY}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLCOMMON_LIBRARIES} # must be after llimage, llwindow, llrender
+        llrender
+        llwindow
+        llimage
+        llinventory
+        llmessage
+        llcorehttp
+        llfilesystem
+        llxml
+        llmath
+        ll::hunspell
+        llcommon
     )
 
 # Add tests
 if(LL_TESTS)
   include(LLAddBuildTest)
+  set(test_libs llmessage llcorehttp llxml llrender llcommon ll::hunspell)
+
   SET(llui_TEST_SOURCE_FILES
       llurlmatch.cpp
       )
+  set_property( SOURCE ${llui_TEST_SOURCE_FILES} PROPERTY LL_TEST_ADDITIONAL_LIBRARIES ${test_libs})
   LL_ADD_PROJECT_UNIT_TESTS(llui "${llui_TEST_SOURCE_FILES}")
   # INTEGRATION TESTS
-  set(test_libs llui llmessage llcorehttp llcommon
-      ${HUNSPELL_LIBRARY}
-      ${LLCOMMON_LIBRARIES}
-      ${BOOST_FIBER_LIBRARY} ${BOOST_CONTEXT_LIBRARY} ${BOOST_SYSTEM_LIBRARY}
-      ${WINDOWS_LIBRARIES})
+
   if(NOT LINUX)
-    if(WINDOWS)
-      LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "imm32;${test_libs}")
-    else(WINDOWS)
-      LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}")
-    endif(WINDOWS)
+    set(test_libs llui llmessage llcorehttp llxml llrender llcommon ll::hunspell )
+    LL_ADD_INTEGRATION_TEST(llurlentry llurlentry.cpp "${test_libs}")
   endif(NOT LINUX)
 endif(LL_TESTS)
diff --git a/indra/llui/lldockablefloater.h b/indra/llui/lldockablefloater.h
index 89c9852f4af3349fe8e3f4bd53ea889205954c15..5d90b3ef4e7a257637ff00b22572b3e175f4d78a 100644
--- a/indra/llui/lldockablefloater.h
+++ b/indra/llui/lldockablefloater.h
@@ -30,6 +30,7 @@
 #include "llerror.h"
 #include "llfloater.h"
 #include "lldockcontrol.h"
+#include <memory>
 
 /**
  * Represents floater that can dock.
@@ -131,7 +132,7 @@ class LLDockableFloater : public LLFloater
 	boost::function<BOOL ()> mIsDockedStateForcedCallback;
 
 private:
-	std::auto_ptr<LLDockControl> mDockControl;
+	std::unique_ptr<LLDockControl> mDockControl;
 	LLUIImagePtr mDockTongue;
 	static LLHandle<LLFloater> sInstanceHandle;
 	/**
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index d413fab2700206e3a24c6f36f7bcfee1c30c9bae..2303cd24b7c8e5bf1ad35caded2ab11316c90ac4 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -759,11 +759,13 @@ void LLFloater::closeFloater(bool app_quitting)
         }
 
 		// now close dependent floater
-		for(handle_set_iter_t dependent_it = mDependents.begin();
-			dependent_it != mDependents.end(); )
+		while(mDependents.size() > 0)
 		{
+            handle_set_iter_t dependent_it = mDependents.begin();
 			LLFloater* floaterp = dependent_it->get();
-            dependent_it = mDependents.erase(dependent_it);
+            // normally removeDependentFloater will do this, but in
+            // case floaterp is somehow invalid or orphaned, erase now
+            mDependents.erase(dependent_it);
             if (floaterp)
             {
                 floaterp->mDependeeHandle = LLHandle<LLFloater>();
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 1547a4ba5c89aa0c0df716e48720989f5e08451f..6a9070634cdd6c2c73effffe75114c2ef84e43ea 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -206,6 +206,7 @@ bool LLUrlEntryBase::isWikiLinkCorrect(const std::string &labeled_url) const
     {
         return (chr == L'\u02D0') // "Modifier Letter Colon"
             || (chr == L'\uFF1A') // "Fullwidth Colon"
+            || (chr == L'\u2236') // "Ratio"
             || (chr == L'\uFE55'); // "Small Colon"
     },
         L'\u003A'); // Colon
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index c9d7013a11ac5dba1887d0d66cbc9f64c17ca1e4..23f3dca3fbdfc5b9262efac792c36d5a89a6a2c4 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -169,7 +169,7 @@ bool LLUrlRegistry::findUrl(const std::string &text, LLUrlMatch &match, const LL
 	for (it = mUrlEntry.begin(); it != mUrlEntry.end(); ++it)
 	{
 		//Skip for url entry icon if content is not trusted
-		if(!is_content_trusted && (mUrlEntryIcon == *it))
+		if((mUrlEntryIcon == *it) && ((text.find("Hand") != std::string::npos) || !is_content_trusted))
 		{
 			continue;
 		}
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 5fbb88400b7ede464f9fed82f161b1620d1e07f8..7b1430c67cd0937ce5a8405f4c490db7a2704475 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -14,26 +14,9 @@ include(00-Common)
 include(DragDrop)
 include(LLCommon)
 include(LLImage)
-include(LLMath)
-include(LLRender)
-include(LLFileSystem)
 include(LLWindow)
-include(LLXML)
 include(UI)
-
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    )
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLXML_SYSTEM_INCLUDE_DIRS}
-    )
+include(ViewerMiscLibs)
 
 set(llwindow_SOURCE_FILES
     llcursortypes.cpp
@@ -64,22 +47,21 @@ set(viewer_HEADER_FILES
     llmousehandler.h
     )
 
+set(llwindow_LINK_LIBRARIES
+        llcommon
+        llimage
+        llmath
+        llrender
+        llfilesystem
+        llxml
+        ll::glh_linear
+        ll::glext
+        ll::uilibraries
+        ll::SDL
+        )
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 if (LINUX)
-  set(llwindow_LINK_LIBRARIES
-      ${LLCOMMON_LIBRARIES}
-      ${LLIMAGE_LIBRARIES}
-      ${LLMATH_LIBRARIES}
-      ${LLRENDER_LIBRARIES}
-      ${LLFILESYSTEM_LIBRARIES}
-      ${LLWINDOW_LIBRARIES}
-      ${LLXML_LIBRARIES}
-      ${UI_LIBRARIES}     # for GTK
-      ${SDL_LIBRARY}
-      fontconfig          # For FCInit and other FC* functions.
-      )
-
   list(APPEND viewer_SOURCE_FILES 
        llkeyboardsdl.cpp 
        llwindowsdl.cpp
@@ -159,9 +141,6 @@ if (SOLARIS)
        )
 endif (SOLARIS)
 
-set_source_files_properties(${llwindow_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 if (BUILD_HEADLESS)
   set(llwindowheadless_SOURCE_FILES
        llwindowmesaheadless.cpp
@@ -199,10 +178,10 @@ if (SDL_FOUND)
 endif (SDL_FOUND)
 
   target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
+  target_include_directories(llwindow INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
   
 if (DARWIN)
   include(CMakeFindFrameworks)
   find_library(CARBON_LIBRARY Carbon)
   target_link_libraries(llwindow ${CARBON_LIBRARY})
 endif (DARWIN)
-
diff --git a/indra/llwindow/llwindowmacosx-objc.mm b/indra/llwindow/llwindowmacosx-objc.mm
index 57c3d862956ec5dd483ec06c66765270f08139b5..690fe058dbf56e9838d39a2b29840e7429c6b8a0 100644
--- a/indra/llwindow/llwindowmacosx-objc.mm
+++ b/indra/llwindow/llwindowmacosx-objc.mm
@@ -215,6 +215,7 @@ NSWindowRef createNSWindow(int x, int y, int width, int height)
 													  styleMask:NSTitledWindowMask | NSResizableWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSTexturedBackgroundWindowMask backing:NSBackingStoreBuffered defer:NO];
 	[window makeKeyAndOrderFront:nil];
 	[window setAcceptsMouseMovedEvents:TRUE];
+    [window setRestorable:FALSE]; // Viewer manages state from own settings
 	return window;
 }
 
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 3d9963897c0857fd5472efd16f5646e94cf1d921..aae6539685cfd0aedf8ec94d11c1bcc7ba9be3fd 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -634,7 +634,6 @@ BOOL LLWindowMacOSX::createContext(int x, int y, int width, int height, int bits
 		// Get the view instead.
 		mGLView = createOpenGLView(mWindow, mFSAASamples, enable_vsync);
 		mContext = getCGLContextObj(mGLView);
-		
 		gGLManager.mVRAM = getVramSize(mGLView);
 	}
 	
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 666adcf6727f9777da86c9ddad12ee64338273a3..2bdfaf57dea2a6621ddf2f66ed3b2b842fef0169 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -3993,42 +3993,48 @@ void LLWindowWin32::allowLanguageTextInput(LLPreeditor *preeditor, BOOL b)
 
 	sLanguageTextInputAllowed = b;
 
-	if ( sLanguageTextInputAllowed )
-	{
-		// Allowing: Restore the previous IME status, so that the user has a feeling that the previous 
-		// text input continues naturally.  Be careful, however, the IME status is meaningful only during the user keeps 
-		// using same Input Locale (aka Keyboard Layout).
-		if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale)
-		{
-			HIMC himc = LLWinImm::getContext(mWindowHandle);
-			LLWinImm::setOpenStatus(himc, TRUE);
-			LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode);
-			LLWinImm::releaseContext(mWindowHandle, himc);
-		}
-	}
-	else
-	{
-		// Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly.
-		// However, do it after saving the current IME  status.  We need to restore the status when
-		//   allowing language text input again.
-		sWinInputLocale = GetKeyboardLayout(0);
-		sWinIMEOpened = LLWinImm::isIME(sWinInputLocale);
-		if (sWinIMEOpened)
-		{
-			HIMC himc = LLWinImm::getContext(mWindowHandle);
-			sWinIMEOpened = LLWinImm::getOpenStatus(himc);
-			if (sWinIMEOpened)
-			{
-				LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode);
+    if (sLanguageTextInputAllowed)
+    {
+        mWindowThread->post([=]()
+        {
+            // Allowing: Restore the previous IME status, so that the user has a feeling that the previous 
+            // text input continues naturally.  Be careful, however, the IME status is meaningful only during the user keeps 
+            // using same Input Locale (aka Keyboard Layout).
+            if (sWinIMEOpened && GetKeyboardLayout(0) == sWinInputLocale)
+            {
+                HIMC himc = LLWinImm::getContext(mWindowHandle);
+                LLWinImm::setOpenStatus(himc, TRUE);
+                LLWinImm::setConversionStatus(himc, sWinIMEConversionMode, sWinIMESentenceMode);
+                LLWinImm::releaseContext(mWindowHandle, himc);
+            }
+        });
+    }
+    else
+    {
+        mWindowThread->post([=]()
+        {
+            // Disallowing: Turn off the IME so that succeeding key events bypass IME and come to us directly.
+            // However, do it after saving the current IME  status.  We need to restore the status when
+            //   allowing language text input again.
+            sWinInputLocale = GetKeyboardLayout(0);
+            sWinIMEOpened = LLWinImm::isIME(sWinInputLocale);
+            if (sWinIMEOpened)
+            {
+                HIMC himc = LLWinImm::getContext(mWindowHandle);
+                sWinIMEOpened = LLWinImm::getOpenStatus(himc);
+                if (sWinIMEOpened)
+                {
+                    LLWinImm::getConversionStatus(himc, &sWinIMEConversionMode, &sWinIMESentenceMode);
 
-				// We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's 
-				// keyboard hooking, because Some IME reacts only on the former and some other on the latter...
-				LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode);
-				LLWinImm::setOpenStatus(himc, FALSE);
-			}
-			LLWinImm::releaseContext(mWindowHandle, himc);
- 		}
-	}
+                    // We need both ImmSetConversionStatus and ImmSetOpenStatus here to surely disable IME's 
+                    // keyboard hooking, because Some IME reacts only on the former and some other on the latter...
+                    LLWinImm::setConversionStatus(himc, IME_CMODE_NOCONVERSION, sWinIMESentenceMode);
+                    LLWinImm::setOpenStatus(himc, FALSE);
+                }
+                LLWinImm::releaseContext(mWindowHandle, himc);
+            }
+        });
+    }
 }
 
 void LLWindowWin32::fillCandidateForm(const LLCoordGL& caret, const LLRect& bounds, 
@@ -4225,6 +4231,10 @@ void LLWindowWin32::handleStartCompositionMessage()
 
 void LLWindowWin32::handleCompositionMessage(const U32 indexes)
 {
+    if (!mPreeditor)
+    {
+        return;
+    }
 	BOOL needs_update = FALSE;
 	LLWString result_string;
 	LLWString preedit_string;
@@ -4523,7 +4533,7 @@ BOOL LLWindowWin32::handleImeRequests(WPARAM request, LPARAM param, LRESULT *res
 				LLWString context = find_context(wtext, preedit, preedit_length, &context_offset);
 				preedit -= context_offset;
 				preedit_length = llmin(preedit_length, (S32)context.length() - preedit);
-				if (preedit_length && preedit >= 0)
+				if (preedit_length > 0 && preedit >= 0)
 				{
 					// IMR_DOCUMENTFEED may be called when we have an active preedit.
 					// We should pass the context string *excluding* the preedit string.
diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt
index 3a7a54e51d04402d3fd2481bbbece95299174d41..508c2b919b7e0bbdcb7bd45b4b792c314577887b 100644
--- a/indra/llxml/CMakeLists.txt
+++ b/indra/llxml/CMakeLists.txt
@@ -4,18 +4,6 @@ project(llxml)
 
 include(00-Common)
 include(LLCommon)
-include(LLMath)
-include(LLFileSystem)
-include(LLXML)
-
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    )
-include_directories(
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    )
 
 set(llxml_SOURCE_FILES
     llcontrol.cpp
@@ -33,20 +21,19 @@ set(llxml_HEADER_FILES
     llxmltree.h
     )
 
-set_source_files_properties(${llxml_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES})
 
 add_library (llxml ${llxml_SOURCE_FILES})
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 target_link_libraries( llxml
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLCOMMON_LIBRARIES}
-    ${EXPAT_LIBRARIES}
+        llfilesystem
+        llmath
+        llcommon
+        ll::expat
     )
+target_include_directories( llxml  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
+
 
 # tests
 
@@ -62,11 +49,10 @@ if (LL_TESTS)
 
     #    set(TEST_DEBUG on)
     set(test_libs
-      ${LLXML_LIBRARIES}
-      ${WINDOWS_LIBRARIES}
-      ${LLMATH_LIBRARIES}
-      ${LLCOMMON_LIBRARIES}
-      )
+            llxml
+            llmath
+            llcommon
+            )
 
     LL_ADD_INTEGRATION_TEST(llcontrol "" "${test_libs}")
 endif (LL_TESTS)
diff --git a/indra/media_plugins/CMakeLists.txt b/indra/media_plugins/CMakeLists.txt
index 1a5cc8ec9a44af8014a042eaece49c7722d26895..972bb7dd2dea06b07f95388710986204f8f63e08 100644
--- a/indra/media_plugins/CMakeLists.txt
+++ b/indra/media_plugins/CMakeLists.txt
@@ -3,8 +3,7 @@
 add_subdirectory(base)
 
 if (LINUX)
-    add_subdirectory(gstreamer010)
-    add_subdirectory(libvlc)
+    #add_subdirectory(gstreamer010)
     add_subdirectory(example)
 endif (LINUX)
 
diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt
index 7f2b82ffdd0b34c501b2a18f228eaafeb63ed7e7..64b6a4228d29081f72d3c6e1848b4b4df7f34103 100644
--- a/indra/media_plugins/base/CMakeLists.txt
+++ b/indra/media_plugins/base/CMakeLists.txt
@@ -5,25 +5,9 @@ project(media_plugin_base)
 include(00-Common)
 include(LLCommon)
 include(LLImage)
-include(LLPlugin)
-include(LLMath)
-include(LLRender)
 include(LLWindow)
 include(Linking)
 include(PluginAPI)
-include(OpenGL)
-
-include_directories(
-    ${LLPLUGIN_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-)
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    )
 
 
 ### media_plugin_base
@@ -48,5 +32,7 @@ set(media_plugin_base_HEADER_FILES
 
 add_library(media_plugin_base
     ${media_plugin_base_SOURCE_FILES}
-    )
+        )
 
+target_link_libraries( media_plugin_base llplugin )
+target_include_directories( media_plugin_base  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
diff --git a/indra/media_plugins/cef/CMakeLists.txt b/indra/media_plugins/cef/CMakeLists.txt
index 2acce03d08cf02051bd4a9babc0431154aa856a1..410778114d773cf3919442fdb50114371a7cb9c7 100644
--- a/indra/media_plugins/cef/CMakeLists.txt
+++ b/indra/media_plugins/cef/CMakeLists.txt
@@ -5,29 +5,12 @@ project(media_plugin_cef)
 include(Boost)
 include(00-Common)
 include(LLCommon)
-include(LLPlugin)
-include(LLMath)
-include(LLRender)
 include(LLWindow)
 include(Linking)
 include(PluginAPI)
-include(MediaPluginBase)
 
 include(CEFPlugin)
 
-include_directories(
-    ${LLPLUGIN_INCLUDE_DIRS}
-    ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-    ${CEF_INCLUDE_DIR}
-)
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    )
-
 
 ### media_plugin_cef
 
@@ -47,13 +30,6 @@ set(media_plugin_cef_HEADER_FILES
     volume_catcher.h
     )
 
-set (media_plugin_cef_LINK_LIBRARIES
-  ${LLPLUGIN_LIBRARIES}
-  ${MEDIA_PLUGIN_BASE_LIBRARIES}
-  ${CEF_PLUGIN_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"
@@ -62,7 +38,7 @@ 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
+  set( media_plugin_cef_LINK_LIBRARIES
        ${CORESERVICES_LIBRARY}     # for Component Manager calls
        ${AUDIOUNIT_LIBRARY}        # for AudioUnit calls
        )
@@ -70,9 +46,6 @@ 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)
-
 list(APPEND media_plugin_cef_SOURCE_FILES ${media_plugin_cef_HEADER_FILES})
 
 add_library(media_plugin_cef
@@ -85,7 +58,8 @@ add_library(media_plugin_cef
 #)
 
 target_link_libraries(media_plugin_cef
-  ${media_plugin_cef_LINK_LIBRARIES}
+        media_plugin_base
+        ll::cef
 )
 
 if (WINDOWS)
@@ -93,7 +67,6 @@ if (WINDOWS)
     media_plugin_cef
     PROPERTIES
     LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMT /IGNORE:4099"
-    LINK_FLAGS_DEBUG "/MANIFEST:NO /SAFESEH:NO /NODEFAULTLIB:LIBCMTD /IGNORE:4099"
     )
 endif (WINDOWS)
 
diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt
index eb067a7f6e56a204c59b8f0a2a1d07cbdbc5b7cb..7d3e7f663b5ec156ad8cced6297a7945b98bba13 100644
--- a/indra/media_plugins/example/CMakeLists.txt
+++ b/indra/media_plugins/example/CMakeLists.txt
@@ -5,31 +5,12 @@ project(media_plugin_example)
 include(00-Common)
 include(LLCommon)
 include(LLImage)
-include(LLPlugin)
-include(LLMath)
-include(LLRender)
 include(LLWindow)
 include(Linking)
 include(PluginAPI)
-include(MediaPluginBase)
-include(OpenGL)
 
 include(ExamplePlugin)
 
-include_directories(
-    ${LLPLUGIN_INCLUDE_DIRS}
-    ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-)
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    )
-
-
 ### media_plugin_example
 
 if(NOT ADDRESS_SIZE EQUAL 32)
@@ -49,21 +30,7 @@ add_library(media_plugin_example
     ${media_plugin_example_SOURCE_FILES}
     )
 
-target_link_libraries(media_plugin_example
-  ${LLPLUGIN_LIBRARIES}
-  ${MEDIA_PLUGIN_BASE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-  ${EXAMPLE_PLUGIN_LIBRARIES}
-  ${PLUGIN_API_WINDOWS_LIBRARIES}
-)
-
-add_dependencies(media_plugin_example
-  ${LLPLUGIN_LIBRARIES}
-  ${MEDIA_PLUGIN_BASE_LIBRARIES}
-  # Using ${LLCOMMON_LIBRARIES} here drags in a whole bunch of Boost stuff
-  # that only produces CMake warnings about nonexistent dependencies.
-  llcommon
-)
+target_link_libraries(media_plugin_example media_plugin_base )
 
 if (WINDOWS)
   set_target_properties(
diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt
index 571eb57b248f95b1ee5debd51d72d2c2bdf9208e..38fc8201bf294cb298b316369a275d00bbab620c 100644
--- a/indra/media_plugins/gstreamer010/CMakeLists.txt
+++ b/indra/media_plugins/gstreamer010/CMakeLists.txt
@@ -5,32 +5,14 @@ project(media_plugin_gstreamer010)
 include(00-Common)
 include(LLCommon)
 include(LLImage)
-include(LLPlugin)
 include(LLMath)
-include(LLRender)
 include(LLWindow)
 include(Linking)
 include(PluginAPI)
-include(MediaPluginBase)
 include(OpenGL)
 
 include(GStreamer010Plugin)
 
-include_directories(
-    ${LLPLUGIN_INCLUDE_DIRS}
-    ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-    ${GSTREAMER010_INCLUDE_DIRS}
-    ${GSTREAMER010_PLUGINS_BASE_INCLUDE_DIRS}
-)
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    )
-
 ### media_plugin_gstreamer010
 
 if(NOT ADDRESS_SIZE EQUAL 32)
@@ -59,17 +41,6 @@ add_library(media_plugin_gstreamer010
     )
 
 target_link_libraries(media_plugin_gstreamer010
-  ${LLPLUGIN_LIBRARIES}
-  ${MEDIA_PLUGIN_BASE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-  ${PLUGIN_API_WINDOWS_LIBRARIES}
-  ${GSTREAMER010_LIBRARIES}
-)
-
-add_dependencies(media_plugin_gstreamer010
-  ${LLPLUGIN_LIBRARIES}
-  ${MEDIA_PLUGIN_BASE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-)
-
-
+        media_plugin_base
+        ll::gstreamer
+  )
diff --git a/indra/media_plugins/libvlc/CMakeLists.txt b/indra/media_plugins/libvlc/CMakeLists.txt
index 97392bbe089f960db59ab3f374d4082df80209d1..a3c1c4ef99abb5471d12db4b01f49626abd955ad 100644
--- a/indra/media_plugins/libvlc/CMakeLists.txt
+++ b/indra/media_plugins/libvlc/CMakeLists.txt
@@ -5,32 +5,12 @@ project(media_plugin_libvlc)
 include(00-Common)
 include(LLCommon)
 include(LLImage)
-include(LLPlugin)
-include(LLMath)
-include(LLRender)
 include(LLWindow)
 include(Linking)
 include(PluginAPI)
-include(MediaPluginBase)
-include(OpenGL)
 
 include(LibVLCPlugin)
 
-include_directories(
-    ${LLPLUGIN_INCLUDE_DIRS}
-    ${MEDIA_PLUGIN_BASE_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-    ${VLC_INCLUDE_DIR}
-)
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    )
-
-
 ### media_plugin_libvlc
 
 if(NOT ADDRESS_SIZE EQUAL 32)
@@ -51,27 +31,8 @@ add_library(media_plugin_libvlc
     )
 
 target_link_libraries(media_plugin_libvlc
-  ${LLPLUGIN_LIBRARIES}
-  ${MEDIA_PLUGIN_BASE_LIBRARIES}
-  ${LLCOMMON_LIBRARIES}
-  ${VLC_PLUGIN_LIBRARIES}
-  ${PLUGIN_API_WINDOWS_LIBRARIES}
-)
-
-add_dependencies(media_plugin_libvlc
-  ${LLPLUGIN_LIBRARIES}
-  ${MEDIA_PLUGIN_BASE_LIBRARIES}
-##${LLCOMMON_LIBRARIES}
-  # Just say 'llcommon' here. LLCOMMON_LIBRARIES is specified for use in
-  # target_link_libraries: it includes several Boost libraries, which are
-  # absolutely NOT dependencies in the sense intended here. Those Boost
-  # library macros, in turn, specify 'debug' and 'optimized' and a different
-  # library name for each, producing several wordy errors:
-  # Policy CMP0046 is not set: Error on non-existent dependency in
-  # add_dependencies.
-  # Really, the only dependency we should mention from LLCOMMON_LIBRARIES is
-  # llcommon itself.
-  llcommon
+        media_plugin_base
+        ll::libvlc
 )
 
 if (WINDOWS)
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 3271de72c96116613c2b0d64c5d7145022d0356e..b19718200929e2c921224c3c6df7e860d60b488b 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -23,25 +23,13 @@ include(JsonCpp)
 include(LLAppearance)
 include(LLAudio)
 include(LLCA)
-include(LLCharacter)
 include(LLCommon)
 include(LLCoreHttp)
 include(LLImage)
-include(LLImageJ2COJ)
-include(LLInventory)
 include(LLKDU)
-include(LLLogin)
-include(LLMath)
-include(LLMeshOptimizer)
-include(LLMessage)
 include(LLPhysicsExtensions)
-include(LLPlugin)
 include(LLPrimitive)
-include(LLRender)
-include(LLUI)
-include(LLFileSystem)
 include(LLWindow)
-include(LLXML)
 include(NDOF)
 include(NVAPI)
 include(OPENAL)
@@ -52,65 +40,37 @@ include(TemplateCheck)
 include(ThreeJS)
 include(Tracy)
 include(UI)
-include(UnixInstall)
 include(ViewerMiscLibs)
 include(ViewerManager)
 include(VisualLeakDetector)
 include(VulkanGltf)
 include(ZLIBNG)
 include(URIPARSER)
+include(LLPrimitive)
 
 if (NOT HAVOK_TPV)
    # When using HAVOK_TPV, the library is precompiled, so no need for this
-   add_subdirectory(${LLPHYSICSEXTENSIONS_SRC_DIR} llphysicsextensions)
-endif (NOT HAVOK_TPV)
 
-if(FMODSTUDIO)
-  include_directories(${FMODSTUDIO_INCLUDE_DIR})
-endif(FMODSTUDIO)
-
-include_directories(
-    ${DBUSGLIB_INCLUDE_DIRS}
-    ${JSONCPP_INCLUDE_DIR}
-    ${LLAUDIO_INCLUDE_DIRS}
-    ${LLCHARACTER_INCLUDE_DIRS}
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLCOREHTTP_INCLUDE_DIRS}
-    ${LLPHYSICS_INCLUDE_DIRS}
-    ${LLIMAGE_INCLUDE_DIRS}
-    ${LLKDU_INCLUDE_DIRS}
-    ${LLINVENTORY_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESHOPTIMIZER_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLPLUGIN_INCLUDE_DIRS}
-    ${LLPRIMITIVE_INCLUDE_DIRS}
-    ${LLRENDER_INCLUDE_DIRS}
-    ${LLUI_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${LLWINDOW_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    ${LLLOGIN_INCLUDE_DIRS}
-    ${LIBS_PREBUILT_DIR}/include/collada
-    ${LIBS_PREBUILD_DIR}/include/hunspell
-    ${OPENAL_LIB_INCLUDE_DIRS}
-    ${LIBS_PREBUILT_DIR}/include/collada/1.4
-    ${LLAPPEARANCE_INCLUDE_DIRS}
-    ${CMAKE_CURRENT_SOURCE_DIR}
-    ${TRACY_INCLUDE_DIR}
-    )
+   # Stub and probably havok lib itself is a hack, autobuild loads a 3p that really is a source tarball
+   # which includes a CMakeList.txt and then this whole source tree gets pushed into out build ... :/
+   # To make matters worse there is a internal assumption about the structure of the viewers CMake layout,
+   # which means we need to duct tape this togther ...
 
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLXML_SYSTEM_INCLUDE_DIRS}
-    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
-    )
+   add_subdirectory(${LLPHYSICSEXTENSIONS_SRC_DIR} llphysicsextensions)
+
+   # Another hack that works with newer cmake versions:
+   cmake_policy( SET CMP0079 NEW)
+   if( TARGET llphysicsextensionsstub )
+      target_link_libraries(llphysicsextensionsstub llcommon llmath)
+   endif()
+   if( TARGET llphysicsextensions )
+      target_link_libraries(llphysicsextensions llrender )
+      if (DARWIN)
+        target_compile_options( llphysicsextensions  PRIVATE -Wno-unused-local-typedef)
+      endif (DARWIN)
+   endif()
+endif (NOT HAVOK_TPV)
 
-if (USE_BUGSPLAT)
-  include_directories(AFTER
-    ${BUGSPLAT_INCLUDE_DIR}
-    )
-endif (USE_BUGSPLAT)
 
 set(viewer_SOURCE_FILES
     groupchatlistener.cpp
@@ -1425,25 +1385,6 @@ if (DARWIN)
     COMPILE_FLAGS "-fmodules -fcxx-modules -Wno-nullability-completeness"
     )
 
-  find_library(AGL_LIBRARY AGL)
-  find_library(APPKIT_LIBRARY AppKit)
-  find_library(COCOA_LIBRARY Cocoa)
-  find_library(IOKIT_LIBRARY IOKit)
-  find_library(COREAUDIO_LIBRARY CoreAudio)
-
-  set(viewer_LIBRARIES
-    ${COCOA_LIBRARY}
-    ${AGL_LIBRARY}
-    ${IOKIT_LIBRARY}
-    ${COREAUDIO_LIBRARY}
-    )
-
-  if (USE_BUGSPLAT)
-    list(APPEND viewer_LIBRARIES
-      ${BUGSPLAT_LIBRARIES}
-      )
-  endif (USE_BUGSPLAT)
-
   # Add resource files to the project.
   set(viewer_RESOURCE_FILES
     secondlife.icns
@@ -1457,12 +1398,7 @@ if (DARWIN)
     Japanese.lproj/language.txt
     Korean.lproj/language.txt
     )
-  set_source_files_properties(
-    ${viewer_RESOURCE_FILES}
-    PROPERTIES
-    HEADER_FILE_ONLY TRUE
-    #MACOSX_PACKAGE_LOCATION Resources #don't do this! this tells cmake to copy the files.
-    )
+
   SOURCE_GROUP("Resources" FILES ${viewer_RESOURCE_FILES})
   list(APPEND viewer_SOURCE_FILES ${viewer_RESOURCE_FILES})
 endif (DARWIN)
@@ -1477,12 +1413,6 @@ if (LINUX)
     LIST(APPEND viewer_SOURCE_FILES llappviewerlinux_api_dbus.cpp)
     SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--as-needed")
 
-    set(viewer_LIBRARIES
-        Xinerama
-        )
-    if (OPENAL)
-      LIST(APPEND viewer_LIBRARIES ${OPENAL_LIBRARIES})
-    endif (OPENAL)
 endif (LINUX)
 
 if (WINDOWS)
@@ -1501,19 +1431,6 @@ if (WINDOWS)
          llwindebug.h
          )
 
-    # precompiled header configuration
-    # llviewerprecompiledheaders.cpp generates
-    # the .pch file.
-    # All sources added to viewer_SOURCE_FILES
-    # at this point use it.
-    if(USE_PRECOMPILED_HEADERS)
-        set_source_files_properties(llviewerprecompiledheaders.cpp
-            PROPERTIES
-            COMPILE_FLAGS "/Ycllviewerprecompiledheaders.h"
-            )
-        set(viewer_SOURCE_FILES "${viewer_SOURCE_FILES}" llviewerprecompiledheaders.cpp)
-    endif(USE_PRECOMPILED_HEADERS)
-
     # Replace the icons with the appropriate ones for the channel
     # ('test' is the default)
     set(ICON_PATH "test")
@@ -1610,26 +1527,7 @@ if (WINDOWS)
 
     SOURCE_GROUP("Resource Files" FILES ${viewer_RESOURCE_FILES})
 
-    if (NOT USESYSTEMLIBS)
-        list(APPEND viewer_SOURCE_FILES ${viewer_RESOURCE_FILES})
-    endif (NOT USESYSTEMLIBS)
-
-# see EXP-1765 - theory is opengl32.lib needs to be included before gdi32.lib (windows libs)
-    set(viewer_LIBRARIES
-        opengl32
-        ${WINDOWS_LIBRARIES}
-        comdlg32
-        dxguid
-        imm32
-        kernel32
-        odbc32
-        odbccp32
-        oleaut32
-        shell32
-        Vfw32
-        wer
-        winspool
-        )
+    list(APPEND viewer_SOURCE_FILES ${viewer_RESOURCE_FILES})
 
     find_library(INTEL_MEMOPS_LIBRARY
                  NAMES ll_intel_memops
@@ -1639,8 +1537,10 @@ if (WINDOWS)
                  )
     mark_as_advanced(INTEL_MEMOPS_LIBRARY)
 
+
     if (INTEL_MEMOPS_LIBRARY)
-      list(APPEND viewer_LIBRARIES ${INTEL_MEMOPS_LIBRARY})
+      add_library( ll::intel_memops INTERFACE IMPORTED )
+      target_link_libraries( ll::intel_memops ${INTEL_MEMOPS_LIBRARY} )
     endif (INTEL_MEMOPS_LIBRARY)
 
     if (ADDRESS_SIZE EQUAL 64)
@@ -1652,9 +1552,6 @@ if (WINDOWS)
         LIST(APPEND viewer_SOURCE_FILES windows.manifest)
     endif (ADDRESS_SIZE EQUAL 64)
 
-    if (OPENAL)
-      LIST(APPEND viewer_LIBRARIES ${OPENAL_LIBRARIES})
-    endif (OPENAL)
 endif (WINDOWS)
 
 # Add the xui files. This is handy for searching for xui elements
@@ -1737,9 +1634,7 @@ source_group("Character File" FILES ${viewer_CHARACTER_FILES})
 
 set_source_files_properties(${viewer_CHARACTER_FILES}
                             PROPERTIES HEADER_FILE_ONLY TRUE)
-if (NOT USESYSTEMLIBS)
-    list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
-endif (NOT USESYSTEMLIBS)
+list(APPEND viewer_SOURCE_FILES ${viewer_CHARACTER_FILES})
 
 if (WINDOWS)
   file(GLOB viewer_INSTALLER_FILES installers/windows/*.nsi)
@@ -1752,28 +1647,18 @@ if (WINDOWS)
   list(APPEND viewer_SOURCE_FILES ${viewer_INSTALLER_FILES})
 endif (WINDOWS)
 
-if (OPENAL)
-  set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_OPENAL")
-endif (OPENAL)
-
-if (FMODSTUDIO)
-  set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_FMODSTUDIO")
-  set(FMODWRAPPER_LIBRARY ${FMODSTUDIO_LIBRARY})
-endif (FMODSTUDIO)
-
-set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
-
 if (HAVOK OR HAVOK_TPV)
   set(LLSTARTUP_COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS} -DLL_HAVOK")
 endif (HAVOK OR HAVOK_TPV)
 
-# progress view disables/enables icons based on available packages
-set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
+if( DEFINED LLSTARTUP_COMPILE_FLAGS )
+   # progress view disables/enables icons based on available packages
+   set_source_files_properties(llprogressview.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
 
-list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
+   set_source_files_properties(llstartup.cpp PROPERTIES COMPILE_FLAGS "${LLSTARTUP_COMPILE_FLAGS}")
+endif()
 
-set_source_files_properties(${viewer_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
+list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
 
 add_executable(${VIEWER_BINARY_NAME}
     WIN32
@@ -1781,17 +1666,6 @@ add_executable(${VIEWER_BINARY_NAME}
     ${viewer_SOURCE_FILES}
     )
 
-if (SDL_FOUND)
-  set_property(TARGET ${VIEWER_BINARY_NAME}
-    PROPERTY COMPILE_DEFINITIONS LL_SDL=1
-    )
-endif (SDL_FOUND)
-
-if (USE_BUGSPLAT)
-  set_property(TARGET ${VIEWER_BINARY_NAME}
-    PROPERTY COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
-endif (USE_BUGSPLAT)
-
 # add package files
 file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
      ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@@ -1810,11 +1684,7 @@ if (WINDOWS)
         )
 
     if(USE_PRECOMPILED_HEADERS)
-        set_target_properties(
-            ${VIEWER_BINARY_NAME}
-            PROPERTIES
-            COMPILE_FLAGS "/Yullviewerprecompiledheaders.h"
-            )
+       target_precompile_headers( ${VIEWER_BINARY_NAME} PRIVATE llviewerprecompiledheaders.h )
     endif(USE_PRECOMPILED_HEADERS)
 
     # If adding a file to viewer_manifest.py in the WindowsManifest.construct() method, be sure to add the dependency
@@ -1833,67 +1703,51 @@ if (WINDOWS)
       # The following commented dependencies are determined at variably at build time. Can't do this here.
       ${CMAKE_SOURCE_DIR}/../etc/message.xml
       ${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg
-      ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/llcommon.dll
-      ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libapr-1.dll
-      ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libaprutil-1.dll
-      ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libapriconv-1.dll
-      ${SHARED_LIB_STAGING_DIR}/Release/libcollada14dom22.dll
-      ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libcollada14dom22.dll
-      ${SHARED_LIB_STAGING_DIR}/Debug/libcollada14dom22-d.dll
-      ${SHARED_LIB_STAGING_DIR}/Release/openjp2.dll
-      ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/openjp2.dll
-      ${SHARED_LIB_STAGING_DIR}/Debug/openjp2.dll
-      ${SHARED_LIB_STAGING_DIR}/Release/libhunspell.dll
-      ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/libhunspell.dll
-      ${SHARED_LIB_STAGING_DIR}/Debug/libhunspell.dll
-      ${SHARED_LIB_STAGING_DIR}/Release/uriparser.dll
-      ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/uriparser.dll
-      ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/SLVoice.exe
-      ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/libsndfile-1.dll
-      ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxoal.dll
-      ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ca-bundle.crt
-      ${GOOGLE_PERF_TOOLS_SOURCE}
+      ${SHARED_LIB_STAGING_DIR}/openjp2.dll
+      ${SHARED_LIB_STAGING_DIR}/libhunspell.dll
+      ${SHARED_LIB_STAGING_DIR}/uriparser.dll
+      #${SHARED_LIB_STAGING_DIR}/${LL_INTDIR}/SLVoice.exe
+      #${SHARED_LIB_STAGING_DIR}/${LL_INTDIR}/libsndfile-1.dll
+      #${SHARED_LIB_STAGING_DIR}/${LL_INTDIR}/vivoxoal.dll
+      ${AUTOBUILD_INSTALL_DIR}/ca-bundle.crt
       ${CMAKE_CURRENT_SOURCE_DIR}/licenses-win32.txt
       ${CMAKE_CURRENT_SOURCE_DIR}/featuretable.txt
-      ${CMAKE_CURRENT_SOURCE_DIR}/featuretable_xp.txt
       ${viewer_APPSETTINGS_FILES}
       SLPlugin
       media_plugin_cef
       media_plugin_libvlc
       media_plugin_example
-      winmm_shim
       )
 
     if (ADDRESS_SIZE EQUAL 64)
-        list(APPEND COPY_INPUT_DEPENDENCIES
-            ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk_x64.dll
-            ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ortp_x64.dll
-           ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto-1_1-x64.dll
-           ${ARCH_PREBUILT_DIRS_RELEASE}/libssl-1_1-x64.dll
-            )
+       list(APPEND COPY_INPUT_DEPENDENCIES
+               ${SHARED_LIB_STAGING_DIR}/vivoxsdk_x64.dll
+               ${SHARED_LIB_STAGING_DIR}/ortp_x64.dll
+               ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto-1_1-x64.dll
+               ${ARCH_PREBUILT_DIRS_RELEASE}/libssl-1_1-x64.dll
+               )
     else (ADDRESS_SIZE EQUAL 64)
-        list(APPEND COPY_INPUT_DEPENDENCIES
-            ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/vivoxsdk.dll
-            ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/ortp.dll
-            ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto-1_1.dll
-            ${ARCH_PREBUILT_DIRS_RELEASE}/libssl-1_1.dll
-            )
+       list(APPEND COPY_INPUT_DEPENDENCIES
+               ${SHARED_LIB_STAGING_DIR}/vivoxsdk.dll
+               ${SHARED_LIB_STAGING_DIR}/ortp.dll
+               ${ARCH_PREBUILT_DIRS_RELEASE}/libcrypto-1_1.dll
+               ${ARCH_PREBUILT_DIRS_RELEASE}/libssl-1_1.dll
+               )
     endif (ADDRESS_SIZE EQUAL 64)
 
-    if (FMODSTUDIO)
+    if (TARGET ll::fmodstudio)
       list(APPEND COPY_INPUT_DEPENDENCIES
-           ${SHARED_LIB_STAGING_DIR}/Release/fmod.dll
-           ${SHARED_LIB_STAGING_DIR}/RelWithDebInfo/fmod.dll
+           ${SHARED_LIB_STAGING_DIR}/fmod.dll
            ${SHARED_LIB_STAGING_DIR}/Debug/fmodL.dll
           )
-    endif (FMODSTUDIO)
+    endif ()
 
-    if (OPENAL)
+    if (TARGET ll::openal)
       list(APPEND COPY_INPUT_DEPENDENCIES
-           ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/OpenAL32.dll
-           ${SHARED_LIB_STAGING_DIR}/${CMAKE_CFG_INTDIR}/alut.dll
+           ${SHARED_LIB_STAGING_DIR}/OpenAL32.dll
+           ${SHARED_LIB_STAGING_DIR}/alut.dll
           )
-    endif (OPENAL)
+    endif ()
 
     add_custom_command(
       OUTPUT  ${CMAKE_CFG_INTDIR}/copy_touched.bat
@@ -1904,16 +1758,16 @@ if (WINDOWS)
         --arch=${ARCH}
         --artwork=${ARTWORK_DIR}
         "--bugsplat=${BUGSPLAT_DB}"
-        "--fmodstudio=${FMODSTUDIO}"
-        "--openal=${OPENAL}"
+        "--fmodstudio=${USE_FMODSTUDIO}"
+        "--openal=${USE_OPENAL}"
         --build=${CMAKE_CURRENT_BINARY_DIR}
-        --buildtype=${CMAKE_BUILD_TYPE}
+        --buildtype=$<CONFIG>
         "--channel=${VIEWER_CHANNEL}"
         --configuration=${CMAKE_CFG_INTDIR}
-        --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
+        --dest=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>
         --grid=${GRID}
         --source=${CMAKE_CURRENT_SOURCE_DIR}
-        --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/copy_touched.bat
+        --touch=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/copy_touched.bat
         --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
       DEPENDS
         ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@@ -1960,21 +1814,21 @@ if (WINDOWS)
         OUTPUT ${CMAKE_CFG_INTDIR}/touched.bat
         COMMAND ${PYTHON_EXECUTABLE}
         ARGS
-          ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
-          --arch=${ARCH}
-          --artwork=${ARTWORK_DIR}
-          "--bugsplat=${BUGSPLAT_DB}"
-          "--fmodstudio=${FMODSTUDIO}"
-          "--openal=${OPENAL}"
-          --build=${CMAKE_CURRENT_BINARY_DIR}
-          --buildtype=${CMAKE_BUILD_TYPE}
-          "--channel=${VIEWER_CHANNEL}"
-          --configuration=${CMAKE_CFG_INTDIR}
-          --dest=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
-          --grid=${GRID}
-          --source=${CMAKE_CURRENT_SOURCE_DIR}
-          --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/touched.bat
-          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
+              ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
+              --arch=${ARCH}
+              --artwork=${ARTWORK_DIR}
+              "--bugsplat=${BUGSPLAT_DB}"
+              "--fmodstudio=${USE_FMODSTUDIO}"
+              "--openal=${USE_OPENAL}"
+              --build=${CMAKE_CURRENT_BINARY_DIR}
+              --buildtype=$<CONFIG>
+              "--channel=${VIEWER_CHANNEL}"
+              --configuration=${CMAKE_CFG_INTDIR}
+              --dest=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>
+              --grid=${GRID}
+              --source=${CMAKE_CURRENT_SOURCE_DIR}
+              --touch=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/touched.bat
+              --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
         DEPENDS
             ${VIEWER_BINARY_NAME}
             ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
@@ -1983,8 +1837,7 @@ if (WINDOWS)
         )
 
       add_custom_target(llpackage ALL DEPENDS
-        ${CMAKE_CFG_INTDIR}/touched.bat
-        windows-setup-build-all
+              ${CMAKE_CFG_INTDIR}/touched.bat
         )
         # temporarily disable packaging of event_host until hg subrepos get
         # sorted out on the parabuild cluster...
@@ -2033,61 +1886,38 @@ endif (WINDOWS)
 # modern version.
 
 target_link_libraries(${VIEWER_BINARY_NAME}
-    ${LEGACY_STDIO_LIBS}
-    ${PNG_PRELOAD_ARCHIVES}
-    ${ZLIBNG_PRELOAD_ARCHIVES}
-    ${URIPARSER_PRELOAD_ARCHIVES}
-    ${GOOGLE_PERFTOOLS_LIBRARIES}
-    ${LLAUDIO_LIBRARIES}
-    ${LLCHARACTER_LIBRARIES}
-    ${LLIMAGE_LIBRARIES}
-    ${LLINVENTORY_LIBRARIES}
-    ${LLMESHOPTIMIZER_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLPLUGIN_LIBRARIES}
-    ${LLPRIMITIVE_LIBRARIES}
-    ${LLRENDER_LIBRARIES}
-    ${FREETYPE_LIBRARIES}
-    ${LLUI_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLWINDOW_LIBRARIES}
-    ${LLXML_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLCOREHTTP_LIBRARIES}
-    ${LLCOMMON_LIBRARIES}
-    ${NDOF_LIBRARY}
-    ${NVAPI_LIBRARY}
-    ${HUNSPELL_LIBRARY}
-    ${viewer_LIBRARIES}
-    ${BOOST_PROGRAM_OPTIONS_LIBRARY}
-    ${BOOST_REGEX_LIBRARY}
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    ${DBUSGLIB_LIBRARIES}
-    ${OPENGL_LIBRARIES}
-    ${FMODWRAPPER_LIBRARY} # must come after LLAudio
-    ${OPENGL_LIBRARIES}
-    ${JSONCPP_LIBRARIES}
-    ${SDL_LIBRARY}
-    ${SMARTHEAP_LIBRARY}
-    ${UI_LIBRARIES}
-    ${WINDOWS_LIBRARIES}
-    ${EXPAT_LIBRARIES}
-    ${XMLRPCEPI_LIBRARIES}
-    ${OPENSSL_LIBRARIES}
-    ${CRYPTO_LIBRARIES}
-    ${LLLOGIN_LIBRARIES}
-    ${LLPHYSICS_LIBRARIES}
-    ${LLPHYSICSEXTENSIONS_LIBRARIES}
-    ${LLAPPEARANCE_LIBRARIES}
-    ${TRACY_LIBRARY}
-    )
+        llaudio
+        llcharacter
+        llimage
+        llinventory
+        llmessage
+        llplugin
+        llprimitive
+        llrender
+        llui
+        llfilesystem
+        llwindow
+        llxml
+        llmath
+        llcorehttp
+        llcommon
+        llmeshoptimizer
+        ll::ndof
+        lllogin
+        llprimitive
+        llappearance
+        ${LLPHYSICSEXTENSIONS_LIBRARIES}
+        ll::bugsplat
+        ll::tracy
+        )
 
-if (USE_BUGSPLAT)
-  target_link_libraries(${VIEWER_BINARY_NAME}
-    ${BUGSPLAT_LIBRARIES}
-    )
-endif (USE_BUGSPLAT)
+if( TARGET ll::intel_memops )
+   target_link_libraries(${VIEWER_BINARY_NAME} ll::intel_memops )
+endif()
+
+if( TARGET ll::nvapi )
+   target_link_libraries(${VIEWER_BINARY_NAME} ll::nvapi )
+endif()
 
 set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
     "Path to artwork files.")
@@ -2099,14 +1929,13 @@ if (LINUX)
   set(COPY_INPUT_DEPENDENCIES
     ${VIEWER_BINARY_NAME}
     SLPlugin
-    media_plugin_gstreamer010
-    media_plugin_libvlc
+    #media_plugin_gstreamer010
     llcommon
     )
 
-  if (NOT USE_BUGSPLAT)
-      LIST(APPEND COPY_INPUT_DEPENDENCIES linux-crash-logger)
-  endif (NOT USE_BUGSPLAT)
+  #if (NOT USE_BUGSPLAT)
+  #    LIST(APPEND COPY_INPUT_DEPENDENCIES linux-crash-logger)
+  #endif (NOT USE_BUGSPLAT)
 
   add_custom_command(
       OUTPUT ${product}.tar.bz2
@@ -2116,8 +1945,8 @@ if (LINUX)
         --arch=${ARCH}
         --artwork=${ARTWORK_DIR}
         "--bugsplat=${BUGSPLAT_DB}"
-        "--fmodstudio=${FMODSTUDIO}"
-        "--openal=${OPENAL}"
+        "--fmodstudio=${USE_FMODSTUDIO}"
+        "--openal=${USE_OPENAL}"
         --build=${CMAKE_CURRENT_BINARY_DIR}
         --buildtype=${CMAKE_BUILD_TYPE}
         "--channel=${VIEWER_CHANNEL}"
@@ -2144,8 +1973,8 @@ if (LINUX)
       --arch=${ARCH}
       --artwork=${ARTWORK_DIR}
       "--bugsplat=${BUGSPLAT_DB}"
-      "--fmodstudio=${FMODSTUDIO}"
-      "--openal=${OPENAL}"
+      "--fmodstudio=${USE_FMODSTUDIO}"
+      "--openal=${USE_OPENAL}"
       --build=${CMAKE_CURRENT_BINARY_DIR}
       --buildtype=${CMAKE_BUILD_TYPE}
       "--channel=${VIEWER_CHANNEL}"
@@ -2203,7 +2032,7 @@ if (DARWIN)
     XCODE_ATTRIBUTE_PRODUCT_BUNDLE_IDENTIFIER "${MACOSX_BUNDLE_GUI_IDENTIFIER}"
     )
 
-  set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${product}.app")
+  set(VIEWER_APP_BUNDLE "${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/${product}.app")
   set(VIEWER_APP_EXE "${VIEWER_APP_BUNDLE}/Contents/MacOS/${product}")
   set(VIEWER_APP_DSYM "${VIEWER_APP_EXE}.dSYM")
   set(VIEWER_APP_XCARCHIVE "${VIEWER_APP_BUNDLE}/../${product}.xcarchive.zip")
@@ -2222,10 +2051,10 @@ if (DARWIN)
       --arch=${ARCH}
       --artwork=${ARTWORK_DIR}
       "--bugsplat=${BUGSPLAT_DB}"
-      "--fmodstudio=${FMODSTUDIO}"
-      "--openal=${OPENAL}"
+      "--fmodstudio=${USE_FMODSTUDIO}"
+      "--openal=${USE_OPENAL}"
       --build=${CMAKE_CURRENT_BINARY_DIR}
-      --buildtype=${CMAKE_BUILD_TYPE}
+      --buildtype=$<CONFIG>
       --bundleid=${MACOSX_BUNDLE_GUI_IDENTIFIER}
       "--channel=${VIEWER_CHANNEL}"
       --configuration=${CMAKE_CFG_INTDIR}
@@ -2253,22 +2082,22 @@ if (DARWIN)
         TARGET llpackage POST_BUILD
         COMMAND ${PYTHON_EXECUTABLE}
         ARGS
-          ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
-          --arch=${ARCH}
-          --artwork=${ARTWORK_DIR}
-          "--bugsplat=${BUGSPLAT_DB}"
-          "--fmodstudio=${FMODSTUDIO}"
-          "--openal=${OPENAL}"
-          --build=${CMAKE_CURRENT_BINARY_DIR}
-          --buildtype=${CMAKE_BUILD_TYPE}
-          "--channel=${VIEWER_CHANNEL}"
-          --configuration=${CMAKE_CFG_INTDIR}
-          --dest=${VIEWER_APP_BUNDLE}
-          --grid=${GRID}
-          --source=${CMAKE_CURRENT_SOURCE_DIR}
-          --touch=${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/.${product}.touched
-          --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
-          ${SIGNING_SETTING}
+              ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
+              --arch=${ARCH}
+              --artwork=${ARTWORK_DIR}
+              "--bugsplat=${BUGSPLAT_DB}"
+              "--fmodstudio=${USE_FMODSTUDIO}"
+              "--openal=${USE_OPENAL}"
+              --build=${CMAKE_CURRENT_BINARY_DIR}
+              --buildtype=$<CONFIG>
+              "--channel=${VIEWER_CHANNEL}"
+              --configuration=${CMAKE_CFG_INTDIR}
+              --dest=${VIEWER_APP_BUNDLE}
+              --grid=${GRID}
+              --source=${CMAKE_CURRENT_SOURCE_DIR}
+              --touch=${CMAKE_CURRENT_BINARY_DIR}/$<IF:$<BOOL:${LL_GENERATOR_IS_MULTI_CONFIG}>,$<CONFIG>,>/.${product}.bat
+              --versionfile=${CMAKE_CURRENT_BINARY_DIR}/viewer_version.txt
+              ${SIGNING_SETTING}
         DEPENDS
           ${CMAKE_CURRENT_SOURCE_DIR}/viewer_manifest.py
       )
@@ -2400,15 +2229,20 @@ if (LL_TESTS)
   set_source_files_properties(
     llvocache.cpp
     PROPERTIES
-    LL_TEST_ADDITIONAL_SOURCE_FILES 
-    ../llmessage/lldatapacker.cpp
+    LL_TEST_ADDITIONAL_SOURCE_FILES ../llmessage/lldatapacker.cpp
+    LL_TEST_ADDITIONAL_PROJECTS "llprimitive"
   )
 
   set(test_libs
-    ${LLCOMMON_LIBRARIES}
-    ${JSONCPP_LIBRARIES}
-    ${CURL_LIBRARIES}
-    ${NGHTTP2_LIBRARIES}
+          llcommon
+          llfilesystem
+          llxml
+          llmessage
+          llcharacter
+          llui
+          lllogin
+          llplugin
+          llappearance
     )
 
   set_source_files_properties(
@@ -2417,101 +2251,56 @@ if (LL_TESTS)
     LL_TEST_ADDITIONAL_LIBRARIES "${test_libs}"
   )
 
-  set_source_files_properties(
-    llviewerhelputil.cpp
-    PROPERTIES
-    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
-  )
-
-  set_source_files_properties(
-    llremoteparcelrequest.cpp
-    PROPERTIES
-    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
-  )
-
   set_source_files_properties(
     llworldmap.cpp
     llworldmipmap.cpp
     PROPERTIES
     LL_TEST_ADDITIONAL_SOURCE_FILES 
     tests/llviewertexture_stub.cpp
-    #llviewertexturelist.cpp
-    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
   )
 
   set_source_files_properties(
     llmediadataclient.cpp
     PROPERTIES
-    LL_TEST_ADDITIONAL_LIBRARIES "${LLPRIMITIVE_LIBRARIES}"
-  )
-
-  set_source_files_properties(
-    llagentaccess.cpp
-    PROPERTIES
-    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
+    LL_TEST_ADDITIONAL_LIBRARIES llprimitive
   )
 
   set_source_files_properties(
     lllogininstance.cpp
     PROPERTIES
     LL_TEST_ADDITIONAL_SOURCE_FILES llversioninfo.cpp
-    LL_TEST_ADDITIONAL_LIBRARIES "${BOOST_SYSTEM_LIBRARY}"
   )
 
-  ##################################################
-  # DISABLING PRECOMPILED HEADERS USAGE FOR TESTS
-  ##################################################
-  # if(USE_PRECOMPILED_HEADERS)
-  #     set_source_files_properties(
-  #       ${viewer_TEST_SOURCE_FILES}
-  #       PROPERTIES
-  #         LL_TEST_ADDITIONAL_SOURCE_FILES llviewerprecompiledheaders.cpp
-  #       )
-  # endif(USE_PRECOMPILED_HEADERS)
+  set_property( SOURCE
+          ${viewer_TEST_SOURCE_FILES}
+          PROPERTY
+          LL_TEST_ADDITIONAL_LIBRARIES ${test_libs}
+  )
+
   LL_ADD_PROJECT_UNIT_TESTS(${VIEWER_BINARY_NAME} "${viewer_TEST_SOURCE_FILES}")
 
   #set(TEST_DEBUG on)
-  ##################################################
-  # DISABLING PRECOMPILED HEADERS USAGE FOR TESTS
-  ##################################################
-  # if(USE_PRECOMPILED_HEADERS)
-  #     set(test_sources "${test_sources}" llviewerprecompiledheaders.cpp)
-  # endif(USE_PRECOMPILED_HEADERS)
-  set(test_libs
-    ${LLMESSAGE_LIBRARIES}
-    ${WINDOWS_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLCOMMON_LIBRARIES}
-    ${GOOGLEMOCK_LIBRARIES}
-    )
-
-  if (LINUX)
-    # llcommon uses `clock_gettime' which is provided by librt on linux.
-    set(LIBRT_LIBRARY
-      rt
-      )
-  endif (LINUX)
 
   set(test_libs
-    ${WINDOWS_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLCOMMON_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLCOREHTTP_LIBRARIES}
-    ${GOOGLEMOCK_LIBRARIES}
-    ${OPENSSL_LIBRARIES}
-    ${CRYPTO_LIBRARIES}
-    ${LIBRT_LIBRARY}
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-  )
+          llfilesystem
+          llmath
+          llcommon
+          llmessage
+          llcorehttp
+          llxml
+          llui
+          llplugin
+          llappearance
+          lllogin
+          llprimitive
+          lllogin
+          )
 
   LL_ADD_INTEGRATION_TEST(cppfeatures
     ""
     "${test_libs}"
     )
+
   LL_ADD_INTEGRATION_TEST(llsechandler_basic
     llsechandler_basic.cpp
     "${test_libs}"
@@ -2527,7 +2316,6 @@ if (LL_TESTS)
       llviewernetwork.cpp
   )
 
-
   LL_ADD_INTEGRATION_TEST(llslurl
      "${llslurl_test_sources}"
     "${test_libs}"
@@ -2563,15 +2351,6 @@ if (LL_TESTS)
   #ADD_VIEWER_BUILD_TEST(lltextureinfo viewer)
   #ADD_VIEWER_BUILD_TEST(lltextureinfodetails viewer)
 
-include(LLAddBuildTest)
-SET(viewer_TEST_SOURCE_FILES
-  llagentaccess.cpp
-  )
-set_source_files_properties(
-  ${viewer_TEST_SOURCE_FILES}
-  PROPERTIES
-    LL_TEST_ADDITIONAL_SOURCE_FILES llviewerprecompiledheaders.cpp
-  )
 
 endif (LL_TESTS)
 
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index eb3528b9b7f7be29e81ea738a5464869c62c890c..6b788dd78f5bc460f51b2ae1157c185314df496d 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -220,6 +220,17 @@
         <key>Value</key>
             <integer>1</integer>
         </map>
+    <key>FetchGroupChatHistory</key>
+      <map>
+        <key>Comment</key>
+        <string>Fetch recent messages from group chat servers when a group window opens</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>Boolean</string>
+        <key>Value</key>
+        <integer>1</integer>
+      </map>
     <key>VoiceCallsFriendsOnly</key>
     <map>
         <key>Comment</key>
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 5de52c1dafbc98364a39816115d1965e4555d3a3..826a4ba761e4ab01e293cf4281a351042ca14739 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -133,7 +133,6 @@ LLAgentCamera::LLAgentCamera() :
 	mCameraFOVZoomFactor(0.f),
 	mCameraCurrentFOVZoomFactor(0.f),
 	mCameraFocusOffset(),
-	mCameraFOVDefault(DEFAULT_FIELD_OF_VIEW),
 
 	mCameraCollidePlane(),
 
@@ -155,7 +154,6 @@ LLAgentCamera::LLAgentCamera() :
 	mFocusObject(NULL),
 	mFocusObjectDist(0.f),
 	mFocusObjectOffset(),
-	mFocusDotRadius( 0.1f ),			// meters
 	mTrackFocusObject(TRUE),
 
 	mAtKey(0), // Either 1, 0, or -1... indicates that movement-key is pressed
@@ -2374,6 +2372,11 @@ void LLAgentCamera::changeCameraToCustomizeAvatar()
 	gAgent.standUp(); // force stand up
 	gViewerWindow->getWindow()->resetBusyCount();
 
+    if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
+    {
+        LLSelectMgr::getInstance()->deselectAll();
+    }
+
 	if (gFaceEditToolset)
 	{
 		LLToolMgr::getInstance()->setCurrentToolset(gFaceEditToolset);
diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h
index 89680f95dc28982ffadcb0c26fcf05b54e1886a1..d27cdb0c5ca03e54c163f69f0dc1de15da6de763 100644
--- a/indra/newview/llagentcamera.h
+++ b/indra/newview/llagentcamera.h
@@ -152,7 +152,6 @@ class LLAgentCamera
 	F32				mTargetCameraDistance;			// Target camera offset from avatar
 	F32				mCameraFOVZoomFactor;			// Amount of fov zoom applied to camera when zeroing in on an object
 	F32				mCameraCurrentFOVZoomFactor;	// Interpolated fov zoom
-	F32				mCameraFOVDefault;				// Default field of view that is basis for FOV zoom effect
 	LLVector4		mCameraCollidePlane;			// Colliding plane for camera
 	F32				mCameraZoomFraction;			// Mousewheel driven fraction of zoom
 	LLVector3		mCameraPositionAgent;			// Camera position in agent coordinates
@@ -167,7 +166,6 @@ class LLAgentCamera
 	// Follow
 	//--------------------------------------------------------------------
 public:
-	void			setUsingFollowCam(bool using_follow_cam);
 	bool 			isfollowCamLocked();
 private:
 	LLFollowCam 	mFollowCam; 			// Ventrella
@@ -233,7 +231,6 @@ class LLAgentCamera
 	LLPointer<LLViewerObject> mFocusObject;
 	F32				mFocusObjectDist;
 	LLVector3		mFocusObjectOffset;
-	F32				mFocusDotRadius; 				// Meters
 	BOOL			mTrackFocusObject;
 	
 	//--------------------------------------------------------------------
diff --git a/indra/newview/llagentui.cpp b/indra/newview/llagentui.cpp
index 3410a37890505052f86db52601015e878f6f469c..c19ad2ae6f9e8158ff4147408a339dcc09a418d2 100644
--- a/indra/newview/llagentui.cpp
+++ b/indra/newview/llagentui.cpp
@@ -53,7 +53,16 @@ void LLAgentUI::buildSLURL(LLSLURL& slurl, const bool escaped /*= true*/)
       LLViewerRegion *regionp = gAgent.getRegion();
       if (regionp)
       {
-		  return_slurl = LLSLURL(regionp->getName(), gAgent.getPositionGlobal());
+          // Make sure coordinates are within current region
+          LLVector3d global_pos = gAgent.getPositionGlobal();
+          LLVector3d region_origin = regionp->getOriginGlobal();
+          // -1 otherwise slurl will fmod 256 to 0.
+          // And valid slurl range is supposed to be 0..255
+          F64 max_val = REGION_WIDTH_METERS - 1;
+          global_pos.mdV[VX] = llclamp(global_pos[VX], region_origin[VX], region_origin[VX] + max_val);
+          global_pos.mdV[VY] = llclamp(global_pos[VY], region_origin[VY], region_origin[VY] + max_val);
+
+          return_slurl = LLSLURL(regionp->getName(), global_pos);
       }
 	slurl = return_slurl;
 }
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 8a55a848db426bb2ffd4a14f63907a7e81024375..cf953d21aca1f3ea67776e07befb3b38a24b8933 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -35,6 +35,7 @@
 #include "llinventoryobserver.h"
 #include "llviewerinventory.h"
 #include "llcorehttputil.h"
+#include <memory>
 
 class LLWearableHoldingPattern;
 class LLInventoryCallback;
@@ -276,7 +277,7 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	
 	LLUUID mCOFImageID;
 
-	std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
+	std::unique_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
 
 	// Set of temp attachment UUIDs that should be removed
 	typedef std::set<LLUUID> doomed_temp_attachments_t;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 7731f37c942c09a1b2ddc6dbbd0e236c82163949..12ed123805de79b13f7e5ef0b16ebfe0ab1a1bec 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -307,7 +307,7 @@ S32 gLastExecDuration = -1; // (<0 indicates unknown)
 #   define LL_PLATFORM_KEY "mac"
 #elif LL_LINUX
 #   define LL_PLATFORM_KEY "lnx"
-else
+#else
 #   error "Unknown Platform"
 #endif
 const char* gPlatform = LL_PLATFORM_KEY;
@@ -1189,12 +1189,8 @@ bool LLAppViewer::init()
     {
         LL_WARNS("InitInfo") << "Skipping updater check." << LL_ENDL;
     }
+#endif //LL_RELEASE_FOR_DOWNLOAD
 
-    if (mUpdaterNotFound)
-    {
-        LL_WARNS("InitInfo") << "Failed to launch updater. Skipping Leap commands." << LL_ENDL;
-    }
-    else
     {
         // Iterate over --leap command-line options. But this is a bit tricky: if
         // there's only one, it won't be an array at all.
@@ -1227,7 +1223,6 @@ bool LLAppViewer::init()
                              << "lleventhost no longer supported as a dynamic library"
                              << LL_ENDL;
     }
-#endif //LL_RELEASE_FOR_DOWNLOAD
 
 	LLTextUtil::TextHelpers::iconCallbackCreationFunction = create_text_segment_icon_from_url_match;
 
@@ -5464,7 +5459,8 @@ void LLAppViewer::disconnectViewer()
     {
         gInventory.cache(gInventory.getRootFolderID(), gAgent.getID());
         if (gInventory.getLibraryRootFolderID().notNull()
-            && gInventory.getLibraryOwnerID().notNull())
+            && gInventory.getLibraryOwnerID().notNull()
+            && !mSecondInstance) // agent is unique, library isn't
         {
             gInventory.cache(
                 gInventory.getLibraryRootFolderID(),
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index a39ec7f51be6a58a43bda9da7543a0c03aca2089..6457c13ef3b6775e57ba76c9840b54d01e7bea28 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -75,7 +75,7 @@
 // Bugsplat (http://bugsplat.com) crash reporting tool
 #ifdef LL_BUGSPLAT
 #include "BugSplat.h"
-#include "reader.h"                 // JsonCpp
+#include "json/reader.h"                 // JsonCpp
 #include "llagent.h"                // for agent location
 #include "llviewerregion.h"
 #include "llvoavatarself.h"         // for agent name
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 965aa39338ffa925b2491282051c18d953830164..763943f9ccef268cb829304e2aecdd196d588358 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -78,7 +78,9 @@ static S32 cube_channel = -1;
 static S32 diffuse_channel = -1;
 static S32 bump_channel = -1;
 
-#define LL_BUMPLIST_MULTITHREADED 0 // TODO -- figure out why this doesn't work
+// Enabled after changing LLViewerTexture::mNeedsCreateTexture to an
+// LLAtomicBool; this should work just fine, now. HB
+#define LL_BUMPLIST_MULTITHREADED 1
 
 
 // static 
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp
index 4fdb86059286b13d4b12ec5fc665182b40b0dd4d..5be56660d65fb9a093d717a85ee3bb6c43f8e07e 100644
--- a/indra/newview/llestateinfomodel.cpp
+++ b/indra/newview/llestateinfomodel.cpp
@@ -74,6 +74,7 @@ bool LLEstateInfoModel::getDenyAgeUnverified()		const {	return getFlag(REGION_FL
 bool LLEstateInfoModel::getAllowVoiceChat()			const { return getFlag(REGION_FLAGS_ALLOW_VOICE); }
 bool LLEstateInfoModel::getAllowAccessOverride()	const { return getFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE); }
 bool LLEstateInfoModel::getAllowEnvironmentOverride() const { return getFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE); }
+bool LLEstateInfoModel::getDenyScriptedAgents()     const { return getFlag(REGION_FLAGS_DENY_BOTS); }
 
 void LLEstateInfoModel::setUseFixedSun(bool val)			{ setFlag(REGION_FLAGS_SUN_FIXED, 				val);	}
 void LLEstateInfoModel::setIsExternallyVisible(bool val)	{ setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE,		val);	}
@@ -83,6 +84,7 @@ void LLEstateInfoModel::setDenyAgeUnverified(bool val)		{ setFlag(REGION_FLAGS_D
 void LLEstateInfoModel::setAllowVoiceChat(bool val)		    { setFlag(REGION_FLAGS_ALLOW_VOICE,				val);	}
 void LLEstateInfoModel::setAllowAccessOverride(bool val)    { setFlag(REGION_FLAGS_ALLOW_ACCESS_OVERRIDE,   val);   }
 void LLEstateInfoModel::setAllowEnvironmentOverride(bool val) { setFlag(REGION_FLAGS_ALLOW_ENVIRONMENT_OVERRIDE, val); }
+void LLEstateInfoModel::setDenyScriptedAgents(bool val)     { setFlag(REGION_FLAGS_DENY_BOTS, val); }
 
 void LLEstateInfoModel::update(const strings_t& strings)
 {
@@ -148,6 +150,7 @@ void LLEstateInfoModel::commitEstateInfoCapsCoro(std::string url)
     body["allow_direct_teleport"] = getAllowDirectTeleport();
     body["deny_anonymous"] = getDenyAnonymous();
     body["deny_age_unverified"] = getDenyAgeUnverified();
+    body["block_bots"] = getDenyScriptedAgents();
     body["allow_voice_chat"] = getAllowVoiceChat();
     body["override_public_access"] = getAllowAccessOverride();
 
@@ -222,6 +225,7 @@ std::string LLEstateInfoModel::getInfoDump()
 	dump["allow_direct_teleport"] = getAllowDirectTeleport();
 	dump["deny_anonymous"       ] = getDenyAnonymous();
 	dump["deny_age_unverified"  ] = getDenyAgeUnverified();
+    dump["block_bots"           ] = getDenyScriptedAgents();
 	dump["allow_voice_chat"     ] = getAllowVoiceChat();
     dump["override_public_access"] = getAllowAccessOverride();
     dump["override_environment"] = getAllowEnvironmentOverride();
diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h
index d6f00c573cf11c619d9ee62917c6bde60d31938e..cfe91a2930976ffd7fe915aef048ce1f50b36877 100644
--- a/indra/newview/llestateinfomodel.h
+++ b/indra/newview/llestateinfomodel.h
@@ -57,6 +57,7 @@ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
 	bool				getAllowVoiceChat()			const;
     bool                getAllowAccessOverride()    const;
     bool                getAllowEnvironmentOverride() const;
+    bool                getDenyScriptedAgents()     const;
 
 	const std::string&	getName()					const { return mName; }
 	const LLUUID&		getOwnerID()				const { return mOwnerID; }
@@ -72,6 +73,7 @@ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
 	void setAllowVoiceChat(bool val);
     void setAllowAccessOverride(bool val);
     void setAllowEnvironmentOverride(bool val);
+    void setDenyScriptedAgents(bool val);
 
 	void setSunHour(F32 sun_hour) { mSunHour = sun_hour; }
 
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 70e843719094c41791d5ce14f34071b0bcd08c86..cdce6f71565423de4db94133ea6aa3397a79cde3 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -878,8 +878,11 @@ void LLFavoritesBarCtrl::updateButtons(bool force_update)
 		if (getChildList()->size() > 0)
 		{
 			//find last visible child to get the rightest button offset
-			child_list_const_reverse_iter_t last_visible_it = std::find_if(childs->rbegin(), childs->rend(), 
-					std::mem_fun(&LLView::getVisible));
+			child_list_const_reverse_iter_t last_visible_it =
+				std::find_if(
+					childs->rbegin(), childs->rend(), 
+					[](const child_list_t::value_type& child)
+					{ return child->getVisible(); });
 			if(last_visible_it != childs->rend())
 			{
 				last_right_edge = (*last_visible_it)->getRect().mRight;
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 014c8a4d2d2160c5af75f0bca641da4c1df77732..e63ab44e1606763b5cb82e8a41d4188537524f14 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -1213,7 +1213,7 @@ static std::string add_save_texture_filter_to_gtkchooser(GtkWindow *picker)
 	return caption;
 }
 
-BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
+BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking )
 {
 	BOOL rtn = FALSE;
 
@@ -1433,7 +1433,7 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter, bool blocking)
 // Hacky stubs designed to facilitate fake getSaveFile and getOpenFile with
 // static results, when we don't have a real filepicker.
 
-BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
+BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename, bool blocking )
 {
 	// if local file browsing is turned off, return without opening dialog
 	// (Even though this is a stub, I think we still should not return anything at all)
diff --git a/indra/newview/llfloater360capture.cpp b/indra/newview/llfloater360capture.cpp
index eff94bd1951a0422e7e55da75bef1880c4e13d7f..542a1ea39ba93926cb7b1241e6fc2e32ce3bd7d3 100644
--- a/indra/newview/llfloater360capture.cpp
+++ b/indra/newview/llfloater360capture.cpp
@@ -898,8 +898,10 @@ const std::string LLFloater360Capture::generate_proposed_filename()
         // this looks complex but it's straightforward - removes all non-alpha chars from a string
         // which in this case is the SL region name - we use it as a proposed filename but the user is free to change
         std::string region_name = region->getName();
-        std::replace_if(region_name.begin(), region_name.end(), std::not1(std::ptr_fun(isalnum)), '_');
-        if (region_name.length() > 0)
+        std::replace_if(region_name.begin(), region_name.end(),
+                        [](char c){ return ! std::isalnum(c); },
+                        '_');
+        if (! region_name.empty())
         {
             filename << region_name;
             filename << "_";
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 0186c4aebefa2dea030c0d903de74a928bc164ee..2422596f60ae1312bc55bda66cc281b1ae2e2db0 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -428,13 +428,18 @@ void LLFloaterAvatarPicker::findCoro(std::string url, LLUUID queryID, std::strin
 
     if (status || (status == LLCore::HttpStatus(HTTP_BAD_REQUEST)))
     {
-        LLFloaterAvatarPicker* floater =
-            LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", name);
-        if (floater)
-        {
-            result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
-            floater->processResponse(queryID, result);
-        }
+        result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+    }
+    else
+    {
+        result["failure_reason"] = status.toString();
+    }
+
+    LLFloaterAvatarPicker* floater =
+        LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", name);
+    if (floater)
+    {
+        floater->processResponse(queryID, result);
     }
 }
 
@@ -672,59 +677,67 @@ void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD&
 	{
 		LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults");
 
-		LLSD agents = content["agents"];
-
-		// clear "Searching" label on first results
-		search_results->deleteAllItems();
-
-		LLSD item;
-		LLSD::array_const_iterator it = agents.beginArray();
-		for ( ; it != agents.endArray(); ++it)
-		{
-			const LLSD& row = *it;
-			if (row["id"].asUUID() != gAgent.getID() || !mExcludeAgentFromSearchResults)
-			{
-				item["id"] = row["id"];
-				LLSD& columns = item["columns"];
-				columns[0]["column"] = "name";
-				columns[0]["value"] = row["display_name"];
-				columns[1]["column"] = "username";
-				columns[1]["value"] = row["username"];
-				search_results->addElement(item);
-
-				// add the avatar name to our list
-				LLAvatarName avatar_name;
-				avatar_name.fromLLSD(row);
-				sAvatarNameMap[row["id"].asUUID()] = avatar_name;
-			}
-		}
+        // clear "Searching" label on first results
+        search_results->deleteAllItems();
 
-		if (search_results->isEmpty())
-		{
-			std::string name = "'" + getChild<LLUICtrl>("Edit")->getValue().asString() + "'";
-			LLSD item;
-			item["id"] = LLUUID::null;
-			item["columns"][0]["column"] = "name";
-			item["columns"][0]["value"] = name;
-			item["columns"][1]["column"] = "username";
-			item["columns"][1]["value"] = getString("not_found_text");
-			search_results->addElement(item);
-			search_results->setEnabled(false);
-			getChildView("ok_btn")->setEnabled(false);
-		}
-		else
-		{
-			getChildView("ok_btn")->setEnabled(true);
-			search_results->setEnabled(true);
-			search_results->sortByColumnIndex(1, TRUE);
-			std::string text = getChild<LLUICtrl>("Edit")->getValue().asString();
-			if (!search_results->selectItemByLabel(text, TRUE, 1))
-			{
-				search_results->selectFirstItem();
-			}			
-			onList();
-			search_results->setFocus(TRUE);
-		}
+        if (content.has("failure_reason"))
+        {
+            getChild<LLScrollListCtrl>("SearchResults")->setCommentText(content["failure_reason"].asString());
+            getChildView("ok_btn")->setEnabled(false);
+        }
+        else
+        {
+            LLSD agents = content["agents"];
+
+            LLSD item;
+            LLSD::array_const_iterator it = agents.beginArray();
+            for (; it != agents.endArray(); ++it)
+            {
+                const LLSD& row = *it;
+                if (row["id"].asUUID() != gAgent.getID() || !mExcludeAgentFromSearchResults)
+                {
+                    item["id"] = row["id"];
+                    LLSD& columns = item["columns"];
+                    columns[0]["column"] = "name";
+                    columns[0]["value"] = row["display_name"];
+                    columns[1]["column"] = "username";
+                    columns[1]["value"] = row["username"];
+                    search_results->addElement(item);
+
+                    // add the avatar name to our list
+                    LLAvatarName avatar_name;
+                    avatar_name.fromLLSD(row);
+                    sAvatarNameMap[row["id"].asUUID()] = avatar_name;
+                }
+            }
+
+            if (search_results->isEmpty())
+            {
+                std::string name = "'" + getChild<LLUICtrl>("Edit")->getValue().asString() + "'";
+                LLSD item;
+                item["id"] = LLUUID::null;
+                item["columns"][0]["column"] = "name";
+                item["columns"][0]["value"] = name;
+                item["columns"][1]["column"] = "username";
+                item["columns"][1]["value"] = getString("not_found_text");
+                search_results->addElement(item);
+                search_results->setEnabled(false);
+                getChildView("ok_btn")->setEnabled(false);
+            }
+            else
+            {
+                getChildView("ok_btn")->setEnabled(true);
+                search_results->setEnabled(true);
+                search_results->sortByColumnIndex(1, TRUE);
+                std::string text = getChild<LLUICtrl>("Edit")->getValue().asString();
+                if (!search_results->selectItemByLabel(text, TRUE, 1))
+                {
+                    search_results->selectFirstItem();
+                }
+                onList();
+                search_results->setFocus(TRUE);
+            }
+        }
 	}
 }
 
diff --git a/indra/newview/llfloateravatarrendersettings.cpp b/indra/newview/llfloateravatarrendersettings.cpp
index b8f854feb327cb1e6dd569256c0969e074934c0d..8b28f6941ef66653c67fcc67cc57bdc8235e5d5b 100644
--- a/indra/newview/llfloateravatarrendersettings.cpp
+++ b/indra/newview/llfloateravatarrendersettings.cpp
@@ -89,6 +89,7 @@ BOOL LLFloaterAvatarRenderSettings::postBuild()
     LLFloater::postBuild();
     mAvatarSettingsList = getChild<LLNameListCtrl>("render_settings_list");
     mAvatarSettingsList->setRightMouseDownCallback(boost::bind(&LLFloaterAvatarRenderSettings::onAvatarListRightClick, this, _1, _2, _3));
+    mAvatarSettingsList->setAlternateSort();
     getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterAvatarRenderSettings::onFilterEdit, this, _2));
 
 	return TRUE;
@@ -138,8 +139,8 @@ void LLFloaterAvatarRenderSettings::updateList()
             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");
-            std::string timestamp = createTimestamp(LLRenderMuteList::getInstance()->getVisualMuteDate(iter->first));
-            item_params.columns.add().value(timestamp).column("timestamp");
+            S32 mute_date = LLRenderMuteList::getInstance()->getVisualMuteDate(iter->first);
+            item_params.columns.add().value(createTimestamp(mute_date)).column("timestamp").alt_value(std::to_string(mute_date));
             mAvatarSettingsList->addNameItemRow(item_params);
         }
     }
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
index 3b0c67415a35883eb8fe01973d01f5a061836842..19bc865d8b92635bda1afa4cbc16a13e69b9ddf4 100644
--- a/indra/newview/llfloaterdisplayname.cpp
+++ b/indra/newview/llfloaterdisplayname.cpp
@@ -47,6 +47,7 @@ class LLFloaterDisplayName : public LLFloater
 	virtual ~LLFloaterDisplayName() { }
 	/*virtual*/	BOOL	postBuild();
 	void onSave();
+	void onReset();
 	void onCancel();
 	/*virtual*/ void onOpen(const LLSD& key);
 	
@@ -101,6 +102,7 @@ void LLFloaterDisplayName::onOpen(const LLSD& key)
 
 BOOL LLFloaterDisplayName::postBuild()
 {
+	getChild<LLUICtrl>("reset_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onReset, this));	
 	getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onCancel, this));	
 	getChild<LLUICtrl>("save_btn")->setCommitCallback(boost::bind(&LLFloaterDisplayName::onSave, this));	
 	
@@ -156,6 +158,20 @@ void LLFloaterDisplayName::onCancel()
 	setVisible(false);
 }
 
+void LLFloaterDisplayName::onReset()
+{
+    LLAvatarName av_name;
+    if (!LLAvatarNameCache::get(gAgent.getID(), &av_name))
+    {
+        return;
+    }
+    getChild<LLUICtrl>("display_name_editor")->setValue(av_name.getCompleteName());
+
+    getChild<LLUICtrl>("display_name_confirm")->clear();
+    getChild<LLUICtrl>("display_name_confirm")->setFocus(TRUE);
+}
+
+
 void LLFloaterDisplayName::onSave()
 {
 	std::string display_name_utf8 = getChild<LLUICtrl>("display_name_editor")->getValue().asString();
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index 07d4dcae38f766ea2fc2e3dcd3fa4e170af1f133..da7a4733c7dab78f244349c905fdef9ca8c5494c 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -657,13 +657,11 @@ void LLFloaterRegionInfo::refreshFromRegion(LLViewerRegion* region)
 	}
 
 	// call refresh from region on all panels
-	std::for_each(
-		mInfoPanels.begin(),
-		mInfoPanels.end(),
-		llbind2nd(
-			std::mem_fun(&LLPanelRegionInfo::refreshFromRegion),
-			region));
-    mEnvironmentPanel->refreshFromRegion(region);
+	for (const auto& infoPanel : mInfoPanels)
+	{
+		infoPanel->refreshFromRegion(region);
+	}
+	mEnvironmentPanel->refreshFromRegion(region);
 }
 
 // public
@@ -1882,6 +1880,7 @@ BOOL LLPanelEstateInfo::postBuild()
 	initCtrl("allow_direct_teleport");
 	initCtrl("limit_payment");
 	initCtrl("limit_age_verified");
+    initCtrl("limit_bots");
 	initCtrl("voice_chat_check");
     initCtrl("parcel_access_override");
 
@@ -1905,12 +1904,14 @@ void LLPanelEstateInfo::refresh()
 	getChildView("Only Allow")->setEnabled(public_access);
 	getChildView("limit_payment")->setEnabled(public_access);
 	getChildView("limit_age_verified")->setEnabled(public_access);
+    getChildView("limit_bots")->setEnabled(public_access);
 
 	// if this is set to false, then the limit fields are meaningless and should be turned off
 	if (public_access == false)
 	{
 		getChild<LLUICtrl>("limit_payment")->setValue(false);
 		getChild<LLUICtrl>("limit_age_verified")->setValue(false);
+        getChild<LLUICtrl>("limit_bots")->setValue(false);
 	}
 }
 
@@ -1927,6 +1928,7 @@ void LLPanelEstateInfo::refreshFromEstate()
 	getChild<LLUICtrl>("limit_payment")->setValue(estate_info.getDenyAnonymous());
 	getChild<LLUICtrl>("limit_age_verified")->setValue(estate_info.getDenyAgeUnverified());
     getChild<LLUICtrl>("parcel_access_override")->setValue(estate_info.getAllowAccessOverride());
+    getChild<LLUICtrl>("limit_bots")->setValue(estate_info.getDenyScriptedAgents());
 
 	// Ensure appriopriate state of the management UI
 	updateControls(gAgent.getRegion());
@@ -1970,6 +1972,7 @@ bool LLPanelEstateInfo::callbackChangeLindenEstate(const LLSD& notification, con
 			estate_info.setDenyAgeUnverified(getChild<LLUICtrl>("limit_age_verified")->getValue().asBoolean());
 			estate_info.setAllowVoiceChat(getChild<LLUICtrl>("voice_chat_check")->getValue().asBoolean());
             estate_info.setAllowAccessOverride(getChild<LLUICtrl>("parcel_access_override")->getValue().asBoolean());
+            estate_info.setDenyScriptedAgents(getChild<LLUICtrl>("limit_bots")->getValue().asBoolean());
             // JIGGLYPUFF
             //estate_info.setAllowAccessOverride(getChild<LLUICtrl>("")->getValue().asBoolean());
 			// send the update to sim
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 489d34edca403173a755b0e3479a911c678f6223..c0f773968d1be210ebb171d973dbc1e4f0244781 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -757,11 +757,11 @@ S32 LLGestureMgr::getPlayingCount() const
 }
 
 
-struct IsGesturePlaying : public std::unary_function<LLMultiGesture*, bool>
+struct IsGesturePlaying
 {
 	bool operator()(const LLMultiGesture* gesture) const
 	{
-		return gesture->mPlaying ? true : false;
+		return bool(gesture->mPlaying);
 	}
 };
 
diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp
index 9c78e48cab66808487e43d61248f8ec95a4073d0..57a67f52f6238c2488e643a7dd6d2a570d37bb1e 100644
--- a/indra/newview/llgltfmateriallist.cpp
+++ b/indra/newview/llgltfmateriallist.cpp
@@ -554,8 +554,6 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp
         LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop");
         LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General");
 
-        typedef std::pair<U32, tinygltf::Model> return_data_t;
-
         main_queue->postTo(
             general_queue,
             [id, asset_type, asset_data]() // Work done on general queue
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index e2d63ecc0aa37a3c4a14c98d616b27d88b82eb98..0408cfc659a713b458b982051413347bd8ec273b 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -56,7 +56,6 @@ const F32 HORIZONTAL_PADDING = 16.f;
 const F32 VERTICAL_PADDING = 12.f;
 const F32 LINE_PADDING = 3.f;			// aka "leading"
 const F32 BUFFER_SIZE = 2.f;
-const F32 HUD_TEXT_MAX_WIDTH = 190.f;
 const S32 NUM_OVERLAP_ITERATIONS = 10;
 const F32 POSITION_DAMPING_TC = 0.2f;
 const F32 MAX_STABLE_CAMERA_VELOCITY = 0.1f;
@@ -67,6 +66,8 @@ const F32 LOD_2_SCREEN_COVERAGE = 0.40f;
 std::set<LLPointer<LLHUDNameTag> > LLHUDNameTag::sTextObjects;
 std::vector<LLPointer<LLHUDNameTag> > LLHUDNameTag::sVisibleTextObjects;
 BOOL LLHUDNameTag::sDisplayText = TRUE ;
+const F32 LLHUDNameTag::NAMETAG_MAX_WIDTH = 298.f;
+const F32 LLHUDNameTag::HUD_TEXT_MAX_WIDTH = 190.f;
 
 bool llhudnametag_further_away::operator()(const LLPointer<LLHUDNameTag>& lhs, const LLPointer<LLHUDNameTag>& rhs) const
 {
@@ -414,7 +415,8 @@ void LLHUDNameTag::addLine(const std::string &text_utf8,
 						const LLColor4& color,
 						const LLFontGL::StyleFlags style,
 						const LLFontGL* font,
-						const bool use_ellipses)
+						const bool use_ellipses,
+						F32 max_pixels)
 {
 	LLWString wline = utf8str_to_wstring(text_utf8);
 	if (!wline.empty())
@@ -431,7 +433,7 @@ void LLHUDNameTag::addLine(const std::string &text_utf8,
 		tokenizer tokens(wline, sep);
 		tokenizer::iterator iter = tokens.begin();
 
-        const F32 max_pixels = HUD_TEXT_MAX_WIDTH;
+        max_pixels = llmin(max_pixels, NAMETAG_MAX_WIDTH);
         while (iter != tokens.end())
         {
             U32 line_length = 0;
@@ -488,7 +490,7 @@ void LLHUDNameTag::setLabel(const std::string &label_utf8)
 	addLabel(label_utf8);
 }
 
-void LLHUDNameTag::addLabel(const std::string& label_utf8)
+void LLHUDNameTag::addLabel(const std::string& label_utf8, F32 max_pixels)
 {
 	LLWString wstr = utf8string_to_wstring(label_utf8);
 	if (!wstr.empty())
@@ -502,13 +504,15 @@ void LLHUDNameTag::addLabel(const std::string& label_utf8)
 		tokenizer tokens(wstr, sep);
 		tokenizer::iterator iter = tokens.begin();
 
+        max_pixels = llmin(max_pixels, NAMETAG_MAX_WIDTH);
+
 		while (iter != tokens.end())
 		{
 			U32 line_length = 0;
 			do	
 			{
 				S32 segment_length = mFontp->maxDrawableChars(iter->substr(line_length).c_str(), 
-					HUD_TEXT_MAX_WIDTH, wstr.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE);
+                    max_pixels, wstr.length(), LLFontGL::WORD_BOUNDARY_IF_POSSIBLE);
 				LLHUDTextSegment segment(iter->substr(line_length, segment_length), LLFontGL::NORMAL, mColor, mFontp);
 				mLabelSegments.push_back(segment);
 				line_length += segment_length;
@@ -695,7 +699,7 @@ void LLHUDNameTag::updateSize()
 		const LLFontGL* fontp = iter->mFont;
 		height += fontp->getLineHeight();
 		height += LINE_PADDING;
-		width = llmax(width, llmin(iter->getWidth(fontp), HUD_TEXT_MAX_WIDTH));
+		width = llmax(width, llmin(iter->getWidth(fontp), NAMETAG_MAX_WIDTH));
 		++iter;
 	}
 
@@ -709,7 +713,7 @@ void LLHUDNameTag::updateSize()
 	while (iter != mLabelSegments.end())
 	{
 		height += mFontp->getLineHeight();
-		width = llmax(width, llmin(iter->getWidth(mFontp), HUD_TEXT_MAX_WIDTH));
+		width = llmax(width, llmin(iter->getWidth(mFontp), NAMETAG_MAX_WIDTH));
 		++iter;
 	}
 	
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 7577dd5de66b6946d756d8c1ed838b32209f6306..361e4d4f4b50598afa0203ae452f038f786685e0 100644
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -85,6 +85,9 @@ class LLHUDNameTag : public LLHUDObject
 		ALIGN_VERT_CENTER
 	} EVertAlignment;
 
+    static const F32 NAMETAG_MAX_WIDTH; // 298px, made to fit 31 M's
+    static const F32 HUD_TEXT_MAX_WIDTH; // 190px
+
 public:
 	// Set entire string, eliminating existing lines
 	void setString(const std::string& text_utf8);
@@ -92,11 +95,17 @@ class LLHUDNameTag : public LLHUDObject
 	void clearString();
 
 	// Add text a line at a time, allowing custom formatting
-	void addLine(const std::string &text_utf8, const LLColor4& color, const LLFontGL::StyleFlags style = LLFontGL::NORMAL, const LLFontGL* font = NULL, const bool use_ellipses = false);
+	void addLine(
+        const std::string &text_utf8,
+        const LLColor4& color,
+        const LLFontGL::StyleFlags style = LLFontGL::NORMAL,
+        const LLFontGL* font = NULL,
+        const bool use_ellipses = false,
+        F32 max_pixels = HUD_TEXT_MAX_WIDTH);
 
 	// For bubble chat, set the part above the chat text
 	void setLabel(const std::string& label_utf8);
-	void addLabel(const std::string& label_utf8);
+	void addLabel(const std::string& label_utf8, F32 max_pixels = HUD_TEXT_MAX_WIDTH);
 
 	// Sets the default font for lines with no font specified
 	void setFont(const LLFontGL* font);
diff --git a/indra/newview/llimprocessing.cpp b/indra/newview/llimprocessing.cpp
index af2d168aefef8211ef667cd3234a86241ce0934f..3536b839899ead94b282bca2740747456a14e6be 100644
--- a/indra/newview/llimprocessing.cpp
+++ b/indra/newview/llimprocessing.cpp
@@ -453,7 +453,7 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
     BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
     BOOL accept_im_from_only_friend = gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly");
     BOOL is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
-        LLMuteList::getInstance()->isLinden(name);
+        LLMuteList::isLinden(name);
 
     chat.mMuted = is_muted;
     chat.mFromID = from_id;
@@ -521,7 +521,9 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
                     dialog,
                     parent_estate_id,
                     region_id,
-                    position);
+                    position,
+                    false,      // is_region_msg
+                    timestamp);
 
                 if (!gIMMgr->isDNDMessageSend(session_id))
                 {
@@ -592,7 +594,8 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
                         parent_estate_id,
                         region_id,
                         position,
-                        region_message);
+                        region_message,
+                        timestamp);
                 }
                 else
                 {
@@ -1111,7 +1114,9 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
                     IM_SESSION_INVITE,
                     parent_estate_id,
                     region_id,
-                    position);
+                    position,
+                    false,      // is_region_msg
+                    timestamp);
             }
             else
             {
@@ -1131,12 +1136,14 @@ void LLIMProcessing::processNewMessage(LLUUID from_id,
                     from_id,
                     name,
                     buffer,
-                    IM_OFFLINE == offline,
-                    ll_safe_string((char*)binary_bucket),
+                    (IM_OFFLINE == offline),
+                    ll_safe_string((char*)binary_bucket),   // session name
                     IM_SESSION_INVITE,
                     parent_estate_id,
                     region_id,
-                    position);
+                    position,
+                    false,      // is_region_msg
+                    timestamp);
             }
             break;
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 3607e49b4abbc8bf3dc573a981da8f227b95b830..6880cf217189e663448827cfef7a99394b3909fa 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -1,25 +1,25 @@
-/** 
+/**
  * @file LLIMMgr.cpp
  * @brief Container for Instant Messaging
  *
  * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
@@ -41,6 +41,7 @@
 #include "llstring.h"
 #include "lltextutil.h"
 #include "lltrans.h"
+#include "lltranslate.h"
 #include "lluictrlfactory.h"
 #include "llfloaterimsessiontab.h"
 #include "llagent.h"
@@ -76,11 +77,17 @@ const static std::string ADHOC_NAME_SUFFIX(" Conference");
 const static std::string NEARBY_P2P_BY_OTHER("nearby_P2P_by_other");
 const static std::string NEARBY_P2P_BY_AGENT("nearby_P2P_by_agent");
 
+// Markers inserted around translated part of chat text
+const static std::string XL8_START_TAG(" (");
+const static std::string XL8_END_TAG(")");
+const S32 XL8_PADDING = 3;  // XL8_START_TAG.size() + XL8_END_TAG.size()
+
 /** Timeout of outgoing session initialization (in seconds) */
 const static U32 SESSION_INITIALIZATION_TIMEOUT = 30;
 
 void startConfrenceCoro(std::string url, LLUUID tempSessionId, LLUUID creatorId, LLUUID otherParticipantId, LLSD agents);
 void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvitationType invitationType);
+void chatterBoxHistoryCoro(std::string url, LLUUID sessionId, std::string from, std::string message, U32 timestamp);
 void start_deprecated_conference_chat(const LLUUID& temp_session_id, const LLUUID& creator_id, const LLUUID& other_participant_id, const LLSD& agents_to_invite);
 
 const LLUUID LLOutgoingCallDialog::OCD_KEY = LLUUID("7CF78E11-0CFE-498D-ADB9-1417BF03DDB4");
@@ -111,7 +118,7 @@ void process_dnd_im(const LLSD& notification)
     LLUUID sessionID = data["SESSION_ID"].asUUID();
     LLUUID fromID = data["FROM_ID"].asUUID();
 
-    //re-create the IM session if needed 
+    //re-create the IM session if needed
     //(when coming out of DND mode upon app restart)
     if(!gIMMgr->hasSession(sessionID))
     {
@@ -122,13 +129,13 @@ void process_dnd_im(const LLSD& notification)
         {
             name = av_name.getDisplayName();
         }
-		
-        
-        LLIMModel::getInstance()->newSession(sessionID, 
-            name, 
-            IM_NOTHING_SPECIAL, 
-            fromID, 
-            false, 
+
+
+        LLIMModel::getInstance()->newSession(sessionID,
+            name,
+            IM_NOTHING_SPECIAL,
+            fromID,
+            false,
             false); //will need slight refactor to retrieve whether offline message or not (assume online for now)
     }
 
@@ -311,8 +318,8 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg)
 			}
 			else
 			{
-				if (is_dnd_msg && (ON_TOP == conversations_floater_status || 
-									NOT_ON_TOP == conversations_floater_status || 
+				if (is_dnd_msg && (ON_TOP == conversations_floater_status ||
+									NOT_ON_TOP == conversations_floater_status ||
 									CLOSED == conversations_floater_status))
 				{
 					im_box->highlightConversationItemWidget(session_id, true);
@@ -371,7 +378,7 @@ void notify_of_message(const LLSD& msg, bool is_dnd_msg)
 	}
 	if (store_dnd_message)
 	{
-		// If in DND mode, allow notification to be stored so upon DND exit 
+		// If in DND mode, allow notification to be stored so upon DND exit
 		// the user will be notified with some limitations (see 'is_dnd_msg' flag checks)
 		if(session_id.notNull()
 			&& participant_id.notNull()
@@ -392,7 +399,7 @@ void startConfrenceCoro(std::string url,
 {
     LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
     LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ConferenceChatStart", httpPolicy));
     LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
 
     LLSD postData;
@@ -432,7 +439,7 @@ void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvit
 {
     LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
     LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("TwitterConnect", httpPolicy));
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ConferenceInviteStart", httpPolicy));
     LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
 
     LLSD postData;
@@ -510,8 +517,124 @@ void chatterBoxInvitationCoro(std::string url, LLUUID sessionId, LLIMMgr::EInvit
 
 }
 
+void translateSuccess(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text,
+                        U64 time_n_flags, std::string originalMsg, std::string expectLang, std::string translation, const std::string detected_language)
+{
+    std::string message_txt(utf8_text);
+    // filter out non-interesting responses
+    if (!translation.empty()
+        && ((detected_language.empty()) || (expectLang != detected_language))
+        && (LLStringUtil::compareInsensitive(translation, originalMsg) != 0))
+    {   // Note - if this format changes, also fix code in addMessagesFromServerHistory()
+        message_txt += XL8_START_TAG + LLTranslate::removeNoTranslateTags(translation) + XL8_END_TAG;
+    }
+
+    // Extract info packed in time_n_flags
+    bool log2file =      (bool)(time_n_flags & (1LL << 32));
+    bool is_region_msg = (bool)(time_n_flags & (1LL << 33));
+    U32 time_stamp = (U32)(time_n_flags & 0x00000000ffffffff);
+
+    LLIMModel::getInstance()->processAddingMessage(session_id, from, from_id, message_txt, log2file, is_region_msg, time_stamp);
+}
+
+void translateFailure(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text,
+                        U64 time_n_flags, int status, const std::string err_msg)
+{
+    std::string message_txt(utf8_text);
+    std::string msg = LLTrans::getString("TranslationFailed", LLSD().with("[REASON]", err_msg));
+    LLStringUtil::replaceString(msg, "\n", " "); // we want one-line error messages
+    message_txt += XL8_START_TAG + msg + XL8_END_TAG;
+
+    // Extract info packed in time_n_flags
+    bool log2file = (bool)(time_n_flags & (1LL << 32));
+    bool is_region_msg = (bool)(time_n_flags & (1LL << 33));
+    U32 time_stamp = (U32)(time_n_flags & 0x00000000ffffffff);
+
+    LLIMModel::getInstance()->processAddingMessage(session_id, from, from_id, message_txt, log2file, is_region_msg, time_stamp);
+}
+
+void chatterBoxHistoryCoro(std::string url, LLUUID sessionId, std::string from, std::string message, U32 timestamp)
+{   // if parameters from, message and timestamp have values, they are a message that opened chat
+    LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("ChatHistory", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+    LLSD postData;
+    postData["method"] = "fetch history";
+    postData["session-id"] = sessionId;
+
+    LL_DEBUGS("ChatHistory") << sessionId << ": Chat history posting " << postData << " to " << url
+        << ", from " << from << ", message " << message << ", timestamp " << (S32)timestamp << LL_ENDL;
+
+    LLSD result = httpAdapter->postAndSuspend(httpRequest, url, postData);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        LL_WARNS("ChatHistory") << sessionId << ": Bad HTTP response in chatterBoxHistoryCoro"
+            << ", results: " << httpResults << LL_ENDL;
+        return;
+    }
+
+    // Add history to IM session
+    LLSD history = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_CONTENT];
+
+    LL_DEBUGS("ChatHistory") << sessionId << ": Chat server history fetch returned " << history << LL_ENDL;
+
+    try
+    {
+        LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(sessionId);
+        if (session && history.isArray())
+        {   // Result array is sorted oldest to newest
+            if (history.size() > 0)
+            {   // History from the chat server has an integer 'time' value timestamp.   Create 'datetime' string which will match
+                // what we have from the local history cache
+                for (LLSD::array_iterator cur_server_hist = history.beginArray(), endLists = history.endArray();
+                    cur_server_hist != endLists;
+                    cur_server_hist++)
+                {
+                    if ((*cur_server_hist).isMap())
+                    {   // Take the 'time' value from the server and make the date-time string that will be in local cache log files
+                        //   {'from_id':u7aa8c222-8a81-450e-b3d1-9c28491ef717,'message':'Can you hear me now?','from':'Chat Tester','num':i86,'time':r1.66501e+09}
+                        U32 timestamp = (U32)((*cur_server_hist)[LL_IM_TIME].asInteger());
+                        (*cur_server_hist)[LL_IM_DATE_TIME] = LLLogChat::timestamp2LogString(timestamp, true);
+                    }
+                }
+
+                session->addMessagesFromServerHistory(history, from, message, timestamp);
+
+                // Display the newly added messages
+                LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", sessionId);
+                if (floater && floater->isInVisibleChain())
+                {
+                    floater->updateMessages();
+                }
+            }
+            else
+            {
+                LL_DEBUGS("ChatHistory") << sessionId << ": Empty history from chat server, nothing to add" << LL_ENDL;
+            }
+        }
+        else if (session && !history.isArray())
+        {
+            LL_WARNS("ChatHistory") << sessionId << ": Bad array data fetching chat history" << LL_ENDL;
+        }
+        else
+        {
+            LL_WARNS("ChatHistory") << sessionId << ": Unable to find session fetching chat history" << LL_ENDL;
+        }
+    }
+    catch (...)
+    {
+        LOG_UNHANDLED_EXCEPTION("chatterBoxHistoryCoro");
+        LL_WARNS("ChatHistory") << "chatterBoxHistoryCoro unhandled exception while processing data for session " << sessionId << LL_ENDL;
+    }
+}
 
-LLIMModel::LLIMModel() 
+LLIMModel::LLIMModel()
 {
 	addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1));
 	addNewMsgCallback(boost::bind(&on_new_message, _1));
@@ -556,25 +679,25 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 		else
 		{
 			mSessionType = ADHOC_SESSION;
-		} 
+		}
 	}
 
 	if(mVoiceChannel)
 	{
 		mVoiceChannelStateChangeConnection = mVoiceChannel->setStateChangedCallback(boost::bind(&LLIMSession::onVoiceChannelStateChanged, this, _1, _2, _3));
 	}
-		
+
 	mSpeakers = new LLIMSpeakerMgr(mVoiceChannel);
 
 	// All participants will be added to the list of people we've recently interacted with.
 
-	// we need to add only _active_ speakers...so comment this. 
+	// we need to add only _active_ speakers...so comment this.
 	// may delete this later on cleanup
 	//mSpeakers->addListener(&LLRecentPeople::instance(), "add");
 
 	//we need to wait for session initialization for outgoing ad-hoc and group chat session
 	//correct session id for initiated ad-hoc chat will be received from the server
-	if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID, 
+	if (!LLIMModel::getInstance()->sendStartSession(mSessionID, mOtherParticipantID,
 		mInitialTargetIDs, mType))
 	{
 		//we don't need to wait for any responses
@@ -656,7 +779,7 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
 					LLStringUtil::format_map_t string_args;
 					string_args["[NAME]"] = other_avatar_name;
 					message = LLTrans::getString("name_started_call", string_args);
-					LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message);				
+					LLIMModel::getInstance()->addMessage(mSessionID, SYSTEM_FROM, LLUUID::null, message);
 					break;
 				}
 			case LLVoiceChannel::STATE_CONNECTED :
@@ -760,14 +883,21 @@ void LLIMModel::LLIMSession::sessionInitReplyReceived(const LLUUID& new_session_
 	}
 }
 
-void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history, bool is_region_msg)
+void LLIMModel::LLIMSession::addMessage(const std::string& from,
+                                        const LLUUID& from_id,
+                                        const std::string& utf8_text,
+                                        const std::string& time,
+                                        const bool is_history,  // comes from a history file or chat server
+                                        const bool is_region_msg,
+                                        const U32 timestamp)   // may be zero
 {
 	LLSD message;
 	message["from"] = from;
 	message["from_id"] = from_id;
 	message["message"] = utf8_text;
-	message["time"] = time; 
-	message["index"] = (LLSD::Integer)mMsgs.size(); 
+	message["time"] = time;         // string used in display, may be full data YYYY/MM/DD HH:MM or just HH:MM
+    message["timestamp"] = (S32)timestamp;          // use string? LLLogChat::timestamp2LogString(timestamp, true);
+	message["index"] = (LLSD::Integer)mMsgs.size();
 	message["is_history"] = is_history;
 	message["is_region_msg"] = is_region_msg;
 
@@ -788,7 +918,7 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f
 		}
 	}
 
-	mMsgs.push_front(message); 
+	mMsgs.push_front(message);          // Add most recent messages to the front of mMsgs
 
 	if (mSpeakers && from_id.notNull())
 	{
@@ -797,35 +927,281 @@ void LLIMModel::LLIMSession::addMessage(const std::string& from, const LLUUID& f
 	}
 }
 
-void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& history)
+void LLIMModel::LLIMSession::addMessagesFromHistoryCache(const chat_message_list_t& history)
 {
-	std::list<LLSD>::const_iterator it = history.begin();
-	while (it != history.end())
-	{
-		const LLSD& msg = *it;
+    // Add the messages from the local cached chat history to the session window
+    for (const auto& msg : history)
+    {
+        std::string from = msg[LL_IM_FROM];
+        LLUUID from_id;
+        if (msg[LL_IM_FROM_ID].isDefined())
+        {
+            from_id = msg[LL_IM_FROM_ID].asUUID();
+        }
+        else
+        {   // convert it to a legacy name if we have a complete name
+            std::string legacy_name = gCacheName->buildLegacyName(from);
+            from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);
+        }
 
-		std::string from = msg[LL_IM_FROM];
-		LLUUID from_id;
-		if (msg[LL_IM_FROM_ID].isDefined())
-		{
-			from_id = msg[LL_IM_FROM_ID].asUUID();
-		}
-		else
-		{
-			// convert it to a legacy name if we have a complete name
-			std::string legacy_name = gCacheName->buildLegacyName(from);
-			from_id = LLAvatarNameCache::getInstance()->findIdByName(legacy_name);
-		}
+        // Save the last minute of messages so we can merge with the chat server history.
+        // Really would be nice to have a numeric timestamp in the local cached chat file
+        const std::string & msg_time_str = msg[LL_IM_DATE_TIME].asString();
+        if (mLastHistoryCacheDateTime != msg_time_str)
+        {
+            mLastHistoryCacheDateTime = msg_time_str;   // Reset to the new time
+            mLastHistoryCacheMsgs.clear();
+        }
+        mLastHistoryCacheMsgs.push_front(msg);
+        LL_DEBUGS("ChatHistory") << mSessionID << ": Adding history cache message: " << msg << LL_ENDL;
 
-		std::string timestamp = msg[LL_IM_TIME];
-		std::string text = msg[LL_IM_TEXT];
+        // Add message from history cache to the display
+        addMessage(from, from_id, msg[LL_IM_TEXT], msg[LL_IM_TIME], true, false, 0);   // from history data, not region message, no timestamp
+    }
+}
 
-		addMessage(from, from_id, text, timestamp, true);
+void LLIMModel::LLIMSession::addMessagesFromServerHistory(const LLSD& history,             // Array of chat messages from chat server
+                                                        const std::string& target_from,    // Sender of message that opened chat
+                                                        const std::string& target_message, // Message text that opened chat
+                                                        U32 timestamp)                     // timestamp of message that opened chat
+{   // Add messages from history returned by the chat server.
+
+    // The session mMsgs may contain chat messages from the local history cache file, and possibly one or more newly
+    // arrived chat messages.   If the chat window was manually opened, these will be empty and history can
+    // more easily merged.    The history from the server, however, may overlap what is in the file and those must also be merged.
+
+    // At this point, the session mMsgs can have
+    //   no messages
+    //   nothing from history file cache, but one or more very recently arrived messages,
+    //   messages from history file cache, no recent chat
+    //   messages from history file cache, one or more very recent messages
+    //
+    // The chat history from server can possibly contain:
+    //   no messages
+    //   messages that start back before anything in the local file (obscure case, but possible)
+    //   messages that match messages from the history file cache
+    //   messages from the last hour, new to the viewer
+    //   one or more messages that match most recently received chat (the one that opened the window)
+    // In other words:
+    //   messages from chat server may or may not match what we already have in mMsgs
+    //   We can drop anything that is during the time span covered by the local cache file
+    //   To keep things simple, drop any chat data older than the local cache file
+
+    if (!history.isArray())
+    {
+        LL_WARNS("ChatHistory") << mSessionID << ": Unexpected history data not array, type " << (S32)history.type() << LL_ENDL;
+        return;
+    }
 
-		it++;
-	}
+    if (history.size() == 0)
+    {   // If history is empty
+        LL_DEBUGS("ChatHistory") << mSessionID << ": addMessagesFromServerHistory() has empty history, nothing to merge" << LL_ENDL;
+        return;
+    }
+
+    if (history.size() == 1 &&          // Server chat history has one entry,
+        target_from.length() > 0 &&     // and we have a chat message that just arrived
+        mMsgs.size() > 0)               // and we have some data in the window - assume the history message is there.
+    {   // This is the common case where a group chat is silent for a while, and then one message is sent.
+        LL_DEBUGS("ChatHistory") << mSessionID << ": addMessagesFromServerHistory() only has chat message just received." << LL_ENDL;
+        return;
+    }
+
+    LL_DEBUGS("ChatHistory") << mSessionID << ": addMessagesFromServerHistory() starting with mMsg.size() " << mMsgs.size()
+        << " adding history with " << history.size() << " messages"
+        << ", target_from: " << target_from
+        << ", target_message: " << target_message
+        << ", timestamp: " << (S32)timestamp << LL_ENDL;
+
+    // At start of merging, mMsgs is either empty, has some chat messages read from a local cache file, and may have
+    // one or more messages that just arrived from the server.
+    U32 match_timestamp = 0;
+    chat_message_list_t shift_msgs;
+    if (mMsgs.size() > 0 &&
+        target_from.length() > 0
+        && target_message.length() > 0)
+    {   // Find where to insert the history messages by popping off a few in the session.
+        // The most common case is one duplciate message, the one that opens a chat session
+        while (mMsgs.size() > 0)
+        {
+            // The "time" value from mMsgs is a string, either just time HH:MM or a full date and time
+            LLSD cur_msg = mMsgs.front();       // Get most recent message from the chat display (front of mMsgs list)
+
+            if (cur_msg.isMap())
+            {
+                LL_DEBUGS("ChatHistoryCompare") << mSessionID << ": Finding insertion point, looking at cur_msg: " << cur_msg << LL_ENDL;
+
+                match_timestamp = cur_msg["timestamp"].asInteger();  // get timestamp of message in the session, may be zero
+                if ((S32)timestamp > match_timestamp)
+                {
+                    LL_DEBUGS("ChatHistory") << mSessionID << ": found older chat message: " << cur_msg
+                        << ", timestamp " << (S32)timestamp
+                        << " vs. match_timestamp " << match_timestamp
+                        << ", shift_msgs size is " << shift_msgs.size() << LL_ENDL;
+                    break;
+                }
+                // Have the matching message or one more recent: these need to be at the end
+                shift_msgs.push_front(cur_msg);     // Move chat message to temp list.
+                mMsgs.pop_front();                  // Normally this is just one message
+                LL_DEBUGS("ChatHistory") << mSessionID << ": shifting chat message " << cur_msg
+                    << " to be inserted at end, shift_msgs size is " << shift_msgs.size()
+                    << ", match_timestamp " << match_timestamp
+                    << ", timestamp " << (S32)timestamp << LL_ENDL;
+            }
+            else
+            {
+                LL_DEBUGS("ChatHistory") << mSessionID << ": Unexpected non-map entry in session messages: " << cur_msg << LL_ENDL;
+                return;
+            }
+        }
+    }
+
+    // Now merge messages from server history data into the session display.   The history data
+    // from the local file may overlap with the chat messages from the server.
+    // Drop any messages from the chat server history that are before the latest one from the local history file.
+    // Unfortunately, messages from the local file don't have timestamps - just datetime strings
+    LLSD::array_const_iterator cur_history_iter = history.beginArray();
+    while (cur_history_iter != history.endArray())
+    {
+        const LLSD &cur_server_hist = *cur_history_iter;
+        cur_history_iter++;
+
+        if (cur_server_hist.isMap())
+        {   // Each server history entry looks like
+            //   { 'from':'Laggy Avatar', 'from_id' : u72345678 - 744f - 43b9 - 98af - b06f1c76ddda, 'index' : i24, 'is_history' : 1, 'message' : 'That was slow', 'time' : '02/13/2023 10:03', 'timestamp' : i1676311419 }
+
+            // If we reach the message that opened our window, stop adding messages
+            U32 history_msg_timestamp = (U32)cur_server_hist[LL_IM_TIME].asInteger();
+            if ((match_timestamp > 0 && match_timestamp <= history_msg_timestamp) ||
+                (timestamp > 0 && timestamp <= history_msg_timestamp))
+            {   // we found the message we matched, so stop inserting from chat server history
+                LL_DEBUGS("ChatHistoryCompare") << "Found end of chat history insertion with match_timestamp " << (S32)match_timestamp
+                    << " vs. history_msg_timestamp " << (S32)history_msg_timestamp
+                    << " vs. timestamp " << (S32)timestamp
+                    << LL_ENDL;
+                break;
+            }
+            LL_DEBUGS("ChatHistoryCompare") << "Compared match_timestamp " << (S32)match_timestamp
+                << " vs. history_msg_timestamp " << (S32)history_msg_timestamp << LL_ENDL;
+
+            bool add_chat_to_conversation = true;
+            if (!mLastHistoryCacheDateTime.empty())
+            {   // Skip past the any from server that are older than what we already read from the history file.
+                std::string history_datetime = cur_server_hist[LL_IM_DATE_TIME].asString();
+                if (history_datetime.empty())
+                {
+                    history_datetime = cur_server_hist[LL_IM_TIME].asString();
+                }
+
+                if (history_datetime < mLastHistoryCacheDateTime)
+                {
+                    LL_DEBUGS("ChatHistoryCompare") << "Skipping message from chat server history since it's older than messages the session already has."
+                        << history_datetime << " vs  " << mLastHistoryCacheDateTime << LL_ENDL;
+                    add_chat_to_conversation = false;
+                }
+                else if (history_datetime > mLastHistoryCacheDateTime)
+                {   // The message from the chat server is more recent than the last one from the local cache file.   Add it
+                    LL_DEBUGS("ChatHistoryCompare") << "Found message dated "
+                        << history_datetime << " vs " << mLastHistoryCacheDateTime
+                        << ", adding new message from chat server history " << cur_server_hist << LL_ENDL;
+                }
+                else   // (history_datetime == mLastHistoryCacheDateTime)
+                {      // Messages are in the same minute as the last from the cache log file.
+                    const std::string & history_msg_text = cur_server_hist[LL_IM_TEXT];
+
+                    // Look in the saved messages from the history file that have the same time
+                    for (const auto& scan_msg : mLastHistoryCacheMsgs)
+                    {
+                        LL_DEBUGS("ChatHistoryCompare") << "comparing messages " << scan_msg[LL_IM_TEXT]
+                            << " with " << cur_server_hist << LL_ENDL;
+                        if (scan_msg.size() > 0)
+                        {   // Extra work ... the history_msg_text value may have been translated, i.e. "I am confused (je suis confus)"
+                            //  while the server history will only have the first part "I am confused"
+                            std::string target_compare(scan_msg[LL_IM_TEXT]);
+                            if (target_compare.size() > history_msg_text.size() + XL8_PADDING &&
+                                target_compare.substr(history_msg_text.size(), XL8_START_TAG.size()) == XL8_START_TAG &&
+                                target_compare.substr(target_compare.size() - XL8_END_TAG.size()) == XL8_END_TAG)
+                            {   // This really looks like a "translated string (cadena traducida)" so just compare the source part
+                                LL_DEBUGS("ChatHistory") << mSessionID << ": Found translated chat " << target_compare
+                                    << " when comparing to history " << history_msg_text
+                                    << ", will truncate" << LL_ENDL;
+                                target_compare = target_compare.substr(0, history_msg_text.size());
+                            }
+                            if (history_msg_text == target_compare)
+                            {   // Found a match, so don't add a duplicate chat message to the window
+                                LL_DEBUGS("ChatHistory") << mSessionID << ": Found duplicate message text " << history_msg_text
+                                    << " : " << (S32)history_msg_timestamp << ", matching datetime " << history_datetime << LL_ENDL;
+                                add_chat_to_conversation = false;
+                                break;
+                            }
+                        }
+                    }
+                }
+            }
+
+            LLUUID sender_id = cur_server_hist[LL_IM_FROM_ID].asUUID();
+            if (add_chat_to_conversation)
+            {   // Check if they're muted
+                if (LLMuteList::getInstance()->isMuted(sender_id, LLMute::flagTextChat))
+                {
+                    add_chat_to_conversation = false;
+                    LL_DEBUGS("ChatHistory") << mSessionID << ": Skipped adding chat from " << sender_id
+                        << " as muted, message: " << cur_server_hist
+                        << LL_ENDL;
+                }
+            }
+
+            if (add_chat_to_conversation)
+            {   // Finally add message to the chat session
+                std::string chat_time_str = LLConversation::createTimestamp((U64Seconds)history_msg_timestamp);
+                std::string sender_name = cur_server_hist[LL_IM_FROM].asString();
+
+                std::string history_msg_text = cur_server_hist[LL_IM_TEXT].asString();
+                LLSD message;
+                message["from"] = sender_name;
+                message["from_id"] = sender_id;
+                message["message"] = history_msg_text;
+                message["time"] = chat_time_str;
+                message["timestamp"] = (S32)history_msg_timestamp;
+                message["index"] = (LLSD::Integer)mMsgs.size();
+                message["is_history"] = true;
+                mMsgs.push_front(message);
+
+                LL_DEBUGS("ChatHistory") << mSessionID << ": push_front() adding group chat history message " << message << LL_ENDL;
+
+                // Add chat history messages to the local cache file, only in the case where we opened the chat window
+                // Need to solve the logic around messages that arrive and open chat - at this point, they've already been added to the
+                //   local history cache file.   If we append messages here, it will be out of order.
+                if (target_from.empty() && target_message.empty())
+                {
+                    LLIMModel::getInstance()->logToFile(LLIMModel::getInstance()->getHistoryFileName(mSessionID),
+                        sender_name, sender_id, history_msg_text);
+                }
+            }
+        }
+    }
+
+    S32 shifted_size = shift_msgs.size();
+    while (shift_msgs.size() > 0)
+    {   // Finally add back any new messages, and tweak the index value to be correct.
+        LLSD newer_message = shift_msgs.front();
+        shift_msgs.pop_front();
+        S32 old_index = newer_message["index"];
+        newer_message["index"] = (LLSD::Integer)mMsgs.size();   // Update the index to match the new position in the conversation
+        LL_DEBUGS("ChatHistory") << mSessionID << ": Re-adding newest group chat history messages from " << newer_message["from"]
+            << ", text: " << newer_message["message"]
+            << " old index " << old_index << ", new index " << newer_message["index"] << LL_ENDL;
+        mMsgs.push_front(newer_message);
+    }
+
+    LL_DEBUGS("ChatHistory") << mSessionID << ": addMessagesFromServerHistory() exiting with mMsg.size() " << mMsgs.size()
+        << ", shifted " << shifted_size << " messages" << LL_ENDL;
+
+    mLastHistoryCacheDateTime.clear();  // Don't need this data
+    mLastHistoryCacheMsgs.clear();
 }
 
+
 void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata)
 {
 	if (!userdata) return;
@@ -834,26 +1210,29 @@ void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const
 
 	if (type == LLLogChat::LOG_LINE)
 	{
-		self->addMessage("", LLSD(), msg["message"].asString(), "", true);
+        LL_DEBUGS("ChatHistory") << "chatFromLogFile() adding LOG_LINE message from " << msg << LL_ENDL;
+        self->addMessage("", LLSD(), msg["message"].asString(), "", true, false, 0);        // from history data, not region message, no timestamp
 	}
 	else if (type == LLLogChat::LOG_LLSD)
 	{
-		self->addMessage(msg["from"].asString(), msg["from_id"].asUUID(), msg["message"].asString(), msg["time"].asString(), true);
+        LL_DEBUGS("ChatHistory") << "chatFromLogFile() adding LOG_LLSD message from " << msg << LL_ENDL;
+        self->addMessage(msg["from"].asString(), msg["from_id"].asUUID(), msg["message"].asString(), msg["time"].asString(), true, false, 0);  // from history data, not region message, no timestamp
 	}
 }
 
 void LLIMModel::LLIMSession::loadHistory()
 {
 	mMsgs.clear();
+    mLastHistoryCacheMsgs.clear();
+    mLastHistoryCacheDateTime.clear();
 
 	if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
 	{
-		std::list<LLSD> chat_history;
-
-		//involves parsing of a chat history
+        // read and parse chat history from local file
+        chat_message_list_t chat_history;
 		LLLogChat::loadChatHistory(mHistoryFileName, chat_history, LLSD(), isGroupChat());
-		addMessagesFromHistory(chat_history);
-	}
+        addMessagesFromHistoryCache(chat_history);
+    }
 }
 
 LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
@@ -873,7 +1252,7 @@ LLIMModel::LLIMSession* LLIMModel::findAdHocIMSession(const uuid_vec_t& ids)
 	for (; it != mId2SessionMap.end(); ++it)
 	{
 		LLIMSession* session = (*it).second;
-	
+
 		if (!session->isAdHoc()) continue;
 		if (session->mInitialTargetIDs.size() != num) continue;
 
@@ -884,8 +1263,8 @@ LLIMModel::LLIMSession* LLIMModel::findAdHocIMSession(const uuid_vec_t& ids)
 		{
 			tmp_list.remove(*iter);
 			++iter;
-			
-			if (tmp_list.empty()) 
+
+			if (tmp_list.empty())
 			{
 				break;
 			}
@@ -941,7 +1320,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 	if (isAdHoc())
 	{
 		/* in case of outgoing ad-hoc sessions we need to make specilized names
-		* if this naming system is ever changed then the filtering definitions in 
+		* if this naming system is ever changed then the filtering definitions in
 		* lllogchat.cpp need to be change acordingly so that the filtering for the
 		* date stamp code introduced in STORM-102 will work properly and not add
 		* a date stamp to the Ad-hoc conferences.
@@ -954,7 +1333,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 		else
 		{
 			//in case of incoming ad-hoc sessions
-			mHistoryFileName = mName + " " + LLLogChat::timestamp(true) + " " + mSessionID.asString().substr(0, 4);
+			mHistoryFileName = mName + " " + LLLogChat::timestamp2LogString(0, true) + " " + mSessionID.asString().substr(0, 4);
 		}
 	}
 	else if (isP2P()) // look up username to use as the log name
@@ -985,7 +1364,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 LLUUID LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids)
 {
 	LLMD5 md5_uuid;
-	
+
 	std::set<LLUUID>::const_iterator it = sorted_uuids.begin();
 	while (it != sorted_uuids.end())
 	{
@@ -1047,7 +1426,7 @@ void LLIMModel::testMessages()
 
 	S32 rand1 = ll_rand(sizeof firstname)/(sizeof firstname[0]);
 	S32 rand2 = ll_rand(sizeof lastname)/(sizeof lastname[0]);
-	
+
 	from = firstname[rand1] + " " + lastname[rand2];
 	bot2_id.generate(from);
 	LLUUID bot2_session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, bot2_id);
@@ -1057,7 +1436,7 @@ void LLIMModel::testMessages()
 }
 
 //session name should not be empty
-bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, 
+bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type,
 						   const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg)
 {
 	if (name.empty())
@@ -1099,7 +1478,7 @@ bool LLIMModel::clearSession(const LLUUID& session_id)
 	return true;
 }
 
-void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index, const bool sendNoUnreadMsgs)
+void LLIMModel::getMessages(const LLUUID& session_id, chat_message_list_t& messages, int start_index, const bool sendNoUnreadMsgs)
 {
 	getMessagesSilently(session_id, messages, start_index);
 
@@ -1109,7 +1488,7 @@ void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages,
 	}
 }
 
-void LLIMModel::getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index)
+void LLIMModel::getMessagesSilently(const LLUUID& session_id, chat_message_list_t& messages, int start_index)
 {
 	LLIMSession* session = findIMSession(session_id);
 	if (!session)
@@ -1120,7 +1499,7 @@ void LLIMModel::getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& m
 
 	int i = session->mMsgs.size() - start_index;
 
-	for (std::list<LLSD>::iterator iter = session->mMsgs.begin();
+	for (chat_message_list_t::iterator iter = session->mMsgs.begin();
 		iter != session->mMsgs.end() && i > 0;
 		iter++)
 	{
@@ -1142,7 +1521,7 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id)
 
 	session->mNumUnread = 0;
 	session->mParticipantUnreadMessageCount = 0;
-	
+
 	LLSD arg;
 	arg["session_id"] = session_id;
 	arg["num_unread"] = 0;
@@ -1150,17 +1529,23 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id)
 	mNoUnreadMsgsSignal(arg);
 }
 
-bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg) {
-	
+bool LLIMModel::addToHistory(const LLUUID& session_id,
+                             const std::string& from,
+                             const LLUUID& from_id,
+                             const std::string& utf8_text,
+                             bool is_region_msg,
+                             U32 timestamp)
+{
 	LLIMSession* session = findIMSession(session_id);
 
-	if (!session) 
+	if (!session)
 	{
 		LL_WARNS() << "session " << session_id << "does not exist " << LL_ENDL;
 		return false;
 	}
 
-	session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp(false), false, is_region_msg); //might want to add date separately
+    // This is where a normal arriving message is added to the session.   Note that the time string created here is without the full date
+	session->addMessage(from, from_id, utf8_text, LLLogChat::timestamp2LogString(timestamp, false), false, is_region_msg, timestamp);
 
 	return true;
 }
@@ -1168,14 +1553,14 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
 bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
 {
 	if (gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 1)
-	{	
+	{
 		std::string from_name = from;
 
 		LLAvatarName av_name;
-		if (!from_id.isNull() && 
+		if (!from_id.isNull() &&
 			LLAvatarNameCache::get(from_id, &av_name) &&
 			!av_name.isDisplayNameDefault())
-		{	
+		{
 			from_name = av_name.getCompleteName();
 		}
 
@@ -1189,43 +1574,63 @@ bool LLIMModel::logToFile(const std::string& file_name, const std::string& from,
 	}
 }
 
-bool LLIMModel::proccessOnlineOfflineNotification(
-	const LLUUID& session_id, 
-	const std::string& utf8_text)
+void LLIMModel::proccessOnlineOfflineNotification(
+	const LLUUID& session_id,
+    const std::string& utf8_text)
 {
 	// Add system message to history
-	return addMessage(session_id, SYSTEM_FROM, LLUUID::null, utf8_text);
+	addMessage(session_id, SYSTEM_FROM, LLUUID::null, utf8_text);
 }
 
-bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, 
-						   const std::string& utf8_text, bool log2file, bool is_region_msg) { 
+void LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
+						   const std::string& utf8_text, bool log2file /* = true */, bool is_region_msg, /* = false */ U32 time_stamp /* = 0 */)
+{
+    if (gSavedSettings.getBOOL("TranslateChat") && (from != SYSTEM_FROM))
+    {
+        const std::string from_lang = ""; // leave empty to trigger autodetect
+        const std::string to_lang = LLTranslate::getTranslateLanguage();
+        U64 time_n_flags = ((U64) time_stamp) | (log2file ? (1LL << 32) : 0) | (is_region_msg ? (1LL << 33) : 0);   // boost::bind has limited parameters
+        LLTranslate::translateMessage(from_lang, to_lang, utf8_text,
+            boost::bind(&translateSuccess, session_id, from, from_id, utf8_text, time_n_flags, utf8_text, from_lang, _1, _2),
+            boost::bind(&translateFailure, session_id, from, from_id, utf8_text, time_n_flags, _1, _2));
+    }
+    else
+    {
+        processAddingMessage(session_id, from, from_id, utf8_text, log2file, is_region_msg, time_stamp);
+    }
+}
 
-	LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, is_region_msg);
-	if (!session) return false;
+void LLIMModel::processAddingMessage(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
+    const std::string& utf8_text, bool log2file, bool is_region_msg, U32 time_stamp)
+{
+    LLIMSession* session = addMessageSilently(session_id, from, from_id, utf8_text, log2file, is_region_msg, time_stamp);
+    if (!session)
+        return;
 
-	//good place to add some1 to recent list
-	//other places may be called from message history.
-	if( !from_id.isNull() &&
-		( session->isP2PSessionType() || session->isAdHocSessionType() ) )
-		LLRecentPeople::instance().add(from_id);
+    //good place to add some1 to recent list
+    //other places may be called from message history.
+    if( !from_id.isNull() &&
+        ( session->isP2PSessionType() || session->isAdHocSessionType() ) )
+        LLRecentPeople::instance().add(from_id);
 
-	// notify listeners
-	LLSD arg;
-	arg["session_id"] = session_id;
-	arg["num_unread"] = session->mNumUnread;
-	arg["participant_unread"] = session->mParticipantUnreadMessageCount;
-	arg["message"] = utf8_text;
-	arg["from"] = from;
-	arg["from_id"] = from_id;
-	arg["time"] = LLLogChat::timestamp(false);
-	arg["session_type"] = session->mSessionType;
-	mNewMsgSignal(arg);
+    // notify listeners
+    LLSD arg;
+    arg["session_id"] = session_id;
+    arg["num_unread"] = session->mNumUnread;
+    arg["participant_unread"] = session->mParticipantUnreadMessageCount;
+    arg["message"] = utf8_text;
+    arg["from"] = from;
+    arg["from_id"] = from_id;
+    arg["time"] = LLLogChat::timestamp2LogString(time_stamp, true);
+    arg["session_type"] = session->mSessionType;
+    arg["is_region_msg"] = is_region_msg;
 
-	return true;
+    mNewMsgSignal(arg);
 }
 
-LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, 
-													 const std::string& utf8_text, bool log2file, bool is_region_msg)
+LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
+													  const std::string& utf8_text, bool log2file /* = true */, bool is_region_msg, /* false */
+                                                      U32 timestamp /* = 0 */)
 {
 	LLIMSession* session = findIMSession(session_id);
 
@@ -1241,12 +1646,12 @@ LLIMModel::LLIMSession* LLIMModel::addMessageSilently(const LLUUID& session_id,
 		from_name = SYSTEM_FROM;
 	}
 
-	addToHistory(session_id, from_name, from_id, utf8_text, is_region_msg);
+	addToHistory(session_id, from_name, from_id, utf8_text, is_region_msg, timestamp);
 	if (log2file)
 	{
 		logToFile(getHistoryFileName(session_id), from_name, from_id, utf8_text);
 	}
-	
+
 	session->mNumUnread++;
 
 	//update count of unread messages from real participant
@@ -1348,7 +1753,7 @@ const std::string& LLIMModel::getHistoryFileName(const LLUUID& session_id) const
 
 
 // TODO get rid of other participant ID
-void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing) 
+void LLIMModel::sendTypingState(LLUUID session_id, LLUUID other_participant_id, BOOL typing)
 {
 	std::string name;
 	LLAgentUI::buildFullname(name);
@@ -1379,7 +1784,7 @@ void LLIMModel::sendLeaveSession(const LLUUID& session_id, const LLUUID& other_p
 			FALSE,
 			gAgent.getSessionID(),
 			other_participant_id,
-			name, 
+			name,
 			LLStringUtil::null,
 			IM_ONLINE,
 			IM_SESSION_LEAVE,
@@ -1400,7 +1805,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
 
 	const LLRelationship* info = NULL;
 	info = LLAvatarTracker::instance().getBuddyInfo(other_participant_id);
-	
+
 	U8 offline = (!info || info->isOnline()) ? IM_ONLINE : IM_OFFLINE;
 	// Old call to send messages to SLim client,  no longer supported.
 	//if((offline == IM_OFFLINE) && (LLVoiceClient::getInstance()->isOnlineSIP(other_participant_id)))
@@ -1408,7 +1813,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
 	//	// User is online through the OOW connector, but not with a regular viewer.  Try to send the message via SLVoice.
 	//	sent = LLVoiceClient::getInstance()->sendTextMessage(other_participant_id, utf8_text);
 	//}
-	
+
 	if(!sent)
 	{
 		// Send message normally.
@@ -1465,7 +1870,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
 		}
 	}
 
-	if((dialog == IM_NOTHING_SPECIAL) && 
+	if((dialog == IM_NOTHING_SPECIAL) &&
 	   (other_participant_id.notNull()))
 	{
 		// Do we have to replace the /me's here?
@@ -1503,7 +1908,7 @@ void LLIMModel::sendMessage(const std::string& utf8_text,
 		// to Recent People to prevent showing of an item with (?? ?)(?? ?), sans the spaces. See EXT-8246.
 		// Concrete participants will be added into this list once they sent message in chat.
 		if (IM_SESSION_INVITE == dialog) return;
-			
+
 		if (IM_SESSION_CONFERENCE_START == dialog) // outgoing ad-hoc session
 		{
 			// Add only online members of conference to recent list (EXT-8658)
@@ -1585,7 +1990,7 @@ void start_deprecated_conference_chat(
 	for(S32 i = 0; i < count; ++i)
 	{
 		LLUUID agent_id = agents_to_invite[i].asUUID();
-		
+
 		memcpy(pos, &agent_id, UUID_BYTES);
 		pos += UUID_BYTES;
 	}
@@ -1601,7 +2006,7 @@ void start_deprecated_conference_chat(
 		bucket_size);
 
 	gAgent.sendReliableMessage();
- 
+
 	delete[] bucket;
 }
 
@@ -1822,7 +2227,7 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
 {
 	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
 	if(!session)
-	{		
+	{
 		mPreviousSessionlName = mCurrentSessionlName;
 		mCurrentSessionlName = ""; // Empty string results in "Nearby Voice Chat" after substitution
 		return;
@@ -1845,7 +2250,7 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
 	if (LLVoiceChannel::getCurrentVoiceChannel()->getState() == LLVoiceChannel::STATE_CALL_STARTED &&
 		LLVoiceChannel::getCurrentVoiceChannel()->getCallDirection() == LLVoiceChannel::OUTGOING_CALL)
 	{
-		
+
 		//*TODO get rid of duplicated code
 		LLSD mCallDialogPayload;
 		mCallDialogPayload["session_id"] = mSession->mSessionID;
@@ -1860,7 +2265,7 @@ void LLCallDialogManager::onVoiceChannelChangedInt(const LLUUID &session_id)
 		if(ocd)
 		{
 			ocd->show(mCallDialogPayload);
-		}	
+		}
 	}
 
 }
@@ -1893,7 +2298,7 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
 	mCallDialogPayload["ended_by_agent"] = ended_by_agent;
 
 	switch(new_state)
-	{			
+	{
 	case LLVoiceChannel::STATE_CALL_STARTED :
 		// do not show "Calling to..." if it is incoming call
 		if(direction == LLVoiceChannel::INCOMING_CALL)
@@ -1922,7 +2327,7 @@ void LLCallDialogManager::onVoiceChannelStateChangedInt(const LLVoiceChannel::ES
 	if(ocd)
 	{
 		ocd->show(mCallDialogPayload);
-	}	
+	}
 }
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -1948,9 +2353,9 @@ BOOL LLCallDialog::postBuild()
 {
 	if (!LLDockableFloater::postBuild() || !gToolBarView)
 		return FALSE;
-	
+
 	dockToToolbarButton("speak");
-	
+
 	return TRUE;
 }
 
@@ -1968,20 +2373,20 @@ LLDockControl::DocAt LLCallDialog::getDockControlPos(const std::string& toolbarB
 {
 	LLCommandId command_id(toolbarButtonName);
 	S32 toolbar_loc = gToolBarView->hasCommand(command_id);
-	
+
 	LLDockControl::DocAt doc_at = LLDockControl::TOP;
-	
+
 	switch (toolbar_loc)
 	{
 		case LLToolBarEnums::TOOLBAR_LEFT:
 			doc_at = LLDockControl::RIGHT;
 			break;
-			
+
 		case LLToolBarEnums::TOOLBAR_RIGHT:
 			doc_at = LLDockControl::LEFT;
 			break;
 	}
-	
+
 	return doc_at;
 }
 
@@ -1996,7 +2401,7 @@ LLCallDialog(payload)
 	if(instance && instance->getVisible())
 	{
 		instance->onCancel(instance);
-	}	
+	}
 }
 
 void LLCallDialog::draw()
@@ -2053,7 +2458,7 @@ bool LLCallDialog::lifetimeHasExpired()
 	if (mLifetimeTimer.getStarted())
 	{
 		F32 elapsed_time = mLifetimeTimer.getElapsedTimeF32();
-		if (elapsed_time > mLifetime) 
+		if (elapsed_time > mLifetime)
 		{
 			return true;
 		}
@@ -2095,7 +2500,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
 	}
 	else
 	{
-		getChild<LLUICtrl>("leaving")->setTextArg("[CURRENT_CHAT]", getString("localchat"));		
+		getChild<LLUICtrl>("leaving")->setTextArg("[CURRENT_CHAT]", getString("localchat"));
 	}
 
 	if (!mPayload["disconnected_channel_name"].asString().empty())
@@ -2119,7 +2524,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
 	{
 		callee_name = getString("anonymous");
 	}
-	
+
 	LLSD callee_id = mPayload["other_user_id"];
 	// Beautification:  Since you know who you called, just show display name
 	std::string title = callee_name;
@@ -2175,7 +2580,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
 		{
 			const std::string& nearby_str = mPayload["ended_by_agent"] ? NEARBY_P2P_BY_AGENT : NEARBY_P2P_BY_OTHER;
 			getChild<LLTextBox>(nearby_str)->setVisible(true);
-		} 
+		}
 		else
 		{
 			getChild<LLTextBox>("nearby")->setVisible(true);
@@ -2209,7 +2614,7 @@ void LLOutgoingCallDialog::onCancel(void* user_data)
 
 	LLUUID session_id = self->mPayload["session_id"].asUUID();
 	gIMMgr->endCall(session_id);
-	
+
 	self->closeFloater();
 }
 
@@ -2294,7 +2699,7 @@ BOOL LLIncomingCallDialog::postBuild()
         LL_INFOS("IMVIEW") << "IncomingCall: notify_box_type was not provided" << LL_ENDL;
         return TRUE;
     }
-	
+
 	// init notification's lifetime
 	std::istringstream ss( getString("lifetime") );
 	if (!(ss >> mLifetime))
@@ -2469,7 +2874,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 			if (session_name.empty())
 			{
 				LL_WARNS() << "Received an empty session name from a server" << LL_ENDL;
-				
+
 				switch(type){
 				case IM_SESSION_CONFERENCE_START:
 				case IM_SESSION_GROUP_START:
@@ -2487,17 +2892,17 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 						if (LLAvatarNameCache::get(caller_id, &av_name))
 						{
 							correct_session_name = av_name.getCompleteName();
-							correct_session_name.append(ADHOC_NAME_SUFFIX); 
+							correct_session_name.append(ADHOC_NAME_SUFFIX);
 						}
 					}
 					LL_INFOS("IMVIEW") << "Corrected session name is " << correct_session_name << LL_ENDL;
 					break;
-				default: 
+				default:
 					LL_WARNS("IMVIEW") << "Received an empty session name from a server and failed to generate a new proper session name" << LL_ENDL;
 					break;
 				}
 			}
-			
+
 			gIMMgr->addSession(correct_session_name, type, session_id, true);
 
 			std::string url = gAgent.getRegion()->getCapability(
@@ -2509,7 +2914,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
                     boost::bind(&chatterBoxInvitationCoro, url,
                     session_id, inv_type));
 
-				// send notification message to the corresponding chat 
+				// send notification message to the corresponding chat
 				if (payload["notify_box_type"].asString() == "VoiceInviteGroup" || payload["notify_box_type"].asString() == "VoiceInviteAdHoc")
 				{
 					LLStringUtil::format_map_t string_args;
@@ -2544,7 +2949,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 			data["session-id"] = session_id;
 
             LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data,
-                "Invitation declined", 
+                "Invitation declined",
                 "Invitation decline failed.");
 		}
 	}
@@ -2564,7 +2969,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 	EInstantMessage type = (EInstantMessage)payload["type"].asInteger();
 	LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger();
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	switch(option) 
+	switch(option)
 	{
 	case 0: // accept
 		{
@@ -2608,7 +3013,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 		}
 	}
 	/* FALLTHROUGH */
-	
+
 	case 1: // decline
 	{
 		if (type == IM_SESSION_P2P_INVITE)
@@ -2624,8 +3029,8 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 			LLSD data;
 			data["method"] = "decline invitation";
 			data["session-id"] = session_id;
-            LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data, 
-                "Invitation declined.", 
+            LLCoreHttpUtil::HttpCoroutineAdapter::messageHttpPost(url, data,
+                "Invitation declined.",
                 "Invitation decline failed.");
 		}
 	}
@@ -2634,7 +3039,7 @@ bool inviteUserResponse(const LLSD& notification, const LLSD& response)
 	gIMMgr->clearPendingInvitation(session_id);
 	break;
 	}
-	
+
 	return false;
 }
 
@@ -2648,9 +3053,11 @@ LLIMMgr::LLIMMgr()
 	mPendingAgentListUpdates = LLSD::emptyMap();
 
 	LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLFloaterIMSession::sRemoveTypingIndicator, _1));
+
+	gSavedPerAccountSettings.declareBOOL("FetchGroupChatHistory", TRUE, "Fetch recent messages from group chat servers when a group window opens", LLControlVariable::PERSIST_ALWAYS);
 }
 
-// Add a message to a session. 
+// Add a message to a session.
 void LLIMMgr::addMessage(
 	const LLUUID& session_id,
 	const LLUUID& target_id,
@@ -2662,7 +3069,8 @@ void LLIMMgr::addMessage(
 	U32 parent_estate_id,
 	const LLUUID& region_id,
 	const LLVector3& position,
-	bool is_region_msg)
+    bool is_region_msg,
+    U32 timestamp)      // May be zero
 {
 	LLUUID other_participant_id = target_id;
 
@@ -2682,7 +3090,7 @@ void LLIMMgr::addMessage(
 		name_is_setted = true;
 	}
 	bool skip_message = false;
-	bool from_linden = LLMuteList::getInstance()->isLinden(from);
+	bool from_linden = LLMuteList::isLinden(from);
     if (gSavedPerAccountSettings.getBOOL("VoiceCallsFriendsOnly") && !from_linden)
 	{
 		// Evaluate if we need to skip this message when that setting is true (default is false)
@@ -2749,6 +3157,14 @@ void LLIMMgr::addMessage(
 				return;
 			}
 
+            // Fetch group chat history, enabled by default.
+            if (gSavedPerAccountSettings.getBOOL("FetchGroupChatHistory"))
+            {
+                std::string chat_url = gAgent.getRegion()->getCapability("ChatSessionRequest");
+                LLCoros::instance().launch("chatterBoxHistoryCoro",
+                    boost::bind(&chatterBoxHistoryCoro, chat_url, session_id, from, msg, timestamp));
+            }
+
 			//Play sound for new conversations
 			if (!skip_message & !gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
 			{
@@ -2764,7 +3180,7 @@ void LLIMMgr::addMessage(
 
 	if (!LLMuteList::getInstance()->isMuted(other_participant_id, LLMute::flagTextChat) && !skip_message)
 	{
-		LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg);
+		LLIMModel::instance().addMessage(new_session_id, from, other_participant_id, msg, true, is_region_msg, timestamp);
 	}
 
 	// Open conversation floater if offline messages are present
@@ -2779,7 +3195,7 @@ void LLIMMgr::addMessage(
 void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
 {
 	LLUIString message;
-	
+
 	// null session id means near me (chat history)
 	if (session_id.isNull())
 	{
@@ -2819,7 +3235,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 S32 LLIMMgr::getNumberOfUnreadIM()
 {
 	std::map<LLUUID, LLIMModel::LLIMSession*>::iterator it;
-	
+
 	S32 num = 0;
 	for(it = LLIMModel::getInstance()->mId2SessionMap.begin(); it != LLIMModel::getInstance()->mId2SessionMap.end(); ++it)
 	{
@@ -2846,7 +3262,7 @@ void LLIMMgr::autoStartCallOnStartup(const LLUUID& session_id)
 {
 	LLIMModel::LLIMSession *session = LLIMModel::getInstance()->findIMSession(session_id);
 	if (!session) return;
-	
+
 	if (session->mSessionInitialized)
 	{
 		startCall(session_id);
@@ -2854,7 +3270,7 @@ void LLIMMgr::autoStartCallOnStartup(const LLUUID& session_id)
 	else
 	{
 		session->mStartCallOnInitialize = true;
-	}	
+	}
 }
 
 LLUUID LLIMMgr::addP2PSession(const std::string& name,
@@ -2891,7 +3307,7 @@ LLUUID LLIMMgr::addSession(
 	return session_id;
 }
 
-// Adds a session using the given session_id.  If the session already exists 
+// Adds a session using the given session_id.  If the session already exists
 // the dialog type is assumed correct. Returns the uuid of the session.
 LLUUID LLIMMgr::addSession(
 	const std::string& name,
@@ -2954,9 +3370,9 @@ LLUUID LLIMMgr::addSession(
 
 	//we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions
 	if (!new_session) return session_id;
-	
+
     LL_INFOS("IMVIEW") << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << LL_ENDL;
-    
+
 	//Per Plan's suggestion commented "explicit offline status warning" out to make Dessie happier (see EXT-3609)
 	//*TODO After February 2010 remove this commented out line if no one will be missing that warning
 	//noteOfflineUsers(session_id, floater, ids);
@@ -2986,7 +3402,7 @@ bool LLIMMgr::leaveSession(const LLUUID& session_id)
 void LLIMMgr::removeSession(const LLUUID& session_id)
 {
 	llassert_always(hasSession(session_id));
-	
+
 	clearPendingInvitation(session_id);
 	clearPendingAgentListUpdates(session_id);
 
@@ -2998,9 +3414,9 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
 }
 
 void LLIMMgr::inviteToSession(
-	const LLUUID& session_id, 
-	const std::string& session_name, 
-	const LLUUID& caller_id, 
+	const LLUUID& session_id,
+	const std::string& session_name,
+	const LLUUID& caller_id,
 	const std::string& caller_name,
 	EInstantMessage type,
 	EInvitationType inv_type,
@@ -3012,7 +3428,7 @@ void LLIMMgr::inviteToSession(
 	std::string question_type = "VoiceInviteQuestionDefault";
 
 	BOOL voice_invite = FALSE;
-	bool is_linden = LLMuteList::getInstance()->isLinden(caller_name);
+	bool is_linden = LLMuteList::isLinden(caller_name);
 
 
 	if(type == IM_SESSION_P2P_INVITE)
@@ -3117,22 +3533,22 @@ void LLIMMgr::inviteToSession(
 	{
 		if (caller_name.empty())
 		{
-			LLAvatarNameCache::get(caller_id, 
+			LLAvatarNameCache::get(caller_id,
 				boost::bind(&LLIMMgr::onInviteNameLookup, payload, _1, _2));
 		}
 		else
 		{
 			LLFloaterReg::showInstance("incoming_call", payload, FALSE);
 		}
-		
-		// Add the caller to the Recent List here (at this point 
+
+		// Add the caller to the Recent List here (at this point
 		// "incoming_call" floater is shown and the recipient can
 		// reject the call), because even if a recipient will reject
 		// the call, the caller should be added to the recent list
 		// anyway. STORM-507.
 		if(type == IM_SESSION_P2P_INVITE)
 			LLRecentPeople::instance().add(caller_id);
-		
+
 		mPendingInvitations[session_id.asString()] = LLSD();
 	}
 }
@@ -3329,7 +3745,7 @@ bool LLIMMgr::startCall(const LLUUID& session_id, LLVoiceChannel::EDirection dir
 {
 	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(session_id);
 	if (!voice_channel) return false;
-	
+
 	voice_channel->setCallDirection(direction);
 	voice_channel->activate();
 	return true;
@@ -3447,7 +3863,7 @@ void LLIMMgr::noteMutedUsers(const LLUUID& session_id,
 	if(count > 0)
 	{
 		LLIMModel* im_model = LLIMModel::getInstance();
-		
+
 		for(S32 i = 0; i < count; ++i)
 		{
 			if( ml->isMuted(ids.at(i)) )
@@ -3525,7 +3941,15 @@ class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
 				if ( body.has("session_info") )
 				{
 					im_floater->processSessionUpdate(body["session_info"]);
-				}
+
+                    // Send request for chat history, if enabled.
+                    if (gSavedPerAccountSettings.getBOOL("FetchGroupChatHistory"))
+                    {
+                        std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
+                        LLCoros::instance().launch("chatterBoxHistoryCoro",
+                            boost::bind(&chatterBoxHistoryCoro, url, session_id, "", "", 0));
+                    }
+                }
 			}
 
 			gIMMgr->clearPendingAgentListUpdates(session_id);
@@ -3654,7 +4078,7 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 			LLUUID session_id = message_params["id"].asUUID();
 			std::vector<U8> bin_bucket = message_params["data"]["binary_bucket"].asBinary();
 			U8 offline = (U8)message_params["offline"].asInteger();
-			
+
 			time_t timestamp =
 				(time_t) message_params["timestamp"].asInteger();
 
@@ -3691,7 +4115,9 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 				IM_SESSION_INVITE,
 				message_params["parent_estate_id"].asInteger(),
 				message_params["region_id"].asUUID(),
-				ll_vector3_from_sd(message_params["position"]));
+				ll_vector3_from_sd(message_params["position"]),
+                false,      // is_region_message
+                timestamp);
 
 			if (LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat))
 			{
@@ -3717,8 +4143,8 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 			}
 
 			gIMMgr->inviteToSession(
-				input["body"]["session_id"].asUUID(), 
-				input["body"]["session_name"].asString(), 
+				input["body"]["session_id"].asUUID(),
+				input["body"]["session_name"].asString(),
 				input["body"]["from_id"].asUUID(),
 				input["body"]["from_name"].asString(),
 				IM_SESSION_INVITE,
@@ -3727,8 +4153,8 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 		else if ( input["body"].has("immediate") )
 		{
 			gIMMgr->inviteToSession(
-				input["body"]["session_id"].asUUID(), 
-				input["body"]["session_name"].asString(), 
+				input["body"]["session_id"].asUUID(),
+				input["body"]["session_name"].asString(),
 				input["body"]["from_id"].asUUID(),
 				input["body"]["from_name"].asString(),
 				IM_SESSION_INVITE,
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 326e8f22e3061829ca0edddbaaf3200c5ed69a4c..946eb02f26bf6a50abbd10881512af61b9040d06 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -42,6 +42,7 @@ class LLAvatarName;
 class LLFriendObserver;
 class LLCallDialogManager;	
 class LLIMSpeakerMgr;
+
 /**
  * Timeout Timer for outgoing Ad-Hoc/Group IM sessions which being initialized by the server
  */
@@ -63,11 +64,14 @@ class LLSessionTimeoutTimer : public LLEventTimer
 class LLIMModel :  public LLSingleton<LLIMModel>
 {
 	LLSINGLETON(LLIMModel);
+
 public:
 
-	struct LLIMSession : public boost::signals2::trackable
+    typedef std::list<LLSD> chat_message_list_t;
+
+    struct LLIMSession : public boost::signals2::trackable
 	{
-		typedef enum e_session_type
+        typedef enum e_session_type
 		{   // for now we have 4 predefined types for a session
 			P2P_SESSION,
 			GROUP_SESSION,
@@ -75,15 +79,23 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 			NONE_SESSION,
 		} SType;
 
-		LLIMSession(const LLUUID& session_id, const std::string& name, 
+		LLIMSession(const LLUUID& session_id, const std::string& name,
 			const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg);
 		virtual ~LLIMSession();
 
 		void sessionInitReplyReceived(const LLUUID& new_session_id);
-		void addMessagesFromHistory(const std::list<LLSD>& history);
-		void addMessage(const std::string& from, const LLUUID& from_id, const std::string& utf8_text, const std::string& time, const bool is_history = false, bool is_region_msg = false);
-		void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction);
-		
+		void addMessagesFromHistoryCache(const std::list<LLSD>& history);        // From local file
+        void addMessagesFromServerHistory(const LLSD& history, const std::string& target_from, const std::string& target_message, U32 timestamp);  // From chat server
+		void addMessage(const std::string& from,
+                        const LLUUID& from_id,
+                        const std::string& utf8_text,
+                        const std::string& time,
+                        const bool is_history,
+                        const bool is_region_msg,
+                        U32 timestamp);
+
+        void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction);
+
 		/** @deprecated */
 		static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata);
 
@@ -112,6 +124,10 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 		uuid_vec_t mInitialTargetIDs;
 		std::string mHistoryFileName;
 
+        // Saved messages from the last minute of history read from the local group chat cache file
+        std::string mLastHistoryCacheDateTime;
+        chat_message_list_t mLastHistoryCacheMsgs;
+
 		// connection to voice channel state change signal
 		boost::signals2::connection mVoiceChannelStateChangeConnection;
 
@@ -121,7 +137,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 		// does include all incoming messages
 		S32 mNumUnread;
 
-		std::list<LLSD> mMsgs;
+        chat_message_list_t mMsgs;
 
 		LLVoiceChannel* mVoiceChannel;
 		LLIMSpeakerMgr* mSpeakers;
@@ -208,29 +224,43 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	 * and also saved into a file if log2file is specified.
 	 * It sends new message signal for each added message.
 	 */
-	bool addMessage(const LLUUID& session_id, const std::string& from, const LLUUID& other_participant_id, const std::string& utf8_text, bool log2file = true, bool is_region_msg = false);
+	void addMessage(const LLUUID& session_id,
+                    const std::string& from,
+                    const LLUUID& other_participant_id,
+                    const std::string& utf8_text,
+                    bool log2file = true,
+                    bool is_region_msg = false,
+                    U32 time_stamp = 0);
+
+    void processAddingMessage(const LLUUID& session_id,
+                    const std::string& from,
+                    const LLUUID& from_id,
+                    const std::string& utf8_text,
+                    bool log2file,
+                    bool is_region_msg,
+                    U32 time_stamp);
 
 	/**
 	 * Similar to addMessage(...) above but won't send a signal about a new message added
 	 */
-	LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, 
-		const std::string& utf8_text, bool log2file = true, bool is_region_msg = false);
+	LLIMModel::LLIMSession* addMessageSilently(const LLUUID& session_id, const std::string& from, const LLUUID& from_id,
+		const std::string& utf8_text, bool log2file = true, bool is_region_msg = false, U32 timestamp = 0);
 
 	/**
 	 * Add a system message to an IM Model
 	 */
-	bool proccessOnlineOfflineNotification(const LLUUID& session_id, const std::string& utf8_text);
+	void proccessOnlineOfflineNotification(const LLUUID& session_id, const std::string& utf8_text);
 
 	/**
-	 * Get a session's name. 
-	 * For a P2P chat - it's an avatar's name, 
+	 * Get a session's name.
+	 * For a P2P chat - it's an avatar's name,
 	 * For a group chat - it's a group's name
 	 * For an incoming ad-hoc chat - is received from the server and is in a from of "<Avatar's name> Conference"
 	 *	It is updated in LLIMModel::LLIMSession's constructor to localize the "Conference".
 	 */
 	const std::string getName(const LLUUID& session_id) const;
 
-	/** 
+	/**
 	 * Get number of unread messages in a session with session_id
 	 * Returns -1 if the session with session_id doesn't exist
 	 */
@@ -282,7 +312,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	bool logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text);
 
 private:
-	
+
 	/**
 	 * Populate supplied std::list with messages starting from index specified by start_index without
 	 * emitting no unread messages signal.
@@ -292,7 +322,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	/**
 	 * Add message to a list of message associated with session specified by session_id
 	 */
-	bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg = false);
+	bool addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text, bool is_region_msg, U32 timestamp);
 
 };
 
@@ -334,7 +364,8 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 					U32 parent_estate_id = 0,
 					const LLUUID& region_id = LLUUID::null,
 					const LLVector3& position = LLVector3::zero,
-					bool is_region_msg = false);
+                    bool is_region_msg = false,
+                    U32 timestamp = 0);
 
 	void addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args);
 
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index af1c93f38379d2b38bc62dab4966c17f1589bdc1..67240ac7e7ff0b1bafcf14646cf4b3c92a8a4cec 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -529,7 +529,11 @@ BOOL get_is_item_worn(const LLUUID& id)
 	const LLViewerInventoryItem* item = gInventory.getItem(id);
 	if (!item)
 		return FALSE;
-
+    
+    if (item->getIsLinkType() && !gInventory.getItem(item->getLinkedUUID()))
+    {
+        return FALSE;
+    }
 	// Consider the item as worn if it has links in COF.
 	if (LLAppearanceMgr::instance().isLinkedInCOF(id))
 	{
@@ -787,7 +791,7 @@ void show_item_original(const LLUUID& item_uuid)
         LLPanelMainInventory* main_inventory = sidepanel_inventory->getMainInventoryPanel();
         if (main_inventory)
         {
-            main_inventory->resetFilters();
+            main_inventory->resetAllItemsFilters();
         }
         reset_inventory_filter();
 
@@ -795,6 +799,7 @@ void show_item_original(const LLUUID& item_uuid)
         {
             LLFloaterReg::toggleInstanceOrBringToFront("inventory");
         }
+        sidepanel_inventory->showInventoryPanel();
 
         const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX);
         if (gInventory.isObjectDescendentOf(gInventory.getLinkedItemID(item_uuid), inbox_id))
@@ -2650,7 +2655,12 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
     }
     else
     {
-        std::copy(selected_uuid_set.begin(), selected_uuid_set.end(), std::back_inserter(ids));
+        for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end();
+            it != end_it;
+            ++it)
+        {
+            ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+        }
     }
 
     // Check for actions that get handled in bulk
@@ -2711,7 +2721,7 @@ void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root
     }
     else if ("ungroup_folder_items" == action)
     {
-        if (selected_uuid_set.size() == 1)
+        if (ids.size() == 1)
         {
             LLInventoryCategory* inv_cat = gInventory.getCategory(*ids.begin());
             if (!inv_cat || LLFolderType::lookupIsProtectedType(inv_cat->getPreferredType()))
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 75dda5557d161d3e1c89777c97ef6601802c5b36..7ccb8b807d31279f2de6eac12bc217c6e00e822d 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -1639,6 +1639,9 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo
 		LL_WARNS(LOG_INV) << "Deleting non-existent object [ id: " << id << " ] " << LL_ENDL;
 		return;
 	}
+
+    //collect the links before removing the item from mItemMap
+    LLInventoryModel::item_array_t links = collectLinksTo(id);
 	
 	LL_DEBUGS(LOG_INV) << "Deleting inventory object " << id << LL_ENDL;
 	mLastItem = NULL;
@@ -1696,7 +1699,7 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo
 	// update is getting broken link info separately.
 	if (fix_broken_links && !is_link_type)
 	{
-		updateLinkedObjectsFromPurge(id);
+        rebuildLinkItems(links);
 	}
 	obj = nullptr; // delete obj
 	if (do_notify_observers)
@@ -1705,26 +1708,25 @@ void LLInventoryModel::deleteObject(const LLUUID& id, bool fix_broken_links, boo
 	}
 }
 
-void LLInventoryModel::updateLinkedObjectsFromPurge(const LLUUID &baseobj_id)
+void LLInventoryModel::rebuildLinkItems(LLInventoryModel::item_array_t& items)
 {
-	LLInventoryModel::item_array_t item_array = collectLinksTo(baseobj_id);
-
-	// REBUILD is expensive, so clear the current change list first else
-	// everything else on the changelist will also get rebuilt.
-	if (item_array.size() > 0)
-	{
-		notifyObservers();
-		for (LLInventoryModel::item_array_t::const_iterator iter = item_array.begin();
-			iter != item_array.end();
-			iter++)
-		{
-			const LLViewerInventoryItem *linked_item = (*iter);
-			const LLUUID &item_id = linked_item->getUUID();
-			if (item_id == baseobj_id) continue;
-			addChangedMask(LLInventoryObserver::REBUILD, item_id);
-		}
-		notifyObservers();
-	}
+    // REBUILD is expensive, so clear the current change list first else
+    // everything else on the changelist will also get rebuilt.
+    if (items.size() > 0)
+    {
+        notifyObservers();
+        for (LLInventoryModel::item_array_t::const_iterator iter = items.begin();
+            iter != items.end();
+            iter++)
+        {
+            const LLViewerInventoryItem *linked_item = (*iter);
+            if (linked_item)
+            {
+                addChangedMask(LLInventoryObserver::REBUILD, linked_item->getUUID());
+            }
+        }
+        notifyObservers();
+    }
 }
 
 // Add/remove an observer. If the observer is destroyed, be sure to
@@ -1954,18 +1956,20 @@ void LLInventoryModel::cache(
 		items,
 		INCLUDE_TRASH,
 		can_cache);
-	std::string inventory_filename = getInvCacheAddres(agent_id);
-	saveToFile(inventory_filename, categories, items);
-	std::string gzip_filename(inventory_filename);
+    // Use temporary file to avoid potential conflicts with other
+    // instances (even a 'read only' instance unzips into a file)
+    std::string temp_file = gDirUtilp->getTempFilename();
+	saveToFile(temp_file, categories, items);
+    std::string gzip_filename = getInvCacheAddres(agent_id);
 	gzip_filename.append(".gz");
-	if(gzip_file(inventory_filename, gzip_filename))
+	if(gzip_file(temp_file, gzip_filename))
 	{
-		LL_DEBUGS(LOG_INV) << "Successfully compressed " << inventory_filename << LL_ENDL;
-		LLFile::remove(inventory_filename);
+		LL_DEBUGS(LOG_INV) << "Successfully compressed " << temp_file << " to " << gzip_filename << LL_ENDL;
+		LLFile::remove(temp_file);
 	}
 	else
 	{
-		LL_WARNS(LOG_INV) << "Unable to compress " << inventory_filename << LL_ENDL;
+		LL_WARNS(LOG_INV) << "Unable to compress " << temp_file << " into " << gzip_filename << LL_ENDL;
 	}
 }
 
@@ -3038,6 +3042,7 @@ bool LLInventoryModel::saveToFile(const std::string& filename,
                 return false;
             }
         }
+        fileXML.flush();
 
         fileXML.close();
 
@@ -4597,7 +4602,6 @@ void LLInventoryModel::FetchItemHttpHandler::processData(LLSD & content, LLCore:
 	{
 		gInventory.updateItem(*it);
 	}
-	
 	gInventory.notifyObservers();
 	gViewerWindow->getWindow()->decBusyCount();
 }
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index cb960d8185cc79660195bdc357499b2d99d7dd1a..af9a020788b1e91708fbb9ebf7d65da2cd3826ef 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -445,7 +445,7 @@ class LLInventoryModel
 	void checkTrashOverflow();
 
 protected:
-	void updateLinkedObjectsFromPurge(const LLUUID& baseobj_id);
+    void rebuildLinkItems(LLInventoryModel::item_array_t& items);
 	
 	//--------------------------------------------------------------------
 	// Reorder
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index 406c8b89d0b48d0667d1167d4a19339282eb630a..4a9b471a47e22559c94f47ae71f84f074421162b 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -363,7 +363,7 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
 	//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.  
 	LLViewerRegion * region(gAgent.getRegion());
-	if (! region || gDisconnected)
+	if (! region || gDisconnected || LLApp::isExiting())
 	{
 		return;
 	}
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index 7e5a2b3950dd3853bc71904013e25e7aa89ec6f9..2c9ed26a39230a522b2bc2b5e4faee712f17f165 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -1631,6 +1631,7 @@ void LLInventoryPanel::purgeSelectedItems()
     if (inventory_selected.empty()) return;
     LLSD args;
     S32 count = inventory_selected.size();
+    std::vector<LLUUID> selected_items;
     for (std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin(), end_it = inventory_selected.end();
         it != end_it;
         ++it)
@@ -1640,27 +1641,23 @@ void LLInventoryPanel::purgeSelectedItems()
         LLInventoryModel::item_array_t items;
         gInventory.collectDescendents(item_id, cats, items, LLInventoryModel::INCLUDE_TRASH);
         count += items.size() + cats.size();
+        selected_items.push_back(item_id);
     }
     args["COUNT"] = count;
-    LLNotificationsUtil::add("PurgeSelectedItems", args, LLSD(), boost::bind(&LLInventoryPanel::callbackPurgeSelectedItems, this, _1, _2));
+    LLNotificationsUtil::add("PurgeSelectedItems", args, LLSD(), boost::bind(callbackPurgeSelectedItems, _1, _2, selected_items));
 }
 
-void LLInventoryPanel::callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response)
+// static
+void LLInventoryPanel::callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response, const std::vector<LLUUID> inventory_selected)
 {
-    if (!mFolderRoot.get()) return;
-
     S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
     if (option == 0)
     {
-        const std::set<LLFolderViewItem*> inventory_selected = mFolderRoot.get()->getSelectionList();
         if (inventory_selected.empty()) return;
 
-        std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin();
-        const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();
-        for (; it != it_end; ++it)
+        for (auto it : inventory_selected)
         {
-            LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID();
-            remove_inventory_object(item_id, NULL);
+            remove_inventory_object(it, NULL);
         }
     }
 }
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index d5219a22e7e21b2e08a0c8be82a9423add5de4d3..45e71539d1214d6406f2d2ad15da649783c2e40a 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -260,7 +260,7 @@ class LLInventoryPanel : public LLPanel
     // Clean up stuff when the folder root gets deleted
     void clearFolderRoot();
 
-    void callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response);
+    static void callbackPurgeSelectedItems(const LLSD& notification, const LLSD& response, const std::vector<LLUUID> inventory_selected);
 
 protected:
 	void openStartFolderOrMyInventory(); // open the first level of inventory
diff --git a/indra/newview/lllegacyatmospherics.cpp b/indra/newview/lllegacyatmospherics.cpp
index ce4ec668f144f0045fc24c77977c7ddbd26aeeff..a34dafb19a7ae2f69e6dba78525c779b1b979e59 100644
--- a/indra/newview/lllegacyatmospherics.cpp
+++ b/indra/newview/lllegacyatmospherics.cpp
@@ -482,7 +482,6 @@ void LLAtmospherics::updateFog(const F32 distance, const LLVector3& tosun_in)
 	{
         LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater();
 		F32 depth = water_height - camera_height;
-
 		LLColor4 water_fog_color(pwater->getWaterFogColor());
 
 		// adjust the color based on depth.  We're doing linear approximations
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index fb9885b454d930c13aba8ab5b93a0d2663519020..ba82ff0b0f685b35df8864ac152ab4a72319537d 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -62,6 +62,7 @@
 const S32 LOG_RECALL_SIZE = 2048;
 
 const std::string LL_IM_TIME("time");
+const std::string LL_IM_DATE_TIME("datetime");
 const std::string LL_IM_TEXT("message");
 const std::string LL_IM_FROM("from");
 const std::string LL_IM_FROM_ID("from_id");
@@ -133,14 +134,14 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
 	messages.back()[LL_IM_TEXT] = im_text;
 }
 
-std::string remove_utf8_bom(const char* buf)
+const char* remove_utf8_bom(const char* buf)
 {
-	std::string res(buf);
-	if (res[0] == (char)0xEF && res[1] == (char)0xBB && res[2] == (char)0xBF)
-	{
-		res.erase(0, 3);
+    const char* start = buf;
+	if (start[0] == (char)0xEF && start[1] == (char)0xBB && start[2] == (char)0xBF)
+	{   // If string starts with the magic bytes, return pointer after it.
+        start += 3;
 	}
-	return res;
+	return start;
 }
 
 class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
@@ -315,7 +316,7 @@ std::string LLLogChat::cleanFileName(std::string filename)
 	return filename;
 }
 
-std::string LLLogChat::timestamp(bool withdate)
+std::string LLLogChat::timestamp2LogString(U32 timestamp, bool withdate)
 {
 	std::string timeStr;
 	if (withdate)
@@ -333,7 +334,14 @@ std::string LLLogChat::timestamp(bool withdate)
 	}
 
 	LLSD substitution;
-	substitution["datetime"] = (S32)time_corrected();
+    if (timestamp == 0)
+    {
+        substitution["datetime"] = (S32)time_corrected();
+    }
+    else
+    {   // timestamp is correct utc already
+        substitution["datetime"] = (S32)timestamp;
+    }
 
 	LLStringUtil::format (timeStr, substitution);
 	return timeStr;
@@ -355,7 +363,7 @@ void LLLogChat::saveHistory(const std::string& filename,
 		llassert(tmp_filename.size());
 		return;
 	}
-	
+
 	llofstream file(LLLogChat::makeLogFileName(filename).c_str(), std::ios_base::app);
 	if (!file.is_open())
 	{
@@ -366,7 +374,7 @@ void LLLogChat::saveHistory(const std::string& filename,
 	LLSD item;
 
 	if (gSavedPerAccountSettings.getBOOL("LogTimestamp"))
-		 item["time"] = LLLogChat::timestamp(gSavedPerAccountSettings.getBOOL("LogTimestampDate"));
+		 item["time"] = LLLogChat::timestamp2LogString(0, gSavedPerAccountSettings.getBOOL("LogTimestampDate"));
 
 	item["from_id"]	= from_id;
 	item["message"]	= line;
@@ -374,7 +382,7 @@ void LLLogChat::saveHistory(const std::string& filename,
 	//adding "Second Life:" for all system messages to make chat log history parsing more reliable
 	if (from.empty() && from_id.isNull())
 	{
-		item["from"] = SYSTEM_FROM; 
+		item["from"] = SYSTEM_FROM;
 	}
 	else
 	{
@@ -393,37 +401,60 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
 {
 	if (file_name.empty())
 	{
-		LL_WARNS("LLLogChat::loadChatHistory") << "Session name is Empty!" << LL_ENDL;
+		LL_WARNS("LLLogChat::loadChatHistory") << "Local history file name is empty!" << LL_ENDL;
 		return ;
 	}
 
 	bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
 
-	LLFILE* fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
+    // Stat the file to find it and get the last history entry time
+    llstat stat_data;
+
+    std::string log_file_name = LLLogChat::makeLogFileName(file_name);
+    LL_DEBUGS("ChatHistory") << "First attempt to stat chat history file " << log_file_name << LL_ENDL;
+
+    S32 no_stat = LLFile::stat(log_file_name, &stat_data);
+
+    if (no_stat)
+    {
+        if (is_group)
+        {
+            std::string old_name(file_name);
+            old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size());     // trim off " (group)"
+            log_file_name = LLLogChat::makeLogFileName(old_name);
+            LL_DEBUGS("ChatHistory") << "Attempting to stat adjusted chat history file " << log_file_name << LL_ENDL;
+            no_stat = LLFile::stat(log_file_name, &stat_data);
+            if (!no_stat)
+            {   // Found it without "(group)", copy to new naming style.  We already have the mod time in stat_data
+                log_file_name = LLLogChat::makeLogFileName(file_name);
+                LL_DEBUGS("ChatHistory") << "Attempt to stat copied history file " << log_file_name << LL_ENDL;
+                LLFile::copy(LLLogChat::makeLogFileName(old_name), log_file_name);
+            }
+        }
+        if (no_stat)
+        {
+            log_file_name = LLLogChat::oldLogFileName(file_name);
+            LL_DEBUGS("ChatHistory") << "Attempt to stat old history file name " << log_file_name << LL_ENDL;
+            no_stat = LLFile::stat(log_file_name, &stat_data);
+            if (no_stat)
+            {
+                LL_DEBUGS("ChatHistory") << "No previous conversation log file found for " << file_name << LL_ENDL;
+                return;						//No previous conversation with this name.
+            }
+        }
+    }
+
+    // If we got here, we managed to stat the file.
+    // Open the file to read
+    LLFILE* fptr = LLFile::fopen(log_file_name, "r");       /*Flawfinder: ignore*/
 	if (!fptr)
-	{
-		if (is_group)
-		{
-			std::string old_name(file_name);
-			old_name.erase(old_name.size() - GROUP_CHAT_SUFFIX.size());
-			fptr = LLFile::fopen(LLLogChat::makeLogFileName(old_name), "r");
-			if (fptr)
-			{
-				fclose(fptr);
-				LLFile::copy(LLLogChat::makeLogFileName(old_name), LLLogChat::makeLogFileName(file_name));
-			}
-			fptr = LLFile::fopen(LLLogChat::makeLogFileName(file_name), "r");
-		}
-		if (!fptr)
-		{
-			fptr = LLFile::fopen(LLLogChat::oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
-			if (!fptr)
-			{
-				return;						//No previous conversation with this name.
-			}
-		}
+	{   // Ok, this is strange but not really tragic in the big picture of things
+        LL_WARNS("ChatHistory") << "Unable to read file " << log_file_name << " after stat was successful" << LL_ENDL;
+        return;
 	}
 
+    S32 save_num_messages = messages.size();
+
 	char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/
 	char *bptr;
 	S32 len;
@@ -441,6 +472,7 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
 	while (fgets(buffer, LOG_RECALL_SIZE, fptr)  && !feof(fptr))
 	{
 		len = strlen(buffer) - 1;		/*Flawfinder: ignore*/
+        // backfill any end of line characters with nulls
 		for (bptr = (buffer + len); (*bptr == '\n' || *bptr == '\r') && bptr>buffer; bptr--)	*bptr='\0';
 
 		if (firstline)
@@ -473,6 +505,10 @@ void LLLogChat::loadChatHistory(const std::string& file_name, std::list<LLSD>& m
 		}
 	}
 	fclose(fptr);
+
+    LL_DEBUGS("ChatHistory") << "Read " << (messages.size() - save_num_messages)
+        << " messages of chat history from " << log_file_name
+        << " file mod time " << (F64)stat_data.st_mtime << LL_ENDL;
 }
 
 bool LLLogChat::historyThreadsFinished(LLUUID session_id)
@@ -837,7 +873,8 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname)
 		{
 			//matching a timestamp
 			boost::match_results<std::string::const_iterator> matches;
-			if (ll_regex_match(remove_utf8_bom(buffer), matches, TIMESTAMP))
+            std::string line(remove_utf8_bom(buffer));
+			if (ll_regex_match(line, matches, TIMESTAMP))
 			{
 				result = true;
 			}
@@ -847,7 +884,7 @@ bool LLLogChat::isTranscriptFileFound(std::string fullname)
 	return result;
 }
 
-//*TODO mark object's names in a special way so that they will be distinguishable form avatar name 
+//*TODO mark object's names in a special way so that they will be distinguishable form avatar name
 //which are more strict by its nature (only firstname and secondname)
 //Example, an object's name can be written like "Object <actual_object's_name>"
 void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
@@ -865,7 +902,7 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 		ostr << '[' << timestamp << ']' << TWO_SPACES;
 	}
 	
-	//*TODO mark object's names in a special way so that they will be distinguishable form avatar name 
+	//*TODO mark object's names in a special way so that they will be distinguishable from avatar name 
 	//which are more strict by its nature (only firstname and secondname)
 	//Example, an object's name can be written like "Object <actual_object's_name>"
 	if (im[LL_IM_FROM].isDefined())
@@ -928,7 +965,9 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 		timestamp.erase(0, 1);
 		timestamp.erase(timestamp.length()-1, 1);
 
-		if (cut_off_todays_date)
+        im[LL_IM_DATE_TIME] = timestamp;    // Retain full date-time for merging chat histories
+
+        if (cut_off_todays_date)
 		{
 			LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp);
 		}
@@ -936,9 +975,9 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params
 		im[LL_IM_TIME] = timestamp;
 	}
 	else
-	{
-		//timestamp is optional
-		im[LL_IM_TIME] = "";
+	{   //timestamp is optional
+        im[LL_IM_DATE_TIME] = "";
+        im[LL_IM_TIME] = "";
 	}
 
 	bool has_stuff = matches[IDX_STUFF].matched;
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index c4b61ee716b56e1832e3a0e373a84c30ca559ca7..5dce8ab1d25443349737b0cac405ba0c3dccaeda 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -92,7 +92,7 @@ class LLLogChat : public LLSingleton<LLLogChat>
 		LOG_END
 	};
 
-	static std::string timestamp(bool withdate = false);
+	static std::string timestamp2LogString(U32 timestamp, bool withdate);
 	static std::string makeLogFileName(std::string(filename));
 	static void renameLogFile(const std::string& old_filename, const std::string& new_filename);
 	/**
@@ -201,6 +201,7 @@ extern const std::string GROUP_CHAT_SUFFIX;
 
 // LLSD map lookup constants
 extern const std::string LL_IM_TIME; //("time");
+extern const std::string LL_IM_DATE_TIME; //("datetime");
 extern const std::string LL_IM_TEXT; //("message");
 extern const std::string LL_IM_FROM; //("from");
 extern const std::string LL_IM_FROM_ID; //("from_id");
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 2d726409c6da24e67cb9e5282abdb90406934f35..6f3d40bb3aa5bf4824a10cd32c27d892bb298833 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -42,8 +42,8 @@
 #include "llviewermedia.h"
 #include "llviewernetwork.h"
 #include "llviewerregion.h"
-#include "reader.h" // JSON
-#include "writer.h" // JSON
+#include "json/reader.h" // JSON
+#include "json/writer.h" // JSON
 #include "lleventcoro.h"
 #include "llcoros.h"
 #include "llcorehttputil.h"
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index bf00d77dea955d897329eb9da79fffcbc09ea4d8..a7a7ed1b70b89ec154752b1b69bec1655752a36b 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -192,7 +192,7 @@ void LLMuteList::cleanupSingleton()
     LLAvatarNameCache::getInstance()->setAccountNameChangedCallback(NULL);
 }
 
-BOOL LLMuteList::isLinden(const std::string& name) const
+bool LLMuteList::isLinden(const std::string& name)
 {
 	std::string username = boost::replace_all_copy(name, ".", " ");
 	typedef boost::tokenizer<boost::char_separator<char> > tokenizer;
@@ -200,9 +200,9 @@ BOOL LLMuteList::isLinden(const std::string& name) const
 	tokenizer tokens(username, sep);
 	tokenizer::iterator token_iter = tokens.begin();
 	
-	if (token_iter == tokens.end()) return FALSE;
+	if (token_iter == tokens.end()) return false;
 	token_iter++;
-	if (token_iter == tokens.end()) return FALSE;
+	if (token_iter == tokens.end()) return false;
 	
 	std::string last_name = *token_iter;
 	LLStringUtil::toLower(last_name);
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 0d426fbd48438459ba10e43158810531be336233..2c45014321d5e4cfb6ce3f4c9bd4f003322a71af 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -104,7 +104,7 @@ class LLMuteList : public LLSingleton<LLMuteList>
 	// Alternate (convenience) form for places we don't need to pass the name, but do need flags
 	BOOL isMuted(const LLUUID& id, U32 flags) const { return isMuted(id, LLStringUtil::null, flags); };
 	
-	BOOL isLinden(const std::string& name) const;
+	static bool isLinden(const std::string& name);
 	
 	BOOL isLoaded() const { return mIsLoaded; }
 
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 39a0b9b50ed9f538367480befc5b217e13885ad9..85adfaab559f701c6df8e8d07138798a2eb14222 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -275,7 +275,7 @@ void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification)
 	LLSD offer;
 	offer["notification_id"] = notification->getID();
 	offer["from"] = SYSTEM_FROM;
-	offer["time"] = LLLogChat::timestamp(false);
+	offer["time"] = LLLogChat::timestamp2LogString(0, false);   // Use current time
 	offer["index"] = (LLSD::Integer)session->mMsgs.size();
 	session->mMsgs.push_front(offer);
 
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 9df3a8e31aaf4bd7428f5123e333c0cc4c4640c3..b14fdbf38e8601a0ac9318d8ced512c5a477ab9b 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -1103,6 +1103,18 @@ void LLPanelLogin::onRememberPasswordCheck(void*)
     if (sInstance)
     {
         gSavedSettings.setBOOL("UpdateRememberPasswordSetting", TRUE);
+
+        LLPointer<LLCredential> cred;
+        bool remember_user, remember_password;
+        getFields(cred, remember_user, remember_password);
+
+        std::string grid(LLGridManager::getInstance()->getGridId());
+        std::string user_id(cred->userID());
+        if (!remember_password)
+        {
+            gSecAPIHandler->removeFromProtectedMap("mfa_hash", grid, user_id);
+            gSecAPIHandler->syncProtectedMap();
+        }
     }
 }
 
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index f38357c5dae8f06a3a4ae6dab7e4e46726a242e1..b332de3f9898bf637cbee1b4104ca4a694c1b09d 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -411,6 +411,18 @@ void LLPanelMainInventory::resetFilters()
 	setFilterTextFromFilter();
 }
 
+void LLPanelMainInventory::resetAllItemsFilters()
+{
+    LLFloaterInventoryFinder *finder = getFinder();
+    getAllItemsPanel()->getFilter().resetDefault();
+    if (finder)
+    {
+        finder->updateElementsFromFilter();
+    }
+
+    setFilterTextFromFilter();
+}
+
 void LLPanelMainInventory::setSortBy(const LLSD& userdata)
 {
 	U32 sort_order_mask = getActivePanel()->getSortOrder();
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index 9a3647027396a9a6145d61d1062d5b2e586d5ea7..8f357d9e5a69e864093529a94ff94b5cf0a160d4 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -96,6 +96,7 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver
 	void toggleFindOptions();
 
     void resetFilters();
+    void resetAllItemsFilters();
 
 protected:
 	//
diff --git a/indra/newview/llpanelmediasettingsgeneral.cpp b/indra/newview/llpanelmediasettingsgeneral.cpp
index 416857bd305f2b22567a03381c30065d14c2a65f..8380394f2cc2c4b2f5d8bd0b459d142d31974932 100644
--- a/indra/newview/llpanelmediasettingsgeneral.cpp
+++ b/indra/newview/llpanelmediasettingsgeneral.cpp
@@ -39,6 +39,7 @@
 #include "llagent.h"
 #include "llviewerwindow.h"
 #include "llviewermedia.h"
+#include "llvovolume.h"
 #include "llsdutil.h"
 #include "llselectmgr.h"
 #include "llbutton.h"
@@ -452,10 +453,17 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_
 					{
 						viewer_media_t media_impl =
 							LLViewerMedia::getInstance()->getMediaImplFromTextureID(object->getTE(face)->getMediaData()->getMediaID());
-						if(media_impl)
-						{
+                        if (media_impl)
+                        {
                             media_impl->setPriority(LLPluginClassMedia::PRIORITY_NORMAL);
                             media_impl->navigateHome();
+
+                            if (!only_if_current_is_empty)
+                            {
+                                LLSD media_data;
+                                media_data[LLMediaEntry::CURRENT_URL_KEY] = std::string();
+                                object->getTE(face)->mergeIntoMediaData(media_data);
+                            }
 							return true;
 						}
 					}
@@ -471,6 +479,23 @@ bool LLPanelMediaSettingsGeneral::navigateHomeSelectedFace(bool only_if_current_
 	LLObjectSelectionHandle selected_objects =LLSelectMgr::getInstance()->getSelection();
 	selected_objects->getSelectedTEValue( &functor_navigate_media, all_face_media_navigated );
 	
+    if (all_face_media_navigated)
+    {
+        struct functor_sync_to_server : public LLSelectedObjectFunctor
+        {
+            virtual bool apply(LLViewerObject* object)
+            {
+                LLVOVolume *volume = dynamic_cast<LLVOVolume*>(object);
+                if (volume)
+                {
+                    volume->sendMediaDataUpdate();
+                }
+                return true;
+            }
+        } sendfunc;
+        selected_objects->applyToObjects(&sendfunc);
+    }
+
 	// Note: we don't update the 'current URL' field until the media data itself changes
 
 	return all_face_media_navigated;
diff --git a/indra/newview/llsceneview.cpp b/indra/newview/llsceneview.cpp
index e250f9bc7a998730c056b98cc448ad670f229f06..5e339a52bf1da57f3c522456fa88c1747c573bc5 100644
--- a/indra/newview/llsceneview.cpp
+++ b/indra/newview/llsceneview.cpp
@@ -207,7 +207,7 @@ void LLSceneView::draw()
 			for (U32 i = 0; i < count; ++i)
 			{
 				F32 rad = size[idx][i];
-				total += rad;	
+				total += rad;
 				F32 y = (rad-size_domain[0])/size_range*size_rect.getHeight()+size_rect.mBottom;
 				F32 x = (F32) i / count * size_rect.getWidth() + size_rect.mLeft;
 
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index d0da3387ec3c810a96a9a4c371cc32ca83ed27d9..8e8f2f4fe0efaefc1ae5f76adba634731a81c3b4 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -355,7 +355,7 @@ LLSD cert_name_from_X509_NAME(X509_NAME* name)
 		char buffer[32];
 		X509_NAME_ENTRY *entry = X509_NAME_get_entry(name, entry_index);
 		
-		std::string name_value = std::string((const char*)ASN1_STRING_data(X509_NAME_ENTRY_get_data(entry)), 
+		std::string name_value = std::string((const char*)ASN1_STRING_get0_data(X509_NAME_ENTRY_get_data(entry)), 
 											 ASN1_STRING_length(X509_NAME_ENTRY_get_data(entry)));
 
 		ASN1_OBJECT* name_obj = X509_NAME_ENTRY_get_object(entry);		
diff --git a/indra/newview/llskinningutil.cpp b/indra/newview/llskinningutil.cpp
index cf3519c1c7f3c0df69f0303c1851b341daccfcfa..8bdccfd9f6627bd0430fe0648a8447e1044f2e2f 100644
--- a/indra/newview/llskinningutil.cpp
+++ b/indra/newview/llskinningutil.cpp
@@ -264,6 +264,9 @@ void LLSkinningUtil::getPerVertexSkinMatrix(
     // SL-366 - with weight validation/cleanup code, it should no longer be
     // possible to hit the bad scale case.
     llassert(valid_weights);
+    // When building for Release, the above llassert() goes away. Ward off
+    // variable-set-but-unused error.
+    (void)valid_weights;
 }
 
 void LLSkinningUtil::initJointNums(LLMeshSkinInfo* skin, LLVOAvatar *avatar)
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index 69074b1670548593f16f5a058eb1805d1c9ba1ea..ab559f1e6f3279a584dc4ba33e6538874e7a47cd 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -35,6 +35,7 @@
 
 #include "llviewercontrol.h"
 #include "lltexteditor.h"
+#include <memory>
 
 #define MOUSE_LEAVE false
 #define MOUSE_ENTER true
@@ -222,7 +223,7 @@ class LLToast : public LLModalDialog, public LLInstanceTracker<LLToast>
 	LLPanel*	 mWrapperPanel;
 
 	// timer counts a lifetime of a toast
-	std::auto_ptr<LLToastLifeTimer> mTimer;
+	std::unique_ptr<LLToastLifeTimer> mTimer;
 
 	F32			mToastLifetime; // in seconds
 	F32			mToastFadingTime; // in seconds
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index 07f46c5fbe07e08669b25992412af8ab4d970162..4e94895a3ebac2889e9bfcf7908054377d535874 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -75,6 +75,7 @@ LLToolCamera::LLToolCamera()
 	mOutsideSlopX(FALSE),
 	mOutsideSlopY(FALSE),
 	mValidClickPoint(FALSE),
+    mClickPickPending(false),
 	mValidSelection(FALSE),
 	mMouseSteering(FALSE),
 	mMouseUpX(0),
@@ -127,6 +128,11 @@ BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask)
 
 	mValidClickPoint = FALSE;
 
+    // Sometimes Windows issues down and up events near simultaneously
+    // without giving async pick a chance to trigged
+    // Ex: mouse from numlock emulation
+    mClickPickPending = true;
+
 	// If mouse capture gets ripped away, claim we moused up
 	// at the point we moused down. JC
 	mMouseUpX = x;
@@ -142,13 +148,15 @@ BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask)
 
 void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
 {
-	if (!LLToolCamera::getInstance()->hasMouseCapture())
+    LLToolCamera* camera = LLToolCamera::getInstance();
+	if (!camera->mClickPickPending)
 	{
 		return;
 	}
+    camera->mClickPickPending = false;
 
-	LLToolCamera::getInstance()->mMouseDownX = pick_info.mMousePt.mX;
-	LLToolCamera::getInstance()->mMouseDownY = pick_info.mMousePt.mY;
+    camera->mMouseDownX = pick_info.mMousePt.mX;
+    camera->mMouseDownY = pick_info.mMousePt.mY;
 
 	gViewerWindow->moveCursorToCenter();
 
@@ -158,7 +166,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
 	// Check for hit the sky, or some other invalid point
 	if (!hit_obj && pick_info.mPosGlobal.isExactlyZero())
 	{
-		LLToolCamera::getInstance()->mValidClickPoint = FALSE;
+        camera->mValidClickPoint = FALSE;
 		return;
 	}
 
@@ -168,7 +176,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
 		LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
 		if (!selection->getObjectCount() || selection->getSelectType() != SELECT_TYPE_HUD)
 		{
-			LLToolCamera::getInstance()->mValidClickPoint = FALSE;
+            camera->mValidClickPoint = FALSE;
 			return;
 		}
 	}
@@ -192,7 +200,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
 
 		if( !good_customize_avatar_hit )
 		{
-			LLToolCamera::getInstance()->mValidClickPoint = FALSE;
+            camera->mValidClickPoint = FALSE;
 			return;
 		}
 
@@ -237,7 +245,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
 
 	}
 
-	LLToolCamera::getInstance()->mValidClickPoint = TRUE;
+    camera->mValidClickPoint = TRUE;
 
 	if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
 	{
@@ -284,32 +292,36 @@ BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask)
 
 	if (hasMouseCapture())
 	{
-		if (mValidClickPoint)
-		{
-			if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode() )
-			{
-				LLCoordGL mouse_pos;
-				LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgentCamera.getFocusGlobal());
-				BOOL success = LLViewerCamera::getInstance()->projectPosAgentToScreen(focus_pos, mouse_pos);
-				if (success)
-				{
-					LLUI::getInstance()->setMousePositionScreen(mouse_pos.mX, mouse_pos.mY);
-				}
-			}
-			else if (mMouseSteering)
-			{
-				LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY);
-			}
-			else
-			{
-				gViewerWindow->moveCursorToCenter();
-			}
-		}
-		else
-		{
-			// not a valid zoomable object
-			LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY);
-		}
+        // Do not move camera if we haven't gotten a pick
+        if (!mClickPickPending)
+        {
+            if (mValidClickPoint)
+            {
+                if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgentCamera.getCameraMode())
+                {
+                    LLCoordGL mouse_pos;
+                    LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgentCamera.getFocusGlobal());
+                    BOOL success = LLViewerCamera::getInstance()->projectPosAgentToScreen(focus_pos, mouse_pos);
+                    if (success)
+                    {
+                        LLUI::getInstance()->setMousePositionScreen(mouse_pos.mX, mouse_pos.mY);
+                    }
+                }
+                else if (mMouseSteering)
+                {
+                    LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY);
+                }
+                else
+                {
+                    gViewerWindow->moveCursorToCenter();
+                }
+            }
+            else
+            {
+                // not a valid zoomable object
+                LLUI::getInstance()->setMousePositionScreen(mMouseDownX, mMouseDownY);
+            }
+        }
 
 		// calls releaseMouse() internally
 		setMouseCapture(FALSE);
diff --git a/indra/newview/lltoolfocus.h b/indra/newview/lltoolfocus.h
index cfc235b6c2a411fba999d95e0de805f7fb13b532..ef71f9230a701b209c7cb3db64b9fa93f151bfeb 100644
--- a/indra/newview/lltoolfocus.h
+++ b/indra/newview/lltoolfocus.h
@@ -49,6 +49,7 @@ class LLToolCamera
 
 	virtual LLTool*	getOverrideTool(MASK mask) { return NULL; }
 
+    void setClickPickPending() { mClickPickPending = true; }
 	static void pickCallback(const LLPickInfo& pick_info);
 	BOOL mouseSteerMode() { return mMouseSteering; }
 
@@ -65,6 +66,7 @@ class LLToolCamera
 	BOOL	mOutsideSlopX;
 	BOOL	mOutsideSlopY;
 	BOOL	mValidClickPoint;
+    bool	mClickPickPending;
 	BOOL	mValidSelection;
 	BOOL	mMouseSteering;
 	S32		mMouseUpX;	// needed for releaseMouse()
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index dcc528e8873905a6dd40b488c6faa724b1356462..2c5b8ffae4526ef69c38324e7472c375397930ac 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -443,6 +443,7 @@ BOOL LLToolPie::handleLeftClickPick()
 		LLToolMgr::getInstance()->setTransientTool(LLToolCamera::getInstance());
 		gViewerWindow->hideCursor();
 		LLToolCamera::getInstance()->setMouseCapture(TRUE);
+        LLToolCamera::getInstance()->setClickPickPending();
 		LLToolCamera::getInstance()->pickCallback(mPick);
 		gAgentCamera.setFocusOnAvatar(TRUE, TRUE);
 
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index a2c696c762fbcb9599da8452643e696e1cf81b7a..34d3ed8bb10a4956c624ed7f7e9cebaf298c49de 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -36,7 +36,7 @@
 #include "llversioninfo.h"
 #include "llviewercontrol.h"
 #include "llcoros.h"
-#include "reader.h"
+#include "json/reader.h"
 #include "llcorehttputil.h"
 #include "llurlregistry.h"
 
@@ -546,6 +546,18 @@ void LLBingTranslationHandler::verifyKey(const std::string &key, LLTranslate::Ke
 }
 
 //=========================================================================
+LLTranslate::LLTranslate():
+	mCharsSeen(0),
+	mCharsSent(0),
+	mFailureCount(0),
+	mSuccessCount(0)
+{
+}
+
+LLTranslate::~LLTranslate()
+{
+}
+
 /*static*/
 void LLTranslate::translateMessage(const std::string &from_lang, const std::string &to_lang,
     const std::string &mesg, TranslationSuccess_fn success, TranslationFailure_fn failure)
@@ -634,6 +646,43 @@ bool LLTranslate::isTranslationConfigured()
 	return getPreferredHandler().isConfigured();
 }
 
+void LLTranslate::logCharsSeen(size_t count)
+{
+	mCharsSeen += count;
+}
+
+void LLTranslate::logCharsSent(size_t count)
+{
+	mCharsSent += count;
+}
+
+void LLTranslate::logSuccess(S32 count)
+{
+	mSuccessCount += count;
+}
+
+void LLTranslate::logFailure(S32 count)
+{
+	mFailureCount += count;
+}
+
+LLSD LLTranslate::asLLSD() const
+{
+	LLSD res;
+	bool on = gSavedSettings.getBOOL("TranslateChat");
+	res["on"] = on;
+	res["chars_seen"] = (S32) mCharsSeen;
+	if (on)
+	{
+		res["chars_sent"] = (S32) mCharsSent;
+		res["success_count"] = mSuccessCount;
+		res["failure_count"] = mFailureCount;
+		res["language"] = getTranslateLanguage();  
+		res["service"] = gSavedSettings.getString("TranslationService");
+	}
+	return res;
+}
+
 // static
 LLTranslationAPIHandler& LLTranslate::getPreferredHandler()
 {
diff --git a/indra/newview/lltranslate.h b/indra/newview/lltranslate.h
index e0722fbd83f92dce9b41c58012e19875893d6621..58707e2d3620e1c0f8b59d24be16f2f7a546b9b3 100644
--- a/indra/newview/lltranslate.h
+++ b/indra/newview/lltranslate.h
@@ -30,6 +30,8 @@
 #include "llbufferstream.h"
 #include <boost/function.hpp>
 
+#include "llsingleton.h"
+
 namespace Json
 {
     class Value;
@@ -48,8 +50,10 @@ class LLTranslationAPIHandler;
  *
  * API keys for translation are taken from saved settings.
  */
-class LLTranslate
+class LLTranslate: public LLSingleton<LLTranslate>
 {
+	LLSINGLETON(LLTranslate);
+	~LLTranslate();
 	LOG_CLASS(LLTranslate);
 
 public :
@@ -94,9 +98,19 @@ public :
     static std::string addNoTranslateTags(std::string mesg);
     static std::string removeNoTranslateTags(std::string mesg);
 
+	void logCharsSeen(size_t count);
+	void logCharsSent(size_t count);
+	void logSuccess(S32 count);
+	void logFailure(S32 count);
+	LLSD asLLSD() const;
 private:
 	static LLTranslationAPIHandler& getPreferredHandler();
 	static LLTranslationAPIHandler& getHandler(EService service);
+
+	size_t mCharsSeen;
+	size_t mCharsSent;
+	S32 mFailureCount;
+	S32 mSuccessCount;
 };
 
 #endif
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 323190a04c5530463aa8902e05a14ce3bc1b9565..a2b0b04092f8a2a8d42fd2b429d0cf709b52edc4 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -788,7 +788,7 @@ bool LLBufferedAssetUploadInfo::failedUpload(LLSD &result, std::string &reason)
 LLScriptAssetUpload::LLScriptAssetUpload(LLUUID itemId, std::string buffer, invnUploadFinish_f finish, uploadFailed_f failed):
     LLBufferedAssetUploadInfo(itemId, LLAssetType::AT_LSL_TEXT, buffer, finish, failed),
     mExerienceId(),
-    mTargetType(LSL2),
+    mTargetType(MONO),
     mIsRunning(false)
 {
 }
@@ -809,7 +809,7 @@ LLSD LLScriptAssetUpload::generatePostBody()
     if (getTaskId().isNull())
     {
         body["item_id"] = getItemId();
-        body["target"] = "lsl2";
+        body["target"] = "mono";
     }
     else
     {
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 4ecb54aa0fee2da09e99f1d2680790d998c8c902..7c4bd2b0698c76634d4f2f425eab21174055641e 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1911,7 +1911,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 				log_message = LLTrans::getString("InvOfferDecline", log_message_args);
 			}
 			chat.mText = log_message;
-			if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::getInstance()->isLinden(mFromName) )  // muting for SL-42269
+			if( LLMuteList::getInstance()->isMuted(mFromID ) && ! LLMuteList::isLinden(mFromName) )  // muting for SL-42269
 			{
 				chat.mMuted = TRUE;
 				accept_to_trash = false; // will send decline message
@@ -2430,6 +2430,7 @@ void translateSuccess(LLChat chat, LLSD toastArgs, std::string originalMsg, std:
         chat.mText += " (" + LLTranslate::removeNoTranslateTags(translation) + ")";
     }
 
+	LLTranslate::instance().logSuccess(1);
     LLNotificationsUI::LLNotificationManager::instance().onChat(chat, toastArgs);
 }
 
@@ -2439,6 +2440,7 @@ void translateFailure(LLChat chat, LLSD toastArgs, int status, const std::string
     LLStringUtil::replaceString(msg, "\n", " "); // we want one-line error messages
     chat.mText += " (" + msg + ")";
 
+	LLTranslate::instance().logFailure(1);
     LLNotificationsUI::LLNotificationManager::instance().onChat(chat, toastArgs);
 }
 
@@ -2516,7 +2518,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		LLMute::flagTextChat) 
 		|| LLMuteList::getInstance()->isMuted(owner_id, LLMute::flagTextChat);
 	is_linden = chat.mSourceType != CHAT_SOURCE_OBJECT &&
-		LLMuteList::getInstance()->isLinden(from_name);
+		LLMuteList::isLinden(from_name);
 
 	if (is_muted && (chat.mSourceType == CHAT_SOURCE_OBJECT))
 	{
@@ -2673,6 +2675,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		LLSD args;
 		chat.mOwnerID = owner_id;
 
+		LLTranslate::instance().logCharsSeen(mesg.size());
 		if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM)
 		{
 			if (chat.mChatStyle == CHAT_STYLE_IRC)
@@ -2682,6 +2685,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 			const std::string from_lang = ""; // leave empty to trigger autodetect
 			const std::string to_lang = LLTranslate::getTranslateLanguage();
 
+			LLTranslate::instance().logCharsSent(mesg.size());
             LLTranslate::translateMessage(from_lang, to_lang, mesg,
                 boost::bind(&translateSuccess, chat, args, mesg, from_lang, _1, _2),
                 boost::bind(&translateFailure, chat, args, _1, _2));
@@ -5821,8 +5825,12 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
 			{
 				count++;
 				known_questions |= script_perm.permbit;
-				// check whether permission question should cause special caution dialog
-				caution |= (script_perm.caution);
+
+                if (!LLMuteList::isLinden(owner_name))
+                {
+                    // check whether permission question should cause special caution dialog
+                    caution |= (script_perm.caution);
+                }
 
 				if (("ScriptTakeMoney" == script_perm.question) && has_not_only_debit)
 					continue;
@@ -6348,7 +6356,7 @@ bool teleport_request_callback(const LLSD& notification, const LLSD& response)
 	LLAvatarName av_name;
 	LLAvatarNameCache::get(from_id, &av_name);
 
-	if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::getInstance()->isLinden(av_name.getUserName()))
+	if(LLMuteList::getInstance()->isMuted(from_id) && !LLMuteList::isLinden(av_name.getUserName()))
 	{
 		return false;
 	}
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index bb22d90cd98e8a23a4c55a243a5ce1f6ba98db39..ea2a955ab1a682554e4f6d0f7c1c577f24d18ef8 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -842,7 +842,10 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
 	{
 		virtual bool apply(LLViewerObject* objectp)
 		{
-			objectp->boostTexturePriority();
+            if (objectp)
+            {
+                objectp->boostTexturePriority();
+            }
 			return true;
 		}
 	} func;
diff --git a/indra/newview/llviewerprecompiledheaders.cpp b/indra/newview/llviewerprecompiledheaders.cpp
deleted file mode 100644
index 307e9037269a6c6e4b7de41fcd8d58f4a13cd26a..0000000000000000000000000000000000000000
--- a/indra/newview/llviewerprecompiledheaders.cpp
+++ /dev/null
@@ -1,34 +0,0 @@
-/** 
- * @file llviewerprecompiledheaders.cpp
- * @brief precompiled headers for newview project
- *
- * $LicenseInfo:firstyear=2005&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-// source file that includes just the standard includes
-// newview.pch will be the pre-compiled header
-// llviewerprecompiledheaders.obj will contain the pre-compiled type information
-
-#include "llviewerprecompiledheaders.h"
-
-// TODO: reference any additional headers you need in llviewerprecompiledheaders.h
-// and not in this file
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index b1abd0a656941d051662f4496fcd08f4400cc642..986319f26d4789b4710e97ee8593b5bedb9ab282 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -64,6 +64,7 @@
 #include "llvoicevivox.h"
 #include "llinventorymodel.h"
 #include "lluiusage.h"
+#include "lltranslate.h"
 
 // "Minimal Vulkan" to get max API Version
 
@@ -524,6 +525,7 @@ void send_viewer_stats(bool include_preferences)
 	agent["meters_traveled"] = gAgent.getDistanceTraveled();
 	agent["regions_visited"] = gAgent.getRegionsVisited();
 	agent["mem_use"] = LLMemory::getCurrentRSS() / 1024.0;
+	agent["translation"] = LLTranslate::instance().asLLSD();
 
 	LLSD &system = body["system"];
 	
@@ -533,6 +535,7 @@ void send_viewer_stats(bool include_preferences)
     system["cpu_sse"] = gSysCPU.getSSEVersions();
 	system["address_size"] = ADDRESS_SIZE;
 	system["os_bitness"] = LLOSInfo::instance().getOSBitness();
+	system["hardware_concurrency"] = (LLSD::Integer) std::thread::hardware_concurrency();
 	unsigned char MACAddress[MAC_ADDRESS_BYTES];
 	LLUUID::getNodeID(MACAddress);
 	std::string macAddressString = llformat("%02x-%02x-%02x-%02x-%02x-%02x",
@@ -554,6 +557,7 @@ void send_viewer_stats(bool include_preferences)
 
 	gGLManager.asLLSD(system["gl"]);
 
+
 	S32 shader_level = 0;
 	if (LLPipeline::sRenderDeferred)
 	{
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index ec03556ff40739dbe53b7ab55ea4b9a008a066ff..ca8cdbaea9f72cc129f4c0de368960bd0c0349d0 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1066,7 +1066,7 @@ void LLViewerFetchedTexture::init(bool firstinit)
 	mLoadedCallbackDesiredDiscardLevel = S8_MAX;
 	mPauseLoadedCallBacks = FALSE;
 
-	mNeedsCreateTexture = FALSE;
+	mNeedsCreateTexture = false;
 	
 	mIsRawImageValid = FALSE;
 	mRawDiscardLevel = INVALID_DISCARD_LEVEL;
@@ -1346,12 +1346,12 @@ void LLViewerFetchedTexture::addToCreateTexture()
 	{
 		//just update some variables, not to create a real GL texture.
 		createGLTexture(mRawDiscardLevel, mRawImage, 0, FALSE);
-		mNeedsCreateTexture = FALSE;
+		mNeedsCreateTexture = false;
 		destroyRawImage();
 	}
 	else if(!force_update && getDiscardLevel() > -1 && getDiscardLevel() <= mRawDiscardLevel)
 	{
-		mNeedsCreateTexture = FALSE;
+		mNeedsCreateTexture = false;
 		destroyRawImage();
 	}
 	else
@@ -1387,7 +1387,7 @@ void LLViewerFetchedTexture::addToCreateTexture()
 						mRawDiscardLevel += i;
 						if(mRawDiscardLevel >= getDiscardLevel() && getDiscardLevel() > 0)
 						{
-							mNeedsCreateTexture = FALSE;
+							mNeedsCreateTexture = false;
 							destroyRawImage();
 							return;
 						}
@@ -1419,7 +1419,7 @@ BOOL LLViewerFetchedTexture::preCreateTexture(S32 usename/*= 0*/)
         destroyRawImage();
         return FALSE;
     }
-    mNeedsCreateTexture = FALSE;
+    mNeedsCreateTexture = false;
 
     if (mRawImage.isNull())
     {
@@ -1554,7 +1554,7 @@ void LLViewerFetchedTexture::postCreateTexture()
         destroyRawImage();
     }
 
-    mNeedsCreateTexture = FALSE;
+    mNeedsCreateTexture = false;
 }
 
 void LLViewerFetchedTexture::scheduleCreateTexture()
@@ -1563,7 +1563,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
 
     if (!mNeedsCreateTexture)
     {
-        mNeedsCreateTexture = TRUE;
+        mNeedsCreateTexture = true;
         if (preCreateTexture())
         {
 #if LL_IMAGEGL_THREAD_CHECK
@@ -1577,7 +1577,7 @@ void LLViewerFetchedTexture::scheduleCreateTexture()
                 memcpy(data_copy, data, size);
             }
 #endif
-            mNeedsCreateTexture = TRUE;
+            mNeedsCreateTexture = true;
             auto mainq = LLImageGLThread::sEnabled ? mMainQueue.lock() : nullptr;
             if (mainq)
             {
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 1370f4debef4b41a2ccbfda9e4ae8dbd1f375c33..34118c86cd7d5a1f2b54c5e6cd3ebdad6a9a5348 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -27,6 +27,7 @@
 #ifndef LL_LLVIEWERTEXTURE_H					
 #define LL_LLVIEWERTEXTURE_H
 
+#include "llatomic.h"
 #include "llgltexture.h"
 #include "lltimer.h"
 #include "llframetimer.h"
@@ -512,7 +513,9 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	LLFrameTimer mStopFetchingTimer;	// Time since mDecodePriority == 0.f.
 
 	BOOL  mInImageList;				// TRUE if image is in list (in which case don't reset priority!)
-	BOOL  mNeedsCreateTexture;	
+	// This needs to be atomic, since it is written both in the main thread
+	// and in the GL image worker thread... HB
+	LLAtomicBool  mNeedsCreateTexture;	
 
 	BOOL   mForSculpt ; //a flag if the texture is used as sculpt data.
 	BOOL   mIsFetched ; //is loaded from remote or from cache, not generated locally.
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 0f89401bf1f3a6a30b41afcee061a2160021b7e1..09a1cd51480e6d54e3951f5dd92ec80891d89286 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1157,6 +1157,7 @@ F32 LLViewerTextureList::updateImagesFetchTextures(F32 max_time)
     for (auto& imagep : entries)
     {
         if (imagep->getNumRefs() > 1) // make sure this image hasn't been deleted before attempting to update (may happen as a side effect of some other image updating)
+
         {
             updateImageDecodePriority(imagep);
             imagep->updateFetch();
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 05fac036fb50fabbd2b6b46838c653f76660a22d..5adb3f9ede4c69a8d89cdc1686893890b38188d3 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -3531,14 +3531,15 @@ void LLVOAvatar::idleUpdateNameTagText(bool new_name)
 
 void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color, S32 style, const LLFontGL* font, const bool use_ellipses)
 {
+    // extra width (NAMETAG_MAX_WIDTH) is for names only, not for chat
 	llassert(mNameText);
 	if (mVisibleChat)
 	{
-		mNameText->addLabel(line);
+		mNameText->addLabel(line, LLHUDNameTag::NAMETAG_MAX_WIDTH);
 	}
 	else
 	{
-		mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses);
+		mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font, use_ellipses, LLHUDNameTag::NAMETAG_MAX_WIDTH);
 	}
     mNameIsSet |= !line.empty();
 }
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 8f0938d01efda29dbfd6296d2211c42bf94a97b5..c73f96da2d31a4fccea06d294a7b0049f83ef5bc 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -4525,7 +4525,7 @@ void LLVivoxVoiceClient::messageEvent(
 		{
 			bool is_do_not_disturb = gAgent.isDoNotDisturb();
 			bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat);
-			bool is_linden = LLMuteList::getInstance()->isLinden(session->mName);
+			bool is_linden = LLMuteList::isLinden(session->mName);
 			LLChat chat;
 
 			chat.mMuted = is_muted && !is_linden;
diff --git a/indra/newview/llwatchdog.cpp b/indra/newview/llwatchdog.cpp
index 0aa0280b25720b304c00ad249e4be4de8bfd9f70..ceff5cc8eeb97d54b82f6de89df76c42d697f419 100644
--- a/indra/newview/llwatchdog.cpp
+++ b/indra/newview/llwatchdog.cpp
@@ -222,18 +222,17 @@ void LLWatchdog::run()
 	if(current_run_delta > (WATCHDOG_SLEEP_TIME_USEC * TIME_ELAPSED_MULTIPLIER))
 	{
 		LL_INFOS() << "Watchdog thread delayed: resetting entries." << LL_ENDL;
-		std::for_each(mSuspects.begin(), 
-			mSuspects.end(), 
-			std::mem_fun(&LLWatchdogEntry::reset)
-			);
+		for (const auto& suspect : mSuspects)
+		{
+			suspect->reset();
+		}
 	}
 	else
 	{
 		SuspectsRegistry::iterator result = 
 			std::find_if(mSuspects.begin(), 
-				mSuspects.end(), 
-				std::not1(std::mem_fun(&LLWatchdogEntry::isAlive))
-				);
+				mSuspects.end(),
+				[](const LLWatchdogEntry* suspect){ return ! suspect->isAlive(); });
 		if(result != mSuspects.end())
 		{
 			// error!!!
diff --git a/indra/newview/llwebprofile.cpp b/indra/newview/llwebprofile.cpp
index 3cc82621c49d0722c073c88c26147a79c4c74d0a..f2d7e4585ae723347d87c3919ccd75f190e50ce9 100644
--- a/indra/newview/llwebprofile.cpp
+++ b/indra/newview/llwebprofile.cpp
@@ -42,7 +42,7 @@
 #include "llcorehttputil.h"
 
 // third-party
-#include "reader.h" // JSON
+#include "json/reader.h" // JSON
 
 /*
  * Workflow:
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index bba5f6dca6edd64496b9099d15219217fd2c6436..9fa3d18a4016d481649ee254d999b99a8c164213 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -766,13 +766,10 @@ void LLWorld::updateParticles()
 
 void LLWorld::renderPropertyLines()
 {
-	S32 region_count = 0;
-
 	for (region_list_t::iterator iter = mVisibleRegionList.begin();
 		 iter != mVisibleRegionList.end(); ++iter)
 	{
 		LLViewerRegion* regionp = *iter;
-		region_count++;
 		regionp->renderPropertyLines();
 	}
 }
diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp
index 4401f6105986596735b76718fba310a3f815a852..b816f9a3b5ec2a738aa8b32b3a6a4c7a208593b0 100644
--- a/indra/newview/llxmlrpclistener.cpp
+++ b/indra/newview/llxmlrpclistener.cpp
@@ -38,7 +38,13 @@
 // external library headers
 #include <boost/scoped_ptr.hpp>
 #include <boost/range.hpp>          // boost::begin(), boost::end()
+
+#ifdef LL_USESYSTEMLIBS
+#include <xmlrpc.h>
+#else
 #include <xmlrpc-epi/xmlrpc.h>
+#endif
+
 #include "curl/curl.h"
 
 // other Linden headers
@@ -343,7 +349,9 @@ class Poller
 		
 		switch (curlcode)
 		{
+#if CURLE_SSL_PEER_CERTIFICATE != CURLE_SSL_CACERT
 			case CURLE_SSL_PEER_CERTIFICATE:
+#endif
 			case CURLE_SSL_CACERT:
                 data["certificate"] = mTransaction->getErrorCertData();
 				break;
diff --git a/indra/newview/llxmlrpctransaction.cpp b/indra/newview/llxmlrpctransaction.cpp
index 20084aa5d12dca826133c4553d62c9fc089ef03e..1760ccde1f8405c5afd55a3f56503302671b8dac 100644
--- a/indra/newview/llxmlrpctransaction.cpp
+++ b/indra/newview/llxmlrpctransaction.cpp
@@ -44,7 +44,12 @@
 #include "llviewercontrol.h"
 
 // Have to include these last to avoid queue redefinition!
+
+#ifdef LL_USESYSTEMLIBS
+#include <xmlrpc.h>
+#else
 #include <xmlrpc-epi/xmlrpc.h>
+#endif
 // <xmlrpc-epi/queue.h> contains a harmful #define queue xmlrpc_queue. This
 // breaks any use of std::queue. Ditch that #define: if any of our code wants
 // to reference xmlrpc_queue, let it reference it directly.
@@ -514,10 +519,11 @@ void LLXMLRPCTransaction::Impl::setHttpStatus(const LLCore::HttpStatus &status)
 		message = LLTrans::getString("couldnt_resolve_host", args);
 		break;
 
+#if CURLE_SSL_PEER_CERTIFICATE != CURLE_SSL_CACERT
 	case CURLE_SSL_PEER_CERTIFICATE:
 		message = LLTrans::getString("ssl_peer_certificate");
 		break;
-
+#endif
 	case CURLE_SSL_CACERT:
 	case CURLE_SSL_CONNECT_ERROR:		
 		message = LLTrans::getString("ssl_connect_error");
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index eaec698f84028f2c79f856b6039826829f599ab2..991e694cfc7853c53969b1a11853323d400fbc5f 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1677,20 +1677,17 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable)
 void LLPipeline::removeMutedAVsLights(LLVOAvatar* muted_avatar)
 {
     LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE;
-    light_set_t::iterator iter = gPipeline.mNearbyLights.begin();
-
-    while (iter != gPipeline.mNearbyLights.end())
-    {
-        if (iter->drawable->getVObj()->isAttachment() && iter->drawable->getVObj()->getAvatar() == muted_avatar)
-        {
-            gPipeline.mLights.erase(iter->drawable);
-            iter = gPipeline.mNearbyLights.erase(iter);
-        }
-        else
-        {
-            iter++;
-        }
-    }
+	for (light_set_t::iterator iter = gPipeline.mNearbyLights.begin();
+		 iter != gPipeline.mNearbyLights.end(); iter++)
+	{
+        const LLViewerObject *vobj = iter->drawable->getVObj();
+        if (vobj && vobj->getAvatar()
+            && vobj->isAttachment() && vobj->getAvatar() == muted_avatar)
+		{
+			gPipeline.mLights.erase(iter->drawable);
+			gPipeline.mNearbyLights.erase(iter);
+		}
+	}
 }
 
 U32 LLPipeline::addObject(LLViewerObject *vobj)
diff --git a/indra/newview/skins/default/xui/de/floater_tools.xml b/indra/newview/skins/default/xui/de/floater_tools.xml
index a4dfde66bcccd4d942b72d4e9c830eb4ae443cf7..f6208e11a5d956a9e3f0983fa4addba481c7f09a 100644
--- a/indra/newview/skins/default/xui/de/floater_tools.xml
+++ b/indra/newview/skins/default/xui/de/floater_tools.xml
@@ -40,7 +40,7 @@
 		Klicken und ziehen, um Land auszuwählen
 	</floater.string>
 	<floater.string name="status_selectcount">
-		[OBJ_COUNT] Objekte ausgewählt, Auswirkung auf Land [LAND_IMPACT]
+		[OBJ_COUNT] Objekte ausgewählt, Auswirkung auf Land [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
 	</floater.string>
 	<floater.string name="status_remaining_capacity">
 		Verbleibende Kapazität [LAND_CAPACITY].
diff --git a/indra/newview/skins/default/xui/en/floater_display_name.xml b/indra/newview/skins/default/xui/en/floater_display_name.xml
index 3c8f4158605579d383dfa14fdcad8c1e0fc97ecb..f3431da858d78c15e9ccdf10845dde815941c8cf 100644
--- a/indra/newview/skins/default/xui/en/floater_display_name.xml
+++ b/indra/newview/skins/default/xui/en/floater_display_name.xml
@@ -56,7 +56,7 @@
       max_length_chars="31"
       height="20"
       top_pad="5"
-      left="50" />
+      left_delta="0" />
 	<text
        top_pad="15"
        left="25"
@@ -72,23 +72,33 @@
       max_length_chars="31"
       height="20"
       top_pad="5"
-      left="50" />
+      left_delta="0" />
+    <button
+     label="Reset"
+     layout="topleft"
+     font="SansSerif"
+     width="120"
+     height="23"
+     top_pad="40"
+     left_delta="0"
+     name="reset_btn"
+     tool_tip="Use Username as a Display Name" />
     <button
      height="23"
      label="Save"
      layout="topleft"
      font="SansSerif"
-     left="35"
+     left_pad="35"
      name="save_btn"
      tool_tip="Save your new Display Name" 
-     top_pad="40"
+     top_delta="0"
      width="120" />
     <button
      height="23"
      label="Cancel"
      font="SansSerif"
      layout="topleft"
-     left_pad="125"
+     left_pad="5"
      name="cancel_btn"
      width="120" />
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
index 45e16c59ae3bef4be672e9861ee9eb6efc3f38c8..850e1be372db8639e780f47916c9d7780d693d10 100644
--- a/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
+++ b/indra/newview/skins/default/xui/en/floater_inventory_item_properties.xml
@@ -323,7 +323,6 @@
         follows="left|top"
         decimal_digits="0"
         increment="1"
-        control_name="Edit Cost"
         name="Edit Cost"
         label="Price:"
         label_width="100"
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index 4700488197dd1cc633d88bebe71c9d28741fac5c..1faf9c31522550044c08aef0844e6ab3fc353e7d 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -1140,7 +1140,6 @@ even though the user gets a free copy.
       decimal_digits="0"
       increment="1"
       left_pad="0"
-      control_name="Edit Cost"
       name="Edit Cost"
       label="L$"
       label_width="15"
diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
index 7ea87ee05c442542a9bcc79117d6b710e832c664..b9750284cdf29e61b30b00ada3d99bdc4c788bb4 100644
--- a/indra/newview/skins/default/xui/en/menu_participant_view.xml
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -90,7 +90,7 @@
          parameter="conversation_log" />
     </menu_item_check>
     <menu_item_separator layout="topleft" />
-    <menu_item_check name="Translate_chat" label="Translate Nearby chat">
+    <menu_item_check name="Translate_chat" label="Translate chat">
         <menu_item_check.on_click
          function="IMFloaterContainer.Action" 
          parameter="Translating.Toggle" />
diff --git a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
index 2316beeb36c8cef72fe69dbd28852a079081a0b1..4c566dc60a13ce971b51c2f840c132512b713ddc 100644
--- a/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_media_settings_general.xml
@@ -92,10 +92,7 @@
    label="Reset"
    left_delta="233" 
    name="current_url_reset_btn" 
-   width="110" > 
-   <button.commit_callback
-	     function="Media.ResetCurrentUrl"/>
-  </button>
+   width="110"/>
   <check_box 
    bottom_delta="-25" 
    enabled="true" 
diff --git a/indra/newview/skins/default/xui/en/panel_region_estate.xml b/indra/newview/skins/default/xui/en/panel_region_estate.xml
index 9b9c870c49f384ebd8a41ef55652b567df02232a..33e99a46aecf4a62d341ead9666955bb21e76679 100644
--- a/indra/newview/skins/default/xui/en/panel_region_estate.xml
+++ b/indra/newview/skins/default/xui/en/panel_region_estate.xml
@@ -82,7 +82,7 @@
     <view_border
      bevel_style="none"
      follows="top|left"
-     height="185"
+     height="205"
      layout="topleft"
      left="10"
      top_pad="5"
@@ -125,6 +125,16 @@
      tool_tip="Residents must have payment information on file to access this estate.  See the [SUPPORT_SITE] for more information."
      top_pad="2"
      width="278" />
+    <check_box
+     follows="top|left"
+     height="18"
+     label="Must not be a scripted agent"
+     layout="topleft"
+     left_delta="0"
+     name="limit_bots"
+     tool_tip="Residents must not be a scripted agents (bots) to access this estate.  See the [SUPPORT_SITE] for more information."
+     top_pad="2"
+     width="278" />
     <check_box
      height="18"
      label="Parcel owners can be more restrictive"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
index 9a68479d05c143907a5ef0d73ed09f28016ad986..35d14251c75ff85682cb7e15f1fe5bd5525a3405 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -450,7 +450,6 @@
         follows="left|top"
         decimal_digits="0"
         increment="1"
-        control_name="Edit Cost"
         name="Edit Cost"
         label="Price: L$"
         label_width="75"
@@ -461,8 +460,72 @@
         max_val="999999999"
         top_pad="10"
         tool_tip="Object cost." />
-    </panel>
-
+      <text
+        type="string"
+        length="1"
+        follows="left|top"
+        height="10"
+        layout="topleft"
+        left="10"
+        name="BaseMaskDebug"
+        text_color="White"
+        top_pad="30"
+        width="130">
+        B:
+      </text>
+      <text
+        type="string"
+        length="1"
+        follows="left|top"
+        height="10"
+        layout="topleft"
+        left_delta="60"
+        name="OwnerMaskDebug"
+        text_color="White"
+        top_delta="0"
+        width="270">
+        O:
+      </text>
+      <text
+        type="string"
+        length="1"
+        follows="left|top"
+        height="10"
+        layout="topleft"
+        left_delta="60"
+        name="GroupMaskDebug"
+        text_color="White"
+        top_delta="0"
+        width="210">
+        G:
+      </text>
+      <text
+        type="string"
+        length="1"
+        follows="left|top"
+        height="10"
+        layout="topleft"
+        left_delta="60"
+        name="EveryoneMaskDebug"
+        text_color="White"
+        top_delta="0"
+        width="150">
+        E:
+      </text>
+      <text
+       type="string"
+       length="1"
+       follows="left|top"
+       height="10"
+       layout="topleft"
+       left_delta="60"
+       name="NextMaskDebug"
+       text_color="White"
+       top_delta="0"
+       width="90">
+        N:
+      </text>
+    </panel>   
   </scroll_container>
   <panel
     height="30"
diff --git a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
index 1c9d750aa638cd4b8cc2f480157248b46f22eb07..0b32215964bbb0a548b303b01802b1057692fd1f 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -454,7 +454,6 @@
         increment="1"
         top_pad="10"
         left="120"
-        control_name="Edit Cost"
         name="Edit Cost"
         label="Price: L$"
         label_width="73"				
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 67ea085c559f7fda1f33d81ec989ab9fa646028d..62b26da55289e237b71399df180fbed2df0d1a55 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -126,8 +126,8 @@ http://secondlife.com/download
 
 For more information, see our FAQ below:
 http://secondlife.com/viewer-access-faq</string>
-	<string name="LoginFailed">Grid emergency login failure.
-If you feel this is an error, please contact support@secondlife.com.</string>
+	<string name="LoginFailed">"Login process did not complete due to system issues. Try again in a few minutes.
+If you feel this is an error, contact Support at https://support.secondlife.com"</string>
 	<string name="LoginIntermediateOptionalUpdateAvailable">Optional viewer update available: [VERSION]</string>
 	<string name="LoginFailedRequiredUpdate">Required viewer update: [VERSION]</string>
 	<string name="LoginFailedAlreadyLoggedIn">This agent is already logged in.
diff --git a/indra/newview/skins/default/xui/es/floater_tools.xml b/indra/newview/skins/default/xui/es/floater_tools.xml
index 6fce98472d1d5715a76f457dfdd3256e86c2180b..ffa85a2f04221e19cadf85cfddd415502784251b 100644
--- a/indra/newview/skins/default/xui/es/floater_tools.xml
+++ b/indra/newview/skins/default/xui/es/floater_tools.xml
@@ -25,7 +25,7 @@
 		Pulsa y arrastra para seleccionar el terreno.
 	</floater.string>
 	<floater.string name="status_selectcount">
-		[OBJ_COUNT] objetos seleccionados, impacto en el terreno [LAND_IMPACT]
+		[OBJ_COUNT] objetos seleccionados, impacto en el terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
 	</floater.string>
 	<floater.string name="status_remaining_capacity">
 		Capacidad restante [LAND_CAPACITY].
diff --git a/indra/newview/skins/default/xui/fr/floater_tools.xml b/indra/newview/skins/default/xui/fr/floater_tools.xml
index 9597d38dcab206587c333bbc9541d552daea738d..c161f3f5306de68d1a20d0a607a2278abea1e613 100644
--- a/indra/newview/skins/default/xui/fr/floater_tools.xml
+++ b/indra/newview/skins/default/xui/fr/floater_tools.xml
@@ -40,7 +40,7 @@
 		Cliquez et faites glisser pour sélectionner le terrain.
 	</floater.string>
 	<floater.string name="status_selectcount">
-		[OBJ_COUNT] objets sélectionnés, impact sur le terrain [LAND_IMPACT]
+		[OBJ_COUNT] objets sélectionnés, impact sur le terrain [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
 	</floater.string>
 	<floater.string name="status_remaining_capacity">
 		Capacité restante [LAND_CAPACITY].
diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml
index a21ae9a485ad110fac397d7888d49c694463c902..f98a2da277cbec7800ecd769f473537064e078f1 100644
--- a/indra/newview/skins/default/xui/it/floater_tools.xml
+++ b/indra/newview/skins/default/xui/it/floater_tools.xml
@@ -40,7 +40,7 @@
 		Clicca e trascina per selezionare il terreno
 	</floater.string>
 	<floater.string name="status_selectcount">
-		[OBJ_COUNT] oggetti selezionati, impatto terreno [LAND_IMPACT]
+		[OBJ_COUNT] oggetti selezionati, impatto terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
 	</floater.string>
 	<floater.string name="status_remaining_capacity">
 		Capacità restante [LAND_CAPACITY].
diff --git a/indra/newview/skins/default/xui/ja/floater_tools.xml b/indra/newview/skins/default/xui/ja/floater_tools.xml
index aec0dbdb555fa9cb77d5564eeba240b5ce7b9bbf..13f766698ebdd9746fa8f8c23dde2a150b6b851f 100644
--- a/indra/newview/skins/default/xui/ja/floater_tools.xml
+++ b/indra/newview/skins/default/xui/ja/floater_tools.xml
@@ -40,7 +40,7 @@
 		土地をクリックし、ドラッグして選択
 	</floater.string>
 	<floater.string name="status_selectcount">
-		選択されているオブジェクトは [OBJ_COUNT] 個、土地の負荷は [LAND_IMPACT]
+		選択されているオブジェクトは [OBJ_COUNT] 個、土地の負荷は [LAND_IMPACT] [secondlife:///app/openfloater/object_weights 詳細]
 	</floater.string>
 	<floater.string name="status_remaining_capacity">
 		残りの許容数 [LAND_CAPACITY]。
diff --git a/indra/newview/skins/default/xui/pl/floater_tools.xml b/indra/newview/skins/default/xui/pl/floater_tools.xml
index 5e2ed4a3510b46a42b5e662bf0b06ef00ef1628e..8932a86fd1c8588eadc0c576252e8411e1da7864 100644
--- a/indra/newview/skins/default/xui/pl/floater_tools.xml
+++ b/indra/newview/skins/default/xui/pl/floater_tools.xml
@@ -40,7 +40,7 @@
 		Kliknij i przeciągnij, aby zaznaczyć teren
 	</floater.string>
 	<floater.string name="status_selectcount">
-		[OBJ_COUNT] zaznaczonych obiektów, wpływ na strefę: [LAND_IMPACT]
+		[OBJ_COUNT] zaznaczonych obiektów, wpływ na strefę: [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
 	</floater.string>
 	<floater.string name="status_remaining_capacity">
 		Pojemność pozostała: [LAND_CAPACITY].
diff --git a/indra/newview/skins/default/xui/pt/floater_tools.xml b/indra/newview/skins/default/xui/pt/floater_tools.xml
index 0882f485a6e652b0911328b5b1dc385430b29b51..c0eab171c8bbdd39928e44f9cc88e64f93a9316f 100644
--- a/indra/newview/skins/default/xui/pt/floater_tools.xml
+++ b/indra/newview/skins/default/xui/pt/floater_tools.xml
@@ -40,7 +40,7 @@
 		Clicar e arrastar para selecionar a terra
 	</floater.string>
 	<floater.string name="status_selectcount">
-		[OBJ_COUNT] objetos selecionados, impacto no terreno [LAND_IMPACT]
+		[OBJ_COUNT] objetos selecionados, impacto no terreno [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
 	</floater.string>
 	<floater.string name="status_remaining_capacity">
 		Capacidade restante [LAND_CAPACITY].
diff --git a/indra/newview/skins/default/xui/ru/floater_tools.xml b/indra/newview/skins/default/xui/ru/floater_tools.xml
index 82ee3c49ae112976ff71d58d94935659a4b0c69c..44f54aabb6dfd00aea2739b67076b5d2fbe15072 100644
--- a/indra/newview/skins/default/xui/ru/floater_tools.xml
+++ b/indra/newview/skins/default/xui/ru/floater_tools.xml
@@ -40,7 +40,7 @@
 		Щелкните и перетащите для выделения земли
 	</floater.string>
 	<floater.string name="status_selectcount">
-		Выбрано объектов: [OBJ_COUNT], влияние на землю [LAND_IMPACT]
+		Выбрано объектов: [OBJ_COUNT], влияние на землю [LAND_IMPACT] [secondlife:///app/openfloater/object_weights ?]
 	</floater.string>
 	<floater.string name="status_remaining_capacity">
 		Остаток емкости [LAND_CAPACITY].
diff --git a/indra/newview/skins/default/xui/tr/floater_tools.xml b/indra/newview/skins/default/xui/tr/floater_tools.xml
index d6b9a4a533f79d4cb91b938908ec906dbfaa41c8..d48a617e388f01483405090a9b4b2e281f7cf630 100644
--- a/indra/newview/skins/default/xui/tr/floater_tools.xml
+++ b/indra/newview/skins/default/xui/tr/floater_tools.xml
@@ -40,7 +40,7 @@
 		Araziyi seçmek için tıklayın ve sürükleyin
 	</floater.string>
 	<floater.string name="status_selectcount">
-		[OBJ_COUNT] nesne seçili, [LAND_IMPACT] arazi etkisi
+		[OBJ_COUNT] nesne seçili, [LAND_IMPACT] arazi etkisi [secondlife:///app/openfloater/object_weights Ek bilgi]
 	</floater.string>
 	<floater.string name="status_remaining_capacity">
 		Kalan kapasite [LAND_CAPACITY].
diff --git a/indra/newview/skins/default/xui/zh/floater_tools.xml b/indra/newview/skins/default/xui/zh/floater_tools.xml
index 539c7454f1506453509da5697584e2a3bdceabb0..f83b058ce18b32196f875077a662324397e64d7e 100644
--- a/indra/newview/skins/default/xui/zh/floater_tools.xml
+++ b/indra/newview/skins/default/xui/zh/floater_tools.xml
@@ -40,7 +40,7 @@
 		按住並拖曳,可以選取土地
 	</floater.string>
 	<floater.string name="status_selectcount">
-		選取了 [OBJ_COUNT] 個物件,土地衝擊量 [LAND_IMPACT]
+		選取了 [OBJ_COUNT] 個物件,土地衝擊量 [LAND_IMPACT] [secondlife:///app/openfloater/object_weights 詳情]
 	</floater.string>
 	<floater.string name="status_remaining_capacity">
 		剩餘容納量 [LAND_CAPACITY]。
diff --git a/indra/newview/tests/llviewercontrollistener_test.cpp b/indra/newview/tests/llviewercontrollistener_test.cpp
index 6d100ef984b51aab980cff5e58043c51d04afc02..8aed2a80431f090de35097a4b19f770405787b35 100644
--- a/indra/newview/tests/llviewercontrollistener_test.cpp
+++ b/indra/newview/tests/llviewercontrollistener_test.cpp
@@ -10,9 +10,9 @@
  */
 
 // Precompiled header
-#include "llviewerprecompiledheaders.h"
+#include "../llviewerprecompiledheaders.h"
 // associated header
-#include "llviewercontrollistener.h"
+#include "../llviewercontrollistener.h"
 // STL headers
 // std headers
 // external library headers
@@ -21,7 +21,6 @@
 #include "../test/catch_and_store_what_in.h" // catch_what()
 #include "commoncontrol.h"
 #include "llcontrol.h"              // LLControlGroup
-#include "llviewercontrollistener.h"
 
 /*****************************************************************************
 *   TUT
diff --git a/indra/newview/tests/llvocache_test.cpp b/indra/newview/tests/llvocache_test.cpp
index ea6abe254ee19c27fb51346658295905ec22ddf0..c27730eb584b3fc4b76224466a5dc1773ac63964 100644
--- a/indra/newview/tests/llvocache_test.cpp
+++ b/indra/newview/tests/llvocache_test.cpp
@@ -28,15 +28,16 @@
 #include "../llviewerprecompiledheaders.h"
 #include "../test/lltut.h"
 
-#include "llvocache.h"
+#include "../llvocache.h"
 
 #include "lldir.h"
-#include "llhudobject.h"
+#include "../llhudobject.h"
 #include "llregionhandle.h"
 #include "llsdutil.h"
 #include "llsdserialize.h"
-#include "llviewerobjectlist.h"
-#include "llviewerregion.h"
+
+#include "../llviewerobjectlist.h"
+#include "../llviewerregion.h"
 
 #include "lldir_stub.cpp"
 #include "llvieweroctree_stub.cpp"
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 6d68fd545303d15d750444762ba1fe338cc6face..89481add2942377b764a9e90a05036691ba2604b 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -75,7 +75,7 @@ def construct(self):
                 # include the entire shaders directory recursively
                 self.path("shaders")
                 # include the extracted list of contributors
-                contributions_path = "../../doc/contributions.txt"
+                contributions_path = os.path.join(self.args['source'], "..", "..", "doc", "contributions.txt")
                 contributor_names = self.extract_names(contributions_path)
                 self.put_in_file(contributor_names.encode(), "contributors.txt", src=contributions_path)
 
@@ -435,7 +435,7 @@ def test_msvcrt_and_copy_action(self, src, dst):
             self.cmakedirs(os.path.dirname(dst))
             self.created_paths.append(dst)
             if not os.path.isdir(src):
-                if(self.args['configuration'].lower() == 'debug'):
+                if(self.args['buildtype'].lower() == 'debug'):
                     test_assembly_binding(src, "Microsoft.VC80.DebugCRT", "8.0.50727.4053")
                 else:
                     test_assembly_binding(src, "Microsoft.VC80.CRT", "8.0.50727.4053")
@@ -458,7 +458,7 @@ def test_for_no_msvcrt_manifest_and_copy_action(self, src, dst):
             self.created_paths.append(dst)
             if not os.path.isdir(src):
                 try:
-                    if(self.args['configuration'].lower() == 'debug'):
+                    if(self.args['buildtype'].lower() == 'debug'):
                         test_assembly_binding(src, "Microsoft.VC80.DebugCRT", "")
                     else:
                         test_assembly_binding(src, "Microsoft.VC80.CRT", "")
@@ -504,10 +504,10 @@ def construct(self):
         
         # Get shared libs from the shared libs staging directory
         with self.prefix(src=os.path.join(self.args['build'], os.pardir,
-                                          'sharedlibs', self.args['configuration'])):
+                                          'sharedlibs', self.args['buildtype'])):
             # Get fmodstudio dll if needed
             if self.args['fmodstudio'] == 'ON':
-                if(self.args['configuration'].lower() == 'debug'):
+                if(self.args['buildtype'].lower() == 'debug'):
                     self.path("fmodL.dll")
                 else:
                     self.path("fmod.dll")
@@ -603,7 +603,7 @@ def construct(self):
 
             # MSVC DLLs needed for CEF and have to be in same directory as plugin
             with self.prefix(src=os.path.join(self.args['build'], os.pardir,
-                                              'sharedlibs', 'Release')):
+                                              'sharedlibs', self.args['buildtype'])):
                 self.path("msvcp140.dll")
                 self.path("vcruntime140.dll")
                 self.path_optional("vcruntime140_1.dll")
@@ -909,7 +909,7 @@ def construct(self):
                     # Let exception, if any, propagate -- if this doesn't
                     # work, we need the build to noisily fail!
                     oldpath = subprocess.check_output(
-                        ['objdump', '-macho', '-dylib-id', '-non-verbose',
+                        ['objdump', '--macho', '--dylib-id', '--non-verbose',
                          os.path.join(relpkgdir, "BugsplatMac.framework", "BugsplatMac")]
                         ).splitlines()[-1]  # take the last line of output
                     self.run_command(
@@ -1040,7 +1040,7 @@ def path_optional(src, dst):
 
                 # Fmod studio dylibs (vary based on configuration)
                 if self.args['fmodstudio'] == 'ON':
-                    if self.args['configuration'].lower() == 'debug':
+                    if self.args['buildtype'].lower() == 'debug':
                         for libfile in (
                                     "libfmodL.dylib",
                                     ):
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index 084aa8d9f7fd35740fa3d5a879604fbf2c46590a..b7a39a745099428037a6cc2114e1e897d4ab4bd9 100644
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -5,35 +5,12 @@ project (lltest)
 include(00-Common)
 include(LLCommon)
 include(LLCoreHttp)
-include(LLInventory)
-include(LLMath)
-include(LLMessage)
-include(LLFileSystem)
-include(LLXML)
 include(Linking)
 include(Tut)
 include(LLAddBuildTest)
 include(bugsplat)
 include(GoogleMock)
 
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLCOREHTTP_INCLUDE_DIRS}
-    ${LLDATABASE_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLINVENTORY_INCLUDE_DIRS}
-    ${LLFILESYSTEM_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    ${LSCRIPT_INCLUDE_DIRS}
-    ${GOOGLEMOCK_INCLUDE_DIRS}
-    ${TUT_INCLUDE_DIR}
-    )
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLXML_SYSTEM_INCLUDE_DIRS}
-    )
-
 set(test_SOURCE_FILES
     io.cpp
     llapp_tut.cpp
@@ -76,39 +53,20 @@ if (NOT WINDOWS)
        )
 endif (NOT WINDOWS)
 
-set_source_files_properties(${test_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND test_SOURCE_FILES ${test_HEADER_FILES})
 
 add_executable(lltest ${test_SOURCE_FILES})
 
-if (USE_BUGSPLAT)
-  set_target_properties(lltest PROPERTIES COMPILE_DEFINITIONS "${BUGSPLAT_DEFINE}")
-endif (USE_BUGSPLAT)
-
 target_link_libraries(lltest
-    ${LEGACY_STDIO_LIBS}
-    ${LLDATABASE_LIBRARIES}
-    ${LLINVENTORY_LIBRARIES}
-    ${LLMESSAGE_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLFILESYSTEM_LIBRARIES}
-    ${LLXML_LIBRARIES}
-    ${LSCRIPT_LIBRARIES}
-    ${LLCOMMON_LIBRARIES}
-    ${LLCOREHTTP_LIBRARIES}
-    ${EXPAT_LIBRARIES}
-    ${GOOGLEMOCK_LIBRARIES}
-    ${PTHREAD_LIBRARY}
-    ${WINDOWS_LIBRARIES}
-    ${BOOST_PROGRAM_OPTIONS_LIBRARY}
-    ${BOOST_REGEX_LIBRARY}
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    ${BOOST_SYSTEM_LIBRARY}
-    ${DL_LIBRARY}
-    )
+        llinventory
+        llmessage
+        llmath
+        llfilesystem
+        llxml
+        llcommon
+        llcorehttp
+        ll::googlemock
+        )
 
 if (WINDOWS)
   set_target_properties(lltest
@@ -120,10 +78,10 @@ endif (WINDOWS)
 
 set(TEST_EXE $<TARGET_FILE:lltest>)
 
-SET_TEST_PATH(DYLD_LIBRARY_PATH)
+SET_TEST_PATH(LD_LIBRARY_PATH)
 
 LL_TEST_COMMAND(command 
-  "${DYLD_LIBRARY_PATH}"
+  "${LD_LIBRARY_PATH}"
   "${TEST_EXE}"
   "--output=${CMAKE_CURRENT_BINARY_DIR}/cpp_test_results.txt" 
   "--touch=${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt")
@@ -144,4 +102,13 @@ set(test_results ${CMAKE_CURRENT_BINARY_DIR}/cpp_tests_ok.txt)
 # developers choose to disable LL_TESTS.
 if (LL_TESTS)  
     add_custom_target(tests_ok ALL DEPENDS ${test_results})
+    if(DARWIN)
+      # Support our "@executable_path/../Resources" load path for our test
+      # executable. This SHOULD properly be "$<TARGET_FILE_DIR:lltest>/Resources",
+      # but the CMake $<TARGET_FILE_DIR> generator expression isn't evaluated by
+      # CREATE_LINK, so fudge it.
+      add_custom_command( TARGET lltest POST_BUILD
+              COMMAND cmake -E create_symlink ${SHARED_LIB_STAGING_DIR} ${CMAKE_BINARY_DIR}/test/Resources
+              )
+    endif()
 endif (LL_TESTS)
diff --git a/indra/test/lldoubledispatch_tut.cpp b/indra/test/lldoubledispatch_tut.cpp
index ad8f6454d4caa5604a1e7a96f7eb1377b914f8f1..dbf55e666f19b3173ea4521c9a7942187462b82f 100644
--- a/indra/test/lldoubledispatch_tut.cpp
+++ b/indra/test/lldoubledispatch_tut.cpp
@@ -35,8 +35,9 @@
 #include "lldoubledispatch.h"
 // STL headers
 // std headers
-#include <string>
 #include <iostream>
+#include <memory>
+#include <string>
 #include <typeinfo>
 // external library headers
 // other Linden headers
@@ -135,10 +136,10 @@ namespace tut
 
         // Instantiate a few GameObjects.  Make sure we refer to them
         // polymorphically, and don't let them leak.
-        std::auto_ptr<GameObject> home;
-        std::auto_ptr<GameObject> obstacle;
-        std::auto_ptr<GameObject> tug;
-        std::auto_ptr<GameObject> patrol;
+        std::unique_ptr<GameObject> home;
+        std::unique_ptr<GameObject> obstacle;
+        std::unique_ptr<GameObject> tug;
+        std::unique_ptr<GameObject> patrol;
 
         // prototype objects
         Asteroid dummyAsteroid;
diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt
index 23518b791c0a7d78967376b837565b9b86c25858..8381803b03870a8abb3c96da6b21f62776307c22 100644
--- a/indra/viewer_components/login/CMakeLists.txt
+++ b/indra/viewer_components/login/CMakeLists.txt
@@ -7,21 +7,7 @@ if(LL_TESTS)
   include(LLAddBuildTest)
 endif(LL_TESTS)
 include(LLCommon)
-include(LLMath)
-include(LLXML)
-include(Boost)
 include(LLCoreHttp)
-include(LLMessage)
-
-include_directories(
-    ${LLCOMMON_INCLUDE_DIRS}
-    ${LLMATH_INCLUDE_DIRS}
-    ${LLXML_INCLUDE_DIRS}
-    )
-include_directories(SYSTEM
-    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
-    ${LLXML_SYSTEM_INCLUDE_DIRS}
-    )
 
 set(login_SOURCE_FILES
     lllogin.cpp
@@ -31,9 +17,6 @@ set(login_HEADER_FILES
     lllogin.h
     )
 
-set_source_files_properties(${login_HEADER_FILES}
-                            PROPERTIES HEADER_FILE_ONLY TRUE)
-
 list(APPEND 
     login_SOURCE_FILES 
     ${login_HEADER_FILES} 
@@ -42,17 +25,14 @@ list(APPEND
 add_library(lllogin 
             ${login_SOURCE_FILES}
             )
+target_include_directories( lllogin  INTERFACE   ${CMAKE_CURRENT_SOURCE_DIR})
 
 target_link_libraries(lllogin
-    ${LLMESSAGE_LIBRARIES}
-    ${LLCOREHTTP_LIBRARIES}
-    ${LLCOMMON_LIBRARIES}
-    ${LLMATH_LIBRARIES}
-    ${LLXML_LIBRARIES}
-    ${BOOST_THREAD_LIBRARY}
-    ${BOOST_FIBER_LIBRARY}
-    ${BOOST_CONTEXT_LIBRARY}
-    ${BOOST_SYSTEM_LIBRARY}
+        llmessage
+        llcorehttp
+        llcommon
+        llmath
+        llxml
     )
 
 if(LL_TESTS)
@@ -62,7 +42,7 @@ if(LL_TESTS)
   set_source_files_properties(
     lllogin.cpp
     PROPERTIES
-    LL_TEST_ADDITIONAL_LIBRARIES "${LLMESSAGE_LIBRARIES};${LLCOREHTTP_LIBRARIES};${LLCOMMON_LIBRARIES};${BOOST_FIBER_LIBRARY};${BOOST_CONTEXT_LIBRARY};${BOOST_THREAD_LIBRARY};${BOOST_SYSTEM_LIBRARY}"
+    LL_TEST_ADDITIONAL_LIBRARIES llmessage llcorehttp llcommon
     )
 
   LL_ADD_PROJECT_UNIT_TESTS(lllogin "${lllogin_TEST_SOURCE_FILES}")
diff --git a/scripts/packages-formatter.py b/scripts/packages-formatter.py
index ff7c8925777b330634f3288e6825140857a4262c..4449111e46b7a86b250f2e15d808df745c52932d 100755
--- a/scripts/packages-formatter.py
+++ b/scripts/packages-formatter.py
@@ -34,6 +34,7 @@
 parser = argparse.ArgumentParser(description='Format dependency version and copyright information for the viewer About box content')
 parser.add_argument('channel', help='viewer channel name')
 parser.add_argument('version', help='viewer version number')
+parser.add_argument('install_dir', help="install dir of packages")
 args = parser.parse_args()
 
 _autobuild=os.getenv('AUTOBUILD', 'autobuild')
@@ -74,8 +75,8 @@ def add_info(key, pkg, lines):
     else:
         dups[key].add(pkg)
 
-versions=autobuild('install', '--versions')
-copyrights=autobuild('install', '--copyrights')
+versions=autobuild('install', '--versions', '--install-dir', args.install_dir)
+copyrights=autobuild('install', '--copyrights', '--install-dir', args.install_dir)
 viewer_copyright = copyrights.readline() # first line is the copyright for the viewer itself
 
 # Two different autobuild outputs, but we treat them essentially the same way: