diff --git a/.hgtags b/.hgtags
index 58b5f41a3b290b5143aa30ef032b3f8ec17d2424..d7465f4c596a67bcec1bf0cdcea7d5086dae40aa 100644
--- a/.hgtags
+++ b/.hgtags
@@ -34,3 +34,11 @@ b0cd7e150009809a0b5b0a9d5785cd4bb230413a 2.2.0-beta3
 98e0d6df638429fd2f0476667504bd5a6b298def 2.3.0-start
 a3c12342b1af0951b8aa3b828aacef17fcea8178 2.3.0-beta1
 db0fe9bb65187f365e58a717dd23d0f4754a9c1d 2.3.0-beta2
+6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 2.3.0-beta3
+6ad3d6fa35a4e320e9ce442fce2bf9c7fc852556 2.3.0-release
+dbc206fc61d89ff4cfe15aade0bf0c7bc7fee1c9 2.4.0-start
+dc6483491b4af559060bccaef8e9045a303212dd 2.4.0-beta1
+dc6483491b4af559060bccaef8e9045a303212dd 2.4.0-beta1
+3bc1f50a72e117f4d4ad8d555f0c785ea8cc201e 2.4.0-beta1
+25bd6007e3d2fc15db9326ed4b18a24a5969a46a 2.4.0-beta2
+1ed382c6a08ba3850b6ce9061bc551ddece0ea07 2.4.0-release
diff --git a/BuildParams b/BuildParams
index 151b21fb1fdca9bed88e710c4838961a56b26bc8..0a4271f7a8bba336d155de09405b4e341d3c08dd 100644
--- a/BuildParams
+++ b/BuildParams
@@ -14,6 +14,9 @@ public_build = true
 # Update Public Inworld Build Status Indicators
 email_status_this_is_os = true
 
+# Limit extent of codeticket updates to revisions after...
+codeticket_since = 2.2.0-release
+
 # ========================================
 # Viewer Development
 # ========================================
@@ -51,6 +54,7 @@ viewer-release.viewer_channel = "Second Life Release"
 viewer-release.login_channel = "Second Life Release"
 viewer-release.build_debug_release_separately = true
 viewer-release.build_viewer_update_version_manager = true
+viewer-release.release-viewer.jira = DRTVWR-13
 
 # ========================================
 # aimee
@@ -205,5 +209,29 @@ viewer-tut-teamcity.email = enus@lindenlab.com
 viewer-tut-teamcity.build_server = false
 viewer-tut-teamcity.build_server_tests = false
 
+# ========================================
+# experience
+# ========================================
+viewer-experience.public_build = false
+viewer-experience.viewer_channel = "Second Life SkyLight Viewer"
+viewer-experience.login_channel = "Second Life SkyLight Viewer"
+
+# =================================================================
+# asset delivery 2010 projects
+# =================================================================
+viewer-asset-delivery.viewer_channel = "Second Life Development"
+viewer-asset-delivery.login_channel = "Second Life Development"
+viewer-asset-delivery.build_viewer_update_version_manager = false
+viewer-asset-delivery.email = monty@lindenlab.com
+viewer-asset-delivery.build_server = false
+viewer-asset-delivery.build_server_tests = false
+
+viewer-asset-delivery-metrics.viewer_channel = "Second Life Development"
+viewer-asset-delivery-metrics.login_channel = "Second Life Development"
+viewer-asset-delivery-metrics.build_viewer_update_version_manager = false
+viewer-asset-delivery-metrics.email = monty@lindenlab.com
+viewer-asset-delivery-metrics.build_server = false
+viewer-asset-delivery-metrics.build_server_tests = false
+
 
 # eof
diff --git a/build.sh b/build.sh
index f9c6beefeded66430d40c4d0d7cd9c5c6be66bed..c5f74c23ee07ac283b76289af82d8d5fe2a2644c 100755
--- a/build.sh
+++ b/build.sh
@@ -59,10 +59,11 @@ pre_build()
     -t $variant \
     -G "$cmake_generator" \
    configure \
-	-DGRID:STRING="$viewer_grid" \
+    -DGRID:STRING="$viewer_grid" \
     -DVIEWER_CHANNEL:STRING="$viewer_channel" \
     -DVIEWER_LOGIN_CHANNEL:STRING="$login_channel" \
     -DINSTALL_PROPRIETARY:BOOL=ON \
+    -DRELEASE_CRASH_REPORTING:BOOL=ON \
     -DLOCALIZESETUP:BOOL=ON \
     -DPACKAGE:BOOL=ON \
     -DCMAKE_VERBOSE_MAKEFILE:BOOL=TRUE
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 79e8607f15cd48e60722097f6b5fdd657781274f..f987cf485202b07485c54054158a85e7d2c0e55b 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -61,19 +61,27 @@ Aimee Trescothick
 Alejandro Rosenthal
 	VWR-1184
 Aleric Inglewood
+	SNOW-240
 	SNOW-522
 	SNOW-626
 	SNOW-756
 	SNOW-764
 	VWR-10001
+	VWR-10579
 	VWR-10759
 	VWR-10837
 	VWR-12691
 	VWR-12984
 	VWR-13996
 	VWR-14426
+	VWR-24247
+	VWR-24251
+	VWR-24252
+	VWR-24254
+	VWR-24261
 	SNOW-84
 	SNOW-477
+	SNOW-744
 	SNOW-766
 	STORM-163
 Ales Beaumont
@@ -177,6 +185,7 @@ Boroondas Gupte
 	SNOW-610
 	SNOW-624
 	SNOW-737
+	STORM-318
 	VWR-233
 	VWR-20583
 	VWR-20891
@@ -210,6 +219,8 @@ Catherine Pfeffer
 Celierra Darling
 	VWR-1274
 	VWR-6975
+Cron Stardust
+	VWR-10579
 Cypren Christenson
 	STORM-417
 Dale Glass
@@ -354,6 +365,12 @@ Joghert LeSabre
 	VWR-64
 Jonathan Yap
 	VWR-17801
+	STORM-523
+	STORM-616
+	STORM-679
+	STORM-596
+	STORM-726
+	STORM-785
 Kage Pixel
 	VWR-11
 Ken March
@@ -367,6 +384,9 @@ Khyota Wulluf
 	VWR-9966
 Kitty Barnett
 	VWR-19699
+	STORM-288
+	STORM-799
+	STORM-800
 Kunnis Basiat
 	VWR-82
 	VWR-102
@@ -414,6 +434,7 @@ McCabe Maxsted
 	VWR-8689
 	VWR-9007
 Michelle2 Zenovka
+    STORM-477
 	VWR-2652
 	VWR-2662
 	VWR-2834
@@ -578,6 +599,7 @@ Robin Cornelius
 	STORM-422
 	VWR-2488
 	VWR-9557
+	VWR-10579
 	VWR-11128
 	VWR-12533
 	VWR-12587
@@ -601,6 +623,7 @@ Sammy Frederix
 	VWR-6186
 Satomi Ahn
 	STORM-501
+	STORM-229
 Scrippy Scofield
 	VWR-3748
 Seg Baphomet
@@ -759,11 +782,24 @@ Whoops Babii
 	VWR-8298
 Wilton Lundquist
 	VWR-7682
-Zai Lynch
-	VWR-19505
-Wolfpup Lowenhar
+WolfPup Lowenhar
+	SNOW-622
+	SNOW-772
+	STORM-102
+	STORM-103
+	STORM-143
 	STORM-255
 	STORM-256
+	STORM-288
+	STORM-535
+	STORM-544
+	STORM-654
+	STORM-674
+	STORM-776
+	VWR-20741
+	VWR-20933
+Zai Lynch
+	VWR-19505
 Zarkonnen Decosta
 	VWR-253
 Zi Ree
diff --git a/etc/message.xml b/etc/message.xml
index ebbb4e57a96fafd0407f74861500e67daf1916cf..7c4a927cc5e7997b7533e98ec4d2143c60f19b87 100644
--- a/etc/message.xml
+++ b/etc/message.xml
@@ -442,6 +442,14 @@
           <boolean>true</boolean>
         </map>
 
+        <key>SimConsoleResponse</key>
+        <map>
+          <key>flavor</key>
+          <string>llsd</string>
+          <key>trusted-sender</key>
+          <boolean>true</boolean>
+        </map>
+
         <key>DirLandReply</key>
         <map>
           <key>flavor</key>
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index a8716b10f16fa4fe20e16a3928e35a3955ded17e..6d17a6f402efbf917fe8a24a51fa25fe70fbefb3 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -22,7 +22,10 @@ set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
 include(Variables)
 
 if (DARWIN)
-  cmake_minimum_required(VERSION 2.6.2 FATAL_ERROR)
+  # 2.6.4 fixes a Mac bug in get_target_property(... "SLPlugin" LOCATION):
+  # before that version it returns "pathname/SLPlugin", whereas the correct
+  # answer is "pathname/SLPlugin.app/Contents/MacOS/SLPlugin".
+  cmake_minimum_required(VERSION 2.6.4 FATAL_ERROR)
 endif (DARWIN)
 
 if (NOT CMAKE_BUILD_TYPE)
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index a114d6e7783497b8ad194ee5eb9263617ca1c560..dbe0cf5cd051eb02b865210c6c39e104fc1caa6e 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -4,27 +4,28 @@
 
 include(Variables)
 
-
 # Portable compilation flags.
-
-if (EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
-  # The release build should only offer to send crash reports if we're
-  # building from a Linden internal source tree.
-  set(release_crash_reports 1)
-else (EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
-  set(release_crash_reports 0) 
-endif (EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
-
 set(CMAKE_CXX_FLAGS_DEBUG "-D_DEBUG -DLL_DEBUG=1")
 set(CMAKE_CXX_FLAGS_RELEASE
-    "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=${release_crash_reports} -DNDEBUG") 
+    "-DLL_RELEASE=1 -DLL_RELEASE_FOR_DOWNLOAD=1 -D_SECURE_SCL=0 -DNDEBUG") 
 
 set(CMAKE_CXX_FLAGS_RELWITHDEBINFO 
-    "-DLL_RELEASE=1 -D_SECURE_SCL=0 -DLL_SEND_CRASH_REPORTS=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
+    "-DLL_RELEASE=1 -D_SECURE_SCL=0 -DNDEBUG -DLL_RELEASE_WITH_DEBUG_INFO=1")
 
+# 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")
 
-# Don't bother with a MinSizeRel build.
+if(RELEASE_CRASH_REPORTING)
+  set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DLL_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 a MinSizeRel build.
 set(CMAKE_CONFIGURATION_TYPES "RelWithDebInfo;Release;Debug" CACHE STRING
     "Supported build types." FORCE)
 
@@ -38,10 +39,10 @@ if (WINDOWS)
   set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /Zi /MDd /MP"
       CACHE STRING "C++ compiler debug options" FORCE)
   set(CMAKE_CXX_FLAGS_RELWITHDEBINFO 
-      "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP"
+      "${CMAKE_CXX_FLAGS_RELWITHDEBINFO} /Od /Zi /MD /MP /Ob2"
       CACHE STRING "C++ compiler release-with-debug options" FORCE)
   set(CMAKE_CXX_FLAGS_RELEASE
-      "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP"
+      "${CMAKE_CXX_FLAGS_RELEASE} ${LL_CXX_FLAGS} /O2 /Zi /MD /MP /Ob2"
       CACHE STRING "C++ compiler release options" FORCE)
 
   set(CMAKE_CXX_STANDARD_LIBRARIES "")
diff --git a/indra/cmake/BerkeleyDB.cmake b/indra/cmake/BerkeleyDB.cmake
index d98e79179d9f6c635d69473438408926901ef0ca..e3ca0fd77d62c55e08165c53ace8e9564526cf64 100644
--- a/indra/cmake/BerkeleyDB.cmake
+++ b/indra/cmake/BerkeleyDB.cmake
@@ -6,6 +6,11 @@ set(DB_FIND_REQUIRED ON)
 if (STANDALONE)
   include(FindBerkeleyDB)
 else (STANDALONE)
-  set(DB_LIBRARIES db-4.2)
+  if (LINUX)
+    # Need to add dependency pthread explicitely to support ld.gold.
+    set(DB_LIBRARIES db-4.2 pthread)
+  else (LINUX)
+    set(DB_LIBRARIES db-4.2)
+  endif (LINUX)
   set(DB_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
 endif (STANDALONE)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 6470836286135d173fe4287d1504bbe0817d5959..3f421b270b92507fc3295cf14a99000de2e9595c 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -33,6 +33,7 @@ set(cmake_SOURCE_FILES
     FindMySQL.cmake
     FindOpenJPEG.cmake
     FindXmlRpcEpi.cmake
+    FindZLIB.cmake
     FMOD.cmake
     FreeType.cmake
     GStreamer010Plugin.cmake
diff --git a/indra/cmake/CURL.cmake b/indra/cmake/CURL.cmake
index 6e5fed4d5285e473d121d367c4da18ee15f76b18..9aba08e573df9bc636cdc6cd59f841f12228c72f 100644
--- a/indra/cmake/CURL.cmake
+++ b/indra/cmake/CURL.cmake
@@ -10,10 +10,10 @@ else (STANDALONE)
   use_prebuilt_binary(curl)
   if (WINDOWS)
     set(CURL_LIBRARIES 
-    debug libcurld
-    optimized libcurl)
+    debug libcurld.lib
+    optimized libcurl.lib)
   else (WINDOWS)
-    set(CURL_LIBRARIES curl)
+    set(CURL_LIBRARIES libcurl.a)
   endif (WINDOWS)
   set(CURL_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
 endif (STANDALONE)
diff --git a/indra/cmake/FindJsonCpp.cmake b/indra/cmake/FindJsonCpp.cmake
index 9d16f2aaabcfbdb88e7763f16d0ef38deb8580c4..cf84b309c1f64617aeb916d46fc89a8dcb26a419 100644
--- a/indra/cmake/FindJsonCpp.cmake
+++ b/indra/cmake/FindJsonCpp.cmake
@@ -21,7 +21,12 @@ EXEC_PROGRAM(${CMAKE_CXX_COMPILER}
             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 (STANDALONE)
+	# On standalone, assume that the system installed library was compiled with the used compiler.
+	SET(JSONCPP_NAMES ${JSONCPP_NAMES} libjson.so)
+ENDIF (STANDALONE)
 FIND_LIBRARY(JSONCPP_LIBRARY
   NAMES ${JSONCPP_NAMES}
   PATHS /usr/lib /usr/local/lib
diff --git a/indra/cmake/FindLLQtWebkit.cmake b/indra/cmake/FindLLQtWebkit.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..c747ec32a2850957f45ccb5fe239b6f995cb611c
--- /dev/null
+++ b/indra/cmake/FindLLQtWebkit.cmake
@@ -0,0 +1,62 @@
+# -*- cmake -*-
+
+# - Find llqtwebkit
+# Find the llqtwebkit includes and library
+# This module defines
+#  LLQTWEBKIT_INCLUDE_DIR, where to find llqtwebkit.h, etc.
+#  LLQTWEBKIT_LIBRARY, the llqtwebkit library with full path.
+#  LLQTWEBKIT_FOUND, If false, do not try to use llqtwebkit.
+# also defined, but not for general use are
+#  LLQTWEBKIT_LIBRARIES, the libraries needed to use llqtwebkit.
+#  LLQTWEBKIT_LIBRARY_DIRS, where to find the llqtwebkit library.
+#  LLQTWEBKIT_DEFINITIONS - You should add_definitions(${LLQTWEBKIT_DEFINITIONS})
+#      before compiling code that includes llqtwebkit library files.
+
+# Try to use pkg-config first.
+# This allows to have two different libllqtwebkit packages installed:
+# one for viewer 2.x and one for viewer 1.x.
+include(FindPkgConfig)
+if (PKG_CONFIG_FOUND)
+    if (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
+        set(_PACKAGE_ARGS libllqtwebkit>=${LLQtWebkit_FIND_VERSION} REQUIRED)
+    else (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
+        set(_PACKAGE_ARGS libllqtwebkit)
+    endif (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
+    if (NOT "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" VERSION_LESS "2.8")
+      # As virtually nobody will have a pkg-config file for this, do this check always quiet.
+      # Unfortunately cmake 2.8 or higher is required for pkg_check_modules to have a 'QUIET'.
+      set(_PACKAGE_ARGS ${_PACKAGE_ARGS} QUIET)
+    endif ()
+    pkg_check_modules(LLQTWEBKIT ${_PACKAGE_ARGS})
+endif (PKG_CONFIG_FOUND)
+set(LLQTWEBKIT_DEFINITIONS ${LLQTWEBKIT_CFLAGS_OTHER})
+
+find_path(LLQTWEBKIT_INCLUDE_DIR llqtwebkit.h NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_INCLUDE_DIRS})
+
+find_library(LLQTWEBKIT_LIBRARY NAMES llqtwebkit NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_LIBRARY_DIRS})
+
+if (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND)	# If pkg-config couldn't find it, pretend we don't have pkg-config.
+   set(LLQTWEBKIT_LIBRARIES llqtwebkit)
+   get_filename_component(LLQTWEBKIT_LIBRARY_DIRS ${LLQTWEBKIT_LIBRARY} PATH)
+endif (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND)
+
+# Handle the QUIETLY and REQUIRED arguments and set LLQTWEBKIT_FOUND
+# to TRUE if all listed variables are TRUE.
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(
+  LLQTWEBKIT
+  DEFAULT_MSG
+  LLQTWEBKIT_LIBRARY
+  LLQTWEBKIT_INCLUDE_DIR
+  LLQTWEBKIT_LIBRARIES
+  LLQTWEBKIT_LIBRARY_DIRS
+  )
+
+mark_as_advanced(
+  LLQTWEBKIT_LIBRARY
+  LLQTWEBKIT_INCLUDE_DIR
+  LLQTWEBKIT_LIBRARIES
+  LLQTWEBKIT_LIBRARY_DIRS
+  LLQTWEBKIT_DEFINITIONS
+  )
+
diff --git a/indra/cmake/FindNDOF.cmake b/indra/cmake/FindNDOF.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..6dcf590a53d5f77cb6614752d8f78f0ef0336f30
--- /dev/null
+++ b/indra/cmake/FindNDOF.cmake
@@ -0,0 +1,39 @@
+# -*- 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/FindTut.cmake b/indra/cmake/FindTut.cmake
index b5d58f6396e63c265eafda0d9d6df0c0e6c1906a..c2a9f430534aa1ee7e50ab87ed0bbe6b0cb241a2 100644
--- a/indra/cmake/FindTut.cmake
+++ b/indra/cmake/FindTut.cmake
@@ -3,12 +3,11 @@
 # - Find Tut
 # Find the Tut unit test framework includes and library
 # This module defines
-#  TUT_INCLUDE_DIR, where to find tut.h, etc.
+#  TUT_INCLUDE_DIR, where to find tut/tut.hpp.
 #  TUT_FOUND, If false, do not try to use Tut.
 
-find_path(TUT_INCLUDE_DIR tut.h
-    /usr/local/include/
-    /usr/include
+find_path(TUT_INCLUDE_DIR tut/tut.hpp
+    NO_SYSTEM_ENVIRONMENT_PATH
     )
 
 if (TUT_INCLUDE_DIR)
diff --git a/indra/cmake/FindZLIB.cmake b/indra/cmake/FindZLIB.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..6d630f1ba967e4d418965730b3032d4290f5c842
--- /dev/null
+++ b/indra/cmake/FindZLIB.cmake
@@ -0,0 +1,46 @@
+# -*- cmake -*-
+
+# - Find zlib
+# Find the ZLIB includes and library
+# This module defines
+#  ZLIB_INCLUDE_DIRS, where to find zlib.h, etc.
+#  ZLIB_LIBRARIES, the libraries needed to use zlib.
+#  ZLIB_FOUND, If false, do not try to use zlib.
+#
+# This FindZLIB 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(ZLIB_INCLUDE_DIR zlib.h
+  NO_SYSTEM_ENVIRONMENT_PATH
+  )
+
+FIND_LIBRARY(ZLIB_LIBRARY z)
+
+if (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
+  SET(ZLIB_INCLUDE_DIRS ${ZLIB_INCLUDE_DIR})
+  SET(ZLIB_LIBRARIES ${ZLIB_LIBRARY})
+  SET(ZLIB_FOUND "YES")
+else (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
+  SET(ZLIB_FOUND "NO")
+endif (ZLIB_LIBRARY AND ZLIB_INCLUDE_DIR)
+
+if (ZLIB_FOUND)
+  if (NOT ZLIB_FIND_QUIETLY)
+	message(STATUS "Found ZLIB: ${ZLIB_LIBRARIES}")
+	SET(ZLIB_FIND_QUIETLY TRUE)
+  endif (NOT ZLIB_FIND_QUIETLY)
+else (ZLIB_FOUND)
+  if (ZLIB_FIND_REQUIRED)
+	message(FATAL_ERROR "Could not find ZLIB library")
+  endif (ZLIB_FIND_REQUIRED)
+endif (ZLIB_FOUND)
+
+mark_as_advanced(
+  ZLIB_LIBRARY
+  ZLIB_INCLUDE_DIR
+  )
+
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 79c3bb7da25b3d3d4417f44335aa6a30e5d1b695..62b764bb307debcee404eb7bc355f8b361cabadb 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -1,265 +1,276 @@
-# -*- cmake -*-
-include(LLTestCommand)
-include(GoogleMock)
-
-MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
-  # Given a project name and a list of sourcefiles (with optional properties on each),
-  # add targets to build and run the tests specified.
-  # ASSUMPTIONS:
-  # * this macro is being executed in the project file that is passed in
-  # * current working SOURCE dir is that project dir
-  # * there is a subfolder tests/ with test code corresponding to the filenames passed in
-  # * 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)
-
-  # 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")
-    # 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
-    ${GOOGLEMOCK_LIBRARIES}
-    ${PTHREAD_LIBRARY}
-    ${WINDOWS_LIBRARIES}
-    )
-  # Headers, for convenience in targets.
-  SET(alltest_HEADER_FILES
-    ${CMAKE_SOURCE_DIR}/test/test.h
-    )
-
-  # Use the default flags
-  if (LINUX)
-    SET(CMAKE_EXE_LINKER_FLAGS "")
-  endif (LINUX)
-
-  # 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)
-
-    #
-    # Per-codefile additional / external source, header, and include dir property extraction
-    #
-    # Source
-    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES)
-    IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
-      SET(${name}_test_additional_SOURCE_FILES "")
-    ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
-    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)
-    # Headers
-    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
-    IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
-      SET(${name}_test_additional_HEADER_FILES "")
-    ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
-    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
-    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS)
-    IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
-      SET(${name}_test_additional_INCLUDE_DIRS "")
-    ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
-    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)
-
-
-    # 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}")
-
-    #
-    # Per-codefile additional / external project dep and lib dep property extraction
-    #
-    # WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19
-    # Projects
-    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS)
-    IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
-      SET(${name}_test_additional_PROJECTS "")
-    ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
-    # Libraries
-    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES)
-    IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
-      SET(${name}_test_additional_LIBRARIES "")
-    ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
-    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)
-    # Add to project
-    TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} )
-    
-    #
-    # Setup test targets
-    #
-    GET_TARGET_PROPERTY(TEST_EXE PROJECT_${project}_TEST_${name} LOCATION)
-    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)
-
-    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}
-        )
-    # 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 
-    # > failure after the first time you build and fail a test. - daveh 2009-04-20
-    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)
-ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
-
-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)
-  
-  SET(source_files
-    tests/${testname}_test.cpp
-    ${CMAKE_SOURCE_DIR}/test/test.cpp
-    ${CMAKE_SOURCE_DIR}/test/lltut.cpp
-    ${additional_source_files}
-    )
-
-  SET(libraries
-    ${library_dependencies}
-    ${GOOGLEMOCK_LIBRARIES}
-    ${PTHREAD_LIBRARY}
-    )
-
-  # 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}")
-
-  # 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})
-
-  # Create the test running command
-  SET(test_command ${ARGN})
-  GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION)
-  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
-    # shorthand for both straightforward execution of the test program (empty
-    # $ARGN) and for running a "wrapper" program of some kind accepting the
-    # 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)
-    # Found {} marker at test_exe_pos. Remove the {}...
-    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)
-
-  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)
-
-  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})
-
-ENDFUNCTION(LL_ADD_INTEGRATION_TEST)
-
-MACRO(SET_TEST_PATH LISTVAR)
-  IF(WINDOWS)
-    # 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)
-  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)
-  ELSE(WINDOWS)
-    # Linux uses a single staging directory anyway.
-    IF (STANDALONE)
-      set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib)
-    ELSE (STANDALONE)
-      set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib)
-    ENDIF (STANDALONE)
-  ENDIF(WINDOWS)
-ENDMACRO(SET_TEST_PATH)
+# -*- cmake -*-
+include(LLTestCommand)
+include(GoogleMock)
+
+MACRO(LL_ADD_PROJECT_UNIT_TESTS project sources)
+  # Given a project name and a list of sourcefiles (with optional properties on each),
+  # add targets to build and run the tests specified.
+  # ASSUMPTIONS:
+  # * this macro is being executed in the project file that is passed in
+  # * current working SOURCE dir is that project dir
+  # * there is a subfolder tests/ with test code corresponding to the filenames passed in
+  # * 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)
+
+  # 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")
+    # 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
+    ${GOOGLEMOCK_LIBRARIES}
+    ${PTHREAD_LIBRARY}
+    ${WINDOWS_LIBRARIES}
+    )
+  # Headers, for convenience in targets.
+  SET(alltest_HEADER_FILES
+    ${CMAKE_SOURCE_DIR}/test/test.h
+    )
+
+  # Use the default flags
+  if (LINUX)
+    SET(CMAKE_EXE_LINKER_FLAGS "")
+  endif (LINUX)
+
+  # 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)
+
+    #
+    # Per-codefile additional / external source, header, and include dir property extraction
+    #
+    # Source
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_SOURCE_FILES ${source} LL_TEST_ADDITIONAL_SOURCE_FILES)
+    IF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
+      SET(${name}_test_additional_SOURCE_FILES "")
+    ENDIF(${name}_test_additional_SOURCE_FILES MATCHES NOTFOUND)
+    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)
+    # Headers
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_HEADER_FILES ${source} LL_TEST_ADDITIONAL_HEADER_FILES)
+    IF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
+      SET(${name}_test_additional_HEADER_FILES "")
+    ENDIF(${name}_test_additional_HEADER_FILES MATCHES NOTFOUND)
+    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
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_INCLUDE_DIRS ${source} LL_TEST_ADDITIONAL_INCLUDE_DIRS)
+    IF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
+      SET(${name}_test_additional_INCLUDE_DIRS "")
+    ENDIF(${name}_test_additional_INCLUDE_DIRS MATCHES NOTFOUND)
+    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)
+
+
+    # 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}")
+
+    #
+    # Per-codefile additional / external project dep and lib dep property extraction
+    #
+    # WARNING: it's REALLY IMPORTANT to not mix these. I guarantee it will not work in the future. + poppy 2009-04-19
+    # Projects
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_PROJECTS ${source} LL_TEST_ADDITIONAL_PROJECTS)
+    IF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
+      SET(${name}_test_additional_PROJECTS "")
+    ENDIF(${name}_test_additional_PROJECTS MATCHES NOTFOUND)
+    # Libraries
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_LIBRARIES ${source} LL_TEST_ADDITIONAL_LIBRARIES)
+    IF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
+      SET(${name}_test_additional_LIBRARIES "")
+    ENDIF(${name}_test_additional_LIBRARIES MATCHES NOTFOUND)
+    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)
+    # Add to project
+    TARGET_LINK_LIBRARIES(PROJECT_${project}_TEST_${name} ${alltest_LIBRARIES} ${alltest_DEP_TARGETS} ${${name}_test_additional_PROJECTS} ${${name}_test_additional_LIBRARIES} )
+    # Compile-time Definitions
+    GET_SOURCE_FILE_PROPERTY(${name}_test_additional_CFLAGS ${source} LL_TEST_ADDITIONAL_CFLAGS)
+     IF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
+       SET_TARGET_PROPERTIES(PROJECT_${project}_TEST_${name} PROPERTIES COMPILE_FLAGS ${${name}_test_additional_CFLAGS} )
+       IF(LL_TEST_VERBOSE)
+         MESSAGE("LL_ADD_PROJECT_UNIT_TESTS ${name}_test_additional_CFLAGS ${${name}_test_additional_CFLAGS}")
+       ENDIF(LL_TEST_VERBOSE)
+     ENDIF(NOT ${name}_test_additional_CFLAGS MATCHES NOTFOUND)
+     
+    #
+    # Setup test targets
+    #
+    GET_TARGET_PROPERTY(TEST_EXE PROJECT_${project}_TEST_${name} LOCATION)
+    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)
+
+    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}
+        )
+    # 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 
+    # > failure after the first time you build and fail a test. - daveh 2009-04-20
+    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)
+ENDMACRO(LL_ADD_PROJECT_UNIT_TESTS)
+
+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)
+  
+  SET(source_files
+    tests/${testname}_test.cpp
+    ${CMAKE_SOURCE_DIR}/test/test.cpp
+    ${CMAKE_SOURCE_DIR}/test/lltut.cpp
+    ${additional_source_files}
+    )
+
+  SET(libraries
+    ${library_dependencies}
+    ${GOOGLEMOCK_LIBRARIES}
+    ${PTHREAD_LIBRARY}
+    )
+
+  # 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}")
+  if(STANDALONE)
+    SET_TARGET_PROPERTIES(INTEGRATION_TEST_${testname} PROPERTIES COMPILE_FLAGS -I"${TUT_INCLUDE_DIR}")
+  endif(STANDALONE)
+
+  # 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})
+
+  # Create the test running command
+  SET(test_command ${ARGN})
+  GET_TARGET_PROPERTY(TEST_EXE INTEGRATION_TEST_${testname} LOCATION)
+  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
+    # shorthand for both straightforward execution of the test program (empty
+    # $ARGN) and for running a "wrapper" program of some kind accepting the
+    # 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)
+    # Found {} marker at test_exe_pos. Remove the {}...
+    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)
+
+  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)
+
+  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})
+
+ENDFUNCTION(LL_ADD_INTEGRATION_TEST)
+
+MACRO(SET_TEST_PATH LISTVAR)
+  IF(WINDOWS)
+    # 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)
+  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)
+  ELSE(WINDOWS)
+    # Linux uses a single staging directory anyway.
+    IF (STANDALONE)
+      set(${LISTVAR} ${CMAKE_BINARY_DIR}/llcommon /usr/lib /usr/local/lib)
+    ELSE (STANDALONE)
+      set(${LISTVAR} ${SHARED_LIB_STAGING_DIR} /usr/lib)
+    ENDIF (STANDALONE)
+  ENDIF(WINDOWS)
+ENDMACRO(SET_TEST_PATH)
diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake
index d1ab264a413b8a3eaf263ea3bbef32e59ac42e9c..17e211cb9937eb8e5544423e1c3ddb03a675fabc 100644
--- a/indra/cmake/LLCommon.cmake
+++ b/indra/cmake/LLCommon.cmake
@@ -13,7 +13,14 @@ set(LLCOMMON_INCLUDE_DIRS
     ${Boost_INCLUDE_DIRS}
     )
 
-set(LLCOMMON_LIBRARIES llcommon)
+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 rt)
+else (LINUX)
+    set(LLCOMMON_LIBRARIES llcommon)
+endif (LINUX)
 
 add_definitions(${TCMALLOC_FLAG})
 
diff --git a/indra/cmake/LLPlugin.cmake b/indra/cmake/LLPlugin.cmake
index 9722f16c3c31ebc09fac22b4f5bda01c0ae312c1..7ee404b9bdfa68fc6d398c48a2549b4449fc84d9 100644
--- a/indra/cmake/LLPlugin.cmake
+++ b/indra/cmake/LLPlugin.cmake
@@ -5,4 +5,10 @@ set(LLPLUGIN_INCLUDE_DIRS
     ${LIBS_OPEN_DIR}/llplugin
     )
 
-set(LLPLUGIN_LIBRARIES 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/NDOF.cmake b/indra/cmake/NDOF.cmake
index dad74e99b1bb7c8a4d79022938cb6df2d0ecb2bf..7a463d11907d9596e24ae1d2527a611459b4958d 100644
--- a/indra/cmake/NDOF.cmake
+++ b/indra/cmake/NDOF.cmake
@@ -1,14 +1,32 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-use_prebuilt_binary(ndofdev)
+set(NDOF ON CACHE BOOL "Use NDOF space navigator joystick library.")
 
-if (WINDOWS OR DARWIN OR LINUX)
+if (NDOF)
+  if (STANDALONE)
+	set(NDOF_FIND_REQUIRED ON)
+	include(FindNDOF)
+  else (STANDALONE)
+	use_prebuilt_binary(ndofdev)
+
+	if (WINDOWS)
+	  set(NDOF_LIBRARY libndofdev)
+	elseif (DARWIN OR LINUX)
+	  set(NDOF_LIBRARY ndofdev)
+	endif (WINDOWS)
+
+	set(NDOF_INCLUDE_DIR ${ARCH_PREBUILT_DIRS}/include/ndofdev)
+	set(NDOF_FOUND 1)
+  endif (STANDALONE)
+endif (NDOF)
+
+if (NDOF_FOUND)
   add_definitions(-DLIB_NDOF=1)
-endif (WINDOWS OR DARWIN OR LINUX)
+  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)
 
-if (WINDOWS)
-  set(NDOF_LIBRARY libndofdev)
-elseif (DARWIN OR LINUX)
-  set(NDOF_LIBRARY ndofdev)
-endif (WINDOWS)
diff --git a/indra/cmake/PulseAudio.cmake b/indra/cmake/PulseAudio.cmake
index e918de0198aca68e0b4de20e6e376b3868f88459..360a971058717b989bee052de2e8a99d72ea5a37 100644
--- a/indra/cmake/PulseAudio.cmake
+++ b/indra/cmake/PulseAudio.cmake
@@ -1,7 +1,7 @@
 # -*- cmake -*-
 include(Prebuilt)
 
-set(PULSEAUDIO ON CACHE BOOL "Build with PulseAudio support, if available.")
+set(PULSEAUDIO OFF CACHE BOOL "Build with PulseAudio support, if available.")
 
 if (PULSEAUDIO)
   if (STANDALONE)
diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake
index 0901c1b7a2174979f4d5546962c7db9c1fd62f02..748c8c2bec1b80b3680c2b7e410fbf3de1830df5 100644
--- a/indra/cmake/Python.cmake
+++ b/indra/cmake/Python.cmake
@@ -9,10 +9,12 @@ if (WINDOWS)
     NAMES python25.exe python23.exe python.exe
     NO_DEFAULT_PATH # added so that cmake does not find cygwin python
     PATHS
+    [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath]
     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]
     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
     [HKEY_LOCAL_MACHINE\\SOFTWARE\\Python\\PythonCore\\2.3\\InstallPath]
+    [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.7\\InstallPath]
     [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.6\\InstallPath]
     [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.5\\InstallPath]
     [HKEY_CURRENT_USER\\SOFTWARE\\Python\\PythonCore\\2.4\\InstallPath]
diff --git a/indra/cmake/TemplateCheck.cmake b/indra/cmake/TemplateCheck.cmake
index fa4e387dd5c60aac177fb36fa3bfc1ddc0ed2b75..90d58d93ad4bd652f0260d48f03ec9e04239edea 100644
--- a/indra/cmake/TemplateCheck.cmake
+++ b/indra/cmake/TemplateCheck.cmake
@@ -7,8 +7,9 @@ macro (check_message_template _target)
       TARGET ${_target}
       POST_BUILD
       COMMAND ${PYTHON_EXECUTABLE}
-      ARGS ${SCRIPTS_DIR}/template_verifier.py
-           --mode=development --cache_master
-      COMMENT "Verifying message template"
+      ARGS ${SCRIPTS_DIR}/md5check.py
+           3f19d130400c547de36278a6b6f9b028
+           ${SCRIPTS_DIR}/messages/message_template.msg
+      COMMENT "Verifying message template - See http://wiki.secondlife.com/wiki/Template_verifier.py"
       )
 endmacro (check_message_template)
diff --git a/indra/cmake/Tut.cmake b/indra/cmake/Tut.cmake
index 784560471d503492a7daf43bfdaaba166de58bec..738c08c42fe6c10e3c82d0e48994d095e9744271 100644
--- a/indra/cmake/Tut.cmake
+++ b/indra/cmake/Tut.cmake
@@ -6,7 +6,6 @@ set(TUT_FIND_QUIETLY TRUE)
 
 if (STANDALONE)
   include(FindTut)
-  include_directories(${TUT_INCLUDE_DIR})
 else (STANDALONE)
   use_prebuilt_binary(tut)
 endif (STANDALONE)
diff --git a/indra/cmake/ViewerMiscLibs.cmake b/indra/cmake/ViewerMiscLibs.cmake
index 32c4bc81dfc4af75a888e511ba62beb7004a984f..df013b1665058e458ede89172c2aa5281ea480a5 100644
--- a/indra/cmake/ViewerMiscLibs.cmake
+++ b/indra/cmake/ViewerMiscLibs.cmake
@@ -3,7 +3,7 @@ include(Prebuilt)
 
 if (NOT STANDALONE)
   use_prebuilt_binary(libuuid)
-  use_prebuilt_binary(vivox)
+  use_prebuilt_binary(slvoice)
   use_prebuilt_binary(fontconfig)
 endif(NOT STANDALONE)
 
diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake
index 12ba1b1b35b8f95f43f194c7fb3a35a0d12fb64f..1f5b0f5d84b65d8dd2bd937cc8f7bec1c4ef5a50 100644
--- a/indra/cmake/WebKitLibPlugin.cmake
+++ b/indra/cmake/WebKitLibPlugin.cmake
@@ -3,6 +3,29 @@ include(Linking)
 include(Prebuilt)
 
 if (STANDALONE)
+  # The minimal version, 4.4.3, is rather arbitrary: it's the version in Debian/Lenny.
+  find_package(Qt4 4.4.3 COMPONENTS QtCore QtGui QtNetwork QtOpenGL QtWebKit REQUIRED)
+  include(${QT_USE_FILE})
+  set(QTDIR $ENV{QTDIR})
+  if (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
+	message(FATAL_ERROR "\"${QT_BINARY_DIR}\" is unequal \"${QTDIR}/bin\"; "
+	  "Qt is found by looking for qmake in your PATH. "
+	  "Please set your PATH such that 'qmake' is found in \$QTDIR/bin, "
+	  "or unset QTDIR if the found Qt is correct.")
+	endif (QTDIR AND NOT "${QT_BINARY_DIR}" STREQUAL "${QTDIR}/bin")
+  find_package(LLQtWebkit REQUIRED QUIET)
+  # Add the plugins.
+  set(QT_PLUGIN_LIBRARIES)
+  foreach(qlibname qgif qjpeg)
+	find_library(QT_PLUGIN_${qlibname} ${qlibname} PATHS ${QT_PLUGINS_DIR}/imageformats NO_DEFAULT_PATH)
+	if (QT_PLUGIN_${qlibname})
+	  list(APPEND QT_PLUGIN_LIBRARIES ${QT_PLUGIN_${qlibname}})
+	else (QT_PLUGIN_${qtlibname})
+	  message(FATAL_ERROR "Could not find the Qt plugin ${qlibname} in \"${QT_PLUGINS_DIR}/imageformats\"!")
+	endif (QT_PLUGIN_${qlibname})
+  endforeach(qlibname)
+  # qjpeg depends on libjpeg
+  list(APPEND QT_PLUGIN_LIBRARIES jpeg)
   set(WEBKITLIBPLUGIN OFF CACHE BOOL
       "WEBKITLIBPLUGIN support for the llplugin/llmedia test apps.")
 else (STANDALONE)
@@ -35,7 +58,7 @@ elseif (DARWIN)
       )
 elseif (LINUX)
   if (STANDALONE) 
-    set(WEBKIT_PLUGIN_LIBRARIES llqtwebkit)
+    set(WEBKIT_PLUGIN_LIBRARIES ${LLQTWEBKIT_LIBRARY} ${QT_LIBRARIES} ${QT_PLUGIN_LIBRARIES})
   else (STANDALONE)
     set(WEBKIT_PLUGIN_LIBRARIES
         llqtwebkit
diff --git a/indra/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp
index 1f15b73182d9268e3985edb130f037d7bb89c36e..c34115ee8064a6d8a63b3ad03ad85e7d44b5dfed 100644
--- a/indra/integration_tests/llui_libtest/llui_libtest.cpp
+++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp
@@ -174,7 +174,7 @@ void export_test_floaters()
 	std::string delim = gDirUtilp->getDirDelimiter();
 	std::string xui_dir = get_xui_dir() + "en" + delim;
 	std::string filename;
-	while (gDirUtilp->getNextFileInDir(xui_dir, "floater_test_*.xml", filename, false))
+	while (gDirUtilp->getNextFileInDir(xui_dir, "floater_test_*.xml", filename))
 	{
 		if (filename.find("_new.xml") != std::string::npos)
 		{
diff --git a/indra/lib/python/indra/util/test_win32_manifest.py b/indra/lib/python/indra/util/test_win32_manifest.py
index 786521c06805d6533afb378ee76bb57360cc9c85..da8ee6c545741a56a43d849f0f68420b4f3d2df9 100644
--- a/indra/lib/python/indra/util/test_win32_manifest.py
+++ b/indra/lib/python/indra/util/test_win32_manifest.py
@@ -52,20 +52,22 @@ def get_HKLM_registry_value(key_str, value_str):
         
 def find_vc_dir():
     supported_versions = (r'8.0', r'9.0')
+    supported_products = (r'VisualStudio', r'VCExpress')
     value_str = (r'ProductDir')
     
-    for version in supported_versions:
-        key_str = (r'SOFTWARE\Microsoft\VisualStudio\%s\Setup\VC' %
-                   version)
-        try:
-            return get_HKLM_registry_value(key_str, value_str)
-        except WindowsError, err:
-            x64_key_str = (r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%s\Setup\VS' %
-                       version)
+    for product in supported_products:
+        for version in supported_versions:
+            key_str = (r'SOFTWARE\Microsoft\%s\%s\Setup\VC' %
+                      (product, version))
             try:
-                return get_HKLM_registry_value(x64_key_str, value_str)
-            except:
-                print >> sys.stderr, "Didn't find MS VC version %s " % version
+                return get_HKLM_registry_value(key_str, value_str)
+            except WindowsError, err:
+                x64_key_str = (r'SOFTWARE\Wow6432Node\Microsoft\VisualStudio\%s\Setup\VS' %
+                        version)
+                try:
+                    return get_HKLM_registry_value(x64_key_str, value_str)
+                except:
+                    print >> sys.stderr, "Didn't find MS %s version %s " % (product,version)
         
     raise
 
diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index be4d8108602e03a137641f1ad412d544dd13fee0..d909516bf8fbce6872458eec049e0b4c836df6ae 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -49,6 +49,7 @@ const guint ROTATE_IMAGE_TIMEOUT = 8000;
 typedef struct _updater_app_state {
 	std::string app_name;
 	std::string url;
+	std::string file;
 	std::string image_dir;
 	std::string dest_dir;
 	std::string strings_dirs;
@@ -113,7 +114,7 @@ BOOL install_package(std::string package_file, std::string destination);
 BOOL spawn_viewer(UpdaterAppState *app_state);
 
 extern "C" {
-	void on_window_closed(GtkWidget *sender, gpointer state);
+	void on_window_closed(GtkWidget *sender, GdkEvent *event, gpointer state);
 	gpointer worker_thread_cb(gpointer *data);
 	int download_progress_cb(gpointer data, double t, double d, double utotal, double ulnow);
 	gboolean rotate_image_cb(gpointer data);
@@ -216,11 +217,11 @@ gboolean rotate_image_cb(gpointer data)
 std::string next_image_filename(std::string& image_path)
 {
 	std::string image_filename;
-	gDirUtilp->getNextFileInDir(image_path, "/*.jpg", image_filename, true);
+	gDirUtilp->getNextFileInDir(image_path, "/*.jpg", image_filename);
 	return image_path + "/" + image_filename;
 }
 
-void on_window_closed(GtkWidget *sender, gpointer data)
+void on_window_closed(GtkWidget *sender, GdkEvent* event, gpointer data)
 {
 	UpdaterAppState *app_state;
 
@@ -266,85 +267,95 @@ gpointer worker_thread_cb(gpointer data)
 	CURLcode result;
 	FILE *package_file;
 	GError *error = NULL;
-	char *tmp_filename = NULL;
 	int fd;
 
 	//g_return_val_if_fail (data != NULL, NULL);
 	app_state = (UpdaterAppState *) data;
 
 	try {
-		// create temporary file to store the package.
-		fd = g_file_open_tmp
-			("secondlife-update-XXXXXX", &tmp_filename, &error);
-		if (error != NULL)
-		{
-			llerrs << "Unable to create temporary file: "
-			       << error->message
-			       << llendl;
-
-			g_error_free(error);
-			throw 0;
-		}
 
-		package_file = fdopen(fd, "wb");
-		if (package_file == NULL)
+		if(!app_state->url.empty())
 		{
-			llerrs << "Failed to create temporary file: "
-			       << tmp_filename
-			       << llendl;
+			char* tmp_local_filename = NULL;
+			// create temporary file to store the package.
+			fd = g_file_open_tmp
+				("secondlife-update-XXXXXX", &tmp_local_filename, &error);
+			if (error != NULL)
+			{
+				llerrs << "Unable to create temporary file: "
+					   << error->message
+					   << llendl;
 
-			gdk_threads_enter();
-			display_error(app_state->window,
-				      LLTrans::getString("UpdaterFailDownloadTitle"),
-				      LLTrans::getString("UpdaterFailUpdateDescriptive"));
-			gdk_threads_leave();
-			throw 0;
-		}
+				g_error_free(error);
+				throw 0;
+			}
+			
+			if(tmp_local_filename != NULL)
+			{
+				app_state->file = tmp_local_filename;
+				g_free(tmp_local_filename);
+			}
 
-		// initialize curl and start downloading the package
-		llinfos << "Downloading package: " << app_state->url << llendl;
+			package_file = fdopen(fd, "wb");
+			if (package_file == NULL)
+			{
+				llerrs << "Failed to create temporary file: "
+					   << app_state->file.c_str()
+					   << llendl;
+
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
+				throw 0;
+			}
 
-		curl = curl_easy_init();
-		if (curl == NULL)
-		{
-			llerrs << "Failed to initialize libcurl" << llendl;
+			// initialize curl and start downloading the package
+			llinfos << "Downloading package: " << app_state->url << llendl;
 
-			gdk_threads_enter();
-			display_error(app_state->window,
-				      LLTrans::getString("UpdaterFailDownloadTitle"),
-				      LLTrans::getString("UpdaterFailUpdateDescriptive"));
-			gdk_threads_leave();
-			throw 0;
-		}
+			curl = curl_easy_init();
+			if (curl == NULL)
+			{
+				llerrs << "Failed to initialize libcurl" << llendl;
+
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
+				throw 0;
+			}
 
-		curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str());
-		curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE);
-		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE);
-		curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file);
-		curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
-		curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, 
-				 &download_progress_cb);
-		curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state);
+			curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str());
+			curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE);
+			curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE);
+			curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file);
+			curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
+			curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION, 
+							 &download_progress_cb);
+			curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state);
 
-		result = curl_easy_perform(curl);
-		fclose(package_file);
-		curl_easy_cleanup(curl);
+			result = curl_easy_perform(curl);
+			fclose(package_file);
+			curl_easy_cleanup(curl);
 
-		if (result)
-		{
-			llerrs << "Failed to download update: " 
-			       << app_state->url 
-			       << llendl;
+			if (result)
+			{
+				llerrs << "Failed to download update: " 
+					   << app_state->url 
+					   << llendl;
 
-			gdk_threads_enter();
-			display_error(app_state->window,
-				      LLTrans::getString("UpdaterFailDownloadTitle"),
-				      LLTrans::getString("UpdaterFailUpdateDescriptive"));
-			gdk_threads_leave();
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
 
-			throw 0;
+				throw 0;
+			}
 		}
-
+		
 		// now pulse the progres bar back and forth while the package is
 		// being unpacked
 		gdk_threads_enter();
@@ -357,7 +368,7 @@ gpointer worker_thread_cb(gpointer data)
 
 		// *TODO: if the destination is not writable, terminate this
 		// thread and show file chooser?
-		if (!install_package(tmp_filename, app_state->dest_dir))
+		if (!install_package(app_state->file.c_str(), app_state->dest_dir))
 		{
 			llwarns << "Failed to install package to destination: "
 				<< app_state->dest_dir
@@ -392,15 +403,6 @@ gpointer worker_thread_cb(gpointer data)
 		app_state->failure = TRUE;
 	}
 
-	// FIXME: delete package file also if delete-event is raised on window
-	if (tmp_filename != NULL)
-	{
-		if (gDirUtilp->fileExists(tmp_filename))
-		{
-			LLFile::remove(tmp_filename);
-		}
-	}
-
 	gdk_threads_enter();
 	updater_app_quit(app_state);
 	gdk_threads_leave();
@@ -712,7 +714,7 @@ BOOL spawn_viewer(UpdaterAppState *app_state)
 
 void show_usage_and_exit()
 {
-	std::cout << "Usage: linux-updater --url URL --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE"
+	std::cout << "Usage: linux-updater <--url URL | --file FILE> --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE"
 		  << "[--image-dir PATH]"
 		  << std::endl;
 	exit(1);
@@ -728,6 +730,10 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
 		{
 			app_state->url = argv[i];
 		}
+		else if ((!strcmp(argv[i], "--file")) && (++i < argc))
+		{
+			app_state->file = argv[i];
+		}
 		else if ((!strcmp(argv[i], "--name")) && (++i < argc))
 		{
 			app_state->app_name = argv[i];
@@ -756,7 +762,7 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
 	}
 
 	if (app_state->app_name.empty() 
-	    || app_state->url.empty() 
+	    || (app_state->url.empty() && app_state->file.empty())  
 	    || app_state->dest_dir.empty())
 	{
 		show_usage_and_exit();
@@ -771,10 +777,10 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
 
 int main(int argc, char **argv)
 {
-	UpdaterAppState app_state;
+	UpdaterAppState* app_state = new UpdaterAppState;
 	GThread *worker_thread;
 
-	parse_args_and_init(argc, argv, &app_state);
+	parse_args_and_init(argc, argv, app_state);
 
 	// Initialize logger, and rename old log file
 	gDirUtilp->initAppDirs("SecondLife");
@@ -797,17 +803,29 @@ int main(int argc, char **argv)
 	gtk_init(&argc, &argv);
 
 	// create UI
-	updater_app_ui_init(&app_state);
+	updater_app_ui_init(app_state);
 
 	//llinfos << "SAMPLE TRANSLATION IS: " << LLTrans::getString("LoginInProgress") << llendl;
 
 	// create download thread
 	worker_thread = g_thread_create
-		(GThreadFunc(worker_thread_cb), &app_state, FALSE, NULL);
+		(GThreadFunc(worker_thread_cb), app_state, FALSE, NULL);
 
 	gdk_threads_enter();
 	gtk_main();
 	gdk_threads_leave();
 
-	return (app_state.failure == FALSE) ? 0 : 1;
+	// Delete the file only if created from url download.
+	if(!app_state->url.empty() && !app_state->file.empty())
+	{
+		if (gDirUtilp->fileExists(app_state->file))
+		{
+			LLFile::remove(app_state->file);
+		}
+	}
+
+	bool success = !app_state->failure;
+	delete app_state;
+	return success ? 0 : 1;
 }
+
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index 1cc03bddb8ecfe665fa7a5bd51b1d1a5585cd062..c9cb1cd6e7c80366564891c9440a1630ea203a73 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -1557,6 +1557,10 @@ bool LLAudioSource::hasPendingPreloads() const
 		LLAudioData *adp = iter->second;
 		// note: a bad UUID will forever be !hasDecodedData()
 		// but also !hasValidData(), hence the check for hasValidData()
+		if (!adp)
+		{
+			continue;
+		}
 		if (!adp->hasDecodedData() && adp->hasValidData())
 		{
 			// This source is still waiting for a preload
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 478f2fedbd1912b8807e8730ffc645cb33ab2604..9342a22d46f9d0a3a0b0017544af3aa6a19383bd 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -93,6 +93,7 @@ set(llcommon_SOURCE_FILES
     llstringtable.cpp
     llsys.cpp
     llthread.cpp
+    llthreadsafequeue.cpp
     lltimer.cpp
     lluri.cpp
     lluuid.cpp
@@ -225,6 +226,7 @@ set(llcommon_HEADER_FILES
     llstringtable.h
     llsys.h
     llthread.h
+    llthreadsafequeue.h
     lltimer.h
     lltreeiterators.h
     lluri.h
diff --git a/indra/llcommon/indra_constants.h b/indra/llcommon/indra_constants.h
index b0618bfe596ebb1727f18a45a269d5019d902f02..95cb606240276669b171d4113d18b213e4cd46a5 100644
--- a/indra/llcommon/indra_constants.h
+++ b/indra/llcommon/indra_constants.h
@@ -245,9 +245,6 @@ const U8 SIM_ACCESS_ADULT	= 42;		// Seriously Adult Only
 const U8 SIM_ACCESS_DOWN	= 254;
 const U8 SIM_ACCESS_MAX 	= SIM_ACCESS_ADULT;
 
-// group constants
-const S32 MAX_AGENT_GROUPS = 25;
-
 // attachment constants
 const S32 MAX_AGENT_ATTACHMENTS = 38;
 const U8  ATTACHMENT_ADD = 0x80;
@@ -300,6 +297,14 @@ const U32 START_LOCATION_ID_COUNT 		= 6;
 // group constants
 const U32 GROUP_MIN_SIZE = 2;
 
+// gMaxAgentGroups is now sent by login.cgi, which
+// looks it up from globals.xml.
+//
+// For now we need an old default value however,
+// so the viewer can be deployed ahead of login.cgi.
+//
+const S32 DEFAULT_MAX_AGENT_GROUPS = 25;
+
 // radius within which a chat message is fully audible
 const F32 CHAT_WHISPER_RADIUS = 10.f;
 const F32 CHAT_NORMAL_RADIUS = 20.f;
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index 66ec5bad2c55291b1d798811da15e454c3120b95..d1c44c94032851a19a4ab42f20006ce04a1eb1f4 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -28,6 +28,7 @@
 
 #include "linden_common.h"
 #include "llapr.h"
+#include "apr_dso.h"
 
 apr_pool_t *gAPRPoolp = NULL; // Global APR memory pool
 LLVolatileAPRPool *LLAPRFile::sAPRFilePoolp = NULL ; //global volatile APR memory pool.
@@ -279,14 +280,31 @@ bool ll_apr_warn_status(apr_status_t status)
 {
 	if(APR_SUCCESS == status) return false;
 	char buf[MAX_STRING];	/* Flawfinder: ignore */
-	apr_strerror(status, buf, MAX_STRING);
+	apr_strerror(status, buf, sizeof(buf));
 	LL_WARNS("APR") << "APR: " << buf << LL_ENDL;
 	return true;
 }
 
+bool ll_apr_warn_status(apr_status_t status, apr_dso_handle_t *handle)
+{
+    bool result = ll_apr_warn_status(status);
+    // Despite observed truncation of actual Mac dylib load errors, increasing
+    // this buffer to more than MAX_STRING doesn't help: it appears that APR
+    // stores the output in a fixed 255-character internal buffer. (*sigh*)
+    char buf[MAX_STRING];           /* Flawfinder: ignore */
+    apr_dso_error(handle, buf, sizeof(buf));
+    LL_WARNS("APR") << "APR: " << buf << LL_ENDL;
+    return result;
+}
+
 void ll_apr_assert_status(apr_status_t status)
 {
-	llassert(ll_apr_warn_status(status) == false);
+	llassert(! ll_apr_warn_status(status));
+}
+
+void ll_apr_assert_status(apr_status_t status, apr_dso_handle_t *handle)
+{
+    llassert(! ll_apr_warn_status(status, handle));
 }
 
 //---------------------------------------------------------------------
diff --git a/indra/llcommon/llapr.h b/indra/llcommon/llapr.h
index 4930270af81c843ef24420d499e774989e09630b..af33ce666f1558193d3d2818cf0c3a5e98d6ee7a 100644
--- a/indra/llcommon/llapr.h
+++ b/indra/llcommon/llapr.h
@@ -53,6 +53,8 @@
 extern LL_COMMON_API apr_thread_mutex_t* gLogMutexp;
 extern apr_thread_mutex_t* gCallStacksLogMutexp;
 
+struct apr_dso_handle_t;
+
 /** 
  * @brief initialize the common apr constructs -- apr itself, the
  * global pool, and a mutex.
@@ -259,8 +261,11 @@ class LL_COMMON_API LLAPRFile : boost::noncopyable
  * @return Returns <code>true</code> if status is an error condition.
  */
 bool LL_COMMON_API ll_apr_warn_status(apr_status_t status);
+/// There's a whole other APR error-message function if you pass a DSO handle.
+bool LL_COMMON_API ll_apr_warn_status(apr_status_t status, apr_dso_handle_t* handle);
 
 void LL_COMMON_API ll_apr_assert_status(apr_status_t status);
+void LL_COMMON_API ll_apr_assert_status(apr_status_t status, apr_dso_handle_t* handle);
 
 extern "C" LL_COMMON_API apr_pool_t* gAPRPoolp; // Global APR memory pool
 
diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp
index 84a6620a77782b82cb764b0d1691ee9a52919bd9..97e2bdeb5754288521d26fe379b987f19312a2d0 100644
--- a/indra/llcommon/llevents.cpp
+++ b/indra/llcommon/llevents.cpp
@@ -475,7 +475,7 @@ void LLEventPump::stopListening(const std::string& name)
 *****************************************************************************/
 bool LLEventStream::post(const LLSD& event)
 {
-    if (! mEnabled)
+    if (! mEnabled || !mSignal)
     {
         return false;
     }
@@ -515,6 +515,8 @@ bool LLEventQueue::post(const LLSD& event)
 
 void LLEventQueue::flush()
 {
+	if(!mSignal) return;
+		
     // Consider the case when a given listener on this LLEventQueue posts yet
     // another event on the same queue. If we loop over mEventQueue directly,
     // we'll end up processing all those events during the same flush() call
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index 289ce0bc2cfda4b52a63975e7d1905e47d03210b..8f02391e75a7dcbcf6f2d1b8734aca1550d7969f 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -318,7 +318,12 @@ void llofstream::close()
 	if(is_open())
 	{
 		if (_Filebuffer->close() == 0)
+		{
 			_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
+		}
+		delete _Filebuffer;
+		_Filebuffer = NULL;
+		_ShouldClose = false;
 	}
 }
 
diff --git a/indra/llcommon/llprocesslauncher.cpp b/indra/llcommon/llprocesslauncher.cpp
index 99308c94e7caceda486897c83d5f4dc3a8d04284..4b0f6b02511ecd46f46a889262c4c2017b4f8b2c 100644
--- a/indra/llcommon/llprocesslauncher.cpp
+++ b/indra/llcommon/llprocesslauncher.cpp
@@ -58,6 +58,11 @@ void LLProcessLauncher::setWorkingDirectory(const std::string &dir)
 	mWorkingDir = dir;
 }
 
+const std::string& LLProcessLauncher::getExecutable() const
+{
+	return mExecutable;
+}
+
 void LLProcessLauncher::clearArguments()
 {
 	mLaunchArguments.clear();
@@ -260,14 +265,7 @@ int LLProcessLauncher::launch(void)
 	delete[] fake_argv;
 	
 	mProcessID = id;
-	
-	// At this point, the child process will have been created (since that's how vfork works -- the child borrowed our execution context until it forked)
-	// If the process doesn't exist at this point, the exec failed.
-	if(!isRunning())
-	{
-		result = -1;
-	}
-	
+
 	return result;
 }
 
diff --git a/indra/llcommon/llprocesslauncher.h b/indra/llcommon/llprocesslauncher.h
index 479aeb664a5df4cd3498252c5b8f66968b6636eb..954c2491472eb2e17b11122fe7d95eeb53348fff 100644
--- a/indra/llcommon/llprocesslauncher.h
+++ b/indra/llcommon/llprocesslauncher.h
@@ -47,6 +47,8 @@ class LL_COMMON_API LLProcessLauncher
 	void setExecutable(const std::string &executable);
 	void setWorkingDirectory(const std::string &dir);
 
+	const std::string& getExecutable() const;
+
 	void clearArguments();
 	void addArgument(const std::string &arg);
 	void addArgument(const char *arg);
diff --git a/indra/llcommon/llqueuedthread.h b/indra/llcommon/llqueuedthread.h
index c75e0e2bbf9e613579d24283662d27443b7f0512..a53b22f6fc2889622682d9cb446a3a5eabff7d89 100644
--- a/indra/llcommon/llqueuedthread.h
+++ b/indra/llcommon/llqueuedthread.h
@@ -179,7 +179,7 @@ class LL_COMMON_API LLQueuedThread : public LLThread
 	void waitOnPending();
 	void printQueueStats();
 
-	S32 getPending();
+	virtual S32 getPending();
 	bool getThreaded() { return mThreaded ? true : false; }
 
 	// Request accessors
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index d7b7c3699ccdca91002c21d34bcd25fba57a28d0..49d05ef4114ddd5fb3df5c8a777e0c13dbaa4e38 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -63,9 +63,6 @@ void *APR_THREAD_FUNC LLThread::staticRun(apr_thread_t *apr_threadp, void *datap
 {
 	LLThread *threadp = (LLThread *)datap;
 
-	// Set thread state to running
-	threadp->mStatus = RUNNING;
-
 	// Run the user supplied function
 	threadp->run();
 
@@ -147,26 +144,45 @@ void LLThread::shutdown()
 		{
 			// This thread just wouldn't stop, even though we gave it time
 			llwarns << "LLThread::~LLThread() exiting thread before clean exit!" << llendl;
+			// Put a stake in its heart.
+			apr_thread_exit(mAPRThreadp, -1);
 			return;
 		}
 		mAPRThreadp = NULL;
 	}
 
 	delete mRunCondition;
+	mRunCondition = 0;
 	
-	if (mIsLocalPool)
+	if (mIsLocalPool && mAPRPoolp)
 	{
 		apr_pool_destroy(mAPRPoolp);
+		mAPRPoolp = 0;
 	}
 }
 
 
 void LLThread::start()
 {
-	apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);	
+	llassert(isStopped());
+	
+	// Set thread state to running
+	mStatus = RUNNING;
 
-	// We won't bother joining
-	apr_thread_detach(mAPRThreadp);
+	apr_status_t status =
+		apr_thread_create(&mAPRThreadp, NULL, staticRun, (void *)this, mAPRPoolp);
+	
+	if(status == APR_SUCCESS)
+	{	
+		// We won't bother joining
+		apr_thread_detach(mAPRThreadp);
+	}
+	else
+	{
+		mStatus = STOPPED;
+		llwarns << "failed to start thread " << mName << llendl;
+		ll_apr_warn_status(status);
+	}
 }
 
 //============================================================================
diff --git a/indra/llcommon/llthreadsafequeue.cpp b/indra/llcommon/llthreadsafequeue.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8a73e632a9ada2249b4353f88828d5d66fcfe00d
--- /dev/null
+++ b/indra/llcommon/llthreadsafequeue.cpp
@@ -0,0 +1,109 @@
+/** 
+ * @file llthread.cpp
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include <apr_pools.h>
+#include <apr_queue.h>
+#include "llthreadsafequeue.h"
+
+
+
+// LLThreadSafeQueueImplementation
+//-----------------------------------------------------------------------------
+
+
+LLThreadSafeQueueImplementation::LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity):
+	mOwnsPool(pool == 0),
+	mPool(pool),
+	mQueue(0)
+{
+	if(mOwnsPool) {
+		apr_status_t status = apr_pool_create(&mPool, 0);
+		if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate pool");
+	} else {
+		; // No op.
+	}
+	
+	apr_status_t status = apr_queue_create(&mQueue, capacity, mPool);
+	if(status != APR_SUCCESS) throw LLThreadSafeQueueError("failed to allocate queue");
+}
+
+
+LLThreadSafeQueueImplementation::~LLThreadSafeQueueImplementation()
+{
+	if(mQueue != 0) {
+		if(apr_queue_size(mQueue) != 0) llwarns << 
+			"terminating queue which still contains " << apr_queue_size(mQueue) <<
+			" elements;" << "memory will be leaked" << LL_ENDL;
+		apr_queue_term(mQueue);
+	}
+	if(mOwnsPool && (mPool != 0)) apr_pool_destroy(mPool);
+}
+
+
+void LLThreadSafeQueueImplementation::pushFront(void * element)
+{
+	apr_status_t status = apr_queue_push(mQueue, element);
+	
+	if(status == APR_EINTR) {
+		throw LLThreadSafeQueueInterrupt();
+	} else if(status != APR_SUCCESS) {
+		throw LLThreadSafeQueueError("push failed");
+	} else {
+		; // Success.
+	}
+}
+
+
+bool LLThreadSafeQueueImplementation::tryPushFront(void * element){
+	return apr_queue_trypush(mQueue, element) == APR_SUCCESS;
+}
+
+
+void * LLThreadSafeQueueImplementation::popBack(void)
+{
+	void * element;
+	apr_status_t status = apr_queue_pop(mQueue, &element);
+
+	if(status == APR_EINTR) {
+		throw LLThreadSafeQueueInterrupt();
+	} else if(status != APR_SUCCESS) {
+		throw LLThreadSafeQueueError("pop failed");
+	} else {
+		return element;
+	}
+}
+
+
+bool LLThreadSafeQueueImplementation::tryPopBack(void *& element)
+{
+	return apr_queue_trypop(mQueue, &element) == APR_SUCCESS;
+}
+
+
+size_t LLThreadSafeQueueImplementation::size()
+{
+	return apr_queue_size(mQueue);
+}
diff --git a/indra/llcommon/llthreadsafequeue.h b/indra/llcommon/llthreadsafequeue.h
new file mode 100644
index 0000000000000000000000000000000000000000..58cac38769cd2d3801fc9f01b1d1cc2a010ae0c6
--- /dev/null
+++ b/indra/llcommon/llthreadsafequeue.h
@@ -0,0 +1,205 @@
+/** 
+ * @file llthreadsafequeue.h
+ * @brief Base classes for thread, mutex and condition handling.
+ *
+ * $LicenseInfo:firstyear=2004&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTHREADSAFEQUEUE_H
+#define LL_LLTHREADSAFEQUEUE_H
+
+
+#include <string>
+#include <stdexcept>
+
+
+struct apr_pool_t; // From apr_pools.h
+class LLThreadSafeQueueImplementation; // See below.
+
+
+//
+// A general queue exception.
+//
+class LL_COMMON_API LLThreadSafeQueueError:
+public std::runtime_error
+{
+public:
+	LLThreadSafeQueueError(std::string const & message):
+	std::runtime_error(message)
+	{
+		; // No op.
+	}
+};
+
+
+//
+// An exception raised when blocking operations are interrupted.
+//
+class LL_COMMON_API LLThreadSafeQueueInterrupt:
+	public LLThreadSafeQueueError
+{
+public:
+	LLThreadSafeQueueInterrupt(void):
+		LLThreadSafeQueueError("queue operation interrupted")
+	{
+		; // No op.
+	}
+};
+
+
+struct apr_queue_t; // From apr_queue.h
+
+
+//
+// Implementation details. 
+//
+class LL_COMMON_API LLThreadSafeQueueImplementation
+{
+public:
+	LLThreadSafeQueueImplementation(apr_pool_t * pool, unsigned int capacity);
+	~LLThreadSafeQueueImplementation();
+	void pushFront(void * element);
+	bool tryPushFront(void * element);
+	void * popBack(void);
+	bool tryPopBack(void *& element);
+	size_t size();
+	
+private:
+	bool mOwnsPool;
+	apr_pool_t * mPool;
+	apr_queue_t * mQueue;
+};
+
+
+//
+// Implements a thread safe FIFO.
+//
+template<typename ElementT>
+class LLThreadSafeQueue
+{
+public:
+	typedef ElementT value_type;
+	
+	// If the pool is set to NULL one will be allocated and managed by this
+	// queue.
+	LLThreadSafeQueue(apr_pool_t * pool = 0, unsigned int capacity = 1024);
+	
+	// Add an element to the front of queue (will block if the queue has
+	// reached capacity).
+	//
+	// This call will raise an interrupt error if the queue is deleted while
+	// the caller is blocked.
+	void pushFront(ElementT const & element);
+	
+	// Try to add an element to the front ofqueue without blocking. Returns
+	// true only if the element was actually added.
+	bool tryPushFront(ElementT const & element);
+	
+	// Pop the element at the end of the queue (will block if the queue is
+	// empty).
+	//
+	// This call will raise an interrupt error if the queue is deleted while
+	// the caller is blocked.
+	ElementT popBack(void);
+	
+	// Pop an element from the end of the queue if there is one available.
+	// Returns true only if an element was popped.
+	bool tryPopBack(ElementT & element);
+	
+	// Returns the size of the queue.
+	size_t size();
+
+private:
+	LLThreadSafeQueueImplementation mImplementation;
+};
+
+
+
+// LLThreadSafeQueue
+//-----------------------------------------------------------------------------
+
+
+template<typename ElementT>
+LLThreadSafeQueue<ElementT>::LLThreadSafeQueue(apr_pool_t * pool, unsigned int capacity):
+	mImplementation(pool, capacity)
+{
+	; // No op.
+}
+
+
+template<typename ElementT>
+void LLThreadSafeQueue<ElementT>::pushFront(ElementT const & element)
+{
+	ElementT * elementCopy = new ElementT(element);
+	try {
+		mImplementation.pushFront(elementCopy);
+	} catch (LLThreadSafeQueueInterrupt) {
+		delete elementCopy;
+		throw;
+	}
+}
+
+
+template<typename ElementT>
+bool LLThreadSafeQueue<ElementT>::tryPushFront(ElementT const & element)
+{
+	ElementT * elementCopy = new ElementT(element);
+	bool result = mImplementation.tryPushFront(elementCopy);
+	if(!result) delete elementCopy;
+	return result;
+}
+
+
+template<typename ElementT>
+ElementT LLThreadSafeQueue<ElementT>::popBack(void)
+{
+	ElementT * element = reinterpret_cast<ElementT *> (mImplementation.popBack());
+	ElementT result(*element);
+	delete element;
+	return result;
+}
+
+
+template<typename ElementT>
+bool LLThreadSafeQueue<ElementT>::tryPopBack(ElementT & element)
+{
+	void * storedElement;
+	bool result = mImplementation.tryPopBack(storedElement);
+	if(result) {
+		ElementT * elementPtr = reinterpret_cast<ElementT *>(storedElement); 
+		element = *elementPtr;
+		delete elementPtr;
+	} else {
+		; // No op.
+	}
+	return result;
+}
+
+
+template<typename ElementT>
+size_t LLThreadSafeQueue<ElementT>::size(void)
+{
+	return mImplementation.size();
+}
+
+
+#endif
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index b209e4aa38bcecaad79cf122ad66aee09545ab87..356e0f4c0f3344ca7bf0e5e332070b384eb7915c 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -28,14 +28,14 @@
 #define LL_LLVERSIONVIEWER_H
 
 const S32 LL_VERSION_MAJOR = 2;
-const S32 LL_VERSION_MINOR = 4;
+const S32 LL_VERSION_MINOR = 5;
 const S32 LL_VERSION_PATCH = 0;
 const S32 LL_VERSION_BUILD = 0;
 
 const char * const LL_CHANNEL = "Second Life Developer";
 
 #if LL_DARWIN
-const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.snowglobe.viewer";
+const char * const LL_VERSION_BUNDLE_ID = "com.secondlife.indra.viewer";
 #endif
 
 #endif
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index bda76eac806620636f721fe77e1f2f3a00f56ef6..a3caf79519cf22e06a277b5971ad45d399782487 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -61,8 +61,6 @@ static const std::string INV_FOLDER_ID_LABEL_WS("category_id");
 ///----------------------------------------------------------------------------
 /// Local function declarations, constants, enums, and typedefs
 ///----------------------------------------------------------------------------
-const U8 TASK_INVENTORY_ITEM_KEY = 0;
-const U8 TASK_INVENTORY_ASSET_KEY = 1;
 
 const LLUUID MAGIC_ID("3c115e51-04f4-523c-9fa6-98aff1034730");	
 
diff --git a/indra/llinventory/llnotecard.cpp b/indra/llinventory/llnotecard.cpp
index 62829c284f4dd764f12e1ae4e984546a0ea38995..69152cefe078a75c034e329f5194387a6d0d731b 100644
--- a/indra/llinventory/llnotecard.cpp
+++ b/indra/llinventory/llnotecard.cpp
@@ -199,7 +199,7 @@ bool LLNotecard::importStream(std::istream& str)
 		return FALSE;
 	}
 
-	if(text_len > mMaxText)
+	if(text_len > mMaxText || text_len < 0)
 	{
 		llwarns << "Invalid Linden text length: " << text_len << llendl;
 		return FALSE;
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index b26d412e9fa688b80f4c2eda69549f9fba579989..27a368df3d0e05ed349dcfa86efd491958f8dc03 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -513,6 +513,10 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL
 
 }
 
+//
+// *NOTE:  Logic here is replicated in LLViewerAssetStorage::_queueDataRequest.
+// Changes here may need to be replicated in the viewer's derived class.
+//
 void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType atype,
 									   LLGetAssetCallback callback,
 									   void *user_data, BOOL duplicate,
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 2f2d9099a34287bf677b0ebcffc5d5f88e08a21c..03c28eb2a56bae5c34059273f637ec3a76fe4a79 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -235,27 +235,21 @@ class LLAvatarNameResponder : public LLHTTPClient::Responder
 
 	/*virtual*/ void error(U32 status, const std::string& reason)
 	{
-		// We're going to construct a dummy record and cache it for a while,
-		// either briefly for a 503 Service Unavailable, or longer for other
-		// errors.
-		F64 retry_timestamp = errorRetryTimestamp(status);
-
-		// *NOTE: "??" starts trigraphs in C/C++, escape the question marks.
-		const std::string DUMMY_NAME("\?\?\?");
-		LLAvatarName av_name;
-		av_name.mUsername = DUMMY_NAME;
-		av_name.mDisplayName = DUMMY_NAME;
-		av_name.mIsDisplayNameDefault = false;
-		av_name.mIsDummy = true;
-		av_name.mExpires = retry_timestamp;
+		// If there's an error, it might be caused by PeopleApi,
+		// or when loading textures on startup and using a very slow 
+		// network, this query may time out. Fallback to the legacy
+		// cache. 
+
+		llwarns << "LLAvatarNameResponder error " << status << " " << reason << llendl;
 
 		// Add dummy records for all agent IDs in this request
 		std::vector<LLUUID>::const_iterator it = mAgentIDs.begin();
 		for ( ; it != mAgentIDs.end(); ++it)
 		{
 			const LLUUID& agent_id = *it;
-			// cache it and fire signals
-			LLAvatarNameCache::processName(agent_id, av_name, true);
+			gCacheName->get(agent_id, false,  // legacy compatibility
+						boost::bind(&LLAvatarNameCache::legacyNameCallback,
+						_1, _2, _3));
 		}
 	}
 
@@ -286,18 +280,8 @@ class LLAvatarNameResponder : public LLHTTPClient::Responder
 		}
 
 		// No information in header, make a guess
-		if (status == 503)
-		{
-			// ...service unavailable, retry soon
-			const F64 SERVICE_UNAVAILABLE_DELAY = 600.0; // 10 min
-			return now + SERVICE_UNAVAILABLE_DELAY;
-		}
-		else
-		{
-			// ...other unexpected error
-			const F64 DEFAULT_DELAY = 3600.0; // 1 hour
-			return now + DEFAULT_DELAY;
-		}
+		const F64 DEFAULT_DELAY = 120.0; // 2 mintues
+		return now + DEFAULT_DELAY;
 	}
 };
 
@@ -367,7 +351,7 @@ void LLAvatarNameCache::requestNamesViaCapability()
 		if (url.size() > NAME_URL_SEND_THRESHOLD)
 		{
 			//llinfos << "requestNames " << url << llendl;
-			LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
+			LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));//, LLSD(), 10.0f);
 			url.clear();
 			agent_ids.clear();
 		}
@@ -376,7 +360,7 @@ void LLAvatarNameCache::requestNamesViaCapability()
 	if (!url.empty())
 	{
 		//llinfos << "requestNames " << url << llendl;
-		LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));
+		LLHTTPClient::get(url, new LLAvatarNameResponder(agent_ids));//, LLSD(), 10.0f);
 		url.clear();
 		agent_ids.clear();
 	}
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 4ab6bd2438cb187d36186b43b4c03b770501a0a5..479efabb5f68836d31a658e35ab1e1874a4ed4f5 100644
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -556,35 +556,43 @@ std::string LLCacheName::buildUsername(const std::string& full_name)
 //static 
 std::string LLCacheName::buildLegacyName(const std::string& complete_name)
 {
-	// regexp doesn't play nice with unicode, chop off the display name
+	//boost::regexp was showing up in the crashreporter, so doing  
+	//painfully manual parsing using substr. LF
 	S32 open_paren = complete_name.rfind(" (");
+	S32 close_paren = complete_name.rfind(')');
 
-	if (open_paren == std::string::npos)
+	if (open_paren != std::string::npos &&
+		close_paren == complete_name.length()-1)
 	{
-		return complete_name;
-	}
+		S32 length = close_paren - open_paren - 2;
+		std::string legacy_name = complete_name.substr(open_paren+2, length);
+		
+		if (legacy_name.length() > 0)
+		{			
+			std::string cap_letter = legacy_name.substr(0, 1);
+			LLStringUtil::toUpper(cap_letter);
+			legacy_name = cap_letter + legacy_name.substr(1);
+	
+			S32 separator = legacy_name.find('.');
 
-	std::string username = complete_name.substr(open_paren);
-	boost::regex complete_name_regex("( \\()([a-z0-9]+)(.[a-z]+)*(\\))");
-	boost::match_results<std::string::const_iterator> name_results;
-	if (!boost::regex_match(username, name_results, complete_name_regex)) return complete_name;
+			if (separator != std::string::npos)
+			{
+				std::string last_name = legacy_name.substr(separator+1);
+				legacy_name = legacy_name.substr(0, separator);
 
-	std::string legacy_name = name_results[2];
-	// capitalize the first letter
-	std::string cap_letter = legacy_name.substr(0, 1);
-	LLStringUtil::toUpper(cap_letter);
-	legacy_name = cap_letter + legacy_name.substr(1);
+				if (last_name.length() > 0)
+				{
+					cap_letter = last_name.substr(0, 1);
+					LLStringUtil::toUpper(cap_letter);
+					legacy_name = legacy_name + " " + cap_letter + last_name.substr(1);
+				}
+			}
 
-	if (name_results[3].matched)
-	{
-		std::string last_name = name_results[3];
-		std::string cap_letter = last_name.substr(1, 1);
-		LLStringUtil::toUpper(cap_letter);
-		last_name = cap_letter + last_name.substr(2);
-		legacy_name = legacy_name + " " + last_name;
+			return legacy_name;
+		}
 	}
 
-	return legacy_name;
+	return complete_name;
 }
 
 // This is a little bit kludgy. LLCacheNameCallback is a slot instead of a function pointer.
@@ -967,6 +975,10 @@ void LLCacheName::Impl::processUUIDReply(LLMessageSystem* msg, bool isGroup)
 			if (entry->mLastName.empty())
 			{
 				full_name = cleanFullName(entry->mFirstName);
+
+				//fix what we are putting in the cache
+				entry->mFirstName = full_name;
+				entry->mLastName = "Resident";
 			}
 			else
 			{
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index d3a73058c4a7a6fbe0b87eabcfe263a65ef53468..1dc05e0b20ba95a29fd4377f610a763f9eefa67f 100644
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -20,6 +20,7 @@ include_directories(
     ${LLRENDER_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
+    ${LLQTWEBKIT_INCLUDE_DIR}
     )
 
 set(llplugin_SOURCE_FILES
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index 69ed0fb09c1406ab8fa7c16d27f3d5f7ed992434..595c470a195cfb12ee9425db6910548be5e99882 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -160,7 +160,7 @@ void LLPluginClassMedia::idle(void)
 		mPlugin->idle();
 	}
 	
-	if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()))
+	if((mMediaWidth == -1) || (!mTextureParamsReceived) || (mPlugin == NULL) || (mPlugin->isBlocked()) || (mOwner == NULL))
 	{
 		// Can't process a size change at this time
 	}
@@ -522,7 +522,15 @@ bool LLPluginClassMedia::keyEvent(EKeyEventType type, int key_code, MASK modifie
 			}
 		break;
 	}
-	
+
+#if LL_DARWIN	
+	if(modifiers & MASK_ALT)
+	{
+		// Option-key modified characters should be handled by the unicode input path instead of this one.
+		result = false;
+	}
+#endif
+
 	if(result)
 	{
 		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "key_event");
@@ -674,7 +682,21 @@ void LLPluginClassMedia::sendPickFileResponse(const std::string &file)
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "pick_file_response");
 	message.setValue("file", file);
-	if(mPlugin->isBlocked())
+	if(mPlugin && mPlugin->isBlocked())
+	{
+		// If the plugin sent a blocking pick-file request, the response should unblock it.
+		message.setValueBoolean("blocking_response", true);
+	}
+	sendMessage(message);
+}
+
+void LLPluginClassMedia::sendAuthResponse(bool ok, const std::string &username, const std::string &password)
+{
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_response");
+	message.setValueBoolean("ok", ok);
+	message.setValue("username", username);
+	message.setValue("password", password);
+	if(mPlugin && mPlugin->isBlocked())
 	{
 		// If the plugin sent a blocking pick-file request, the response should unblock it.
 		message.setValueBoolean("blocking_response", true);
@@ -947,6 +969,12 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 		{
 			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_PICK_FILE_REQUEST);
 		}
+		else if(message_name == "auth_request")
+		{
+			mAuthURL = message.getValue("url");
+			mAuthRealm = message.getValue("realm");
+			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_AUTH_REQUEST);
+		}
 		else
 		{
 			LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
@@ -1019,6 +1047,15 @@ void LLPluginClassMedia::receivePluginMessage(const LLPluginMessage &message)
 				
 			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_GEOMETRY_CHANGE);
 		}
+		else if(message_name == "link_hovered")
+		{
+			// text is not currently used -- the tooltip hover text is taken from the "title".
+			mHoverLink = message.getValue("link");
+			mHoverText = message.getValue("title");
+			// message.getValue("text");
+				
+			mediaEvent(LLPluginClassMediaOwner::MEDIA_EVENT_LINK_HOVERED);
+		}
 		else
 		{
 			LL_WARNS("Plugin") << "Unknown " << message_name << " class message: " << message_name << LL_ENDL;
@@ -1192,6 +1229,20 @@ void LLPluginClassMedia::proxyWindowClosed(const std::string &uuid)
 	sendMessage(message);
 }
 
+void LLPluginClassMedia::ignore_ssl_cert_errors(bool ignore)
+{
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "ignore_ssl_cert_errors");
+	message.setValueBoolean("ignore", ignore);
+	sendMessage(message);
+}
+
+void LLPluginClassMedia::addCertificateFilePath(const std::string& path)
+{
+	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "add_certificate_file_path");
+	message.setValue("path", path);
+	sendMessage(message);
+}
+
 void LLPluginClassMedia::crashPlugin()
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_INTERNAL, "crash");
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index 9cb67fe9091b0f018d0cc19504add6e2caea6a86..c826e13c4078abca91df7eb338a5155415c32c97 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -85,6 +85,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	
 	void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; };
 	
+	void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; };
+	
 	// Returns true if all of the texture parameters (depth, format, size, and texture size) are set up and consistent.
 	// This will initially be false, and will also be false for some time after setSize while the resize is processed.
 	// Note that if this returns true, it is safe to use all the get() functions above without checking for invalid return values
@@ -159,6 +161,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	
 	void sendPickFileResponse(const std::string &file);
 
+	void sendAuthResponse(bool ok, const std::string &username, const std::string &password);
+
 	// Valid after a MEDIA_EVENT_CURSOR_CHANGED event
 	std::string getCursorName() const { return mCursorName; };
 
@@ -198,6 +202,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	void setBrowserUserAgent(const std::string& user_agent);
 	void proxyWindowOpened(const std::string &target, const std::string &uuid);
 	void proxyWindowClosed(const std::string &uuid);
+	void ignore_ssl_cert_errors(bool ignore);
+	void addCertificateFilePath(const std::string& path);
 	
 	// This is valid after MEDIA_EVENT_NAVIGATE_BEGIN or MEDIA_EVENT_NAVIGATE_COMPLETE
 	std::string	getNavigateURI() const { return mNavigateURI; };
@@ -231,7 +237,15 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	S32 getGeometryY() const { return mGeometryY; };
 	S32 getGeometryWidth() const { return mGeometryWidth; };
 	S32 getGeometryHeight() const { return mGeometryHeight; };
+	
+	// These are valid during MEDIA_EVENT_AUTH_REQUEST
+	std::string	getAuthURL() const { return mAuthURL; };
+	std::string	getAuthRealm() const { return mAuthRealm; };
 
+	// These are valid during MEDIA_EVENT_LINK_HOVERED
+	std::string	getHoverText() const { return mHoverText; };
+	std::string	getHoverLink() const { return mHoverLink; };
+	
 	std::string getMediaName() const { return mMediaName; };
 	std::string getMediaDescription() const { return mMediaDescription; };
 
@@ -369,6 +383,10 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	S32				mGeometryY;
 	S32				mGeometryWidth;
 	S32				mGeometryHeight;
+	std::string		mAuthURL;
+	std::string		mAuthRealm;
+	std::string		mHoverText;
+	std::string		mHoverLink;
 	
 	/////////////////////////////////////////
 	// media_time class
diff --git a/indra/llplugin/llpluginclassmediaowner.h b/indra/llplugin/llpluginclassmediaowner.h
index c9efff216c076292fc3237c9de81962efc563c11..42e93cc6d7e12da5b69b30cd8d516b33fefa673e 100644
--- a/indra/llplugin/llpluginclassmediaowner.h
+++ b/indra/llplugin/llpluginclassmediaowner.h
@@ -59,7 +59,11 @@ class LLPluginClassMediaOwner
 		MEDIA_EVENT_GEOMETRY_CHANGE,		// The plugin requested its window geometry be changed (per the javascript window interface)
 		
 		MEDIA_EVENT_PLUGIN_FAILED_LAUNCH,	// The plugin failed to launch 
-		MEDIA_EVENT_PLUGIN_FAILED			// The plugin died unexpectedly
+		MEDIA_EVENT_PLUGIN_FAILED,			// The plugin died unexpectedly
+
+		MEDIA_EVENT_AUTH_REQUEST,			// The plugin wants to display an auth dialog
+
+		MEDIA_EVENT_LINK_HOVERED			// Got a "link hovered" event from the plugin
 		
 	} EMediaEvent;
 	
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index e98201ea63ef8e70d50b9278c76e65e695e5be1d..33ab2e93b5cf8c7b0f4c3fc692421395880f736e 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -111,6 +111,7 @@ set(llui_SOURCE_FILES
     llviewmodel.cpp
     llview.cpp
     llviewquery.cpp
+    llwindowshade.cpp
     )
     
 set(llui_HEADER_FILES
@@ -159,6 +160,7 @@ set(llui_HEADER_FILES
     llnotificationslistener.h
     llnotificationsutil.h
     llnotificationtemplate.h
+	llnotificationvisibilityrule.h
     llpanel.h
     llprogressbar.h
     llradiogroup.h
@@ -209,6 +211,7 @@ set(llui_HEADER_FILES
     llviewmodel.h
     llview.h
     llviewquery.h
+    llwindowshade.h
     )
 
 set_source_files_properties(${llui_HEADER_FILES}
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index 9d49c1a83144330929a0bbd7b6af5e65200620d4..9e4849c58b781a6d2b161f28c80aaec61df03171 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -203,7 +203,8 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::draw()
 	S32 width = getRect().getWidth();
 	S32 height = getRect().getHeight();
 
-	gl_rect_2d(0,0,width - 1 ,height - 1,mHeaderBGColor.get(),true);
+	F32 alpha = getCurrentTransparency();
+	gl_rect_2d(0,0,width - 1 ,height - 1,mHeaderBGColor.get() % alpha,true);
 
 	LLAccordionCtrlTab* parent = dynamic_cast<LLAccordionCtrlTab*>(getParent());
 	bool collapsible = (parent && parent->getCollapsible());
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 65ef3e5f8fe4ff7d314926afa2e07449b1ed3d4a..45ceaff69693e9149130fcedc8063016dbd03927 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -98,7 +98,8 @@ LLButton::Params::Params()
 	is_toggle("is_toggle", false),
 	scale_image("scale_image", true),
 	hover_glow_amount("hover_glow_amount"),
-	commit_on_return("commit_on_return", true)
+	commit_on_return("commit_on_return", true),
+	use_draw_context_alpha("use_draw_context_alpha", true)
 {
 	addSynonym(is_toggle, "toggle");
 	held_down_delay.seconds = 0.5f;
@@ -158,7 +159,8 @@ LLButton::LLButton(const LLButton::Params& p)
 	mLastDrawCharsCount(0),
 	mMouseDownSignal(NULL),
 	mMouseUpSignal(NULL),
-	mHeldDownSignal(NULL)
+	mHeldDownSignal(NULL),
+	mUseDrawContextAlpha(p.use_draw_context_alpha)
 
 {
 	static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
@@ -539,7 +541,7 @@ BOOL LLButton::handleHover(S32 x, S32 y, MASK mask)
 // virtual
 void LLButton::draw()
 {
-	F32 alpha = getDrawContext().mAlpha;
+	F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
 	bool flash = FALSE;
 	static LLUICachedControl<F32> button_flash_rate("ButtonFlashRate", 0);
 	static LLUICachedControl<S32> button_flash_count("ButtonFlashCount", 0);
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index 2d5fefa78c89fa4ac2b193c317d70a50a2b67a57..16aa49b65342f77e4df25e615c10eb58e13f0c96 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -124,6 +124,8 @@ class LLButton
 		Optional<F32>				hover_glow_amount;
 		Optional<TimeIntervalParam>	held_down_delay;
 
+		Optional<bool>			use_draw_context_alpha;
+
 		Params();
 	};
 	
@@ -338,6 +340,8 @@ class LLButton
 	S32							mImageOverlayTopPad;
 	S32							mImageOverlayBottomPad;
 
+	bool						mUseDrawContextAlpha;
+
 	/*
 	 * Space between image_overlay and label
 	 */
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index bbd8db26454d862ab672088ef5363b585e2a8592..4fe444c1a4880848dcc5337a574c5eb35ed131c6 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -88,27 +88,19 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
 		tbparams.font(p.font);
 	}
 	mLabel = LLUICtrlFactory::create<LLTextBox> (tbparams);
+	mLabel->reshapeToFitText();
 	addChild(mLabel);
 
-	S32 text_width = mLabel->getTextBoundingRect().getWidth();
-	S32 text_height = llround(mFont->getLineHeight());
-	LLRect label_rect;
-	label_rect.setOriginAndSize(
-		llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing,
-		llcheckboxctrl_vpad + 1, // padding to get better alignment
-		text_width + llcheckboxctrl_hpad,
-		text_height );
-	mLabel->setShape(label_rect);
-
+	LLRect label_rect = mLabel->getRect();
 
 	// Button
 	// Note: button cover the label by extending all the way to the right.
-	LLRect btn_rect;
+	LLRect btn_rect = p.check_button.rect();
 	btn_rect.setOriginAndSize(
-		llcheckboxctrl_hpad,
-		llcheckboxctrl_vpad,
-		llcheckboxctrl_btn_size + llcheckboxctrl_spacing + text_width + llcheckboxctrl_hpad,
-		llmax( text_height, llcheckboxctrl_btn_size() ) + llcheckboxctrl_vpad);
+		btn_rect.mLeft,
+		btn_rect.mBottom,
+		llmax(btn_rect.mRight, label_rect.mRight - btn_rect.mLeft),
+		llmax( label_rect.getHeight(), btn_rect.mTop));
 	std::string active_true_id, active_false_id;
 	std::string inactive_true_id, inactive_false_id;
 
@@ -174,31 +166,20 @@ void LLCheckBoxCtrl::clear()
 
 void LLCheckBoxCtrl::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
-	//stretch or shrink bounding rectangle of label when rebuilding UI at new scale
-	static LLUICachedControl<S32> llcheckboxctrl_spacing ("UICheckboxctrlSpacing", 0);
-	static LLUICachedControl<S32> llcheckboxctrl_hpad ("UICheckboxctrlHPad", 0);
-	static LLUICachedControl<S32> llcheckboxctrl_vpad ("UICheckboxctrlVPad", 0);
-	static LLUICachedControl<S32> llcheckboxctrl_btn_size ("UICheckboxctrlBtnSize", 0);
 
-	S32 text_width = mLabel->getTextBoundingRect().getWidth();
-	S32 text_height = llround(mFont->getLineHeight());
-	LLRect label_rect;
-	label_rect.setOriginAndSize(
-		llcheckboxctrl_hpad + llcheckboxctrl_btn_size + llcheckboxctrl_spacing,
-		llcheckboxctrl_vpad,
-		text_width,
-		text_height );
-	mLabel->setShape(label_rect);
-
-	LLRect btn_rect;
+	mLabel->reshapeToFitText();
+
+	LLRect label_rect = mLabel->getRect();
+
+	// Button
+	// Note: button cover the label by extending all the way to the right.
+	LLRect btn_rect = mButton->getRect();
 	btn_rect.setOriginAndSize(
-		llcheckboxctrl_hpad,
-		llcheckboxctrl_vpad,
-		llcheckboxctrl_btn_size + llcheckboxctrl_spacing + text_width,
-		llmax( text_height, llcheckboxctrl_btn_size() ) );
-	mButton->setShape( btn_rect );
-	
-	LLUICtrl::reshape(width, height, called_from_parent);
+		btn_rect.mLeft,
+		btn_rect.mBottom,
+		llmax(btn_rect.getWidth(), label_rect.mRight - btn_rect.mLeft),
+		llmax(label_rect.mTop - btn_rect.mBottom, btn_rect.getHeight()));
+	mButton->setShape(btn_rect);
 }
 
 //virtual
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 2dabbc7767cb39f3f04390c30c07522548cc7dfa..6b06040b8a668d2cc99c70d112dd0b491f50e981 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -769,7 +769,8 @@ BOOL LLComboBox::handleKeyHere(KEY key, MASK mask)
 			return FALSE;
 		}
 		// if selection has changed, pop open list
-		else if (mList->getLastSelectedItem() != last_selected_item)
+		else if (mList->getLastSelectedItem() != last_selected_item ||
+				(key == KEY_DOWN || key == KEY_UP) && !mList->isEmpty())
 		{
 			showList();
 		}
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index d48674f306c1173c737dcccde1a630eb911813c9..f6f5a0beb38838e4dfe3008b63ab15101a097590 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -220,10 +220,15 @@ void LLDockControl::moveDockable()
 	case TOP:
 		x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
 		y = dockRect.mTop + dockableRect.getHeight();
-		// unique docking used with dock tongue, so add tongue height o the Y coordinate
+		// unique docking used with dock tongue, so add tongue height to the Y coordinate
 		if (use_tongue)
 		{
 			y += mDockTongue->getHeight();
+
+			if ( y > rootRect.mTop)
+			{
+				y = rootRect.mTop;
+			}
 		}
 
 		// check is dockable inside root view rect
@@ -257,7 +262,7 @@ void LLDockControl::moveDockable()
 	case BOTTOM:
 		x = dockRect.getCenterX() - dockableRect.getWidth() / 2;
 		y = dockRect.mBottom;
-		// unique docking used with dock tongue, so add tongue height o the Y coordinate
+		// unique docking used with dock tongue, so add tongue height to the Y coordinate
 		if (use_tongue)
 		{
 			y -= mDockTongue->getHeight();
@@ -292,9 +297,21 @@ void LLDockControl::moveDockable()
 		break;
 	}
 
-	// move dockable
-	dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
-			dockableRect.getHeight());
+	S32 max_available_height = rootRect.getHeight() - mDockTongueY - mDockTongue->getHeight();
+
+	// A floater should be shrunk so it doesn't cover a part of its docking tongue and
+	// there is a space between a dockable floater and a control to which it is docked.
+	if (use_tongue && dockableRect.getHeight() >= max_available_height)
+	{
+		dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(), max_available_height);
+		mDockableFloater->reshape(dockableRect.getWidth(), dockableRect.getHeight());
+	}
+	else
+	{
+		// move dockable
+		dockableRect.setLeftTopAndSize(x, y, dockableRect.getWidth(),
+				dockableRect.getHeight());
+	}
 	LLRect localDocableParentRect;
 	mDockableFloater->getParent()->screenRectToLocal(dockableRect,
 			&localDocableParentRect);
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 34d8e9c500bacdabe596e7cfdbc4e24d1800dfc1..1265733bf5be3213a10d11280e6e5bf00e3db7ca 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1,4 +1,5 @@
 /** 
+
  * @file llfloater.cpp
  * @brief LLFloater base class
  *
@@ -61,10 +62,6 @@
 // use this to control "jumping" behavior when Ctrl-Tabbing
 const S32 TABBED_FLOATER_OFFSET = 0;
 
-// static
-F32 LLFloater::sActiveFloaterTransparency = 0.0f;
-F32 LLFloater::sInactiveFloaterTransparency = 0.0f;
-
 std::string	LLFloater::sButtonNames[BUTTON_COUNT] = 
 {
 	"llfloater_close_btn",		//BUTTON_CLOSE
@@ -208,14 +205,14 @@ void LLFloater::initClass()
 	if (ctrl)
 	{
 		ctrl->getSignal()->connect(boost::bind(&LLFloater::updateActiveFloaterTransparency));
-		sActiveFloaterTransparency = LLUI::sSettingGroups["config"]->getF32("ActiveFloaterTransparency");
+		updateActiveFloaterTransparency();
 	}
 
 	ctrl = LLUI::sSettingGroups["config"]->getControl("InactiveFloaterTransparency").get();
 	if (ctrl)
 	{
 		ctrl->getSignal()->connect(boost::bind(&LLFloater::updateInactiveFloaterTransparency));
-		sInactiveFloaterTransparency = LLUI::sSettingGroups["config"]->getF32("InactiveFloaterTransparency");
+		updateInactiveFloaterTransparency();
 	}
 
 }
@@ -225,7 +222,7 @@ static LLWidgetNameRegistry::StaticRegistrar sRegisterFloaterParams(&typeid(LLFl
 
 LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
 :	LLPanel(),	// intentionally do not pass params here, see initFromParams
-	mDragHandle(NULL),
+ 	mDragHandle(NULL),
 	mTitle(p.title),
 	mShortTitle(p.short_title),
 	mSingleInstance(p.single_instance),
@@ -368,13 +365,13 @@ void LLFloater::layoutDragHandle()
 // static
 void LLFloater::updateActiveFloaterTransparency()
 {
-	sActiveFloaterTransparency = LLUI::sSettingGroups["config"]->getF32("ActiveFloaterTransparency");
+	sActiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("ActiveFloaterTransparency");
 }
 
 // static
 void LLFloater::updateInactiveFloaterTransparency()
 {
-	sInactiveFloaterTransparency = LLUI::sSettingGroups["config"]->getF32("InactiveFloaterTransparency");
+	sInactiveControlTransparency = LLUI::sSettingGroups["config"]->getF32("InactiveFloaterTransparency");
 }
 
 void LLFloater::addResizeCtrls()
@@ -1193,6 +1190,7 @@ void LLFloater::setFocus( BOOL b )
 			last_focus->setFocus(TRUE);
 		}
 	}
+	updateTransparency(b ? TT_ACTIVE : TT_INACTIVE);
 }
 
 // virtual
@@ -1465,6 +1463,9 @@ void LLFloater::setFrontmost(BOOL take_focus)
 		// there are more than one floater view
 		// so we need to query our parent directly
 		((LLFloaterView*)getParent())->bringToFront(this, take_focus);
+
+		// Make sure to set the appropriate transparency type (STORM-732).
+		updateTransparency(hasFocus() || getIsChrome() ? TT_ACTIVE : TT_INACTIVE);
 	}
 }
 
@@ -1652,7 +1653,7 @@ void	LLFloater::onClickCloseBtn()
 // virtual
 void LLFloater::draw()
 {
-	mCurrentTransparency = hasFocus() ? sActiveFloaterTransparency : sInactiveFloaterTransparency;
+	const F32 alpha = getCurrentTransparency();
 
 	// draw background
 	if( isBackgroundVisible() )
@@ -1684,12 +1685,12 @@ void LLFloater::draw()
 		if (image)
 		{
 			// We're using images for this floater's backgrounds
-			image->draw(getLocalRect(), overlay_color % mCurrentTransparency);
+			image->draw(getLocalRect(), overlay_color % alpha);
 		}
 		else
 		{
 			// We're not using images, use old-school flat colors
-			gl_rect_2d( left, top, right, bottom, color % mCurrentTransparency );
+			gl_rect_2d( left, top, right, bottom, color % alpha );
 
 			// draw highlight on title bar to indicate focus.  RDW
 			if(hasFocus() 
@@ -1701,7 +1702,7 @@ void LLFloater::draw()
 				const LLFontGL* font = LLFontGL::getFontSansSerif();
 				LLRect r = getRect();
 				gl_rect_2d_offset_local(0, r.getHeight(), r.getWidth(), r.getHeight() - (S32)font->getLineHeight() - 1, 
-					titlebar_focus_color % mCurrentTransparency, 0, TRUE);
+					titlebar_focus_color % alpha, 0, TRUE);
 			}
 		}
 	}
@@ -1767,10 +1768,32 @@ void	LLFloater::drawShadow(LLPanel* panel)
 		shadow_color.mV[VALPHA] *= 0.5f;
 	}
 	gl_drop_shadow(left, top, right, bottom, 
-		shadow_color % mCurrentTransparency,
+		shadow_color % getCurrentTransparency(),
 		llround(shadow_offset));
 }
 
+void LLFloater::updateTransparency(LLView* view, ETypeTransparency transparency_type)
+{
+	child_list_t children = *view->getChildList();
+	child_list_t::iterator it = children.begin();
+
+	LLUICtrl* ctrl = dynamic_cast<LLUICtrl*>(view);
+	if (ctrl)
+	{
+		ctrl->setTransparencyType(transparency_type);
+	}
+
+	for(; it != children.end(); ++it)
+	{
+		updateTransparency(*it, transparency_type);
+	}
+}
+
+void LLFloater::updateTransparency(ETypeTransparency transparency_type)
+{
+	updateTransparency(this, transparency_type);
+}
+
 void	LLFloater::setCanMinimize(BOOL can_minimize)
 {
 	// if removing minimize/restore button programmatically,
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index fa806bb632169dca8daa3a4a47df9610e43fe093..bb96272d0269215560d858695ad695607d136c20 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -284,6 +284,8 @@ friend class LLMultiFloater;
 
 	static void		setFloaterHost(LLMultiFloater* hostp) {sHostp = hostp; }
 	static LLMultiFloater* getFloaterHost() {return sHostp; }
+
+	void			updateTransparency(ETypeTransparency transparency_type);
 		
 protected:
 
@@ -343,6 +345,7 @@ friend class LLMultiFloater;
 
 	static void		updateActiveFloaterTransparency();
 	static void		updateInactiveFloaterTransparency();
+	void			updateTransparency(LLView* view, ETypeTransparency transparency_type);
 
 public:
 	// Called when floater is opened, passes mKey
@@ -411,11 +414,6 @@ friend class LLMultiFloater;
 	bool            mDocked;
 	bool            mTornOff;
 
-	F32				mCurrentTransparency;
-
-	static F32		sActiveFloaterTransparency;
-	static F32		sInactiveFloaterTransparency;
-
 	static LLMultiFloater* sHostp;
 	static BOOL		sQuitting;
 	static std::string	sButtonNames[BUTTON_COUNT];
diff --git a/indra/llui/llhandle.h b/indra/llui/llhandle.h
index a43f095d675e364ca5782108dff6c9998737bde1..8c000eee48cc6fe4f682cd33e88dd09e52da94f5 100644
--- a/indra/llui/llhandle.h
+++ b/indra/llui/llhandle.h
@@ -61,13 +61,6 @@ class LLHandle
 		return *this; 
 	}
 
-	template<typename Subclass>
-	LLHandle<T>& operator =(const LLHandle<Subclass>& other)  
-	{ 
-		mTombStone = other.mTombStone;
-		return *this; 
-	}
-
 	bool isDead() const 
 	{ 
 		return mTombStone->getTarget() == NULL; 
@@ -99,7 +92,6 @@ class LLHandle
 	{
 		return lhs.mTombStone > rhs.mTombStone;
 	}
-protected:
 
 protected:
 	LLPointer<LLTombStone<T> > mTombStone;
diff --git a/indra/llui/lliconctrl.cpp b/indra/llui/lliconctrl.cpp
index 627957061d24b4ac017995e87eb9d08e95c50f1f..47f2cfaf89b0c885c2db74df1381d9488bfaf2b5 100644
--- a/indra/llui/lliconctrl.cpp
+++ b/indra/llui/lliconctrl.cpp
@@ -41,6 +41,7 @@ static LLDefaultChildRegistry::Register<LLIconCtrl> r("icon");
 LLIconCtrl::Params::Params()
 :	image("image_name"),
 	color("color"),
+	use_draw_context_alpha("use_draw_context_alpha", true),
 	scale_image("scale_image")
 {
 	tab_stop = false;
@@ -51,6 +52,7 @@ LLIconCtrl::LLIconCtrl(const LLIconCtrl::Params& p)
 :	LLUICtrl(p),
 	mColor(p.color()),
 	mImagep(p.image),
+	mUseDrawContextAlpha(p.use_draw_context_alpha),
 	mPriority(0),
 	mDrawWidth(0),
 	mDrawHeight(0)
@@ -71,7 +73,8 @@ void LLIconCtrl::draw()
 {
 	if( mImagep.notNull() )
 	{
-		mImagep->draw(getLocalRect(), mColor.get() % getDrawContext().mAlpha );
+		const F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
+		mImagep->draw(getLocalRect(), mColor.get() % alpha );
 	}
 
 	LLUICtrl::draw();
diff --git a/indra/llui/lliconctrl.h b/indra/llui/lliconctrl.h
index 79a8b0fb28fa85f0827827b199cb6defbed1c4b8..e9bdab2d47711d6ff19bf6139f4493b85a1b2a08 100644
--- a/indra/llui/lliconctrl.h
+++ b/indra/llui/lliconctrl.h
@@ -48,6 +48,7 @@ class LLIconCtrl
 	{
 		Optional<LLUIImage*>	image;
 		Optional<LLUIColor>		color;
+		Optional<bool>			use_draw_context_alpha;
 		Ignored					scale_image;
 		Params();
 	};
@@ -79,6 +80,10 @@ class LLIconCtrl
 	S32 mDrawWidth ;
 	S32 mDrawHeight ;
 
+	// If set to true (default), use the draw context transparency.
+	// If false, will use transparency returned by getCurrentTransparency(). See STORM-698.
+	bool mUseDrawContextAlpha;
+
 private:
 	LLUIColor mColor;
 	LLPointer<LLUIImage> mImagep;
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 940c7e7e1863837320166e3bbf9fc7b31cc3015a..19ac4c58a851be16bd8f8e734b048a0ebaf26508 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -38,6 +38,12 @@
 static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack");
 static LLLayoutStack::LayoutStackRegistry::Register<LLLayoutPanel> register_layout_panel("layout_panel");
 
+void LLLayoutStack::OrientationNames::declareValues()
+{
+	declare("horizontal", HORIZONTAL);
+	declare("vertical", VERTICAL);
+}
+
 //
 // LLLayoutPanel
 //
@@ -47,47 +53,47 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)
  	mMaxDim(p.max_dim), 
  	mAutoResize(p.auto_resize),
  	mUserResize(p.user_resize),
-		mCollapsed(FALSE),
-		mCollapseAmt(0.f),
-		mVisibleAmt(1.f), // default to fully visible
-		mResizeBar(NULL) 
-	{
+	mCollapsed(FALSE),
+	mCollapseAmt(0.f),
+	mVisibleAmt(1.f), // default to fully visible
+	mResizeBar(NULL) 
+{
 	// panels initialized as hidden should not start out partially visible
 	if (!getVisible())
-		{
+	{
 		mVisibleAmt = 0.f;
-		}
-		}
+	}
+}
 
 void LLLayoutPanel::initFromParams(const Params& p)
-		{
+{
 	LLPanel::initFromParams(p);
 	setFollowsNone();
-	}
+}
 
 
 LLLayoutPanel::~LLLayoutPanel()
-	{
-		// probably not necessary, but...
-		delete mResizeBar;
-		mResizeBar = NULL;
-	}
+{
+	// probably not necessary, but...
+	delete mResizeBar;
+	mResizeBar = NULL;
+}
 	
 F32 LLLayoutPanel::getCollapseFactor(LLLayoutStack::ELayoutOrientation orientation)
-	{
+{
 	if (orientation == LLLayoutStack::HORIZONTAL)
-		{
-			F32 collapse_amt = 
-			clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinDim / (F32)llmax(1, getRect().getWidth()));
-			return mVisibleAmt * collapse_amt;
-		}
-		else
+	{
+		F32 collapse_amt = 
+		clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, (F32)mMinDim / (F32)llmax(1, getRect().getWidth()));
+		return mVisibleAmt * collapse_amt;
+	}
+	else
 	{
 			F32 collapse_amt = 
 			clamp_rescale(mCollapseAmt, 0.f, 1.f, 1.f, llmin(1.f, (F32)mMinDim / (F32)llmax(1, getRect().getHeight())));
 			return mVisibleAmt * collapse_amt;
-		}
 	}
+}
 
 //
 // LLLayoutStack
@@ -97,6 +103,8 @@ LLLayoutStack::Params::Params()
 :	orientation("orientation"),
 	animate("animate", true),
 	clip("clip", true),
+	open_time_constant("open_time_constant", 0.02f),
+	close_time_constant("close_time_constant", 0.03f),
 	border_size("border_size", LLCachedControl<S32>(*LLUI::sSettingGroups["config"], "UIResizeBarHeight", 0))
 {
 	name="stack";
@@ -107,10 +115,12 @@ LLLayoutStack::LLLayoutStack(const LLLayoutStack::Params& p)
 	mMinWidth(0),
 	mMinHeight(0),
 	mPanelSpacing(p.border_size),
-	mOrientation((p.orientation() == "vertical") ? VERTICAL : HORIZONTAL),
+	mOrientation(p.orientation),
 	mAnimate(p.animate),
 	mAnimatedThisFrame(false),
-	mClip(p.clip)
+	mClip(p.clip),
+	mOpenTimeConstant(p.open_time_constant),
+	mCloseTimeConstant(p.close_time_constant)
 {}
 
 LLLayoutStack::~LLLayoutStack()
@@ -303,9 +313,6 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
 	S32 total_width = 0;
 	S32 total_height = 0;
 
-	const F32 ANIM_OPEN_TIME = 0.02f;
-	const F32 ANIM_CLOSE_TIME = 0.03f;
-
 	e_panel_list_t::iterator panel_it;
 	for (panel_it = mPanels.begin(); panel_it != mPanels.end();	++panel_it)
 	{
@@ -316,7 +323,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
 			{
 				if (!mAnimatedThisFrame)
 				{
-					(*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_OPEN_TIME));
+					(*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 1.f, LLCriticalDamp::getInterpolant(mOpenTimeConstant));
 					if ((*panel_it)->mVisibleAmt > 0.99f)
 					{
 						(*panel_it)->mVisibleAmt = 1.f;
@@ -334,7 +341,7 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
 			{
 				if (!mAnimatedThisFrame)
 				{
-					(*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
+					(*panel_it)->mVisibleAmt = lerp((*panel_it)->mVisibleAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
 					if ((*panel_it)->mVisibleAmt < 0.001f)
 					{
 						(*panel_it)->mVisibleAmt = 0.f;
@@ -349,11 +356,11 @@ void LLLayoutStack::updateLayout(BOOL force_resize)
 
 		if ((*panel_it)->mCollapsed)
 		{
-			(*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
+			(*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 1.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
 		}
 		else
 		{
-			(*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(ANIM_CLOSE_TIME));
+			(*panel_it)->mCollapseAmt = lerp((*panel_it)->mCollapseAmt, 0.f, LLCriticalDamp::getInterpolant(mCloseTimeConstant));
 		}
 
 		if (mOrientation == HORIZONTAL)
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index e19ef403eff7594a9a37bf1835624021d4993bf0..4ac8ef0ee9a66ccd299d56fbf85bcabd293bd9e9 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -37,27 +37,35 @@ class LLLayoutPanel;
 class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>
 {
 public:
+	typedef enum e_layout_orientation
+	{
+		HORIZONTAL,
+		VERTICAL
+	} ELayoutOrientation;
+
+	struct OrientationNames
+	:	public LLInitParam::TypeValuesHelper<ELayoutOrientation, OrientationNames>
+	{
+		static void declareValues();
+	};
+
 	struct LayoutStackRegistry : public LLChildRegistry<LayoutStackRegistry>
 	{};
 
 	struct Params : public LLInitParam::Block<Params, LLView::Params>
 	{
-		Mandatory<std::string>	orientation;
+		Mandatory<ELayoutOrientation, OrientationNames>	orientation;
 		Optional<S32>			border_size;
 		Optional<bool>			animate,
 								clip;
+		Optional<F32>			open_time_constant,
+								close_time_constant;
 
 		Params();
 	};
 
 	typedef LayoutStackRegistry child_registry_t;
 
-	typedef enum e_layout_orientation
-	{
-		HORIZONTAL,
-		VERTICAL
-	} ELayoutOrientation;
-
 	virtual ~LLLayoutStack();
 
 	/*virtual*/ void draw();
@@ -137,6 +145,8 @@ class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>
 	bool mAnimatedThisFrame;
 	bool mAnimate;
 	bool mClip;
+	F32 mOpenTimeConstant;
+	F32 mCloseTimeConstant;
 }; // end class LLLayoutStack
 
 class LLLayoutPanel : public LLPanel
@@ -167,6 +177,9 @@ friend class LLUICtrlFactory;
 	~LLLayoutPanel();
 
 	void initFromParams(const Params& p);
+	void setMinDim(S32 value) { mMinDim = value; }
+	void setMaxDim(S32 value) { mMaxDim = value; }
+
 protected:
 	LLLayoutPanel(const Params& p)	;
 
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 5f5fe851bb8c819349299954986c02c0ecbc9883..7e348656a92a63fa5d2755af8e9bfdc280f9798f 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -88,6 +88,7 @@ LLLineEditor::Params::Params()
 	revert_on_esc("revert_on_esc", true),
 	commit_on_focus_lost("commit_on_focus_lost", true),
 	ignore_tab("ignore_tab", true),
+	is_password("is_password", false),
 	cursor_color("cursor_color"),
 	text_color("text_color"),
 	text_readonly_color("text_readonly_color"),
@@ -129,7 +130,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 	mBorderThickness( 0 ),
 	mIgnoreArrowKeys( FALSE ),
 	mIgnoreTab( p.ignore_tab ),
-	mDrawAsterixes( FALSE ),
+	mDrawAsterixes( p.is_password ),
 	mSelectAllonFocusReceived( p.select_on_focus ),
 	mPassDelete(FALSE),
 	mReadOnly(FALSE),
@@ -1304,7 +1305,7 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
 
 	// handle ctrl-uparrow if we have a history enabled line editor.
 	case KEY_UP:
-		if( mHaveHistory && ( MASK_CONTROL == mask ) )
+		if( mHaveHistory && ((mIgnoreArrowKeys == false) || ( MASK_CONTROL == mask )) )
 		{
 			if( mCurrentHistoryLine > mLineHistory.begin() )
 			{
@@ -1319,9 +1320,9 @@ BOOL LLLineEditor::handleSpecialKey(KEY key, MASK mask)
 		}
 		break;
 
-	// handle ctrl-downarrow if we have a history enabled line editor
+	// handle [ctrl]-downarrow if we have a history enabled line editor
 	case KEY_DOWN:
-		if( mHaveHistory  && ( MASK_CONTROL == mask ) )
+		if( mHaveHistory  && ((mIgnoreArrowKeys == false) || ( MASK_CONTROL == mask )) )
 		{
 			if( !mLineHistory.empty() && mCurrentHistoryLine < mLineHistory.end() - 1 )
 			{
@@ -1529,8 +1530,11 @@ void LLLineEditor::drawBackground()
 	{
 		image = mBgImage;
 	}
+
+	if (!image) return;
 	
-	F32 alpha = getDrawContext().mAlpha;
+	F32 alpha = getCurrentTransparency();
+
 	// optionally draw programmatic border
 	if (has_focus)
 	{
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index a1aa6b71c6022ec775e0e77262ceba713e6c5bfa..723423a5b9c2e8ffd46850672109db076356bc11 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -85,7 +85,8 @@ class LLLineEditor
 		Optional<bool>					select_on_focus,
 										revert_on_esc,
 										commit_on_focus_lost,
-										ignore_tab;
+										ignore_tab,
+										is_password;
 
 		// colors
 		Optional<LLUIColor>				cursor_color,
@@ -336,7 +337,7 @@ class LLLineEditor
 	std::vector<S32> mPreeditPositions;
 	LLPreeditor::standouts_t mPreeditStandouts;
 
-	LLHandle<LLView> mContextMenuHandle;
+	LLHandle<LLContextMenu> mContextMenuHandle;
 
 private:
 	// Instances that by default point to the statics but can be overidden in XML.
diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index ac568a83e4a32e4d0e6525ad427460ed8e95d0c6..eed008527328d508a77bc4ddf1e6c101489b6687 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -175,6 +175,13 @@ void LLMenuButton::updateMenuOrigin()
 			mY = rect.mTop + mMenuHandle.get()->getRect().getHeight();
 			break;
 		}
+		case MP_TOP_RIGHT:
+		{
+			const LLRect& menu_rect = mMenuHandle.get()->getRect();
+			mX = rect.mRight - menu_rect.getWidth();
+			mY = rect.mTop + menu_rect.getHeight();
+			break;
+		}
 		case MP_BOTTOM_LEFT:
 		{
 			mX = rect.mLeft;
diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h
index 9e91b9e99d3af9702e026e8bbfc086a88662b424..7b657595da7c6881544872b8e4133fe835427f74 100644
--- a/indra/llui/llmenubutton.h
+++ b/indra/llui/llmenubutton.h
@@ -47,6 +47,7 @@ class LLMenuButton
 	typedef enum e_menu_position
 	{
 		MP_TOP_LEFT,
+		MP_TOP_RIGHT,
 		MP_BOTTOM_LEFT
 	} EMenuPosition;
 	
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index a6cf86d9b8de56e2e366f7a62106fd3f58975e8a..6c0d47ef63d08ffc776cb5bf2cb3de240c93585d 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -1462,7 +1462,7 @@ BOOL LLMenuItemBranchDownGL::handleAcceleratorKey(KEY key, MASK mask)
 {
 	BOOL branch_visible = getBranch()->getVisible();
 	BOOL handled = getBranch()->handleAcceleratorKey(key, mask);
-	if (handled && !branch_visible && getVisible())
+	if (handled && !branch_visible && isInVisibleChain())
 	{
 		// flash this menu entry because we triggered an invisible menu item
 		LLMenuHolderGL::setActivatedItem(this);
@@ -2611,6 +2611,7 @@ LLMenuItemGL* LLMenuGL::getHighlightedItem()
 
 LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disabled)
 {
+	if (mItems.empty()) return NULL;
 	// highlighting first item on a torn off menu is the
 	// same as giving focus to it
 	if (!cur_item && getTornOff())
@@ -2711,6 +2712,8 @@ LLMenuItemGL* LLMenuGL::highlightNextItem(LLMenuItemGL* cur_item, BOOL skip_disa
 
 LLMenuItemGL* LLMenuGL::highlightPrevItem(LLMenuItemGL* cur_item, BOOL skip_disabled)
 {
+	if (mItems.empty()) return NULL;
+
 	// highlighting first item on a torn off menu is the
 	// same as giving focus to it
 	if (!cur_item && getTornOff())
@@ -3045,6 +3048,11 @@ void LLMenuGL::showPopup(LLView* spawning_view, LLMenuGL* menu, S32 x, S32 y)
 	const S32 CURSOR_HEIGHT = 22;		// Approximate "normal" cursor size
 	const S32 CURSOR_WIDTH = 12;
 
+	if(menu->getChildList()->empty())
+	{
+		return;
+	}
+
 	// Save click point for detecting cursor moves before mouse-up.
 	// Must be in local coords to compare with mouseUp events.
 	// If the mouse doesn't move, the menu will stay open ala the Mac.
@@ -3125,7 +3133,10 @@ BOOL LLMenuBarGL::handleAcceleratorKey(KEY key, MASK mask)
 		mAltKeyTrigger = FALSE;
 	}
 
-	if(!result && (key == KEY_F10 && mask == MASK_CONTROL) && !gKeyboard->getKeyRepeated(key))
+	if(!result 
+		&& (key == KEY_F10 && mask == MASK_CONTROL) 
+		&& !gKeyboard->getKeyRepeated(key)
+		&& isInVisibleChain())
 	{
 		if (getHighlightedItem())
 		{
@@ -3508,8 +3519,10 @@ BOOL LLMenuHolderGL::handleKey(KEY key, MASK mask, BOOL called_from_parent)
 			else
 			{
 				//highlight first enabled one
-				pMenu->highlightNextItem(NULL);
-				handled = true;
+				if(pMenu->highlightNextItem(NULL))
+				{
+					handled = true;
+				}
 			}
 		}
 	}
@@ -3742,9 +3755,7 @@ class LLContextMenuBranch : public LLMenuItemGL
 	LLContextMenuBranch(const Params&);
 
 	virtual ~LLContextMenuBranch()
-	{
-		delete mBranch;
-	}
+	{}
 
 	// called to rebuild the draw label
 	virtual void	buildDrawLabel( void );
@@ -3752,21 +3763,21 @@ class LLContextMenuBranch : public LLMenuItemGL
 	// onCommit() - do the primary funcationality of the menu item.
 	virtual void	onCommit( void );
 
-	LLContextMenu*	getBranch() { return mBranch; }
+	LLContextMenu*	getBranch() { return mBranch.get(); }
 	void			setHighlight( BOOL highlight );
 
 protected:
 	void	showSubMenu();
 
-	LLContextMenu* mBranch;
+	LLHandle<LLContextMenu> mBranch;
 };
 
 LLContextMenuBranch::LLContextMenuBranch(const LLContextMenuBranch::Params& p) 
 :	LLMenuItemGL(p),
-	mBranch( p.branch )
+	mBranch( p.branch()->getHandle() )
 {
-	mBranch->hide();
-	mBranch->setParentMenuItem(this);
+	mBranch.get()->hide();
+	mBranch.get()->setParentMenuItem(this);
 }
 
 // called to rebuild the draw label
@@ -3775,12 +3786,12 @@ void LLContextMenuBranch::buildDrawLabel( void )
 	{
 		// default enablement is this -- if any of the subitems are
 		// enabled, this item is enabled. JC
-		U32 sub_count = mBranch->getItemCount();
+		U32 sub_count = mBranch.get()->getItemCount();
 		U32 i;
 		BOOL any_enabled = FALSE;
 		for (i = 0; i < sub_count; i++)
 		{
-			LLMenuItemGL* item = mBranch->getItem(i);
+			LLMenuItemGL* item = mBranch.get()->getItem(i);
 			item->buildDrawLabel();
 			if (item->getEnabled() && !item->getDrawTextDisabled() )
 			{
@@ -3802,13 +3813,13 @@ void LLContextMenuBranch::buildDrawLabel( void )
 
 void	LLContextMenuBranch::showSubMenu()
 {
-	LLMenuItemGL* menu_item = mBranch->getParentMenuItem();
+	LLMenuItemGL* menu_item = mBranch.get()->getParentMenuItem();
 	if (menu_item != NULL && menu_item->getVisible())
 	{
 		S32 center_x;
 		S32 center_y;
 		localPointToScreen(getRect().getWidth(), getRect().getHeight() , &center_x, &center_y);
-		mBranch->show(center_x, center_y);
+		mBranch.get()->show(center_x, center_y);
 	}
 }
 
@@ -3828,7 +3839,7 @@ void LLContextMenuBranch::setHighlight( BOOL highlight )
 	}
 	else
 	{
-		mBranch->hide();
+		mBranch.get()->hide();
 	}
 }
 
@@ -3859,6 +3870,11 @@ void LLContextMenu::setVisible(BOOL visible)
 // Takes cursor position in screen space?
 void LLContextMenu::show(S32 x, S32 y)
 {
+	if (getChildList()->empty())
+	{
+		// nothing to show, so abort
+		return;
+	}
 	// Save click point for detecting cursor moves before mouse-up.
 	// Must be in local coords to compare with mouseUp events.
 	// If the mouse doesn't move, the menu will stay open ala the Mac.
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 35544402f41b101a0d360ecd3838db770a461317..7bde8e83ec7f7f5af017da49cda4e02d6bafed33 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -678,9 +678,12 @@ class LLContextMenu
 
 			BOOL	appendContextSubMenu(LLContextMenu *menu);
 
+			LLHandle<LLContextMenu> getHandle() { mHandle.bind(this); return mHandle; }
+
 protected:
-	BOOL			mHoveredAnyItem;
-	LLMenuItemGL*	mHoverItem;
+	BOOL						mHoveredAnyItem;
+	LLMenuItemGL*				mHoverItem;
+	LLRootHandle<LLContextMenu>	mHandle;
 };
 
 
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index a3df6a3ced803cea339aa7df02542c3f5b4a0265..cd0f0e36b0509d5d40bc311b4d5f8c2be8589ac7 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -28,6 +28,7 @@
 
 #include "llnotifications.h"
 #include "llnotificationtemplate.h"
+#include "llnotificationvisibilityrule.h"
 
 #include "llavatarnamecache.h"
 #include "llinstantmessage.h"
@@ -81,6 +82,7 @@ LLNotificationForm::FormButton::FormButton()
 
 LLNotificationForm::FormInput::FormInput()
 :	type("type"),
+	text("text"),
 	max_length_chars("max_length_chars"),
 	width("width", 0),
 	value("value")
@@ -137,12 +139,6 @@ class LLPersistentNotificationChannel : public LLNotificationChannel
 
 bool filterIgnoredNotifications(LLNotificationPtr notification)
 {
-	// filter everything if we are to ignore ALL
-	if(LLNotifications::instance().getIgnoreAllNotifications())
-	{
-		return false;
-	}
-
 	LLNotificationFormPtr form = notification->getForm();
 	// Check to see if the user wants to ignore this alert
 	return !notification->getForm()->getIgnored();
@@ -177,6 +173,28 @@ bool handleIgnoredNotification(const LLSD& payload)
 	return false;
 }
 
+bool defaultResponse(const LLSD& payload)
+{
+	if (payload["sigtype"].asString() == "add")
+	{
+		LLNotificationPtr pNotif = LLNotifications::instance().find(payload["id"].asUUID());
+		if (pNotif) 
+		{
+			// supply default response
+			pNotif->respond(pNotif->getResponseTemplate(LLNotification::WITH_DEFAULT_BUTTON));
+		}
+	}
+	return false;
+}
+
+bool visibilityRuleMached(const LLSD& payload)
+{
+	// This is needed because LLNotifications::isVisibleByRules may have cancelled the notification.
+	// Returning true here makes LLNotificationChannelBase::updateItem do an early out, which prevents things from happening in the wrong order.
+	return true;
+}
+
+
 namespace LLNotificationFilters
 {
 	// a sample filter
@@ -404,12 +422,49 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
 		it != end_it;
 		++it)
 	{
-		mUniqueContext.push_back(it->key);
+		mUniqueContext.push_back(it->value);
+	}
+	
+	lldebugs << "notification \"" << mName << "\": tag count is " << p.tags.size() << llendl;
+	
+	for(LLInitParam::ParamIterator<LLNotificationTemplate::Tag>::const_iterator it = p.tags.begin(),
+			end_it = p.tags.end();
+		it != end_it;
+		++it)
+	{
+		lldebugs << "    tag \"" << std::string(it->value) << "\"" << llendl;
+		mTags.push_back(it->value);
 	}
 
 	mForm = LLNotificationFormPtr(new LLNotificationForm(p.name, p.form_ref.form));
 }
 
+LLNotificationVisibilityRule::LLNotificationVisibilityRule(const LLNotificationVisibilityRule::Rule &p)
+{
+	if (p.show.isChosen())
+	{
+		mType = p.show.type;
+		mTag = p.show.tag;
+		mName = p.show.name;
+		mVisible = true;
+	}
+	else if (p.hide.isChosen())
+	{
+		mType = p.hide.type;
+		mTag = p.hide.tag;
+		mName = p.hide.name;
+		mVisible = false;
+	}
+	else if (p.respond.isChosen())
+	{
+		mType = p.respond.type;
+		mTag = p.respond.tag;
+		mName = p.respond.name;
+		mVisible = false;
+		mResponse = p.respond.response;
+	}
+}
+
 LLNotification::LLNotification(const LLNotification::Params& p) : 
 	mTimestamp(p.time_stamp), 
 	mSubstitutions(p.substitutions),
@@ -679,6 +734,25 @@ bool LLNotification::hasUniquenessConstraints() const
 	return (mTemplatep ? mTemplatep->mUnique : false);
 }
 
+bool LLNotification::matchesTag(const std::string& tag)
+{
+	bool result = false;
+	
+	if(mTemplatep)
+	{
+		std::list<std::string>::iterator it;
+		for(it = mTemplatep->mTags.begin(); it != mTemplatep->mTags.end(); it++)
+		{
+			if((*it) == tag)
+			{
+				result = true;
+				break;
+			}
+		}
+	}
+	
+	return result;
+}
 
 void LLNotification::setIgnored(bool ignore)
 {
@@ -719,13 +793,19 @@ bool LLNotification::isEquivalentTo(LLNotificationPtr that) const
 	{
 		const LLSD& these_substitutions = this->getSubstitutions();
 		const LLSD& those_substitutions = that->getSubstitutions();
+		const LLSD& this_payload = this->getPayload();
+		const LLSD& that_payload = that->getPayload();
 
 		// highlander bit sez there can only be one of these
 		for (std::vector<std::string>::const_iterator it = mTemplatep->mUniqueContext.begin(), end_it = mTemplatep->mUniqueContext.end();
 			it != end_it;
 			++it)
 		{
-			if (these_substitutions.get(*it).asString() != those_substitutions.get(*it).asString())
+			// if templates differ in either substitution strings or payload with the given field name
+			// then they are considered inequivalent
+			// use of get() avoids converting the LLSD value to a map as the [] operator would
+			if (these_substitutions.get(*it).asString() != those_substitutions.get(*it).asString()
+				|| this_payload.get(*it).asString() != that_payload.get(*it).asString())
 			{
 				return false;
 			}
@@ -1064,12 +1144,12 @@ std::string LLNotificationChannel::summarize()
 // LLNotifications implementation
 // ---
 LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything,
-							       LLNotificationComparators::orderByUUID()),
-				     mIgnoreAllNotifications(false)
+															   LLNotificationComparators::orderByUUID()),
+									mIgnoreAllNotifications(false)
 {
 	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
-	
-	mListener.reset(new LLNotificationsListener(*this));
+
+    mListener.reset(new LLNotificationsListener(*this));
 }
 
 
@@ -1184,6 +1264,7 @@ LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelN
 void LLNotifications::initSingleton()
 {
 	loadTemplates();
+	loadVisibilityRules();
 	createDefaultChannels();
 }
 
@@ -1191,15 +1272,19 @@ void LLNotifications::createDefaultChannels()
 {
 	// now construct the various channels AFTER loading the notifications,
 	// because the history channel is going to rewrite the stored notifications file
-	LLNotificationChannel::buildChannel("Expiration", "",
+	LLNotificationChannel::buildChannel("Enabled", "",
+		!boost::bind(&LLNotifications::getIgnoreAllNotifications, this));
+	LLNotificationChannel::buildChannel("Expiration", "Enabled",
 		boost::bind(&LLNotifications::expirationFilter, this, _1));
-	LLNotificationChannel::buildChannel("Unexpired", "",
+	LLNotificationChannel::buildChannel("Unexpired", "Enabled",
 		!boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind
 	LLNotificationChannel::buildChannel("Unique", "Unexpired",
 		boost::bind(&LLNotifications::uniqueFilter, this, _1));
 	LLNotificationChannel::buildChannel("Ignore", "Unique",
 		filterIgnoredNotifications);
-	LLNotificationChannel::buildChannel("Visible", "Ignore",
+	LLNotificationChannel::buildChannel("VisibilityRules", "Ignore",
+		boost::bind(&LLNotifications::isVisibleByRules, this, _1));
+	LLNotificationChannel::buildChannel("Visible", "VisibilityRules",
 		&LLNotificationFilters::includeEverything);
 
 	// create special persistent notification channel
@@ -1207,6 +1292,8 @@ void LLNotifications::createDefaultChannels()
 	new LLPersistentNotificationChannel();
 
 	// connect action methods to these channels
+	LLNotifications::instance().getChannel("Enabled")->
+		connectFailedFilter(&defaultResponse);
 	LLNotifications::instance().getChannel("Expiration")->
         connectChanged(boost::bind(&LLNotifications::expirationHandler, this, _1));
 	// uniqueHandler slot should be added as first slot of the signal due to
@@ -1218,6 +1305,8 @@ void LLNotifications::createDefaultChannels()
 //        connectFailedFilter(boost::bind(&LLNotifications::failedUniquenessTest, this, _1));
 	LLNotifications::instance().getChannel("Ignore")->
 		connectFailedFilter(&handleIgnoredNotification);
+	LLNotifications::instance().getChannel("VisibilityRules")->
+		connectFailedFilter(&visibilityRuleMached);
 }
 
 bool LLNotifications::addTemplate(const std::string &name, 
@@ -1347,6 +1436,12 @@ bool LLNotifications::loadTemplates()
 	LLXUIParser parser;
 	parser.readXUI(root, params, full_filename);
 
+	if(!params.validateBlock())
+	{
+		llerrs << "Problem reading UI Notifications file: " << full_filename << llendl;
+		return false;
+	}
+
 	mTemplates.clear();
 
 	for(LLInitParam::ParamIterator<LLNotificationTemplate::GlobalString>::const_iterator it = params.strings.begin(), end_it = params.strings.end();
@@ -1396,6 +1491,34 @@ bool LLNotifications::loadTemplates()
 	return true;
 }
 
+bool LLNotifications::loadVisibilityRules()
+{
+	const std::string xml_filename = "notification_visibility.xml";
+	std::string full_filename = gDirUtilp->findSkinnedFilename(LLUI::getXUIPaths().front(), xml_filename);
+
+	LLNotificationVisibilityRule::Rules params;
+	LLSimpleXUIParser parser;
+	parser.readXUI(full_filename, params);
+
+	if(!params.validateBlock())
+	{
+		llerrs << "Problem reading UI Notification Visibility Rules file: " << full_filename << llendl;
+		return false;
+	}
+
+	mVisibilityRules.clear();
+
+	for(LLInitParam::ParamIterator<LLNotificationVisibilityRule::Rule>::iterator it = params.rules.begin(), 
+			end_it = params.rules.end();
+		it != end_it;
+		++it)
+	{
+		mVisibilityRules.push_back(LLNotificationVisibilityRulePtr(new LLNotificationVisibilityRule(*it)));
+	}
+
+	return true;
+}
+
 // Add a simple notification (from XUI)
 void LLNotifications::addFromCallback(const LLSD& name)
 {
@@ -1546,6 +1669,94 @@ bool LLNotifications::getIgnoreAllNotifications()
 	return mIgnoreAllNotifications; 
 }
 													
+bool LLNotifications::isVisibleByRules(LLNotificationPtr n)
+{
+	if(n->isRespondedTo())
+	{
+		// This avoids infinite recursion in the case where the filter calls respond()
+		return true;
+	}
+	
+	VisibilityRuleList::iterator it;
+	
+	for(it = mVisibilityRules.begin(); it != mVisibilityRules.end(); it++)
+	{
+		// An empty type/tag/name string will match any notification, so only do the comparison when the string is non-empty in the rule.
+
+		lldebugs 
+			<< "notification \"" << n->getName() << "\" " 
+			<< "testing against " << ((*it)->mVisible?"show":"hide") << " rule, "
+			<< "name = \"" << (*it)->mName << "\" "
+			<< "tag = \"" << (*it)->mTag << "\" "
+			<< "type = \"" << (*it)->mType << "\" "
+			<< llendl;
+
+		if(!(*it)->mType.empty())
+		{
+			if((*it)->mType != n->getType())
+			{
+				// Type doesn't match, so skip this rule.
+				continue;
+			}
+		}
+		
+		if(!(*it)->mTag.empty())
+		{
+			// check this notification's tag(s) against it->mTag and continue if no match is found.
+			if(!n->matchesTag((*it)->mTag))
+			{
+				// This rule's non-empty tag didn't match one of the notification's tags.  Skip this rule.
+				continue;
+			}
+		}
+
+		if(!(*it)->mName.empty())
+		{
+			// check this notification's name against the notification's name and continue if no match is found.
+			if((*it)->mName != n->getName())
+			{
+				// This rule's non-empty name didn't match the notification.  Skip this rule.
+				continue;
+			}
+		}
+		
+		// If we got here, the rule matches.  Don't evaluate subsequent rules.
+		if(!(*it)->mVisible)
+		{
+			// This notification is being hidden.
+			
+			if((*it)->mResponse.empty())
+			{
+				// Response property is empty.  Cancel this notification.
+				lldebugs << "cancelling notification " << n->getName() << llendl;
+
+				n->cancel();
+			}
+			else
+			{
+				// Response property is not empty.  Return the specified response.
+				LLSD response = n->getResponseTemplate(LLNotification::WITHOUT_DEFAULT_BUTTON);
+				// TODO: verify that the response template has an item with the correct name
+				response[(*it)->mResponse] = true;
+
+				lldebugs << "responding to notification " << n->getName() << " with response = " << response << llendl;
+				
+				n->respond(response);
+			}
+
+			return false;
+		}
+		
+		// If we got here, exit the loop and return true.
+		break;
+	}
+	
+	lldebugs << "allowing notification " << n->getName() << llendl;
+
+	return true;
+}
+			
+
 // ---
 // END OF LLNotifications implementation
 // =========================================================
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 524cff70e80143d5a5685999617b47893c937849..34d3537781ba66df29fa789df743739e507605ed 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -195,6 +195,7 @@ class LLNotificationForm
 		Mandatory<std::string>	type;
 		Optional<S32>			width;
 		Optional<S32>			max_length_chars;
+		Optional<std::string>	text;
 
 		Optional<std::string>	value;
 		FormInput();
@@ -270,6 +271,11 @@ struct LLNotificationTemplate;
 // with smart pointers
 typedef boost::shared_ptr<LLNotificationTemplate> LLNotificationTemplatePtr;
 
+
+struct LLNotificationVisibilityRule;
+
+typedef boost::shared_ptr<LLNotificationVisibilityRule> LLNotificationVisibilityRulePtr;
+
 /**
  * @class LLNotification
  * @brief The object that expresses the details of a notification
@@ -506,7 +512,7 @@ friend class LLNotifications;
 	std::string getLabel() const;
 	std::string getURL() const;
 	S32 getURLOption() const;
-	S32 getURLOpenExternally() const;
+    S32 getURLOpenExternally() const;
 	
 	const LLNotificationFormPtr getForm();
 
@@ -578,6 +584,8 @@ friend class LLNotifications;
 
 	bool hasUniquenessConstraints() const;
 
+	bool matchesTag(const std::string& tag);
+
 	virtual ~LLNotification() {}
 };
 
@@ -859,6 +867,10 @@ class LLNotifications :
 	// OK to call more than once because it will reload
 	bool loadTemplates();  
 	
+	// load visibility rules from file; 
+	// OK to call more than once because it will reload
+	bool loadVisibilityRules();  
+	
 	// Add a simple notification (from XUI)
 	void addFromCallback(const LLSD& name);
 	
@@ -904,6 +916,8 @@ class LLNotifications :
 	// test for existence
 	bool templateExists(const std::string& name);
 
+	typedef std::list<LLNotificationVisibilityRulePtr> VisibilityRuleList;
+	
 	void forceResponse(const LLNotification::Params& params, S32 option);
 
 	void createDefaultChannels();
@@ -919,6 +933,8 @@ class LLNotifications :
 	void setIgnoreAllNotifications(bool ignore);
 	bool getIgnoreAllNotifications();
 
+	bool isVisibleByRules(LLNotificationPtr pNotification);
+	
 private:
 	// we're a singleton, so we don't have a public constructor
 	LLNotifications();
@@ -938,6 +954,8 @@ class LLNotifications :
 	bool addTemplate(const std::string& name, LLNotificationTemplatePtr theTemplate);
 	TemplateMap mTemplates;
 
+	VisibilityRuleList mVisibilityRules;
+
 	std::string mFileName;
 	
 	LLNotificationMap mUniqueNotifications;
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index 6bc0d2aaffd358b3a3cd87746cd422f0a2eb294b..eff572b553f0c5413d3ee6f5c846de13f92c6a5e 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -74,11 +74,13 @@ struct LLNotificationTemplate
 
 	struct UniquenessContext : public LLInitParam::Block<UniquenessContext>
 	{
-		Mandatory<std::string>	key;
+		Mandatory<std::string>	value;
 
 		UniquenessContext()
-		:	key("key")
-		{}
+		:	value("value")
+		{
+			addSynonym(value, "key");
+		}
 		
 	};
 
@@ -88,7 +90,7 @@ struct LLNotificationTemplate
 		// this idiom allows 
 		// <notification unique="true">
 		// as well as
-		// <notification> <unique> <context key=""/> </unique>...
+		// <notification> <unique> <context></context> </unique>...
 		Optional<bool>			dummy_val;
 	public:
 		Multiple<UniquenessContext>	contexts;
@@ -156,6 +158,15 @@ struct LLNotificationTemplate
 		{}
 	};
 
+	struct Tag : public LLInitParam::Block<Tag>
+	{
+		Mandatory<std::string>	value;
+
+		Tag()
+		:	value("value")
+		{}
+	};
+
 	struct Params : public LLInitParam::Block<Params>
 	{
 		Mandatory<std::string>			name;
@@ -173,6 +184,7 @@ struct LLNotificationTemplate
 		Optional<FormRef>				form_ref;
 		Optional<ENotificationPriority, 
 			NotificationPriorityValues> priority;
+		Multiple<Tag>		tags;
 
 
 		Params()
@@ -189,7 +201,8 @@ struct LLNotificationTemplate
 			expire_option("expireOption", -1),
 			url("url"),
 			unique("unique"),
-			form_ref("")
+			form_ref(""),
+			tags("tag")
 		{}
 
 	};
@@ -232,8 +245,8 @@ struct LLNotificationTemplate
     // (used for things like progress indications, or repeating warnings
     // like "the grid is going down in N minutes")
     bool mUnique;
-    // if we want to be unique only if a certain part of the payload is constant
-    // specify the field names for the payload. The notification will only be
+    // if we want to be unique only if a certain part of the payload or substitutions args
+	// are constant specify the field names for the payload. The notification will only be
     // combined if all of the fields named in the context are identical in the
     // new and the old notification; otherwise, the notification will be
     // duplicated. This is to support suppressing duplicate offers from the same
@@ -276,6 +289,8 @@ struct LLNotificationTemplate
 	// this is loaded as a name, but looked up to get the UUID upon template load.
 	// If null, it wasn't specified.
 	LLUUID mSoundEffect;
+	// List of tags that rules can match against.
+	std::list<std::string> mTags;
 };
 
 #endif //LL_LLNOTIFICATION_TEMPLATE_H
diff --git a/indra/llui/llnotificationvisibilityrule.h b/indra/llui/llnotificationvisibilityrule.h
new file mode 100644
index 0000000000000000000000000000000000000000..78bdec2a8f3ac80591a8acbb540164c2942a9e51
--- /dev/null
+++ b/indra/llui/llnotificationvisibilityrule.h
@@ -0,0 +1,104 @@
+/**
+* @file llnotificationvisibility.h
+* @brief Rules for 
+* @author Monroe
+*
+* $LicenseInfo:firstyear=2010&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+* 
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+
+#ifndef LL_LLNOTIFICATION_VISIBILITY_RULE_H
+#define LL_LLNOTIFICATION_VISIBILITY_RULE_H
+
+#include "llinitparam.h"
+//#include "llnotifications.h"
+
+
+
+// This is the class of object read from the XML file (notification_visibility.xml, 
+// from the appropriate local language directory).
+struct LLNotificationVisibilityRule
+{
+	struct Filter : public LLInitParam::Block<Filter>
+	{
+		Optional<std::string>	type,
+								tag,
+								name;
+
+		Filter()
+		:	type("type"),
+			tag("tag"),
+			name("name")
+		{}
+	};
+
+	struct Respond : public LLInitParam::Block<Respond, Filter>
+	{
+		Mandatory<std::string> response;
+
+		Respond()
+		:	response("response")
+		{}
+	};
+
+	struct Rule : public LLInitParam::Choice<Rule>
+	{
+		Alternative<Filter>		show;
+		Alternative<Filter>		hide;
+		Alternative<Respond>	respond;
+
+		Rule()
+		:	show("show"),
+			hide("hide"),
+			respond("respond")
+		{}
+	};
+
+	struct Rules : public LLInitParam::Block<Rules>
+	{
+		Multiple<Rule>	rules;
+
+		Rules()
+		:	rules("")
+		{}
+	};
+
+	LLNotificationVisibilityRule(const Rule& p);
+	
+    // If true, this rule makes matching notifications visible.  Otherwise, it makes them invisible.
+    bool mVisible;
+
+    // Which response to give when making a notification invisible.  An empty string means the notification should be cancelled instead of responded to.
+	std::string mResponse;
+
+    // String to match against the notification's "type".  An empty string matches all notifications.
+    std::string mType;
+	
+    // String to match against the notification's tag(s).  An empty string matches all notifications.
+	std::string mTag;
+
+    // String to match against the notification's name.  An empty string matches all notifications.
+	std::string mName;
+	
+};
+
+#endif //LL_LLNOTIFICATION_VISIBILITY_RULE_H
+
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index 900e2c789e28672b6d1130b0fb0c9634c31570bb..b2383106a86c05cbbeddb602237c95bce6beb51b 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -194,6 +194,8 @@ void LLPanel::draw()
 	// draw background
 	if( mBgVisible )
 	{
+		alpha = getCurrentTransparency();
+
 		LLRect local_rect = getLocalRect();
 		if (mBgOpaque )
 		{
@@ -434,7 +436,7 @@ void LLPanel::initFromParams(const LLPanel::Params& p)
     //and LLView::initFromParams will use them to set visible and enabled  
 	setVisible(p.visible);
 	setEnabled(p.enabled);
-
+	setFocusRoot(p.focus_root);
 	setSoundFlags(p.sound_flags);
 
 	 // control_name, tab_stop, focus_lost_callback, initial_value, rect, enabled, visible
diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp
index aaa328754d361c556c7e450eecab7443167b09bc..ead22686bc405d21191d5aa342350a93d1bc75fe 100644
--- a/indra/llui/llprogressbar.cpp
+++ b/indra/llui/llprogressbar.cpp
@@ -50,7 +50,7 @@ LLProgressBar::Params::Params()
 
 
 LLProgressBar::LLProgressBar(const LLProgressBar::Params& p) 
-:	LLView(p),
+:	LLUICtrl(p),
 	mImageBar(p.image_bar),
 	mImageFill(p.image_fill),
 	mColorBackground(p.color_bg()),
@@ -80,7 +80,7 @@ void LLProgressBar::draw()
 	mImageFill->draw(progress_rect, bar_color);
 }
 
-void LLProgressBar::setPercent(const F32 percent)
+void LLProgressBar::setValue(const LLSD& value)
 {
-	mPercentDone = llclamp(percent, 0.f, 100.f);
+	mPercentDone = llclamp((F32)value.asReal(), 0.f, 100.f);
 }
diff --git a/indra/llui/llprogressbar.h b/indra/llui/llprogressbar.h
index 13297f7493ca24bac7dcf2d1dd1de51b7d8f93c3..3f308e749683feb09e748f9ef522d936ecc83e1a 100644
--- a/indra/llui/llprogressbar.h
+++ b/indra/llui/llprogressbar.h
@@ -27,14 +27,14 @@
 #ifndef LL_LLPROGRESSBAR_H
 #define LL_LLPROGRESSBAR_H
 
-#include "llview.h"
+#include "lluictrl.h"
 #include "llframetimer.h"
 
 class LLProgressBar
-	: public LLView
+	: public LLUICtrl
 {
 public:
-	struct Params : public LLInitParam::Block<Params, LLView::Params>
+	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
 		Optional<LLUIImage*>	image_bar,
 								image_fill;
@@ -47,7 +47,7 @@ class LLProgressBar
 	LLProgressBar(const Params&);
 	virtual ~LLProgressBar();
 
-	void setPercent(const F32 percent);
+	void setValue(const LLSD& value);
 
 	/*virtual*/ void draw();
 
diff --git a/indra/llui/llradiogroup.cpp b/indra/llui/llradiogroup.cpp
index cc348fdc63c2923e9d97d1978945ad71bdec69f2..6e9586369f30aeb418d3b7d64269ca0f2888a72a 100644
--- a/indra/llui/llradiogroup.cpp
+++ b/indra/llui/llradiogroup.cpp
@@ -69,7 +69,7 @@ class LLRadioCtrl : public LLCheckBoxCtrl
 static LLWidgetNameRegistry::StaticRegistrar register_radio_item(&typeid(LLRadioGroup::ItemParams), "radio_item");
 
 LLRadioGroup::Params::Params()
-:	has_border("draw_border"),
+:	allow_deselect("allow_deselect"),
 	items("item") 
 {
 	addSynonym(items, "radio_item");
@@ -85,18 +85,8 @@ LLRadioGroup::LLRadioGroup(const LLRadioGroup::Params& p)
 :	LLUICtrl(p),
 	mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()),
 	mSelectedIndex(-1),
-	mHasBorder(p.has_border)
-{	
-	if (mHasBorder)
-	{
-		LLViewBorder::Params params;
-		params.name("radio group border");
-		params.rect(LLRect(0, getRect().getHeight(), getRect().getWidth(), 0));
-		params.bevel_style(LLViewBorder::BEVEL_NONE);
-		LLViewBorder * vb = LLUICtrlFactory::create<LLViewBorder> (params);
-		addChild (vb);
-	}
-}
+	mAllowDeselect(p.allow_deselect)
+{}
 
 void LLRadioGroup::initFromParams(const Params& p)
 {
@@ -184,7 +174,7 @@ void LLRadioGroup::setIndexEnabled(S32 index, BOOL enabled)
 
 BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event)
 {
-	if (index < 0 || (S32)mRadioButtons.size() <= index )
+	if ((S32)mRadioButtons.size() <= index )
 	{
 		return FALSE;
 	}
@@ -202,13 +192,16 @@ BOOL LLRadioGroup::setSelectedIndex(S32 index, BOOL from_event)
 
 	mSelectedIndex = index;
 
-	LLRadioCtrl* radio_item = mRadioButtons[mSelectedIndex];
-	radio_item->setTabStop(true);
-	radio_item->setValue( TRUE );
-
-	if (hasFocus())
+	if (mSelectedIndex >= 0)
 	{
-		mRadioButtons[mSelectedIndex]->focusFirstItem(FALSE, FALSE);
+		LLRadioCtrl* radio_item = mRadioButtons[mSelectedIndex];
+		radio_item->setTabStop(true);
+		radio_item->setValue( TRUE );
+
+		if (hasFocus())
+		{
+			radio_item->focusFirstItem(FALSE, FALSE);
+		}
 	}
 
 	if (!from_event)
@@ -307,8 +300,15 @@ void LLRadioGroup::onClickButton(LLUICtrl* ctrl)
 		LLRadioCtrl* radio = *iter;
 		if (radio == clicked_radio)
 		{
-			// llinfos << "clicked button " << index << llendl;
-			setSelectedIndex(index);
+			if (index == mSelectedIndex && mAllowDeselect)
+			{
+				// don't select anything
+				setSelectedIndex(-1);
+			}
+			else
+			{
+				setSelectedIndex(index);
+			}
 			
 			// BUG: Calls click callback even if button didn't actually change
 			onCommit();
diff --git a/indra/llui/llradiogroup.h b/indra/llui/llradiogroup.h
index 0588900600484c9bd843044191450eb593d951c2..8bd5698538962e7cd4dd642540515eda81916c47 100644
--- a/indra/llui/llradiogroup.h
+++ b/indra/llui/llradiogroup.h
@@ -49,7 +49,7 @@ class LLRadioGroup
 
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
-		Optional<bool>						has_border;
+		Optional<bool>						allow_deselect;
 		Multiple<ItemParams, AtLeast<1> >	items;
 		Params();
 	};
@@ -73,7 +73,6 @@ class LLRadioGroup
 	void setIndexEnabled(S32 index, BOOL enabled);
 	// return the index value of the selected item
 	S32 getSelectedIndex() const { return mSelectedIndex; }
-	
 	// set the index value programatically
 	BOOL setSelectedIndex(S32 index, BOOL from_event = FALSE);
 
@@ -103,12 +102,13 @@ class LLRadioGroup
 	/*virtual*/ BOOL	operateOnAll(EOperation op);
 
 private:
-	const LLFontGL* mFont;
-	S32 mSelectedIndex;
+	const LLFontGL*		mFont;
+	S32					mSelectedIndex;
+
 	typedef std::vector<class LLRadioCtrl*> button_list_t;
-	button_list_t mRadioButtons;
+	button_list_t		mRadioButtons;
 
-	BOOL mHasBorder;
+	bool				mAllowDeselect;	// user can click on an already selected option to deselect it
 };
 
 #endif
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 3146418a7dd3977b90e9de63a90107fff2ed267a..380c477eb219f26843f374d94805f1f6d57e8dd9 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -422,9 +422,10 @@ void LLScrollContainer::draw()
 	// Draw background
 	if( mIsOpaque )
 	{
+		F32 alpha = getCurrentTransparency();
+
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		gGL.color4fv( mBackgroundColor.get().mV );
-		gl_rect_2d( mInnerRect );
+		gl_rect_2d(mInnerRect, mBackgroundColor.get() % alpha);
 	}
 	
 	// Draw mScrolledViews and update scroll bars.
diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp
index 2a4c1ca44c1f6f7e5c04e1d5e50b8a4baca3223e..696e4a2bb1e60a61391a12ed6dd6408fdb0d8409 100644
--- a/indra/llui/llscrolllistcolumn.cpp
+++ b/indra/llui/llscrolllistcolumn.cpp
@@ -83,7 +83,14 @@ void LLScrollColumnHeader::draw()
 			&& (sort_column == mColumn->mSortingColumn || sort_column == mColumn->mName);
 
 	BOOL is_ascending = mColumn->mParentCtrl->getSortAscending();
-	setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, draw_arrow ? LLColor4::white : LLColor4::transparent);
+	if (draw_arrow)
+	{
+		setImageOverlay(is_ascending ? "up_arrow.tga" : "down_arrow.tga", LLFontGL::RIGHT, LLColor4::white);
+	}
+	else
+	{
+		setImageOverlay(LLUUID::null);
+	}
 
 	// Draw children
 	LLButton::draw();
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 7df7c13dc09bd662ce5d3d59292be0a8306fae03..b7848ec37c31ccd795d5f73d42dfefa0bcbf61fe 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -322,6 +322,7 @@ LLScrollListCtrl::~LLScrollListCtrl()
 	delete mSortCallback;
 
 	std::for_each(mItemList.begin(), mItemList.end(), DeletePointer());
+	std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer());
 }
 
 
@@ -1482,8 +1483,9 @@ void LLScrollListCtrl::draw()
 	// Draw background
 	if (mBackgroundVisible)
 	{
+		F32 alpha = getCurrentTransparency();
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		gl_rect_2d(background, getEnabled() ? mBgWriteableColor.get() : mBgReadOnlyColor.get() );
+		gl_rect_2d(background, getEnabled() ? mBgWriteableColor.get() % alpha : mBgReadOnlyColor.get() % alpha );
 	}
 
 	if (mColumnsDirty)
@@ -2370,10 +2372,10 @@ void LLScrollListCtrl::onScrollChange( S32 new_pos, LLScrollbar* scrollbar )
 
 void LLScrollListCtrl::sortByColumn(const std::string& name, BOOL ascending)
 {
-	std::map<std::string, LLScrollListColumn>::iterator itor = mColumns.find(name);
+	column_map_t::iterator itor = mColumns.find(name);
 	if (itor != mColumns.end())
 	{
-		sortByColumnIndex((*itor).second.mIndex, ascending);
+		sortByColumnIndex((*itor).second->mIndex, ascending);
 	}
 }
 
@@ -2419,11 +2421,11 @@ void LLScrollListCtrl::dirtyColumns()
 	// just in case someone indexes into it immediately
 	mColumnsIndexed.resize(mColumns.size());
 
-	std::map<std::string, LLScrollListColumn>::iterator column_itor;
+	column_map_t::iterator column_itor;
 	for (column_itor = mColumns.begin(); column_itor != mColumns.end(); ++column_itor)
 	{
-		LLScrollListColumn *column = &column_itor->second;
-		mColumnsIndexed[column_itor->second.mIndex] = column;
+		LLScrollListColumn *column = column_itor->second;
+		mColumnsIndexed[column_itor->second->mIndex] = column;
 	}
 }
 
@@ -2581,8 +2583,8 @@ void LLScrollListCtrl::addColumn(const LLScrollListColumn::Params& column_params
 	if (mColumns.find(name) == mColumns.end())
 	{
 		// Add column
-		mColumns[name] = LLScrollListColumn(column_params, this);
-		LLScrollListColumn* new_column = &mColumns[name];
+		mColumns[name] = new LLScrollListColumn(column_params, this);
+		LLScrollListColumn* new_column = mColumns[name];
 		new_column->mIndex = mColumns.size()-1;
 
 		// Add button
@@ -2604,14 +2606,14 @@ void LLScrollListCtrl::addColumn(const LLScrollListColumn::Params& column_params
 			S32 top = mItemListRect.mTop;
 
 			S32 left = mItemListRect.mLeft;
-			for (std::map<std::string, LLScrollListColumn>::iterator itor = mColumns.begin(); 
+			for (column_map_t::iterator itor = mColumns.begin(); 
 				itor != mColumns.end(); 
 				++itor)
 			{
-				if (itor->second.mIndex < new_column->mIndex &&
-					itor->second.getWidth() > 0)
+				if (itor->second->mIndex < new_column->mIndex &&
+					itor->second->getWidth() > 0)
 				{
-					left += itor->second.getWidth() + mColumnPadding;
+					left += itor->second->getWidth() + mColumnPadding;
 				}
 			}
 
@@ -2667,8 +2669,8 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
 	if (column->mSortingColumn != column->mName
 		&& parent->mColumns.find(column->mSortingColumn) != parent->mColumns.end())
 	{
-		LLScrollListColumn& info_redir = parent->mColumns[column->mSortingColumn];
-		column_index = info_redir.mIndex;
+		LLScrollListColumn* info_redir = parent->mColumns[column->mSortingColumn];
+		column_index = info_redir->mIndex;
 	}
 
 	// if this column is the primary sort key, reverse the direction
@@ -2701,16 +2703,17 @@ BOOL LLScrollListCtrl::hasSortOrder() const
 
 void LLScrollListCtrl::clearColumns()
 {
-	std::map<std::string, LLScrollListColumn>::iterator itor;
+	column_map_t::iterator itor;
 	for (itor = mColumns.begin(); itor != mColumns.end(); ++itor)
 	{
-		LLScrollColumnHeader *header = itor->second.mHeader;
+		LLScrollColumnHeader *header = itor->second->mHeader;
 		if (header)
 		{
 			removeChild(header);
 			delete header;
 		}
 	}
+	std::for_each(mColumns.begin(), mColumns.end(), DeletePairedPointer());
 	mColumns.clear();
 	mSortColumns.clear();
 	mTotalStaticColumnWidth = 0;
@@ -2744,7 +2747,7 @@ LLScrollListColumn* LLScrollListCtrl::getColumn(const std::string& name)
 	column_map_t::iterator column_itor = mColumns.find(name);
 	if (column_itor != mColumns.end()) 
 	{
-		return &column_itor->second;
+		return column_itor->second;
 	}
 	return NULL;
 }
@@ -2805,7 +2808,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS
 				new_column.width.pixel_width = cell_p.width;
 			}
 			addColumn(new_column);
-			columnp = &mColumns[column];
+			columnp = mColumns[column];
 			new_item->setNumColumns(mColumns.size());
 		}
 
@@ -2842,7 +2845,7 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS
 		LLScrollListCell* cell = LLScrollListCell::create(LLScrollListCell::Params().value(item_p.value));
 		if (cell)
 		{
-			LLScrollListColumn* columnp = &(mColumns.begin()->second);
+			LLScrollListColumn* columnp = mColumns.begin()->second;
 
 			new_item->setColumn(0, cell);
 			if (columnp->mHeader 
@@ -2857,10 +2860,10 @@ LLScrollListItem* LLScrollListCtrl::addRow(LLScrollListItem *new_item, const LLS
 	// add dummy cells for missing columns
 	for (column_map_t::iterator column_it = mColumns.begin(); column_it != mColumns.end(); ++column_it)
 	{
-		S32 column_idx = column_it->second.mIndex;
+		S32 column_idx = column_it->second->mIndex;
 		if (new_item->getColumn(column_idx) == NULL)
 		{
-			LLScrollListColumn* column_ptr = &column_it->second;
+			LLScrollListColumn* column_ptr = column_it->second;
 			LLScrollListCell::Params cell_p;
 			cell_p.width = column_ptr->getWidth();
 			
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 8a2f893ba2f8ee7131b95768a5bba9a3f4517e40..09ab89960da1814d99d5ae91da24b8f873a08fa0 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -491,7 +491,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 
 	mutable bool	mSorted;
 	
-	typedef std::map<std::string, LLScrollListColumn> column_map_t;
+	typedef std::map<std::string, LLScrollListColumn*> column_map_t;
 	column_map_t mColumns;
 
 	BOOL			mDirty;
diff --git a/indra/llui/llsdparam.cpp b/indra/llui/llsdparam.cpp
index f97f80ab6cb63c3c99b7e0950107a03e2a69f947..9ad13054cb525d61e1351a1ceefc48c58fbc86a2 100644
--- a/indra/llui/llsdparam.cpp
+++ b/indra/llui/llsdparam.cpp
@@ -45,6 +45,7 @@ LLParamSDParser::LLParamSDParser()
 
 	if (sReadFuncs.empty())
 	{
+		registerParserFuncs<LLInitParam::NoParamValue>(readNoValue, &LLParamSDParser::writeNoValue);
 		registerParserFuncs<S32>(readS32, &LLParamSDParser::writeTypedValue<S32>);
 		registerParserFuncs<U32>(readU32, &LLParamSDParser::writeU32Param);
 		registerParserFuncs<F32>(readF32, &LLParamSDParser::writeTypedValue<F32>);
@@ -71,6 +72,18 @@ bool LLParamSDParser::writeU32Param(LLParamSDParser::parser_t& parser, const voi
 	return true;
 }
 
+bool LLParamSDParser::writeNoValue(LLParamSDParser::parser_t& parser, const void* val_ptr, const parser_t::name_stack_t& name_stack)
+{
+	LLParamSDParser& sdparser = static_cast<LLParamSDParser&>(parser);
+	if (!sdparser.mWriteRootSD) return false;
+
+	LLSD* sd_to_write = sdparser.getSDWriteNode(name_stack);
+	if (!sd_to_write) return false;
+
+	return true;
+}
+
+
 void LLParamSDParser::readSD(const LLSD& sd, LLInitParam::BaseBlock& block, bool silent)
 {
 	mCurReadSD = NULL;
@@ -87,6 +100,8 @@ void LLParamSDParser::writeSD(LLSD& sd, const LLInitParam::BaseBlock& block)
 	block.serializeBlock(*this);
 }
 
+const LLSD NO_VALUE_MARKER;
+
 void LLParamSDParser::readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block)
 {
 	if (sd.isMap())
@@ -110,6 +125,11 @@ void LLParamSDParser::readSDValues(const LLSD& sd, LLInitParam::BaseBlock& block
 			readSDValues(*it, block);
 		}
 	}
+	else if (sd.isUndefined())
+	{
+		mCurReadSD = &NO_VALUE_MARKER;
+		block.submitValue(mNameStack, *this);
+	}
 	else
 	{
 		mCurReadSD = &sd;
@@ -206,6 +226,13 @@ LLSD* LLParamSDParser::getSDWriteNode(const parser_t::name_stack_t& name_stack)
 	return sd_to_write;
 }
 
+bool LLParamSDParser::readNoValue(Parser& parser, void* val_ptr)
+{
+	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
+	return self.mCurReadSD == &NO_VALUE_MARKER;
+}
+
+
 bool LLParamSDParser::readS32(Parser& parser, void* val_ptr)
 {
 	LLParamSDParser& self = static_cast<LLParamSDParser&>(parser);
diff --git a/indra/llui/llsdparam.h b/indra/llui/llsdparam.h
index 97e8b58e492bd61d574ad0b61e479d2e80f3a8cb..69dab2b411cf5159934f4b011f5fcc9702f1caa4 100644
--- a/indra/llui/llsdparam.h
+++ b/indra/llui/llsdparam.h
@@ -63,7 +63,9 @@ typedef LLInitParam::Parser parser_t;
 	LLSD* getSDWriteNode(const parser_t::name_stack_t& name_stack);
 
 	static bool writeU32Param(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack);
+	static bool writeNoValue(Parser& parser, const void* value_ptr, const parser_t::name_stack_t& name_stack);
 
+	static bool readNoValue(Parser& parser, void* val_ptr);
 	static bool readS32(Parser& parser, void* val_ptr);
 	static bool readU32(Parser& parser, void* val_ptr);
 	static bool readF32(Parser& parser, void* val_ptr);
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 5721df6b3627c24281c164d6bb30b087d55175eb..49537ef78fc2c1cf11df3c96a63cbcdc2da533c1 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -1005,6 +1005,7 @@ void LLTextBase::draw()
 
 	if (mBGVisible)
 	{
+		F32 alpha = getCurrentTransparency();
 		// clip background rect against extents, if we support scrolling
 		LLRect bg_rect = mVisibleTextRect;
 		if (mScroller)
@@ -1016,7 +1017,7 @@ void LLTextBase::draw()
 							: hasFocus() 
 								? mFocusBgColor.get() 
 								: mWriteableBgColor.get();
-		gl_rect_2d(doc_rect, bg_color, TRUE);
+		gl_rect_2d(doc_rect, bg_color % alpha, TRUE);
 	}
 
 	// draw document view
@@ -1591,7 +1592,10 @@ void LLTextBase::setText(const LLStringExplicit &utf8str, const LLStyle::Params&
 	// appendText modifies mCursorPos...
 	appendText(text, false, input_params);
 	// ...so move cursor to top after appending text
-	startOfDoc();
+	if (!mTrackEnd)
+	{
+		startOfDoc();
+	}
 
 	onValueChange(0, getLength());
 }
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 94bf716e7d77863a4d32b77918f30042bc9efe49..5a46c7c98e0721d1178f73da7a02241c58de492e 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -277,6 +277,8 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
 		mHPad += UI_TEXTEDITOR_LINE_NUMBER_MARGIN;
 		updateRects();
 	}
+	
+	mParseOnTheFly = TRUE;
 }
 
 void LLTextEditor::initFromParams( const LLTextEditor::Params& p)
@@ -324,8 +326,10 @@ void LLTextEditor::setText(const LLStringExplicit &utf8str, const LLStyle::Param
 
 	blockUndo();
 	deselect();
-
+	
+	mParseOnTheFly = FALSE;
 	LLTextBase::setText(utf8str, input_params);
+	mParseOnTheFly = TRUE;
 
 	resetDirty();
 }
@@ -1367,6 +1371,7 @@ void LLTextEditor::pastePrimary()
 // paste from primary (itsprimary==true) or clipboard (itsprimary==false)
 void LLTextEditor::pasteHelper(bool is_primary)
 {
+	mParseOnTheFly = FALSE;
 	bool can_paste_it;
 	if (is_primary)
 	{
@@ -1450,6 +1455,7 @@ void LLTextEditor::pasteHelper(bool is_primary)
 	deselect();
 
 	onKeyStroke();
+	mParseOnTheFly = TRUE;
 }
 
 
@@ -2385,7 +2391,7 @@ void LLTextEditor::loadKeywords(const std::string& filename,
 
 void LLTextEditor::updateSegments()
 {
-	if (mReflowIndex < S32_MAX && mKeywords.isLoaded())
+	if (mReflowIndex < S32_MAX && mKeywords.isLoaded() && mParseOnTheFly)
 	{
 		LLFastTimer ft(FTM_SYNTAX_HIGHLIGHTING);
 		// HACK:  No non-ascii keywords for now
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 58ecefdccbd4ee9798bc6b24ce873ea26fa9b00e..9e4b95003b7f45aeb1c32094a32332f83b40b8ba 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -315,6 +315,7 @@ class LLTextEditor :
 
 	BOOL			mAllowEmbeddedItems;
 	bool			mShowContextMenu;
+	bool			mParseOnTheFly;
 
 	LLUUID			mSourceID;
 
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index ff9af21e545eb762ec7a33874532a2d4c7b590b0..c300fe55d9388f46b99e9346dda5bba9e7279b82 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -950,7 +950,7 @@ void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor
 }
 
 // Draw gray and white checkerboard with black border
-void gl_rect_2d_checkerboard(const LLRect& rect)
+void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
 {
 	// Initialize the first time this is called.
 	const S32 PIXELS = 32;
@@ -971,11 +971,11 @@ void gl_rect_2d_checkerboard(const LLRect& rect)
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 
 	// ...white squares
-	gGL.color3f( 1.f, 1.f, 1.f );
+	gGL.color4f( 1.f, 1.f, 1.f, alpha );
 	gl_rect_2d(rect);
 
 	// ...gray squares
-	gGL.color3f( .7f, .7f, .7f );
+	gGL.color4f( .7f, .7f, .7f, alpha );
 	gGL.flush();
 	glPolygonStipple( checkerboard );
 
@@ -1596,23 +1596,25 @@ void LLUI::initClass(const settings_map_t& settings,
 	sWindow = NULL; // set later in startup
 	LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow");
 
+	LLUICtrl::CommitCallbackRegistry::Registrar& reg = LLUICtrl::CommitCallbackRegistry::defaultRegistrar();
+
 	// Callbacks for associating controls with floater visibilty:
-	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleFloaterInstance, _2));
-	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Show", boost::bind(&LLFloaterReg::showFloaterInstance, _2));
-	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.Hide", boost::bind(&LLFloaterReg::hideFloaterInstance, _2));
-	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Floater.InitToVisibilityControl", boost::bind(&LLFloaterReg::initUICtrlToFloaterVisibilityControl, _1, _2));
+	reg.add("Floater.Toggle", boost::bind(&LLFloaterReg::toggleFloaterInstance, _2));
+	reg.add("Floater.Show", boost::bind(&LLFloaterReg::showFloaterInstance, _2));
+	reg.add("Floater.Hide", boost::bind(&LLFloaterReg::hideFloaterInstance, _2));
+	reg.add("Floater.InitToVisibilityControl", boost::bind(&LLFloaterReg::initUICtrlToFloaterVisibilityControl, _1, _2));
 	
 	// Button initialization callback for toggle buttons
-	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2));
+	reg.add("Button.SetFloaterToggle", boost::bind(&LLButton::setFloaterToggle, _1, _2));
 	
 	// Button initialization callback for toggle buttons on dockale floaters
-	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.SetDockableFloaterToggle", boost::bind(&LLButton::setDockableFloaterToggle, _1, _2));
+	reg.add("Button.SetDockableFloaterToggle", boost::bind(&LLButton::setDockableFloaterToggle, _1, _2));
 
 	// Display the help topic for the current context
-	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2));
+	reg.add("Button.ShowHelp", boost::bind(&LLButton::showHelp, _1, _2));
 
 	// Currently unused, but kept for reference:
-	LLUICtrl::CommitCallbackRegistry::defaultRegistrar().add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2));
+	reg.add("Button.ToggleFloater", boost::bind(&LLButton::toggleFloaterAndSetToggleState, _1, _2));
 	
 	// Used by menus along with Floater.Toggle to display visibility as a checkmark
 	LLUICtrl::EnableCallbackRegistry::defaultRegistrar().add("Floater.Visible", boost::bind(&LLFloaterReg::floaterInstanceVisible, _2));
@@ -1620,7 +1622,10 @@ void LLUI::initClass(const settings_map_t& settings,
 
 void LLUI::cleanupClass()
 {
-	sImageProvider->cleanUp();
+	if(sImageProvider)
+	{
+		sImageProvider->cleanUp();
+	}
 }
 
 void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups)
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index fc545c85d5764a48c691284f571cc7db73697f14..62d10df8b28852db94925ffdffa401f9c12c7d46 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -79,7 +79,7 @@ void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LL
 void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
 void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
 void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
-void gl_rect_2d_checkerboard(const LLRect& rect);
+void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
 
 void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
 
diff --git a/indra/llui/lluicolortable.cpp b/indra/llui/lluicolortable.cpp
index 0641f6d17588ffec708569846d0e40cf4569f080..9455d09cc0c0d5521279930273575004e04add5c 100644
--- a/indra/llui/lluicolortable.cpp
+++ b/indra/llui/lluicolortable.cpp
@@ -215,6 +215,12 @@ bool LLUIColorTable::loadFromSettings()
 		result |= loadFromFilename(current_filename, mLoadedColors);
 	}
 
+	current_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SKIN, "colors.xml");
+	if(current_filename != default_filename)
+	{
+		result |= loadFromFilename(current_filename, mLoadedColors);
+	}
+
 	std::string user_filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "colors.xml");
 	loadFromFilename(user_filename, mUserSetColors);
 
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index 3ac3bf8c41fe35e23017268cb2231d4ca61c49ce..0a06b5e74f6b38480b9f1e3df73b9fd69687c2a8 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -36,6 +36,9 @@
 
 static LLDefaultChildRegistry::Register<LLUICtrl> r("ui_ctrl");
 
+F32 LLUICtrl::sActiveControlTransparency = 1.0f;
+F32 LLUICtrl::sInactiveControlTransparency = 1.0f;
+
 // Compiler optimization, generate extern template
 template class LLUICtrl* LLView::getChild<class LLUICtrl>(
 	const std::string& name, BOOL recurse) const;
@@ -110,7 +113,8 @@ LLUICtrl::LLUICtrl(const LLUICtrl::Params& p, const LLViewModelPtr& viewmodel)
 	mMouseUpSignal(NULL),
 	mRightMouseDownSignal(NULL),
 	mRightMouseUpSignal(NULL),
-	mDoubleClickSignal(NULL)
+	mDoubleClickSignal(NULL),
+	mTransparencyType(TT_DEFAULT)
 {
 	mUICtrlHandle.bind(this);
 }
@@ -823,7 +827,7 @@ LLUICtrl* LLUICtrl::findRootMostFocusRoot()
 {
 	LLUICtrl* focus_root = NULL;
 	LLUICtrl* next_view = this;
-	while(next_view)
+	while(next_view && next_view->hasTabStop())
 	{
 		if (next_view->isFocusRoot())
 		{
@@ -923,6 +927,37 @@ BOOL LLUICtrl::getTentative() const
 void LLUICtrl::setColor(const LLColor4& color)							
 { }
 
+F32 LLUICtrl::getCurrentTransparency()
+{
+	F32 alpha = 0;
+
+	switch(mTransparencyType)
+	{
+	case TT_DEFAULT:
+		alpha = getDrawContext().mAlpha;
+		break;
+
+	case TT_ACTIVE:
+		alpha = sActiveControlTransparency;
+		break;
+
+	case TT_INACTIVE:
+		alpha = sInactiveControlTransparency;
+		break;
+
+	case TT_FADING:
+		alpha = sInactiveControlTransparency / 2;
+		break;
+	}
+
+	return alpha;
+}
+
+void LLUICtrl::setTransparencyType(ETypeTransparency type)
+{
+	mTransparencyType = type;
+}
+
 boost::signals2::connection LLUICtrl::setCommitCallback( const commit_signal_t::slot_type& cb ) 
 { 
 	if (!mCommitSignal) mCommitSignal = new commit_signal_t();
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 76dfdf754c3dc70598ca5e6ccc91752ff479eb27..b37e9f6b1b4d5818a811b91db300e26e4aac6a9c 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -120,6 +120,13 @@ class LLUICtrl
 		Params();
 	};
 
+	enum ETypeTransparency
+	{
+		TT_DEFAULT,
+		TT_ACTIVE,		// focused floater
+		TT_INACTIVE,	// other floaters
+		TT_FADING,		// fading toast
+	};
 	/*virtual*/ ~LLUICtrl();
 
 	void initFromParams(const Params& p);
@@ -202,6 +209,11 @@ class LLUICtrl
 
 	virtual void	setColor(const LLColor4& color);
 
+	F32 			getCurrentTransparency();
+
+	void				setTransparencyType(ETypeTransparency type);
+	ETypeTransparency	getTransparencyType() const {return mTransparencyType;}
+
 	BOOL	focusNextItem(BOOL text_entry_only);
 	BOOL	focusPrevItem(BOOL text_entry_only);
 	BOOL 	focusFirstItem(BOOL prefer_text_fields = FALSE, BOOL focus_flash = TRUE );
@@ -283,6 +295,10 @@ class LLUICtrl
 	boost::signals2::connection mMakeVisibleControlConnection;
 	LLControlVariable* mMakeInvisibleControlVariable;
 	boost::signals2::connection mMakeInvisibleControlConnection;
+
+	static F32 sActiveControlTransparency;
+	static F32 sInactiveControlTransparency;
+
 private:
 
 	BOOL			mTabStop;
@@ -290,6 +306,8 @@ class LLUICtrl
 	BOOL			mTentative;
 	LLRootHandle<LLUICtrl> mUICtrlHandle;
 
+	ETypeTransparency mTransparencyType;
+
 	class DefaultTabGroupFirstSorter;
 };
 
diff --git a/indra/llui/lluistring.h b/indra/llui/lluistring.h
index 4faa0e070e673e62dd183346f5814a9a05e08419..cb40c8558235cf65867575818ac254265c5a3dcb 100644
--- a/indra/llui/lluistring.h
+++ b/indra/llui/lluistring.h
@@ -61,7 +61,6 @@ class LLUIString
 	LLUIString() : mArgs(NULL), mNeedsResult(false), mNeedsWResult(false) {}
 	LLUIString(const std::string& instring, const LLStringUtil::format_map_t& args);
 	LLUIString(const std::string& instring) : mArgs(NULL) { assign(instring); }
-
 	~LLUIString() { delete mArgs; }
 
 	void assign(const std::string& instring);
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 6cc72bad82817e081ab94a9cdb81131579f83bc8..4f7b4be52609206899dee5e9934bdf6c9aa49d62 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -27,6 +27,7 @@
 
 #include "linden_common.h"
 #include "llurlentry.h"
+#include "lluictrl.h"
 #include "lluri.h"
 #include "llurlmatch.h"
 #include "llurlregistry.h"
@@ -167,6 +168,15 @@ void LLUrlEntryBase::callObservers(const std::string &id,
 	}
 }
 
+/// is this a match for a URL that should not be hyperlinked?
+bool LLUrlEntryBase::isLinkDisabled() const
+{
+	// this allows us to have a global setting to turn off text hyperlink highlighting/action
+	bool globally_disabled = LLUI::sSettingGroups["config"]->getBOOL("DisableTextHyperlinkActions");
+
+	return globally_disabled;
+}
+
 static std::string getStringAfterToken(const std::string str, const std::string token)
 {
 	size_t pos = str.find(token);
@@ -456,8 +466,8 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
 LLStyle::Params LLUrlEntryAgent::getStyle() const
 {
 	LLStyle::Params style_params = LLUrlEntryBase::getStyle();
-	style_params.color = LLUIColorTable::instance().getColor("AgentLinkColor");
-	style_params.readonly_color = LLUIColorTable::instance().getColor("AgentLinkColor");
+	style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
+	style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
 	return style_params;
 }
 
@@ -795,6 +805,69 @@ std::string LLUrlEntryPlace::getLocation(const std::string &url) const
 	return ::getStringAfterToken(url, "://");
 }
 
+//
+// LLUrlEntryRegion Describes secondlife:///app/region/REGION_NAME/X/Y/Z URLs, e.g.
+// secondlife:///app/region/Ahern/128/128/0
+//
+LLUrlEntryRegion::LLUrlEntryRegion()
+{
+	mPattern = boost::regex("secondlife:///app/region/[^/\\s]+(/\\d+)?(/\\d+)?(/\\d+)?/?",
+							boost::regex::perl|boost::regex::icase);
+	mMenuName = "menu_url_slurl.xml";
+	mTooltip = LLTrans::getString("TooltipSLURL");
+}
+
+std::string LLUrlEntryRegion::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
+{
+	//
+	// we handle SLURLs in the following formats:
+	//   - secondlife:///app/region/Place/X/Y/Z
+	//   - secondlife:///app/region/Place/X/Y
+	//   - secondlife:///app/region/Place/X
+	//   - secondlife:///app/region/Place
+	//
+
+	LLSD path_array = LLURI(url).pathArray();
+	S32 path_parts = path_array.size();
+
+	if (path_parts < 3) // no region name
+	{
+		llwarns << "Failed to parse url [" << url << "]" << llendl;
+		return url;
+	}
+
+	std::string label = unescapeUrl(path_array[2]); // region name
+
+	if (path_parts > 3) // secondlife:///app/region/Place/X
+	{
+		std::string x = path_array[3];
+		label += " (" + x;
+
+		if (path_parts > 4) // secondlife:///app/region/Place/X/Y
+		{
+			std::string y = path_array[4];
+			label += "," + y;
+
+			if (path_parts > 5) // secondlife:///app/region/Place/X/Y/Z
+			{
+				std::string z = path_array[5];
+				label = label + "," + z;
+			}
+		}
+
+		label += ")";
+	}
+
+	return label;
+}
+
+std::string LLUrlEntryRegion::getLocation(const std::string &url) const
+{
+	LLSD path_array = LLURI(url).pathArray();
+	std::string region_name = unescapeUrl(path_array[2]);
+	return region_name;
+}
+
 //
 // LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,
 // secondlife:///app/teleport/Ahern/50/50/50/
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 1a16056041abf3113d630cb3f50c8297f6b0d151..1791739061cdae4c3cf3db6891984ef99d2eeb08 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -94,6 +94,8 @@ class LLUrlEntryBase
 
 	virtual LLUUID	getID(const std::string &string) const { return LLUUID::null; }
 
+	bool isLinkDisabled() const;
+
 protected:
 	std::string getIDStringFromUrl(const std::string &url) const;
 	std::string escapeUrl(const std::string &url) const;
@@ -299,6 +301,18 @@ class LLUrlEntryPlace : public LLUrlEntryBase
 	/*virtual*/ std::string getLocation(const std::string &url) const;
 };
 
+///
+/// LLUrlEntryRegion Describes a Second Life location Url, e.g.,
+/// secondlife:///app/region/Ahern/128/128/0
+///
+class LLUrlEntryRegion : public LLUrlEntryBase
+{
+public:
+	LLUrlEntryRegion();
+	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+	/*virtual*/ std::string getLocation(const std::string &url) const;
+};
+
 ///
 /// LLUrlEntryTeleport Describes a Second Life teleport Url, e.g.,
 /// secondlife:///app/teleport/Ahern/50/50/50/
diff --git a/indra/llui/llurlregistry.cpp b/indra/llui/llurlregistry.cpp
index 478b412d5ea541a2bbd908d9b4f3055bede59882..523ee5d78c6534c1682d4aee4f166b52c92b4bab 100644
--- a/indra/llui/llurlregistry.cpp
+++ b/indra/llui/llurlregistry.cpp
@@ -54,6 +54,7 @@ LLUrlRegistry::LLUrlRegistry()
 	registerUrl(new LLUrlEntryGroup());
 	registerUrl(new LLUrlEntryParcel());
 	registerUrl(new LLUrlEntryTeleport());
+	registerUrl(new LLUrlEntryRegion());
 	registerUrl(new LLUrlEntryWorldMap());
 	registerUrl(new LLUrlEntryObjectIM());
 	registerUrl(new LLUrlEntryPlace());
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 3fa86bf0ca519325c0ccca9ad9bdb2f02a23ca60..267640a2261fa5f10025c0e597c9782fab33205d 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -102,6 +102,7 @@ LLView::Params::Params()
 	left_pad("left_pad"),
 	left_delta("left_delta", S32_MAX),
 	from_xui("from_xui", false),
+	focus_root("focus_root", false),
 	needs_translate("translate"),
 	xmlns("xmlns"),
 	xmlns_xsi("xmlns:xsi"),
@@ -117,7 +118,7 @@ LLView::LLView(const LLView::Params& p)
 	mParentView(NULL),
 	mReshapeFlags(FOLLOWS_NONE),
 	mFromXUI(p.from_xui),
-	mIsFocusRoot(FALSE),
+	mIsFocusRoot(p.focus_root),
 	mLastVisible(FALSE),
 	mNextInsertionOrdinal(0),
 	mHoverCursor(getCursorFromString(p.hover_cursor)),
@@ -163,8 +164,6 @@ LLView::~LLView()
 
 	if (mDefaultWidgets)
 	{
-		std::for_each(mDefaultWidgets->begin(), mDefaultWidgets->end(),
-					  DeletePairedPointer());
 		delete mDefaultWidgets;
 		mDefaultWidgets = NULL;
 	}
@@ -1682,18 +1681,7 @@ BOOL LLView::hasChild(const std::string& childname, BOOL recurse) const
 //-----------------------------------------------------------------------------
 LLView* LLView::getChildView(const std::string& name, BOOL recurse) const
 {
-	LLView* child = findChildView(name, recurse);
-	if (!child)
-	{
-		child = getDefaultWidget<LLView>(name);
-		if (!child)
-		{
-			LLView::Params view_params;
-			view_params.name = name;
-			child = LLUICtrlFactory::create<LLView>(view_params);
-		}
-	}
-	return child;
+	return getChild<LLView>(name, recurse);
 }
 
 static LLFastTimer::DeclareTimer FTM_FIND_VIEWS("Find Widgets");
@@ -2804,11 +2792,14 @@ LLView::root_to_view_iterator_t LLView::endRootToView()
 
 // only create maps on demand, as they incur heap allocation/deallocation cost
 // when a view is constructed/deconstructed
-LLView::default_widget_map_t& LLView::getDefaultWidgetMap() const
+LLView& LLView::getDefaultWidgetContainer() const
 {
 	if (!mDefaultWidgets)
 	{
-		mDefaultWidgets = new default_widget_map_t();
+		LLView::Params p;
+		p.name = "default widget container";
+		p.visible = false; // ensures default widgets can't steal focus, etc.
+		mDefaultWidgets = new LLView(p);
 	}
 	return *mDefaultWidgets;
 }
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 33d345beff50bb9329fa00996e1b010c9c17889e..d2bbd663b85b3175cf44739fadfa458a511ea165 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -116,7 +116,8 @@ class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElem
 									visible,
 									mouse_opaque,
 									use_bounding_rect,
-									from_xui;
+									from_xui,
+									focus_root;
 
 		Optional<S32>				tab_group,
 									default_tab_group;
@@ -412,14 +413,9 @@ class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElem
 	
 	LLControlVariable *findControl(const std::string& name);
 
-    // Moved setValue(), getValue(), setControlValue(), setControlName(),
-    // controlListener() to LLUICtrl because an LLView is NOT assumed to
-    // contain a value. If that's what you want, use LLUICtrl instead.
-//	virtual bool	handleEvent(LLPointer<LLEvent> event, const LLSD& userdata);
-
 	const child_list_t*	getChildList() const { return &mChildList; }
-	const child_list_const_iter_t	beginChild()  { return mChildList.begin(); }
-	const child_list_const_iter_t	endChild()  { return mChildList.end(); }
+	child_list_const_iter_t	beginChild() const { return mChildList.begin(); }
+	child_list_const_iter_t	endChild() const { return mChildList.end(); }
 
 	// LLMouseHandler functions
 	//  Default behavior is to pass events to children
@@ -466,12 +462,8 @@ class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElem
 
 	template <class T> T* getDefaultWidget(const std::string& name) const
 	{
-		default_widget_map_t::const_iterator found_it = getDefaultWidgetMap().find(name);
-		if (found_it == getDefaultWidgetMap().end())
-		{
-			return NULL;
-		}
-		return dynamic_cast<T*>(found_it->second);
+		LLView* widgetp = getDefaultWidgetContainer().findChildView(name);
+		return dynamic_cast<T*>(widgetp);
 	}
 
 	//////////////////////////////////////////////
@@ -585,9 +577,9 @@ class LLView : public LLMouseHandler, public LLMortician, public LLFocusableElem
 
 	typedef std::map<std::string, LLView*> default_widget_map_t;
 	// allocate this map no demand, as it is rarely needed
-	mutable default_widget_map_t* mDefaultWidgets;
+	mutable LLView* mDefaultWidgets;
 
-	default_widget_map_t& getDefaultWidgetMap() const;
+	LLView& getDefaultWidgetContainer() const;
 
 public:
 	// Depth in view hierarchy during rendering
@@ -654,7 +646,7 @@ template <class T> T* LLView::getChild(const std::string& name, BOOL recurse) co
 				return NULL;
 			}
 
-			getDefaultWidgetMap()[name] = result;
+			getDefaultWidgetContainer().addChild(result);
 		}
 	}
 	return result;
diff --git a/indra/llui/llwindowshade.cpp b/indra/llui/llwindowshade.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..77e94385d424eedb561bf3837e1a10096bfa86eb
--- /dev/null
+++ b/indra/llui/llwindowshade.cpp
@@ -0,0 +1,328 @@
+/**
+ * @file LLWindowShade.cpp
+ * @brief Notification dialog that slides down and optionally disabled a piece of UI
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "llwindowshade.h"
+
+#include "lllayoutstack.h"
+#include "lltextbox.h"
+#include "lliconctrl.h"
+#include "llbutton.h"
+#include "llcheckboxctrl.h"
+#include "lllineeditor.h"
+
+const S32 MIN_NOTIFICATION_AREA_HEIGHT = 30;
+const S32 MAX_NOTIFICATION_AREA_HEIGHT = 100;
+
+LLWindowShade::Params::Params()
+:	bg_image("bg_image"),
+	modal("modal", false),
+	text_color("text_color"),
+	can_close("can_close", true)
+{
+	mouse_opaque = false;
+}
+
+LLWindowShade::LLWindowShade(const LLWindowShade::Params& params)
+:	LLUICtrl(params),
+	mNotification(params.notification),
+	mModal(params.modal),
+	mFormHeight(0),
+	mTextColor(params.text_color)
+{
+	setFocusRoot(true);
+}
+
+void LLWindowShade::initFromParams(const LLWindowShade::Params& params)
+{
+	LLUICtrl::initFromParams(params);
+
+	LLLayoutStack::Params layout_p;
+	layout_p.name = "notification_stack";
+	layout_p.rect = params.rect;
+	layout_p.follows.flags = FOLLOWS_ALL;
+	layout_p.mouse_opaque = false;
+	layout_p.orientation = LLLayoutStack::VERTICAL;
+	layout_p.border_size = 0;
+
+	LLLayoutStack* stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p);
+	addChild(stackp);
+
+	LLLayoutPanel::Params panel_p;
+	panel_p.rect = LLRect(0, 30, 800, 0);
+	panel_p.name = "notification_area";
+	panel_p.visible = false;
+	panel_p.user_resize = false;
+	panel_p.background_visible = true;
+	panel_p.bg_alpha_image = params.bg_image;
+	panel_p.auto_resize = false;
+	LLLayoutPanel* notification_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+	stackp->addChild(notification_panel);
+
+	panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+	panel_p.auto_resize = true;
+	panel_p.user_resize = false;
+	panel_p.rect = params.rect;
+	panel_p.name = "background_area";
+	panel_p.mouse_opaque = false;
+	panel_p.background_visible = false;
+	panel_p.bg_alpha_color = LLColor4(0.f, 0.f, 0.f, 0.2f);
+	LLLayoutPanel* dummy_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+	stackp->addChild(dummy_panel);
+
+	layout_p = LLUICtrlFactory::getDefaultParams<LLLayoutStack>();
+	layout_p.rect = LLRect(0, 30, 800, 0);
+	layout_p.follows.flags = FOLLOWS_ALL;
+	layout_p.orientation = LLLayoutStack::HORIZONTAL;
+	stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p);
+	notification_panel->addChild(stackp);
+
+	panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+	panel_p.rect.height = 30;
+	LLLayoutPanel* panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+	stackp->addChild(panel);
+
+	LLIconCtrl::Params icon_p;
+	icon_p.name = "notification_icon";
+	icon_p.rect = LLRect(5, 23, 21, 8);
+	panel->addChild(LLUICtrlFactory::create<LLIconCtrl>(icon_p));
+
+	LLTextBox::Params text_p;
+	text_p.rect = LLRect(31, 20, panel->getRect().getWidth() - 5, 0);
+	text_p.follows.flags = FOLLOWS_ALL;
+	text_p.text_color = mTextColor;
+	text_p.font = LLFontGL::getFontSansSerifSmall();
+	text_p.font.style = "BOLD";
+	text_p.name = "notification_text";
+	text_p.use_ellipses = true;
+	text_p.wrap = true;
+	panel->addChild(LLUICtrlFactory::create<LLTextBox>(text_p));
+
+	panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+	panel_p.auto_resize = false;
+	panel_p.user_resize = false;
+	panel_p.name="form_elements";
+	panel_p.rect = LLRect(0, 30, 130, 0);
+	LLLayoutPanel* form_elements_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+	stackp->addChild(form_elements_panel);
+
+	if (params.can_close)
+	{
+		panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
+		panel_p.auto_resize = false;
+		panel_p.user_resize = false;
+		panel_p.rect = LLRect(0, 30, 25, 0);
+		LLLayoutPanel* close_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
+		stackp->addChild(close_panel);
+
+		LLButton::Params button_p;
+		button_p.name = "close_notification";
+		button_p.rect = LLRect(5, 23, 21, 7);
+		button_p.image_color.control="DkGray_66";
+		button_p.image_unselected.name="Icon_Close_Foreground";
+		button_p.image_selected.name="Icon_Close_Press";
+		button_p.click_callback.function = boost::bind(&LLWindowShade::onCloseNotification, this);
+
+		close_panel->addChild(LLUICtrlFactory::create<LLButton>(button_p));
+	}
+
+	LLSD payload = mNotification->getPayload();
+
+	LLNotificationFormPtr formp = mNotification->getForm();
+	LLLayoutPanel& notification_area = getChildRef<LLLayoutPanel>("notification_area");
+	notification_area.getChild<LLUICtrl>("notification_icon")->setValue(mNotification->getIcon());
+	notification_area.getChild<LLUICtrl>("notification_text")->setValue(mNotification->getMessage());
+	notification_area.getChild<LLUICtrl>("notification_text")->setToolTip(mNotification->getMessage());
+
+	LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType(); 
+	LLLayoutPanel& form_elements = notification_area.getChildRef<LLLayoutPanel>("form_elements");
+	form_elements.deleteAllChildren();
+
+	const S32 FORM_PADDING_HORIZONTAL = 10;
+	const S32 FORM_PADDING_VERTICAL = 3;
+	const S32 WIDGET_HEIGHT = 24;
+	const S32 LINE_EDITOR_WIDTH = 120;
+	S32 cur_x = FORM_PADDING_HORIZONTAL;
+	S32 cur_y = FORM_PADDING_VERTICAL + WIDGET_HEIGHT;
+	S32 form_width = cur_x;
+
+	if (ignore_type != LLNotificationForm::IGNORE_NO)
+	{
+		LLCheckBoxCtrl::Params checkbox_p;
+		checkbox_p.name = "ignore_check";
+		checkbox_p.rect = LLRect(cur_x, cur_y, cur_x, cur_y - WIDGET_HEIGHT);
+		checkbox_p.label = formp->getIgnoreMessage();
+		checkbox_p.label_text.text_color = LLColor4::black;
+		checkbox_p.commit_callback.function = boost::bind(&LLWindowShade::onClickIgnore, this, _1);
+		checkbox_p.initial_value = formp->getIgnored();
+
+		LLCheckBoxCtrl* check = LLUICtrlFactory::create<LLCheckBoxCtrl>(checkbox_p);
+		check->setRect(check->getBoundingRect());
+		form_elements.addChild(check);
+		cur_x = check->getRect().mRight + FORM_PADDING_HORIZONTAL;
+		form_width = llmax(form_width, cur_x);
+	}
+
+	for (S32 i = 0; i < formp->getNumElements(); i++)
+	{
+		LLSD form_element = formp->getElement(i);
+		std::string type = form_element["type"].asString();
+		if (type == "button")
+		{
+			LLButton::Params button_p;
+			button_p.name = form_element["name"];
+			button_p.label = form_element["text"];
+			button_p.rect = LLRect(cur_x, cur_y, cur_x, cur_y - WIDGET_HEIGHT);
+			button_p.click_callback.function = boost::bind(&LLWindowShade::onClickNotificationButton, this, form_element["name"].asString());
+			button_p.auto_resize = true;
+
+			LLButton* button = LLUICtrlFactory::create<LLButton>(button_p);
+			button->autoResize();
+			form_elements.addChild(button);
+
+			if (form_element["default"].asBoolean())
+			{
+				form_elements.setDefaultBtn(button);
+			}
+
+			cur_x = button->getRect().mRight + FORM_PADDING_HORIZONTAL;
+			form_width = llmax(form_width, cur_x);
+		}
+		else if (type == "text" || type == "password")
+		{
+			// if not at beginning of line...
+			if (cur_x != FORM_PADDING_HORIZONTAL)
+			{
+				// start new line
+				cur_x = FORM_PADDING_HORIZONTAL;
+				cur_y -= WIDGET_HEIGHT + FORM_PADDING_VERTICAL;
+			}
+			LLTextBox::Params label_p;
+			label_p.name = form_element["name"].asString() + "_label";
+			label_p.rect = LLRect(cur_x, cur_y, cur_x + LINE_EDITOR_WIDTH, cur_y - WIDGET_HEIGHT);
+			label_p.initial_value = form_element["text"];
+			label_p.text_color = mTextColor;
+			label_p.font_valign = LLFontGL::VCENTER;
+			label_p.v_pad = 5;
+			LLTextBox* textbox = LLUICtrlFactory::create<LLTextBox>(label_p);
+			textbox->reshapeToFitText();
+			textbox->reshape(textbox->getRect().getWidth(), form_elements.getRect().getHeight() - 2 * FORM_PADDING_VERTICAL); 
+			form_elements.addChild(textbox);
+			cur_x = textbox->getRect().mRight + FORM_PADDING_HORIZONTAL;
+
+			LLLineEditor::Params line_p;
+			line_p.name = form_element["name"];
+			line_p.keystroke_callback = boost::bind(&LLWindowShade::onEnterNotificationText, this, _1, form_element["name"].asString());
+			line_p.is_password = type == "password";
+			line_p.rect = LLRect(cur_x, cur_y, cur_x + LINE_EDITOR_WIDTH, cur_y - WIDGET_HEIGHT);
+
+			LLLineEditor* line_editor = LLUICtrlFactory::create<LLLineEditor>(line_p);
+			form_elements.addChild(line_editor);
+			form_width = llmax(form_width, cur_x + LINE_EDITOR_WIDTH + FORM_PADDING_HORIZONTAL);
+
+			// reset to start of next line
+			cur_x = FORM_PADDING_HORIZONTAL;
+			cur_y -= WIDGET_HEIGHT + FORM_PADDING_VERTICAL;
+		}
+	}
+
+	mFormHeight = form_elements.getRect().getHeight() - (cur_y - FORM_PADDING_VERTICAL) + WIDGET_HEIGHT;
+	form_elements.reshape(form_width, mFormHeight);
+	form_elements.setMinDim(form_width);
+
+	// move all form elements back onto form surface
+	S32 delta_y = WIDGET_HEIGHT + FORM_PADDING_VERTICAL - cur_y;
+	for (child_list_const_iter_t it = form_elements.getChildList()->begin(), end_it = form_elements.getChildList()->end();
+		it != end_it;
+		++it)
+	{
+		(*it)->translate(0, delta_y);
+	}
+}
+
+void LLWindowShade::show()
+{
+	getChildRef<LLLayoutPanel>("notification_area").setVisible(true);
+	getChildRef<LLLayoutPanel>("background_area").setBackgroundVisible(mModal);
+
+	setMouseOpaque(mModal);
+}
+
+void LLWindowShade::draw()
+{
+	LLRect message_rect = getChild<LLTextBox>("notification_text")->getTextBoundingRect();
+
+	LLLayoutPanel* notification_area = getChild<LLLayoutPanel>("notification_area");
+
+	notification_area->reshape(notification_area->getRect().getWidth(), 
+		llclamp(message_rect.getHeight() + 10, 
+				llmin(mFormHeight, MAX_NOTIFICATION_AREA_HEIGHT),
+				MAX_NOTIFICATION_AREA_HEIGHT));
+
+	LLUICtrl::draw();
+	if (mNotification && !mNotification->isActive())
+	{
+		hide();
+	}
+}
+
+void LLWindowShade::hide()
+{
+	getChildRef<LLLayoutPanel>("notification_area").setVisible(false);
+	getChildRef<LLLayoutPanel>("background_area").setBackgroundVisible(false);
+
+	setMouseOpaque(false);
+}
+
+void LLWindowShade::onCloseNotification()
+{
+	LLNotifications::instance().cancel(mNotification);
+}
+
+void LLWindowShade::onClickIgnore(LLUICtrl* ctrl)
+{
+	bool check = ctrl->getValue().asBoolean();
+	if (mNotification && mNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
+	{
+		// question was "show again" so invert value to get "ignore"
+		check = !check;
+	}
+	mNotification->setIgnored(check);
+}
+
+void LLWindowShade::onClickNotificationButton(const std::string& name)
+{
+	if (!mNotification) return;
+
+	mNotificationResponse[name] = true;
+
+	mNotification->respond(mNotificationResponse);
+}
+
+void LLWindowShade::onEnterNotificationText(LLUICtrl* ctrl, const std::string& name)
+{
+	mNotificationResponse[name] = ctrl->getValue().asString();
+}
diff --git a/indra/llui/llwindowshade.h b/indra/llui/llwindowshade.h
new file mode 100644
index 0000000000000000000000000000000000000000..00471959296dd0429d0f500f5911e6d9b28756ff
--- /dev/null
+++ b/indra/llui/llwindowshade.h
@@ -0,0 +1,69 @@
+/**
+ * @file llwindowshade.h
+ * @brief Notification dialog that slides down and optionally disabled a piece of UI
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLWINDOWSHADE_H
+#define LL_LLWINDOWSHADE_H
+
+#include "lluictrl.h"
+#include "llnotifications.h"
+
+class LLWindowShade : public LLUICtrl
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
+	{
+		Mandatory<LLNotificationPtr>	notification;
+		Optional<LLUIImage*>			bg_image;
+		Optional<LLUIColor>				text_color;
+		Optional<bool>					modal,
+										can_close;
+
+		Params();
+	};
+
+	void show();
+	/*virtual*/ void draw();
+	void hide();
+
+private:
+	friend class LLUICtrlFactory;
+
+	LLWindowShade(const Params& p);
+	void initFromParams(const Params& params);
+
+	void onCloseNotification();
+	void onClickNotificationButton(const std::string& name);
+	void onEnterNotificationText(LLUICtrl* ctrl, const std::string& name);
+	void onClickIgnore(LLUICtrl* ctrl);
+
+	LLNotificationPtr	mNotification;
+	LLSD				mNotificationResponse;
+	bool				mModal;
+	S32					mFormHeight;
+	LLUIColor			mTextColor;
+};
+
+#endif // LL_LLWINDOWSHADE_H
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 5c6623da6105e583a0fdff7276c26c4fd295b350..8f0a48018fb26132f0ca1b5257a1110850dce4d3 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -27,6 +27,7 @@
 
 #include "linden_common.h"
 #include "../llurlentry.h"
+#include "../lluictrl.h"
 #include "llurlentry_stub.cpp"
 #include "lltut.h"
 #include "../lluicolortable.h"
@@ -34,6 +35,14 @@
 
 #include <boost/regex.hpp>
 
+typedef std::map<std::string, LLControlGroup*> settings_map_t;
+settings_map_t LLUI::sSettingGroups;
+
+BOOL LLControlGroup::getBOOL(const std::string& name)
+{
+	return false;
+}
+
 LLUIColor LLUIColorTable::getColor(const std::string& name, const LLColor4& default_color) const
 {
 	return LLUIColor();
@@ -94,6 +103,45 @@ namespace tut
 		ensure_equals(testname, url, expected);
 	}
 
+	void dummyCallback(const std::string &url, const std::string &label, const std::string& icon)
+	{
+	}
+
+	void testLabel(const std::string &testname, LLUrlEntryBase &entry,
+				   const char *text, const std::string &expected)
+	{
+		boost::regex regex = entry.getPattern();
+		std::string label = "";
+		boost::cmatch result;
+		bool found = boost::regex_search(text, result, regex);
+		if (found)
+		{
+			S32 start = static_cast<U32>(result[0].first - text);
+			S32 end = static_cast<U32>(result[0].second - text);
+			std::string url = std::string(text+start, end-start);
+			label = entry.getLabel(url, boost::bind(dummyCallback, _1, _2, _3));
+		}
+		ensure_equals(testname, label, expected);
+	}
+
+	void testLocation(const std::string &testname, LLUrlEntryBase &entry,
+					  const char *text, const std::string &expected)
+	{
+		boost::regex regex = entry.getPattern();
+		std::string location = "";
+		boost::cmatch result;
+		bool found = boost::regex_search(text, result, regex);
+		if (found)
+		{
+			S32 start = static_cast<U32>(result[0].first - text);
+			S32 end = static_cast<U32>(result[0].second - text);
+			std::string url = std::string(text+start, end-start);
+			location = entry.getLocation(url);
+		}
+		ensure_equals(testname, location, expected);
+	}
+
+
 	template<> template<>
 	void object::test<1>()
 	{
@@ -688,4 +736,114 @@ namespace tut
 				  "<nolink>My Object</nolink>",
 				  "My Object");
 	}
+
+	template<> template<>
+	void object::test<13>()
+	{
+		//
+		// test LLUrlEntryRegion - secondlife:///app/region/<location> URLs
+		//
+		LLUrlEntryRegion url;
+
+		// Regex tests.
+		testRegex("no valid region", url,
+				  "secondlife:///app/region/",
+				  "");
+
+		testRegex("invalid coords", url,
+				  "secondlife:///app/region/Korea2/a/b/c",
+				  "secondlife:///app/region/Korea2/"); // don't count invalid coords
+
+		testRegex("Ahern (50,50,50) [1]", url,
+				  "secondlife:///app/region/Ahern/50/50/50/",
+				  "secondlife:///app/region/Ahern/50/50/50/");
+
+		testRegex("Ahern (50,50,50) [2]", url,
+				  "XXX secondlife:///app/region/Ahern/50/50/50/ XXX",
+				  "secondlife:///app/region/Ahern/50/50/50/");
+
+		testRegex("Ahern (50,50,50) [3]", url,
+				  "XXX secondlife:///app/region/Ahern/50/50/50 XXX",
+				  "secondlife:///app/region/Ahern/50/50/50");
+
+		testRegex("Ahern (50,50,50) multicase", url,
+				  "XXX secondlife:///app/region/Ahern/50/50/50/ XXX",
+				  "secondlife:///app/region/Ahern/50/50/50/");
+
+		testRegex("Ahern (50,50) [1]", url,
+				  "XXX secondlife:///app/region/Ahern/50/50/ XXX",
+				  "secondlife:///app/region/Ahern/50/50/");
+
+		testRegex("Ahern (50,50) [2]", url,
+				  "XXX secondlife:///app/region/Ahern/50/50 XXX",
+				  "secondlife:///app/region/Ahern/50/50");
+
+		// DEV-21577: In-world SLURLs containing "(" or ")" are not treated as a hyperlink in chat
+		testRegex("Region with brackets", url,
+				  "XXX secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30 XXX",
+				  "secondlife:///app/region/Burning%20Life%20(Hyper)/27/210/30");
+
+		// DEV-35459: SLURLs and teleport Links not parsed properly
+		testRegex("Region with quote", url,
+				  "XXX secondlife:///app/region/A'ksha%20Oasis/41/166/701 XXX",
+			          "secondlife:///app/region/A%27ksha%20Oasis/41/166/701");
+
+		// Rendering tests.
+		testLabel("Render /app/region/Ahern/50/50/50/", url,
+			"secondlife:///app/region/Ahern/50/50/50/",
+			"Ahern (50,50,50)");
+
+		testLabel("Render /app/region/Ahern/50/50/50", url,
+			"secondlife:///app/region/Ahern/50/50/50",
+			"Ahern (50,50,50)");
+
+		testLabel("Render /app/region/Ahern/50/50/", url,
+			"secondlife:///app/region/Ahern/50/50/",
+			"Ahern (50,50)");
+
+		testLabel("Render /app/region/Ahern/50/50", url,
+			"secondlife:///app/region/Ahern/50/50",
+			"Ahern (50,50)");
+
+		testLabel("Render /app/region/Ahern/50/", url,
+			"secondlife:///app/region/Ahern/50/",
+			"Ahern (50)");
+
+		testLabel("Render /app/region/Ahern/50", url,
+			"secondlife:///app/region/Ahern/50",
+			"Ahern (50)");
+
+		testLabel("Render /app/region/Ahern/", url,
+			"secondlife:///app/region/Ahern/",
+			"Ahern");
+
+		testLabel("Render /app/region/Ahern/ within context", url,
+			"XXX secondlife:///app/region/Ahern/ XXX",
+			"Ahern");
+
+		testLabel("Render /app/region/Ahern", url,
+			"secondlife:///app/region/Ahern",
+			"Ahern");
+
+		testLabel("Render /app/region/Ahern within context", url,
+			"XXX secondlife:///app/region/Ahern XXX",
+			"Ahern");
+
+		testLabel("Render /app/region/Product%20Engine/", url,
+			"secondlife:///app/region/Product%20Engine/",
+			"Product Engine");
+
+		testLabel("Render /app/region/Product%20Engine", url,
+			"secondlife:///app/region/Product%20Engine",
+			"Product Engine");
+
+		// Location parsing texts.
+		testLocation("Location /app/region/Ahern/50/50/50/", url,
+			"secondlife:///app/region/Ahern/50/50/50/",
+			"Ahern");
+
+		testLocation("Location /app/region/Product%20Engine", url,
+			"secondlife:///app/region/Product%20Engine",
+			"Product Engine");
+	}
 }
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 938fb008c9900c8497accdb976c570a5ee34d64e..64556bcb4c34dcacd2b48f391dbfebf0eb528421 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -83,7 +83,7 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
 	std::string filename; 
 	std::string fullpath;
 	S32 result;
-	while (getNextFileInDir(dirname, mask, filename, FALSE))
+	while (getNextFileInDir(dirname, mask, filename))
 	{
 		fullpath = dirname;
 		fullpath += getDirDelimiter();
@@ -382,11 +382,7 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
 		break;
 
 	case LL_PATH_USER_SKIN:
-		prefix = getOSUserAppDir();
-		prefix += mDirDelimiter;
-		prefix += "user_settings";
-		prefix += mDirDelimiter;
-		prefix += "skins";
+		prefix = getUserSkinDir();
 		break;
 
 	case LL_PATH_SKINS:
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 4f63c04aabefa6876ad8846417ff97fc873c603f..42996fd051b9f5cc8ed949645fa7fda5c4c58f74 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -74,8 +74,32 @@ class LLDir
 
 // pure virtual functions
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 0;
-	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap) = 0;
-	virtual void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname) = 0;
+
+    /// Walk the files in a directory, with file pattern matching
+	virtual BOOL getNextFileInDir(const std::string& dirname, ///< directory path - must end in trailing slash!
+                                  const std::string& mask,    ///< file pattern string (use "*" for all)
+                                  std::string& fname          ///< output: found file name
+                                  ) = 0;
+    /**<
+     * @returns true if a file was found, false if the entire directory has been scanned.
+     *
+     * @note that this function is NOT thread safe
+     *
+     * This function may not be used to scan part of a directory, then start a new search of a different
+     * directory, and then restart the first search where it left off; the entire search must run to
+     * completion or be abandoned - there is no restart.
+     *
+     * @bug: See http://jira.secondlife.com/browse/VWR-23697
+     *       and/or the tests in test/lldir_test.cpp
+     *       This is known to fail with patterns that have both:
+     *       a wildcard left of a . and more than one sequential ? right of a .
+     *       the pattern foo.??x appears to work
+     *       but *.??x or foo?.??x do not
+     *
+     * @todo this really should be rewritten as an iterator object, and the
+     *       filtering should be done in a platform-independent way.
+     */
+
 	virtual std::string getCurPath() = 0;
 	virtual BOOL fileExists(const std::string &filename) const = 0;
 
diff --git a/indra/llvfs/lldir_linux.cpp b/indra/llvfs/lldir_linux.cpp
index a1c6669b974952ea329b9e1dcbb9abd2da09f27b..73f2336f94fa70bf2d43bc6b924ed6262b7bd2e8 100644
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -243,8 +243,7 @@ U32 LLDir_Linux::countFilesInDir(const std::string &dirname, const std::string &
 }
 
 // get the next file in the directory
-// automatically wrap if we've hit the end
-BOOL LLDir_Linux::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
+BOOL LLDir_Linux::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
 {
 	glob_t g;
 	BOOL result = FALSE;
@@ -276,11 +275,6 @@ BOOL LLDir_Linux::getNextFileInDir(const std::string &dirname, const std::string
 	
 			mCurrentDirIndex++;
 	
-			if((mCurrentDirIndex >= (int)g.gl_pathc) && wrap)
-			{
-				mCurrentDirIndex = 0;
-			}
-			
 			if(mCurrentDirIndex < (int)g.gl_pathc)
 			{
 //				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
@@ -308,47 +302,7 @@ BOOL LLDir_Linux::getNextFileInDir(const std::string &dirname, const std::string
 }
 
 
-// get a random file in the directory
-// automatically wrap if we've hit the end
-void LLDir_Linux::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
-{
-	S32 num_files;
-	S32 which_file;
-	DIR *dirp;
-	dirent *entryp = NULL;
-
-	fname = "";
 
-	num_files = countFilesInDir(dirname,mask);
-	if (!num_files)
-	{
-		return;
-	}
-
-	which_file = ll_rand(num_files);
-
-//	llinfos << "Random select file #" << which_file << llendl;
-
-    // which_file now indicates the (zero-based) index to which file to play
-	
-	if (!((dirp = opendir(dirname.c_str()))))
-	{
-		while (which_file--)
-		{
-			if (!((entryp = readdir(dirp))))
-			{
-				return;
-			}
-		}		   
-
-		if ((!which_file) && entryp)
-		{
-			fname = entryp->d_name;
-		}
-		
-		closedir(dirp);
-	}
-}
 
 std::string LLDir_Linux::getCurPath()
 {
diff --git a/indra/llvfs/lldir_linux.h b/indra/llvfs/lldir_linux.h
index 809959e873f74e3c4fa071dd70b017f21df3c793..451e81ae93c560114b83f556120f3fd42f6dbec9 100644
--- a/indra/llvfs/lldir_linux.h
+++ b/indra/llvfs/lldir_linux.h
@@ -43,8 +43,7 @@ class LLDir_Linux : public LLDir
 public:	
 	virtual std::string getCurPath();
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
-	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap);
-	virtual void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
+	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
 	/*virtual*/ BOOL fileExists(const std::string &filename) const;
 
 	/*virtual*/ std::string getLLPluginLauncher();
diff --git a/indra/llvfs/lldir_mac.cpp b/indra/llvfs/lldir_mac.cpp
index b41b0ec5dd953d0db00d831cc16db24801682e90..445285aa43ac2c5dae2c11187e73280dc88614db 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -259,8 +259,7 @@ U32 LLDir_Mac::countFilesInDir(const std::string &dirname, const std::string &ma
 }
 
 // get the next file in the directory
-// automatically wrap if we've hit the end
-BOOL LLDir_Mac::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
+BOOL LLDir_Mac::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
 {
 	glob_t g;
 	BOOL result = FALSE;
@@ -292,11 +291,6 @@ BOOL LLDir_Mac::getNextFileInDir(const std::string &dirname, const std::string &
 	
 			mCurrentDirIndex++;
 	
-			if((mCurrentDirIndex >= g.gl_pathc) && wrap)
-			{
-				mCurrentDirIndex = 0;
-			}
-			
 			if(mCurrentDirIndex < g.gl_pathc)
 			{
 //				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
@@ -323,41 +317,7 @@ BOOL LLDir_Mac::getNextFileInDir(const std::string &dirname, const std::string &
 	return(result);
 }
 
-// get a random file in the directory
-void LLDir_Mac::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
-{
-	S32 which_file;
-	glob_t g;
-	fname = "";
-	
-	std::string tmp_str;
-	tmp_str = dirname;
-	tmp_str += mask;
-	
-	if(glob(tmp_str.c_str(), GLOB_NOSORT, NULL, &g) == 0)
-	{
-		if(g.gl_pathc > 0)
-		{
-			
-			which_file = ll_rand(g.gl_pathc);
-	
-//			llinfos << "getRandomFileInDir: returning number " << which_file << ", path is " << g.gl_pathv[which_file] << llendl;
-			// The API wants just the filename, not the full path.
-			//fname = g.gl_pathv[which_file];
 
-			char *s = strrchr(g.gl_pathv[which_file], '/');
-			
-			if(s == NULL)
-				s = g.gl_pathv[which_file];
-			else if(s[0] == '/')
-				s++;
-				
-			fname = s;
-		}
-		
-		globfree(&g);
-	}
-}
 
 S32 LLDir_Mac::deleteFilesInDir(const std::string &dirname, const std::string &mask)
 {
diff --git a/indra/llvfs/lldir_mac.h b/indra/llvfs/lldir_mac.h
index 04c52dc9401c19f25902b4ed795ab6984afe7f6d..4eac3c3ae6fce824624bc7c048b8922c6c86e517 100644
--- a/indra/llvfs/lldir_mac.h
+++ b/indra/llvfs/lldir_mac.h
@@ -43,8 +43,7 @@ class LLDir_Mac : public LLDir
 	virtual S32 deleteFilesInDir(const std::string &dirname, const std::string &mask);
 	virtual std::string getCurPath();
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
-	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap);
-	virtual void getRandomFileInDir(const std::string &dirname, const std::string &ask, std::string &fname);
+	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
 	virtual BOOL fileExists(const std::string &filename) const;
 
 	/*virtual*/ std::string getLLPluginLauncher();
diff --git a/indra/llvfs/lldir_solaris.cpp b/indra/llvfs/lldir_solaris.cpp
index 4323dfd44ac0c705401f8e9b28b1781dda0e7be8..515fd66b6e9a9f4d2aef1647ad78134a15419f0c 100644
--- a/indra/llvfs/lldir_solaris.cpp
+++ b/indra/llvfs/lldir_solaris.cpp
@@ -261,8 +261,7 @@ U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string
 }
 
 // get the next file in the directory
-// automatically wrap if we've hit the end
-BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
+BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
 {
 	glob_t g;
 	BOOL result = FALSE;
@@ -294,11 +293,6 @@ BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::stri
 	
 			mCurrentDirIndex++;
 	
-			if((mCurrentDirIndex >= (int)g.gl_pathc) && wrap)
-			{
-				mCurrentDirIndex = 0;
-			}
-			
 			if(mCurrentDirIndex < (int)g.gl_pathc)
 			{
 //				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
@@ -326,47 +320,7 @@ BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::stri
 }
 
 
-// get a random file in the directory
-// automatically wrap if we've hit the end
-void LLDir_Solaris::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
-{
-	S32 num_files;
-	S32 which_file;
-	DIR *dirp;
-	dirent *entryp = NULL;
-
-	fname = "";
-
-	num_files = countFilesInDir(dirname,mask);
-	if (!num_files)
-	{
-		return;
-	}
-
-	which_file = ll_rand(num_files);
-
-//	llinfos << "Random select file #" << which_file << llendl;
 
-    // which_file now indicates the (zero-based) index to which file to play
-	
-	if (!((dirp = opendir(dirname.c_str()))))
-	{
-		while (which_file--)
-		{
-			if (!((entryp = readdir(dirp))))
-			{
-				return;
-			}
-		}		   
-
-		if ((!which_file) && entryp)
-		{
-			fname = entryp->d_name;
-		}
-		
-		closedir(dirp);
-	}
-}
 
 std::string LLDir_Solaris::getCurPath()
 {
diff --git a/indra/llvfs/lldir_solaris.h b/indra/llvfs/lldir_solaris.h
index 6e0c5cfc69015bc47e70d7135cadbd25cb4fb25a..4a1794f53950dab8f147dae3c4bc9cfe4e3b1088 100644
--- a/indra/llvfs/lldir_solaris.h
+++ b/indra/llvfs/lldir_solaris.h
@@ -43,8 +43,7 @@ class LLDir_Solaris : public LLDir
 public:	
 	virtual std::string getCurPath();
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask);
-	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap);
-	virtual void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
+	virtual BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
 	/*virtual*/ BOOL fileExists(const std::string &filename) const;
 
 private:
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 52d864e26f2cee313dbb98e6c3e0af98b9b1d614..33718e520d71b4c3e2595574187c22d0224c0ce7 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -206,14 +206,6 @@ void LLDir_Win32::initAppDirs(const std::string &app_name,
 		}
 	}
 	
-	res = LLFile::mkdir(getExpandedFilename(LL_PATH_USER_SKIN,""));
-	if (res == -1)
-	{
-		if (errno != EEXIST)
-		{
-			llwarns << "Couldn't create LL_PATH_SKINS dir " << getExpandedFilename(LL_PATH_USER_SKIN,"") << llendl;
-		}
-	}
 	mCAFile = getExpandedFilename(LL_PATH_APP_SETTINGS, "CA.pem");
 }
 
@@ -246,21 +238,13 @@ U32 LLDir_Win32::countFilesInDir(const std::string &dirname, const std::string &
 
 
 // get the next file in the directory
-// automatically wrap if we've hit the end
-BOOL LLDir_Win32::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
+BOOL LLDir_Win32::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
 {
-	llutf16string dirnamew = utf8str_to_utf16str(dirname);
-	return getNextFileInDir(dirnamew, mask, fname, wrap);
-
-}
+    BOOL fileFound = FALSE;
+	fname = "";
 
-BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname, BOOL wrap)
-{
 	WIN32_FIND_DATAW FileData;
-
-	fname = "";
-	llutf16string pathname = dirname;
-	pathname += utf8str_to_utf16str(mask);
+    llutf16string pathname = utf8str_to_utf16str(dirname) + utf8str_to_utf16str(mask);
 
 	if (pathname != mCurrentDir)
 	{
@@ -273,91 +257,44 @@ BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::stri
 
 		// and open new one
 		// Check error opening Directory structure
-		if ((mDirSearch_h = FindFirstFile(pathname.c_str(), &FileData)) == INVALID_HANDLE_VALUE)   
-		{
-//			llinfos << "Unable to locate first file" << llendl;
-			return(FALSE);
-		}
-	}
-	else // get next file in list
-	{
-		// Find next entry
-		if (!FindNextFile(mDirSearch_h, &FileData))
+		if ((mDirSearch_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE)   
 		{
-			if (GetLastError() == ERROR_NO_MORE_FILES)
-			{
-                // No more files, so reset to beginning of directory
-				FindClose(mDirSearch_h);
-				mCurrentDir[0] = NULL;
-
-				if (wrap)
-				{
-					return(getNextFileInDir(pathname,"",fname,TRUE));
-				}
-				else
-				{
-					fname[0] = 0;
-					return(FALSE);
-				}
-			}
-			else
-			{
-				// Error
-//				llinfos << "Unable to locate next file" << llendl;
-				return(FALSE);
-			}
+           fileFound = TRUE;
 		}
 	}
 
-	// convert from TCHAR to char
-	fname = utf16str_to_utf8str(FileData.cFileName);
-	
-	// fname now first name in list
-	return(TRUE);
-}
-
-
-// get a random file in the directory
-// automatically wrap if we've hit the end
-void LLDir_Win32::getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
-{
-	S32 num_files;
-	S32 which_file;
-	HANDLE random_search_h;
-
-	fname = "";
-
-	llutf16string pathname = utf8str_to_utf16str(dirname);
-	pathname += utf8str_to_utf16str(mask);
-
-	WIN32_FIND_DATA FileData;
-	fname[0] = NULL;
-
-	num_files = countFilesInDir(dirname,mask);
-	if (!num_files)
-	{
-		return;
-	}
-
-	which_file = ll_rand(num_files);
-
-//	llinfos << "Random select mp3 #" << which_file << llendl;
-
-    // which_file now indicates the (zero-based) index to which file to play
+    // Loop to skip over the current (.) and parent (..) directory entries
+    // (apparently returned in Win7 but not XP)
+    do
+    {
+       if (   fileFound
+           && (  (lstrcmp(FileData.cFileName, (LPCTSTR)TEXT(".")) == 0)
+               ||(lstrcmp(FileData.cFileName, (LPCTSTR)TEXT("..")) == 0)
+               )
+           )
+       {
+          fileFound = FALSE;
+       }
+    } while (   mDirSearch_h != INVALID_HANDLE_VALUE
+             && !fileFound
+             && (fileFound = FindNextFile(mDirSearch_h, &FileData)
+                 )
+             );
+
+    if (!fileFound && GetLastError() == ERROR_NO_MORE_FILES)
+    {
+       // No more files, so reset to beginning of directory
+       FindClose(mDirSearch_h);
+       mCurrentDir[0] = '\000';
+    }
 
-	if ((random_search_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE)   
-	{
-		while (which_file--)
-		{
-			if (!FindNextFile(random_search_h, &FileData))
-			{
-				return;
-			}
-		}		   
-		FindClose(random_search_h);
-
-		fname = utf16str_to_utf8str(llutf16string(FileData.cFileName));
+    if (fileFound)
+    {
+        // convert from TCHAR to char
+        fname = utf16str_to_utf8str(FileData.cFileName);
 	}
+    
+	return fileFound;
 }
 
 std::string LLDir_Win32::getCurPath()
diff --git a/indra/llvfs/lldir_win32.h b/indra/llvfs/lldir_win32.h
index d3e45dc1f37834a7b4d18841f0abdb237f657fff..4c932c932c8f06d6015c106f2b2cd8c9bd50e7f6 100644
--- a/indra/llvfs/lldir_win32.h
+++ b/indra/llvfs/lldir_win32.h
@@ -40,15 +40,14 @@ class LLDir_Win32 : public LLDir
 
 	/*virtual*/ std::string getCurPath();
 	/*virtual*/ U32 countFilesInDir(const std::string &dirname, const std::string &mask);
-	/*virtual*/ BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname, BOOL wrap);
-	/*virtual*/ void getRandomFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
+	/*virtual*/ BOOL getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname);
 	/*virtual*/ BOOL fileExists(const std::string &filename) const;
 
 	/*virtual*/ std::string getLLPluginLauncher();
 	/*virtual*/ std::string getLLPluginFilename(std::string base_name);
 
 private:
-	BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname, BOOL wrap);
+	BOOL LLDir_Win32::getNextFileInDir(const llutf16string &dirname, const std::string &mask, std::string &fname);
 	
 	void* mDirSearch_h;
 	llutf16string mCurrentDir;
diff --git a/indra/llvfs/tests/lldir_test.cpp b/indra/llvfs/tests/lldir_test.cpp
index bcffa449c86ea1f2ea1ae878d0f13602cd77beb1..8788bd63e87d2b8030324ffcd0e0434057844151 100644
--- a/indra/llvfs/tests/lldir_test.cpp
+++ b/indra/llvfs/tests/lldir_test.cpp
@@ -256,5 +256,160 @@ namespace tut
 			      gDirUtilp->getExtension(dottedPathExt),
 			      "ext");
 	}
+
+   std::string makeTestFile( const std::string& dir, const std::string& file )
+   {
+      std::string delim = gDirUtilp->getDirDelimiter();
+      std::string path = dir + delim + file;
+      LLFILE* handle = LLFile::fopen( path, "w" );
+      ensure("failed to open test file '"+path+"'", handle != NULL );
+      // Harbison & Steele, 4th ed., p. 366: "If an error occurs, fputs
+      // returns EOF; otherwise, it returns some other, nonnegative value."
+      ensure("failed to write to test file '"+path+"'", fputs("test file", handle) >= 0);
+      fclose(handle);
+      return path;
+   }
+
+   std::string makeTestDir( const std::string& dirbase )
+   {
+      int counter;
+      std::string uniqueDir;
+      bool foundUnused;
+      std::string delim = gDirUtilp->getDirDelimiter();
+      
+      for (counter=0, foundUnused=false; !foundUnused; counter++ )
+      {
+         char counterStr[3];
+         sprintf(counterStr, "%02d", counter);
+         uniqueDir = dirbase + counterStr;
+         foundUnused = ! ( LLFile::isdir(uniqueDir) || LLFile::isfile(uniqueDir) );
+      }
+      ensure("test directory '" + uniqueDir + "' creation failed", !LLFile::mkdir(uniqueDir));
+      
+      return uniqueDir + delim; // HACK - apparently, the trailing delimiter is needed...
+   }
+
+   static const char* DirScanFilename[5] = { "file1.abc", "file2.abc", "file1.xyz", "file2.xyz", "file1.mno" };
+   
+   void scanTest(const std::string& directory, const std::string& pattern, bool correctResult[5])
+   {
+
+      // Scan directory and see if any file1.* files are found
+      std::string scanResult;
+      int   found = 0;
+      bool  filesFound[5] = { false, false, false, false, false };
+      //std::cerr << "searching '"+directory+"' for '"+pattern+"'\n";
+
+      while ( found <= 5 && gDirUtilp->getNextFileInDir(directory, pattern, scanResult) )
+      {
+         found++;
+         //std::cerr << "  found '"+scanResult+"'\n";
+         int check;
+         for (check=0; check < 5 && ! ( scanResult == DirScanFilename[check] ); check++)
+         {
+         }
+         // check is now either 5 (not found) or the index of the matching name
+         if (check < 5)
+         {
+            ensure( "found file '"+(std::string)DirScanFilename[check]+"' twice", ! filesFound[check] );
+            filesFound[check] = true;
+         }
+         else // check is 5 - should not happen
+         {
+            fail( "found unknown file '"+scanResult+"'");
+         }
+      }
+      for (int i=0; i<5; i++)
+      {
+         if (correctResult[i])
+         {
+            ensure("scan of '"+directory+"' using '"+pattern+"' did not return '"+DirScanFilename[i]+"'", filesFound[i]);
+         }
+         else
+         {
+            ensure("scan of '"+directory+"' using '"+pattern+"' incorrectly returned '"+DirScanFilename[i]+"'", !filesFound[i]);
+         }
+      }
+   }
+   
+   template<> template<>
+   void LLDirTest_object_t::test<5>()
+      // getNextFileInDir
+   {
+      std::string delim = gDirUtilp->getDirDelimiter();
+      std::string dirTemp = LLFile::tmpdir();
+
+      // Create the same 5 file names of the two directories
+
+      std::string dir1 = makeTestDir(dirTemp + "getNextFileInDir");
+      std::string dir2 = makeTestDir(dirTemp + "getNextFileInDir");
+      std::string dir1files[5];
+      std::string dir2files[5];
+      for (int i=0; i<5; i++)
+      {
+         dir1files[i] = makeTestFile(dir1, DirScanFilename[i]);
+         dir2files[i] = makeTestFile(dir2, DirScanFilename[i]);
+      }
+
+      // Scan dir1 and see if each of the 5 files is found exactly once
+      bool expected1[5] = { true, true, true, true, true };
+      scanTest(dir1, "*", expected1);
+
+      // Scan dir2 and see if only the 2 *.xyz files are found
+      bool  expected2[5] = { false, false, true, true, false };
+      scanTest(dir1, "*.xyz", expected2);
+
+      // Scan dir2 and see if only the 1 *.mno file is found
+      bool  expected3[5] = { false, false, false, false, true };
+      scanTest(dir2, "*.mno", expected3);
+
+      // Scan dir1 and see if any *.foo files are found
+      bool  expected4[5] = { false, false, false, false, false };
+      scanTest(dir1, "*.foo", expected4);
+
+      // Scan dir1 and see if any file1.* files are found
+      bool  expected5[5] = { true, false, true, false, true };
+      scanTest(dir1, "file1.*", expected5);
+
+      // Scan dir1 and see if any file1.* files are found
+      bool  expected6[5] = { true, true, false, false, false };
+      scanTest(dir1, "file?.abc", expected6);
+
+      // Scan dir2 and see if any file?.x?z files are found
+      bool  expected7[5] = { false, false, true, true, false };
+      scanTest(dir2, "file?.x?z", expected7);
+
+      // Scan dir2 and see if any file?.??c files are found
+      // THESE FAIL ON Mac and Windows, SO ARE COMMENTED OUT FOR NOW
+      //      bool  expected8[5] = { true, true, false, false, false };
+      //      scanTest(dir2, "file?.??c", expected8);
+      //      scanTest(dir2, "*.??c", expected8);
+
+      // Scan dir1 and see if any *.?n? files are found
+      bool  expected9[5] = { false, false, false, false, true };
+      scanTest(dir1, "*.?n?", expected9);
+
+      // Scan dir1 and see if any *.???? files are found
+      // THIS ONE FAILS ON WINDOWS (returns three charater suffixes) SO IS COMMENTED OUT FOR NOW
+      // bool  expected10[5] = { false, false, false, false, false };
+      // scanTest(dir1, "*.????", expected10);
+
+      // Scan dir1 and see if any ?????.* files are found
+      bool  expected11[5] = { true, true, true, true, true };
+      scanTest(dir1, "?????.*", expected11);
+
+      // Scan dir1 and see if any ??l??.xyz files are found
+      bool  expected12[5] = { false, false, true, true, false };
+      scanTest(dir1, "??l??.xyz", expected12);
+
+      // clean up all test files and directories
+      for (int i=0; i<5; i++)
+      {
+         LLFile::remove(dir1files[i]);
+         LLFile::remove(dir2files[i]);
+      }
+      LLFile::rmdir(dir1);
+      LLFile::rmdir(dir2);
+   }
 }
 
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index bf3233f3862635f5872d7b12ba30b6bd45bc2362..4d2677fd91f062a2ea049ceefe7f22bb43c2ba45 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -59,12 +59,13 @@ set(viewer_HEADER_FILES
 
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
-if (NOT LINUX OR VIEWER)
+if (LINUX AND VIEWER)
   set(llwindow_LINK_LIBRARIES
       ${UI_LIBRARIES}     # for GTK
       ${SDL_LIBRARY}
+      fontconfig          # For FCInit and other FC* functions.
       )
-endif (NOT LINUX OR VIEWER)
+endif (LINUX AND VIEWER)
 
 if (DARWIN)
   list(APPEND llwindow_SOURCE_FILES
diff --git a/indra/llwindow/llkeyboard.h b/indra/llwindow/llkeyboard.h
index be16f31abc47bbcdd4277f777f7cde3719973dc9..ba472cfde5633c1ad80fc95273acc761c91981f2 100644
--- a/indra/llwindow/llkeyboard.h
+++ b/indra/llwindow/llkeyboard.h
@@ -40,7 +40,7 @@ enum EKeystate
 	KEYSTATE_UP 
 };
 
-typedef void (*LLKeyFunc)(EKeystate keystate);
+typedef boost::function<void(EKeystate keystate)> LLKeyFunc;
 typedef std::string (LLKeyStringTranslatorFunc)(const char *label);
 	
 enum EKeyboardInsertMode
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 87075c7318ebbe4f9651dcea309a26bb1874aada..ab089081e6f147313b6022ab74662dcc20c1472b 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -544,7 +544,27 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
 		if (closest_refresh == 0)
 		{
 			LL_WARNS("Window") << "Couldn't find display mode " << width << " by " << height << " at " << BITS_PER_PIXEL << " bits per pixel" << LL_ENDL;
-			success = FALSE;
+			//success = FALSE;
+
+			if (!EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &dev_mode))
+			{
+				success = FALSE;
+			}
+			else
+			{
+				if (dev_mode.dmBitsPerPel == BITS_PER_PIXEL)
+				{
+					LL_WARNS("Window") << "Current BBP is OK falling back to that" << LL_ENDL;
+					window_rect.right=width=dev_mode.dmPelsWidth;
+					window_rect.bottom=height=dev_mode.dmPelsHeight;
+					success = TRUE;
+				}
+				else
+				{
+					LL_WARNS("Window") << "Current BBP is BAD" << LL_ENDL;
+					success = FALSE;
+				}
+			}
 		}
 
 		// If we found a good resolution, use it.
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index f9a39826f56203dab893ca78815704df497f2164..6c726091223fed987392652a96ea24849ee74aac 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -170,6 +170,20 @@ LLSD LLControlVariable::getComparableValue(const LLSD& value)
 			storable_value = false;
 		}
 	}
+	else if (TYPE_LLSD == type() && value.isString())
+	{
+		LLPointer<LLSDNotationParser> parser = new LLSDNotationParser;
+		LLSD result;
+		std::stringstream value_stream(value.asString());
+		if (parser->parse(value_stream, result, LLSDSerialize::SIZE_UNLIMITED) != LLSDParser::PARSE_FAILURE)
+		{
+			storable_value = result;
+		}
+		else
+		{
+			storable_value = value;
+		}
+	}
 	else
 	{
 		storable_value = value;
@@ -1107,7 +1121,7 @@ bool convert_from_llsd<bool>(const LLSD& sd, eControlType type, const std::strin
 		return sd.asBoolean();
 	else
 	{
-		CONTROL_ERRS << "Invalid BOOL value" << llendl;
+		CONTROL_ERRS << "Invalid BOOL value for " << control_name << ": " << sd << llendl;
 		return FALSE;
 	}
 }
@@ -1119,7 +1133,7 @@ S32 convert_from_llsd<S32>(const LLSD& sd, eControlType type, const std::string&
 		return sd.asInteger();
 	else
 	{
-		CONTROL_ERRS << "Invalid S32 value" << llendl;
+		CONTROL_ERRS << "Invalid S32 value for " << control_name << ": " << sd << llendl;
 		return 0;
 	}
 }
@@ -1131,7 +1145,7 @@ U32 convert_from_llsd<U32>(const LLSD& sd, eControlType type, const std::string&
 		return sd.asInteger();
 	else
 	{
-		CONTROL_ERRS << "Invalid U32 value" << llendl;
+		CONTROL_ERRS << "Invalid U32 value for " << control_name << ": " << sd << llendl;
 		return 0;
 	}
 }
@@ -1143,7 +1157,7 @@ F32 convert_from_llsd<F32>(const LLSD& sd, eControlType type, const std::string&
 		return (F32) sd.asReal();
 	else
 	{
-		CONTROL_ERRS << "Invalid F32 value" << llendl;
+		CONTROL_ERRS << "Invalid F32 value for " << control_name << ": " << sd << llendl;
 		return 0.0f;
 	}
 }
@@ -1155,7 +1169,7 @@ std::string convert_from_llsd<std::string>(const LLSD& sd, eControlType type, co
 		return sd.asString();
 	else
 	{
-		CONTROL_ERRS << "Invalid string value" << llendl;
+		CONTROL_ERRS << "Invalid string value for " << control_name << ": " << sd << llendl;
 		return LLStringUtil::null;
 	}
 }
@@ -1173,7 +1187,7 @@ LLVector3 convert_from_llsd<LLVector3>(const LLSD& sd, eControlType type, const
 		return (LLVector3)sd;
 	else
 	{
-		CONTROL_ERRS << "Invalid LLVector3 value" << llendl;
+		CONTROL_ERRS << "Invalid LLVector3 value for " << control_name << ": " << sd << llendl;
 		return LLVector3::zero;
 	}
 }
@@ -1185,7 +1199,7 @@ LLVector3d convert_from_llsd<LLVector3d>(const LLSD& sd, eControlType type, cons
 		return (LLVector3d)sd;
 	else
 	{
-		CONTROL_ERRS << "Invalid LLVector3d value" << llendl;
+		CONTROL_ERRS << "Invalid LLVector3d value for " << control_name << ": " << sd << llendl;
 		return LLVector3d::zero;
 	}
 }
@@ -1197,7 +1211,7 @@ LLRect convert_from_llsd<LLRect>(const LLSD& sd, eControlType type, const std::s
 		return LLRect(sd);
 	else
 	{
-		CONTROL_ERRS << "Invalid rect value" << llendl;
+		CONTROL_ERRS << "Invalid rect value for " << control_name << ": " << sd << llendl;
 		return LLRect::null;
 	}
 }
@@ -1211,19 +1225,19 @@ LLColor4 convert_from_llsd<LLColor4>(const LLSD& sd, eControlType type, const st
 		LLColor4 color(sd);
 		if (color.mV[VRED] < 0.f || color.mV[VRED] > 1.f)
 		{
-			llwarns << "Color " << control_name << " value out of range " << llendl;
+			llwarns << "Color " << control_name << " red value out of range: " << color << llendl;
 		}
 		else if (color.mV[VGREEN] < 0.f || color.mV[VGREEN] > 1.f)
 		{
-			llwarns << "Color " << control_name << " value out of range " << llendl;
+			llwarns << "Color " << control_name << " green value out of range: " << color << llendl;
 		}
 		else if (color.mV[VBLUE] < 0.f || color.mV[VBLUE] > 1.f)
 		{
-			llwarns << "Color " << control_name << " value out of range " << llendl;
+			llwarns << "Color " << control_name << " blue value out of range: " << color << llendl;
 		}
 		else if (color.mV[VALPHA] < 0.f || color.mV[VALPHA] > 1.f)
 		{
-			llwarns << "Color " << control_name << " value out of range " << llendl;
+			llwarns << "Color " << control_name << " alpha value out of range: " << color << llendl;
 		}
 
 		return LLColor4(sd);
@@ -1242,7 +1256,7 @@ LLColor3 convert_from_llsd<LLColor3>(const LLSD& sd, eControlType type, const st
 		return sd;
 	else
 	{
-		CONTROL_ERRS << "Invalid LLColor3 value" << llendl;
+		CONTROL_ERRS << "Invalid LLColor3 value for " << control_name << ": " << sd << llendl;
 		return LLColor3::white;
 	}
 }
diff --git a/indra/llxuixml/llinitparam.cpp b/indra/llxuixml/llinitparam.cpp
index 2c92539387a98560b616785c464b77aa0adf0b11..fcdbaa430973d93b62eda9283ee7f99f835c4246 100644
--- a/indra/llxuixml/llinitparam.cpp
+++ b/indra/llxuixml/llinitparam.cpp
@@ -312,6 +312,14 @@ namespace LLInitParam
 			}
 		}
 
+		// if no match, and no names left on stack, this is just an existence assertion of this block
+		// verify by calling readValue with NoParamValue type, an inherently unparseable type
+		if (!names_left)
+		{
+			NoParamValue no_value;
+			return p.readValue(no_value);
+		}
+
 		return false;
 	}
 
diff --git a/indra/llxuixml/llinitparam.h b/indra/llxuixml/llinitparam.h
index 8cb5bd80fc93a0f3f95b949911964d291ac7b665..1f9045754a9c8b32d698ff6dd6a57f33edbb5575 100644
--- a/indra/llxuixml/llinitparam.h
+++ b/indra/llxuixml/llinitparam.h
@@ -278,6 +278,9 @@ namespace LLInitParam
 		S32	mParseGeneration;
 	};
 
+	// used to indicate no matching value to a given name when parsing
+	struct NoParamValue{};
+
 	class BaseBlock;
 
 	class Param
@@ -303,8 +306,8 @@ namespace LLInitParam
 	private:
 		friend class BaseBlock;
 
-		bool		mIsProvided;
 		U16			mEnclosingBlockOffset;
+		bool		mIsProvided;
 	};
 
 	// various callbacks and constraints associated with an individual param
diff --git a/indra/llxuixml/llregistry.h b/indra/llxuixml/llregistry.h
index eee9933739ac20d6131ddcfd0881fcc0779425fc..36ce6a97b720c75d347d972948f16fee80ce8a2f 100644
--- a/indra/llxuixml/llregistry.h
+++ b/indra/llxuixml/llregistry.h
@@ -343,4 +343,9 @@ class LLRegistrySingleton
 	ScopedRegistrar*	mStaticScope;
 };
 
+// helper macro for doing static registration
+#define GLUED_TOKEN(x, y) x ## y
+#define GLUE_TOKENS(x, y) GLUED_TOKEN(x, y)
+#define LLREGISTER_STATIC(REGISTRY, KEY, VALUE) static REGISTRY::StaticRegistrar GLUE_TOKENS(reg, __LINE__)(KEY, VALUE);
+
 #endif
diff --git a/indra/llxuixml/llxuiparser.cpp b/indra/llxuixml/llxuiparser.cpp
index 9942af6b3738a283ff52869c745b56bfdb1b0a33..72a7bb7af50a1a11dd3e6c4a08b88a0e5d1eca8c 100644
--- a/indra/llxuixml/llxuiparser.cpp
+++ b/indra/llxuixml/llxuiparser.cpp
@@ -388,6 +388,7 @@ LLXUIParser::LLXUIParser()
 {
 	if (sXUIReadFuncs.empty())
 	{
+		registerParserFuncs<LLInitParam::NoParamValue>(readNoValue, writeNoValue);
 		registerParserFuncs<bool>(readBoolValue, writeBoolValue);
 		registerParserFuncs<std::string>(readStringValue, writeStringValue);
 		registerParserFuncs<U8>(readU8Value, writeU8Value);
@@ -406,6 +407,7 @@ LLXUIParser::LLXUIParser()
 }
 
 static LLFastTimer::DeclareTimer FTM_PARSE_XUI("XUI Parsing");
+const LLXMLNodePtr DUMMY_NODE = new LLXMLNode();
 
 void LLXUIParser::readXUI(LLXMLNodePtr node, LLInitParam::BaseBlock& block, const std::string& filename, bool silent)
 {
@@ -432,6 +434,17 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
 	boost::char_separator<char> sep(".");
 
 	bool values_parsed = false;
+	bool silent = mCurReadDepth > 0;
+
+	if (nodep->getFirstChild().isNull() 
+		&& nodep->mAttributes.empty() 
+		&& nodep->getSanitizedValue().empty())
+	{
+		// empty node, just parse as NoValue
+		mCurReadNode = DUMMY_NODE;
+		return block.submitValue(mNameStack, *this, silent);
+	}
+
 
 	// submit attributes for current node
 	values_parsed |= readAttributes(nodep, block);
@@ -444,7 +457,6 @@ bool LLXUIParser::readXUIImpl(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block)
 		mNameStack.push_back(std::make_pair(std::string("value"), newParseGeneration()));
 		// child nodes are not necessarily valid parameters (could be a child widget)
 		// so don't complain once we've recursed
-		bool silent = mCurReadDepth > 0;
 		if (!block.submitValue(mNameStack, *this, true))
 		{
 			mNameStack.pop_back();
@@ -549,6 +561,7 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo
 	boost::char_separator<char> sep(".");
 
 	bool any_parsed = false;
+	bool silent = mCurReadDepth > 0;
 
 	for(LLXMLAttribList::const_iterator attribute_it = nodep->mAttributes.begin(); 
 		attribute_it != nodep->mAttributes.end(); 
@@ -567,7 +580,6 @@ bool LLXUIParser::readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& blo
 		}
 
 		// child nodes are not necessarily valid attributes, so don't complain once we've recursed
-		bool silent = mCurReadDepth > 0;
 		any_parsed |= block.submitValue(mNameStack, *this, silent);
 		
 		while(num_tokens_pushed-- > 0)
@@ -634,6 +646,19 @@ LLXMLNodePtr LLXUIParser::getNode(const name_stack_t& stack)
 	return (out_node == mWriteRootNode ? LLXMLNodePtr(NULL) : out_node);
 }
 
+bool LLXUIParser::readNoValue(Parser& parser, void* val_ptr)
+{
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	return self.mCurReadNode == DUMMY_NODE;
+}
+
+bool LLXUIParser::writeNoValue(Parser& parser, const void* val_ptr, const name_stack_t& stack)
+{
+	// just create node
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	LLXMLNodePtr node = self.getNode(stack);
+	return node.notNull();
+}
 
 bool LLXUIParser::readBoolValue(Parser& parser, void* val_ptr)
 {
@@ -1049,6 +1074,8 @@ static 	LLInitParam::Parser::parser_read_func_map_t sSimpleXUIReadFuncs;
 static 	LLInitParam::Parser::parser_write_func_map_t sSimpleXUIWriteFuncs;
 static 	LLInitParam::Parser::parser_inspect_func_map_t sSimpleXUIInspectFuncs;
 
+const char* NO_VALUE_MARKER = "no_value";
+
 LLSimpleXUIParser::LLSimpleXUIParser(LLSimpleXUIParser::element_start_callback_t element_cb)
 :	Parser(sSimpleXUIReadFuncs, sSimpleXUIWriteFuncs, sSimpleXUIInspectFuncs),
 	mLastWriteGeneration(-1),
@@ -1057,6 +1084,7 @@ LLSimpleXUIParser::LLSimpleXUIParser(LLSimpleXUIParser::element_start_callback_t
 {
 	if (sSimpleXUIReadFuncs.empty())
 	{
+		registerParserFuncs<LLInitParam::NoParamValue>(readNoValue);
 		registerParserFuncs<bool>(readBoolValue);
 		registerParserFuncs<std::string>(readStringValue);
 		registerParserFuncs<U8>(readU8Value);
@@ -1120,6 +1148,8 @@ bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBl
 		return false;
 	}
 	
+	mEmptyLeafNode.push_back(false);
+
 	if( !XML_ParseBuffer(mParser, bytes_read, TRUE ) )
 	{
 		LL_WARNS("ReadXUI") << "Error while parsing file  " << filename << LL_ENDL;
@@ -1127,6 +1157,8 @@ bool LLSimpleXUIParser::readXUI(const std::string& filename, LLInitParam::BaseBl
 		return false;
 	}
 
+	mEmptyLeafNode.pop_back();
+
 	XML_ParserFree( mParser );
 	return true;
 }
@@ -1211,8 +1243,14 @@ void LLSimpleXUIParser::startElement(const char *name, const char **atts)
 		}
 	}
 
+	// parent node is not empty
+	mEmptyLeafNode.back() = false;
+	// we are empty if we have no attributes
+	mEmptyLeafNode.push_back(atts[0] == NULL);
+
 	mTokenSizeStack.push_back(num_tokens_pushed);
 	readAttributes(atts);
+
 }
 
 bool LLSimpleXUIParser::readAttributes(const char **atts)
@@ -1246,7 +1284,7 @@ bool LLSimpleXUIParser::readAttributes(const char **atts)
 	return any_parsed;
 }
 
-void LLSimpleXUIParser::processText()
+bool LLSimpleXUIParser::processText()
 {
 	if (!mTextContents.empty())
 	{
@@ -1259,12 +1297,22 @@ void LLSimpleXUIParser::processText()
 			mNameStack.pop_back();
 		}
 		mTextContents.clear();
+		return true;
 	}
+	return false;
 }
 
 void LLSimpleXUIParser::endElement(const char *name)
 {
-	processText();
+	bool has_text = processText();
+
+	// no text, attributes, or children
+	if (!has_text && mEmptyLeafNode.back())
+	{
+		// submit this as a valueless name (even though there might be text contents we haven't seen yet)
+		mCurAttributeValueBegin = NO_VALUE_MARKER;
+		mOutputStack.back().first->submitValue(mNameStack, *this, mParseSilently);
+	}
 
 	if (--mOutputStack.back().second == 0)
 	{
@@ -1282,6 +1330,7 @@ void LLSimpleXUIParser::endElement(const char *name)
 		mNameStack.pop_back();
 	}
 	mScope.pop_back();
+	mEmptyLeafNode.pop_back();
 }
 
 void LLSimpleXUIParser::characterData(const char *s, int len)
@@ -1328,6 +1377,12 @@ void LLSimpleXUIParser::parserError(const std::string& message)
 #endif
 }
 
+bool LLSimpleXUIParser::readNoValue(Parser& parser, void* val_ptr)
+{
+	LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
+	return self.mCurAttributeValueBegin == NO_VALUE_MARKER;
+}
+
 bool LLSimpleXUIParser::readBoolValue(Parser& parser, void* val_ptr)
 {
 	LLSimpleXUIParser& self = static_cast<LLSimpleXUIParser&>(parser);
diff --git a/indra/llxuixml/llxuiparser.h b/indra/llxuixml/llxuiparser.h
index 5c613b0c6998ed1d5a518d4f61eff284dc32d459..7a748d8aea770562f7312b2686fbe74de0fb10b8 100644
--- a/indra/llxuixml/llxuiparser.h
+++ b/indra/llxuixml/llxuiparser.h
@@ -116,6 +116,7 @@ LOG_CLASS(LLXUIParser);
 	bool readAttributes(LLXMLNodePtr nodep, LLInitParam::BaseBlock& block);
 
 	//reader helper functions
+	static bool readNoValue(Parser& parser, void* val_ptr);
 	static bool readBoolValue(Parser& parser, void* val_ptr);
 	static bool readStringValue(Parser& parser, void* val_ptr);
 	static bool readU8Value(Parser& parser, void* val_ptr);
@@ -132,6 +133,7 @@ LOG_CLASS(LLXUIParser);
 	static bool readSDValue(Parser& parser, void* val_ptr);
 
 	//writer helper functions
+	static bool writeNoValue(Parser& parser, const void* val_ptr, const name_stack_t&);
 	static bool writeBoolValue(Parser& parser, const void* val_ptr, const name_stack_t&);
 	static bool writeStringValue(Parser& parser, const void* val_ptr, const name_stack_t&);
 	static bool writeU8Value(Parser& parser, const void* val_ptr, const name_stack_t&);
@@ -194,6 +196,7 @@ LOG_CLASS(LLSimpleXUIParser);
 
 private:
 	//reader helper functions
+	static bool readNoValue(Parser&, void* val_ptr);
 	static bool readBoolValue(Parser&, void* val_ptr);
 	static bool readStringValue(Parser&, void* val_ptr);
 	static bool readU8Value(Parser&, void* val_ptr);
@@ -218,7 +221,7 @@ LOG_CLASS(LLSimpleXUIParser);
 	void endElement(const char *name);
 	void characterData(const char *s, int len);
 	bool readAttributes(const char **atts);
-	void processText();
+	bool processText();
 
 	Parser::name_stack_t			mNameStack;
 	struct XML_ParserStruct*		mParser;
@@ -230,6 +233,7 @@ LOG_CLASS(LLSimpleXUIParser);
 	const char*						mCurAttributeValueBegin;
 	std::vector<S32>				mTokenSizeStack;
 	std::vector<std::string>		mScope;
+	std::vector<bool>				mEmptyLeafNode;
 	element_start_callback_t		mElementCB;
 
 	std::vector<std::pair<LLInitParam::BaseBlock*, S32> > mOutputStack;
diff --git a/indra/mac_updater/CMakeLists.txt b/indra/mac_updater/CMakeLists.txt
index 44f98e5e18c3371a01c65c4ac090467563f6ce98..a4a6b50c6c14fbfc18e733b043a9c5485b143804 100644
--- a/indra/mac_updater/CMakeLists.txt
+++ b/indra/mac_updater/CMakeLists.txt
@@ -3,6 +3,7 @@
 project(mac_updater)
 
 include(00-Common)
+include(OpenSSL)
 include(CURL)
 include(LLCommon)
 include(LLVFS)
@@ -49,6 +50,8 @@ set_target_properties(mac-updater
 
 target_link_libraries(mac-updater
     ${LLVFS_LIBRARIES}
+    ${OPENSSL_LIBRARIES}
+    ${CRYPTO_LIBRARIES}
     ${CURL_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
     )
diff --git a/indra/mac_updater/mac_updater.cpp b/indra/mac_updater/mac_updater.cpp
index 23980ffac22a7954a0a6327369b71e5b2129ef38..5d19e8a8899b0eb3ca3bd36d558cf6ca5d5a7b4c 100644
--- a/indra/mac_updater/mac_updater.cpp
+++ b/indra/mac_updater/mac_updater.cpp
@@ -26,6 +26,9 @@
 
 #include "linden_common.h"
 
+#include <boost/format.hpp>
+
+#include <libgen.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <unistd.h>
@@ -62,6 +65,8 @@ Boolean gCancelled = false;
 const char *gUpdateURL;
 const char *gProductName;
 const char *gBundleID;
+const char *gDmgFile;
+const char *gMarkerPath;
 
 void *updatethreadproc(void*);
 
@@ -334,6 +339,14 @@ int parse_args(int argc, char **argv)
 		{
 			gBundleID = argv[j];
 		}
+		else if ((!strcmp(argv[j], "-dmg")) && (++j < argc)) 
+		{
+			gDmgFile = argv[j];
+		}
+		else if ((!strcmp(argv[j], "-marker")) && (++j < argc)) 
+		{
+			gMarkerPath = argv[j];;
+		}
 	}
 
 	return 0;
@@ -361,10 +374,12 @@ int main(int argc, char **argv)
 	gUpdateURL  = NULL;
 	gProductName = NULL;
 	gBundleID = NULL;
+	gDmgFile = NULL;
+	gMarkerPath = NULL;
 	parse_args(argc, argv);
-	if (!gUpdateURL)
+	if ((gUpdateURL == NULL) && (gDmgFile == NULL))
 	{
-		llinfos << "Usage: mac_updater -url <url> [-name <product_name>] [-program <program_name>]" << llendl;
+		llinfos << "Usage: mac_updater -url <url> | -dmg <dmg file> [-name <product_name>] [-program <program_name>]" << llendl;
 		exit(1);
 	}
 	else
@@ -488,11 +503,18 @@ int main(int argc, char **argv)
 					NULL,
 					&retval_mac);
 		}
-
+		
+		if(gMarkerPath != 0)
+		{
+			// Create a install fail marker that can be used by the viewer to
+			// detect install problems.
+			std::ofstream stream(gMarkerPath);
+			if(stream) stream << -1;
+		}
+		exit(-1);
+	} else {
+		exit(0);
 	}
-	
-	// Don't dispose of things, just exit.  This keeps the update thread from potentially getting hosed.
-	exit(0);
 
 	if(gWindow != NULL)
 	{
@@ -700,17 +722,26 @@ static OSErr findAppBundleOnDiskImage(FSRef *parent, FSRef *app)
 						// Looks promising.  Check to see if it has the right bundle identifier.
 						if(isFSRefViewerBundle(&ref))
 						{
+							llinfos << name << " is the one" << llendl;
 							// This is the one.  Return it.
 							*app = ref;
 							found = true;
+							break;
+						} else {
+							llinfos << name << " is not the bundle we are looking for; move along" << llendl;
 						}
+
 					}
 				}
 			}
 		}
-		while(!err && !found);
+		while(!err);
+		
+		llinfos << "closing the iterator" << llendl;
 		
 		FSCloseIterator(iterator);
+		
+		llinfos << "closed" << llendl;
 	}
 	
 	if(!err && !found)
@@ -921,6 +952,22 @@ void *updatethreadproc(void*)
 
 #endif // 0 *HACK for DEV-11935
 		
+		// Skip downloading the file if the dmg was passed on the command line.
+		std::string dmgName;
+		if(gDmgFile != NULL) {
+			dmgName = basename((char *)gDmgFile);
+			char * dmgDir = dirname((char *)gDmgFile);
+			strncpy(tempDir, dmgDir, sizeof(tempDir));
+			err = FSPathMakeRef((UInt8*)tempDir, &tempDirRef, NULL);
+			if(err != noErr) throw 0;
+			chdir(tempDir);
+			goto begin_install;
+		} else {
+			// Continue on to download file.
+			dmgName = "SecondLife.dmg";
+		}
+
+		
 		strncat(temp, "/SecondLifeUpdate_XXXXXX", (sizeof(temp) - strlen(temp)) - 1);
 		if(mkdtemp(temp) == NULL)
 		{
@@ -979,14 +1026,17 @@ void *updatethreadproc(void*)
 			fclose(downloadFile);
 			downloadFile = NULL;
 		}
-		
+
+	begin_install:
 		sendProgress(0, 0, CFSTR("Mounting image..."));
 		LLFile::mkdir("mnt", 0700);
 		
 		// NOTE: we could add -private at the end of this command line to keep the image from showing up in the Finder,
 		//		but if our cleanup fails, this makes it much harder for the user to unmount the image.
 		std::string mountOutput;
-		FILE* mounter = popen("hdiutil attach SecondLife.dmg -mountpoint mnt", "r");		/* Flawfinder: ignore */
+		boost::format cmdFormat("hdiutil attach %s -mountpoint mnt");
+		cmdFormat % dmgName;
+		FILE* mounter = popen(cmdFormat.str().c_str(), "r");		/* Flawfinder: ignore */
 		
 		if(mounter == NULL)
 		{
@@ -1052,12 +1102,19 @@ void *updatethreadproc(void*)
 			throw 0;
 		}
 
+		sendProgress(0, 0, CFSTR("Searching for the app bundle..."));
 		err = findAppBundleOnDiskImage(&mountRef, &sourceRef);
 		if(err != noErr)
 		{
 			llinfos << "Couldn't find application bundle on mounted disk image." << llendl;
 			throw 0;
 		}
+		else
+		{
+			llinfos << "found the bundle." << llendl;
+		}
+
+		sendProgress(0, 0, CFSTR("Preparing to copy files..."));
 		
 		FSRef asideRef;
 		char aside[MAX_PATH];		/* Flawfinder: ignore */
@@ -1077,7 +1134,11 @@ void *updatethreadproc(void*)
 			// Move aside old version (into work directory)
 			err = FSMoveObject(&targetRef, &tempDirRef, &asideRef);
 			if(err != noErr)
+			{
+				llwarns << "failed to move aside old version (error code " << 
+					err << ")" << llendl;
 				throw 0;
+			}
 
 			// Grab the path for later use.
 			err = FSRefMakePath(&asideRef, (UInt8*)aside, sizeof(aside));
@@ -1175,6 +1236,10 @@ void *updatethreadproc(void*)
 		llinfos << "Moving work directory to the trash." << llendl;
 
 		err = FSMoveObject(&tempDirRef, &trashFolderRef, NULL);
+		if(err != noErr) {
+			llwarns << "failed to move files to trash, (error code " <<
+				err << ")" << llendl;
+		}
 
 //		snprintf(temp, sizeof(temp), "rm -rf '%s'", tempDir);
 //		printf("%s\n", temp);
diff --git a/indra/media_plugins/example/media_plugin_example.cpp b/indra/media_plugins/example/media_plugin_example.cpp
index f8a871930ecdd7fd467f80006606ef33ca606014..da7de0179908f03a9041e6f6106dee1783356d5f 100644
--- a/indra/media_plugins/example/media_plugin_example.cpp
+++ b/indra/media_plugins/example/media_plugin_example.cpp
@@ -6,21 +6,21 @@
  * $LicenseInfo:firstyear=2008&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  * @endcond
@@ -39,48 +39,48 @@
 ////////////////////////////////////////////////////////////////////////////////
 //
 class MediaPluginExample :
-		public MediaPluginBase
+        public MediaPluginBase
 {
-	public:
-		MediaPluginExample( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data );
-		~MediaPluginExample();
-
-		/*virtual*/ void receiveMessage( const char* message_string );
-
-	private:
-		bool init();
-		void update( F64 milliseconds );
-		void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b );
-		bool mFirstTime;
-
-		time_t mLastUpdateTime;
-		enum Constants { ENumObjects = 10 };
-		unsigned char* mBackgroundPixels;
-		int mColorR[ ENumObjects ];
-		int mColorG[ ENumObjects ];
-		int mColorB[ ENumObjects ];
-		int mXpos[ ENumObjects ];
-		int mYpos[ ENumObjects ];
-		int mXInc[ ENumObjects ];
-		int mYInc[ ENumObjects ];
-		int mBlockSize[ ENumObjects ];
-		bool mMouseButtonDown;
-		bool mStopAction;
+    public:
+        MediaPluginExample( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data );
+        ~MediaPluginExample();
+
+        /*virtual*/ void receiveMessage( const char* message_string );
+
+    private:
+        bool init();
+        void update( F64 milliseconds );
+        void write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b );
+        bool mFirstTime;
+
+        time_t mLastUpdateTime;
+        enum Constants { ENumObjects = 10 };
+        unsigned char* mBackgroundPixels;
+        int mColorR[ ENumObjects ];
+        int mColorG[ ENumObjects ];
+        int mColorB[ ENumObjects ];
+        int mXpos[ ENumObjects ];
+        int mYpos[ ENumObjects ];
+        int mXInc[ ENumObjects ];
+        int mYInc[ ENumObjects ];
+        int mBlockSize[ ENumObjects ];
+        bool mMouseButtonDown;
+        bool mStopAction;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 //
 MediaPluginExample::MediaPluginExample( LLPluginInstance::sendMessageFunction host_send_func, void *host_user_data ) :
-	MediaPluginBase( host_send_func, host_user_data )
+    MediaPluginBase( host_send_func, host_user_data )
 {
-	mFirstTime = true;
-	mWidth = 0;
-	mHeight = 0;
-	mDepth = 4;
-	mPixels = 0;
-	mMouseButtonDown = false;
-	mStopAction = false;
-	mLastUpdateTime = 0;
+    mFirstTime = true;
+    mWidth = 0;
+    mHeight = 0;
+    mDepth = 4;
+    mPixels = 0;
+    mMouseButtonDown = false;
+    mStopAction = false;
+    mLastUpdateTime = 0;
 }
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -93,395 +93,320 @@ MediaPluginExample::~MediaPluginExample()
 //
 void MediaPluginExample::receiveMessage( const char* message_string )
 {
-	LLPluginMessage message_in;
-
-	if ( message_in.parse( message_string ) >= 0 )
-	{
-		std::string message_class = message_in.getClass();
-		std::string message_name = message_in.getName();
-
-		if ( message_class == LLPLUGIN_MESSAGE_CLASS_BASE )
-		{
-			if ( message_name == "init" )
-			{
-				LLPluginMessage message( "base", "init_response" );
-				LLSD versions = LLSD::emptyMap();
-				versions[ LLPLUGIN_MESSAGE_CLASS_BASE ] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
-				versions[ LLPLUGIN_MESSAGE_CLASS_MEDIA ] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
-				versions[ LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER ] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
-				message.setValueLLSD( "versions", versions );
-
-				std::string plugin_version = "Example media plugin, Example Version 1.0.0.0";
-				message.setValue( "plugin_version", plugin_version );
-				sendMessage( message );
-			}
-			else
-			if ( message_name == "idle" )
-			{
-				// no response is necessary here.
-				F64 time = message_in.getValueReal( "time" );
-
-				// Convert time to milliseconds for update()
-				update( time );
-			}
-			else
-			if ( message_name == "cleanup" )
-			{
-				// clean up here
-			}
-			else
-			if ( message_name == "shm_added" )
-			{
-				SharedSegmentInfo info;
-				info.mAddress = message_in.getValuePointer( "address" );
-				info.mSize = ( size_t )message_in.getValueS32( "size" );
-				std::string name = message_in.getValue( "name" );
-
-				mSharedSegments.insert( SharedSegmentMap::value_type( name, info ) );
-
-			}
-			else
-			if ( message_name == "shm_remove" )
-			{
-				std::string name = message_in.getValue( "name" );
-
-				SharedSegmentMap::iterator iter = mSharedSegments.find( name );
-				if( iter != mSharedSegments.end() )
-				{
-					if ( mPixels == iter->second.mAddress )
-					{
-						// This is the currently active pixel buffer.
-						// Make sure we stop drawing to it.
-						mPixels = NULL;
-						mTextureSegmentName.clear();
-					};
-					mSharedSegments.erase( iter );
-				}
-				else
-				{
-					//std::cerr << "MediaPluginExample::receiveMessage: unknown shared memory region!" << std::endl;
-				};
-
-				// Send the response so it can be cleaned up.
-				LLPluginMessage message( "base", "shm_remove_response" );
-				message.setValue( "name", name );
-				sendMessage( message );
-			}
-			else
-			{
-				//std::cerr << "MediaPluginExample::receiveMessage: unknown base message: " << message_name << std::endl;
-			};
-		}
-		else
-		if ( message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA )
-		{
-			if ( message_name == "init" )
-			{
-				// Plugin gets to decide the texture parameters to use.
-				LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params" );
-				message.setValueS32( "default_width", mWidth );
-				message.setValueS32( "default_height", mHeight );
-				message.setValueS32( "depth", mDepth );
-				message.setValueU32( "internalformat", GL_RGBA );
-				message.setValueU32( "format", GL_RGBA );
-				message.setValueU32( "type", GL_UNSIGNED_BYTE );
-				message.setValueBoolean( "coords_opengl", false );
-				sendMessage( message );
-			}
-			else if ( message_name == "size_change" )
-			{
-				std::string name = message_in.getValue( "name" );
-				S32 width = message_in.getValueS32( "width" );
-				S32 height = message_in.getValueS32( "height" );
-				S32 texture_width = message_in.getValueS32( "texture_width" );
-				S32 texture_height = message_in.getValueS32( "texture_height" );
-
-				if ( ! name.empty() )
-				{
-					// Find the shared memory region with this name
-					SharedSegmentMap::iterator iter = mSharedSegments.find( name );
-					if ( iter != mSharedSegments.end() )
-					{
-						mPixels = ( unsigned char* )iter->second.mAddress;
-						mWidth = width;
-						mHeight = height;
-
-						mTextureWidth = texture_width;
-						mTextureHeight = texture_height;
-
-						init();
-					};
-				};
-
-				LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response" );
-				message.setValue( "name", name );
-				message.setValueS32( "width", width );
-				message.setValueS32( "height", height );
-				message.setValueS32( "texture_width", texture_width );
-				message.setValueS32( "texture_height", texture_height );
-				sendMessage( message );
-			}
-			else
-			if ( message_name == "load_uri" )
-			{
-				std::string uri = message_in.getValue( "uri" );
-				if ( ! uri.empty() )
-				{
-				};
-			}
-			else
-			if ( message_name == "mouse_event" )
-			{
-				std::string event = message_in.getValue( "event" );
-				S32 button = message_in.getValueS32( "button" );
-
-				// left mouse button
-				if ( button == 0 )
-				{
-					int mouse_x = message_in.getValueS32( "x" );
-					int mouse_y = message_in.getValueS32( "y" );
-					std::string modifiers = message_in.getValue( "modifiers" );
-
-					if ( event == "move" )
-					{
-						if ( mMouseButtonDown )
-							write_pixel( mouse_x, mouse_y, rand() % 0x80 + 0x80, rand() % 0x80 + 0x80, rand() % 0x80 + 0x80 );
-					}
-					else
-					if ( event == "down" )
-					{
-						mMouseButtonDown = true;
-					}
-					else
-					if ( event == "up" )
-					{
-						mMouseButtonDown = false;
-					}
-					else
-					if ( event == "double_click" )
-					{
-					};
-				};
-			}
-			else
-			if ( message_name == "key_event" )
-			{
-				std::string event = message_in.getValue( "event" );
-				S32 key = message_in.getValueS32( "key" );
-				std::string modifiers = message_in.getValue( "modifiers" );
-
-				if ( event == "down" )
-				{
-					if ( key == ' ')
-					{
-						mLastUpdateTime = 0;
-						update( 0.0f );
-					};
-				};
-			}
-			else
-			{
-				//std::cerr << "MediaPluginExample::receiveMessage: unknown media message: " << message_string << std::endl;
-			};
-		}
-		else
-		if ( message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER )
-		{
-			if ( message_name == "browse_reload" )
-			{
-				mLastUpdateTime = 0;
-				mFirstTime = true;
-				mStopAction = false;
-				update( 0.0f );
-			}
-			else
-			if ( message_name == "browse_stop" )
-			{
-				for( int n = 0; n < ENumObjects; ++n )
-					mXInc[ n ] = mYInc[ n ] = 0;
-
-				mStopAction = true;
-				update( 0.0f );
-			}
-			else
-			{
-				//std::cerr << "MediaPluginExample::receiveMessage: unknown media_browser message: " << message_string << std::endl;
-			};
-		}
-		else
-		{
-			//std::cerr << "MediaPluginExample::receiveMessage: unknown message class: " << message_class << std::endl;
-		};
-	};
+//  std::cerr << "MediaPluginWebKit::receiveMessage: received message: \"" << message_string << "\"" << std::endl;
+    LLPluginMessage message_in;
+
+    if(message_in.parse(message_string) >= 0)
+    {
+        std::string message_class = message_in.getClass();
+        std::string message_name = message_in.getName();
+        if(message_class == LLPLUGIN_MESSAGE_CLASS_BASE)
+        {
+            if(message_name == "init")
+            {
+                LLPluginMessage message("base", "init_response");
+                LLSD versions = LLSD::emptyMap();
+                versions[LLPLUGIN_MESSAGE_CLASS_BASE] = LLPLUGIN_MESSAGE_CLASS_BASE_VERSION;
+                versions[LLPLUGIN_MESSAGE_CLASS_MEDIA] = LLPLUGIN_MESSAGE_CLASS_MEDIA_VERSION;
+                versions[LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER] = LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER_VERSION;
+                message.setValueLLSD("versions", versions);
+
+                std::string plugin_version = "Example plugin 1.0..0";
+                message.setValue("plugin_version", plugin_version);
+                sendMessage(message);
+            }
+            else if(message_name == "idle")
+            {
+                // no response is necessary here.
+                F64 time = message_in.getValueReal("time");
+
+                // Convert time to milliseconds for update()
+                update((int)(time * 1000.0f));
+            }
+            else if(message_name == "cleanup")
+            {
+            }
+            else if(message_name == "shm_added")
+            {
+                SharedSegmentInfo info;
+                info.mAddress = message_in.getValuePointer("address");
+                info.mSize = (size_t)message_in.getValueS32("size");
+                std::string name = message_in.getValue("name");
+
+                mSharedSegments.insert(SharedSegmentMap::value_type(name, info));
+
+            }
+            else if(message_name == "shm_remove")
+            {
+                std::string name = message_in.getValue("name");
+
+                SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+                if(iter != mSharedSegments.end())
+                {
+                    if(mPixels == iter->second.mAddress)
+                    {
+                        // This is the currently active pixel buffer.  Make sure we stop drawing to it.
+                        mPixels = NULL;
+                        mTextureSegmentName.clear();
+                    }
+                    mSharedSegments.erase(iter);
+                }
+                else
+                {
+//                  std::cerr << "MediaPluginWebKit::receiveMessage: unknown shared memory region!" << std::endl;
+                }
+
+                // Send the response so it can be cleaned up.
+                LLPluginMessage message("base", "shm_remove_response");
+                message.setValue("name", name);
+                sendMessage(message);
+            }
+            else
+            {
+//              std::cerr << "MediaPluginWebKit::receiveMessage: unknown base message: " << message_name << std::endl;
+            }
+        }
+        else if(message_class == LLPLUGIN_MESSAGE_CLASS_MEDIA)
+        {
+            if(message_name == "init")
+            {
+                // Plugin gets to decide the texture parameters to use.
+                mDepth = 4;
+                LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "texture_params");
+                message.setValueS32("default_width", 1024);
+                message.setValueS32("default_height", 1024);
+                message.setValueS32("depth", mDepth);
+                message.setValueU32("internalformat", GL_RGBA);
+                message.setValueU32("format", GL_RGBA);
+                message.setValueU32("type", GL_UNSIGNED_BYTE);
+                message.setValueBoolean("coords_opengl", true);
+                sendMessage(message);
+            }
+            else if(message_name == "size_change")
+            {
+                std::string name = message_in.getValue("name");
+                S32 width = message_in.getValueS32("width");
+                S32 height = message_in.getValueS32("height");
+                S32 texture_width = message_in.getValueS32("texture_width");
+                S32 texture_height = message_in.getValueS32("texture_height");
+
+                if(!name.empty())
+                {
+                    // Find the shared memory region with this name
+                    SharedSegmentMap::iterator iter = mSharedSegments.find(name);
+                    if(iter != mSharedSegments.end())
+                    {
+                        mPixels = (unsigned char*)iter->second.mAddress;
+                        mWidth = width;
+                        mHeight = height;
+
+                        mTextureWidth = texture_width;
+                        mTextureHeight = texture_height;
+                    };
+                };
+
+                LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "size_change_response");
+                message.setValue("name", name);
+                message.setValueS32("width", width);
+                message.setValueS32("height", height);
+                message.setValueS32("texture_width", texture_width);
+                message.setValueS32("texture_height", texture_height);
+                sendMessage(message);
+
+            }
+            else if(message_name == "load_uri")
+            {
+            }
+            else if(message_name == "mouse_event")
+            {
+                std::string event = message_in.getValue("event");
+                if(event == "down")
+                {
+
+                }
+                else if(event == "up")
+                {
+                }
+                else if(event == "double_click")
+                {
+                }
+            }
+        }
+        else
+        {
+//          std::cerr << "MediaPluginWebKit::receiveMessage: unknown message class: " << message_class << std::endl;
+        };
+    }
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //
 void MediaPluginExample::write_pixel( int x, int y, unsigned char r, unsigned char g, unsigned char b )
 {
-	// make sure we don't write outside the buffer
-	if ( ( x < 0 ) || ( x >= mWidth ) || ( y < 0 ) || ( y >= mHeight ) )
-		return;
-		
-	if ( mBackgroundPixels != NULL )
-	{
-		unsigned char *pixel = mBackgroundPixels;
-		pixel += y * mWidth * mDepth;
-		pixel += ( x * mDepth );
-		pixel[ 0 ] = b;
-		pixel[ 1 ] = g;
-		pixel[ 2 ] = r;
-
-		setDirty( x, y, x + 1, y + 1 );
-	};
+    // make sure we don't write outside the buffer
+    if ( ( x < 0 ) || ( x >= mWidth ) || ( y < 0 ) || ( y >= mHeight ) )
+        return;
+
+    if ( mBackgroundPixels != NULL )
+    {
+        unsigned char *pixel = mBackgroundPixels;
+        pixel += y * mWidth * mDepth;
+        pixel += ( x * mDepth );
+        pixel[ 0 ] = b;
+        pixel[ 1 ] = g;
+        pixel[ 2 ] = r;
+
+        setDirty( x, y, x + 1, y + 1 );
+    };
 }
 
 ////////////////////////////////////////////////////////////////////////////////
 //
 void MediaPluginExample::update( F64 milliseconds )
 {
-	if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 )
-		return;
-
-	if ( mPixels == 0 )
-			return;
-
-	if ( mFirstTime )
-	{
-		for( int n = 0; n < ENumObjects; ++n )
-		{
-			mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 );
-			mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 );
-
-			mColorR[ n ] = rand() % 0x60 + 0x60;
-			mColorG[ n ] = rand() % 0x60 + 0x60;
-			mColorB[ n ] = rand() % 0x60 + 0x60;
-
-			mXInc[ n ] = 0;
-			while ( mXInc[ n ] == 0 )
-				mXInc[ n ] = rand() % 7 - 3;
-
-			mYInc[ n ] = 0;
-			while ( mYInc[ n ] == 0 )
-				mYInc[ n ] = rand() % 9 - 4;
-
-			mBlockSize[ n ] = rand() % 0x30 + 0x10;
-		};
-
-		delete [] mBackgroundPixels;
-				
-		mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ];
-
-		mFirstTime = false;
-	};
-
-	if ( mStopAction )
-		return;
-
-	if ( time( NULL ) > mLastUpdateTime + 3 )
-	{
-		const int num_squares = rand() % 20 + 4;
-		int sqr1_r = rand() % 0x80 + 0x20;
-		int sqr1_g = rand() % 0x80 + 0x20;
-		int sqr1_b = rand() % 0x80 + 0x20;
-		int sqr2_r = rand() % 0x80 + 0x20;
-		int sqr2_g = rand() % 0x80 + 0x20;
-		int sqr2_b = rand() % 0x80 + 0x20;
-
-		for ( int y1 = 0; y1 < num_squares; ++y1 )
-		{
-			for ( int x1 = 0; x1 < num_squares; ++x1 )
-			{
-				int px_start = mWidth * x1 / num_squares;
-				int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares;
-				int py_start = mHeight * y1 / num_squares;
-				int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares;
-
-				for( int y2 = py_start; y2 < py_end; ++y2 )
-				{
-					for( int x2 = px_start; x2 < px_end; ++x2 )
-					{
-						int rowspan = mWidth * mDepth;
-
-						if ( ( y1 % 2 ) ^ ( x1 % 2 ) )
-						{
-							mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r;
-							mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g;
-							mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b;
-						}
-						else
-						{
-							mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r;
-							mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g;
-							mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b;
-						};
-					};
-				};
-			};
-		};
-
-		time( &mLastUpdateTime );
-	};
-
-	memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth );
-
-	for( int n = 0; n < ENumObjects; ++n )
-	{
-		if ( rand() % 50 == 0 )
-		{
-				mXInc[ n ] = 0;
-				while ( mXInc[ n ] == 0 )
-					mXInc[ n ] = rand() % 7 - 3;
-
-				mYInc[ n ] = 0;
-				while ( mYInc[ n ] == 0 )
-					mYInc[ n ] = rand() % 9 - 4;
-		};
-
-		if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] )
-			mXInc[ n ] =- mXInc[ n ];
-
-		if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] )
-			mYInc[ n ] =- mYInc[ n ];
-
-		mXpos[ n ] += mXInc[ n ];
-		mYpos[ n ] += mYInc[ n ];
-
-		for( int y = 0; y < mBlockSize[ n ]; ++y )
-		{
-			for( int x = 0; x < mBlockSize[ n ]; ++x )
-			{
-				mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ];
-				mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ];
-				mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ];
-			};
-		};
-	};
-
-	setDirty( 0, 0, mWidth, mHeight );
+    if ( mWidth < 1 || mWidth > 2048 || mHeight < 1 || mHeight > 2048 )
+        return;
+
+    if ( mPixels == 0 )
+            return;
+
+    if ( mFirstTime )
+    {
+        for( int n = 0; n < ENumObjects; ++n )
+        {
+            mXpos[ n ] = ( mWidth / 2 ) + rand() % ( mWidth / 16 ) - ( mWidth / 32 );
+            mYpos[ n ] = ( mHeight / 2 ) + rand() % ( mHeight / 16 ) - ( mHeight / 32 );
+
+            mColorR[ n ] = rand() % 0x60 + 0x60;
+            mColorG[ n ] = rand() % 0x60 + 0x60;
+            mColorB[ n ] = rand() % 0x60 + 0x60;
+
+            mXInc[ n ] = 0;
+            while ( mXInc[ n ] == 0 )
+                mXInc[ n ] = rand() % 7 - 3;
+
+            mYInc[ n ] = 0;
+            while ( mYInc[ n ] == 0 )
+                mYInc[ n ] = rand() % 9 - 4;
+
+            mBlockSize[ n ] = rand() % 0x30 + 0x10;
+        };
+
+        delete [] mBackgroundPixels;
+
+        mBackgroundPixels = new unsigned char[ mWidth * mHeight * mDepth ];
+
+        mFirstTime = false;
+    };
+
+    if ( mStopAction )
+        return;
+
+    if ( time( NULL ) > mLastUpdateTime + 3 )
+    {
+        const int num_squares = rand() % 20 + 4;
+        int sqr1_r = rand() % 0x80 + 0x20;
+        int sqr1_g = rand() % 0x80 + 0x20;
+        int sqr1_b = rand() % 0x80 + 0x20;
+        int sqr2_r = rand() % 0x80 + 0x20;
+        int sqr2_g = rand() % 0x80 + 0x20;
+        int sqr2_b = rand() % 0x80 + 0x20;
+
+        for ( int y1 = 0; y1 < num_squares; ++y1 )
+        {
+            for ( int x1 = 0; x1 < num_squares; ++x1 )
+            {
+                int px_start = mWidth * x1 / num_squares;
+                int px_end = ( mWidth * ( x1 + 1 ) ) / num_squares;
+                int py_start = mHeight * y1 / num_squares;
+                int py_end = ( mHeight * ( y1 + 1 ) ) / num_squares;
+
+                for( int y2 = py_start; y2 < py_end; ++y2 )
+                {
+                    for( int x2 = px_start; x2 < px_end; ++x2 )
+                    {
+                        int rowspan = mWidth * mDepth;
+
+                        if ( ( y1 % 2 ) ^ ( x1 % 2 ) )
+                        {
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr1_r;
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr1_g;
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr1_b;
+                        }
+                        else
+                        {
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 0 ] = sqr2_r;
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 1 ] = sqr2_g;
+                            mBackgroundPixels[ y2 * rowspan + x2 * mDepth + 2 ] = sqr2_b;
+                        };
+                    };
+                };
+            };
+        };
+
+        time( &mLastUpdateTime );
+    };
+
+    memcpy( mPixels, mBackgroundPixels, mWidth * mHeight * mDepth );
+
+    for( int n = 0; n < ENumObjects; ++n )
+    {
+        if ( rand() % 50 == 0 )
+        {
+                mXInc[ n ] = 0;
+                while ( mXInc[ n ] == 0 )
+                    mXInc[ n ] = rand() % 7 - 3;
+
+                mYInc[ n ] = 0;
+                while ( mYInc[ n ] == 0 )
+                    mYInc[ n ] = rand() % 9 - 4;
+        };
+
+        if ( mXpos[ n ] + mXInc[ n ] < 0 || mXpos[ n ] + mXInc[ n ] >= mWidth - mBlockSize[ n ] )
+            mXInc[ n ] =- mXInc[ n ];
+
+        if ( mYpos[ n ] + mYInc[ n ] < 0 || mYpos[ n ] + mYInc[ n ] >= mHeight - mBlockSize[ n ] )
+            mYInc[ n ] =- mYInc[ n ];
+
+        mXpos[ n ] += mXInc[ n ];
+        mYpos[ n ] += mYInc[ n ];
+
+        for( int y = 0; y < mBlockSize[ n ]; ++y )
+        {
+            for( int x = 0; x < mBlockSize[ n ]; ++x )
+            {
+                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 0 ] = mColorR[ n ];
+                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 1 ] = mColorG[ n ];
+                mPixels[ ( mXpos[ n ] + x ) * mDepth + ( mYpos[ n ] + y ) * mDepth * mWidth + 2 ] = mColorB[ n ];
+            };
+        };
+    };
+
+    setDirty( 0, 0, mWidth, mHeight );
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 //
 bool MediaPluginExample::init()
 {
-	LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text" );
-	message.setValue( "name", "Example Plugin" );
-	sendMessage( message );
+    LLPluginMessage message( LLPLUGIN_MESSAGE_CLASS_MEDIA, "name_text" );
+    message.setValue( "name", "Example Plugin" );
+    sendMessage( message );
 
-	return true;
+    return true;
 };
 
 ////////////////////////////////////////////////////////////////////////////////
 //
 int init_media_plugin( LLPluginInstance::sendMessageFunction host_send_func,
-						void* host_user_data,
-						LLPluginInstance::sendMessageFunction *plugin_send_func,
-						void **plugin_user_data )
+                        void* host_user_data,
+                        LLPluginInstance::sendMessageFunction *plugin_send_func,
+                        void **plugin_user_data )
 {
-	MediaPluginExample* self = new MediaPluginExample( host_send_func, host_user_data );
-	*plugin_send_func = MediaPluginExample::staticReceiveMessage;
-	*plugin_user_data = ( void* )self;
+    MediaPluginExample* self = new MediaPluginExample( host_send_func, host_user_data );
+    *plugin_send_func = MediaPluginExample::staticReceiveMessage;
+    *plugin_user_data = ( void* )self;
 
-	return 0;
+    return 0;
 }
+
diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt
index 05f12366066ccd8881b75291ca412f2ee24065fe..3b1f6795401cd2a35558e492a07688d470e3ea3a 100644
--- a/indra/media_plugins/webkit/CMakeLists.txt
+++ b/indra/media_plugins/webkit/CMakeLists.txt
@@ -27,6 +27,7 @@ include_directories(
     ${LLIMAGE_INCLUDE_DIRS}
     ${LLRENDER_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
+    ${LLQTWEBKIT_INCLUDE_DIR}
 )
 
 
diff --git a/indra/media_plugins/webkit/media_plugin_webkit.cpp b/indra/media_plugins/webkit/media_plugin_webkit.cpp
index bd1a44a930702c885b62fd99853dd87e4517d979..d6f8ae3e16ae6d3b6a6aa58310cd06c4fe554ec3 100644
--- a/indra/media_plugins/webkit/media_plugin_webkit.cpp
+++ b/indra/media_plugins/webkit/media_plugin_webkit.cpp
@@ -341,7 +341,7 @@ class MediaPluginWebKit :
 		url << std::setfill('0') << std::setw(2) << std::hex << int(mBackgroundB * 255.0f);
 		url << "%22%3E%3C/body%3E%3C/html%3E";
 		
-		lldebugs << "data url is: " << url.str() << llendl;
+		//lldebugs << "data url is: " << url.str() << llendl;
 					
 		LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, url.str() );
 //		LLQtWebKit::getInstance()->navigateTo( mBrowserWindowId, "about:blank" );
@@ -407,6 +407,8 @@ class MediaPluginWebKit :
 		{
 			LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "navigate_begin");
 			message.setValue("uri", event.getEventUri());
+			message.setValueBoolean("history_back_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_BACK));
+			message.setValueBoolean("history_forward_available", LLQtWebKit::getInstance()->userActionIsEnabled( mBrowserWindowId, LLQtWebKit::UA_NAVIGATE_FORWARD));
 			sendMessage(message);
 		
 			setStatus(STATUS_LOADING);
@@ -569,6 +571,57 @@ class MediaPluginWebKit :
 		return blockingPickFile();
 	}
 	
+	std::string mAuthUsername;
+	std::string mAuthPassword;
+	bool mAuthOK;
+	
+	////////////////////////////////////////////////////////////////////////////////
+	// virtual
+	bool onAuthRequest(const std::string &in_url, const std::string &in_realm, std::string &out_username, std::string &out_password)
+	{
+		mAuthOK = false;
+
+		LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "auth_request");
+		message.setValue("url", in_url);
+		message.setValue("realm", in_realm);
+		message.setValueBoolean("blocking_request", true);
+				
+		// The "blocking_request" key in the message means this sendMessage call will block until a response is received.
+		sendMessage(message);
+		
+		if(mAuthOK)
+		{
+			out_username = mAuthUsername;
+			out_password = mAuthPassword;
+		}
+		
+		return mAuthOK;
+	}
+	
+	void authResponse(LLPluginMessage &message)
+	{
+		mAuthOK = message.getValueBoolean("ok");
+		if(mAuthOK)
+		{
+			mAuthUsername = message.getValue("username");
+			mAuthPassword = message.getValue("password");
+		}
+	}
+	
+	////////////////////////////////////////////////////////////////////////////////
+	// virtual
+	void onLinkHovered(const EventType& event)
+	{
+		if(mInitState >= INIT_STATE_NAVIGATE_COMPLETE)
+		{
+			LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "link_hovered");
+			message.setValue("link", event.getEventUri());
+			message.setValue("title", event.getStringValue());
+			message.setValue("text", event.getStringValue2());
+			sendMessage(message);
+		}
+	}
+	
 	LLQtWebKit::EKeyboardModifier decodeModifiers(std::string &modifiers)
 	{
 		int result = 0;
@@ -1096,6 +1149,10 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
 			{
 				onPickFileResponse(message_in.getValue("file"));
 			}
+			if(message_name == "auth_response")
+			{
+				authResponse(message_in);
+			}
 			else
 			{
 //				std::cerr << "MediaPluginWebKit::receiveMessage: unknown media message: " << message_string << std::endl;
@@ -1182,6 +1239,22 @@ void MediaPluginWebKit::receiveMessage(const char *message_string)
 				mUserAgent = message_in.getValue("user_agent");
 				LLQtWebKit::getInstance()->setBrowserAgentId( mUserAgent );
 			}
+			else if(message_name == "ignore_ssl_cert_errors")
+			{
+#if LLQTWEBKIT_API_VERSION >= 3
+				LLQtWebKit::getInstance()->setIgnoreSSLCertErrors( message_in.getValueBoolean("ignore") );
+#else
+				llwarns << "Ignoring ignore_ssl_cert_errors message (llqtwebkit version is too old)." << llendl;
+#endif
+			}
+			else if(message_name == "add_certificate_file_path")
+			{
+#if LLQTWEBKIT_API_VERSION >= 6
+				LLQtWebKit::getInstance()->addCAFile( message_in.getValue("path") );
+#else
+				llwarns << "Ignoring add_certificate_file_path message (llqtwebkit version is too old)." << llendl;
+#endif
+			}
 			else if(message_name == "init_history")
 			{
 				// Initialize browser history
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 8c404a4ca21a3cd8eb936fbfe659a1df69635ee1..ce22a52460b4354ddb3bde5a0549a82a9e09c4c4 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -65,6 +65,7 @@ include_directories(
     ${LSCRIPT_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}/lscript_compile
     ${LLLOGIN_INCLUDE_DIRS}
+    ${UPDATER_INCLUDE_DIRS}
     )
 
 set(viewer_SOURCE_FILES
@@ -144,6 +145,7 @@ set(viewer_SOURCE_FILES
     lleventnotifier.cpp
     lleventpoll.cpp
     llexpandabletextbox.cpp
+    llexternaleditor.cpp
     llface.cpp
     llfasttimerview.cpp
     llfavoritesbar.cpp
@@ -201,6 +203,7 @@ set(viewer_SOURCE_FILES
     llfloaterpostprocess.cpp
     llfloaterpreference.cpp
     llfloaterproperties.cpp
+    llfloaterregiondebugconsole.cpp
     llfloaterregioninfo.cpp
     llfloaterreporter.cpp
     llfloaterscriptdebug.cpp
@@ -220,6 +223,7 @@ set(viewer_SOURCE_FILES
     llfloaterurlentry.cpp
     llfloatervoiceeffect.cpp
     llfloaterwater.cpp
+    llfloaterwebcontent.cpp
     llfloaterwhitelistentry.cpp
     llfloaterwindlight.cpp
     llfloaterwindowsize.cpp
@@ -283,6 +287,7 @@ set(viewer_SOURCE_FILES
     llloginhandler.cpp
     lllogininstance.cpp
     llmachineid.cpp
+    llmainlooprepeater.cpp
     llmanip.cpp
     llmaniprotate.cpp
     llmanipscale.cpp
@@ -444,6 +449,7 @@ set(viewer_SOURCE_FILES
     lltoastimpanel.cpp
     lltoastnotifypanel.cpp
     lltoastpanel.cpp
+    lltoastscripttextbox.cpp
     lltool.cpp
     lltoolbrush.cpp
     lltoolcomp.cpp
@@ -477,6 +483,7 @@ set(viewer_SOURCE_FILES
     llvectorperfoptions.cpp
     llversioninfo.cpp
     llviewchildren.cpp
+    llviewerassetstats.cpp
     llviewerassetstorage.cpp
     llviewerassettype.cpp
     llviewerattachmenu.cpp
@@ -675,6 +682,7 @@ set(viewer_HEADER_FILES
     lleventnotifier.h
     lleventpoll.h
     llexpandabletextbox.h
+    llexternaleditor.h
     llface.h
     llfasttimerview.h
     llfavoritesbar.h
@@ -732,6 +740,7 @@ set(viewer_HEADER_FILES
     llfloaterpostprocess.h
     llfloaterpreference.h
     llfloaterproperties.h
+    llfloaterregiondebugconsole.h
     llfloaterregioninfo.h
     llfloaterreporter.h
     llfloaterscriptdebug.h
@@ -751,6 +760,7 @@ set(viewer_HEADER_FILES
     llfloaterurlentry.h
     llfloatervoiceeffect.h
     llfloaterwater.h
+    llfloaterwebcontent.h
     llfloaterwhitelistentry.h
     llfloaterwindlight.h
     llfloaterwindowsize.h
@@ -814,6 +824,7 @@ set(viewer_HEADER_FILES
     llloginhandler.h
     lllogininstance.h
     llmachineid.h
+    llmainlooprepeater.h
     llmanip.h
     llmaniprotate.h
     llmanipscale.h
@@ -972,6 +983,7 @@ set(viewer_HEADER_FILES
     lltoastimpanel.h
     lltoastnotifypanel.h
     lltoastpanel.h
+    lltoastscripttextbox.h
     lltool.h
     lltoolbrush.h
     lltoolcomp.h
@@ -1006,6 +1018,7 @@ set(viewer_HEADER_FILES
     llvectorperfoptions.h
     llversioninfo.h
     llviewchildren.h
+    llviewerassetstats.h
     llviewerassetstorage.h
     llviewerassettype.h
     llviewerattachmenu.h
@@ -1317,7 +1330,7 @@ set(viewer_APPSETTINGS_FILES
     app_settings/grass.xml
     app_settings/high_graphics.xml
     app_settings/ignorable_dialogs.xml
-    app_settings/keys.ini
+    app_settings/keys.xml
     app_settings/keywords.ini
     app_settings/logcontrol.xml
     app_settings/low_graphics.xml
@@ -1635,7 +1648,14 @@ if (WINDOWS)
     endif (PACKAGE)
 endif (WINDOWS)
 
+# *NOTE - this list is very sensitive to ordering, test carefully on all
+# platforms if you change the releative order of the entries here.
+# In particular, cmake 2.6.4 (when buidling with linux/makefile generators)
+# appears to sometimes de-duplicate redundantly listed dependencies improperly.
+# To work around this, higher level modules should be listed before the modules
+# that they depend upon. -brad
 target_link_libraries(${VIEWER_BINARY_NAME}
+    ${UPDATER_LIBRARIES}
     ${LLAUDIO_LIBRARIES}
     ${LLCHARACTER_LIBRARIES}
     ${LLIMAGE_LIBRARIES}
@@ -1832,21 +1852,31 @@ if (PACKAGE)
     set(VIEWER_COPY_MANIFEST copy_l_viewer_manifest)
   endif (LINUX)
 
-  add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
-    COMMAND "${PYTHON_EXECUTABLE}"
-    ARGS
-      "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
-      "${VIEWER_DIST_DIR}"
-      "${VIEWER_EXE_GLOBS}"
-      "${VIEWER_LIB_GLOB}"
-      "${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/bin/dump_syms"
-      "${VIEWER_SYMBOL_FILE}"
-    DEPENDS generate_breakpad_symbols.py
-    VERBATIM
-  )
-  add_custom_target(generate_breakpad_symbols ALL DEPENDS "${VIEWER_SYMBOL_FILE}")
-  add_dependencies(generate_breakpad_symbols "${VIEWER_BINARY_NAME}" "${VIEWER_COPY_MANIFEST}")
-  add_dependencies(package generate_breakpad_symbols)
+  if(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
+    if(CMAKE_CFG_INTDIR STREQUAL ".")
+      set(LLBUILD_CONFIG ${CMAKE_BUILD_TYPE})
+    else(CMAKE_CFG_INTDIR STREQUAL ".")
+      # set LLBUILD_CONFIG to be a shell variable evaluated at build time
+      # reflecting the configuration we are currently building.
+      set(LLBUILD_CONFIG ${CMAKE_CFG_INTDIR})
+    endif(CMAKE_CFG_INTDIR STREQUAL ".")
+    add_custom_command(OUTPUT "${VIEWER_SYMBOL_FILE}"
+      COMMAND "${PYTHON_EXECUTABLE}"
+      ARGS
+        "${CMAKE_CURRENT_SOURCE_DIR}/generate_breakpad_symbols.py"
+        "${LLBUILD_CONFIG}"
+        "${VIEWER_DIST_DIR}"
+        "${VIEWER_EXE_GLOBS}"
+        "${VIEWER_LIB_GLOB}"
+        "${LIBS_PREBUILT_DIR}/${LL_ARCH_DIR}/bin/dump_syms"
+        "${VIEWER_SYMBOL_FILE}"
+        DEPENDS generate_breakpad_symbols.py
+        VERBATIM)
+
+    add_custom_target(generate_breakpad_symbols DEPENDS "${VIEWER_SYMBOL_FILE}")
+    add_dependencies(generate_breakpad_symbols "${VIEWER_BINARY_NAME}" "${VIEWER_COPY_MANIFEST}")
+    add_dependencies(package generate_breakpad_symbols)
+  endif(RELEASE_CRASH_REPORTING OR NON_RELEASE_CRASH_REPORTING)
 endif (PACKAGE)
 
 if (LL_TESTS)
@@ -1858,7 +1888,9 @@ if (LL_TESTS)
     lldateutil.cpp
     llmediadataclient.cpp
     lllogininstance.cpp
+    llremoteparcelrequest.cpp
     llviewerhelputil.cpp
+    llversioninfo.cpp
     llworldmap.cpp
     llworldmipmap.cpp
   )
@@ -1936,6 +1968,16 @@ if (LL_TESTS)
     "${test_libs}"
     )
 
+  LL_ADD_INTEGRATION_TEST(llsimplestat
+	""
+    "${test_libs}"
+    )
+
+  LL_ADD_INTEGRATION_TEST(llviewerassetstats
+	llviewerassetstats.cpp
+    "${test_libs}"
+    )
+
   #ADD_VIEWER_BUILD_TEST(llmemoryview viewer)
   #ADD_VIEWER_BUILD_TEST(llagentaccess viewer)
   #ADD_VIEWER_BUILD_TEST(lltextureinfo viewer)
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index 0562cf5480e901c8d090674e14f53aee5ab961ee..e4ac455e7cb659ecb95274e2390e271ebb9315bf 100644
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -363,8 +363,7 @@
     <map>
       <key>count</key>
       <integer>1</integer>
-      <key>map-to</key>
-      <string>VersionChannelName</string>
+      <!-- Special case. Not mapped to a setting. -->
     </map>
 
     <key>loginpage</key>
@@ -400,6 +399,5 @@
       <key>map-to</key>
       <string>DisableCrashLogger</string>
     </map>
-
   </map>
 </llsd>
diff --git a/indra/newview/app_settings/ignorable_dialogs.xml b/indra/newview/app_settings/ignorable_dialogs.xml
index 9ddf007ce7623516f99041e97ed40136d0d49100..89fd4e59358ceb9aa21b6d5f4a6f605d4f5248a3 100644
--- a/indra/newview/app_settings/ignorable_dialogs.xml
+++ b/indra/newview/app_settings/ignorable_dialogs.xml
@@ -23,6 +23,17 @@
     <key>Value</key>
     <integer>1</integer>
   </map>
+  <key>FirstNotUseAvatarPicker</key>
+  <map>
+    <key>Comment</key>
+    <string>Shows hint when resident doesn't activate avatar picker</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
   <key>FirstNotUseSidePanel</key>
   <map>
     <key>Comment</key>
@@ -56,6 +67,17 @@
     <key>Value</key>
     <integer>1</integer>
   </map>
+  <key>FirstViewPopup</key>
+  <map>
+    <key>Comment</key>
+    <string>Shows hint when resident opens view popup</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
   <key>FirstReceiveLindens</key>
   <map>
     <key>Comment</key>
diff --git a/indra/newview/app_settings/keys.ini b/indra/newview/app_settings/keys.ini
deleted file mode 100644
index b79e5bf508a81990b1f8d56da1ee7eab7df17a4c..0000000000000000000000000000000000000000
--- a/indra/newview/app_settings/keys.ini
+++ /dev/null
@@ -1,357 +0,0 @@
-# keys.ini
-#
-# keyboard binding initialization
-#
-# comments must have # in the first column
-# blank lines OK
-#
-# Format:
-# mode key mask function
-#
-# mode must be one of FIRST_PERSON, THIRD_PERSON, EDIT, EDIT_AVATAR, or CONVERSATION
-# key must be upper case, or SPACE, HOME, END, PGUP, PGDN, LEFT, RIGHT, UP, DOWN,
-#     or one of ,.;'[]
-# mask must be NONE, SHIFT, ALT, ALT_SHIFT.
-# Control is reserved for user commands.
-# function must be a function named in llkeyboard.cpp
-
-FIRST_PERSON	A		NONE		slide_left
-FIRST_PERSON	D		NONE		slide_right
-FIRST_PERSON	W		NONE		push_forward
-FIRST_PERSON	S		NONE		push_backward
-FIRST_PERSON	E		NONE		jump
-FIRST_PERSON	C		NONE		push_down
-FIRST_PERSON	F		NONE		toggle_fly
-
-FIRST_PERSON	LEFT	NONE		slide_left
-FIRST_PERSON	RIGHT	NONE		slide_right
-FIRST_PERSON	UP		NONE		push_forward
-FIRST_PERSON	DOWN	NONE		push_backward
-FIRST_PERSON	PGUP	NONE		jump
-FIRST_PERSON	PGDN	NONE		push_down
-FIRST_PERSON	HOME	NONE		toggle_fly
-
-FIRST_PERSON	PAD_LEFT	NONE		slide_left
-FIRST_PERSON	PAD_RIGHT	NONE		slide_right
-FIRST_PERSON	PAD_UP		NONE		push_forward
-FIRST_PERSON	PAD_DOWN	NONE		push_backward
-FIRST_PERSON	PAD_PGUP	NONE		jump
-FIRST_PERSON	PAD_PGDN	NONE		push_down
-FIRST_PERSON	PAD_HOME	NONE		toggle_fly
-FIRST_PERSON	PAD_CENTER	NONE		stop_moving
-FIRST_PERSON	PAD_ENTER	NONE		start_chat
-FIRST_PERSON	PAD_DIVIDE	NONE		start_gesture
-
-FIRST_PERSON	A		SHIFT		slide_left
-FIRST_PERSON	D		SHIFT		slide_right
-FIRST_PERSON	W		SHIFT		push_forward
-FIRST_PERSON	S		SHIFT		push_backward
-FIRST_PERSON	E		SHIFT		jump
-FIRST_PERSON	C		SHIFT		push_down
-FIRST_PERSON	F		SHIFT		toggle_fly
-
-FIRST_PERSON	SPACE	NONE		stop_moving
-FIRST_PERSON	ENTER	NONE		start_chat
-FIRST_PERSON	DIVIDE	NONE		start_gesture
-
-FIRST_PERSON	LEFT	SHIFT		slide_left
-FIRST_PERSON	RIGHT	SHIFT		slide_right
-FIRST_PERSON	UP		SHIFT		push_forward
-FIRST_PERSON	DOWN	SHIFT		push_backward
-FIRST_PERSON	PGUP	SHIFT		jump
-FIRST_PERSON	PGDN	SHIFT		push_down
-
-FIRST_PERSON	PAD_LEFT	SHIFT		slide_left
-FIRST_PERSON	PAD_RIGHT	SHIFT		slide_right
-FIRST_PERSON	PAD_UP		SHIFT		push_forward
-FIRST_PERSON	PAD_DOWN	SHIFT		push_backward
-FIRST_PERSON	PAD_PGUP	SHIFT		jump
-FIRST_PERSON	PAD_PGDN	SHIFT		push_down
-FIRST_PERSON	PAD_HOME	SHIFT		toggle_fly
-FIRST_PERSON	PAD_ENTER	SHIFT		start_chat
-FIRST_PERSON	PAD_DIVIDE	SHIFT		start_gesture
-
-THIRD_PERSON	A		NONE		turn_left
-THIRD_PERSON	D		NONE		turn_right
-THIRD_PERSON	A		SHIFT		slide_left
-THIRD_PERSON	D		SHIFT		slide_right
-THIRD_PERSON	W		NONE		push_forward
-THIRD_PERSON	S		NONE		push_backward
-THIRD_PERSON	W		SHIFT		push_forward
-THIRD_PERSON	S		SHIFT		push_backward
-THIRD_PERSON	E		NONE		jump
-THIRD_PERSON	C		NONE		push_down
-THIRD_PERSON	E		SHIFT		jump
-THIRD_PERSON	C		SHIFT		push_down
-
-THIRD_PERSON	F		NONE		toggle_fly
-THIRD_PERSON	F		SHIFT		toggle_fly
-
-THIRD_PERSON	SPACE	NONE		stop_moving
-THIRD_PERSON	ENTER	NONE		start_chat
-THIRD_PERSON	DIVIDE	NONE		start_gesture
-
-THIRD_PERSON	LEFT	NONE		turn_left
-THIRD_PERSON	LEFT	SHIFT		slide_left
-THIRD_PERSON	RIGHT	NONE		turn_right
-THIRD_PERSON	RIGHT	SHIFT		slide_right
-THIRD_PERSON	UP		NONE		push_forward
-THIRD_PERSON	DOWN	NONE		push_backward
-THIRD_PERSON	UP		SHIFT		push_forward
-THIRD_PERSON	DOWN	SHIFT		push_backward
-THIRD_PERSON	PGUP	NONE		jump
-THIRD_PERSON	PGDN	NONE		push_down
-THIRD_PERSON	PGUP	SHIFT		jump
-THIRD_PERSON	PGDN	SHIFT		push_down
-THIRD_PERSON	HOME	SHIFT		toggle_fly
-THIRD_PERSON	HOME	NONE		toggle_fly
-
-THIRD_PERSON	PAD_LEFT	NONE		turn_left
-THIRD_PERSON	PAD_LEFT	SHIFT		slide_left
-THIRD_PERSON	PAD_RIGHT	NONE		turn_right
-THIRD_PERSON	PAD_RIGHT	SHIFT		slide_right
-THIRD_PERSON	PAD_UP		NONE		push_forward
-THIRD_PERSON	PAD_DOWN	NONE		push_backward
-THIRD_PERSON	PAD_UP		SHIFT		push_forward
-THIRD_PERSON	PAD_DOWN	SHIFT		push_backward
-THIRD_PERSON	PAD_PGUP	NONE		jump
-THIRD_PERSON	PAD_PGDN	NONE		push_down
-THIRD_PERSON	PAD_PGUP	SHIFT		jump
-THIRD_PERSON	PAD_PGDN	SHIFT		push_down
-THIRD_PERSON	PAD_HOME	NONE		toggle_fly
-THIRD_PERSON	PAD_HOME	SHIFT		toggle_fly
-THIRD_PERSON	PAD_CENTER	NONE		stop_moving
-THIRD_PERSON	PAD_CENTER	SHIFT		stop_moving
-THIRD_PERSON	PAD_ENTER	NONE		start_chat
-THIRD_PERSON	PAD_ENTER	SHIFT		start_chat
-THIRD_PERSON	PAD_DIVIDE	NONE		start_gesture
-THIRD_PERSON	PAD_DIVIDE	SHIFT		start_gesture
-
-# Camera controls in third person on Alt
-THIRD_PERSON	LEFT	ALT			spin_around_cw
-THIRD_PERSON	RIGHT	ALT			spin_around_ccw
-THIRD_PERSON	UP		ALT			move_forward
-THIRD_PERSON	DOWN	ALT			move_backward
-THIRD_PERSON	PGUP	ALT			spin_over
-THIRD_PERSON	PGDN	ALT			spin_under
-
-THIRD_PERSON	A		ALT			spin_around_cw
-THIRD_PERSON	D		ALT			spin_around_ccw
-THIRD_PERSON	W		ALT			move_forward
-THIRD_PERSON	S		ALT			move_backward
-THIRD_PERSON	E		ALT			spin_over
-THIRD_PERSON	C		ALT			spin_under
-
-THIRD_PERSON	PAD_LEFT	ALT			spin_around_cw
-THIRD_PERSON	PAD_RIGHT	ALT			spin_around_ccw
-THIRD_PERSON	PAD_UP		ALT			move_forward
-THIRD_PERSON	PAD_DOWN	ALT			move_backward
-THIRD_PERSON	PAD_PGUP	ALT			spin_over
-THIRD_PERSON	PAD_PGDN	ALT			spin_under
-THIRD_PERSON	PAD_ENTER	ALT			start_chat
-THIRD_PERSON	PAD_DIVIDE	ALT			start_gesture
-
-# mimic alt zoom behavior with keyboard only
-THIRD_PERSON	A		CTL_ALT			spin_around_cw
-THIRD_PERSON	D		CTL_ALT			spin_around_ccw
-THIRD_PERSON	W		CTL_ALT			spin_over
-THIRD_PERSON	S		CTL_ALT			spin_under
-THIRD_PERSON	E		CTL_ALT			spin_over
-THIRD_PERSON	C		CTL_ALT			spin_under
-
-THIRD_PERSON	LEFT	CTL_ALT			spin_around_cw
-THIRD_PERSON	RIGHT	CTL_ALT			spin_around_ccw
-THIRD_PERSON	UP		CTL_ALT			spin_over
-THIRD_PERSON	DOWN	CTL_ALT			spin_under
-THIRD_PERSON	PGUP	CTL_ALT			spin_over
-THIRD_PERSON	PGDN	CTL_ALT			spin_under
-
-THIRD_PERSON	PAD_LEFT	CTL_ALT			spin_around_cw
-THIRD_PERSON	PAD_RIGHT	CTL_ALT			spin_around_ccw
-THIRD_PERSON	PAD_UP		CTL_ALT			spin_over
-THIRD_PERSON	PAD_DOWN	CTL_ALT			spin_under
-THIRD_PERSON	PAD_PGUP	CTL_ALT			spin_over
-THIRD_PERSON	PAD_PGDN	CTL_ALT			spin_under
-THIRD_PERSON	PAD_ENTER	CTL_ALT			start_chat
-THIRD_PERSON	PAD_DIVIDE	CTL_ALT			start_gesture
-
-# Therefore pan on Alt-Shift
-THIRD_PERSON	A		CTL_ALT_SHIFT	pan_left
-THIRD_PERSON	D		CTL_ALT_SHIFT	pan_right
-THIRD_PERSON	W		CTL_ALT_SHIFT	pan_up
-THIRD_PERSON	S		CTL_ALT_SHIFT	pan_down
-
-THIRD_PERSON	LEFT	CTL_ALT_SHIFT	pan_left
-THIRD_PERSON	RIGHT	CTL_ALT_SHIFT	pan_right
-THIRD_PERSON	UP		CTL_ALT_SHIFT	pan_up
-THIRD_PERSON	DOWN	CTL_ALT_SHIFT	pan_down
-
-THIRD_PERSON	PAD_LEFT	CTL_ALT_SHIFT	pan_left
-THIRD_PERSON	PAD_RIGHT	CTL_ALT_SHIFT	pan_right
-THIRD_PERSON	PAD_UP		CTL_ALT_SHIFT	pan_up
-THIRD_PERSON	PAD_DOWN	CTL_ALT_SHIFT	pan_down
-THIRD_PERSON	PAD_ENTER	CTL_ALT_SHIFT	start_chat
-THIRD_PERSON	PAD_DIVIDE	CTL_ALT_SHIFT	start_gesture
-
-# Basic editing camera control
-EDIT			A		NONE		spin_around_cw
-EDIT			D		NONE		spin_around_ccw
-EDIT			W		NONE		move_forward
-EDIT			S		NONE		move_backward
-EDIT			E		NONE		spin_over
-EDIT			C		NONE		spin_under
-EDIT			ENTER	NONE		start_chat
-EDIT			DIVIDE	NONE		start_gesture
-EDIT			PAD_ENTER	NONE	start_chat
-EDIT			PAD_DIVIDE	NONE	start_gesture
-
-EDIT			LEFT	NONE		spin_around_cw
-EDIT			RIGHT	NONE		spin_around_ccw
-EDIT			UP		NONE		move_forward
-EDIT			DOWN	NONE		move_backward
-EDIT			PGUP	NONE		spin_over
-EDIT			PGDN	NONE		spin_under
-
-EDIT			A		SHIFT		pan_left
-EDIT			D		SHIFT		pan_right
-EDIT			W		SHIFT		pan_up
-EDIT			S		SHIFT		pan_down
-
-EDIT			LEFT	SHIFT		pan_left
-EDIT			RIGHT	SHIFT		pan_right
-EDIT			UP		SHIFT		pan_up
-EDIT			DOWN	SHIFT		pan_down
-
-# Walking works with ALT held down.
-EDIT			A		ALT			slide_left
-EDIT			D		ALT			slide_right
-EDIT			W		ALT			push_forward
-EDIT			S		ALT			push_backward
-EDIT			E		ALT			jump
-EDIT			C		ALT			push_down
-
-EDIT			LEFT	ALT			slide_left
-EDIT			RIGHT	ALT			slide_right
-EDIT			UP		ALT			push_forward
-EDIT			DOWN	ALT			push_backward
-EDIT			PGUP	ALT			jump
-EDIT			PGDN	ALT			push_down
-EDIT			HOME	ALT			toggle_fly
-
-EDIT			PAD_LEFT	ALT			slide_left
-EDIT			PAD_RIGHT	ALT			slide_right
-EDIT			PAD_UP		ALT			push_forward
-EDIT			PAD_DOWN	ALT			push_backward
-EDIT			PAD_PGUP	ALT			jump
-EDIT			PAD_PGDN	ALT			push_down
-EDIT			PAD_ENTER	ALT			start_chat
-EDIT			PAD_DIVIDE	ALT			start_gesture
-
-SITTING			A	ALT			spin_around_cw
-SITTING			D	ALT			spin_around_ccw
-SITTING			W	ALT			move_forward
-SITTING			S	ALT			move_backward
-SITTING			E	ALT			spin_over_sitting
-SITTING			C	ALT			spin_under_sitting
-
-SITTING			LEFT	ALT			spin_around_cw
-SITTING			RIGHT	ALT			spin_around_ccw
-SITTING			UP		ALT			move_forward
-SITTING			DOWN	ALT			move_backward
-SITTING			PGUP	ALT			spin_over
-SITTING			PGDN	ALT			spin_under
-
-SITTING			A	CTL_ALT			spin_around_cw
-SITTING 		D	CTL_ALT			spin_around_ccw
-SITTING			W	CTL_ALT			spin_over
-SITTING			S	CTL_ALT			spin_under
-SITTING 		E	CTL_ALT			spin_over
-SITTING			C	CTL_ALT			spin_under
-
-SITTING			LEFT	CTL_ALT			spin_around_cw
-SITTING			RIGHT	CTL_ALT			spin_around_ccw
-SITTING			UP		CTL_ALT			spin_over
-SITTING			DOWN	CTL_ALT			spin_under
-SITTING			PGUP	CTL_ALT			spin_over
-SITTING			PGDN	CTL_ALT			spin_under
-
-
-SITTING			A		NONE		spin_around_cw_sitting
-SITTING			D		NONE		spin_around_ccw_sitting
-SITTING			W		NONE		move_forward_sitting
-SITTING			S		NONE		move_backward_sitting
-SITTING			E		NONE		spin_over_sitting
-SITTING			C		NONE		spin_under_sitting
-
-SITTING			LEFT	NONE		spin_around_cw_sitting
-SITTING			RIGHT	NONE		spin_around_ccw_sitting
-SITTING			UP		NONE		move_forward_sitting
-SITTING			DOWN	NONE		move_backward_sitting
-SITTING			PGUP	NONE		spin_over_sitting
-SITTING			PGDN	NONE		spin_under_sitting
-
-SITTING			PAD_LEFT	NONE		spin_around_cw_sitting
-SITTING			PAD_RIGHT	NONE		spin_around_ccw_sitting
-SITTING			PAD_UP		NONE		move_forward_sitting
-SITTING			PAD_DOWN	NONE		move_backward_sitting
-SITTING			PAD_PGUP	NONE		spin_over_sitting
-SITTING			PAD_PGDN	NONE		spin_under_sitting
-SITTING			PAD_CENTER	NONE		stop_moving
-SITTING			PAD_ENTER	NONE		start_chat
-SITTING			PAD_DIVIDE	NONE		start_gesture
-
-# these are for passing controls when sitting on vehicles
-SITTING			A		SHIFT		slide_left
-SITTING			D		SHIFT		slide_right
-SITTING			LEFT	SHIFT		slide_left
-SITTING			RIGHT	SHIFT		slide_right
-
-SITTING			PAD_LEFT	SHIFT		slide_left
-SITTING			PAD_RIGHT	SHIFT		slide_right
-SITTING			PAD_ENTER	SHIFT		start_chat
-SITTING			PAD_DIVIDE	SHIFT		start_gesture
-
-# pan on Alt-Shift
-SITTING			A		CTL_ALT_SHIFT	pan_left
-SITTING			D		CTL_ALT_SHIFT	pan_right
-SITTING			W		CTL_ALT_SHIFT	pan_up
-SITTING			S		CTL_ALT_SHIFT	pan_down
-
-SITTING			LEFT	CTL_ALT_SHIFT	pan_left
-SITTING			RIGHT	CTL_ALT_SHIFT	pan_right
-SITTING			UP		CTL_ALT_SHIFT	pan_up
-SITTING			DOWN	CTL_ALT_SHIFT	pan_down
-
-SITTING			PAD_LEFT	CTL_ALT_SHIFT	pan_left
-SITTING			PAD_RIGHT	CTL_ALT_SHIFT	pan_right
-SITTING			PAD_UP		CTL_ALT_SHIFT	pan_up
-SITTING			PAD_DOWN	CTL_ALT_SHIFT	pan_down
-SITTING			PAD_ENTER	CTL_ALT_SHIFT	start_chat
-SITTING			PAD_DIVIDE	CTL_ALT_SHIFT	start_gesture
-
-SITTING			ENTER	NONE		start_chat
-SITTING			DIVIDE	NONE		start_gesture
-
-# Avatar editing camera controls
-EDIT_AVATAR		A		NONE		edit_avatar_spin_cw
-EDIT_AVATAR		D		NONE		edit_avatar_spin_ccw
-EDIT_AVATAR		W		NONE		edit_avatar_move_forward
-EDIT_AVATAR		S		NONE		edit_avatar_move_backward
-EDIT_AVATAR		E		NONE		edit_avatar_spin_over
-EDIT_AVATAR		C		NONE		edit_avatar_spin_under
-EDIT_AVATAR		LEFT	NONE		edit_avatar_spin_cw
-EDIT_AVATAR		RIGHT	NONE		edit_avatar_spin_ccw
-EDIT_AVATAR		UP		NONE		edit_avatar_move_forward
-EDIT_AVATAR		DOWN	NONE		edit_avatar_move_backward
-EDIT_AVATAR		PGUP	NONE		edit_avatar_spin_over
-EDIT_AVATAR		PGDN	NONE		edit_avatar_spin_under
-EDIT_AVATAR		ENTER	NONE		start_chat
-EDIT_AVATAR		DIVIDE	NONE		start_gesture
-EDIT_AVATAR		PAD_LEFT	NONE	edit_avatar_spin_cw
-EDIT_AVATAR		PAD_RIGHT	NONE	edit_avatar_spin_ccw
-EDIT_AVATAR		PAD_UP		NONE	edit_avatar_move_forward
-EDIT_AVATAR		PAD_DOWN	NONE	edit_avatar_move_backward
-EDIT_AVATAR		PAD_PGUP	NONE	edit_avatar_spin_over
-EDIT_AVATAR		PAD_PGDN	NONE	edit_avatar_spin_under
-EDIT_AVATAR		PAD_ENTER	NONE	start_chat
-EDIT_AVATAR		PAD_DIVIDE	NONE	start_gesture
diff --git a/indra/newview/app_settings/keys.xml b/indra/newview/app_settings/keys.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d085475c6ca009d262a84094bf9adb1c8ba72ff7
--- /dev/null
+++ b/indra/newview/app_settings/keys.xml
@@ -0,0 +1,350 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<keys>
+  <first_person>
+    <binding key="A" mask="NONE" command="slide_left"/>
+    <binding key="D" mask="NONE" command="slide_right"/>
+    <binding key="W" mask="NONE" command="push_forward"/>
+    <binding key="S" mask="NONE" command="push_backward"/>
+    <binding key="E" mask="NONE" command="jump"/>
+    <binding key="C" mask="NONE" command="push_down"/>
+    <binding key="F" mask="NONE" command="toggle_fly"/>
+
+    <binding key="LEFT" mask="NONE" command="slide_left"/>
+    <binding key="RIGHT" mask="NONE" command="slide_right"/>
+    <binding key="UP" mask="NONE" command="push_forward"/>
+    <binding key="DOWN" mask="NONE" command="push_backward"/>
+    <binding key="PGUP" mask="NONE" command="jump"/>
+    <binding key="PGDN" mask="NONE" command="push_down"/>
+    <binding key="HOME" mask="NONE" command="toggle_fly"/>
+
+    <binding key="PAD_LEFT" mask="NONE" command="slide_left"/>
+    <binding key="PAD_RIGHT" mask="NONE" command="slide_right"/>
+    <binding key="PAD_UP" mask="NONE" command="push_forward"/>
+    <binding key="PAD_DOWN" mask="NONE" command="push_backward"/>
+    <binding key="PAD_PGUP" mask="NONE" command="jump"/>
+    <binding key="PAD_PGDN" mask="NONE" command="push_down"/>
+    <binding key="PAD_HOME" mask="NONE" command="toggle_fly"/>
+    <binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
+    <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
+
+    <binding key="A" mask="SHIFT" command="slide_left"/>
+    <binding key="D" mask="SHIFT" command="slide_right"/>
+    <binding key="W" mask="SHIFT" command="push_forward"/>
+    <binding key="S" mask="SHIFT" command="push_backward"/>
+    <binding key="E" mask="SHIFT" command="jump"/>
+    <binding key="C" mask="SHIFT" command="push_down"/>
+    <binding key="F" mask="SHIFT" command="toggle_fly"/>
+
+    <binding key="SPACE" mask="NONE" command="stop_moving"/>
+    <binding key="ENTER" mask="NONE" command="start_chat"/>
+    <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
+
+    <binding key="LEFT" mask="SHIFT" command="slide_left"/>
+    <binding key="RIGHT" mask="SHIFT" command="slide_right"/>
+    <binding key="UP" mask="SHIFT" command="push_forward"/>
+    <binding key="DOWN" mask="SHIFT" command="push_backward"/>
+    <binding key="PGUP" mask="SHIFT" command="jump"/>
+    <binding key="PGDN" mask="SHIFT" command="push_down"/>
+
+    <binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
+    <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
+    <binding key="PAD_UP" mask="SHIFT" command="push_forward"/>
+    <binding key="PAD_DOWN" mask="SHIFT" command="push_backward"/>
+    <binding key="PAD_PGUP" mask="SHIFT" command="jump"/>
+    <binding key="PAD_PGDN" mask="SHIFT" command="push_down"/>
+    <binding key="PAD_HOME" mask="SHIFT" command="toggle_fly"/>
+    <binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
+  </first_person>
+  <third_person>
+    <binding key="A" mask="NONE" command="turn_left"/>
+    <binding key="D" mask="NONE" command="turn_right"/>
+    <binding key="A" mask="SHIFT" command="slide_left"/>
+    <binding key="D" mask="SHIFT" command="slide_right"/>
+    <binding key="W" mask="NONE" command="push_forward"/>
+    <binding key="S" mask="NONE" command="push_backward"/>
+    <binding key="W" mask="SHIFT" command="push_forward"/>
+    <binding key="S" mask="SHIFT" command="push_backward"/>
+    <binding key="E" mask="NONE" command="jump"/>
+    <binding key="C" mask="NONE" command="push_down"/>
+    <binding key="E" mask="SHIFT" command="jump"/>
+    <binding key="C" mask="SHIFT" command="push_down"/>
+
+    <binding key="F" mask="NONE" command="toggle_fly"/>
+    <binding key="F" mask="SHIFT" command="toggle_fly"/>
+
+    <binding key="SPACE" mask="NONE" command="stop_moving"/>
+    <binding key="ENTER" mask="NONE" command="start_chat"/>
+    <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
+
+    <binding key="LEFT" mask="NONE" command="turn_left"/>
+    <binding key="LEFT" mask="SHIFT" command="slide_left"/>
+    <binding key="RIGHT" mask="NONE" command="turn_right"/>
+    <binding key="RIGHT" mask="SHIFT" command="slide_right"/>
+    <binding key="UP" mask="NONE" command="push_forward"/>
+    <binding key="DOWN" mask="NONE" command="push_backward"/>
+    <binding key="UP" mask="SHIFT" command="push_forward"/>
+    <binding key="DOWN" mask="SHIFT" command="push_backward"/>
+    <binding key="PGUP" mask="NONE" command="jump"/>
+    <binding key="PGDN" mask="NONE" command="push_down"/>
+    <binding key="PGUP" mask="SHIFT" command="jump"/>
+    <binding key="PGDN" mask="SHIFT" command="push_down"/>
+    <binding key="HOME" mask="SHIFT" command="toggle_fly"/>
+    <binding key="HOME" mask="NONE" command="toggle_fly"/>
+
+    <binding key="PAD_LEFT" mask="NONE" command="turn_left"/>
+    <binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
+    <binding key="PAD_RIGHT" mask="NONE" command="turn_right"/>
+    <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
+    <binding key="PAD_UP" mask="NONE" command="push_forward"/>
+    <binding key="PAD_DOWN" mask="NONE" command="push_backward"/>
+    <binding key="PAD_UP" mask="SHIFT" command="push_forward"/>
+    <binding key="PAD_DOWN" mask="SHIFT" command="push_backward"/>
+    <binding key="PAD_PGUP" mask="NONE" command="jump"/>
+    <binding key="PAD_PGDN" mask="NONE" command="push_down"/>
+    <binding key="PAD_PGUP" mask="SHIFT" command="jump"/>
+    <binding key="PAD_PGDN" mask="SHIFT" command="push_down"/>
+    <binding key="PAD_HOME" mask="NONE" command="toggle_fly"/>
+    <binding key="PAD_HOME" mask="SHIFT" command="toggle_fly"/>
+    <binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
+    <binding key="PAD_CENTER" mask="SHIFT" command="stop_moving"/>
+    <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
+    <binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
+    <binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
+
+    <!--Camera controls in third person on Alt-->
+    <binding key="LEFT" mask="ALT" command="spin_around_cw"/>
+    <binding key="RIGHT" mask="ALT" command="spin_around_ccw"/>
+    <binding key="UP" mask="ALT" command="move_forward"/>
+    <binding key="DOWN" mask="ALT" command="move_backward"/>
+    <binding key="PGUP" mask="ALT" command="spin_over"/>
+    <binding key="PGDN" mask="ALT" command="spin_under"/>
+
+    <binding key="A" mask="ALT" command="spin_around_cw"/>
+    <binding key="D" mask="ALT" command="spin_around_ccw"/>
+    <binding key="W" mask="ALT" command="move_forward"/>
+    <binding key="S" mask="ALT" command="move_backward"/>
+    <binding key="E" mask="ALT" command="spin_over"/>
+    <binding key="C" mask="ALT" command="spin_under"/>
+
+    <binding key="PAD_LEFT" mask="ALT" command="spin_around_cw"/>
+    <binding key="PAD_RIGHT" mask="ALT" command="spin_around_ccw"/>
+    <binding key="PAD_UP" mask="ALT" command="move_forward"/>
+    <binding key="PAD_DOWN" mask="ALT" command="move_backward"/>
+    <binding key="PAD_PGUP" mask="ALT" command="spin_over"/>
+    <binding key="PAD_PGDN" mask="ALT" command="spin_under"/>
+    <binding key="PAD_ENTER" mask="ALT" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/>
+
+    <!--mimic alt zoom behavior with keyboard only-->
+    <binding key="A" mask="CTL_ALT" command="spin_around_cw"/>
+    <binding key="D" mask="CTL_ALT" command="spin_around_ccw"/>
+    <binding key="W" mask="CTL_ALT" command="spin_over"/>
+    <binding key="S" mask="CTL_ALT" command="spin_under"/>
+    <binding key="E" mask="CTL_ALT" command="spin_over"/>
+    <binding key="C" mask="CTL_ALT" command="spin_under"/>
+
+    <binding key="LEFT" mask="CTL_ALT" command="spin_around_cw"/>
+    <binding key="RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
+    <binding key="UP" mask="CTL_ALT" command="spin_over"/>
+    <binding key="DOWN" mask="CTL_ALT" command="spin_under"/>
+    <binding key="PGUP" mask="CTL_ALT" command="spin_over"/>
+    <binding key="PGDN" mask="CTL_ALT" command="spin_under"/>
+
+    <binding key="PAD_LEFT" mask="CTL_ALT" command="spin_around_cw"/>
+    <binding key="PAD_RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
+    <binding key="PAD_UP" mask="CTL_ALT" command="spin_over"/>
+    <binding key="PAD_DOWN" mask="CTL_ALT" command="spin_under"/>
+    <binding key="PAD_PGUP" mask="CTL_ALT" command="spin_over"/>
+    <binding key="PAD_PGDN" mask="CTL_ALT" command="spin_under"/>
+    <binding key="PAD_ENTER" mask="CTL_ALT" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="CTL_ALT" command="start_gesture"/>
+
+    <!--Therefore pan on Alt-Shift-->
+    <binding key="A" mask="CTL_ALT_SHIFT" command="pan_left"/>
+    <binding key="D" mask="CTL_ALT_SHIFT" command="pan_right"/>
+    <binding key="W" mask="CTL_ALT_SHIFT" command="pan_up"/>
+    <binding key="S" mask="CTL_ALT_SHIFT" command="pan_down"/>
+
+    <binding key="LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
+    <binding key="RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
+    <binding key="UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
+    <binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
+
+    <binding key="PAD_LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
+    <binding key="PAD_RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
+    <binding key="PAD_UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
+    <binding key="PAD_DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
+    <binding key="PAD_ENTER" mask="CTL_ALT_SHIFT" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/>
+  </third_person>
+
+  # Basic editing camera control
+  <edit>
+    <binding key="A" mask="NONE" command="spin_around_cw"/>
+    <binding key="D" mask="NONE" command="spin_around_ccw"/>
+    <binding key="W" mask="NONE" command="move_forward"/>
+    <binding key="S" mask="NONE" command="move_backward"/>
+    <binding key="E" mask="NONE" command="spin_over"/>
+    <binding key="C" mask="NONE" command="spin_under"/>
+    <binding key="ENTER" mask="NONE" command="start_chat"/>
+    <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
+    <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
+
+    <binding key="LEFT" mask="NONE" command="spin_around_cw"/>
+    <binding key="RIGHT" mask="NONE" command="spin_around_ccw"/>
+    <binding key="UP" mask="NONE" command="move_forward"/>
+    <binding key="DOWN" mask="NONE" command="move_backward"/>
+    <binding key="PGUP" mask="NONE" command="spin_over"/>
+    <binding key="PGDN" mask="NONE" command="spin_under"/>
+
+    <binding key="A" mask="SHIFT" command="pan_left"/>
+    <binding key="D" mask="SHIFT" command="pan_right"/>
+    <binding key="W" mask="SHIFT" command="pan_up"/>
+    <binding key="S" mask="SHIFT" command="pan_down"/>
+
+    <binding key="LEFT" mask="SHIFT" command="pan_left"/>
+    <binding key="RIGHT" mask="SHIFT" command="pan_right"/>
+    <binding key="UP" mask="SHIFT" command="pan_up"/>
+    <binding key="DOWN" mask="SHIFT" command="pan_down"/>
+
+    <!--Walking works with ALT held down.-->
+    <binding key="A" mask="ALT" command="slide_left"/>
+    <binding key="D" mask="ALT" command="slide_right"/>
+    <binding key="W" mask="ALT" command="push_forward"/>
+    <binding key="S" mask="ALT" command="push_backward"/>
+    <binding key="E" mask="ALT" command="jump"/>
+    <binding key="C" mask="ALT" command="push_down"/>
+
+    <binding key="LEFT" mask="ALT" command="slide_left"/>
+    <binding key="RIGHT" mask="ALT" command="slide_right"/>
+    <binding key="UP" mask="ALT" command="push_forward"/>
+    <binding key="DOWN" mask="ALT" command="push_backward"/>
+    <binding key="PGUP" mask="ALT" command="jump"/>
+    <binding key="PGDN" mask="ALT" command="push_down"/>
+    <binding key="HOME" mask="ALT" command="toggle_fly"/>
+
+    <binding key="PAD_LEFT" mask="ALT" command="slide_left"/>
+    <binding key="PAD_RIGHT" mask="ALT" command="slide_right"/>
+    <binding key="PAD_UP" mask="ALT" command="push_forward"/>
+    <binding key="PAD_DOWN" mask="ALT" command="push_backward"/>
+    <binding key="PAD_PGUP" mask="ALT" command="jump"/>
+    <binding key="PAD_PGDN" mask="ALT" command="push_down"/>
+    <binding key="PAD_ENTER" mask="ALT" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="ALT" command="start_gesture"/>
+  </edit>
+  <sitting>
+    <binding key="A" mask="ALT" command="spin_around_cw"/>
+    <binding key="D" mask="ALT" command="spin_around_ccw"/>
+    <binding key="W" mask="ALT" command="move_forward"/>
+    <binding key="S" mask="ALT" command="move_backward"/>
+    <binding key="E" mask="ALT" command="spin_over_sitting"/>
+    <binding key="C" mask="ALT" command="spin_under_sitting"/>
+
+    <binding key="LEFT" mask="ALT" command="spin_around_cw"/>
+    <binding key="RIGHT" mask="ALT" command="spin_around_ccw"/>
+    <binding key="UP" mask="ALT" command="move_forward"/>
+    <binding key="DOWN" mask="ALT" command="move_backward"/>
+    <binding key="PGUP" mask="ALT" command="spin_over"/>
+    <binding key="PGDN" mask="ALT" command="spin_under"/>
+
+    <binding key="A" mask="CTL_ALT" command="spin_around_cw"/>
+    <binding key="D" mask="CTL_ALT" command="spin_around_ccw"/>
+    <binding key="W" mask="CTL_ALT" command="spin_over"/>
+    <binding key="S" mask="CTL_ALT" command="spin_under"/>
+    <binding key="E" mask="CTL_ALT" command="spin_over"/>
+    <binding key="C" mask="CTL_ALT" command="spin_under"/>
+
+    <binding key="LEFT" mask="CTL_ALT" command="spin_around_cw"/>
+    <binding key="RIGHT" mask="CTL_ALT" command="spin_around_ccw"/>
+    <binding key="UP" mask="CTL_ALT" command="spin_over"/>
+    <binding key="DOWN" mask="CTL_ALT" command="spin_under"/>
+    <binding key="PGUP" mask="CTL_ALT" command="spin_over"/>
+    <binding key="PGDN" mask="CTL_ALT" command="spin_under"/>
+
+
+    <binding key="A" mask="NONE" command="spin_around_cw_sitting"/>
+    <binding key="D" mask="NONE" command="spin_around_ccw_sitting"/>
+    <binding key="W" mask="NONE" command="move_forward_sitting"/>
+    <binding key="S" mask="NONE" command="move_backward_sitting"/>
+    <binding key="E" mask="NONE" command="spin_over_sitting"/>
+    <binding key="C" mask="NONE" command="spin_under_sitting"/>
+
+    <binding key="LEFT" mask="NONE" command="spin_around_cw_sitting"/>
+    <binding key="RIGHT" mask="NONE" command="spin_around_ccw_sitting"/>
+    <binding key="UP" mask="NONE" command="move_forward_sitting"/>
+    <binding key="DOWN" mask="NONE" command="move_backward_sitting"/>
+    <binding key="PGUP" mask="NONE" command="spin_over_sitting"/>
+    <binding key="PGDN" mask="NONE" command="spin_under_sitting"/>
+
+    <binding key="PAD_LEFT" mask="NONE" command="spin_around_cw_sitting"/>
+    <binding key="PAD_RIGHT" mask="NONE" command="spin_around_ccw_sitting"/>
+    <binding key="PAD_UP" mask="NONE" command="move_forward_sitting"/>
+    <binding key="PAD_DOWN" mask="NONE" command="move_backward_sitting"/>
+    <binding key="PAD_PGUP" mask="NONE" command="spin_over_sitting"/>
+    <binding key="PAD_PGDN" mask="NONE" command="spin_under_sitting"/>
+    <binding key="PAD_CENTER" mask="NONE" command="stop_moving"/>
+    <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
+
+    <!--these are for passing controls when sitting on vehicles-->
+    <binding key="A" mask="SHIFT" command="slide_left"/>
+    <binding key="D" mask="SHIFT" command="slide_right"/>
+    <binding key="LEFT" mask="SHIFT" command="slide_left"/>
+    <binding key="RIGHT" mask="SHIFT" command="slide_right"/>
+
+    <binding key="PAD_LEFT" mask="SHIFT" command="slide_left"/>
+    <binding key="PAD_RIGHT" mask="SHIFT" command="slide_right"/>
+    <binding key="PAD_ENTER" mask="SHIFT" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="SHIFT" command="start_gesture"/>
+
+    <!--pan on Alt-Shift-->
+    <binding key="A" mask="CTL_ALT_SHIFT" command="pan_left"/>
+    <binding key="D" mask="CTL_ALT_SHIFT" command="pan_right"/>
+    <binding key="W" mask="CTL_ALT_SHIFT" command="pan_up"/>
+    <binding key="S" mask="CTL_ALT_SHIFT" command="pan_down"/>
+
+    <binding key="LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
+    <binding key="RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
+    <binding key="UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
+    <binding key="DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
+
+    <binding key="PAD_LEFT" mask="CTL_ALT_SHIFT" command="pan_left"/>
+    <binding key="PAD_RIGHT" mask="CTL_ALT_SHIFT" command="pan_right"/>
+    <binding key="PAD_UP" mask="CTL_ALT_SHIFT" command="pan_up"/>
+    <binding key="PAD_DOWN" mask="CTL_ALT_SHIFT" command="pan_down"/>
+    <binding key="PAD_ENTER" mask="CTL_ALT_SHIFT" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="CTL_ALT_SHIFT" command="start_gesture"/>
+
+    <binding key="ENTER" mask="NONE" command="start_chat"/>
+    <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
+  </sitting>
+  <edit_avatar>
+    <!--Avatar editing camera controls-->
+    <binding key="A" mask="NONE" command="edit_avatar_spin_cw"/>
+    <binding key="D" mask="NONE" command="edit_avatar_spin_ccw"/>
+    <binding key="W" mask="NONE" command="edit_avatar_move_forward"/>
+    <binding key="S" mask="NONE" command="edit_avatar_move_backward"/>
+    <binding key="E" mask="NONE" command="edit_avatar_spin_over"/>
+    <binding key="C" mask="NONE" command="edit_avatar_spin_under"/>
+    <binding key="LEFT" mask="NONE" command="edit_avatar_spin_cw"/>
+    <binding key="RIGHT" mask="NONE" command="edit_avatar_spin_ccw"/>
+    <binding key="UP" mask="NONE" command="edit_avatar_move_forward"/>
+    <binding key="DOWN" mask="NONE" command="edit_avatar_move_backward"/>
+    <binding key="PGUP" mask="NONE" command="edit_avatar_spin_over"/>
+    <binding key="PGDN" mask="NONE" command="edit_avatar_spin_under"/>
+    <binding key="ENTER" mask="NONE" command="start_chat"/>
+    <binding key="DIVIDE" mask="NONE" command="start_gesture"/>
+    <binding key="PAD_LEFT" mask="NONE" command="edit_avatar_spin_cw"/>
+    <binding key="PAD_RIGHT" mask="NONE" command="edit_avatar_spin_ccw"/>
+    <binding key="PAD_UP" mask="NONE" command="edit_avatar_move_forward"/>
+    <binding key="PAD_DOWN" mask="NONE" command="edit_avatar_move_backward"/>
+    <binding key="PAD_PGUP" mask="NONE" command="edit_avatar_spin_over"/>
+    <binding key="PAD_PGDN" mask="NONE" command="edit_avatar_spin_under"/>
+    <binding key="PAD_ENTER" mask="NONE" command="start_chat"/>
+    <binding key="PAD_DIVIDE" mask="NONE" command="start_gesture"/>
+  </edit_avatar>
+</keys>
\ No newline at end of file
diff --git a/indra/newview/app_settings/lindenlab.pem b/indra/newview/app_settings/lindenlab.pem
new file mode 100644
index 0000000000000000000000000000000000000000..cf88d0e04799bf09835f2c78959e9e8bce3d75f9
--- /dev/null
+++ b/indra/newview/app_settings/lindenlab.pem
@@ -0,0 +1,27 @@
+-----BEGIN CERTIFICATE-----
+MIIEUDCCA7mgAwIBAgIJAN4ppNGwj6yIMA0GCSqGSIb3DQEBBAUAMIHMMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5j
+aXNjbzEZMBcGA1UEChMQTGluZGVuIExhYiwgSW5jLjEpMCcGA1UECxMgTGluZGVu
+IExhYiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAnBgNVBAMTIExpbmRlbiBMYWIg
+Q2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYJKoZIhvcNAQkBFhBjYUBsaW5kZW5s
+YWIuY29tMB4XDTA1MDQyMTAyNDAzMVoXDTI1MDQxNjAyNDAzMVowgcwxCzAJBgNV
+BAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNp
+c2NvMRkwFwYDVQQKExBMaW5kZW4gTGFiLCBJbmMuMSkwJwYDVQQLEyBMaW5kZW4g
+TGFiIENlcnRpZmljYXRlIEF1dGhvcml0eTEpMCcGA1UEAxMgTGluZGVuIExhYiBD
+ZXJ0aWZpY2F0ZSBBdXRob3JpdHkxHzAdBgkqhkiG9w0BCQEWEGNhQGxpbmRlbmxh
+Yi5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAKXh1MThucdTbMg9bYBO
+rAm8yWns32YojB0PRfbq8rUjepEhTm3/13s0u399Uc202v4ejcGhkIDWJZd2NZMF
+oKrhmRfxGHSKPCuFaXC3jh0lRECj7k8FoPkcmaPjSyodrDFDUUuv+C06oYJoI+rk
+8REyal9NwgHvqCzOrZtiTXAdAgMBAAGjggE2MIIBMjAdBgNVHQ4EFgQUO1zK2e1f
+1wO1fHAjq6DTJobKDrcwggEBBgNVHSMEgfkwgfaAFDtcytntX9cDtXxwI6ug0yaG
+yg63oYHSpIHPMIHMMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEW
+MBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEZMBcGA1UEChMQTGluZGVuIExhYiwgSW5j
+LjEpMCcGA1UECxMgTGluZGVuIExhYiBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkxKTAn
+BgNVBAMTIExpbmRlbiBMYWIgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MR8wHQYJKoZI
+hvcNAQkBFhBjYUBsaW5kZW5sYWIuY29tggkA3imk0bCPrIgwDAYDVR0TBAUwAwEB
+/zANBgkqhkiG9w0BAQQFAAOBgQA/ZkgfvwHYqk1UIAKZS3kMCxz0HvYuEQtviwnu
+xA39CIJ65Zozs28Eg1aV9/Y+Of7TnWhW+U3J3/wD/GghaAGiKK6vMn9gJBIdBX/9
+e6ef37VGyiOEFFjnUIbuk0RWty0orN76q/lI/xjCi15XSA/VSq2j4vmnwfZcPTDu
+glmQ1A==
+-----END CERTIFICATE-----
+
diff --git a/indra/newview/app_settings/llsd.xsd b/indra/newview/app_settings/llsd.xsd
new file mode 100644
index 0000000000000000000000000000000000000000..34612d9faa11a010149e4a078e90d04dd0bf20ef
--- /dev/null
+++ b/indra/newview/app_settings/llsd.xsd
@@ -0,0 +1,131 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+        <!-- LLSD document has exactly one value -->
+	<xsd:element name="llsd">
+		<xsd:complexType>                        
+                        <xsd:group ref="llsd-value" />
+		</xsd:complexType>
+	</xsd:element>
+
+        <!-- Value is one of undef, boolean, integer, real, 
+             uuid, string, date, binary, array, or map -->
+        <xsd:group name="llsd-value">
+                <xsd:choice>
+        		<xsd:element ref="undef"/>
+        		<xsd:element ref="boolean"/>
+        		<xsd:element ref="integer"/>
+        		<xsd:element ref="real"/>
+        		<xsd:element ref="uuid"/>
+        		<xsd:element ref="string"/>
+        		<xsd:element ref="date"/>
+			<xsd:element ref="uri"/>
+			<xsd:element ref="binary"/>
+			<xsd:element ref="array"/>
+			<xsd:element ref="map"/>
+                </xsd:choice>
+        </xsd:group>
+
+        <!-- Undefined is an empty eleemnt -->
+	<xsd:element name="undef">
+		<xsd:simpleType>
+                        <xsd:restriction base="xsd:string">
+                             <xsd:length value="0" />
+                        </xsd:restriction>
+                </xsd:simpleType>
+        </xsd:element>
+
+        <!-- Boolean is true or false -->
+	<xsd:element name="boolean">
+		<xsd:simpleType>
+			<xsd:restriction base="xsd:string">
+				<xsd:enumeration value="true" />
+				<xsd:enumeration value="false" />
+
+                                <!-- In practice, these other serializations are seen: -->
+				<xsd:enumeration value="" />
+				<xsd:enumeration value="1" />
+				<xsd:enumeration value="0" />
+			</xsd:restriction>
+		</xsd:simpleType>
+	</xsd:element>
+
+        <!-- Integer is restricted to 32-bit signed values -->
+	<xsd:element name="integer">
+		<xsd:simpleType>
+			<xsd:restriction base="xsd:int" />
+		</xsd:simpleType>
+	</xsd:element>
+
+        <!-- Real is an IEEE 754 "double" value, including Infinities and NaN -->
+	<xsd:element name="real">
+		<xsd:simpleType>
+                        <!-- TODO: xsd:double uses "INF", "-INF", and "NaN",
+                        whereas LLSD prefers "Infinity", "-Infinity" and "NaN" -->
+			<xsd:restriction base="xsd:double" />
+		</xsd:simpleType>
+	</xsd:element>
+
+        <!-- UUID per RFC 4122 -->
+	<xsd:element name="uuid">
+		<xsd:simpleType>
+			<xsd:restriction base="xsd:string">
+				<xsd:pattern value="[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}|" />
+			</xsd:restriction>
+		</xsd:simpleType>
+	</xsd:element>
+
+        <!-- String is any sequence of Unicode characters -->
+	<xsd:element name="string">
+		<xsd:simpleType>
+			<xsd:restriction base="xsd:string" />
+		</xsd:simpleType>
+	</xsd:element>
+
+        <!-- Date is ISO 8601 in UTC -->
+	<xsd:element name="date">
+		<xsd:simpleType>
+			<xsd:restriction base="xsd:dateTime">
+                                <!-- Restrict to UTC (Z) times -->
+                                <xsd:pattern value="[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\.[0-9]+)?Z" />
+			</xsd:restriction>
+		</xsd:simpleType>
+	</xsd:element>
+
+        <!-- URI per RFC 3986 -->
+	<xsd:element name="uri">
+		<xsd:simpleType>
+			<xsd:restriction base="xsd:anyURI" />
+		</xsd:simpleType>
+	</xsd:element>
+
+        <!-- Binary data is base64 encoded -->
+	<xsd:element name="binary">
+		<xsd:simpleType>
+                        <!-- TODO: Require encoding attribute? -->
+			<xsd:restriction base="xsd:base64Binary" />
+		</xsd:simpleType>
+	</xsd:element>
+
+        <!-- Array is a sequence of zero or more values -->
+	<xsd:element name="array">
+		<xsd:complexType>
+                        <xsd:group minOccurs="0" maxOccurs="unbounded" ref="llsd-value" />
+		</xsd:complexType>
+	</xsd:element>
+
+        <!-- Map is a sequence of zero or more key/value pairs -->
+	<xsd:element name="map">
+		<xsd:complexType>
+			<xsd:sequence minOccurs="0" maxOccurs="unbounded">
+				<xsd:element name="key">
+                                	<xsd:simpleType>
+                                        	<xsd:restriction base="xsd:string" />
+                                        </xsd:simpleType>
+				</xsd:element>
+                                <xsd:group ref="llsd-value" />
+			</xsd:sequence>
+		</xsd:complexType>
+	</xsd:element>
+
+</xsd:schema>
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index ebd93b59875db8073643bc746e1c5d12b2e1f003..ea7ac6bedab5a401794e338bf4f9bfb81c91304f 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1,5 +1,6 @@
 <?xml version="1.0" ?>
-<llsd>
+<llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:noNamespaceSchemaLocation="llsd.xsd">
 <map>
 	<key>CrashHostUrl</key>
     <map>
@@ -607,6 +608,17 @@
       <key>Value</key>
       <integer>2</integer>
     </map>
+    <key>AvatarPickerURL</key>
+    <map>
+      <key>Comment</key>
+      <string>Avatar picker contents</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>http://interest.secondlife.com/viewer/avatar</string>
+    </map>
     <key>AvatarBakedTextureUploadTimeout</key>
     <map>
       <key>Comment</key>
@@ -674,6 +686,39 @@
       <key>Value</key>
       <string>http://www.secondlife.com</string>
     </map>
+    <key>BrowserIgnoreSSLCertErrors</key>
+    <map>
+      <key>Comment</key>
+      <string>FOR TESTING ONLY: Tell the built-in web browser to ignore SSL cert errors.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>BrowserUseDefaultCAFile</key>
+    <map>
+      <key>Comment</key>
+      <string>Tell the built-in web browser to use the CA.pem file shipped with the client.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BrowserCAFilePath</key>
+    <map>
+      <key>Comment</key>
+      <string>Tell the built-in web browser the path to an alternative CA.pem file (only used if BrowserUseDefaultCAFile is false).</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string></string>
+    </map>  
     <key>BlockAvatarAppearanceMessages</key>
         <map>
         <key>Comment</key>
@@ -1365,6 +1410,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>LetterKeysFocusChatBar</key>
+    <map>
+      <key>Comment</key>
+      <string>When printable characters keys (possibly with Shift held) are pressed, the chatbar takes focus</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>ChatBubbleOpacity</key>
     <map>
       <key>Comment</key>
@@ -2545,7 +2601,18 @@
       <key>Value</key>
       <integer>10</integer>
     </map>
-    <key>DisableCameraConstraints</key>
+    <key>DestinationGuideURL</key>
+    <map>
+      <key>Comment</key>
+      <string>Destination guide contents</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>http://www.secondlife.com</string>
+    </map>
+  <key>DisableCameraConstraints</key>
     <map>
       <key>Comment</key>
       <string>Disable the normal bounds put on the camera by avatar position</string>
@@ -2567,6 +2634,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>DisableExternalBrowser</key>
+    <map>
+      <key>Comment</key>
+      <string>Disable opening an external browser.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>DisableRendering</key>
     <map>
       <key>Comment</key>
@@ -2578,6 +2656,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>DisableTextHyperlinkActions</key>
+    <map>
+      <key>Comment</key>
+      <string>Disable highlighting and linking of URLs in XUI text boxes</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>DisableVerticalSync</key>
     <map>
       <key>Comment</key>
@@ -2721,6 +2810,28 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>ClickActionBuyEnabled</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable click to buy actions in tool pie menu</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>ClickActionPayEnabled</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable click to pay actions in tool pie menu</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>DoubleClickAutoPilot</key>
     <map>
       <key>Comment</key>
@@ -2864,6 +2975,39 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>EnableGrab</key>
+    <map>
+      <key>Comment</key>
+      <string>Use Ctrl+mouse to grab and manipulate objects</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>EnableAltZoom</key>
+    <map>
+      <key>Comment</key>
+      <string>Use Alt+mouse to look at and zoom in on objects</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>EnableMouselook</key>
+    <map>
+      <key>Comment</key>
+      <string>Allow first person perspective and mouse control of camera</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>EnableRippleWater</key>
     <map>
       <key>Comment</key>
@@ -3557,72 +3701,6 @@
       <key>Value</key>
       <real>0.5</real>
     </map>
-    <key>FontMonospace</key>
-    <map>
-      <key>Comment</key>
-      <string>Name of monospace font that definitely exists (Truetype file name)</string>
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>String</string>
-      <key>Value</key>
-      <string>DejaVuSansMono.ttf</string>
-    </map>
-    <key>FontSansSerif</key>
-    <map>
-      <key>Comment</key>
-      <string>Name of primary sans-serif font that definitely exists (Truetype file name)</string>
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>String</string>
-      <key>Value</key>
-      <string>MtBkLfRg.ttf</string>
-    </map>
-    <key>FontSansSerifBundledFallback</key>
-    <map>
-      <key>Comment</key>
-      <string>Name of secondary sans-serif font that definitely exists (Truetype file name)</string>
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>String</string>
-      <key>Value</key>
-      <string>DejaVuSansCondensed.ttf</string>
-    </map>
-    <key>FontSansSerifBold</key>
-    <map>
-      <key>Comment</key>
-      <string>Name of bold font (Truetype file name)</string>
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>String</string>
-      <key>Value</key>
-      <string>MtBdLfRg.ttf</string>
-    </map>
-    <key>FontSansSerifFallback</key>
-    <map>
-      <key>Comment</key>
-      <string>Name of sans-serif font (Truetype file name)</string>
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>String</string>
-      <key>Value</key>
-      <string />
-    </map>
-    <key>FontSansSerifFallbackScale</key>
-    <map>
-      <key>Comment</key>
-      <string>Scale of fallback font relative to huge font (fraction of huge font size)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>F32</string>
-      <key>Value</key>
-      <real>1.0</real>
-    </map>
     <key>FontScreenDPI</key>
     <map>
       <key>Comment</key>
@@ -3634,61 +3712,6 @@
       <key>Value</key>
       <real>96.0</real>
     </map>
-    <key>FontSizeHuge</key>
-    <map>
-      <key>Comment</key>
-      <string>Size of huge font (points, or 1/72 of an inch)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>F32</string>
-      <key>Value</key>
-      <real>16.0</real>
-    </map>
-    <key>FontSizeLarge</key>
-    <map>
-      <key>Comment</key>
-      <string>Size of large font (points, or 1/72 of an inch)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>F32</string>
-      <key>Value</key>
-      <real>12.0</real>
-    </map>
-    <key>FontSizeMedium</key>
-    <map>
-      <key>Comment</key>
-      <string>Size of medium font (points, or 1/72 of an inch)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>F32</string>
-      <key>Value</key>
-      <real>10.0</real>
-    </map>
-    <key>FontSizeMonospace</key>
-    <map>
-      <key>Comment</key>
-      <string>Size of monospaced font (points, or 1/72 of an inch)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>F32</string>
-      <key>Value</key>
-      <real>8.1</real>
-    </map>
-    <key>FontSizeSmall</key>
-    <map>
-      <key>Comment</key>
-      <string>Size of small font (points, or 1/72 of an inch)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>F32</string>
-      <key>Value</key>
-      <real>9.0</real>
-    </map>
     <key>ForceAssetFail</key>
     <map>
       <key>Comment</key>
@@ -3881,7 +3904,7 @@
       <key>Comment</key>
       <string>URL pattern for help page; arguments will be encoded; see llviewerhelp.cpp:buildHelpURL for arguments</string>
       <key>Persist</key>
-      <integer>0</integer>
+      <integer>1</integer>
       <key>Type</key>
       <string>String</string>
       <key>Value</key>
@@ -3931,6 +3954,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>	
+    <key>HostID</key>
+    <map>
+      <key>Comment</key>
+      <string>Machine identifier for hosted Second Life instances</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string />
+    </map>
     <key>HtmlHelpLastPage</key>
     <map>
       <key>Comment</key>
@@ -3969,7 +4003,7 @@
       <key>Comment</key>
       <string>Ignore all notifications so we never need user input on them.</string>
       <key>Persist</key>
-      <integer>0</integer>
+      <integer>1</integer>
       <key>Type</key>
       <string>Boolean</string>
       <key>Value</key>
@@ -4006,7 +4040,7 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <real>0.5</real>
+      <real>0.65</real>
     </map>
     <key>InBandwidth</key>
     <map>
@@ -4603,6 +4637,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>LocalFileSystemBrowsingEnabled</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable/disable access to the local file system via the file picker</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
   <key>LoginSRVTimeout</key>
   <map>
     <key>Comment</key>
@@ -4735,6 +4780,17 @@
       <key>Value</key>
       <string>http://map.secondlife.com.s3.amazonaws.com/</string>
     </map>
+    <key>CurrentMapServerURL</key>
+    <map>
+      <key>Comment</key>
+      <string>Current Session World map URL</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string></string>
+    </map>
     <key>MapShowEvents</key>
     <map>
       <key>Comment</key>
@@ -5230,61 +5286,6 @@
       <key>Value</key>
       <real>60.0</real>
     </map>
-    <key>MeanCollisionBump</key>
-    <map>
-      <key>Comment</key>
-      <string>You have experienced an abuse of being bumped by an object or avatar</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
-    <key>MeanCollisionPhysical</key>
-    <map>
-      <key>Comment</key>
-      <string>You have experienced an abuse from a physical object</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
-    <key>MeanCollisionPushObject</key>
-    <map>
-      <key>Comment</key>
-      <string>You have experienced an abuse of being pushed by a scripted object</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
-    <key>MeanCollisionScripted</key>
-    <map>
-      <key>Comment</key>
-      <string>You have experienced an abuse from a scripted object</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
-    <key>MeanCollisionSelected</key>
-    <map>
-      <key>Comment</key>
-      <string>You have experienced an abuse of being pushed via a selected object</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
   <key>MediaControlFadeTime</key>
   <map>
     <key>Comment</key>
@@ -6557,6 +6558,28 @@
       <key>Value</key>
       <real>0.0</real>
     </map>
+    <key>QuitAfterSecondsOfAFK</key>
+    <map>
+      <key>Comment</key>
+      <string>The duration allowed after being AFK before quitting.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>0.0</real>
+    </map>
+    <key>QuitOnLoginActivated</key>
+    <map>
+      <key>Comment</key>
+      <string>Quit if login page is activated (used when auto login is on and users must not be able to login manually)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>RadioLandBrushAction</key>
     <map>
       <key>Comment</key>
@@ -6593,7 +6616,18 @@
     <key>MediaBrowserWindowLimit</key>
     <map>
       <key>Comment</key>
-      <string>Maximum number of media brower windows that can be open at once (0 for no limit)</string>
+      <string>Maximum number of media brower windows that can be open at once in the media browser floater (0 for no limit)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>5</integer>
+    </map>
+    <key>WebContentWindowLimit</key>
+    <map>
+      <key>Comment</key>
+      <string>Maximum number of web brower windows that can be open at once in the Web content floater (0 for no limit)</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -7814,17 +7848,6 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>RenderFastUI</key>
-    <map>
-      <key>Comment</key>
-      <string>[NOT USED]</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>RenderFlexTimeFactor</key>
     <map>
       <key>Comment</key>
@@ -8340,6 +8363,28 @@
       <key>Value</key>
       <real>1.0</real>
     </map>
+    <key>RenderTrackerBeacon</key>
+    <map>
+      <key>Comment</key>
+      <string>Display tracking arrow and beacon to target avatar, teleport destination</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+	<key>RenderTransparentWater</key>
+	<map>
+	  <key>Comment</key>
+	  <string>Render water as transparent.  Setting to false renders water as opaque with a simple texture applied.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+	</map>
     <key>RenderTreeLODFactor</key>
     <map>
       <key>Comment</key>
@@ -8516,6 +8561,17 @@
       <key>Value</key>
       <integer>512</integer>
     </map>
+    <key>RenderParcelSelection</key>
+    <map>
+      <key>Comment</key>
+      <string>Display selected parcel outline</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>RotateRight</key>
     <map>
       <key>Comment</key>
@@ -8604,6 +8660,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>ScriptsCanShowUI</key>
+    <map>
+      <key>Comment</key>
+      <string>Allow LSL calls (such as LLMapDestination) to spawn viewer UI</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>SecondLifeEnterprise</key>
     <map>
       <key>Comment</key>
@@ -9968,6 +10035,17 @@
       <key>Value</key>
       <real>500.0</real>
     </map>
+    <key>UpdaterMaximumBandwidth</key>
+    <map>
+      <key>Comment</key>
+      <string>Maximum allowable downstream bandwidth for updater service (kilo bits per second)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>500.0</real>
+    </map>
     <key>ToolTipDelay</key>
     <map>
       <key>Comment</key>
@@ -11068,7 +11146,62 @@
       <key>Value</key>
       <integer>15</integer>
     </map>
-	<key>UploadBakedTexOld</key>
+    <key>UpdaterServiceSetting</key>
+    <map>
+      <key>Comment</key>
+      <string>Configure updater service.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>3</integer>
+    </map>
+    <key>UpdaterServiceCheckPeriod</key>
+    <map>
+      <key>Comment</key>
+      <string>Default period between update checking.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>3600</integer>
+    </map>
+    <key>UpdaterServiceURL</key>
+    <map>
+      <key>Comment</key>
+      <string>Default location for the updater service.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>https://update.secondlife.com</string>
+    </map>
+    <key>UpdaterServicePath</key>
+    <map>
+      <key>Comment</key>
+      <string>Path on the update server host.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>update</string>
+    </map>
+    <key>UpdaterServiceProtocolVersion</key>
+    <map>
+      <key>Comment</key>
+      <string>The update protocol version to use.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>v1.0</string>
+    </map>
+    <key>UploadBakedTexOld</key>
     <map>
       <key>Comment</key>
       <string>Forces the baked texture pipeline to upload using the old method.</string>
@@ -11388,27 +11521,38 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>VerboseLogs</key>
+    <key>InterpolationTime</key>
     <map>
       <key>Comment</key>
-      <string>Display source file and line number for each log item for debugging purposes</string>
+      <string>How long to extrapolate object motion after last packet received</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
-      <string>Boolean</string>
+      <string>F32</string>
       <key>Value</key>
-      <integer>0</integer>
+      <integer>3.0</integer>
     </map>
-    <key>VersionChannelName</key>
+    <key>InterpolationPhaseOut</key>
     <map>
       <key>Comment</key>
-      <string>Versioning Channel Name.</string>
+      <string>Seconds to phase out interpolated motion</string>
       <key>Persist</key>
-      <integer>0</integer>
+      <integer>1</integer>
       <key>Type</key>
-      <string>String</string>
+      <string>F32</string>
       <key>Value</key>
-      <string>Second Life Release</string>
+      <integer>1.0</integer>
+    </map>
+    <key>VerboseLogs</key>
+    <map>
+      <key>Comment</key>
+      <string>Display source file and line number for each log item for debugging purposes</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
     </map>
     <key>VertexShaderEnable</key>
     <map>
@@ -11509,6 +11653,28 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>VoiceCallsRejectAll</key>
+    <map>
+      <key>Comment</key>
+      <string>Silently reject all incoming voice calls.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>VoiceDisableMic</key>
+    <map>
+      <key>Comment</key>
+      <string>Completely disable the ability to open the mic.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>VoiceEffectExpiryWarningTime</key>
     <map>
       <key>Comment</key>
@@ -11817,6 +11983,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>WindowFullScreen</key>
+    <map>
+      <key>Comment</key>
+      <string>SL viewer window full screen</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>WindowHeight</key>
     <map>
       <key>Comment</key>
@@ -11883,10 +12060,10 @@
       <key>Value</key>
       <real>150000.0</real>
     </map>
-    <key>XUIEditor</key>
+    <key>ExternalEditor</key>
     <map>
       <key>Comment</key>
-      <string>Path to program used to edit XUI files</string>
+      <string>Path to program used to edit LSL scripts and XUI files, e.g.: /usr/bin/gedit --new-window "%s"</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -12114,6 +12291,7 @@
       <key>Comment</key>
       <string>Maximum texture width for user uploaded textures</string>
       <key>Persist</key>
+      <integer>1</integer>
       <key>Type</key>
       <string>S32</string>
       <key>Value</key>
@@ -12153,6 +12331,7 @@
       <key>Value</key>
       <array>
 	      <string>snapshot</string>
+	      <string>postcard</string>
 	      <string>mini_map</string>
       </array>
     </map>
@@ -12220,6 +12399,17 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
+      <real>1200.0</real>
+    </map>
+    <key>AvatarPickerHintTimeout</key>
+    <map>
+      <key>Comment</key>
+      <string>Number of seconds to wait before telling resident about avatar picker.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
       <real>600.0</real>
     </map>
     <key>SidePanelHintTimeout</key>
@@ -12244,5 +12434,16 @@
       <key>Value</key>
       <string>name</string>
     </map>
+    <key>ReleaseNotesURL</key>
+    <map>
+      <key>Comment</key>
+      <string>Release notes URL template</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>http://secondlife.com/app/releasenotes/?channel=[CHANNEL]&amp;version=[VERSION]</string>
+    </map>
 </map>
 </llsd>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index dc76a4e5183ad137b5917aaa933d311b46c7369f..705c73cbf7fef6dbc80fe916f7b36ac95c4f531d 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -110,7 +110,17 @@
         <key>Value</key>
             <string>00000000-0000-0000-0000-000000000000</string>
     </map>
-
+    <key>LogFileNamewithDate</key>
+      <map>
+        <key>Comment</key>
+        <string>Add Date Stamp to chat and IM Logs with format chat-YYYY-MM-DD and 'IM file name'-YYYY-MM. To view old logs goto ..\Second Life\[login name]</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>Boolean</string>
+        <key>Value</key>
+        <integer>0</integer>
+      </map>
     <!-- Settings below are for back compatibility only.
     They are not used in current viewer anymore. But they can't be removed to avoid
     influence on previous versions of the viewer in case of settings are not used or default value
diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt
index d69842d5f100320355b9f9e60c98e5603fd8577b..a95abd7dd185e55e8992b612dfbb20f393d61788 100644
--- a/indra/newview/featuretable.txt
+++ b/indra/newview/featuretable.txt
@@ -42,6 +42,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	4
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	1.0
 RenderUseImpostors			1	1
 RenderVBOEnable				1	1
@@ -80,6 +81,7 @@ RenderObjectBump			1	0
 RenderReflectionDetail		1	0
 RenderTerrainDetail			1	0
 RenderTerrainLODFactor		1	1
+RenderTransparentWater		1	0
 RenderTreeLODFactor			1	0
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	0.5
@@ -108,6 +110,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	0
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	1.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	1.125
@@ -135,6 +138,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	2
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	1.125
@@ -162,6 +166,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	4
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	1.0
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	2.0
diff --git a/indra/newview/featuretable_linux.txt b/indra/newview/featuretable_linux.txt
index efe29005f23895393beffe1f9cf34e8b4fe299bf..a52b32355de22ba0efbafb2451686a9cf8fdf8d4 100644
--- a/indra/newview/featuretable_linux.txt
+++ b/indra/newview/featuretable_linux.txt
@@ -42,6 +42,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	4
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	1.0
 RenderUseImpostors			1	1
 RenderVBOEnable				1	1
@@ -79,6 +80,7 @@ RenderObjectBump			1	0
 RenderReflectionDetail		1	0
 RenderTerrainDetail			1	0
 RenderTerrainLODFactor		1	1
+RenderTransparentWater		1	0
 RenderTreeLODFactor			1	0
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	0.5
@@ -107,6 +109,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	0
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	1.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	1.125
@@ -134,6 +137,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	2
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	1.125
@@ -161,6 +165,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	4
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	1.0
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	2.0
diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt
index f030c9f8e594015287ff2d7946f1f67559a158fd..6dabef53a846a54d69de2f6f83ed623c531c3e65 100644
--- a/indra/newview/featuretable_mac.txt
+++ b/indra/newview/featuretable_mac.txt
@@ -43,6 +43,7 @@ RenderObjectBump				1	1
 RenderReflectionDetail			1	3
 RenderTerrainDetail				1	1
 RenderTerrainLODFactor			1	2.0
+RenderTransparentWater			1	1
 RenderTreeLODFactor				1	1.0
 RenderUseImpostors				1	1
 RenderVBOEnable					1	1
@@ -80,6 +81,7 @@ RenderObjectBump			1	0
 RenderReflectionDetail		1	0
 RenderTerrainDetail			1	0
 RenderTerrainLODFactor		1	1
+RenderTransparentWater		1	0
 RenderTreeLODFactor			1	0
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	0.5
@@ -107,6 +109,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	0
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	1.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	1.125
@@ -133,6 +136,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	2
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	1.125
@@ -159,6 +163,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	3
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	1.0
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	2.0
diff --git a/indra/newview/featuretable_xp.txt b/indra/newview/featuretable_xp.txt
index dae77059710835a1c45477dc308e0d806b794438..a09ba17c6246535e031014482d732addb02f9114 100644
--- a/indra/newview/featuretable_xp.txt
+++ b/indra/newview/featuretable_xp.txt
@@ -42,6 +42,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	4
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	1.0
 RenderUseImpostors			1	1
 RenderVBOEnable				1	1
@@ -80,6 +81,7 @@ RenderObjectBump			1	0
 RenderReflectionDetail		1	0
 RenderTerrainDetail			1	0
 RenderTerrainLODFactor		1	1
+RenderTransparentWater		1	0
 RenderTreeLODFactor			1	0
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	0.5
@@ -108,6 +110,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	0
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	1.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	1.125
@@ -135,6 +138,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	2
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	0.5
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	1.125
@@ -162,6 +166,7 @@ RenderObjectBump			1	1
 RenderReflectionDetail		1	4
 RenderTerrainDetail			1	1
 RenderTerrainLODFactor		1	2.0
+RenderTransparentWater		1	1
 RenderTreeLODFactor			1	1.0
 RenderUseImpostors			1	1
 RenderVolumeLODFactor		1	2.0
diff --git a/indra/newview/generate_breakpad_symbols.py b/indra/newview/generate_breakpad_symbols.py
index 8f2dfd2348909bec0991d12992956d4c5bcd91c7..4fd04d780eb0a8b926797d7623d26b1b04ab611e 100644
--- a/indra/newview/generate_breakpad_symbols.py
+++ b/indra/newview/generate_breakpad_symbols.py
@@ -31,6 +31,7 @@
 import itertools
 import operator
 import os
+import re
 import sys
 import shlex
 import subprocess
@@ -45,8 +46,12 @@ def __init__(self, modules):
         Exception.__init__(self, "Failed to find required modules: %r" % modules)
         self.modules = modules
 
-def main(viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file):
-    print "generate_breakpad_symbols run with args: %s" % str((viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file))
+def main(configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file):
+    print "generate_breakpad_symbols run with args: %s" % str((configuration, viewer_dir, viewer_exes, libs_suffix, dump_syms_tool, viewer_symbol_file))
+
+    if not re.match("release", configuration, re.IGNORECASE):
+        print "skipping breakpad symbol generation for non-release build."
+        return 0
 
     # split up list of viewer_exes
     # "'Second Life' SLPlugin" becomes ['Second Life', 'SLPlugin']
@@ -122,7 +127,7 @@ def match_module_basename(m):
     return 0
 
 if __name__ == "__main__":
-    if len(sys.argv) != 6:
+    if len(sys.argv) != 7:
         usage()
         sys.exit(1)
     sys.exit(main(*sys.argv[1:]))
diff --git a/indra/newview/installers/windows/installer_template.nsi b/indra/newview/installers/windows/installer_template.nsi
index d5712f80cfffe15745b26700903103c2d90778ce..4e8ed807eeef65541d288055ff4dbb948fd91b9b 100644
--- a/indra/newview/installers/windows/installer_template.nsi
+++ b/indra/newview/installers/windows/installer_template.nsi
@@ -85,6 +85,8 @@ AutoCloseWindow true					; after all files install, close window
 InstallDir "$PROGRAMFILES\${INSTNAME}"
 InstallDirRegKey HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" ""
 DirText $(DirectoryChooseTitle) $(DirectoryChooseSetup)
+Page directory dirPre
+Page instfiles
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;; Variables
@@ -95,6 +97,8 @@ Var INSTFLAGS
 Var INSTSHORTCUT
 Var COMMANDLINE         ; command line passed to this installer, set in .onInit
 Var SHORTCUT_LANG_PARAM ; "--set InstallLanguage de", passes language to viewer
+Var SKIP_DIALOGS        ; set from command line in  .onInit. autoinstall 
+                        ; GUI and the defaults.
 
 ;;; Function definitions should go before file includes, because calls to
 ;;; DLLs like LangDLL trigger an implicit file include, so if that call is at
@@ -110,6 +114,9 @@ Var SHORTCUT_LANG_PARAM ; "--set InstallLanguage de", passes language to viewer
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Function .onInstSuccess
     Push $R0	# Option value, unused
+
+    StrCmp $SKIP_DIALOGS "true" label_launch 
+
     ${GetOptions} $COMMANDLINE "/AUTOSTART" $R0
     # If parameter was there (no error) just launch
     # Otherwise ask
@@ -128,6 +135,13 @@ label_no_launch:
 	Pop $R0
 FunctionEnd
 
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;;; Pre-directory page callback
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+Function dirPre
+    StrCmp $SKIP_DIALOGS "true" 0 +2
+	Abort
+FunctionEnd    
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Make sure we're not on Windows 98 / ME
@@ -145,7 +159,8 @@ Function CheckWindowsVersion
 	StrCmp $R0 "NT" win_ver_bad
 	Return
 win_ver_bad:
-	MessageBox MB_YESNO $(CheckWindowsVersionMB) IDNO win_ver_abort
+	StrCmp $SKIP_DIALOGS "true" +2 ; If skip_dialogs is set just install
+            MessageBox MB_YESNO $(CheckWindowsVersionMB) IDNO win_ver_abort
 	Return
 win_ver_abort:
 	Quit
@@ -184,13 +199,13 @@ FunctionEnd
 ; If it has, allow user to bail out of install process.
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 Function CheckIfAlreadyCurrent
-  Push $0
-	ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version"
-    StrCmp $0 ${VERSION_LONG} 0 DONE
-	MessageBox MB_OKCANCEL $(CheckIfCurrentMB) /SD IDOK IDOK DONE
+    Push $0
+    ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\$INSTPROG" "Version"
+    StrCmp $0 ${VERSION_LONG} 0 continue_install
+    StrCmp $SKIP_DIALOGS "true" continue_install
+    MessageBox MB_OKCANCEL $(CheckIfCurrentMB) /SD IDOK IDOK continue_install
     Quit
-
-  DONE:
+continue_install:
     Pop $0
     Return
 FunctionEnd
@@ -203,7 +218,9 @@ Function CloseSecondLife
   Push $0
   FindWindow $0 "Second Life" ""
   IntCmp $0 0 DONE
-  MessageBox MB_OKCANCEL $(CloseSecondLifeInstMB) IDOK CLOSE IDCANCEL CANCEL_INSTALL
+  
+  StrCmp $SKIP_DIALOGS "true" CLOSE
+    MessageBox MB_OKCANCEL $(CloseSecondLifeInstMB) IDOK CLOSE IDCANCEL CANCEL_INSTALL
 
   CANCEL_INSTALL:
     Quit
@@ -659,23 +676,29 @@ FunctionEnd
 Function .onInit
     Push $0
     ${GetParameters} $COMMANDLINE              ; get our command line
+
+    ${GetOptions} $COMMANDLINE "/SKIP_DIALOGS" $0   
+    IfErrors +2 0 ; If error jump past setting SKIP_DIALOGS
+        StrCpy $SKIP_DIALOGS "true"
+
     ${GetOptions} $COMMANDLINE "/LANGID=" $0   ; /LANGID=1033 implies US English
     ; If no language (error), then proceed
-    IfErrors lbl_check_silent
+    IfErrors lbl_configure_default_lang
     ; No error means we got a language, so use it
     StrCpy $LANGUAGE $0
     Goto lbl_return
 
-lbl_check_silent:
-    ; For silent installs, no language prompt, use default
-    IfSilent lbl_return
-    
-	; If we currently have a version of SL installed, default to the language of that install
+lbl_configure_default_lang:
+    ; If we currently have a version of SL installed, default to the language of that install
     ; Otherwise don't change $LANGUAGE and it will default to the OS UI language.
-	ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage"
-    IfErrors lbl_build_menu
+    ReadRegStr $0 HKEY_LOCAL_MACHINE "SOFTWARE\Linden Research, Inc.\${INSTNAME}" "InstallerLanguage"
+    IfErrors +2 0 ; If error skip the copy instruction 
 	StrCpy $LANGUAGE $0
 
+    ; For silent installs, no language prompt, use default
+    IfSilent lbl_return
+    StrCmp $SKIP_DIALOGS "true" lbl_return
+  
 lbl_build_menu:
 	Push ""
     # Use separate file so labels can be UTF-16 but we can still merge changes
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index c9bd7851ed5c610a046130665cea1e94f8de9b79..ea3c2eb312567fca46abcb563d771ee1581ec646 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -56,9 +56,9 @@
 #include "llparcel.h"
 #include "llrendersphere.h"
 #include "llsdutil.h"
-#include "llsidetray.h"
 #include "llsky.h"
 #include "llsmoothstep.h"
+#include "llstartup.h"
 #include "llstatusbar.h"
 #include "llteleportflags.h"
 #include "lltool.h"
@@ -637,6 +637,9 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 			// Update all of the regions.
 			LLWorld::getInstance()->updateAgentOffset(mAgentOriginGlobal);
 		}
+
+		// Pass new region along to metrics components that care about this level of detail.
+		LLAppViewer::metricsUpdateRegion(regionp->getHandle());
 	}
 	mRegionp = regionp;
 
@@ -1726,9 +1729,6 @@ void LLAgent::endAnimationUpdateUI()
 
 		LLBottomTray::getInstance()->onMouselookModeOut();
 
-		LLSideTray::getInstance()->getButtonsPanel()->setVisible(TRUE);
-		LLSideTray::getInstance()->updateSidetrayVisibility();
-
 		LLPanelStandStopFlying::getInstance()->setVisible(TRUE);
 
 		LLToolMgr::getInstance()->setCurrentToolset(gBasicToolset);
@@ -1828,9 +1828,6 @@ void LLAgent::endAnimationUpdateUI()
 
 		LLBottomTray::getInstance()->onMouselookModeIn();
 
-		LLSideTray::getInstance()->getButtonsPanel()->setVisible(FALSE);
-		LLSideTray::getInstance()->updateSidetrayVisibility();
-
 		LLPanelStandStopFlying::getInstance()->setVisible(FALSE);
 
 		// clear out camera lag effect
@@ -2452,7 +2449,7 @@ BOOL LLAgent::setUserGroupFlags(const LLUUID& group_id, BOOL accept_notices, BOO
 
 BOOL LLAgent::canJoinGroups() const
 {
-	return mGroups.count() < MAX_AGENT_GROUPS;
+	return mGroups.count() < gMaxAgentGroups;
 }
 
 LLQuaternion LLAgent::getHeadRotation()
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 6c598d5d7199f4452222c6113164fc2576241018..aebebad96aa580651df092103960ce68e795f967 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -33,6 +33,7 @@
 #include "llagentconstants.h"
 #include "llagentdata.h" 			// gAgentID, gAgentSessionID
 #include "llcharacter.h" 			// LLAnimPauseRequest
+#include "llcoordframe.h"			// for mFrameAgent
 #include "llpointer.h"
 #include "lluicolor.h"
 #include "llvoavatardefines.h"
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 7c953cd2dc2ff9343fe0499a660f8a500e125d3c..f01d5ff1f539121e87b6c3ce373b9fbdb6e2e2d5 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -2041,7 +2041,7 @@ void LLAgentCamera::resetCamera()
 //-----------------------------------------------------------------------------
 void LLAgentCamera::changeCameraToMouselook(BOOL animate)
 {
-	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	if (!gSavedSettings.getBOOL("EnableMouselook") || LLViewerJoystick::getInstance()->getOverrideCamera())
 	{
 		return;
 	}
@@ -2695,6 +2695,9 @@ void LLAgentCamera::lookAtLastChat()
 		new_camera_pos -= delta_pos * 0.4f;
 		new_camera_pos += left * 0.3f;
 		new_camera_pos += up * 0.2f;
+
+		setFocusOnAvatar(FALSE, FALSE);
+
 		if (chatter_av->mHeadp)
 		{
 			setFocusGlobal(gAgent.getPosGlobalFromAgent(chatter_av->mHeadp->getWorldPosition()), gAgent.getLastChatter());
@@ -2705,7 +2708,6 @@ void LLAgentCamera::lookAtLastChat()
 			setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter());
 			mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
 		}
-		setFocusOnAvatar(FALSE, TRUE);
 	}
 	else
 	{
@@ -2725,9 +2727,10 @@ void LLAgentCamera::lookAtLastChat()
 		new_camera_pos += left * 0.3f;
 		new_camera_pos += up * 0.2f;
 
+		setFocusOnAvatar(FALSE, FALSE);
+
 		setFocusGlobal(chatter->getPositionGlobal(), gAgent.getLastChatter());
 		mCameraFocusOffsetTarget = gAgent.getPosGlobalFromAgent(new_camera_pos) - chatter->getPositionGlobal();
-		setFocusOnAvatar(FALSE, TRUE);
 	}
 }
 
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 62074ddcd5c4f69fd2a9db395294d522ac2a4e72..80734b0d41ae5231d670a03cf50c2bb5ef8f5868 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -2437,6 +2437,12 @@ class LLShowCreatedOutfit: public LLInventoryCallback
 
 	virtual ~LLShowCreatedOutfit()
 	{
+		if (!LLApp::isRunning())
+		{
+			llwarns << "called during shutdown, skipping" << llendl;
+			return;
+		}
+
 		LLSD key;
 		
 		//EXT-7727. For new accounts LLShowCreatedOutfit is created during login process
@@ -2941,3 +2947,32 @@ void wear_multiple(const uuid_vec_t& ids, bool replace)
 	}
 }
 
+// SLapp for easy-wearing of a stock (library) avatar
+//
+class LLWearFolderHandler : public LLCommandHandler
+{
+public:
+	// not allowed from outside the app
+	LLWearFolderHandler() : LLCommandHandler("wear_folder", UNTRUSTED_BLOCK) { }
+
+	bool handle(const LLSD& tokens, const LLSD& query_map,
+				LLMediaCtrl* web)
+	{
+		LLPointer<LLInventoryCategory> category = new LLInventoryCategory(query_map["folder_id"],
+																		  LLUUID::null,
+																		  LLFolderType::FT_CLOTHING,
+																		  "Quick Appearance");
+		LLSD::UUID folder_uuid = query_map["folder_id"].asUUID();
+		if ( gInventory.getCategory( folder_uuid ) != NULL )
+		{
+			LLAppearanceMgr::getInstance()->wearInventoryCategory(category, true, false);
+
+			// *TODOw: This may not be necessary if initial outfit is chosen already -- josh
+			gAgent.setGenderChosen(TRUE);
+		}
+
+		return true;
+	}
+};
+
+LLWearFolderHandler gWearFolderHandler;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index bf0f948a6db3fc252cf1329e272baafa07ce431f..3a98c23e05d70a2a4b43a32ebf6b05a666577a06 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -80,9 +80,12 @@
 #include "llfeaturemanager.h"
 #include "llurlmatch.h"
 #include "lltextutil.h"
+#include "lllogininstance.h"
+#include "llprogressview.h"
 
 #include "llweb.h"
 #include "llsecondlifeurls.h"
+#include "llupdaterservice.h"
 
 // Linden library includes
 #include "llavatarnamecache.h"
@@ -191,11 +194,14 @@
 #include "llparcel.h"
 #include "llavatariconctrl.h"
 #include "llgroupiconctrl.h"
+#include "llviewerassetstats.h"
 
 // Include for security api initialization
 #include "llsecapi.h"
 #include "llmachineid.h"
 
+#include "llmainlooprepeater.h"
+
 // *FIX: These extern globals should be cleaned up.
 // The globals either represent state/config/resource-storage of either 
 // this app, or another 'component' of the viewer. App globals should be 
@@ -333,6 +339,14 @@ static std::string gWindowTitle;
 
 LLAppViewer::LLUpdaterInfo *LLAppViewer::sUpdaterInfo = NULL ;
 
+//----------------------------------------------------------------------------
+// Metrics logging control constants
+//----------------------------------------------------------------------------
+static const F32 METRICS_INTERVAL_DEFAULT = 600.0;
+static const F32 METRICS_INTERVAL_QA = 30.0;
+static F32 app_metrics_interval = METRICS_INTERVAL_DEFAULT;
+static bool app_metrics_qa_mode = false;
+
 void idle_afk_check()
 {
 	// check idle timers
@@ -502,6 +516,9 @@ static void settings_modify()
 	gSavedSettings.setBOOL("VectorizeEnable", FALSE );
 	gSavedSettings.setU32("VectorizeProcessor", 0 );
 	gSavedSettings.setBOOL("VectorizeSkin", FALSE);
+
+	// disable fullscreen mode, unsupported
+	gSavedSettings.setBOOL("WindowFullScreen", FALSE);
 #endif
 }
 
@@ -576,7 +593,8 @@ LLAppViewer::LLAppViewer() :
 	mAgentRegionLastAlive(false),
 	mRandomizeFramerate(LLCachedControl<bool>(gSavedSettings,"Randomize Framerate", FALSE)),
 	mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
-	mFastTimerLogThread(NULL)
+	mFastTimerLogThread(NULL),
+	mUpdater(new LLUpdaterService())
 {
 	if(NULL != sInstance)
 	{
@@ -586,10 +604,14 @@ LLAppViewer::LLAppViewer() :
 	setupErrorHandling();
 	sInstance = this;
 	gLoggedInTime.stop();
+	
+	LLLoginInstance::instance().setUpdaterService(mUpdater.get());
 }
 
 LLAppViewer::~LLAppViewer()
 {
+	LLLoginInstance::instance().setUpdaterService(0);
+	
 	destroyMainloopTimeout();
 
 	// If we got to this destructor somehow, the app didn't hang.
@@ -648,14 +670,32 @@ bool LLAppViewer::init()
     // Called before threads are created.
     LLCurl::initClass();
     LLMachineID::init();
+	
+	{
+		// Viewer metrics initialization
+		static LLCachedControl<bool> metrics_submode(gSavedSettings,
+													 "QAModeMetrics",
+													 false,
+													 "Enables QA features (logging, faster cycling) for metrics collector");
+
+		if (metrics_submode)
+		{
+			app_metrics_qa_mode = true;
+			app_metrics_interval = METRICS_INTERVAL_QA;
+		}
+		LLViewerAssetStatsFF::init();
+	}
 
     initThreads();
     writeSystemInfo();
 
-	// Build a string representing the current version number.
-    gCurrentVersion = llformat("%s %s", 
-							   gSavedSettings.getString("VersionChannelName").c_str(),
-							   LLVersionInfo::getVersion().c_str());
+	// Initialize updater service (now that we have an io pump)
+	initUpdater();
+	if(isQuitting())
+	{
+		// Early out here because updater set the quitting flag.
+		return true;
+	}
 
 	//////////////////////////////////////////////////////////////////////////////
 	//////////////////////////////////////////////////////////////////////////////
@@ -799,6 +839,9 @@ bool LLAppViewer::init()
 		return 1;
 	}
 	
+	// Initialize the repeater service.
+	LLMainLoopRepeater::instance().start();
+	
 	//
 	// Initialize the window
 	//
@@ -813,16 +856,22 @@ bool LLAppViewer::init()
 	gGLManager.getGLInfo(gDebugInfo);
 	gGLManager.printGLInfoString();
 
-	//load key settings
-	bind_keyboard_functions();
-
 	// Load Default bindings
-	if (!gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"keys.ini")))
+	std::string key_bindings_file = gDirUtilp->findFile("keys.xml",
+														gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
+														gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+
+
+	if (!gViewerKeyboard.loadBindingsXML(key_bindings_file))
 	{
-		LL_ERRS("InitInfo") << "Unable to open keys.ini" << LL_ENDL;
+		std::string key_bindings_file = gDirUtilp->findFile("keys.ini",
+															gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, ""),
+															gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+		if (!gViewerKeyboard.loadBindings(key_bindings_file))
+		{
+			LL_ERRS("InitInfo") << "Unable to open keys.ini" << LL_ENDL;
+		}
 	}
-	// Load Custom bindings (override defaults)
-	gViewerKeyboard.loadBindings(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS,"custom_keys.ini"));
 
 	// If we don't have the right GL requirements, exit.
 	if (!gGLManager.mHasRequirements && !gNoRender)
@@ -895,7 +944,8 @@ bool LLAppViewer::init()
 	gDebugInfo["GraphicsCard"] = LLFeatureManager::getInstance()->getGPUString();
 
 	// Save the current version to the prefs file
-	gSavedSettings.setString("LastRunVersion", gCurrentVersion);
+	gSavedSettings.setString("LastRunVersion", 
+							 LLVersionInfo::getChannelAndVersion());
 
 	gSimLastTime = gRenderStartTime.getElapsedTimeF32();
 	gSimFrames = (F32)gFrameCount;
@@ -970,7 +1020,7 @@ bool LLAppViewer::mainLoop()
 	gServicePump = new LLPumpIO(gAPRPoolp);
 	LLHTTPClient::setPump(*gServicePump);
 	LLCurl::setCAFile(gDirUtilp->getCAFile());
-
+	
 	// Note: this is where gLocalSpeakerMgr and gActiveSpeakerMgr used to be instantiated.
 
 	LLVoiceChannel::initClass();
@@ -1299,6 +1349,21 @@ bool LLAppViewer::mainLoop()
 	return true;
 }
 
+void LLAppViewer::flushVFSIO()
+{
+	while (1)
+	{
+		S32 pending = LLVFSThread::updateClass(0);
+		pending += LLLFSThread::updateClass(0);
+		if (!pending)
+		{
+			break;
+		}
+		llinfos << "Waiting for pending IO to finish: " << pending << llendflush;
+		ms_sleep(100);
+	}
+}
+
 bool LLAppViewer::cleanup()
 {
 	// workaround for DEV-35406 crash on shutdown
@@ -1353,11 +1418,14 @@ bool LLAppViewer::cleanup()
 	llinfos << "Cleaning Up" << llendflush;
 
 	// Must clean up texture references before viewer window is destroyed.
-	LLHUDManager::getInstance()->updateEffects();
-	LLHUDObject::updateAll();
-	LLHUDManager::getInstance()->cleanupEffects();
-	LLHUDObject::cleanupHUDObjects();
-	llinfos << "HUD Objects cleaned up" << llendflush;
+	if(LLHUDManager::instanceExists())
+	{
+		LLHUDManager::getInstance()->updateEffects();
+		LLHUDObject::updateAll();
+		LLHUDManager::getInstance()->cleanupEffects();
+		LLHUDObject::cleanupHUDObjects();
+		llinfos << "HUD Objects cleaned up" << llendflush;
+	}
 
 	LLKeyframeDataCache::clear();
 	
@@ -1369,8 +1437,10 @@ bool LLAppViewer::cleanup()
 	// Note: this is where gWorldMap used to be deleted.
 
 	// Note: this is where gHUDManager used to be deleted.
-	LLHUDManager::getInstance()->shutdownClass();
-	
+	if(LLHUDManager::instanceExists())
+	{
+		LLHUDManager::getInstance()->shutdownClass();
+	}
 
 	delete gAssetStorage;
 	gAssetStorage = NULL;
@@ -1433,17 +1503,7 @@ bool LLAppViewer::cleanup()
 	llinfos << "Cache files removed" << llendflush;
 
 	// Wait for any pending VFS IO
-	while (1)
-	{
-		S32 pending = LLVFSThread::updateClass(0);
-		pending += LLLFSThread::updateClass(0);
-		if (!pending)
-		{
-			break;
-		}
-		llinfos << "Waiting for pending IO to finish: " << pending << llendflush;
-		ms_sleep(100);
-	}
+	flushVFSIO();
 	llinfos << "Shutting down Views" << llendflush;
 
 	// Destroy the UI
@@ -1666,7 +1726,10 @@ bool LLAppViewer::cleanup()
 
 #ifndef LL_RELEASE_FOR_DOWNLOAD
 	llinfos << "Auditing VFS" << llendl;
-	gVFS->audit();
+	if(gVFS)
+	{
+		gVFS->audit();
+	}
 #endif
 
 	llinfos << "Misc Cleanup" << llendflush;
@@ -1684,6 +1747,8 @@ bool LLAppViewer::cleanup()
 
 	LLWatchdog::getInstance()->cleanup();
 
+	LLViewerAssetStatsFF::cleanup();
+	
 	llinfos << "Shutting down message system" << llendflush;
 	end_messaging_system();
 
@@ -1707,6 +1772,8 @@ bool LLAppViewer::cleanup()
 		llinfos << "File launched." << llendflush;
 	}
 
+	LLMainLoopRepeater::instance().stop();
+
 	ll_close_fail_log();
 
     llinfos << "Goodbye!" << llendflush;
@@ -1748,7 +1815,10 @@ bool LLAppViewer::initThreads()
 	// Image decoding
 	LLAppViewer::sImageDecodeThread = new LLImageDecodeThread(enable_threads && true);
 	LLAppViewer::sTextureCache = new LLTextureCache(enable_threads && true);
-	LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(), sImageDecodeThread, enable_threads && true);
+	LLAppViewer::sTextureFetch = new LLTextureFetch(LLAppViewer::getTextureCache(),
+													sImageDecodeThread,
+													enable_threads && true,
+													app_metrics_qa_mode);
 	LLImage::initClass();
 
 	if (LLFastTimer::sLog || LLFastTimer::sMetricLog)
@@ -1953,8 +2023,6 @@ bool LLAppViewer::initConfiguration()
 	gSavedSettings.setString("ClientSettingsFile", 
         gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, getSettingsFilename("Default", "Global")));
 
-	gSavedSettings.setString("VersionChannelName", LLVersionInfo::getChannel());
-
 #ifndef	LL_RELEASE_FOR_DOWNLOAD
 	// provide developer build only overrides for these control variables that are not
 	// persisted to settings.xml
@@ -2095,6 +2163,11 @@ bool LLAppViewer::initConfiguration()
         }
     }
 
+    if(clp.hasOption("channel"))
+    {
+		LLVersionInfo::resetChannel(clp.getOption("channel")[0]);
+	}
+	
 
 	// If we have specified crash on startup, set the global so we'll trigger the crash at the right time
 	if(clp.hasOption("crashonstartup"))
@@ -2172,7 +2245,7 @@ bool LLAppViewer::initConfiguration()
 
 	if (clp.hasOption("nonotifications"))
 	{
-		gSavedSettings.setBOOL("IgnoreAllNotifications", TRUE);
+		gSavedSettings.getControl("IgnoreAllNotifications")->setValue(true, false);
 	}
 	
 	if (clp.hasOption("debugsession"))
@@ -2219,8 +2292,8 @@ bool LLAppViewer::initConfiguration()
     if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
     {   
 		// hack to force the skin to default.
-        //gDirUtilp->setSkinFolder(skinfolder->getValue().asString());
-		gDirUtilp->setSkinFolder("default");
+        gDirUtilp->setSkinFolder(skinfolder->getValue().asString());
+		//gDirUtilp->setSkinFolder("default");
     }
 
     mYieldTime = gSavedSettings.getS32("YieldTime");
@@ -2364,6 +2437,155 @@ bool LLAppViewer::initConfiguration()
 	return true; // Config was successful.
 }
 
+namespace {
+    // *TODO - decide if there's a better place for these functions.
+    // do we need a file llupdaterui.cpp or something? -brad
+
+	void apply_update_callback(LLSD const & notification, LLSD const & response)
+	{
+		lldebugs << "LLUpdate user response: " << response << llendl;
+		if(response["OK_okcancelbuttons"].asBoolean())
+		{
+			llinfos << "LLUpdate restarting viewer" << llendl;
+			static const bool install_if_ready = true;
+			// *HACK - this lets us launch the installer immediately for now
+			LLUpdaterService().startChecking(install_if_ready);
+		}
+	}
+	
+	void apply_update_ok_callback(LLSD const & notification, LLSD const & response)
+	{
+		llinfos << "LLUpdate restarting viewer" << llendl;
+		static const bool install_if_ready = true;
+		// *HACK - this lets us launch the installer immediately for now
+		LLUpdaterService().startChecking(install_if_ready);
+	}
+	
+	void on_update_downloaded(LLSD const & data)
+	{
+		std::string notification_name;
+		void (*apply_callback)(LLSD const &, LLSD const &) = NULL;
+
+		if(data["required"].asBoolean())
+		{
+			apply_callback = &apply_update_ok_callback;
+			if(LLStartUp::getStartupState() <= STATE_LOGIN_WAIT)
+			{
+				// The user never saw the progress bar.
+				notification_name = "RequiredUpdateDownloadedVerboseDialog";
+			}
+			else
+			{
+				notification_name = "RequiredUpdateDownloadedDialog";
+			}
+		}
+		else
+		{
+			apply_callback = &apply_update_callback;
+			if(LLStartUp::getStartupState() < STATE_STARTED)
+			{
+				// CHOP-262 we need to use a different notification
+				// method prior to login.
+				notification_name = "DownloadBackgroundDialog";
+			}
+			else
+			{
+				notification_name = "DownloadBackgroundTip";
+			}
+		}
+
+		LLSD substitutions;
+		substitutions["VERSION"] = data["version"];
+
+		// truncate version at the rightmost '.' 
+		std::string version_short(data["version"]);
+		size_t short_length = version_short.rfind('.');
+		if (short_length != std::string::npos)
+		{
+			version_short.resize(short_length);
+		}
+
+		LLUIString relnotes_url("[RELEASE_NOTES_BASE_URL][CHANNEL_URL]/[VERSION_SHORT]");
+		relnotes_url.setArg("[VERSION_SHORT]", version_short);
+
+		// *TODO thread the update service's response through to this point
+		std::string const & channel = LLVersionInfo::getChannel();
+		boost::shared_ptr<char> channel_escaped(curl_escape(channel.c_str(), channel.size()), &curl_free);
+
+		relnotes_url.setArg("[CHANNEL_URL]", channel_escaped.get());
+		relnotes_url.setArg("[RELEASE_NOTES_BASE_URL]", LLTrans::getString("RELEASE_NOTES_BASE_URL"));
+		substitutions["RELEASE_NOTES_FULL_URL"] = relnotes_url.getString();
+
+		LLNotificationsUtil::add(notification_name, substitutions, LLSD(), apply_callback);
+	}
+
+	void install_error_callback(LLSD const & notification, LLSD const & response)
+	{
+		LLAppViewer::instance()->forceQuit();
+	}
+	
+    bool notify_update(LLSD const & evt)
+    {
+		std::string notification_name;
+		switch (evt["type"].asInteger())
+		{
+			case LLUpdaterService::DOWNLOAD_COMPLETE:
+				on_update_downloaded(evt);
+				break;
+			case LLUpdaterService::INSTALL_ERROR:
+				if(evt["required"].asBoolean()) {
+					LLNotificationsUtil::add("FailedRequiredUpdateInstall", LLSD(), LLSD(), &install_error_callback);
+				} else {
+					LLNotificationsUtil::add("FailedUpdateInstall");
+				}
+				break;
+			default:
+				break;
+		}
+
+		// let others also handle this event by default
+        return false;
+    }
+	
+	bool on_bandwidth_throttle(LLUpdaterService * updater, LLSD const & evt)
+	{
+		updater->setBandwidthLimit(evt.asInteger() * (1024/8));
+		return false; // Let others receive this event.
+	};
+};
+
+void LLAppViewer::initUpdater()
+{
+	// Initialize the updater service.
+	// Generate URL to the udpater service
+	// Get Channel
+	// Get Version
+	std::string url = gSavedSettings.getString("UpdaterServiceURL");
+	std::string channel = LLVersionInfo::getChannel();
+	std::string version = LLVersionInfo::getVersion();
+	std::string protocol_version = gSavedSettings.getString("UpdaterServiceProtocolVersion");
+	std::string service_path = gSavedSettings.getString("UpdaterServicePath");
+	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
+
+	mUpdater->setAppExitCallback(boost::bind(&LLAppViewer::forceQuit, this));
+	mUpdater->initialize(protocol_version, 
+						 url, 
+						 service_path, 
+						 channel, 
+						 version);
+ 	mUpdater->setCheckPeriod(check_period);
+	mUpdater->setBandwidthLimit((int)gSavedSettings.getF32("UpdaterMaximumBandwidth") * (1024/8));
+	gSavedSettings.getControl("UpdaterMaximumBandwidth")->getSignal()->
+		connect(boost::bind(&on_bandwidth_throttle, mUpdater.get(), _2));
+	if(gSavedSettings.getU32("UpdaterServiceSetting"))
+	{
+		bool install_if_ready = true;
+		mUpdater->startChecking(install_if_ready);
+	}
+
+    LLEventPump & updater_pump = LLEventPumps::instance().obtain(LLUpdaterService::pumpName());
+    updater_pump.listen("notify_update", &notify_update);
+}
 
 void LLAppViewer::checkForCrash(void)
 {
@@ -2423,7 +2645,7 @@ bool LLAppViewer::initWindow()
 		VIEWER_WINDOW_CLASSNAME,
 		gSavedSettings.getS32("WindowX"), gSavedSettings.getS32("WindowY"),
 		gSavedSettings.getS32("WindowWidth"), gSavedSettings.getS32("WindowHeight"),
-		FALSE, ignorePixelDepth);
+		gSavedSettings.getBOOL("WindowFullScreen"), ignorePixelDepth);
 
 	// Need to load feature table before cheking to start watchdog.
 	const S32 NEVER_SUBMIT_REPORT = 2;
@@ -2524,15 +2746,18 @@ void LLAppViewer::cleanupSavedSettings()
 
 	// save window position if not maximized
 	// as we don't track it in callbacks
-	BOOL maximized = gViewerWindow->mWindow->getMaximized();
-	if (!maximized)
+	if(NULL != gViewerWindow)
 	{
-		LLCoordScreen window_pos;
-
-		if (gViewerWindow->mWindow->getPosition(&window_pos))
+		BOOL maximized = gViewerWindow->mWindow->getMaximized();
+		if (!maximized)
 		{
-			gSavedSettings.setS32("WindowX", window_pos.mX);
-			gSavedSettings.setS32("WindowY", window_pos.mY);
+			LLCoordScreen window_pos;
+
+			if (gViewerWindow->mWindow->getPosition(&window_pos))
+			{
+				gSavedSettings.setS32("WindowX", window_pos.mX);
+				gSavedSettings.setS32("WindowY", window_pos.mY);
+			}
 		}
 	}
 
@@ -2555,7 +2780,7 @@ void LLAppViewer::writeSystemInfo()
 {
 	gDebugInfo["SLLog"] = LLError::logFileName();
 
-	gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+	gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
 	gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
 	gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
 	gDebugInfo["ClientInfo"]["PatchVersion"] = LLVersionInfo::getPatch();
@@ -2658,7 +2883,7 @@ void LLAppViewer::handleViewerCrash()
 	
 	//We already do this in writeSystemInfo(), but we do it again here to make /sure/ we have a version
 	//to check against no matter what
-	gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+	gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
 
 	gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
 	gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
@@ -2779,8 +3004,10 @@ void LLAppViewer::handleViewerCrash()
 		pApp->removeMarkerFile(false);
 	}
 	
+#if LL_SEND_CRASH_REPORTS
 	// Call to pure virtual, handled by platform specific llappviewer instance.
 	pApp->handleCrashReporting(); 
+#endif
     
 	return;
 }
@@ -2915,6 +3142,23 @@ void LLAppViewer::forceQuit()
 	LLApp::setQuitting(); 
 }
 
+//TODO: remove
+void LLAppViewer::fastQuit(S32 error_code)
+{
+	// finish pending transfers
+	flushVFSIO();
+	// let sim know we're logging out
+	sendLogoutRequest();
+	// flush network buffers by shutting down messaging system
+	end_messaging_system();
+	// figure out the error code
+	S32 final_error_code = error_code ? error_code : (S32)isError();
+	// this isn't a crash	
+	removeMarkerFile();
+	// get outta here
+	_exit(final_error_code);	
+}
+
 void LLAppViewer::requestQuit()
 {
 	llinfos << "requestQuit" << llendl;
@@ -2923,11 +3167,21 @@ void LLAppViewer::requestQuit()
 	
 	if( (LLStartUp::getStartupState() < STATE_STARTED) || !region )
 	{
+		// If we have a region, make some attempt to send a logout request first.
+		// This prevents the halfway-logged-in avatar from hanging around inworld for a couple minutes.
+		if(region)
+		{
+			sendLogoutRequest();
+		}
+		
 		// Quit immediately
 		forceQuit();
 		return;
 	}
 
+	// Try to send metrics back to the grid
+	metricsSend(!gDisconnected);
+	
 	LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
 	effectp->setPositionGlobal(gAgent.getPositionGlobal());
 	effectp->setColor(LLColor4U(gAgent.getEffectColor()));
@@ -2964,7 +3218,7 @@ static LLNotificationFunctorRegistration finish_quit_reg("ConfirmQuit", finish_q
 
 void LLAppViewer::userQuit()
 {
-	if (gDisconnected)
+	if (gDisconnected || gViewerWindow->getProgressView()->getVisible())
 	{
 		requestQuit();
 	}
@@ -2987,12 +3241,12 @@ void LLAppViewer::earlyExit(const std::string& name, const LLSD& substitutions)
 	LLNotificationsUtil::add(name, substitutions, LLSD(), finish_early_exit);
 }
 
-void LLAppViewer::forceExit(S32 arg)
+// case where we need the viewer to exit without any need for notifications
+void LLAppViewer::earlyExitNoNotify()
 {
-    removeMarkerFile();
-    
-    // *FIX:Mani - This kind of exit hardly seems appropriate.
-    exit(arg);
+   	llwarns << "app_early_exit with no notification: " << llendl;
+	gDoDisconnect = TRUE;
+	finish_early_exit( LLSD(), LLSD() );
 }
 
 void LLAppViewer::abortQuit()
@@ -3036,7 +3290,7 @@ void LLAppViewer::migrateCacheDirectory()
 			S32 file_count = 0;
 			std::string file_name;
 			std::string mask = delimiter + "*.*";
-			while (gDirUtilp->getNextFileInDir(old_cache_dir, mask, file_name, false))
+			while (gDirUtilp->getNextFileInDir(old_cache_dir, mask, file_name))
 			{
 				if (file_name == "." || file_name == "..") continue;
 				std::string source_path = old_cache_dir + delimiter + file_name;
@@ -3255,7 +3509,7 @@ bool LLAppViewer::initCache()
 		dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"");
 
 		std::string found_file;
-		if (gDirUtilp->getNextFileInDir(dir, mask, found_file, false))
+		if (gDirUtilp->getNextFileInDir(dir, mask, found_file))
 		{
 			old_vfs_data_file = dir + gDirUtilp->getDirDelimiter() + found_file;
 
@@ -3588,6 +3842,18 @@ void LLAppViewer::idle()
 		}
 	}
 
+	// debug setting to quit after N seconds of being AFK - 0 to never do this
+	F32 qas_afk = gSavedSettings.getF32("QuitAfterSecondsOfAFK");
+	if (qas_afk > 0.f)
+	{
+		// idle time is more than setting
+		if ( gAwayTriggerTimer.getElapsedTimeF32() > qas_afk )
+		{
+			// go ahead and just quit gracefully
+			LLAppViewer::instance()->requestQuit();
+		}
+	}
+
 	// Must wait until both have avatar object and mute list, so poll
 	// here.
 	request_initial_instant_messages();
@@ -3693,6 +3959,11 @@ void LLAppViewer::idle()
 				llinfos << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << llendl;
 				gObjectList.mNumUnknownUpdates = 0;
 			}
+
+			// ViewerMetrics FPS piggy-backing on the debug timer.
+			// The 5-second interval is nice for this purpose.  If the object debug
+			// bit moves or is disabled, please give this a suitable home.
+			LLViewerAssetStatsFF::record_fps_main(gFPSClamped);
 		}
 	}
 
@@ -3735,6 +4006,18 @@ void LLAppViewer::idle()
 		gInventory.idleNotifyObservers();
 	}
 	
+	// Metrics logging (LLViewerAssetStats, etc.)
+	{
+		static LLTimer report_interval;
+
+		// *TODO:  Add configuration controls for this
+		if (report_interval.getElapsedTimeF32() >= app_metrics_interval)
+		{
+			metricsSend(! gDisconnected);
+			report_interval.reset();
+		}
+	}
+
 	if (gDisconnected)
     {
 		return;
@@ -4024,7 +4307,10 @@ void LLAppViewer::sendLogoutRequest()
 		gLogoutMaxTime = LOGOUT_REQUEST_TIME;
 		mLogoutRequestSent = TRUE;
 		
-		LLVoiceClient::getInstance()->leaveChannel();
+		if(LLVoiceClient::instanceExists())
+		{
+			LLVoiceClient::getInstance()->leaveChannel();
+		}
 
 		//Set internal status variables and marker files
 		gLogoutInProgress = TRUE;
@@ -4271,7 +4557,10 @@ void LLAppViewer::disconnectViewer()
 
 	// This is where we used to call gObjectList.destroy() and then delete gWorldp.
 	// Now we just ask the LLWorld singleton to cleanly shut down.
-	LLWorld::getInstance()->destroyClass();
+	if(LLWorld::instanceExists())
+	{
+		LLWorld::getInstance()->destroyClass();
+	}
 
 	// call all self-registered classes
 	LLDestroyClassList::instance().fireCallbacks();
@@ -4385,7 +4674,7 @@ void LLAppViewer::handleLoginComplete()
 	initMainloopTimeout("Mainloop Init");
 
 	// Store some data to DebugInfo in case of a freeze.
-	gDebugInfo["ClientInfo"]["Name"] = gSavedSettings.getString("VersionChannelName");
+	gDebugInfo["ClientInfo"]["Name"] = LLVersionInfo::getChannel();
 
 	gDebugInfo["ClientInfo"]["MajorVersion"] = LLVersionInfo::getMajor();
 	gDebugInfo["ClientInfo"]["MinorVersion"] = LLVersionInfo::getMinor();
@@ -4445,6 +4734,35 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
 		return;
 	}
 
+	LL_INFOS("eventhost") << "Found lleventhost at '" << dso_path << "'" << LL_ENDL;
+#if ! defined(LL_WINDOWS)
+	{
+		std::string outfile("/tmp/lleventhost.file.out");
+		std::string command("file '" + dso_path + "' > '" + outfile + "' 2>&1");
+		int rc = system(command.c_str());
+		if (rc != 0)
+		{
+			LL_WARNS("eventhost") << command << " ==> " << rc << ':' << LL_ENDL;
+		}
+		else
+		{
+			LL_INFOS("eventhost") << command << ':' << LL_ENDL;
+		}
+		{
+			std::ifstream reader(outfile.c_str());
+			std::string line;
+			while (std::getline(reader, line))
+			{
+				size_t len = line.length();
+				if (len && line[len-1] == '\n')
+					line.erase(len-1);
+				LL_INFOS("eventhost") << line << LL_ENDL;
+			}
+		}
+		remove(outfile.c_str());
+	}
+#endif // LL_WINDOWS
+
 	apr_dso_handle_t * eventhost_dso_handle = NULL;
 	apr_pool_t * eventhost_dso_memory_pool = NULL;
 
@@ -4453,13 +4771,13 @@ void LLAppViewer::loadEventHostModule(S32 listen_port)
 	apr_status_t rv = apr_dso_load(&eventhost_dso_handle,
 		dso_path.c_str(),
 		eventhost_dso_memory_pool);
-	ll_apr_assert_status(rv);
+	llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle));
 	llassert_always(eventhost_dso_handle != NULL);
 
 	int (*ll_plugin_start_func)(LLSD const &) = NULL;
 	rv = apr_dso_sym((apr_dso_handle_sym_t*)&ll_plugin_start_func, eventhost_dso_handle, "ll_plugin_start");
 
-	ll_apr_assert_status(rv);
+	llassert_always(! ll_apr_warn_status(rv, eventhost_dso_handle));
 	llassert_always(ll_plugin_start_func != NULL);
 
 	LLSD args;
@@ -4491,7 +4809,7 @@ void LLAppViewer::launchUpdater()
 	// *TODO change userserver to be grid on both viewer and sim, since
 	// userserver no longer exists.
 	query_map["userserver"] = LLGridManager::getInstance()->getGridLabel();
-	query_map["channel"] = gSavedSettings.getString("VersionChannelName");
+	query_map["channel"] = LLVersionInfo::getChannel();
 	// *TODO constantize this guy
 	// *NOTE: This URL is also used in win_setup/lldownloader.cpp
 	LLURI update_url = LLURI::buildHTTP("secondlife.com", 80, "update.php", query_map);
@@ -4631,3 +4949,75 @@ bool LLAppViewer::getMasterSystemAudioMute()
 {
 	return gSavedSettings.getBOOL("MuteAudio");
 }
+
+//----------------------------------------------------------------------------
+// Metrics-related methods (static and otherwise)
+//----------------------------------------------------------------------------
+
+/**
+ * LLViewerAssetStats collects data on a per-region (as defined by the agent's
+ * location) so we need to tell it about region changes which become a kind of
+ * hidden variable/global state in the collectors.  For collectors not running
+ * on the main thread, we need to send a message to move the data over safely
+ * and cheaply (amortized over a run).
+ */
+void LLAppViewer::metricsUpdateRegion(U64 region_handle)
+{
+	if (0 != region_handle)
+	{
+		LLViewerAssetStatsFF::set_region_main(region_handle);
+		if (LLAppViewer::sTextureFetch)
+		{
+			// Send a region update message into 'thread1' to get the new region.
+			LLAppViewer::sTextureFetch->commandSetRegion(region_handle);
+		}
+		else
+		{
+			// No 'thread1', a.k.a. TextureFetch, so update directly
+			LLViewerAssetStatsFF::set_region_thread1(region_handle);
+		}
+	}
+}
+
+
+/**
+ * Attempts to start a multi-threaded metrics report to be sent back to
+ * the grid for consumption.
+ */
+void LLAppViewer::metricsSend(bool enable_reporting)
+{
+	if (! gViewerAssetStatsMain)
+		return;
+
+	if (LLAppViewer::sTextureFetch)
+	{
+		LLViewerRegion * regionp = gAgent.getRegion();
+
+		if (enable_reporting && regionp)
+		{
+			std::string	caps_url = regionp->getCapability("ViewerMetrics");
+
+			// Make a copy of the main stats to send into another thread.
+			// Receiving thread takes ownership.
+			LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStatsMain));
+			
+			// Send a report request into 'thread1' to get the rest of the data
+			// and provide some additional parameters while here.
+			LLAppViewer::sTextureFetch->commandSendMetrics(caps_url,
+														   gAgentSessionID,
+														   gAgentID,
+														   main_stats);
+			main_stats = 0;		// Ownership transferred
+		}
+		else
+		{
+			LLAppViewer::sTextureFetch->commandDataBreak();
+		}
+	}
+
+	// Reset even if we can't report.  Rather than gather up a huge chunk of
+	// data, we'll keep to our sampling interval and retain the data
+	// resolution in time.
+	gViewerAssetStatsMain->reset();
+}
+
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index a14ab4362f104922abe0602321ba7211c83b4765..a18e6cbb028153a5fffa9eb225bbb50542d6218b 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -39,7 +39,7 @@ class LLTextureCache;
 class LLImageDecodeThread;
 class LLTextureFetch;
 class LLWatchdogTimeout;
-class LLCommandLineParser;
+class LLUpdaterService;
 
 struct apr_dso_handle_t;
 
@@ -65,12 +65,14 @@ class LLAppViewer : public LLApp
 	virtual bool mainLoop(); // Override for the application main loop.  Needs to at least gracefully notice the QUITTING state and exit.
 
 	// Application control
+	void flushVFSIO(); // waits for vfs transfers to complete
 	void forceQuit(); // Puts the viewer into 'shutting down without error' mode.
+	void fastQuit(S32 error_code = 0); // Shuts down the viewer immediately after sending a logout message
 	void requestQuit(); // Request a quit. A kinder, gentler quit.
 	void userQuit(); // The users asks to quit. Confirm, then requestQuit()
     void earlyExit(const std::string& name, 
 				   const LLSD& substitutions = LLSD()); // Display an error dialog and forcibly quit.
-    void forceExit(S32 arg); // exit() immediately (after some cleanup).
+	void earlyExitNoNotify(); // Do not display error dialog then forcibly quit.
     void abortQuit();  // Called to abort a quit request.
 
     bool quitRequested() { return mQuitRequested; }
@@ -167,6 +169,10 @@ class LLAppViewer : public LLApp
 	// mute/unmute the system's master audio
 	virtual void setMasterSystemAudioMute(bool mute);
 	virtual bool getMasterSystemAudioMute();
+
+	// Metrics policy helper statics.
+	static void metricsUpdateRegion(U64 region_handle);
+	static void metricsSend(bool enable_reporting);
 	
 protected:
 	virtual bool initWindow(); // Initialize the viewer's window.
@@ -186,7 +192,7 @@ class LLAppViewer : public LLApp
 
 	bool initThreads(); // Initialize viewer threads, return false on failure.
 	bool initConfiguration(); // Initialize settings from the command line/config file.
-
+	void initUpdater(); // Initialize the updater service.
 	bool initCache(); // Initialize local client cache.
 
 
@@ -264,7 +270,14 @@ class LLAppViewer : public LLApp
 
 	U32 mAvailPhysicalMemInKB ;
 	U32 mAvailVirtualMemInKB ;
+	
+	boost::scoped_ptr<LLUpdaterService> mUpdater;
+
+	//---------------------------------------------
+	//*NOTE: Mani - legacy updater stuff
+	// Still useable?
 public:
+
 	//some information for updater
 	typedef struct
 	{
@@ -274,6 +287,7 @@ class LLAppViewer : public LLApp
 	static LLUpdaterInfo *sUpdaterInfo ;
 
 	void launchUpdater();
+	//---------------------------------------------
 };
 
 // consts from viewer.h
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 7629265730b7aa3ce8962e278edf6dee797b3136..898cc1c0ba8686bc615b685e2d17353c5d51dbb9 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -504,8 +504,7 @@ std::string LLAppViewerLinux::generateSerialNumber()
 
 	// trawl /dev/disk/by-uuid looking for a good-looking UUID to grab
 	std::string this_name;
-	BOOL wrap = FALSE;
-	while (gDirUtilp->getNextFileInDir(uuiddir, "*", this_name, wrap))
+	while (gDirUtilp->getNextFileInDir(uuiddir, "*", this_name))
 	{
 		if (this_name.length() > best.length() ||
 		    (this_name.length() == best.length() &&
diff --git a/indra/newview/llbottomtray.cpp b/indra/newview/llbottomtray.cpp
index 29c2b7565e3da65c8adbc3143f7f22f4fb751c76..35e4548483d5b5e9a36b811a1cb53633b1331961 100644
--- a/indra/newview/llbottomtray.cpp
+++ b/indra/newview/llbottomtray.cpp
@@ -65,31 +65,42 @@ LLDefaultChildRegistry::Register<LLBottomtrayButton> bottomtray_button("bottomtr
 // virtual
 BOOL LLBottomtrayButton::handleHover(S32 x, S32 y, MASK mask)
 {
+	if (mCanDrag)
+	{
 	S32 screenX, screenY;
 	localPointToScreen(x, y, &screenX, &screenY);
 	// pass hover to bottomtray
 	LLBottomTray::getInstance()->onDraggableButtonHover(screenX, screenY);
-	return FALSE;
+		return TRUE;
+	}
+	else
+	{
+		return LLButton::handleHover(x, y, mask);
+	}
 }
 //virtual
 BOOL LLBottomtrayButton::handleMouseUp(S32 x, S32 y, MASK mask)
 {
+	if (mCanDrag)
+	{
 	S32 screenX, screenY;
 	localPointToScreen(x, y, &screenX, &screenY);
 	// pass mouse up to bottomtray
 	LLBottomTray::getInstance()->onDraggableButtonMouseUp(this, screenX, screenY);
-	LLButton::handleMouseUp(x, y, mask);
-	return FALSE;
+	}
+	return LLButton::handleMouseUp(x, y, mask);
 }
 //virtual
 BOOL LLBottomtrayButton::handleMouseDown(S32 x, S32 y, MASK mask)
 {
+	if (mCanDrag)
+	{
 	S32 screenX, screenY;
 	localPointToScreen(x, y, &screenX, &screenY);
 	// pass mouse up to bottomtray
 	LLBottomTray::getInstance()->onDraggableButtonMouseDown(this, screenX, screenY);
-	LLButton::handleMouseDown(x, y, mask);
-	return FALSE;
+	}
+	return LLButton::handleMouseDown(x, y, mask);
 }
 
 static void update_build_button_enable_state()
@@ -150,8 +161,6 @@ class LLBottomTrayLite
 	{
 		mFactoryMap["chat_bar"] = LLCallbackMap(LLBottomTray::createNearbyChatBar, NULL);
 		buildFromFile("panel_bottomtray_lite.xml");
-		// Necessary for focus movement among child controls
-		setFocusRoot(TRUE);
 	}
 
 	BOOL postBuild()
@@ -218,9 +227,6 @@ LLBottomTray::LLBottomTray(const LLSD&)
 	//destroyed LLBottomTray requires some subsystems that are long gone
 	//LLUI::getRootView()->addChild(this);
 
-	// Necessary for focus movement among child controls
-	setFocusRoot(TRUE);
-
 	{
 		mBottomTrayLite = new LLBottomTrayLite();
 		mBottomTrayLite->setFollowsAll();
@@ -513,6 +519,9 @@ void LLBottomTray::toggleCameraControls()
 
 BOOL LLBottomTray::postBuild()
 {
+	LLHints::registerHintTarget("bottom_tray", LLView::getHandle());
+	LLHints::registerHintTarget("dest_guide_btn", getChild<LLUICtrl>("destination_btn")->getHandle());
+	LLHints::registerHintTarget("avatar_picker_btn", getChild<LLUICtrl>("avatar_btn")->getHandle());
 
 	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("NearbyChatBar.Action", boost::bind(&LLBottomTray::onContextMenuItemClicked, this, _2));
 	LLUICtrl::EnableCallbackRegistry::currentRegistrar().add("NearbyChatBar.EnableMenuItem", boost::bind(&LLBottomTray::onContextMenuItemEnabled, this, _2));
@@ -1365,20 +1374,33 @@ void LLBottomTray::processExtendButtons(S32& available_width)
 		processExtendButton(*it, available_width);
 	}
 
+	const S32 chiclet_panel_width = mChicletPanel->getParent()->getRect().getWidth();
+	static const S32 chiclet_panel_min_width = mChicletPanel->getMinWidth();
+	const S32 available_width_chiclet = chiclet_panel_width - chiclet_panel_min_width;
+
 	// then try to extend Speak button
-	if (available_width > 0)
+	if (available_width > 0 || available_width_chiclet > 0)
 	{
 		S32 panel_max_width = mObjectDefaultWidthMap[RS_BUTTON_SPEAK];
 		S32 panel_width = mSpeakPanel->getRect().getWidth();
 		S32 possible_extend_width = panel_max_width - panel_width;
-		if (possible_extend_width >= 0 && possible_extend_width <= available_width)  // HACK: this button doesn't change size so possible_extend_width will be 0
+
+		if (possible_extend_width >= 0 && possible_extend_width <= available_width + available_width_chiclet)  // HACK: this button doesn't change size so possible_extend_width will be 0
 		{
 			mSpeakBtn->setLabelVisible(true);
 			mSpeakPanel->reshape(panel_max_width, mSpeakPanel->getRect().getHeight());
 			log(mSpeakBtn, "speak button is extended");
 
-			available_width -= possible_extend_width;
-
+			if( available_width > possible_extend_width)
+			{
+				available_width -= possible_extend_width;
+			}
+			else
+			{
+				S32 required_width = possible_extend_width - available_width;
+				available_width = 0;
+				mChicletPanel->getParent()->reshape(mChicletPanel->getParent()->getRect().getWidth() - required_width, mChicletPanel->getParent()->getRect().getHeight());
+			}
 			lldebugs << "Extending Speak button panel: " << mSpeakPanel->getName()
 				<< ", extended width: " << possible_extend_width
 				<< ", rest width to process: " << available_width
diff --git a/indra/newview/llbottomtray.h b/indra/newview/llbottomtray.h
index 8d8a42c553c41929404628b84b88d3d80ffa5d27..dc98170049d4e63cfefc3eb6f185dc16f405ba01 100644
--- a/indra/newview/llbottomtray.h
+++ b/indra/newview/llbottomtray.h
@@ -54,7 +54,9 @@ class LLBottomtrayButton : public LLButton
 public:
 	struct Params : public LLInitParam::Block<Params, LLButton::Params>
 	{
-		Params(){}
+		Optional<bool> can_drag;
+		Params()
+		: can_drag("can_drag", true){}
 	};
 	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
@@ -62,11 +64,14 @@ class LLBottomtrayButton : public LLButton
 
 protected:
 	LLBottomtrayButton(const Params& p)
-		:	LLButton(p)
+	:	LLButton(p),
+		mCanDrag(p.can_drag)
 	{
 
 	}
 	friend class LLUICtrlFactory;
+
+	bool mCanDrag;
 };
 
 class LLBottomTray 
diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp
index d6a813d60806ddefbbed85abc3a20d0eddb506a0..6e77d1e3363dd6ecede27859efe9f45b75eb2a44 100644
--- a/indra/newview/llbrowsernotification.cpp
+++ b/indra/newview/llbrowsernotification.cpp
@@ -29,8 +29,9 @@
 
 #include "llnotificationhandler.h"
 #include "llnotifications.h"
-#include "llfloaterreg.h"
 #include "llmediactrl.h"
+#include "llviewermedia.h"
+#include "llviewermediafocus.h"
 
 using namespace LLNotificationsUI;
 
@@ -39,10 +40,19 @@ bool LLBrowserNotification::processNotification(const LLSD& notify)
 	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
 	if (!notification) return false;
 
-	LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(notification->getPayload()["media_id"].asUUID());
+	LLUUID media_id = notification->getPayload()["media_id"].asUUID();
+	LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id);
 	if (media_instance)
 	{
 		media_instance->showNotification(notification);
 	}
+	else if (LLViewerMediaFocus::instance().getControlsMediaID() == media_id)
+	{
+		LLViewerMediaImpl* impl = LLViewerMedia::getMediaImplFromTextureID(media_id);
+		if (impl)
+		{
+			impl->showNotification(notification);
+		}
+	}
 	return false;
 }
diff --git a/indra/newview/llbuycurrencyhtml.cpp b/indra/newview/llbuycurrencyhtml.cpp
index d35c9ed8535f658fd761abc0f8942f86a8e7aaad..e5a9be020311da047208e1646899560ae9b92915 100644
--- a/indra/newview/llbuycurrencyhtml.cpp
+++ b/indra/newview/llbuycurrencyhtml.cpp
@@ -33,6 +33,7 @@
 #include "llfloaterreg.h"
 #include "llcommandhandler.h"
 #include "llviewercontrol.h"
+#include "llstatusbar.h"
 
 // support for secondlife:///app/buycurrencyhtml/{ACTION}/{NEXT_ACTION}/{RETURN_CODE} SLapps
 class LLBuyCurrencyHTMLHandler : 
@@ -156,4 +157,7 @@ void LLBuyCurrencyHTML::closeDialog()
 	{
 		buy_currency_floater->closeFloater();
 	};
+	
+	// Update L$ balance in the status bar in case L$ were purchased
+	LLStatusBar::sendMoneyBalanceRequest();
 }
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
index b2e9564f7d3bb13a3240577e604d998140f79e5e..328c3262787a2f94f83cbecb1650e892757253ac 100644
--- a/indra/newview/llcallfloater.cpp
+++ b/indra/newview/llcallfloater.cpp
@@ -167,6 +167,7 @@ BOOL LLCallFloater::postBuild()
 	//chrome="true" hides floater caption 
 	if (mDragHandle)
 		mDragHandle->setTitleVisible(TRUE);
+	updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)
 	
 	updateSession();
 
@@ -205,6 +206,17 @@ void LLCallFloater::draw()
 	LLTransientDockableFloater::draw();
 }
 
+// virtual
+void LLCallFloater::setFocus( BOOL b )
+{
+	LLTransientDockableFloater::setFocus(b);
+
+	// Force using active floater transparency (STORM-730).
+	// We have to override setFocus() for LLCallFloater because selecting an item
+	// of the voice morphing combobox causes the floater to lose focus and thus become transparent.
+	updateTransparency(TT_ACTIVE);
+}
+
 // virtual
 void LLCallFloater::onParticipantsChanged()
 {
diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h
index 3bc70433530da2027c0895929d11715075a9b27c..00a3f76e5679d53ee2908cff0ab9776ebe04e289 100644
--- a/indra/newview/llcallfloater.h
+++ b/indra/newview/llcallfloater.h
@@ -64,6 +64,7 @@ class LLCallFloater : public LLTransientDockableFloater, LLVoiceClientParticipan
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void draw();
+	/*virtual*/ void setFocus( BOOL b );
 
 	/**
 	 * Is called by LLVoiceClient::notifyParticipantObservers when voice participant list is changed.
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 0f7e9313a9fff1e60e13e877f3692f4396bf62c7..c98bcbda45325b6abb9b1da5a565e8aaaac191a8 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -586,7 +586,7 @@ void LLChatHistory::initFromParams(const LLChatHistory::Params& p)
 	LLLayoutStack::Params layout_p;
 	layout_p.rect = stack_rect;
 	layout_p.follows.flags = FOLLOWS_ALL;
-	layout_p.orientation = "vertical";
+	layout_p.orientation = LLLayoutStack::VERTICAL;
 	layout_p.mouse_opaque = false;
 	
 	LLLayoutStack* stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p, this);
@@ -789,9 +789,12 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 				// set the link for the object name to be the objectim SLapp
 				// (don't let object names with hyperlinks override our objectim Url)
 				LLStyle::Params link_params(style_params);
-				link_params.color.control = "HTMLLinkColor";
+				LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
+				link_params.color = link_color;
+				link_params.readonly_color = link_color;
 				link_params.is_link = true;
 				link_params.link_href = url;
+
 				mEditor->appendText(chat.mFromName + delimiter,
 									false, link_params);
 			}
@@ -799,9 +802,9 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			{
 				LLStyle::Params link_params(style_params);
 				link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));
+
 				// Add link to avatar's inspector and delimiter to message.
-				mEditor->appendText(link_params.link_href, false, style_params);
-				mEditor->appendText(delimiter, false, style_params);
+				mEditor->appendText(std::string(link_params.link_href) + delimiter, false, link_params);
 			}
 			else
 			{
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index d353c809cac14e2c06a36a0ab0fdf23d17dadfab..899e0431e7c29634dd37c8e7ddd7c759151b8eca 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -213,7 +213,6 @@ void LLNearbyChatToastPanel::init(LLSD& notification)
 		{
 			LLStyle::Params style_params_name;
 
-			LLColor4 userNameColor = LLUIColorTable::instance().getColor("ChatToastAgentNameColor");
 			std::string href;
 
 			if (mSourceType == CHAT_SOURCE_AGENT)
@@ -225,7 +224,8 @@ void LLNearbyChatToastPanel::init(LLSD& notification)
 				href = LLSLURL("object", mFromID, "inspect").getSLURLString();
 			}
 
-			style_params_name.color(userNameColor);
+			LLColor4 user_name_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
+			style_params_name.color(user_name_color);
 
 			std::string font_name = LLFontGL::nameFromFont(messageFont);
 			std::string font_style_size = LLFontGL::sizeFromFont(messageFont);
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 8f385160e9e50c084a03a3f5b62515a4117a468c..885d5535247e86c3de6449e2d06fd110bd85b21e 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -1092,9 +1092,11 @@ LLChicletPanel::LLChicletPanel(const Params&p)
 
 LLChicletPanel::~LLChicletPanel()
 {
-	LLTransientFloaterMgr::getInstance()->removeControlView(mLeftScrollButton);
-	LLTransientFloaterMgr::getInstance()->removeControlView(mRightScrollButton);
-
+	if(LLTransientFloaterMgr::instanceExists())
+	{
+		LLTransientFloaterMgr::getInstance()->removeControlView(mLeftScrollButton);
+		LLTransientFloaterMgr::getInstance()->removeControlView(mRightScrollButton);
+	}
 }
 
 void im_chiclet_callback(LLChicletPanel* panel, const LLSD& data){
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index c9a526a3beb323b1806949883dc288ad2909d1c9..4a1ba6f1b5fe91903323ccb8f5ad23b280eb7305 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -53,6 +53,7 @@ LLColorSwatchCtrl::Params::Params()
 	alpha_background_image("alpha_background_image"),
 	border_color("border_color"),
     label_width("label_width", -1),
+	label_height("label_height", -1),
 	caption_text("caption_text"),
 	border("border")
 {
@@ -68,17 +69,20 @@ LLColorSwatchCtrl::LLColorSwatchCtrl(const Params& p)
 	mOnCancelCallback(p.cancel_callback()),
 	mOnSelectCallback(p.select_callback()),
 	mBorderColor(p.border_color()),
-	mLabelWidth(p.label_width)
+	mLabelWidth(p.label_width),
+	mLabelHeight(p.label_height)
 {	
 	LLTextBox::Params tp = p.caption_text;
+	// use custom label height if it is provided
+	mLabelHeight = mLabelHeight != -1 ? mLabelHeight : BTN_HEIGHT_SMALL;
 	// label_width is specified, not -1
 	if(mLabelWidth!= -1)
 	{
-		tp.rect(LLRect( 0, BTN_HEIGHT_SMALL, mLabelWidth, 0 ));
+		tp.rect(LLRect( 0, mLabelHeight, mLabelWidth, 0 ));
 	}
 	else
 	{
-		tp.rect(LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ));
+		tp.rect(LLRect( 0, mLabelHeight, getRect().getWidth(), 0 ));
 	}
 	
 	tp.initial_value(p.label());
@@ -88,7 +92,7 @@ LLColorSwatchCtrl::LLColorSwatchCtrl(const Params& p)
 	LLRect border_rect = getLocalRect();
 	border_rect.mTop -= 1;
 	border_rect.mRight -=1;
-	border_rect.mBottom += BTN_HEIGHT_SMALL;
+	border_rect.mBottom += mLabelHeight;
 
 	LLViewBorder::Params params = p.border;
 	params.rect(border_rect);
@@ -191,10 +195,12 @@ BOOL LLColorSwatchCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
 // assumes GL state is set for 2D
 void LLColorSwatchCtrl::draw()
 {
-	F32 alpha = getDrawContext().mAlpha;
+	// If we're in a focused floater, don't apply the floater's alpha to the color swatch (STORM-676).
+	F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
+
 	mBorder->setKeyboardFocusHighlight(hasFocus());
 	// Draw border
-	LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
+	LLRect border( 0, getRect().getHeight(), getRect().getWidth(), mLabelHeight );
 	gl_rect_2d( border, mBorderColor.get(), FALSE );
 
 	LLRect interior = border;
@@ -203,19 +209,29 @@ void LLColorSwatchCtrl::draw()
 	// Check state
 	if ( mValid )
 	{
+		if (!mColor.isOpaque())
+		{
+			// Draw checker board.
+			gl_rect_2d_checkerboard(interior, alpha);
+		}
+
 		// Draw the color swatch
-		gl_rect_2d_checkerboard( interior );
-		gl_rect_2d(interior, mColor, TRUE);
-		LLColor4 opaque_color = mColor;
-		opaque_color.mV[VALPHA] = 1.f;
-		gGL.color4fv(opaque_color.mV);
-		if (mAlphaGradientImage.notNull())
+		gl_rect_2d(interior, mColor % alpha, TRUE);
+
+		if (!mColor.isOpaque())
 		{
-			gGL.pushMatrix();
+			// Draw semi-transparent center area in filled with mColor.
+			LLColor4 opaque_color = mColor;
+			opaque_color.mV[VALPHA] = alpha;
+			gGL.color4fv(opaque_color.mV);
+			if (mAlphaGradientImage.notNull())
 			{
-				mAlphaGradientImage->draw(interior, mColor);
+				gGL.pushMatrix();
+				{
+					mAlphaGradientImage->draw(interior, mColor % alpha);
+				}
+				gGL.popMatrix();
 			}
-			gGL.popMatrix();
 		}
 	}
 	else
diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h
index a4ce1ca099218bb13d66cf05fa81e6b16eda71f1..cd859ea1286c052a51d4247c627907f9f562d4d1 100644
--- a/indra/newview/llcolorswatch.h
+++ b/indra/newview/llcolorswatch.h
@@ -61,6 +61,7 @@ class LLColorSwatchCtrl
 		Optional<commit_callback_t> 	select_callback;
 		Optional<LLUIColor>				border_color;
 		Optional<S32>					label_width;
+		Optional<S32>					label_height;
 		
 		Optional<LLTextBox::Params>		caption_text;
 		Optional<LLViewBorder::Params>	border;
@@ -112,6 +113,7 @@ class LLColorSwatchCtrl
 	commit_callback_t mOnCancelCallback;
 	commit_callback_t mOnSelectCallback;
 	S32             mLabelWidth;
+	S32             mLabelHeight;
 
 	LLPointer<LLUIImage> mAlphaGradientImage;
 	std::string		mFallbackImageName;
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp
index f31ff14df6390d34712b77a636bd1815fb120c14..65c61c4a8bdf456c6b41dc7f9a2c505d1b525ad8 100644
--- a/indra/newview/llcommandlineparser.cpp
+++ b/indra/newview/llcommandlineparser.cpp
@@ -345,7 +345,10 @@ bool LLCommandLineParser::parseCommandLine(int argc, char **argv)
 bool LLCommandLineParser::parseCommandLineString(const std::string& str)
 {
     // Split the string content into tokens
-    boost::escaped_list_separator<char> sep("\\", "\r\n ", "\"'");
+	const char* escape_chars = "\\";
+	const char* separator_chars = "\r\n ";
+	const char* quote_chars = "\"'";
+    boost::escaped_list_separator<char> sep(escape_chars, separator_chars, quote_chars);
     boost::tokenizer< boost::escaped_list_separator<char> > tok(str, sep);
     std::vector<std::string> tokens;
     // std::copy(tok.begin(), tok.end(), std::back_inserter(tokens));
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index 2b92b228b39c2274981a3bae9df64905fb92abf8..b4a1457f47f9d302982bbfecc489ebb9f8cd0b35 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -166,7 +166,7 @@ void LLCurrencyUIManager::Impl::updateCurrencyInfo()
 		gAgent.getSecureSessionID().asString());
 	keywordArgs.appendString("language", LLUI::getLanguage());
 	keywordArgs.appendInt("currencyBuy", mUserCurrencyBuy);
-	keywordArgs.appendString("viewerChannel", gSavedSettings.getString("VersionChannelName"));
+	keywordArgs.appendString("viewerChannel", LLVersionInfo::getChannel());
 	keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::getMajor());
 	keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::getMinor());
 	keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::getPatch());
@@ -241,7 +241,7 @@ void LLCurrencyUIManager::Impl::startCurrencyBuy(const std::string& password)
 	{
 		keywordArgs.appendString("password", password);
 	}
-	keywordArgs.appendString("viewerChannel", gSavedSettings.getString("VersionChannelName"));
+	keywordArgs.appendString("viewerChannel", LLVersionInfo::getChannel());
 	keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::getMajor());
 	keywordArgs.appendInt("viewerMinorVersion", LLVersionInfo::getMinor());
 	keywordArgs.appendInt("viewerPatchVersion", LLVersionInfo::getPatch());
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index 53101f0ce2ab01b47e592545a08df30f1e27492f..dd243397a1a4f65c314b75c25e2c6d401468772e 100644
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -35,6 +35,7 @@
 #include "llframetimer.h"
 #include "lltrans.h"
 #include "llwindow.h"	// beforeDialog()
+#include "llviewercontrol.h"
 
 #if LL_LINUX || LL_SOLARIS
 # include "llfilepicker.h"
@@ -53,6 +54,23 @@ LLDirPicker LLDirPicker::sInstance;
 //
 // Implementation
 //
+
+// utility function to check if access to local file system via file browser 
+// is enabled and if not, tidy up and indicate we're not allowed to do this.
+bool LLDirPicker::check_local_file_access_enabled()
+{
+	// if local file browsing is turned off, return without opening dialog
+	bool local_file_system_browsing_enabled = gSavedSettings.getBOOL("LocalFileSystemBrowsingEnabled");
+	if ( ! local_file_system_browsing_enabled )
+	{
+		mDir.clear();	// Windows
+		mFileName = NULL; // Mac/Linux
+		return false;
+	}
+
+	return true;
+}
+
 #if LL_WINDOWS
 
 LLDirPicker::LLDirPicker() :
@@ -72,6 +90,13 @@ BOOL LLDirPicker::getDir(std::string* filename)
 	{
 		return FALSE;
 	}
+
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	BOOL success = FALSE;
 
 	// Modal, so pause agent
@@ -231,7 +256,13 @@ BOOL LLDirPicker::getDir(std::string* filename)
 	if( mLocked ) return FALSE;
 	BOOL success = FALSE;
 	OSStatus	error = noErr;
-	
+
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	mFileName = filename;
 	
 //	mNavOptions.saveFileName 
@@ -289,6 +320,13 @@ void LLDirPicker::reset()
 BOOL LLDirPicker::getDir(std::string* filename)
 {
 	reset();
+
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	if (mFilePicker)
 	{
 		GtkWindow* picker = mFilePicker->buildFilePicker(false, true,
diff --git a/indra/newview/lldirpicker.h b/indra/newview/lldirpicker.h
index a360293fff599c767c55ffe4dd2143b0d1e168e5..2188b7edd0447caec684c73f1c5c387130af1e64 100644
--- a/indra/newview/lldirpicker.h
+++ b/indra/newview/lldirpicker.h
@@ -75,6 +75,7 @@ class LLDirPicker
 	};
 	
 	void buildDirname( void );
+	bool check_local_file_access_enabled();
 
 #if LL_DARWIN
 	NavDialogCreationOptions mNavOptions;
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 0ee70bcdd14525a810dd9c11461b4d8239a927b1..dc94924da4e2cc358fee04a08d82c861061ae4de 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -48,7 +48,8 @@
 #include "llviewershadermgr.h"
 #include "llwaterparammanager.h"
 
-const LLUUID WATER_TEST("2bfd3884-7e27-69b9-ba3a-3e673f680004");
+const LLUUID TRANSPARENT_WATER_TEXTURE("2bfd3884-7e27-69b9-ba3a-3e673f680004");
+const LLUUID OPAQUE_WATER_TEXTURE("43c32285-d658-1793-c123-bf86315de055");
 
 static float sTime;
 
@@ -71,10 +72,14 @@ LLDrawPoolWater::LLDrawPoolWater() :
 	gGL.getTexUnit(0)->bind(mHBTex[1]);
 	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
 
-	mWaterImagep = LLViewerTextureManager::getFetchedTexture(WATER_TEST);
-	mWaterImagep->setNoDelete() ;
+
+	mWaterImagep = LLViewerTextureManager::getFetchedTexture(TRANSPARENT_WATER_TEXTURE);
+	llassert(mWaterImagep);
+	mWaterImagep->setNoDelete();
+	mOpaqueWaterImagep = LLViewerTextureManager::getFetchedTexture(OPAQUE_WATER_TEXTURE);
+	llassert(mOpaqueWaterImagep);
 	mWaterNormp = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL);
-	mWaterNormp->setNoDelete() ;
+	mWaterNormp->setNoDelete();
 
 	restoreGL();
 }
@@ -161,6 +166,14 @@ void LLDrawPoolWater::render(S32 pass)
 
 	std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater());
 
+	// See if we are rendering water as opaque or not
+	if (!gSavedSettings.getBOOL("RenderTransparentWater"))
+	{
+		// render water for low end hardware
+		renderOpaqueLegacyWater();
+		return;
+	}
+
 	LLGLEnable blend(GL_BLEND);
 
 	if ((mVertexShaderLevel > 0) && !sSkipScreenCopy)
@@ -314,6 +327,87 @@ void LLDrawPoolWater::render(S32 pass)
 	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
 }
 
+// for low end hardware
+void LLDrawPoolWater::renderOpaqueLegacyWater()
+{
+	LLVOSky *voskyp = gSky.mVOSkyp;
+
+	stop_glerror();
+
+	// Depth sorting and write to depth buffer
+	// since this is opaque, we should see nothing
+	// behind the water.  No blending because
+	// of no transparency.  And no face culling so
+	// that the underside of the water is also opaque.
+	LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE);
+	LLGLDisable no_cull(GL_CULL_FACE);
+	LLGLDisable no_blend(GL_BLEND);
+
+	gPipeline.disableLights();
+
+	mOpaqueWaterImagep->addTextureStats(1024.f*1024.f);
+
+	// Activate the texture binding and bind one
+	// texture since all images will have the same texture
+	gGL.getTexUnit(0)->activate();
+	gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(0)->bind(mOpaqueWaterImagep);
+
+	// Automatically generate texture coords for water texture
+	glEnable(GL_TEXTURE_GEN_S); //texture unit 0
+	glEnable(GL_TEXTURE_GEN_T); //texture unit 0
+	glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+	glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
+
+	// Use the fact that we know all water faces are the same size
+	// to save some computation
+
+	// Slowly move texture coordinates over time so the watter appears
+	// to be moving.
+	F32 movement_period_secs = 50.f;
+
+	F32 offset = fmod(gFrameTimeSeconds, movement_period_secs);
+
+	if (movement_period_secs != 0)
+	{
+	 	offset /= movement_period_secs;
+	}
+	else
+	{
+		offset = 0;
+	}
+
+	F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset };
+	F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset };
+
+	glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0);
+	glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1);
+
+	glColor3f(1.f, 1.f, 1.f);
+
+	for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
+		 iter != mDrawFace.end(); iter++)
+	{
+		LLFace *face = *iter;
+		if (voskyp->isReflFace(face))
+		{
+			continue;
+		}
+
+		face->renderIndexed();
+	}
+
+	stop_glerror();
+
+	// Reset the settings back to expected values
+	glDisable(GL_TEXTURE_GEN_S); //texture unit 0
+	glDisable(GL_TEXTURE_GEN_T); //texture unit 0
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+}
+
+
 void LLDrawPoolWater::renderReflection(LLFace* face)
 {
 	LLVOSky *voskyp = gSky.mVOSkyp;
diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h
index 2648a5276cb6b2ae8d8121a4ed5869ca4daba49b..99b541ca5a384d1de939c9795e96b908f0265abd 100644
--- a/indra/newview/lldrawpoolwater.h
+++ b/indra/newview/lldrawpoolwater.h
@@ -39,6 +39,7 @@ class LLDrawPoolWater: public LLFacePool
 protected:
 	LLPointer<LLViewerTexture> mHBTex[2];
 	LLPointer<LLViewerTexture> mWaterImagep;
+	LLPointer<LLViewerTexture> mOpaqueWaterImagep;
 	LLPointer<LLViewerTexture> mWaterNormp;
 
 public:
@@ -80,6 +81,9 @@ class LLDrawPoolWater: public LLFacePool
 
 	void renderReflection(LLFace* face);
 	void shade();
+
+protected:
+	void renderOpaqueLegacyWater();
 };
 
 void cgErrorCallback();
diff --git a/indra/newview/llexternaleditor.cpp b/indra/newview/llexternaleditor.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..54968841ab1521461002482ad0631f39aecfa46f
--- /dev/null
+++ b/indra/newview/llexternaleditor.cpp
@@ -0,0 +1,192 @@
+/** 
+ * @file llexternaleditor.cpp
+ * @brief A convenient class to run external editor.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llexternaleditor.h"
+
+#include "llui.h"
+
+// static
+const std::string LLExternalEditor::sFilenameMarker = "%s";
+
+// static
+const std::string LLExternalEditor::sSetting = "ExternalEditor";
+
+bool LLExternalEditor::setCommand(const std::string& env_var, const std::string& override)
+{
+	std::string cmd = findCommand(env_var, override);
+	if (cmd.empty())
+	{
+		llwarns << "Empty editor command" << llendl;
+		return false;
+	}
+
+	// Add the filename marker if missing.
+	if (cmd.find(sFilenameMarker) == std::string::npos)
+	{
+		cmd += " \"" + sFilenameMarker + "\"";
+		llinfos << "Adding the filename marker (" << sFilenameMarker << ")" << llendl;
+	}
+
+	string_vec_t tokens;
+	if (tokenize(tokens, cmd) < 2) // 2 = bin + at least one arg (%s)
+	{
+		llwarns << "Error parsing editor command" << llendl;
+		return false;
+	}
+
+	// Check executable for existence.
+	std::string bin_path = tokens[0];
+	if (!LLFile::isfile(bin_path))
+	{
+		llwarns << "Editor binary [" << bin_path << "] not found" << llendl;
+		return false;
+	}
+
+	// Save command.
+	mProcess.setExecutable(bin_path);
+	mArgs.clear();
+	for (size_t i = 1; i < tokens.size(); ++i)
+	{
+		if (i > 1) mArgs += " ";
+		mArgs += "\"" + tokens[i] + "\"";
+	}
+	llinfos << "Setting command [" << bin_path << " " << mArgs << "]" << llendl;
+
+	return true;
+}
+
+bool LLExternalEditor::run(const std::string& file_path)
+{
+	std::string args = mArgs;
+	if (mProcess.getExecutable().empty() || args.empty())
+	{
+		llwarns << "Editor command not set" << llendl;
+		return false;
+	}
+
+	// Substitute the filename marker in the command with the actual passed file name.
+	LLStringUtil::replaceString(args, sFilenameMarker, file_path);
+
+	// Split command into separate tokens.
+	string_vec_t tokens;
+	tokenize(tokens, args);
+
+	// Set process arguments taken from the command.
+	mProcess.clearArguments();
+	for (string_vec_t::const_iterator arg_it = tokens.begin(); arg_it != tokens.end(); ++arg_it)
+	{
+		mProcess.addArgument(*arg_it);
+	}
+
+	// Run the editor.
+	llinfos << "Running editor command [" << mProcess.getExecutable() + " " + args << "]" << llendl;
+	int result = mProcess.launch();
+	if (result == 0)
+	{
+		// Prevent killing the process in destructor (will add it to the zombies list).
+		mProcess.orphan();
+	}
+
+	return result == 0;
+}
+
+// static
+size_t LLExternalEditor::tokenize(string_vec_t& tokens, const std::string& str)
+{
+	tokens.clear();
+
+	// Split the argument string into separate strings for each argument
+	typedef boost::tokenizer< boost::char_separator<char> > tokenizer;
+	boost::char_separator<char> sep("", "\" ", boost::drop_empty_tokens);
+
+	tokenizer tokens_list(str, sep);
+	tokenizer::iterator token_iter;
+	BOOL inside_quotes = FALSE;
+	BOOL last_was_space = FALSE;
+	for (token_iter = tokens_list.begin(); token_iter != tokens_list.end(); ++token_iter)
+	{
+		if (!strncmp("\"",(*token_iter).c_str(),2))
+		{
+			inside_quotes = !inside_quotes;
+		}
+		else if (!strncmp(" ",(*token_iter).c_str(),2))
+		{
+			if(inside_quotes)
+			{
+				tokens.back().append(std::string(" "));
+				last_was_space = TRUE;
+			}
+		}
+		else
+		{
+			std::string to_push = *token_iter;
+			if (last_was_space)
+			{
+				tokens.back().append(to_push);
+				last_was_space = FALSE;
+			}
+			else
+			{
+				tokens.push_back(to_push);
+			}
+		}
+	}
+
+	return tokens.size();
+}
+
+// static
+std::string LLExternalEditor::findCommand(
+	const std::string& env_var,
+	const std::string& override)
+{
+	std::string cmd;
+
+	// Get executable path.
+	if (!override.empty())	// try the supplied override first
+	{
+		cmd = override;
+		llinfos << "Using override" << llendl;
+	}
+	else if (!LLUI::sSettingGroups["config"]->getString(sSetting).empty())
+	{
+		cmd = LLUI::sSettingGroups["config"]->getString(sSetting);
+		llinfos << "Using setting" << llendl;
+	}
+	else					// otherwise use the path specified by the environment variable
+	{
+		char* env_var_val = getenv(env_var.c_str());
+		if (env_var_val)
+		{
+			cmd = env_var_val;
+			llinfos << "Using env var " << env_var << llendl;
+		}
+	}
+
+	llinfos << "Found command [" << cmd << "]" << llendl;
+	return cmd;
+}
diff --git a/indra/newview/llexternaleditor.h b/indra/newview/llexternaleditor.h
new file mode 100644
index 0000000000000000000000000000000000000000..6ea210d5e222d69dfc81ed3d4d9ab23758ad520b
--- /dev/null
+++ b/indra/newview/llexternaleditor.h
@@ -0,0 +1,91 @@
+/** 
+ * @file llexternaleditor.h
+ * @brief A convenient class to run external editor.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLEXTERNALEDITOR_H
+#define LL_LLEXTERNALEDITOR_H
+
+#include <llprocesslauncher.h>
+
+/**
+ * Usage:
+ *  LLExternalEditor ed;
+ *  ed.setCommand("MY_EXTERNAL_EDITOR_VAR");
+ *  ed.run("/path/to/file1");
+ *  ed.run("/other/path/to/file2");
+ */
+class LLExternalEditor
+{
+	typedef std::vector<std::string> string_vec_t;
+
+public:
+
+	/**
+	 * Set editor command.
+	 *
+	 * @param env_var			Environment variable of the same purpose.
+	 * @param override			Optional override.
+	 *
+	 * First tries the override, then a predefined setting (sSetting),
+	 * then the environment variable.
+	 *
+	 * @return Command if found, empty string otherwise.
+	 *
+	 * @see sSetting
+	 */
+	bool setCommand(const std::string& env_var, const std::string& override = LLStringUtil::null);
+
+	/**
+	 * Run the editor with the given file.
+	 *
+	 * @param file_path File to edit.
+	 * @return true on success, false on error.
+	 */
+	bool run(const std::string& file_path);
+
+private:
+
+	static std::string findCommand(
+		const std::string& env_var,
+		const std::string& override);
+
+	static size_t tokenize(string_vec_t& tokens, const std::string& str);
+
+	/**
+	 * Filename placeholder that gets replaced with an actual file name.
+	 */
+	static const std::string sFilenameMarker;
+
+	/**
+	 * Setting that can specify the editor command.
+	 */
+	static const std::string sSetting;
+
+
+	std::string			mArgs;
+	LLProcessLauncher	mProcess;
+};
+
+#endif // LL_LLEXTERNALEDITOR_H
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index a1ba370c2646ac390f29015383fc1cf53ccdafcf..0c0fdd5572cad3821ba4c91f938ac68c01beb005 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -368,14 +368,15 @@ LLFavoritesBarCtrl::Params::Params()
 LLFavoritesBarCtrl::LLFavoritesBarCtrl(const LLFavoritesBarCtrl::Params& p)
 :	LLUICtrl(p),
 	mFont(p.font.isProvided() ? p.font() : LLFontGL::getFontSansSerifSmall()),
-	mPopupMenuHandle(),
-	mInventoryItemsPopupMenuHandle(),
+	mOverflowMenuHandle(),
+	mContextMenuHandle(),
 	mImageDragIndication(p.image_drag_indication),
 	mShowDragMarker(FALSE),
 	mLandingTab(NULL),
 	mLastTab(NULL),
 	mTabsHighlightEnabled(TRUE)
   , mUpdateDropDownItems(true)
+,	mRestoreOverflowMenu(false)
 {
 	// Register callback for menus with current registrar (will be parent panel's registrar)
 	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Favorites.DoToSelected",
@@ -402,8 +403,8 @@ LLFavoritesBarCtrl::~LLFavoritesBarCtrl()
 {
 	gInventory.removeObserver(this);
 
-	LLView::deleteViewByHandle(mPopupMenuHandle);
-	LLView::deleteViewByHandle(mInventoryItemsPopupMenuHandle);
+	LLView::deleteViewByHandle(mOverflowMenuHandle);
+	LLView::deleteViewByHandle(mContextMenuHandle);
 }
 
 BOOL LLFavoritesBarCtrl::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
@@ -520,7 +521,7 @@ void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
 
 	gInventory.saveItemsOrder(mItems);
 
-	LLToggleableMenu* menu = (LLToggleableMenu*) mPopupMenuHandle.get();
+	LLToggleableMenu* menu = (LLToggleableMenu*) mOverflowMenuHandle.get();
 
 	if (menu && menu->getVisible())
 	{
@@ -776,7 +777,7 @@ void LLFavoritesBarCtrl::updateButtons()
 			mChevronButton->setVisible(TRUE);
 		}
 		// Update overflow menu
-		LLToggleableMenu* overflow_menu = static_cast <LLToggleableMenu*> (mPopupMenuHandle.get());
+		LLToggleableMenu* overflow_menu = static_cast <LLToggleableMenu*> (mOverflowMenuHandle.get());
 		if (overflow_menu && overflow_menu->getVisible())
 		{
 			overflow_menu->setVisible(FALSE);
@@ -850,7 +851,7 @@ BOOL LLFavoritesBarCtrl::postBuild()
 		menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
 	}
 	menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
-	mInventoryItemsPopupMenuHandle = menu->getHandle();
+	mContextMenuHandle = menu->getHandle();
 
 	return TRUE;
 }
@@ -881,7 +882,7 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it
 
 void LLFavoritesBarCtrl::showDropDownMenu()
 {
-	if (mPopupMenuHandle.isDead())
+	if (mOverflowMenuHandle.isDead())
 	{
 		LLToggleableMenu::Params menu_p;
 		menu_p.name("favorites menu");
@@ -892,10 +893,10 @@ void LLFavoritesBarCtrl::showDropDownMenu()
 		menu_p.preferred_width = DROP_DOWN_MENU_WIDTH;
 
 		LLToggleableMenu* menu = LLUICtrlFactory::create<LLFavoriteLandmarkToggleableMenu>(menu_p);
-		mPopupMenuHandle = menu->getHandle();
+		mOverflowMenuHandle = menu->getHandle();
 	}
 
-	LLToggleableMenu* menu = (LLToggleableMenu*)mPopupMenuHandle.get();
+	LLToggleableMenu* menu = (LLToggleableMenu*)mOverflowMenuHandle.get();
 
 	if (menu)
 	{
@@ -973,11 +974,19 @@ void LLFavoritesBarCtrl::onButtonRightClick( LLUUID item_id,LLView* fav_button,S
 {
 	mSelectedItemID = item_id;
 	
-	LLMenuGL* menu = (LLMenuGL*)mInventoryItemsPopupMenuHandle.get();
+	LLMenuGL* menu = (LLMenuGL*)mContextMenuHandle.get();
 	if (!menu)
 	{
 		return;
 	}
+
+	// Remember that the context menu was shown simultaneously with the overflow menu,
+	// so that we can restore the overflow menu when user clicks a context menu item
+	// (which hides the overflow menu).
+	{
+		LLView* overflow_menu = mOverflowMenuHandle.get();
+		mRestoreOverflowMenu = overflow_menu && overflow_menu->getVisible();
+	}
 	
 	// Release mouse capture so hover events go to the popup menu
 	// because this is happening during a mouse down.
@@ -1082,8 +1091,8 @@ void LLFavoritesBarCtrl::doToSelected(const LLSD& userdata)
 
 	// Pop-up the overflow menu again (it gets hidden whenever the user clicks a context menu item).
 	// See EXT-4217 and STORM-207.
-	LLToggleableMenu* menu = (LLToggleableMenu*) mPopupMenuHandle.get();
-	if (menu && !menu->getVisible())
+	LLToggleableMenu* menu = (LLToggleableMenu*) mOverflowMenuHandle.get();
+	if (mRestoreOverflowMenu && menu && !menu->getVisible())
 	{
 		showDropDownMenu();
 	}
@@ -1149,11 +1158,11 @@ void LLFavoritesBarCtrl::pastFromClipboard() const
 void LLFavoritesBarCtrl::onButtonMouseDown(LLUUID id, LLUICtrl* ctrl, S32 x, S32 y, MASK mask)
 {
 	// EXT-6997 (Fav bar: Pop-up menu for LM in overflow dropdown is kept after LM was dragged away)
-	// mInventoryItemsPopupMenuHandle.get() - is a pop-up menu (of items) in already opened dropdown menu.
+	// mContextMenuHandle.get() - is a pop-up menu (of items) in already opened dropdown menu.
 	// We have to check and set visibility of pop-up menu in such a way instead of using
 	// LLMenuHolderGL::hideMenus() because it will close both menus(dropdown and pop-up), but
 	// we need to close only pop-up menu while dropdown one should be still opened.
-	LLMenuGL* menu = (LLMenuGL*)mInventoryItemsPopupMenuHandle.get();
+	LLMenuGL* menu = (LLMenuGL*)mContextMenuHandle.get();
 	if(menu && menu->getVisible())
 	{
 		menu->setVisible(FALSE);
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 37645523f6771937827fc8700d6728c7f904edc5..1a28731c4f27838b1565ddbc5b26d400bd4f9ff5 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -91,13 +91,14 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 	
 	void showDropDownMenu();
 
-	LLHandle<LLView> mPopupMenuHandle;
-	LLHandle<LLView> mInventoryItemsPopupMenuHandle;
+	LLHandle<LLView> mOverflowMenuHandle;
+	LLHandle<LLView> mContextMenuHandle;
 
 	LLUUID mFavoriteFolderId;
 	const LLFontGL *mFont;
 	S32 mFirstDropDownItem;
 	bool mUpdateDropDownItems;
+	bool mRestoreOverflowMenu;
 
 	LLUUID mSelectedItemID;
 
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index c14be89641ce7b34c5fa82a5c9ac7d3fc3de8e0d..f0840774bda22029f40f44c1b14211dab871a863 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -33,6 +33,7 @@
 #include "lldir.h"
 #include "llframetimer.h"
 #include "lltrans.h"
+#include "llviewercontrol.h"
 #include "llwindow.h"	// beforeDialog()
 
 #if LL_SDL
@@ -104,6 +105,20 @@ LLFilePicker::~LLFilePicker()
 	// nothing
 }
 
+// utility function to check if access to local file system via file browser 
+// is enabled and if not, tidy up and indicate we're not allowed to do this.
+bool LLFilePicker::check_local_file_access_enabled()
+{
+	// if local file browsing is turned off, return without opening dialog
+	bool local_file_system_browsing_enabled = gSavedSettings.getBOOL("LocalFileSystemBrowsingEnabled");
+	if ( ! local_file_system_browsing_enabled )
+	{
+		mFiles.clear();
+		return false;
+	}
+
+	return true;
+}
 
 const std::string LLFilePicker::getFirstFile()
 {
@@ -203,6 +218,12 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
 	}
 	BOOL success = FALSE;
 
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	// don't provide default file selection
 	mFilesW[0] = '\0';
 
@@ -241,6 +262,12 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
 	}
 	BOOL success = FALSE;
 
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	// don't provide default file selection
 	mFilesW[0] = '\0';
 
@@ -304,6 +331,12 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
 	}
 	BOOL success = FALSE;
 
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	mOFN.lpstrFile = mFilesW;
 	if (!filename.empty())
 	{
@@ -581,6 +614,12 @@ OSStatus	LLFilePicker::doNavChooseDialog(ELoadFilter filter)
 	NavDialogRef	navRef = NULL;
 	NavReplyRecord	navReply;
 
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	memset(&navReply, 0, sizeof(navReply));
 	
 	// NOTE: we are passing the address of a local variable here.  
@@ -809,6 +848,12 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
 
 	BOOL success = FALSE;
 
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	OSStatus	error = noErr;
 	
 	reset();
@@ -845,6 +890,12 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
 
 	BOOL success = FALSE;
 
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	OSStatus	error = noErr;
 
 	reset();
@@ -876,6 +927,12 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
 	BOOL success = FALSE;
 	OSStatus	error = noErr;
 
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	reset();
 	
 	mNavOptions.optionFlags &= ~kNavAllowMultipleFiles;
@@ -1100,6 +1157,12 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
 {
 	BOOL rtn = FALSE;
 
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	gViewerWindow->mWindow->beforeDialog();
 
 	reset();
@@ -1189,6 +1252,12 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
 {
 	BOOL rtn = FALSE;
 
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	gViewerWindow->mWindow->beforeDialog();
 
 	reset();
@@ -1233,6 +1302,12 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
 {
 	BOOL rtn = FALSE;
 
+	// if local file browsing is turned off, return without opening dialog
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	gViewerWindow->mWindow->beforeDialog();
 
 	reset();
@@ -1263,6 +1338,13 @@ BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
 
 BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename )
 {
+	// 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)
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	reset();
 	
 	llinfos << "getSaveFile suggested filename is [" << filename
@@ -1277,6 +1359,13 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
 
 BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
 {
+	// 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)
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	reset();
 	
 	// HACK: Static filenames for 'open' until we implement filepicker
@@ -1295,6 +1384,13 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
 
 BOOL LLFilePicker::getMultipleOpenFiles( ELoadFilter filter )
 {
+	// 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)
+	if ( check_local_file_access_enabled() == false )
+	{
+		return FALSE;
+	}
+
 	reset();
 	return FALSE;
 }
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 5819ac4fd8d2d14458201b92e7262cdb02d125e7..596bfa3e6953859bebdeef9748d8bb6dd30c95d7 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -140,6 +140,10 @@ class LLFilePicker
 		//FILENAME_BUFFER_SIZE = 65536
 		FILENAME_BUFFER_SIZE = 65000
 	};
+
+	// utility function to check if access to local file system via file browser 
+	// is enabled and if not, tidy up and indicate we're not allowed to do this.
+	bool check_local_file_access_enabled();
 	
 #if LL_WINDOWS
 	OPENFILENAMEW mOFN;				// for open and save dialogs
diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp
index b08c1139234788e50af96d45ee9ba8b20904417e..4c171998953b75716c9fcfe1268fcbde2e1123b2 100644
--- a/indra/newview/llfirstuse.cpp
+++ b/indra/newview/llfirstuse.cpp
@@ -100,9 +100,16 @@ void LLFirstUse::useSandbox()
 void LLFirstUse::notUsingDestinationGuide(bool enable)
 {
 	// not doing this yet
-	//firstUseNotification("FirstNotUseDestinationGuide", enable, "HintDestinationGuide", LLSD(), LLSD().with("target", "dest_guide_btn").with("direction", "left"));
+	firstUseNotification("FirstNotUseDestinationGuide", enable, "HintDestinationGuide", LLSD(), LLSD().with("target", "dest_guide_btn").with("direction", "top"));
 }
 
+void LLFirstUse::notUsingAvatarPicker(bool enable)
+{
+	// not doing this yet
+	firstUseNotification("FirstNotUseAvatarPicker", enable, "HintAvatarPicker", LLSD(), LLSD().with("target", "avatar_picker_btn").with("direction", "top"));
+}
+
+
 // static
 void LLFirstUse::notUsingSidePanel(bool enable)
 {
@@ -113,7 +120,15 @@ void LLFirstUse::notUsingSidePanel(bool enable)
 // static
 void LLFirstUse::notMoving(bool enable)
 {
+	// fire off 2 notifications and rely on filtering to select the relevant one
 	firstUseNotification("FirstNotMoving", enable, "HintMove", LLSD(), LLSD().with("target", "move_btn").with("direction", "top"));
+	firstUseNotification("FirstNotMoving", enable, "HintMoveArrows", LLSD(), LLSD().with("target", "bottom_tray").with("direction", "top").with("hint_image", "arrow_keys.png").with("down_arrow", ""));
+}
+
+// static
+void LLFirstUse::viewPopup(bool enable)
+{
+	firstUseNotification("FirstViewPopup", enable, "HintView", LLSD(), LLSD().with("target", "view_popup").with("direction", "right"));
 }
 
 // static
diff --git a/indra/newview/llfirstuse.h b/indra/newview/llfirstuse.h
index 3b7ff6383b4b68b8080ef6b0957394f79796c0f8..81659988e6b95b443b4607a538ebd85e2c0dcdd0 100644
--- a/indra/newview/llfirstuse.h
+++ b/indra/newview/llfirstuse.h
@@ -87,8 +87,10 @@ class LLFirstUse
 	static void otherAvatarChatFirst(bool enable = true);
 	static void sit(bool enable = true);
 	static void notUsingDestinationGuide(bool enable = true);
+	static void notUsingAvatarPicker(bool enable = true);
 	static void notUsingSidePanel(bool enable = true);
 	static void notMoving(bool enable = true);
+	static void viewPopup(bool enable = true);
 	static void newInventory(bool enable = true);
 	static void receiveLindens(bool enable = true);
 	static void setDisplayName(bool enable = true);
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 135137069c5a4735a5b39cf0dc1ca803e475352c..2873bc00599e6fcd5c26e82be55841db738a42e4 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -213,7 +213,7 @@ LLSD LLFloaterAbout::getInfo()
 	info["VIEWER_VERSION_STR"] = LLVersionInfo::getVersion();
 	info["BUILD_DATE"] = __DATE__;
 	info["BUILD_TIME"] = __TIME__;
-	info["CHANNEL"] = gSavedSettings.getString("VersionChannelName");
+	info["CHANNEL"] = LLVersionInfo::getChannel();
 
 	info["VIEWER_RELEASE_NOTES_URL"] = get_viewer_release_notes_url();
 
@@ -272,7 +272,7 @@ LLSD LLFloaterAbout::getInfo()
 	}
 	
 	// TODO: Implement media plugin version query
-	info["QT_WEBKIT_VERSION"] = "4.6 (version number hard-coded)";
+	info["QT_WEBKIT_VERSION"] = "4.7.1 (version number hard-coded)";
 
 	if (gPacketsIn > 0)
 	{
@@ -291,7 +291,7 @@ static std::string get_viewer_release_notes_url()
 	std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
 	if (! LLStringUtil::endsWith(url, "/"))
 		url += "/";
-	url += gSavedSettings.getString("VersionChannelName") + "/";
+	url += LLVersionInfo::getChannel() + "/";
 	url += LLVersionInfo::getShortVersion();
 	return LLWeb::escapeURL(url);
 }
diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index 58c79fdf151b10350cb293c69815168f17832c97..e21a8594bc0e4f37c3087a65dab274c874807f2b 100644
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
@@ -267,17 +267,23 @@ void LLFloaterBuyCurrencyUI::onClickBuy()
 {
 	mManager.buy(getString("buy_currency"));
 	updateUI();
+	// Update L$ balance
+	LLStatusBar::sendMoneyBalanceRequest();
 }
 
 void LLFloaterBuyCurrencyUI::onClickCancel()
 {
 	closeFloater();
+	// Update L$ balance
+	LLStatusBar::sendMoneyBalanceRequest();
 }
 
 void LLFloaterBuyCurrencyUI::onClickErrorWeb()
 {
 	LLWeb::loadURLExternal(mManager.errorURI());
 	closeFloater();
+	// Update L$ balance
+	LLStatusBar::sendMoneyBalanceRequest();
 }
 
 // static
diff --git a/indra/newview/llfloaterbuycurrencyhtml.cpp b/indra/newview/llfloaterbuycurrencyhtml.cpp
index bde620d965bffe6fde637e4994daaac1f44a616a..013cf74c7bab3ee8260090ba21d204943a0134df 100644
--- a/indra/newview/llfloaterbuycurrencyhtml.cpp
+++ b/indra/newview/llfloaterbuycurrencyhtml.cpp
@@ -82,7 +82,7 @@ void LLFloaterBuyCurrencyHTML::navigateToFinalURL()
 	LLStringUtil::format( buy_currency_url, replace );
 
 	// write final URL to debug console
-	llinfos << "Buy currency HTML prased URL is " << buy_currency_url << llendl;
+	llinfos << "Buy currency HTML parsed URL is " << buy_currency_url << llendl;
 
 	// kick off the navigation
 	mBrowser->navigateTo( buy_currency_url, "text/html" );
@@ -105,7 +105,7 @@ void LLFloaterBuyCurrencyHTML::handleMediaEvent( LLPluginClassMedia* self, EMedi
 //
 void LLFloaterBuyCurrencyHTML::onClose( bool app_quitting )
 {
-	// update L$ balanace one more time
+	// Update L$ balance one more time
 	LLStatusBar::sendMoneyBalanceRequest();
 
 	destroy();
diff --git a/indra/newview/llfloatercamera.cpp b/indra/newview/llfloatercamera.cpp
index ad24c6534a4951cb0170a93a6f203c5d477809fb..1dfa904a191de18c5b56780d0e6a13d43c35308b 100644
--- a/indra/newview/llfloatercamera.cpp
+++ b/indra/newview/llfloatercamera.cpp
@@ -40,6 +40,8 @@
 #include "lltoolmgr.h"
 #include "lltoolfocus.h"
 #include "llslider.h"
+#include "llfirstuse.h"
+#include "llhints.h"
 
 static LLDefaultChildRegistry::Register<LLPanelCameraItem> r("panel_camera_item");
 
@@ -73,6 +75,8 @@ class LLPanelCameraZoom
 	void	onZoomPlusHeldDown();
 	void	onZoomMinusHeldDown();
 	void	onSliderValueChanged();
+	void	onCameraTrack();
+	void	onCameraRotate();
 	F32		getOrbitRate(F32 time);
 
 private:
@@ -162,6 +166,8 @@ LLPanelCameraZoom::LLPanelCameraZoom()
 	mCommitCallbackRegistrar.add("Zoom.minus", boost::bind(&LLPanelCameraZoom::onZoomMinusHeldDown, this));
 	mCommitCallbackRegistrar.add("Zoom.plus", boost::bind(&LLPanelCameraZoom::onZoomPlusHeldDown, this));
 	mCommitCallbackRegistrar.add("Slider.value_changed", boost::bind(&LLPanelCameraZoom::onSliderValueChanged, this));
+	mCommitCallbackRegistrar.add("Camera.track", boost::bind(&LLPanelCameraZoom::onCameraTrack, this));
+	mCommitCallbackRegistrar.add("Camera.rotate", boost::bind(&LLPanelCameraZoom::onCameraRotate, this));
 }
 
 BOOL LLPanelCameraZoom::postBuild()
@@ -198,6 +204,18 @@ void LLPanelCameraZoom::onZoomMinusHeldDown()
 	gAgentCamera.setOrbitOutKey(getOrbitRate(time));
 }
 
+void LLPanelCameraZoom::onCameraTrack()
+{
+	// EXP-202 when camera panning activated, remove the hint
+	LLFirstUse::viewPopup( false );
+}
+
+void LLPanelCameraZoom::onCameraRotate()
+{
+	// EXP-202 when camera rotation activated, remove the hint
+	LLFirstUse::viewPopup( false );
+}
+
 F32 LLPanelCameraZoom::getOrbitRate(F32 time)
 {
 	if( time < NUDGE_TIME )
@@ -294,6 +312,8 @@ LLFloaterCamera* LLFloaterCamera::findInstance()
 
 void LLFloaterCamera::onOpen(const LLSD& key)
 {
+	LLFirstUse::viewPopup();
+
 	LLButton *anchor_panel = LLBottomTray::getInstance()->getChild<LLButton>("camera_btn");
 
 	setDockControl(new LLDockControl(
@@ -336,6 +356,7 @@ LLFloaterCamera::LLFloaterCamera(const LLSD& val)
 	mCurrMode(CAMERA_CTRL_MODE_PAN),
 	mPrevMode(CAMERA_CTRL_MODE_PAN)
 {
+	LLHints::registerHintTarget("view_popup", LLView::getHandle());
 }
 
 // virtual
@@ -343,6 +364,7 @@ BOOL LLFloaterCamera::postBuild()
 {
 	setIsChrome(TRUE);
 	setTitleVisible(TRUE); // restore title visibility after chrome applying
+	updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)
 
 	mRotate = getChild<LLJoystickCameraRotate>(ORBIT);
 	mZoom = findChild<LLPanelCameraZoom>(ZOOM);
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index 69f1774ff8bf7321581de9af0d32153d5ba0d67e..659e52271afc44402f361f31c08d7cb644936a4c 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -472,6 +472,12 @@ void LLFloaterColorPicker::onMouseCaptureLost()
 	setMouseDownInLumRegion(FALSE);
 }
 
+F32 LLFloaterColorPicker::getSwatchTransparency()
+{
+	// If the floater is focused, don't apply its alpha to the color swatch (STORM-676).
+	return getTransparencyType() == TT_ACTIVE ? 1.f : LLFloater::getCurrentTransparency();
+}
+
 //////////////////////////////////////////////////////////////////////////////
 //
 void LLFloaterColorPicker::draw()
@@ -533,8 +539,10 @@ void LLFloaterColorPicker::draw()
 	// base floater stuff
 	LLFloater::draw ();
 
+	const F32 alpha = getSwatchTransparency();
+
 	// draw image for RGB area (not really RGB but you'll see what I mean...
-	gl_draw_image ( mRGBViewerImageLeft, mRGBViewerImageTop - mRGBViewerImageHeight, mRGBImage, LLColor4::white );
+	gl_draw_image ( mRGBViewerImageLeft, mRGBViewerImageTop - mRGBViewerImageHeight, mRGBImage, LLColor4::white % alpha);
 
 	// update 'cursor' into RGB Section
 	S32 xPos = ( S32 ) ( ( F32 )mRGBViewerImageWidth * getCurH () ) - 8;
@@ -556,7 +564,7 @@ void LLFloaterColorPicker::draw()
 				 mRGBViewerImageTop - mRGBViewerImageHeight,
 				 mRGBViewerImageLeft + mRGBViewerImageWidth + 1,
 				 mRGBViewerImageTop,
-				 LLColor4 ( 0.0f, 0.0f, 0.0f, 1.0f ),
+				 LLColor4 ( 0.0f, 0.0f, 0.0f, alpha ),
 				 FALSE );
 
 	// draw luminance slider
@@ -569,7 +577,7 @@ void LLFloaterColorPicker::draw()
 			mLumRegionTop - mLumRegionHeight + y, 
 				mLumRegionLeft + mLumRegionWidth, 
 					mLumRegionTop - mLumRegionHeight + y - 1, 
-						LLColor4 ( rValSlider, gValSlider, bValSlider, 1.0f ) );
+						LLColor4 ( rValSlider, gValSlider, bValSlider, alpha ) );
 	}
 
 
@@ -594,7 +602,7 @@ void LLFloaterColorPicker::draw()
 				 mSwatchRegionTop - mSwatchRegionHeight,
 				 mSwatchRegionLeft + mSwatchRegionWidth,
 				 mSwatchRegionTop,
-				 LLColor4 ( getCurR (), getCurG (), getCurB (), 1.0f ),
+				 LLColor4 ( getCurR (), getCurG (), getCurB (), alpha ),
 				 TRUE );
 
 	// draw selected color swatch outline
@@ -634,6 +642,7 @@ const LLColor4& LLFloaterColorPicker::getComplimentaryColor ( const LLColor4& ba
 void LLFloaterColorPicker::drawPalette ()
 {
 	S32 curEntry = 0;
+	const F32 alpha = getSwatchTransparency();
 
 	for ( S32 y = 0; y < numPaletteRows; ++y )
 	{
@@ -648,7 +657,7 @@ void LLFloaterColorPicker::drawPalette ()
 			// draw palette entry color
 			if ( mPalette [ curEntry ] )
 			{
-				gl_rect_2d ( x1 + 2, y1 - 2, x2 - 2, y2 + 2, *mPalette [ curEntry++ ], TRUE );
+				gl_rect_2d ( x1 + 2, y1 - 2, x2 - 2, y2 + 2, *mPalette [ curEntry++ ] % alpha, TRUE );
 				gl_rect_2d ( x1 + 1, y1 - 1, x2 - 1, y2 + 1, LLColor4 ( 0.0f, 0.0f, 0.0f, 1.0f ), FALSE );
 			}
 		}
diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h
index 110fa43b9ce366fdcc9853a56f0b4ccacd80eb4d..8e387c4f7c151295329aa5c0c2cf05d62c311d3f 100644
--- a/indra/newview/llfloatercolorpicker.h
+++ b/indra/newview/llfloatercolorpicker.h
@@ -55,6 +55,7 @@ class LLFloaterColorPicker
 		virtual BOOL handleMouseUp ( S32 x, S32 y, MASK mask );
 		virtual BOOL handleHover ( S32 x, S32 y, MASK mask );
 		virtual void onMouseCaptureLost();
+		virtual F32  getSwatchTransparency();
 
 		// implicit methods
 		void createUI ();
diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp
index 0b5ac8e798732ac70999dee6e7e262161aa6edc0..a6dafda3e698235c06ff09fa0c3819f9f9940294 100644
--- a/indra/newview/llfloaterevent.cpp
+++ b/indra/newview/llfloaterevent.cpp
@@ -117,8 +117,3 @@ void LLFloaterEvent::setEventID(const U32 event_id)
 		
 	}
 }
-
-void LLFloaterEvent::draw()
-{
-	LLPanel::draw();
-}
diff --git a/indra/newview/llfloaterevent.h b/indra/newview/llfloaterevent.h
index b1963309da5d55956ab0ddf4d9f9b40b00872709..ed90055d95587d6ac0d5b3d5a67bb7d99419e2b6 100644
--- a/indra/newview/llfloaterevent.h
+++ b/indra/newview/llfloaterevent.h
@@ -43,7 +43,6 @@ class LLFloaterEvent : public LLFloater,
 	/*virtual*/ ~LLFloaterEvent();
 
 	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void draw();
 
 	void setEventID(const U32 event_id);
 
diff --git a/indra/newview/llfloatergroups.cpp b/indra/newview/llfloatergroups.cpp
index 234a09d157d1656d0e536a210dcaeae64006f796..d84364a68a76e4fac73e28bfad7f4bc5330ae099 100644
--- a/indra/newview/llfloatergroups.cpp
+++ b/indra/newview/llfloatergroups.cpp
@@ -41,6 +41,7 @@
 #include "llbutton.h"
 #include "llgroupactions.h"
 #include "llscrolllistctrl.h"
+#include "llstartup.h"
 #include "lltextbox.h"
 #include "lluictrlfactory.h"
 #include "lltrans.h"
@@ -171,7 +172,7 @@ void LLPanelGroups::reset()
 		group_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
 	}
 	getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count()));
-	getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",MAX_AGENT_GROUPS));
+	getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",gMaxAgentGroups));
 
 	init_group_list(getChild<LLScrollListCtrl>("group list"), gAgent.getGroupID());
 	enableButtons();
@@ -182,7 +183,7 @@ BOOL LLPanelGroups::postBuild()
 	childSetCommitCallback("group list", onGroupList, this);
 
 	getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count()));
-	getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",MAX_AGENT_GROUPS));
+	getChild<LLUICtrl>("groupcount")->setTextArg("[MAX]", llformat("%d",gMaxAgentGroups));
 
 	LLScrollListCtrl *list = getChild<LLScrollListCtrl>("group list");
 	if (list)
diff --git a/indra/newview/llfloaterhelpbrowser.cpp b/indra/newview/llfloaterhelpbrowser.cpp
index cec98e999235d04c9962a693a3cfc44ea8f504e7..a650886d89f60d08b31bdb2487349f0206ee38ad 100644
--- a/indra/newview/llfloaterhelpbrowser.cpp
+++ b/indra/newview/llfloaterhelpbrowser.cpp
@@ -132,9 +132,10 @@ void LLFloaterHelpBrowser::onClickOpenWebBrowser(void* user_data)
 
 void LLFloaterHelpBrowser::openMedia(const std::string& media_url)
 {
-	mBrowser->setHomePageUrl(media_url);
-	//mBrowser->navigateTo("data:text/html;charset=utf-8,I'd really love to be going to:<br><b>" + media_url + "</b>"); // tofu HACK for debugging =:)
-	mBrowser->navigateTo(media_url);
+	// explicitly make the media mime type for this floater since it will
+	// only ever display one type of content (Web).
+	mBrowser->setHomePageUrl(media_url, "text/html");
+	mBrowser->navigateTo(media_url, "text/html");
 	setCurrentURL(media_url);
 }
 
diff --git a/indra/newview/llfloatermediabrowser.cpp b/indra/newview/llfloatermediabrowser.cpp
index d20092e344f2de809092226080ca4b738a1bd09b..7a670dd90cca7b108027d6911e5ced8d2086b502 100644
--- a/indra/newview/llfloatermediabrowser.cpp
+++ b/indra/newview/llfloatermediabrowser.cpp
@@ -306,17 +306,14 @@ void LLFloaterMediaBrowser::setCurrentURL(const std::string& url)
 {
 	mCurrentURL = url;
 
-	// redirects will navigate momentarily to about:blank, don't add to history
-	if (mCurrentURL != "about:blank")
-	{
-		mAddressCombo->remove(mCurrentURL);
-		mAddressCombo->add(mCurrentURL);
-		mAddressCombo->selectByValue(mCurrentURL);
+	mAddressCombo->remove(mCurrentURL);
+	mAddressCombo->add(mCurrentURL);
+	mAddressCombo->selectByValue(mCurrentURL);
+
+	// Serialize url history
+	LLURLHistory::removeURL("browser", mCurrentURL);
+	LLURLHistory::addURL("browser", mCurrentURL);
 
-		// Serialize url history
-		LLURLHistory::removeURL("browser", mCurrentURL);
-		LLURLHistory::addURL("browser", mCurrentURL);
-	}
 	getChildView("back")->setEnabled(mBrowser->canNavigateBack());
 	getChildView("forward")->setEnabled(mBrowser->canNavigateForward());
 	getChildView("reload")->setEnabled(TRUE);
@@ -334,8 +331,15 @@ void LLFloaterMediaBrowser::onClickRefresh(void* user_data)
 {
 	LLFloaterMediaBrowser* self = (LLFloaterMediaBrowser*)user_data;
 
-	self->mAddressCombo->remove(0);
-	self->mBrowser->navigateTo(self->mCurrentURL);
+	if( self->mBrowser->getMediaPlugin() &&  self->mBrowser->getMediaPlugin()->pluginSupportsMediaBrowser())
+	{
+		bool ignore_cache = true;
+		self->mBrowser->getMediaPlugin()->browse_reload( ignore_cache );
+	}
+	else
+	{
+		self->mBrowser->navigateTo(self->mCurrentURL);
+	}
 }
 
 //static 
diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp
index 42dc60f9e0b04694190fb0df022d3594eac63d64..29af81d64c0e40e5266f74f482c5ec82e8e19e91 100644
--- a/indra/newview/llfloaternotificationsconsole.cpp
+++ b/indra/newview/llfloaternotificationsconsole.cpp
@@ -174,6 +174,7 @@ BOOL LLFloaterNotificationConsole::postBuild()
 	// these are in the order of processing
 	addChannel("Unexpired");
 	addChannel("Ignore");
+	addChannel("VisibilityRules");
 	addChannel("Visible", true);
 	// all the ones below attach to the Visible channel
 	addChannel("Persistent");
diff --git a/indra/newview/llfloaterpostcard.cpp b/indra/newview/llfloaterpostcard.cpp
index e8e9f769128a24a38d7c206a70e0d3f3becf9838..dd0b1d999c978ebe379ead3685cc4afdd1941d05 100644
--- a/indra/newview/llfloaterpostcard.cpp
+++ b/indra/newview/llfloaterpostcard.cpp
@@ -112,11 +112,14 @@ LLFloaterPostcard* LLFloaterPostcard::showFromSnapshot(LLImageJPEG *jpeg, LLView
 	// Take the images from the caller
 	// It's now our job to clean them up
 	LLFloaterPostcard* instance = LLFloaterReg::showTypedInstance<LLFloaterPostcard>("postcard", LLSD(img->getID()));
-	
-	instance->mJPEGImage = jpeg;
-	instance->mViewerImage = img;
-	instance->mImageScale = image_scale;
-	instance->mPosTakenGlobal = pos_taken_global;
+
+	if (instance) // may be 0 if we're in mouselook mode
+	{
+		instance->mJPEGImage = jpeg;
+		instance->mViewerImage = img;
+		instance->mImageScale = image_scale;
+		instance->mPosTakenGlobal = pos_taken_global;
+	}
 	
 	return instance;
 }
@@ -128,6 +131,8 @@ void LLFloaterPostcard::draw()
 
 	if(!isMinimized() && mViewerImage.notNull() && mJPEGImage.notNull()) 
 	{
+		// Force the texture to be 100% opaque when the floater is focused.
+		F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
 		LLRect rect(getRect());
 
 		// first set the max extents of our preview
@@ -149,7 +154,7 @@ void LLFloaterPostcard::draw()
 		}
 		{
 			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-			gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f));
+			gl_rect_2d(rect, LLColor4(0.f, 0.f, 0.f, 1.f) % alpha);
 			rect.stretch(-1);
 		}
 		{
@@ -164,7 +169,7 @@ void LLFloaterPostcard::draw()
 								 rect.getWidth(),
 								 rect.getHeight(),
 								 mViewerImage.get(), 
-								 LLColor4::white);
+								 LLColor4::white % alpha);
 		}
 		glMatrixMode(GL_TEXTURE);
 		glPopMatrix();
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 5becd8f990622ceabfcc7d2f48a814b5e8472964..338b6555ff7a2ffece95db72053ba9fa8bb60954 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -282,7 +282,9 @@ std::string LLFloaterPreference::sSkin = "";
 LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	: LLFloater(key),
 	mGotPersonalInfo(false),
-	mOriginalIMViaEmail(false)
+	mOriginalIMViaEmail(false),
+	mLanguageChanged(false),
+	mDoubleClickActionDirty(false)
 {
 	//Build Floater is now Called from 	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
 	
@@ -320,6 +322,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.getUIColor",				boost::bind(&LLFloaterPreference::getUIColor, this ,_1, _2));
 	mCommitCallbackRegistrar.add("Pref.MaturitySettings",		boost::bind(&LLFloaterPreference::onChangeMaturity, this));
 	mCommitCallbackRegistrar.add("Pref.BlockList",				boost::bind(&LLFloaterPreference::onClickBlockList, this));
+	mCommitCallbackRegistrar.add("Pref.CommitDoubleClickChekbox",	boost::bind(&LLFloaterPreference::onDoubleClickCheckBox, this, _1));
+	mCommitCallbackRegistrar.add("Pref.CommitRadioDoubleClick",	boost::bind(&LLFloaterPreference::onDoubleClickRadio, this));
 
 	sSkin = gSavedSettings.getString("SkinCurrent");
 	
@@ -338,14 +342,20 @@ BOOL LLFloaterPreference::postBuild()
 
 	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2));
 
+	gSavedSettings.getControl("ChatBubbleOpacity")->getSignal()->connect(boost::bind(&LLFloaterPreference::onNameTagOpacityChange, this, _2));
+
 	LLTabContainer* tabcontainer = getChild<LLTabContainer>("pref core");
 	if (!tabcontainer->selectTab(gSavedSettings.getS32("LastPrefTab")))
 		tabcontainer->selectFirstTab();
 
+	updateDoubleClickControls();
+
 	getChild<LLUICtrl>("cache_location")->setEnabled(FALSE); // make it read-only but selectable (STORM-227)
 	std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
 	setCacheLocation(cache_location);
 
+	getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
+
 	// if floater is opened before login set default localized busy message
 	if (LLStartUp::getStartupState() < STATE_STARTED)
 	{
@@ -475,6 +485,12 @@ void LLFloaterPreference::apply()
 			gAgent.sendAgentUpdateUserInfo(new_im_via_email,mDirectoryVisibility);
 		}
 	}
+
+	if (mDoubleClickActionDirty)
+	{
+		updateDoubleClickSettings();
+		mDoubleClickActionDirty = false;
+	}
 }
 
 void LLFloaterPreference::cancel()
@@ -501,6 +517,12 @@ void LLFloaterPreference::cancel()
 	
 	// reverts any changes to current skin
 	gSavedSettings.setString("SkinCurrent", sSkin);
+
+	if (mDoubleClickActionDirty)
+	{
+		updateDoubleClickControls();
+		mDoubleClickActionDirty = false;
+	}
 }
 
 void LLFloaterPreference::onOpen(const LLSD& key)
@@ -553,6 +575,9 @@ void LLFloaterPreference::onOpen(const LLSD& key)
 		getChildView("maturity_desired_combobox")->setVisible( false);
 	}
 
+	// Forget previous language changes.
+	mLanguageChanged = false;
+
 	// Display selected maturity icons.
 	onChangeMaturity();
 	
@@ -710,6 +735,28 @@ void LLFloaterPreference::onClickBrowserClearCache()
 	LLNotificationsUtil::add("ConfirmClearBrowserCache", LLSD(), LLSD(), callback_clear_browser_cache);
 }
 
+// Called when user changes language via the combobox.
+void LLFloaterPreference::onLanguageChange()
+{
+	// Let the user know that the change will only take effect after restart.
+	// Do it only once so that we're not too irritating.
+	if (!mLanguageChanged)
+	{
+		LLNotificationsUtil::add("ChangeLanguage");
+		mLanguageChanged = true;
+	}
+}
+
+void LLFloaterPreference::onNameTagOpacityChange(const LLSD& newvalue)
+{
+	LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("background");
+	if (color_swatch)
+	{
+		LLColor4 new_color = color_swatch->get();
+		color_swatch->set( new_color.setAlpha(newvalue.asReal()) );
+	}
+}
+
 void LLFloaterPreference::onClickSetCache()
 {
 	std::string cur_name(gSavedSettings.getString("CacheLocation"));
@@ -1246,7 +1293,7 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
 	getChildView("show_timestamps_check_im")->setEnabled(TRUE);
 	getChildView("log_path_string")->setEnabled(FALSE);// LineEditor becomes readonly in this case.
 	getChildView("log_path_button")->setEnabled(TRUE);
-	
+	childEnable("logfile_name_datestamp");	
 	std::string display_email(email);
 	getChild<LLUICtrl>("email_address")->setValue(display_email);
 
@@ -1318,6 +1365,68 @@ void LLFloaterPreference::onClickBlockList()
 	}
 }
 
+void LLFloaterPreference::onDoubleClickCheckBox(LLUICtrl* ctrl)
+{
+	if (!ctrl) return;
+	mDoubleClickActionDirty = true;
+	LLRadioGroup* radio_double_click_action = getChild<LLRadioGroup>("double_click_action");
+	if (!radio_double_click_action) return;
+	// select default value("teleport") in radio-group.
+	radio_double_click_action->setSelectedIndex(0);
+	// set radio-group enabled depending on state of checkbox
+	radio_double_click_action->setEnabled(ctrl->getValue());
+}
+
+void LLFloaterPreference::onDoubleClickRadio()
+{
+	mDoubleClickActionDirty = true;
+}
+
+void LLFloaterPreference::updateDoubleClickSettings()
+{
+	LLCheckBoxCtrl* double_click_action_cb = getChild<LLCheckBoxCtrl>("double_click_chkbox");
+	if (!double_click_action_cb) return;
+	bool enable = double_click_action_cb->getValue().asBoolean();
+
+	LLRadioGroup* radio_double_click_action = getChild<LLRadioGroup>("double_click_action");
+	if (!radio_double_click_action) return;
+	
+	// enable double click radio-group depending on state of checkbox
+	radio_double_click_action->setEnabled(enable);
+	
+	if (!enable)
+	{
+		// set double click action settings values to false if checkbox was unchecked
+		gSavedSettings.setBOOL("DoubleClickAutoPilot", false);
+		gSavedSettings.setBOOL("DoubleClickTeleport", false);
+	}
+	else
+	{
+		std::string selected = radio_double_click_action->getValue().asString();
+		bool teleport_selected = selected == "radio_teleport";
+		// set double click action settings values depending on chosen radio-button
+		gSavedSettings.setBOOL( "DoubleClickTeleport", teleport_selected );
+		gSavedSettings.setBOOL( "DoubleClickAutoPilot", !teleport_selected );
+	}
+}
+
+void LLFloaterPreference::updateDoubleClickControls()
+{
+	// check is one of double-click actions settings enabled
+	bool double_click_action_enabled = gSavedSettings.getBOOL("DoubleClickAutoPilot") || gSavedSettings.getBOOL("DoubleClickTeleport");
+	LLCheckBoxCtrl* double_click_action_cb = getChild<LLCheckBoxCtrl>("double_click_chkbox");
+	if (double_click_action_cb)
+	{
+		// check checkbox if one of double-click actions settings enabled, uncheck otherwise
+		double_click_action_cb->setValue(double_click_action_enabled);
+	}
+	LLRadioGroup* double_click_action_radio = getChild<LLRadioGroup>("double_click_action");
+	if (!double_click_action_radio) return;
+	// set radio-group enabled if one of double-click actions settings enabled
+	double_click_action_radio->setEnabled(double_click_action_enabled);
+	// select button in radio-group depending on setting
+	double_click_action_radio->setSelectedIndex(gSavedSettings.getBOOL("DoubleClickAutoPilot"));
+}
 
 void LLFloaterPreference::applyUIColor(LLUICtrl* ctrl, const LLSD& param)
 {
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index e99731b92e41c0d3b0808283ac2e99ca7cd25f88..0f5118985347b100f17ad15c3ccb76c7c1fb7560 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -83,6 +83,8 @@ class LLFloaterPreference : public LLFloater
 	void		onBtnApply();
 
 	void		onClickBrowserClearCache();
+	void		onLanguageChange();
+	void		onNameTagOpacityChange(const LLSD& newvalue);
 
 	// set value of "BusyResponseChanged" in account settings depending on whether busy response
 	// string differs from default after user changes.
@@ -95,6 +97,14 @@ class LLFloaterPreference : public LLFloater
 	void setHardwareDefaults();
 	// callback for when client turns on shaders
 	void onVertexShaderEnable();
+	// callback for changing double click action checkbox
+	void onDoubleClickCheckBox(LLUICtrl* ctrl);
+	// callback for selecting double click action radio-button
+	void onDoubleClickRadio();
+	// updates double-click action settings depending on controls from preferences
+	void updateDoubleClickSettings();
+	// updates double-click action controls depending on values from settings.xml
+	void updateDoubleClickControls();
 	
 	// This function squirrels away the current values of the controls so that
 	// cancel() can restore them.	
@@ -145,8 +155,12 @@ class LLFloaterPreference : public LLFloater
 	static void refreshSkin(void* data);
 private:
 	static std::string sSkin;
+	// set true if state of double-click action checkbox or radio-group was changed by user
+	// (reset back to false on apply or cancel)
+	bool mDoubleClickActionDirty;
 	bool mGotPersonalInfo;
 	bool mOriginalIMViaEmail;
+	bool mLanguageChanged;
 	
 	bool mOriginalHideOnlineStatus;
 	std::string mDirectoryVisibility;
diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b3b7645dd4f2f07f6576c809fc0ef10cd413eb59
--- /dev/null
+++ b/indra/newview/llfloaterregiondebugconsole.cpp
@@ -0,0 +1,227 @@
+/** 
+ * @file llfloaterregiondebugconsole.h
+ * @author Brad Kittenbrink <brad@lindenlab.com>
+ * @brief Quick and dirty console for region debug settings
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010-2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterregiondebugconsole.h"
+
+#include "llagent.h"
+#include "llhttpclient.h"
+#include "llhttpnode.h"
+#include "lllineeditor.h"
+#include "lltexteditor.h"
+#include "llviewerregion.h"
+
+// Two versions of the sim console API are supported.
+//
+// SimConsole capability (deprecated):
+// This is the initial implementation that is supported by some versions of the
+// simulator. It is simple and straight forward, just POST a command and the
+// body of the response has the result. This API is deprecated because it
+// doesn't allow the sim to use any asynchronous API.
+//
+// SimConsoleAsync capability:
+// This capability replaces the original SimConsole capability. It is similar
+// in that the command is POSTed to the SimConsoleAsync cap, but the response
+// comes in through the event poll, which gives the simulator more flexibility
+// and allows it to perform complex operations without blocking any frames.
+//
+// We will assume the SimConsoleAsync capability is available, and fall back to
+// the SimConsole cap if it is not. The simulator will only support one or the
+// other.
+
+namespace
+{
+	// Signal used to notify the floater of responses from the asynchronous
+	// API.
+	typedef boost::signals2::signal<
+		void (const std::string& output)> console_reply_signal_t;
+	console_reply_signal_t sConsoleReplySignal;
+
+	const std::string PROMPT("\n\n> ");
+	const std::string UNABLE_TO_SEND_COMMAND(
+		"ERROR: The last command was not received by the server.");
+	const std::string CONSOLE_UNAVAILABLE(
+		"ERROR: No console available for this region/simulator.");
+	const std::string CONSOLE_NOT_SUPPORTED(
+		"This region does not support the simulator console.");
+
+	// This responder handles the initial response. Unless error() is called
+	// we assume that the simulator has received our request. Error will be
+	// called if this request times out.
+	class AsyncConsoleResponder : public LLHTTPClient::Responder
+	{
+	public:
+		/* virtual */
+		void error(U32 status, const std::string& reason)
+		{
+			sConsoleReplySignal(UNABLE_TO_SEND_COMMAND);
+		}
+	};
+
+	class ConsoleResponder : public LLHTTPClient::Responder
+	{
+	public:
+		ConsoleResponder(LLTextEditor *output) : mOutput(output)
+		{
+		}
+
+		/*virtual*/
+		void error(U32 status, const std::string& reason)
+		{
+			if (mOutput)
+			{
+				mOutput->appendText(
+					UNABLE_TO_SEND_COMMAND + PROMPT,
+					false);
+			}
+		}
+
+		/*virtual*/
+		void result(const LLSD& content)
+		{
+			if (mOutput)
+			{
+				mOutput->appendText(
+					content.asString() + PROMPT, false);
+			}
+		}
+
+		LLTextEditor * mOutput;
+	};
+
+	// This handles responses for console commands sent via the asynchronous
+	// API.
+	class ConsoleResponseNode : public LLHTTPNode
+	{
+	public:
+		/* virtual */
+		void post(
+			LLHTTPNode::ResponsePtr reponse,
+			const LLSD& context,
+			const LLSD& input) const
+		{
+			llinfos << "Received response from the debug console: "
+				<< input << llendl;
+			sConsoleReplySignal(input["body"].asString());
+		}
+	};
+}
+
+LLFloaterRegionDebugConsole::LLFloaterRegionDebugConsole(LLSD const & key)
+: LLFloater(key), mOutput(NULL)
+{
+	mReplySignalConnection = sConsoleReplySignal.connect(
+		boost::bind(
+			&LLFloaterRegionDebugConsole::onReplyReceived,
+			this,
+			_1));
+}
+
+LLFloaterRegionDebugConsole::~LLFloaterRegionDebugConsole()
+{
+	mReplySignalConnection.disconnect();
+}
+
+BOOL LLFloaterRegionDebugConsole::postBuild()
+{
+	LLLineEditor* input = getChild<LLLineEditor>("region_debug_console_input");
+	input->setEnableLineHistory(true);
+	input->setCommitCallback(boost::bind(&LLFloaterRegionDebugConsole::onInput, this, _1, _2));
+	input->setFocus(true);
+	input->setCommitOnFocusLost(false);
+
+	mOutput = getChild<LLTextEditor>("region_debug_console_output");
+
+	std::string url = gAgent.getRegion()->getCapability("SimConsoleAsync");
+	if (url.empty())
+	{
+		// Fall back to see if the old API is supported.
+		url = gAgent.getRegion()->getCapability("SimConsole");
+		if (url.empty())
+		{
+			mOutput->appendText(
+				CONSOLE_NOT_SUPPORTED + PROMPT,
+				false);
+			return TRUE;
+		}
+	}
+
+	mOutput->appendText("> ", false);
+	return TRUE;
+}
+
+void LLFloaterRegionDebugConsole::onInput(LLUICtrl* ctrl, const LLSD& param)
+{
+	LLLineEditor* input = static_cast<LLLineEditor*>(ctrl);
+	std::string text = input->getText() + "\n";
+
+	std::string url = gAgent.getRegion()->getCapability("SimConsoleAsync");
+	if (url.empty())
+	{
+		// Fall back to the old API
+		url = gAgent.getRegion()->getCapability("SimConsole");
+		if (url.empty())
+		{
+			text += CONSOLE_UNAVAILABLE + PROMPT;
+		}
+		else
+		{
+			// Using SimConsole (deprecated)
+			LLHTTPClient::post(
+				url,
+				LLSD(input->getText()),
+				new ConsoleResponder(mOutput));
+		}
+	}
+	else
+	{
+		// Using SimConsoleAsync
+		LLHTTPClient::post(
+			url,
+			LLSD(input->getText()),
+			new AsyncConsoleResponder);
+	}
+
+	mOutput->appendText(text, false);
+	input->clear();
+}
+
+void LLFloaterRegionDebugConsole::onReplyReceived(const std::string& output)
+{
+	mOutput->appendText(output + PROMPT, false);
+}
+
+LLHTTPRegistration<ConsoleResponseNode>
+	gHTTPRegistrationMessageDebugConsoleResponse(
+		"/message/SimConsoleResponse");
diff --git a/indra/newview/llfloaterregiondebugconsole.h b/indra/newview/llfloaterregiondebugconsole.h
new file mode 100644
index 0000000000000000000000000000000000000000..4171a4da6baf293c0475c410b7bd65f6288f2d13
--- /dev/null
+++ b/indra/newview/llfloaterregiondebugconsole.h
@@ -0,0 +1,63 @@
+/** 
+ * @file llfloaterregiondebugconsole.h
+ * @author Brad Kittenbrink <brad@lindenlab.com>
+ * @brief Quick and dirty console for region debug settings
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010-2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERREGIONDEBUGCONSOLE_H
+#define LL_LLFLOATERREGIONDEBUGCONSOLE_H
+
+#include <boost/signals2.hpp>
+
+#include "llfloater.h"
+#include "llhttpclient.h"
+
+class LLTextEditor;
+
+class LLFloaterRegionDebugConsole : public LLFloater, public LLHTTPClient::Responder
+{
+public:
+	LLFloaterRegionDebugConsole(LLSD const & key);
+	virtual ~LLFloaterRegionDebugConsole();
+
+	// virtual
+	BOOL postBuild();
+	
+	void onInput(LLUICtrl* ctrl, const LLSD& param);
+
+	LLTextEditor * mOutput;
+
+ private:
+	void onReplyReceived(const std::string& output);
+
+	boost::signals2::connection mReplySignalConnection;
+};
+
+#endif // LL_LLFLOATERREGIONDEBUGCONSOLE_H
diff --git a/indra/newview/llfloatersearch.cpp b/indra/newview/llfloatersearch.cpp
index 3ed4aec89ab10cfc5e1d9f1bdf6f1c279e6c31cd..2041fac8d8d165cbfd878e5201c2443cceeb50ab 100644
--- a/indra/newview/llfloatersearch.cpp
+++ b/indra/newview/llfloatersearch.cpp
@@ -200,5 +200,5 @@ void LLFloaterSearch::search(const LLSD &key)
 	url = LLWeb::expandURLSubstitutions(url, subs);
 
 	// and load the URL in the web view
-	mBrowser->navigateTo(url);
+	mBrowser->navigateTo(url, "text/html");
 }
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 51ee38bd653fa8fce994dc1d8c0105db04cd8ad2..0931f77281b6dd7a5e3250533a2aa850b3502af7 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -2189,9 +2189,11 @@ void LLFloaterSnapshot::draw()
 			S32 offset_y = thumbnail_rect.mBottom + (thumbnail_rect.getHeight() - previewp->getThumbnailHeight()) / 2 ;
 
 			glMatrixMode(GL_MODELVIEW);
+			// Apply floater transparency to the texture unless the floater is focused.
+			F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
 			gl_draw_scaled_image(offset_x, offset_y, 
 					previewp->getThumbnailWidth(), previewp->getThumbnailHeight(), 
-					previewp->getThumbnailImage(), LLColor4::white);	
+					previewp->getThumbnailImage(), LLColor4::white % alpha);
 
 			previewp->drawPreviewRect(offset_x, offset_y) ;
 		}
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 5dc8067648e6706e958dfded454d12a35fb49d85..11b3379814a52d3de44e343675abd7196417e5e9 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -36,6 +36,7 @@
 
 // Internal utility
 #include "lleventtimer.h"
+#include "llexternaleditor.h"
 #include "llrender.h"
 #include "llsdutil.h"
 #include "llxmltree.h"
@@ -160,6 +161,8 @@ class LLFloaterUIPreview : public LLFloater
 	DiffMap mDiffsMap;							// map, of filename to pair of list of changed element paths and list of errors
 
 private:
+	LLExternalEditor mExternalEditor;
+
 	// XUI elements for this floater
 	LLScrollListCtrl*			mFileList;							// scroll list control for file list
 	LLLineEditor*				mEditorPathTextBox;					// text field for path to editor executable
@@ -185,7 +188,7 @@ class LLFloaterUIPreview : public LLFloater
 	std::string					mSavedDiffPath;						// stored diff file path so closing this floater doesn't reset it
 
 	// Internal functionality
-	static void popupAndPrintWarning(std::string& warning);			// pop up a warning
+	static void popupAndPrintWarning(const std::string& warning);	// pop up a warning
 	std::string getLocalizedDirectory();							// build and return the path to the XUI directory for the currently-selected localization
 	void scanDiffFile(LLXmlTreeNode* file_node);					// scan a given XML node for diff entries and highlight them in its associated file
 	void highlightChangedElements();								// look up the list of elements to highlight and highlight them in the current floater
@@ -480,7 +483,7 @@ BOOL LLFloaterUIPreview::postBuild()
 	mLanguageSelection->removeall();																				// clear out anything temporarily in list from XML
 	while(found)																									// for every directory
 	{
-		if((found = gDirUtilp->getNextFileInDir(xui_dir, "*", language_directory, FALSE)))							// get next directory
+		if((found = gDirUtilp->getNextFileInDir(xui_dir, "*", language_directory)))							// get next directory
 		{
 			std::string full_path = xui_dir + language_directory;
 			if(LLFile::isfile(full_path.c_str()))																	// if it's not a directory, skip it
@@ -597,7 +600,7 @@ void LLFloaterUIPreview::onClose(bool app_quitting)
 
 // Error handling (to avoid code repetition)
 // *TODO: this is currently unlocalized.  Add to alerts/notifications.xml, someday, maybe.
-void LLFloaterUIPreview::popupAndPrintWarning(std::string& warning)
+void LLFloaterUIPreview::popupAndPrintWarning(const std::string& warning)
 {
 	llwarns << warning << llendl;
 	LLSD args;
@@ -634,7 +637,7 @@ void LLFloaterUIPreview::refreshList()
 	BOOL found = TRUE;
 	while(found)				// for every floater file that matches the pattern
 	{
-		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "floater_*.xml", name, FALSE)))	// get next file matching pattern
+		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "floater_*.xml", name)))	// get next file matching pattern
 		{
 			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)
 		}
@@ -642,7 +645,7 @@ void LLFloaterUIPreview::refreshList()
 	found = TRUE;
 	while(found)				// for every inspector file that matches the pattern
 	{
-		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "inspect_*.xml", name, FALSE)))	// get next file matching pattern
+		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "inspect_*.xml", name)))	// get next file matching pattern
 		{
 			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)
 		}
@@ -650,7 +653,7 @@ void LLFloaterUIPreview::refreshList()
 	found = TRUE;
 	while(found)				// for every menu file that matches the pattern
 	{
-		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "menu_*.xml", name, FALSE)))	// get next file matching pattern
+		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "menu_*.xml", name)))	// get next file matching pattern
 		{
 			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)
 		}
@@ -658,7 +661,7 @@ void LLFloaterUIPreview::refreshList()
 	found = TRUE;
 	while(found)				// for every panel file that matches the pattern
 	{
-		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "panel_*.xml", name, FALSE)))	// get next file matching pattern
+		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "panel_*.xml", name)))	// get next file matching pattern
 		{
 			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)
 		}
@@ -667,7 +670,7 @@ void LLFloaterUIPreview::refreshList()
 	found = TRUE;
 	while(found)				// for every sidepanel file that matches the pattern
 	{
-		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "sidepanel_*.xml", name, FALSE)))	// get next file matching pattern
+		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "sidepanel_*.xml", name)))	// get next file matching pattern
 		{
 			addFloaterEntry(name.c_str());	// and add it to the list (file name only; localization code takes care of rest of path)
 		}
@@ -998,190 +1001,55 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID, bool save)
 // Respond to button click to edit currently-selected floater
 void LLFloaterUIPreview::onClickEditFloater()
 {
-	std::string file_name = mFileList->getSelectedItemLabel(1);	// get the file name of the currently-selected floater
-	if(std::string("") == file_name)										// if no item is selected
-	{
-		return;															// ignore click
-	}
-	std::string path = getLocalizedDirectory() + file_name;
-
-	// stat file to see if it exists (some localized versions may not have it there are no diffs, and then we try to open an nonexistent file)
-	llstat dummy;
-	if(LLFile::stat(path.c_str(), &dummy))								// if the file does not exist
-	{
-		std::string warning = "No file for this floater exists in the selected localization.  Opening the EN version instead.";
-		popupAndPrintWarning(warning);
-
-		path = get_xui_dir() + mDelim + "en" + mDelim + file_name; // open the en version instead, by default
-	}
-
-	// get executable path
-	const char* exe_path_char;
-	std::string path_in_textfield = mEditorPathTextBox->getText();
-	if(std::string("") != path_in_textfield)	// if the text field is not emtpy, use its path
-	{
-		exe_path_char = path_in_textfield.c_str();
-	}
-	else if (!LLUI::sSettingGroups["config"]->getString("XUIEditor").empty())
-	{
-		exe_path_char = LLUI::sSettingGroups["config"]->getString("XUIEditor").c_str();
-	}
-	else									// otherwise use the path specified by the environment variable
+	// Determine file to edit.
+	std::string file_path;
 	{
-		exe_path_char = getenv("LL_XUI_EDITOR");
-	}
-
-	// error check executable path
-	if(NULL == exe_path_char)
-	{
-		std::string warning = "Select an editor by setting the environment variable LL_XUI_EDITOR or specifying its path in the \"Editor Path\" field.";
-		popupAndPrintWarning(warning);
-		return;
-	}
-	std::string exe_path = exe_path_char;	// do this after error check, otherwise internal strlen call fails on bad char*
-
-	// remove any quotes; they're added back in later where necessary
-	int found_at;
-	while((found_at = exe_path.find("\"")) != -1 || (found_at = exe_path.find("'")) != -1)
-	{
-		exe_path.erase(found_at,1);
-	}
-
-	llstat s;
-	if(!LLFile::stat(exe_path.c_str(), &s)) // If the executable exists
-	{
-		// build paths and arguments
-		std::string quote = std::string("\"");
-		std::string args;
-		std::string custom_args = mEditorArgsTextBox->getText();
-		int position_of_file = custom_args.find(std::string("%FILE%"), 0);	// prepare to replace %FILE% with actual file path
-		std::string first_part_of_args = "";
-		std::string second_part_of_args = "";
-		if(-1 == position_of_file)	// default: Executable.exe File.xml
-		{
-			args = quote + path + quote;			// execute the command Program.exe "File.xml"
-		}
-		else						// use advanced command-line arguments, e.g. "Program.exe -safe File.xml" -windowed for "-safe %FILE% -windowed"
+		std::string file_name = mFileList->getSelectedItemLabel(1);	// get the file name of the currently-selected floater
+		if (file_name.empty())					// if no item is selected
 		{
-			first_part_of_args = custom_args.substr(0,position_of_file);											// get part of args before file name
-			second_part_of_args = custom_args.substr(position_of_file+6,custom_args.length());						// get part of args after file name
-			custom_args = first_part_of_args + std::string("\"") + path + std::string("\"") + second_part_of_args;	// replace %FILE% with "<file path>" and put back together
-			args = custom_args;																						// and save in the variable that is actually used
+			llwarns << "No file selected" << llendl;
+			return;															// ignore click
 		}
+		file_path = getLocalizedDirectory() + file_name;
 
-		// find directory in which executable resides by taking everything after last slash
-		int last_slash_position = exe_path.find_last_of(mDelim);
-		if(-1 == last_slash_position)
-		{
-			std::string warning = std::string("Unable to find a valid path to the specified executable for XUI XML editing: ") + exe_path;
-			popupAndPrintWarning(warning);
-			return;
-		}
-        std::string exe_dir = exe_path.substr(0,last_slash_position); // strip executable off, e.g. get "C:\Program Files\TextPad 5" (with or without trailing slash)
-
-#if LL_WINDOWS
-		PROCESS_INFORMATION pinfo;
-		STARTUPINFOA sinfo;
-		memset(&sinfo, 0, sizeof(sinfo));
-		memset(&pinfo, 0, sizeof(pinfo));
-
-		std::string exe_name = exe_path.substr(last_slash_position+1);
-		args = quote + exe_name + quote + std::string(" ") + args;				// and prepend the executable name, so we get 'Program.exe "Arg1"'
-
-		char *args2 = new char[args.size() + 1];	// Windows requires that the second parameter to CreateProcessA be a writable (non-const) string...
-		strcpy(args2, args.c_str());
-
-		// we don't want the current directory to be the executable directory, since the file path is now relative. By using
-		// NULL for the current directory instead of exe_dir.c_str(), the path to the target file will work. 
-		if(!CreateProcessA(exe_path.c_str(), args2, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo))
-		{
-			// DWORD dwErr = GetLastError();
-			std::string warning = "Creating editor process failed!";
-			popupAndPrintWarning(warning);
-		}
-		else
+		// stat file to see if it exists (some localized versions may not have it there are no diffs, and then we try to open an nonexistent file)
+		llstat dummy;
+		if(LLFile::stat(file_path.c_str(), &dummy))								// if the file does not exist
 		{
-			// foo = pinfo.dwProcessId; // get your pid here if you want to use it later on
-			// sGatewayHandle = pinfo.hProcess;
-			CloseHandle(pinfo.hThread); // stops leaks - nothing else
+			popupAndPrintWarning("No file for this floater exists in the selected localization.  Opening the EN version instead.");
+			file_path = get_xui_dir() + mDelim + "en" + mDelim + file_name; // open the en version instead, by default
 		}
+	}
 
-		delete[] args2;
-#else	// if !LL_WINDOWS
-		// This code was copied from the code to run SLVoice, with some modification; should work in UNIX (Mac/Darwin or Linux)
+	// Set the editor command.
+	std::string cmd_override;
+	{
+		std::string bin = mEditorPathTextBox->getText();
+		if (!bin.empty())
 		{
-			std::vector<std::string> arglist;
-			arglist.push_back(exe_path.c_str());
-
-			// Split the argument string into separate strings for each argument
-			typedef boost::tokenizer< boost::char_separator<char> > tokenizer;
-			boost::char_separator<char> sep("","\" ", boost::drop_empty_tokens);
-
-			tokenizer tokens(args, sep);
-			tokenizer::iterator token_iter;
-			BOOL inside_quotes = FALSE;
-			BOOL last_was_space = FALSE;
-			for(token_iter = tokens.begin(); token_iter != tokens.end(); ++token_iter)
-			{
-				if(!strncmp("\"",(*token_iter).c_str(),2))
-				{
-					inside_quotes = !inside_quotes;
-				}
-				else if(!strncmp(" ",(*token_iter).c_str(),2))
-				{
-					if(inside_quotes)
-					{
-						arglist.back().append(std::string(" "));
-						last_was_space = TRUE;
-					}
-				}
-				else
-				{
-					std::string to_push = *token_iter;
-					if(last_was_space)
-					{
-						arglist.back().append(to_push);
-						last_was_space = FALSE;
-					}
-					else
-					{
-						arglist.push_back(to_push);
-					}
-				}
-			}
-			
-			// create an argv vector for the child process
-			char **fakeargv = new char*[arglist.size() + 1];
-			int i;
-			for(i=0; i < arglist.size(); i++)
-				fakeargv[i] = const_cast<char*>(arglist[i].c_str());
-
-			fakeargv[i] = NULL;
-
-			fflush(NULL); // flush all buffers before the child inherits them
-			pid_t id = vfork();
-			if(id == 0)
+			// surround command with double quotes for the case if the path contains spaces
+			if (bin.find("\"") == std::string::npos)
 			{
-				// child
-				execv(exe_path.c_str(), fakeargv);
-
-				// If we reach this point, the exec failed.
-				// Use _exit() instead of exit() per the vfork man page.
-				std::string warning = "Creating editor process failed (vfork/execv)!";
-				popupAndPrintWarning(warning);
-				_exit(0);
+				bin = "\"" + bin + "\"";
 			}
 
-			// parent
-			delete[] fakeargv;
-			// sGatewayPID = id;
+			std::string args = mEditorArgsTextBox->getText();
+			cmd_override = bin + " " + args;
 		}
-#endif	// LL_WINDOWS
 	}
-	else
+	if (!mExternalEditor.setCommand("LL_XUI_EDITOR", cmd_override))
 	{
-		std::string warning = "Unable to find path to external XML editor for XUI preview tool";
+		std::string warning = "Select an editor by setting the environment variable LL_XUI_EDITOR "
+			"or the ExternalEditor setting or specifying its path in the \"Editor Path\" field.";
 		popupAndPrintWarning(warning);
+		return;
+	}
+
+	// Run the editor.
+	if (!mExternalEditor.run(file_path))
+	{
+		popupAndPrintWarning("Failed to run editor");
+		return;
 	}
 }
 
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..51726112a0fccb2c2081a701a8ddf16e9d2016bd
--- /dev/null
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -0,0 +1,402 @@
+/**
+ * @file llfloaterwebcontent.cpp
+ * @brief floater for displaying web content - e.g. profiles and search (eventually)
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llcombobox.h"
+#include "lliconctrl.h"
+#include "llfloaterreg.h"
+#include "lllayoutstack.h"
+#include "llpluginclassmedia.h"
+#include "llprogressbar.h"
+#include "lltextbox.h"
+#include "llurlhistory.h"
+#include "llviewercontrol.h"
+#include "llweb.h"
+#include "llwindow.h"
+
+#include "llfloaterwebcontent.h"
+
+LLFloaterWebContent::LLFloaterWebContent( const LLSD& key )
+	: LLFloater( key )
+{
+	mCommitCallbackRegistrar.add( "WebContent.Back", boost::bind( &LLFloaterWebContent::onClickBack, this ));
+	mCommitCallbackRegistrar.add( "WebContent.Forward", boost::bind( &LLFloaterWebContent::onClickForward, this ));
+	mCommitCallbackRegistrar.add( "WebContent.Reload", boost::bind( &LLFloaterWebContent::onClickReload, this ));
+	mCommitCallbackRegistrar.add( "WebContent.Stop", boost::bind( &LLFloaterWebContent::onClickStop, this ));
+	mCommitCallbackRegistrar.add( "WebContent.EnterAddress", boost::bind( &LLFloaterWebContent::onEnterAddress, this ));
+	mCommitCallbackRegistrar.add( "WebContent.PopExternal", boost::bind( &LLFloaterWebContent::onPopExternal, this ));
+}
+
+BOOL LLFloaterWebContent::postBuild()
+{
+	// these are used in a bunch of places so cache them
+	mWebBrowser = getChild< LLMediaCtrl >( "webbrowser" );
+	mAddressCombo = getChild< LLComboBox >( "address" );
+	mStatusBarText = getChild< LLTextBox >( "statusbartext" );
+	mStatusBarProgress = getChild<LLProgressBar>("statusbarprogress" );
+
+	// observe browser events
+	mWebBrowser->addObserver( this );
+
+	// these buttons are always enabled
+	getChildView("reload")->setEnabled( true );
+	getChildView("popexternal")->setEnabled( true );
+
+	// cache image for secure browsing
+	mSecureLockIcon = getChild< LLIconCtrl >("media_secure_lock_flag");
+
+	// initialize the URL history using the system URL History manager
+	initializeURLHistory();
+
+	return TRUE;
+}
+
+void LLFloaterWebContent::initializeURLHistory()
+{
+	// start with an empty list
+	LLCtrlListInterface* url_list = childGetListInterface("address");
+	if (url_list)
+	{
+		url_list->operateOnAll(LLCtrlListInterface::OP_DELETE);
+	}
+
+	// Get all of the entries in the "browser" collection
+	LLSD browser_history = LLURLHistory::getURLHistory("browser");
+	LLSD::array_iterator iter_history =
+		browser_history.beginArray();
+	LLSD::array_iterator end_history =
+		browser_history.endArray();
+	for(; iter_history != end_history; ++iter_history)
+	{
+		std::string url = (*iter_history).asString();
+		if(! url.empty())
+			url_list->addSimpleElement(url);
+	}
+}
+
+//static
+void LLFloaterWebContent::create( const std::string &url, const std::string& target, const std::string& uuid )
+{
+	lldebugs << "url = " << url << ", target = " << target << ", uuid = " << uuid << llendl;
+
+	std::string tag = target;
+
+	if(target.empty() || target == "_blank")
+	{
+		if(!uuid.empty())
+		{
+			tag = uuid;
+		}
+		else
+		{
+			// create a unique tag for this instance
+			LLUUID id;
+			id.generate();
+			tag = id.asString();
+		}
+	}
+
+	S32 browser_window_limit = gSavedSettings.getS32("WebContentWindowLimit");
+
+	if(LLFloaterReg::findInstance("web_content", tag) != NULL)
+	{
+		// There's already a web browser for this tag, so we won't be opening a new window.
+	}
+	else if(browser_window_limit != 0)
+	{
+		// showInstance will open a new window.  Figure out how many web browsers are already open,
+		// and close the least recently opened one if this will put us over the limit.
+
+		LLFloaterReg::const_instance_list_t &instances = LLFloaterReg::getFloaterList("web_content");
+		lldebugs << "total instance count is " << instances.size() << llendl;
+
+		for(LLFloaterReg::const_instance_list_t::const_iterator iter = instances.begin(); iter != instances.end(); iter++)
+		{
+			lldebugs << "    " << (*iter)->getKey() << llendl;
+		}
+
+		if(instances.size() >= (size_t)browser_window_limit)
+		{
+			// Destroy the least recently opened instance
+			(*instances.begin())->closeFloater();
+		}
+	}
+
+	LLFloaterWebContent *browser = dynamic_cast<LLFloaterWebContent*> (LLFloaterReg::showInstance("web_content", tag));
+	llassert(browser);
+	if(browser)
+	{
+		browser->mUUID = uuid;
+
+		// tell the browser instance to load the specified URL
+		browser->open_media(url, target);
+		LLViewerMedia::proxyWindowOpened(target, uuid);
+	}
+}
+
+//static
+void LLFloaterWebContent::closeRequest(const std::string &uuid)
+{
+	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("web_content");
+	lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl;
+	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
+	{
+		LLFloaterWebContent* i = dynamic_cast<LLFloaterWebContent*>(*iter);
+		lldebugs << "    " << i->mUUID << llendl;
+		if (i && i->mUUID == uuid)
+		{
+			i->closeFloater(false);
+			return;
+ 		}
+ 	}
+}
+
+//static
+void LLFloaterWebContent::geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height)
+{
+	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("web_content");
+	lldebugs << "instance list size is " << inst_list.size() << ", incoming uuid is " << uuid << llendl;
+	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin(); iter != inst_list.end(); ++iter)
+	{
+		LLFloaterWebContent* i = dynamic_cast<LLFloaterWebContent*>(*iter);
+		lldebugs << "    " << i->mUUID << llendl;
+		if (i && i->mUUID == uuid)
+		{
+			i->geometryChanged(x, y, width, height);
+			return;
+		}
+	}
+}
+
+void LLFloaterWebContent::geometryChanged(S32 x, S32 y, S32 width, S32 height)
+{
+	// Make sure the layout of the browser control is updated, so this calculation is correct.
+	LLLayoutStack::updateClass();
+
+	// TODO: need to adjust size and constrain position to make sure floaters aren't moved outside the window view, etc.
+	LLCoordWindow window_size;
+	getWindow()->getSize(&window_size);
+
+	// Adjust width and height for the size of the chrome on the web Browser window.
+	width += getRect().getWidth() - mWebBrowser->getRect().getWidth();
+	height += getRect().getHeight() - mWebBrowser->getRect().getHeight();
+
+	LLRect geom;
+	geom.setOriginAndSize(x, window_size.mY - (y + height), width, height);
+
+	lldebugs << "geometry change: " << geom << llendl;
+
+	handleReshape(geom,false);
+}
+
+void LLFloaterWebContent::open_media(const std::string& web_url, const std::string& target)
+{
+	// Specifying a mime type of text/html here causes the plugin system to skip the MIME type probe and just open a browser plugin.
+	mWebBrowser->setHomePageUrl(web_url, "text/html");
+	mWebBrowser->setTarget(target);
+	mWebBrowser->navigateTo(web_url, "text/html");
+	set_current_url(web_url);
+}
+
+//virtual
+void LLFloaterWebContent::onClose(bool app_quitting)
+{
+	LLViewerMedia::proxyWindowClosed(mUUID);
+	destroy();
+}
+
+// virtual
+void LLFloaterWebContent::draw()
+{
+	// this is asychronous so we need to keep checking
+	getChildView( "back" )->setEnabled( mWebBrowser->canNavigateBack() );
+	getChildView( "forward" )->setEnabled( mWebBrowser->canNavigateForward() );
+
+	LLFloater::draw();
+}
+
+// virtual
+void LLFloaterWebContent::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
+{
+	if(event == MEDIA_EVENT_LOCATION_CHANGED)
+	{
+		const std::string url = self->getLocation();
+
+		if ( url.length() )
+			mStatusBarText->setText( url );
+
+		set_current_url( url );
+	}
+	else if(event == MEDIA_EVENT_NAVIGATE_BEGIN)
+	{
+		// flags are sent with this event
+		getChildView("back")->setEnabled( self->getHistoryBackAvailable() );
+		getChildView("forward")->setEnabled( self->getHistoryForwardAvailable() );
+
+		// toggle visibility of these buttons based on browser state
+		getChildView("reload")->setVisible( false );
+		getChildView("stop")->setVisible( true );
+
+		// turn "on" progress bar now we're about to start loading
+		mStatusBarProgress->setVisible( true );
+	}
+	else if(event == MEDIA_EVENT_NAVIGATE_COMPLETE)
+	{
+		// flags are sent with this event
+		getChildView("back")->setEnabled( self->getHistoryBackAvailable() );
+		getChildView("forward")->setEnabled( self->getHistoryForwardAvailable() );
+
+		// toggle visibility of these buttons based on browser state
+		getChildView("reload")->setVisible( true );
+		getChildView("stop")->setVisible( false );
+
+		// turn "off" progress bar now we're loaded
+		mStatusBarProgress->setVisible( false );
+
+		// we populate the status bar with URLs as they change so clear it now we're done
+		const std::string end_str = "";
+		mStatusBarText->setText( end_str );
+
+		// decide if secure browsing icon should be displayed
+		std::string prefix =  std::string("https://");
+		std::string test_prefix = mCurrentURL.substr(0, prefix.length());
+		LLStringUtil::toLower(test_prefix);
+		if(test_prefix == prefix)
+		{
+			mSecureLockIcon->setVisible(true);
+		}
+		else
+		{
+			mSecureLockIcon->setVisible(false);
+		}
+	}
+	else if(event == MEDIA_EVENT_CLOSE_REQUEST)
+	{
+		// The browser instance wants its window closed.
+		closeFloater();
+	}
+	else if(event == MEDIA_EVENT_GEOMETRY_CHANGE)
+	{
+		geometryChanged(self->getGeometryX(), self->getGeometryY(), self->getGeometryWidth(), self->getGeometryHeight());
+	}
+	else if(event == MEDIA_EVENT_STATUS_TEXT_CHANGED )
+	{
+		const std::string text = self->getStatusText();
+		if ( text.length() )
+			mStatusBarText->setText( text );
+	}
+	else if(event == MEDIA_EVENT_PROGRESS_UPDATED )
+	{
+		int percent = (int)self->getProgressPercent();
+		mStatusBarProgress->setValue( percent );
+	}
+	else if(event == MEDIA_EVENT_NAME_CHANGED )
+	{
+		std::string page_title = self->getMediaName();
+		// simulate browser behavior - title is empty, use the current URL
+		if ( page_title.length() > 0 )
+			setTitle( page_title );
+		else
+			setTitle( mCurrentURL );
+	}
+	else if(event == MEDIA_EVENT_LINK_HOVERED )
+	{
+		const std::string link = self->getHoverLink();
+		mStatusBarText->setText( link );
+	}
+}
+
+void LLFloaterWebContent::set_current_url(const std::string& url)
+{
+	mCurrentURL = url;
+
+	// serialize url history into the system URL History manager
+	LLURLHistory::removeURL("browser", mCurrentURL);
+	LLURLHistory::addURL("browser", mCurrentURL);
+
+	mAddressCombo->remove( mCurrentURL );
+	mAddressCombo->add( mCurrentURL );
+	mAddressCombo->selectByValue( mCurrentURL );
+}
+
+void LLFloaterWebContent::onClickForward()
+{
+	mWebBrowser->navigateForward();
+}
+
+void LLFloaterWebContent::onClickBack()
+{
+	mWebBrowser->navigateBack();
+}
+
+void LLFloaterWebContent::onClickReload()
+{
+
+	if( mWebBrowser->getMediaPlugin() )
+	{
+		bool ignore_cache = true;
+		mWebBrowser->getMediaPlugin()->browse_reload( ignore_cache );
+	}
+	else
+	{
+		mWebBrowser->navigateTo(mCurrentURL);
+	}
+}
+
+void LLFloaterWebContent::onClickStop()
+{
+	if( mWebBrowser->getMediaPlugin() )
+		mWebBrowser->getMediaPlugin()->browse_stop();
+
+	// still should happen when we catch the navigate complete event
+	// but sometimes (don't know why) that event isn't sent from Qt
+	// and we getto a point where the stop button stays active.
+	getChildView("reload")->setVisible( true );
+	getChildView("stop")->setVisible( false );
+}
+
+void LLFloaterWebContent::onEnterAddress()
+{
+	// make sure there is at least something there.
+	// (perhaps this test should be for minimum length of a URL)
+	std::string url = mAddressCombo->getValue().asString();
+	if ( url.length() > 0 )
+	{
+		mWebBrowser->navigateTo( url, "text/html");
+	};
+}
+
+void LLFloaterWebContent::onPopExternal()
+{
+	// make sure there is at least something there.
+	// (perhaps this test should be for minimum length of a URL)
+	std::string url = mAddressCombo->getValue().asString();
+	if ( url.length() > 0 )
+	{
+		LLWeb::loadURLExternal( url );
+	};
+}
diff --git a/indra/newview/llfloaterwebcontent.h b/indra/newview/llfloaterwebcontent.h
new file mode 100644
index 0000000000000000000000000000000000000000..001d822ada48b918eb4b5e0b8243377984224c44
--- /dev/null
+++ b/indra/newview/llfloaterwebcontent.h
@@ -0,0 +1,82 @@
+/**
+ * @file llfloaterwebcontent.h
+ * @brief floater for displaying web content - e.g. profiles and search (eventually)
+ *
+ * $LicenseInfo:firstyear=2006&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERWEBCONTENT_H
+#define LL_LLFLOATERWEBCONTENT_H
+
+#include "llfloater.h"
+#include "llmediactrl.h"
+
+class LLMediaCtrl;
+class LLComboBox;
+class LLTextBox;
+class LLProgressBar;
+class LLIconCtrl;
+
+class LLFloaterWebContent :
+	public LLFloater,
+	public LLViewerMediaObserver
+{
+public:
+    LOG_CLASS(LLFloaterWebContent);
+	LLFloaterWebContent(const LLSD& key);
+
+	void initializeURLHistory();
+
+	static void create(const std::string &url, const std::string& target, const std::string& uuid = LLStringUtil::null);
+
+	static void closeRequest(const std::string &uuid);
+	static void geometryChanged(const std::string &uuid, S32 x, S32 y, S32 width, S32 height);
+	void geometryChanged(S32 x, S32 y, S32 width, S32 height);
+
+	/* virtual */ BOOL postBuild();
+	/* virtual */ void onClose(bool app_quitting);
+	/* virtual */ void draw();
+
+	// inherited from LLViewerMediaObserver
+	/*virtual*/ void handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event);
+
+	void onClickBack();
+	void onClickForward();
+	void onClickReload();
+	void onClickStop();
+	void onEnterAddress();
+	void onPopExternal();
+
+private:
+	void open_media(const std::string& media_url, const std::string& target);
+	void set_current_url(const std::string& url);
+
+	LLMediaCtrl* mWebBrowser;
+	LLComboBox* mAddressCombo;
+	LLIconCtrl *mSecureLockIcon;
+	LLTextBox* mStatusBarText;
+	LLProgressBar* mStatusBarProgress;
+	std::string mCurrentURL;
+	std::string mUUID;
+};
+
+#endif  // LL_LLFLOATERWEBCONTENT_H
diff --git a/indra/newview/llhints.cpp b/indra/newview/llhints.cpp
index 3f0deb98cdbe7ecc3a2e8796ee40bc44c957bfc6..c4dcaf11f9044d4a4ea7cab2678a172cdb4c5936 100644
--- a/indra/newview/llhints.cpp
+++ b/indra/newview/llhints.cpp
@@ -33,6 +33,7 @@
 #include "lltextbox.h"
 #include "llviewerwindow.h"
 #include "llviewercontrol.h"
+#include "lliconctrl.h"
 #include "llsdparam.h"
 
 class LLHintPopup : public LLPanel
@@ -80,7 +81,8 @@ class LLHintPopup : public LLPanel
 										up_arrow,
 										right_arrow,
 										down_arrow,
-										lower_left_arrow;
+										lower_left_arrow,
+										hint_image;
 				
 		Optional<S32>					left_arrow_offset,
 										up_arrow_offset,
@@ -96,6 +98,7 @@ class LLHintPopup : public LLPanel
 			right_arrow("right_arrow"),
 			down_arrow("down_arrow"),
 			lower_left_arrow("lower_left_arrow"),
+			hint_image("hint_image"),
 			left_arrow_offset("left_arrow_offset"),
 			up_arrow_offset("up_arrow_offset"),
 			right_arrow_offset("right_arrow_offset"),
@@ -166,7 +169,15 @@ LLHintPopup::LLHintPopup(const LLHintPopup::Params& p)
 		mDirection = p.target_params.direction;
 		mTarget = p.target_params.target;
 	}
-	buildFromFile( "panel_hint.xml", NULL, p);
+	if (p.hint_image.isProvided())
+	{
+		buildFromFile("panel_hint_image.xml", NULL, p);
+		getChild<LLIconCtrl>("hint_image")->setImage(p.hint_image());
+	}
+	else
+	{
+		buildFromFile( "panel_hint.xml", NULL, p);
+	}
 }
 
 BOOL LLHintPopup::postBuild()
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index f7e5103d889b8b5821690cae2a24e9e9c48a33c9..24a876c59adde175e9c7d612f29415e26584aee2 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -194,9 +194,6 @@ void LLHUDText::renderText()
 
 	mRadius = (width_vec + height_vec).magVec() * 0.5f;
 
-	LLCoordGL screen_pos;
-	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);
-
 	LLVector2 screen_offset;
 	screen_offset = mPositionOffset;
 
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
index e000abda2a3a6e73ccb2847687549816db097801..f74ae92a7be67679acff65e255d8f6ad3008c8ec 100644
--- a/indra/newview/llimfloater.cpp
+++ b/indra/newview/llimfloater.cpp
@@ -470,7 +470,7 @@ LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
 }
 
 //static
-bool LLIMFloater::resetAllowedRectPadding(const LLSD& newvalue)
+bool LLIMFloater::resetAllowedRectPadding()
 {
 	//reset allowed rect right padding if "SidebarCameraMovement" option 
 	//or sidebar state changed
@@ -482,10 +482,10 @@ void LLIMFloater::getAllowedRect(LLRect& rect)
 {
 	if (sAllowedRectRightPadding == RECT_PADDING_NOT_INIT) //wasn't initialized
 	{
-		gSavedSettings.getControl("SidebarCameraMovement")->getSignal()->connect(boost::bind(&LLIMFloater::resetAllowedRectPadding, _2));
+		gSavedSettings.getControl("SidebarCameraMovement")->getSignal()->connect(boost::bind(&LLIMFloater::resetAllowedRectPadding));
 
 		LLSideTray*	side_bar = LLSideTray::getInstance();
-		side_bar->getCollapseSignal().connect(boost::bind(&LLIMFloater::resetAllowedRectPadding, _2));
+		side_bar->setVisibleWidthChangeCallback(boost::bind(&LLIMFloater::resetAllowedRectPadding));
 		sAllowedRectRightPadding = RECT_PADDING_NEED_RECALC;
 	}
 
@@ -500,10 +500,7 @@ void LLIMFloater::getAllowedRect(LLRect& rect)
 
 		if (gSavedSettings.getBOOL("SidebarCameraMovement") == FALSE)
 		{
-			LLSideTray*	side_bar = LLSideTray::getInstance();
-
-			if (side_bar->getVisible() && !side_bar->getCollapsed())
-				sAllowedRectRightPadding += side_bar->getRect().getWidth();
+			sAllowedRectRightPadding += LLSideTray::getInstance()->getVisibleWidth();
 		}
 	}
 	rect.mRight -= sAllowedRectRightPadding;
@@ -680,8 +677,6 @@ void LLIMFloater::updateMessages()
 
 	if (messages.size())
 	{
-//		LLUIColor chat_color = LLUIColorTable::instance().getColor("IMChatColor");
-
 		LLSD chat_args;
 		chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
 
diff --git a/indra/newview/llimfloater.h b/indra/newview/llimfloater.h
index e80e45e64ae8c48fd3f56ad5cce0dfe5eb6c9aea..5158f6c1f788d76243b28ada549d9f848d89f721 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llimfloater.h
@@ -156,7 +156,7 @@ class LLIMFloater : public LLTransientDockableFloater
 
 	static void closeHiddenIMToasts();
 
-	static bool resetAllowedRectPadding(const LLSD& newvalue);
+	static bool resetAllowedRectPadding();
 	//need to keep this static for performance issues
 	static S32 sAllowedRectRightPadding;
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 857c27be6394147ff9dd4dbb073d615e93a1f2ea..ce305dcd89741303bfc567e4f87732987d8d78fb 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -279,9 +279,27 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 
 void LLIMModel::LLIMSession::onAdHocNameCache(const LLAvatarName& av_name)
 {
-			LLStringUtil::format_map_t args;
-	args["[AGENT_NAME]"] = av_name.getCompleteName();
-			LLTrans::findString(mName, "conference-title-incoming", args);
+	if (av_name.mIsDummy)
+	{
+		S32 separator_index = mName.rfind(" ");
+		std::string name = mName.substr(0, separator_index);
+		++separator_index;
+		std::string conference_word = mName.substr(separator_index, mName.length());
+
+		// additional check that session name is what we expected
+		if ("Conference" == conference_word)
+		{
+			LLStringUtil::format_map_t args;
+			args["[AGENT_NAME]"] = name;
+			LLTrans::findString(mName, "conference-title-incoming", args);
+		}
+	}
+	else
+	{
+		LLStringUtil::format_map_t args;
+		args["[AGENT_NAME]"] = av_name.getCompleteName();
+		LLTrans::findString(mName, "conference-title-incoming", args);
+	}
 }
 
 void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state, const LLVoiceChannel::EDirection& direction)
@@ -537,15 +555,14 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
 
 void LLIMModel::LLIMSession::onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name)
 {
-	if (av_name.mLegacyFirstName.empty())
+	if (av_name.mUsername.empty())
 	{
-		// if mLegacyFirstName is empty it means display names is off and the 
-		// data came from the gCacheName, mDisplayName will be the legacy name
-		mHistoryFileName = LLCacheName::cleanFullName(av_name.mDisplayName);
+		// display names is off, use mDisplayName which will be the legacy name
+		mHistoryFileName = LLCacheName::buildUsername(av_name.mDisplayName);
 	}
 	else
 	{  
-		mHistoryFileName = LLCacheName::cleanFullName(av_name.getLegacyName());
+		mHistoryFileName = av_name.mUsername;
 	}
 }
 
@@ -556,7 +573,12 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 	//ad-hoc requires sophisticated chat history saving schemes
 	if (isAdHoc())
 	{
-		//in case of outgoing ad-hoc sessions
+		/* 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 
+		* 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.
+		*/
 		if (mInitialTargetIDs.size())
 		{
 			std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end());
@@ -2085,7 +2107,7 @@ void LLIncomingCallDialog::onOpen(const LLSD& key)
 void LLIncomingCallDialog::onAccept(void* user_data)
 {
 	LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
-	self->processCallResponse(0);
+	processCallResponse(0, self->mPayload);
 	self->closeFloater();
 }
 
@@ -2093,7 +2115,7 @@ void LLIncomingCallDialog::onAccept(void* user_data)
 void LLIncomingCallDialog::onReject(void* user_data)
 {
 	LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
-	self->processCallResponse(1);
+	processCallResponse(1, self->mPayload);
 	self->closeFloater();
 }
 
@@ -2101,20 +2123,21 @@ void LLIncomingCallDialog::onReject(void* user_data)
 void LLIncomingCallDialog::onStartIM(void* user_data)
 {
 	LLIncomingCallDialog* self = (LLIncomingCallDialog*)user_data;
-	self->processCallResponse(2);
+	processCallResponse(2, self->mPayload);
 	self->closeFloater();
 }
 
-void LLIncomingCallDialog::processCallResponse(S32 response)
+// static
+void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload)
 {
 	if (!gIMMgr || gDisconnected)
 		return;
 
-	LLUUID session_id = mPayload["session_id"].asUUID();
-	LLUUID caller_id = mPayload["caller_id"].asUUID();
-	std::string session_name = mPayload["session_name"].asString();
-	EInstantMessage type = (EInstantMessage)mPayload["type"].asInteger();
-	LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)mPayload["inv_type"].asInteger();
+	LLUUID session_id = payload["session_id"].asUUID();
+	LLUUID caller_id = payload["caller_id"].asUUID();
+	std::string session_name = payload["session_name"].asString();
+	EInstantMessage type = (EInstantMessage)payload["type"].asInteger();
+	LLIMMgr::EInvitationType inv_type = (LLIMMgr::EInvitationType)payload["inv_type"].asInteger();
 	bool voice = true;
 	switch(response)
 	{
@@ -2131,8 +2154,8 @@ void LLIncomingCallDialog::processCallResponse(S32 response)
 			session_id = gIMMgr->addP2PSession(
 				session_name,
 				caller_id,
-				mPayload["session_handle"].asString(),
-				mPayload["session_uri"].asString());
+				payload["session_handle"].asString(),
+				payload["session_uri"].asString());
 
 			if (voice)
 			{
@@ -2166,7 +2189,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response)
 						LLAvatarName av_name;
 						if (LLAvatarNameCache::get(caller_id, &av_name))
 						{
-							correct_session_name = av_name.mDisplayName + " (" + av_name.mUsername + ")";
+							correct_session_name = av_name.getCompleteName();
 							correct_session_name.append(ADHOC_NAME_SUFFIX); 
 						}
 					}
@@ -2196,10 +2219,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response)
 						inv_type));
 
 				// send notification message to the corresponding chat 
-				if (mPayload["notify_box_type"].asString() == "VoiceInviteGroup" || mPayload["notify_box_type"].asString() == "VoiceInviteAdHoc")
+				if (payload["notify_box_type"].asString() == "VoiceInviteGroup" || payload["notify_box_type"].asString() == "VoiceInviteAdHoc")
 				{
 					LLStringUtil::format_map_t string_args;
-					string_args["[NAME]"] = mPayload["caller_name"].asString();
+					string_args["[NAME]"] = payload["caller_name"].asString();
 					std::string message = LLTrans::getString("name_started_call", string_args);
 					LLIMModel::getInstance()->addMessageSilently(session_id, SYSTEM_FROM, LLUUID::null, message);
 				}
@@ -2216,7 +2239,7 @@ void LLIncomingCallDialog::processCallResponse(S32 response)
 		{
 			if(LLVoiceClient::getInstance())
 			{
-				std::string s = mPayload["session_handle"].asString();
+				std::string s = payload["session_handle"].asString();
 				LLVoiceClient::getInstance()->declineInvite(s);
 			}
 		}
@@ -2623,16 +2646,19 @@ void LLIMMgr::inviteToSession(
 	std::string question_type = "VoiceInviteQuestionDefault";
 
 	BOOL ad_hoc_invite = FALSE;
+	BOOL voice_invite = FALSE;
 	if(type == IM_SESSION_P2P_INVITE)
 	{
 		//P2P is different...they only have voice invitations
 		notify_box_type = "VoiceInviteP2P";
+		voice_invite = TRUE;
 	}
 	else if ( gAgent.isInGroup(session_id) )
 	{
 		//only really old school groups have voice invitations
 		notify_box_type = "VoiceInviteGroup";
 		question_type = "VoiceInviteQuestionGroup";
+		voice_invite = TRUE;
 	}
 	else if ( inv_type == INVITATION_TYPE_VOICE )
 	{
@@ -2640,6 +2666,7 @@ void LLIMMgr::inviteToSession(
 		//and a voice ad-hoc
 		notify_box_type = "VoiceInviteAdHoc";
 		ad_hoc_invite = TRUE;
+		voice_invite = TRUE;
 	}
 	else if ( inv_type == INVITATION_TYPE_IMMEDIATE )
 	{
@@ -2663,23 +2690,21 @@ void LLIMMgr::inviteToSession(
 	if (channelp && channelp->callStarted())
 	{
 		// you have already started a call to the other user, so just accept the invite
-		LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 0);
+		LLIncomingCallDialog::processCallResponse(0, payload);
 		return;
 	}
 
-	if (type == IM_SESSION_P2P_INVITE || ad_hoc_invite)
+	if (voice_invite)
 	{
-		// is the inviter a friend?
-		if (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL)
+		if	(	// if we're rejecting all incoming call requests
+				gSavedSettings.getBOOL("VoiceCallsRejectAll")	
+				// or we're rejecting non-friend voice calls and this isn't a friend	
+				|| (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL))
+			)
 		{
-			// if not, and we are ignoring voice invites from non-friends
-			// then silently decline
-			if (gSavedSettings.getBOOL("VoiceCallsFriendsOnly"))
-			{
-				// invite not from a friend, so decline
-				LLNotifications::instance().forceResponse(LLNotification::Params("VoiceInviteP2P").payload(payload), 1);
-				return;
-			}
+			// silently decline the call
+			LLIncomingCallDialog::processCallResponse(1, payload);
+			return;
 		}
 	}
 
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 3f72d66bfb1dcaaf668de363c53cae7c207a3aa6..e765a8da2fe69167dfd88eb8c8828cdfda28aae7 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -542,6 +542,7 @@ class LLIncomingCallDialog : public LLCallDialog
 	static void onReject(void* user_data);
 	static void onStartIM(void* user_data);
 
+	static void processCallResponse(S32 response, const LLSD& payload);
 private:
 	void setCallerName(const std::string& ui_title,
 		const std::string& ui_label,
@@ -551,7 +552,6 @@ class LLIncomingCallDialog : public LLCallDialog
 		const std::string& call_type);
 
 	/*virtual*/ void onLifetimeExpired();
-	void processCallResponse(S32 response);
 };
 
 class LLOutgoingCallDialog : public LLCallDialog
diff --git a/indra/newview/llinspecttoast.cpp b/indra/newview/llinspecttoast.cpp
index 58b3f0309fd795d10718af884d17214822b98903..d7b82667d17732dacbfa5a7e6521c011f4f8af3f 100644
--- a/indra/newview/llinspecttoast.cpp
+++ b/indra/newview/llinspecttoast.cpp
@@ -46,6 +46,7 @@ class LLInspectToast: public LLInspect
 	virtual ~LLInspectToast();
 
 	/*virtual*/ void onOpen(const LLSD& notification_id);
+	/*virtual*/ BOOL handleToolTip(S32 x, S32 y, MASK mask);
 private:
 	void onToastDestroy(LLToast * toast);
 
@@ -73,6 +74,7 @@ LLInspectToast::~LLInspectToast()
 	LLTransientFloaterMgr::getInstance()->removeControlView(this);
 }
 
+// virtual
 void LLInspectToast::onOpen(const LLSD& notification_id)
 {
 	LLInspect::onOpen(notification_id);
@@ -103,6 +105,15 @@ void LLInspectToast::onOpen(const LLSD& notification_id)
 	LLUI::positionViewNearMouse(this);
 }
 
+// virtual
+BOOL LLInspectToast::handleToolTip(S32 x, S32 y, MASK mask)
+{
+	// We don't like the way LLInspect handles tooltips
+	// (black tooltips look weird),
+	// so force using the default implementation (STORM-511).
+	return LLFloater::handleToolTip(x, y, mask);
+}
+
 void LLInspectToast::onToastDestroy(LLToast * toast)
 {
 	closeFloater(false);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 5ba87423c7bae91222a0fa4ebe526acc332580a8..ab0acbae5062f116cadc5b117936c9ec9d413cc1 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -104,6 +104,7 @@ void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_
 bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
 bool confirm_attachment_rez(const LLSD& notification, const LLSD& response);
 void teleport_via_landmark(const LLUUID& asset_id);
+static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
 
 // +=================================================+
 // |        LLInvFVBridge                            |
@@ -2341,6 +2342,10 @@ void LLFolderBridge::pasteFromClipboard()
 	LLInventoryModel* model = getInventoryModel();
 	if(model && isClipboardPasteable())
 	{
+		const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
+		const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
+		const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
+
 		const LLUUID parent_id(mUUID);
 
 		LLDynamicArray<LLUUID> objects;
@@ -2353,7 +2358,14 @@ void LLFolderBridge::pasteFromClipboard()
 			LLInventoryItem *item = model->getItem(item_id);
 			if (item)
 			{
-				if(LLInventoryClipboard::instance().isCutMode())
+				if (move_is_into_current_outfit || move_is_into_outfit)
+				{
+					if (can_move_to_outfit(item, move_is_into_current_outfit))
+					{
+						dropToOutfit(item, move_is_into_current_outfit);
+					}
+				}
+				else if(LLInventoryClipboard::instance().isCutMode())
 				{
 					// move_inventory_item() is not enough,
 					//we have to update inventory locally too
@@ -2381,9 +2393,13 @@ void LLFolderBridge::pasteFromClipboard()
 
 void LLFolderBridge::pasteLinkFromClipboard()
 {
-	const LLInventoryModel* model = getInventoryModel();
+	LLInventoryModel* model = getInventoryModel();
 	if(model)
 	{
+		const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
+		const BOOL move_is_into_current_outfit = (mUUID == current_outfit_id);
+		const BOOL move_is_into_outfit = (getCategory() && getCategory()->getPreferredType()==LLFolderType::FT_OUTFIT);
+
 		const LLUUID parent_id(mUUID);
 
 		LLDynamicArray<LLUUID> objects;
@@ -2393,7 +2409,15 @@ void LLFolderBridge::pasteLinkFromClipboard()
 			 ++iter)
 		{
 			const LLUUID &object_id = (*iter);
-			if (LLInventoryCategory *cat = model->getCategory(object_id))
+			if (move_is_into_current_outfit || move_is_into_outfit)
+			{
+				LLInventoryItem *item = model->getItem(object_id);
+				if (item && can_move_to_outfit(item, move_is_into_current_outfit))
+				{
+					dropToOutfit(item, move_is_into_current_outfit);
+				}
+			}
+			else if (LLInventoryCategory *cat = model->getCategory(object_id))
 			{
 				const std::string empty_description = "";
 				link_inventory_item(
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index 225d0288a978e66df627ba12e83b3eaf7d46f76d..3e0849a79578d793e0890e45d8a4d74b77b46545 100644
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -97,7 +97,8 @@ void LLPanelInventoryListItemBase::draw()
 		LLRect separator_rect = getLocalRect();
 		separator_rect.mTop = separator_rect.mBottom;
 		separator_rect.mBottom -= mSeparatorImage->getHeight();
-		mSeparatorImage->draw(separator_rect);
+		F32 alpha = getCurrentTransparency();
+		mSeparatorImage->draw(separator_rect, UI_VERTEX_COLOR % alpha);
 	}
 	
 	LLPanel::draw();
diff --git a/indra/newview/lllistcontextmenu.cpp b/indra/newview/lllistcontextmenu.cpp
index ea744072d2f83371bcea70695063efce63b0e330..6421ab42bfe605d066341aff757e8da2b0260ef6 100644
--- a/indra/newview/lllistcontextmenu.cpp
+++ b/indra/newview/lllistcontextmenu.cpp
@@ -36,7 +36,6 @@
 #include "llviewermenu.h" // for LLViewerMenuHolderGL
 
 LLListContextMenu::LLListContextMenu()
-:	mMenu(NULL)
 {
 }
 
@@ -51,23 +50,22 @@ LLListContextMenu::~LLListContextMenu()
 	// of mMenu has already been deleted except of using LLHandle. EXT-4762.
 	if (!mMenuHandle.isDead())
 	{
-		mMenu->die();
-		mMenu = NULL;
+		mMenuHandle.get()->die();
 	}
 }
 
 void LLListContextMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y)
 {
-	if (mMenu)
+	LLContextMenu* menup = mMenuHandle.get();
+	if (menup)
 	{
 		//preventing parent (menu holder) from deleting already "dead" context menus on exit
-		LLView* parent = mMenu->getParent();
+		LLView* parent = menup->getParent();
 		if (parent)
 		{
-			parent->removeChild(mMenu);
+			parent->removeChild(menup);
 		}
-		delete mMenu;
-		mMenu = NULL;
+		delete menup;
 		mUUIDs.clear();
 	}
 
@@ -79,23 +77,23 @@ void LLListContextMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32
 	mUUIDs.resize(uuids.size());
 	std::copy(uuids.begin(), uuids.end(), mUUIDs.begin());
 
-	mMenu = createMenu();
-	if (!mMenu)
+	menup = createMenu();
+	if (!menup)
 	{
 		llwarns << "Context menu creation failed" << llendl;
 		return;
 	}
 
-	mMenuHandle = mMenu->getHandle();
-	mMenu->show(x, y);
-	LLMenuGL::showPopup(spawning_view, mMenu, x, y);
+	mMenuHandle = menup->getHandle();
+	menup->show(x, y);
+	LLMenuGL::showPopup(spawning_view, menup, x, y);
 }
 
 void LLListContextMenu::hide()
 {
-	if(mMenu)
+	if(mMenuHandle.get())
 	{
-		mMenu->hide();
+		mMenuHandle.get()->hide();
 	}
 }
 
diff --git a/indra/newview/lllistcontextmenu.h b/indra/newview/lllistcontextmenu.h
index 5dedc30b0c1cbda6d051e594e15b0b88e73d06ab..fabd68ee20d2b7c6a56d9efd886a313bfb91b861 100644
--- a/indra/newview/lllistcontextmenu.h
+++ b/indra/newview/lllistcontextmenu.h
@@ -71,8 +71,7 @@ class LLListContextMenu
 	static void handleMultiple(functor_t functor, const uuid_vec_t& ids);
 
 	uuid_vec_t			mUUIDs;
-	LLContextMenu*		mMenu;
-	LLHandle<LLView>	mMenuHandle;
+	LLHandle<LLContextMenu>	mMenuHandle;
 };
 
 #endif // LL_LLLISTCONTEXTMENU_H
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 8c70b1e9730e7c7346a5b26173a07b20e7f16b36..0121bbb1ed3dc88164c88cc39f66ee9c0aa1841c 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -89,6 +89,16 @@ const static boost::regex TIMESTAMP_AND_STUFF("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+
  */
 const static boost::regex NAME_AND_TEXT("([^:]+[:]{1})?(\\s*)(.*)");
 
+/**
+ * These are recognizers for matching the names of ad-hoc conferences when generating the log file name
+ * On invited side, an ad-hoc is named like "<first name> <last name> Conference 2010/11/19 03:43 f0f4"
+ * On initiating side, an ad-hoc is named like Ad-hoc Conference hash<hash>"
+ * If the naming system for ad-hoc conferences are change in LLIMModel::LLIMSession::buildHistoryFileName()
+ * then these definition need to be adjusted as well.
+ */
+const static boost::regex INBOUND_CONFERENCE("^[a-zA-Z]{1,31} [a-zA-Z]{1,31} Conference [0-9]{4}/[0-9]{2}/[0-9]{2} [0-9]{2}:[0-9]{2} [0-9a-f]{4}");
+const static boost::regex OUTBOUND_CONFERENCE("^Ad-hoc Conference hash[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}");
+
 //is used to parse complex object names like "Xstreet SL Terminal v2.2.5 st"
 const static std::string NAME_TEXT_DIVIDER(": ");
 
@@ -182,15 +192,43 @@ class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
 //static
 std::string LLLogChat::makeLogFileName(std::string filename)
 {
+	/**
+	* Testing for in bound and out bound ad-hoc file names
+	* if it is then skip date stamping.
+	**/
+	//LL_INFOS("") << "Befor:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+    boost::match_results<std::string::const_iterator> matches;
+	bool inboundConf = boost::regex_match(filename, matches, INBOUND_CONFERENCE);
+	bool outboundConf = boost::regex_match(filename, matches, OUTBOUND_CONFERENCE);
+	if (!(inboundConf || outboundConf))
+	{
+		if( gSavedPerAccountSettings.getBOOL("LogFileNamewithDate") )
+		{
+			time_t now;
+			time(&now);
+			char dbuffer[20];		/* Flawfinder: ignore */
+			if (filename == "chat")
+			{
+				strftime(dbuffer, 20, "-%Y-%m-%d", localtime(&now));
+			}
+			else
+			{
+				strftime(dbuffer, 20, "-%Y-%m", localtime(&now));
+			}
+			filename += dbuffer;
+		}
+	}
+	//LL_INFOS("") << "After:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
 	filename = cleanFileName(filename);
 	filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS,filename);
 	filename += ".txt";
+	//LL_INFOS("") << "Full:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
 	return filename;
 }
 
 std::string LLLogChat::cleanFileName(std::string filename)
 {
-	std::string invalidChars = "\"\'\\/?*:<>|";
+	std::string invalidChars = "\"\'\\/?*:.<>|";
 	std::string::size_type position = filename.find_first_of(invalidChars);
 	while (position != filename.npos)
 	{
@@ -354,10 +392,19 @@ void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& me
 		llwarns << "Session name is Empty!" << llendl;
 		return ;
 	}
-
-	LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");		/*Flawfinder: ignore*/
-	if (!fptr) return;	//No previous conversation with this name.
-
+	//LL_INFOS("") << "Loading:" << file_name << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+	//LL_INFOS("") << "Current:" << makeLogFileName(file_name) << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+	LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
+	if (!fptr)
+    {
+		fptr = LLFile::fopen(oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
+        if (!fptr)
+        {
+			if (!fptr) return;      //No previous conversation with this name.
+        }
+	}
+ 
+    //LL_INFOS("") << "Reading:" << file_name << LL_ENDL;
 	char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/
 	char *bptr;
 	S32 len;
@@ -544,3 +591,32 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
 	im[IM_TEXT] = name_and_text[IDX_TEXT];
 	return true;  //parsed name and message text, maybe have a timestamp too
 }
+std::string LLLogChat::oldLogFileName(std::string filename)
+{
+    std::string scanResult;
+	std::string directory = gDirUtilp->getPerAccountChatLogsDir();/* get Users log directory */
+	directory += gDirUtilp->getDirDelimiter();/* add final OS dependent delimiter */
+	filename=cleanFileName(filename);/* lest make shure the file name has no invalad charecters befor making the pattern */
+	std::string pattern = (filename+(( filename == "chat" ) ? "-???\?-?\?-??.txt" : "-???\?-??.txt"));/* create search pattern*/
+	//LL_INFOS("") << "Checking:" << directory << " for " << pattern << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+	std::vector<std::string> allfiles;
+
+    while (gDirUtilp->getNextFileInDir(directory, pattern, scanResult))
+    {
+		//LL_INFOS("") << "Found   :" << scanResult << LL_ENDL;
+        allfiles.push_back(scanResult);
+    }
+
+    if (allfiles.size() == 0)  // if no result from date search, return generic filename
+    {
+        scanResult = directory + filename + ".txt";
+    }
+    else 
+    {
+        std::sort(allfiles.begin(), allfiles.end());
+        scanResult = directory + allfiles.back();
+        // thisfile is now the most recent version of the file.
+    }
+	//LL_INFOS("") << "Reading:" << scanResult << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+    return scanResult;
+}
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 6958d563111eb7cc96592c46154311833e401a8c..27752452c9e613f236b967f155328fd66171a69e 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -41,6 +41,10 @@ class LLLogChat
 	};
 	static std::string timestamp(bool withdate = false);
 	static std::string makeLogFileName(std::string(filename));
+	/**
+	*Add functions to get old and non date stamped file names when needed
+	*/
+	static std::string oldLogFileName(std::string(filename));
 	static void saveHistory(const std::string& filename,
 				const std::string& from,
 				const LLUUID& from_id,
diff --git a/indra/newview/lllogininstance.cpp b/indra/newview/lllogininstance.cpp
index 029e700c4ccd7678ad8a1df48b9393ccf48cd0da..d866db1829240ac0ffbae648b380cacdaf8f39cc 100644
--- a/indra/newview/lllogininstance.cpp
+++ b/indra/newview/lllogininstance.cpp
@@ -42,24 +42,428 @@
 // newview
 #include "llviewernetwork.h"
 #include "llviewercontrol.h"
+#include "llversioninfo.h"
 #include "llslurl.h"
 #include "llstartup.h"
 #include "llfloaterreg.h"
 #include "llnotifications.h"
 #include "llwindow.h"
 #include "llviewerwindow.h"
+#include "llprogressview.h"
 #if LL_LINUX || LL_SOLARIS
 #include "lltrans.h"
 #endif
 #include "llsecapi.h"
 #include "llstartup.h"
 #include "llmachineid.h"
+#include "llupdaterservice.h"
+#include "llevents.h"
+#include "llnotificationsutil.h"
+#include "llappviewer.h"
+
+#include <boost/scoped_ptr.hpp>
+#include <sstream>
+
+class LLLoginInstance::Disposable {
+public:
+	virtual ~Disposable() {}
+};
+
+namespace {
+	class MandatoryUpdateMachine:
+		public LLLoginInstance::Disposable
+	{
+	public:
+		MandatoryUpdateMachine(LLLoginInstance & loginInstance, LLUpdaterService & updaterService);
+		
+		void start(void);
+		
+	private:
+		class State;
+		class CheckingForUpdate;
+		class Error;
+		class ReadyToInstall; 
+		class StartingUpdaterService;
+		class WaitingForDownload;
+		
+		LLLoginInstance & mLoginInstance;
+		boost::scoped_ptr<State> mState;
+		LLUpdaterService & mUpdaterService;
+		
+		void setCurrentState(State * newState);
+	};
+
+	
+	class MandatoryUpdateMachine::State {
+	public:
+		virtual ~State() {}
+		virtual void enter(void) {}
+		virtual void exit(void) {}
+	};
+	
+	
+	class MandatoryUpdateMachine::CheckingForUpdate:
+	public MandatoryUpdateMachine::State
+	{
+	public:
+		CheckingForUpdate(MandatoryUpdateMachine & machine);
+		
+		virtual void enter(void);
+		virtual void exit(void);
+		
+	private:
+		LLTempBoundListener mConnection;
+		MandatoryUpdateMachine & mMachine;
+		LLProgressView * mProgressView;
+		
+		bool onEvent(LLSD const & event);
+	};
+	
+	
+	class MandatoryUpdateMachine::Error:
+	public MandatoryUpdateMachine::State
+	{
+	public:
+		Error(MandatoryUpdateMachine & machine);
+		
+		virtual void enter(void);
+		virtual void exit(void);
+		void onButtonClicked(const LLSD &, const LLSD &);
+		
+	private:
+		MandatoryUpdateMachine & mMachine;
+	};
+	
+	
+	class MandatoryUpdateMachine::ReadyToInstall:
+	public MandatoryUpdateMachine::State
+	{
+	public:
+		ReadyToInstall(MandatoryUpdateMachine & machine);
+		
+		virtual void enter(void);
+		virtual void exit(void);
+		
+	private:
+		MandatoryUpdateMachine & mMachine;
+	};
+	
+	
+	class MandatoryUpdateMachine::StartingUpdaterService:
+	public MandatoryUpdateMachine::State
+	{
+	public:
+		StartingUpdaterService(MandatoryUpdateMachine & machine);
+		
+		virtual void enter(void);
+		virtual void exit(void);
+		void onButtonClicked(const LLSD & uiform, const LLSD & result);
+	private:
+		MandatoryUpdateMachine & mMachine;
+	};
+	
+	
+	class MandatoryUpdateMachine::WaitingForDownload:
+		public MandatoryUpdateMachine::State
+	{
+	public:
+		WaitingForDownload(MandatoryUpdateMachine & machine);
+		
+		virtual void enter(void);
+		virtual void exit(void);
+		
+	private:
+		LLTempBoundListener mConnection;
+		MandatoryUpdateMachine & mMachine;
+		LLProgressView * mProgressView;
+		
+		bool onEvent(LLSD const & event);
+	};
+}
 
 static const char * const TOS_REPLY_PUMP = "lllogininstance_tos_callback";
 static const char * const TOS_LISTENER_NAME = "lllogininstance_tos";
 
 std::string construct_start_string();
 
+
+
+// MandatoryUpdateMachine
+//-----------------------------------------------------------------------------
+
+
+MandatoryUpdateMachine::MandatoryUpdateMachine(LLLoginInstance & loginInstance, LLUpdaterService & updaterService):
+	mLoginInstance(loginInstance),
+	mUpdaterService(updaterService)
+{
+	; // No op.
+}
+
+
+void MandatoryUpdateMachine::start(void)
+{
+	llinfos << "starting manditory update machine" << llendl;
+	
+	if(mUpdaterService.isChecking()) {
+		switch(mUpdaterService.getState()) {
+			case LLUpdaterService::UP_TO_DATE:
+				mUpdaterService.stopChecking();
+				mUpdaterService.startChecking();
+				// Fall through.
+			case LLUpdaterService::INITIAL:
+			case LLUpdaterService::CHECKING_FOR_UPDATE:
+				setCurrentState(new CheckingForUpdate(*this));
+				break;
+			case LLUpdaterService::DOWNLOADING:
+				setCurrentState(new WaitingForDownload(*this));
+				break;
+			case LLUpdaterService::TERMINAL:
+				if(LLUpdaterService::updateReadyToInstall()) {
+					setCurrentState(new ReadyToInstall(*this));
+				} else {
+					setCurrentState(new Error(*this));
+				}
+				break;
+			case LLUpdaterService::FAILURE:
+				setCurrentState(new Error(*this));
+				break;
+			default:
+				llassert(!"unpossible case");
+				break;
+		}
+	} else {
+		setCurrentState(new StartingUpdaterService(*this));
+	}
+}
+
+
+void MandatoryUpdateMachine::setCurrentState(State * newStatePointer)
+{
+	{
+		boost::scoped_ptr<State> newState(newStatePointer);
+		if(mState != 0) mState->exit();
+		mState.swap(newState);
+		
+		// Old state will be deleted on exit from this block before the new state
+		// is entered.
+	}
+	if(mState != 0) mState->enter();
+}
+
+
+
+// MandatoryUpdateMachine::CheckingForUpdate
+//-----------------------------------------------------------------------------
+
+
+MandatoryUpdateMachine::CheckingForUpdate::CheckingForUpdate(MandatoryUpdateMachine & machine):
+	mMachine(machine)
+{
+	; // No op.
+}
+
+
+void MandatoryUpdateMachine::CheckingForUpdate::enter(void)
+{
+	llinfos << "entering checking for update" << llendl;
+	
+	mProgressView = gViewerWindow->getProgressView();
+	mProgressView->setMessage("Looking for update...");
+	mProgressView->setText("There is a required update for your Second Life installation.");
+	mProgressView->setPercent(0);
+	mProgressView->setVisible(true);
+	mConnection = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()).
+		listen("MandatoryUpdateMachine::CheckingForUpdate", boost::bind(&MandatoryUpdateMachine::CheckingForUpdate::onEvent, this, _1));
+}
+
+
+void MandatoryUpdateMachine::CheckingForUpdate::exit(void)
+{
+}
+
+
+bool MandatoryUpdateMachine::CheckingForUpdate::onEvent(LLSD const & event)
+{
+	if(event["type"].asInteger() == LLUpdaterService::STATE_CHANGE) {
+		switch(event["state"].asInteger()) {
+			case LLUpdaterService::DOWNLOADING:
+				mMachine.setCurrentState(new WaitingForDownload(mMachine));
+				break;
+			case LLUpdaterService::UP_TO_DATE:
+			case LLUpdaterService::TERMINAL:
+			case LLUpdaterService::FAILURE:
+				mProgressView->setVisible(false);
+				mMachine.setCurrentState(new Error(mMachine));
+				break;
+			case LLUpdaterService::INSTALLING:
+				llassert(!"can't possibly be installing");
+				break;
+			default:
+				break;
+		}
+	} else {
+		; // Ignore.
+	}
+	
+	return false;
+}
+
+
+
+// MandatoryUpdateMachine::Error
+//-----------------------------------------------------------------------------
+
+
+MandatoryUpdateMachine::Error::Error(MandatoryUpdateMachine & machine):
+	mMachine(machine)
+{
+	; // No op.
+}
+
+
+void MandatoryUpdateMachine::Error::enter(void)
+{
+	llinfos << "entering error" << llendl;
+	LLNotificationsUtil::add("FailedUpdateInstall", LLSD(), LLSD(), boost::bind(&MandatoryUpdateMachine::Error::onButtonClicked, this, _1, _2));
+}
+
+
+void MandatoryUpdateMachine::Error::exit(void)
+{
+	LLAppViewer::instance()->forceQuit();
+}
+
+
+void MandatoryUpdateMachine::Error::onButtonClicked(const LLSD &, const LLSD &)
+{
+	mMachine.setCurrentState(0);
+}
+
+
+
+// MandatoryUpdateMachine::ReadyToInstall
+//-----------------------------------------------------------------------------
+
+
+MandatoryUpdateMachine::ReadyToInstall::ReadyToInstall(MandatoryUpdateMachine & machine):
+	mMachine(machine)
+{
+	; // No op.
+}
+
+
+void MandatoryUpdateMachine::ReadyToInstall::enter(void)
+{
+	llinfos << "entering ready to install" << llendl;
+	// Open update ready dialog.
+}
+
+
+void MandatoryUpdateMachine::ReadyToInstall::exit(void)
+{
+	// Restart viewer.
+}
+
+
+
+// MandatoryUpdateMachine::StartingUpdaterService
+//-----------------------------------------------------------------------------
+
+
+MandatoryUpdateMachine::StartingUpdaterService::StartingUpdaterService(MandatoryUpdateMachine & machine):
+	mMachine(machine)
+{
+	; // No op.
+}
+
+
+void MandatoryUpdateMachine::StartingUpdaterService::enter(void)
+{
+	llinfos << "entering start update service" << llendl;
+	LLNotificationsUtil::add("UpdaterServiceNotRunning", LLSD(), LLSD(), boost::bind(&MandatoryUpdateMachine::StartingUpdaterService::onButtonClicked, this, _1, _2));
+}
+
+
+void MandatoryUpdateMachine::StartingUpdaterService::exit(void)
+{
+	; // No op.
+}
+
+
+void MandatoryUpdateMachine::StartingUpdaterService::onButtonClicked(const LLSD & uiform, const LLSD & result)
+{
+	if(result["OK_okcancelbuttons"].asBoolean()) {
+		mMachine.mUpdaterService.startChecking(false);
+		mMachine.setCurrentState(new CheckingForUpdate(mMachine));
+	} else {
+		LLAppViewer::instance()->forceQuit();
+	}
+}
+
+
+
+// MandatoryUpdateMachine::WaitingForDownload
+//-----------------------------------------------------------------------------
+
+
+MandatoryUpdateMachine::WaitingForDownload::WaitingForDownload(MandatoryUpdateMachine & machine):
+	mMachine(machine),
+	mProgressView(0)
+{
+	; // No op.
+}
+
+
+void MandatoryUpdateMachine::WaitingForDownload::enter(void)
+{
+	llinfos << "entering waiting for download" << llendl;
+	mProgressView = gViewerWindow->getProgressView();
+	mProgressView->setMessage("Downloading update...");
+	std::ostringstream stream;
+	stream << "There is a required update for your Second Life installation." << std::endl <<
+		"Version " << mMachine.mUpdaterService.updatedVersion();
+	mProgressView->setText(stream.str());
+	mProgressView->setPercent(0);
+	mProgressView->setVisible(true);
+	mConnection = LLEventPumps::instance().obtain(LLUpdaterService::pumpName()).
+		listen("MandatoryUpdateMachine::CheckingForUpdate", boost::bind(&MandatoryUpdateMachine::WaitingForDownload::onEvent, this, _1));
+}
+
+
+void MandatoryUpdateMachine::WaitingForDownload::exit(void)
+{
+	mProgressView->setVisible(false);
+}
+
+
+bool MandatoryUpdateMachine::WaitingForDownload::onEvent(LLSD const & event)
+{
+	switch(event["type"].asInteger()) {
+		case LLUpdaterService::DOWNLOAD_COMPLETE:
+			mMachine.setCurrentState(new ReadyToInstall(mMachine));
+			break;
+		case LLUpdaterService::DOWNLOAD_ERROR:
+			mMachine.setCurrentState(new Error(mMachine));
+			break;
+		case LLUpdaterService::PROGRESS: {
+			double downloadSize = event["download_size"].asReal();
+			double bytesDownloaded = event["bytes_downloaded"].asReal();
+			mProgressView->setPercent(100. * bytesDownloaded / downloadSize);
+			break;
+		}
+		default:
+			break;
+	}
+
+	return false;
+}
+
+
+
+// LLLoginInstance
+//-----------------------------------------------------------------------------
+
+
 LLLoginInstance::LLLoginInstance() :
 	mLoginModule(new LLLogin()),
 	mNotifications(NULL),
@@ -68,7 +472,8 @@ LLLoginInstance::LLLoginInstance() :
 	mSkipOptionalUpdate(false),
 	mAttemptComplete(false),
 	mTransferRate(0.0f),
-	mDispatcher("LLLoginInstance", "change")
+	mDispatcher("LLLoginInstance", "change"),
+	mUpdaterService(0)
 {
 	mLoginModule->getEventPump().listen("lllogininstance", 
 		boost::bind(&LLLoginInstance::handleLoginEvent, this, _1));
@@ -149,6 +554,7 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
 	requested_options.append("newuser-config");
 	requested_options.append("ui-config");
 #endif
+	requested_options.append("max-agent-groups");	
 	requested_options.append("map-server-url");	
 	requested_options.append("voice-config");
 	requested_options.append("tutorial_setting");
@@ -181,9 +587,10 @@ void LLLoginInstance::constructAuthParams(LLPointer<LLCredential> user_credentia
 	request_params["read_critical"] = false; // handleTOSResponse
 	request_params["last_exec_event"] = mLastExecEvent;
 	request_params["mac"] = hashed_unique_id_string;
-	request_params["version"] = gCurrentVersion; // Includes channel name
-	request_params["channel"] = gSavedSettings.getString("VersionChannelName");
+	request_params["version"] = LLVersionInfo::getChannelAndVersion(); // Includes channel name
+	request_params["channel"] = LLVersionInfo::getChannel();
 	request_params["id0"] = mSerialNumber;
+	request_params["host_id"] = gSavedSettings.getString("HostID");
 
 	mRequestData.clear();
 	mRequestData["method"] = "login_to_simulator";
@@ -351,6 +758,15 @@ bool LLLoginInstance::handleTOSResponse(bool accepted, const std::string& key)
 
 void LLLoginInstance::updateApp(bool mandatory, const std::string& auth_msg)
 {
+	if(mandatory)
+	{
+		gViewerWindow->setShowProgress(false);
+		MandatoryUpdateMachine * machine = new MandatoryUpdateMachine(*this, *mUpdaterService);
+		mUpdateStateMachine.reset(machine);
+		machine->start();
+		return;
+	}
+	
 	// store off config state, as we might quit soon
 	gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);	
 	LLUIColorTable::instance().saveUserSettings();
diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h
index 159e05046c40767c01fc8a75bfb4d8025b044fad..b872d7d1b1a417b2e78025e4ba7f9aa2f34a4e6f 100644
--- a/indra/newview/lllogininstance.h
+++ b/indra/newview/lllogininstance.h
@@ -34,12 +34,15 @@
 class LLLogin;
 class LLEventStream;
 class LLNotificationsInterface;
+class LLUpdaterService;
 
 // This class hosts the login module and is used to 
 // negotiate user authentication attempts.
 class LLLoginInstance : public LLSingleton<LLLoginInstance>
 {
 public:
+	class Disposable;
+
 	LLLoginInstance();
 	~LLLoginInstance();
 
@@ -75,6 +78,7 @@ class LLLoginInstance : public LLSingleton<LLLoginInstance>
 	typedef boost::function<void()> UpdaterLauncherCallback;
 	void setUpdaterLauncher(const UpdaterLauncherCallback& ulc) { mUpdaterLauncher = ulc; }
 
+	void setUpdaterService(LLUpdaterService * updaterService) { mUpdaterService = updaterService; }
 private:
 	void constructAuthParams(LLPointer<LLCredential> user_credentials);
 	void updateApp(bool mandatory, const std::string& message);
@@ -104,6 +108,8 @@ class LLLoginInstance : public LLSingleton<LLLoginInstance>
 	int mLastExecEvent;
 	UpdaterLauncherCallback mUpdaterLauncher;
 	LLEventDispatcher mDispatcher;
+	LLUpdaterService * mUpdaterService;	
+	boost::scoped_ptr<Disposable> mUpdateStateMachine;
 };
 
 #endif
diff --git a/indra/newview/llmainlooprepeater.cpp b/indra/newview/llmainlooprepeater.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5c020e6d982eb7060b857a800f36b4d050f87f25
--- /dev/null
+++ b/indra/newview/llmainlooprepeater.cpp
@@ -0,0 +1,88 @@
+/** 
+ * @file llmachineid.cpp
+ * @brief retrieves unique machine ids
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llapr.h"
+#include "llevents.h"
+#include "llmainlooprepeater.h"
+
+
+
+// LLMainLoopRepeater
+//-----------------------------------------------------------------------------
+
+
+LLMainLoopRepeater::LLMainLoopRepeater(void):
+	mQueue(0)
+{
+	; // No op.
+}
+
+
+void LLMainLoopRepeater::start(void)
+{
+	if(mQueue != 0) return;
+
+	mQueue = new LLThreadSafeQueue<LLSD>(gAPRPoolp, 1024);
+	mMainLoopConnection = LLEventPumps::instance().
+		obtain("mainloop").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMainLoop, this, _1));
+	mRepeaterConnection = LLEventPumps::instance().
+		obtain("mainlooprepeater").listen(LLEventPump::inventName(), boost::bind(&LLMainLoopRepeater::onMessage, this, _1));
+}
+
+
+void LLMainLoopRepeater::stop(void)
+{
+	mMainLoopConnection.release();
+	mRepeaterConnection.release();
+
+	delete mQueue;
+	mQueue = 0;
+}
+
+
+bool LLMainLoopRepeater::onMainLoop(LLSD const &)
+{
+	LLSD message;
+	while(mQueue->tryPopBack(message)) {
+		std::string pump = message["pump"].asString();
+		if(pump.length() == 0 ) continue; // No pump.
+		LLEventPumps::instance().obtain(pump).post(message["payload"]);
+	}
+	return false;
+}
+
+
+bool LLMainLoopRepeater::onMessage(LLSD const & event)
+{
+	try {
+		mQueue->pushFront(event);
+	} catch(LLThreadSafeQueueError & e) {
+		llwarns << "could not repeat message (" << e.what() << ")" << 
+			event.asString() << LL_ENDL;
+	}
+	return false;
+}
diff --git a/indra/newview/llmainlooprepeater.h b/indra/newview/llmainlooprepeater.h
new file mode 100644
index 0000000000000000000000000000000000000000..f84c0ca94c2d1b4c812533d655e689a357c275a8
--- /dev/null
+++ b/indra/newview/llmainlooprepeater.h
@@ -0,0 +1,65 @@
+/** 
+ * @file llmainlooprepeater.h
+ * @brief a service for repeating messages on the main loop.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLMAINLOOPREPEATER_H
+#define LL_LLMAINLOOPREPEATER_H
+
+
+#include "llsd.h"
+#include "llthreadsafequeue.h"
+
+
+//
+// A service which creates the pump 'mainlooprepeater' to which any thread can
+// post a message that will be re-posted on the main loop.
+//
+// The posted message should contain two map elements: pump and payload.  The
+// pump value is a string naming the pump to which the message should be
+// re-posted.  The payload value is what will be posted to the designated pump.
+//
+class LLMainLoopRepeater:
+	public LLSingleton<LLMainLoopRepeater>
+{
+public:
+	LLMainLoopRepeater(void);
+	
+	// Start the repeater service.
+	void start(void);
+	
+	// Stop the repeater service.
+	void stop(void);
+	
+private:
+	LLTempBoundListener mMainLoopConnection;
+	LLTempBoundListener mRepeaterConnection;
+	LLThreadSafeQueue<LLSD> * mQueue;
+	
+	bool onMainLoop(LLSD const &);
+	bool onMessage(LLSD const & event);
+};
+
+
+#endif
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 5eb3b789f2656991e8bd7a92fd66b7970bb06f98..f871df0c36cc787abe6a9081f33961f4e16512e3 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -726,7 +726,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 				LLVector3d new_position_global = selectNode->mSavedPositionGlobal + clamped_relative_move;
 
 				// Don't let object centers go too far underground
-				F64 min_height = LLWorld::getInstance()->getMinAllowedZ(object);
+				F64 min_height = LLWorld::getInstance()->getMinAllowedZ(object, object->getPositionGlobal());
 				if (new_position_global.mdV[VZ] < min_height)
 				{
 					new_position_global.mdV[VZ] = min_height;
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index e84c9152b107144166cc386ca576c9a7e21b2c57..9493fddf5044107e0aa502e02ffeea1b967737e8 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -25,7 +25,7 @@
  */
 
 #include "llviewerprecompiledheaders.h"
-
+#include "lltooltip.h"
 
 #include "llmediactrl.h"
 
@@ -54,6 +54,10 @@
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
 #include "llnotifications.h"
+#include "lllineeditor.h"
+#include "llfloatermediabrowser.h"
+#include "llfloaterwebcontent.h"
+#include "llwindowshade.h"
 
 extern BOOL gRestoreGL;
 
@@ -70,7 +74,8 @@ LLMediaCtrl::Params::Params()
 	caret_color("caret_color"),
 	initial_mime_type("initial_mime_type"),
 	media_id("media_id"),
-	trusted_content("trusted_content", false)
+	trusted_content("trusted_content", false),
+	focus_on_click("focus_on_click", true)
 {
 	tab_stop(false);
 }
@@ -86,7 +91,7 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
 	mIgnoreUIScale( true ),
 	mAlwaysRefresh( false ),
 	mMediaSource( 0 ),
-	mTakeFocusOnClick( true ),
+	mTakeFocusOnClick( p.focus_on_click ),
 	mCurrentNavUrl( "" ),
 	mStretchToFill( true ),
 	mMaintainAspectRatio ( true ),
@@ -97,7 +102,9 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
 	mTextureHeight ( 1024 ),
 	mClearCache(false),
 	mHomePageMimeType(p.initial_mime_type),
-	mTrusted(p.trusted_content)
+	mTrusted(p.trusted_content),
+	mWindowShade(NULL),
+	mHoverTextChanged(false)
 {
 	{
 		LLColor4 color = p.caret_color().get();
@@ -126,7 +133,7 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
 		setTextureSize(screen_width, screen_height);
 	}
 	
-	mMediaTextureID.generate();
+	mMediaTextureID = getKey();
 	
 	// We don't need to create the media source up front anymore unless we have a non-empty home URL to navigate to.
 	if(!mHomePageUrl.empty())
@@ -140,8 +147,6 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
 //	addChild( mBorder );
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// note: this is now a singleton and destruction happens via initClass() now
 LLMediaCtrl::~LLMediaCtrl()
 {
 
@@ -181,6 +186,13 @@ BOOL LLMediaCtrl::handleHover( S32 x, S32 y, MASK mask )
 		mMediaSource->mouseMove(x, y, mask);
 		gViewerWindow->setCursor(mMediaSource->getLastSetCursor());
 	}
+	
+	// TODO: Is this the right way to handle hover text changes driven by the plugin?
+	if(mHoverTextChanged)
+	{
+		mHoverTextChanged = false;
+		handleToolTip(x, y, mask);
+	}
 
 	return TRUE;
 }
@@ -196,6 +208,35 @@ BOOL LLMediaCtrl::handleScrollWheel( S32 x, S32 y, S32 clicks )
 	return TRUE;
 }
 
+////////////////////////////////////////////////////////////////////////////////
+//	virtual 
+BOOL LLMediaCtrl::handleToolTip(S32 x, S32 y, MASK mask)
+{
+	std::string hover_text;
+	
+	if (mMediaSource && mMediaSource->hasMedia())
+		hover_text = mMediaSource->getMediaPlugin()->getHoverText();
+	
+	if(hover_text.empty())
+	{
+		return FALSE;
+	}
+	else
+	{
+		S32 screen_x, screen_y;
+
+		localPointToScreen(x, y, &screen_x, &screen_y);
+		LLRect sticky_rect_screen;
+		sticky_rect_screen.setCenterAndSize(screen_x, screen_y, 20, 20);
+
+		LLToolTipMgr::instance().show(LLToolTip::Params()
+			.message(hover_text)
+			.sticky_rect(sticky_rect_screen));		
+	}
+
+	return TRUE;
+}
+
 ////////////////////////////////////////////////////////////////////////////////
 //
 BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )
@@ -206,14 +247,6 @@ BOOL LLMediaCtrl::handleMouseUp( S32 x, S32 y, MASK mask )
 	if (mMediaSource)
 	{
 		mMediaSource->mouseUp(x, y, mask);
-
-		// *HACK: LLMediaImplLLMozLib automatically takes focus on mouseup,
-		// in addition to the onFocusReceived() call below.  Undo this. JC
-		if (!mTakeFocusOnClick)
-		{
-			mMediaSource->focus(false);
-			gViewerWindow->focusClient();
-		}
 	}
 	
 	gFocusMgr.setMouseCapture( NULL );
@@ -345,85 +378,6 @@ void LLMediaCtrl::onFocusLost()
 //
 BOOL LLMediaCtrl::postBuild ()
 {
-	LLLayoutStack::Params layout_p;
-	layout_p.name = "notification_stack";
-	layout_p.rect = LLRect(0,getLocalRect().mTop,getLocalRect().mRight, 30);
-	layout_p.follows.flags = FOLLOWS_ALL;
-	layout_p.mouse_opaque = false;
-	layout_p.orientation = "vertical";
-
-	LLLayoutStack* stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p);
-	addChild(stackp);
-
-	LLLayoutPanel::Params panel_p;
-	panel_p.rect = LLRect(0, 30, 800, 0);
-	panel_p.min_height = 30;
-	panel_p.name = "notification_area";
-	panel_p.visible = false;
-	panel_p.user_resize = false;
-	panel_p.background_visible = true;
-	panel_p.bg_alpha_image.name = "Yellow_Gradient";
-	panel_p.auto_resize = false;
-	LLLayoutPanel* notification_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
-	stackp->addChild(notification_panel);
-
-	panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
-	panel_p.auto_resize = true;
-	panel_p.mouse_opaque = false;
-	LLLayoutPanel* dummy_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
-	stackp->addChild(dummy_panel);
-
-	layout_p = LLUICtrlFactory::getDefaultParams<LLLayoutStack>();
-	layout_p.rect = LLRect(0, 30, 800, 0);
-	layout_p.follows.flags = FOLLOWS_ALL;
-	layout_p.orientation = "horizontal";
-	stackp = LLUICtrlFactory::create<LLLayoutStack>(layout_p);
-	notification_panel->addChild(stackp);
-
-	panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
-	panel_p.rect.height = 30;
-	LLLayoutPanel* panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
-	stackp->addChild(panel);
-
-	LLIconCtrl::Params icon_p;
-	icon_p.name = "notification_icon";
-	icon_p.rect = LLRect(5, 23, 21, 8);
-	panel->addChild(LLUICtrlFactory::create<LLIconCtrl>(icon_p));
-
-	LLTextBox::Params text_p;
-	text_p.rect = LLRect(31, 20, 430, 0);
-	text_p.text_color = LLColor4::black;
-	text_p.font = LLFontGL::getFontSansSerif();
-	text_p.font.style = "BOLD";
-	text_p.name = "notification_text";
-	text_p.use_ellipses = true;
-	panel->addChild(LLUICtrlFactory::create<LLTextBox>(text_p));
-
-	panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
-	panel_p.auto_resize = false;
-	panel_p.user_resize = false;
-	panel_p.name="form_elements";
-	panel_p.rect = LLRect(0, 30, 130, 0);
-	LLLayoutPanel* form_elements_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
-	stackp->addChild(form_elements_panel);
-
-	panel_p = LLUICtrlFactory::getDefaultParams<LLLayoutPanel>();
-	panel_p.auto_resize = false;
-	panel_p.user_resize = false;
-	panel_p.rect = LLRect(0, 30, 25, 0);
-	LLLayoutPanel* close_panel = LLUICtrlFactory::create<LLLayoutPanel>(panel_p);
-	stackp->addChild(close_panel);
-
-	LLButton::Params button_p;
-	button_p.name = "close_notification";
-	button_p.rect = LLRect(5, 23, 21, 7);
-	button_p.image_color=LLUIColorTable::instance().getColor("DkGray_66");
-    button_p.image_unselected.name="Icon_Close_Foreground";
-	button_p.image_selected.name="Icon_Close_Press";
-	button_p.click_callback.function = boost::bind(&LLMediaCtrl::onCloseNotification, this);
-
-	close_panel->addChild(LLUICtrlFactory::create<LLButton>(button_p));
-
 	setVisibleCallback(boost::bind(&LLMediaCtrl::onVisibilityChange, this, _2));
 	return TRUE;
 }
@@ -432,13 +386,15 @@ BOOL LLMediaCtrl::postBuild ()
 //
 BOOL LLMediaCtrl::handleKeyHere( KEY key, MASK mask )
 {
-	if (LLPanel::handleKeyHere(key, mask)) return TRUE;
 	BOOL result = FALSE;
 	
 	if (mMediaSource)
 	{
 		result = mMediaSource->handleKeyHere(key, mask);
 	}
+	
+	if ( ! result )
+		result = LLPanel::handleKeyHere(key, mask);
 		
 	return result;
 }
@@ -458,7 +414,6 @@ void LLMediaCtrl::handleVisibilityChange ( BOOL new_visibility )
 //
 BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)
 {
-	if (LLPanel::handleUnicodeCharHere(uni_char)) return TRUE;
 	BOOL result = FALSE;
 	
 	if (mMediaSource)
@@ -466,6 +421,9 @@ BOOL LLMediaCtrl::handleUnicodeCharHere(llwchar uni_char)
 		result = mMediaSource->handleUnicodeCharHere(uni_char);
 	}
 
+	if ( ! result )
+		result = LLPanel::handleUnicodeCharHere(uni_char);
+
 	return result;
 }
 
@@ -921,11 +879,6 @@ void LLMediaCtrl::draw()
 	if ( mBorder && mBorder->getVisible() )
 		mBorder->setKeyboardFocusHighlight( gFocusMgr.childHasKeyboardFocus( this ) );
 
-	if (mCurNotification && !mCurNotification->isActive())
-	{
-		hideNotification();
-	}
-	
 	LLPanel::draw();
 
 	// Restore the previous values
@@ -1033,7 +986,7 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 
 			LLNotification::Params notify_params;
 			notify_params.name = "PopupAttempt";
-			notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", getKey());
+			notify_params.payload = LLSD().with("target", target).with("url", url).with("uuid", uuid).with("media_id", mMediaTextureID);
 			notify_params.functor.function = boost::bind(&LLMediaCtrl::onPopup, this, _1, _2);
 
 			if (mTrusted)
@@ -1088,6 +1041,31 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 			LL_DEBUGS("Media") << "Media event:  MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL;
 		}
 		break;
+
+		case MEDIA_EVENT_AUTH_REQUEST:
+		{
+			LLNotification::Params auth_request_params;
+			auth_request_params.name = "AuthRequest";
+
+			// pass in host name and realm for site (may be zero length but will always exist)
+			LLSD args;
+			LLURL raw_url( self->getAuthURL().c_str() );
+			args["HOST_NAME"] = raw_url.getAuthority();
+			args["REALM"] = self->getAuthRealm();
+			auth_request_params.substitutions = args;
+
+			auth_request_params.payload = LLSD().with("media_id", mMediaTextureID);
+			auth_request_params.functor.function = boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2);
+			LLNotifications::instance().add(auth_request_params);
+		};
+		break;
+
+		case MEDIA_EVENT_LINK_HOVERED:
+		{
+			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << LL_ENDL;
+			mHoverTextChanged = true;
+		};
+		break;
 	};
 
 	// chain all events to any potential observers of this object.
@@ -1105,109 +1083,85 @@ void LLMediaCtrl::onPopup(const LLSD& notification, const LLSD& response)
 {
 	if (response["open"])
 	{
-		LLWeb::loadURL(notification["payload"]["url"], notification["payload"]["target"], notification["payload"]["uuid"]);
+		// name of default floater to open
+		std::string floater_name = "media_browser";
+
+		// look for parent floater name
+		if ( gFloaterView )
+		{
+			if ( gFloaterView->getParentFloater(this) )
+			{
+				floater_name = gFloaterView->getParentFloater(this)->getInstanceName();
+			}
+			else
+			{
+				lldebugs << "No gFloaterView->getParentFloater(this) for onPopuup()" << llendl;
+			};
+		}
+		else
+		{
+			lldebugs << "No gFloaterView for onPopuup()" << llendl;
+		};
+
+		// (for now) open web content floater if that's our parent, otherwise, open the current media floater
+		// (this will change soon)
+		if ( floater_name == "web_content" )
+		{
+			LLWeb::loadWebURL(notification["payload"]["url"], notification["payload"]["target"], notification["payload"]["uuid"]);
+		}
+		else
+		{
+			LLWeb::loadURL(notification["payload"]["url"], notification["payload"]["target"], notification["payload"]["uuid"]);
+		}
 	}
 	else
 	{
 		// Make sure the opening instance knows its window open request was denied, so it can clean things up.
 		LLViewerMedia::proxyWindowClosed(notification["payload"]["uuid"]);
 	}
-
 }
 
-void LLMediaCtrl::onCloseNotification()
-{
-	LLNotifications::instance().cancel(mCurNotification);
-}
-
-void LLMediaCtrl::onClickIgnore(LLUICtrl* ctrl)
+void LLMediaCtrl::showNotification(LLNotificationPtr notify)
 {
-	bool check = ctrl->getValue().asBoolean();
-	if (mCurNotification && mCurNotification->getForm()->getIgnoreType() == LLNotificationForm::IGNORE_SHOW_AGAIN)
+	delete mWindowShade;
+
+	LLWindowShade::Params params;
+	params.name = "notification_shade";
+	params.rect = getLocalRect();
+	params.follows.flags = FOLLOWS_ALL;
+	params.notification = notify;
+	params.modal = true;
+	//HACK: don't hardcode this
+	if (notify->getIcon() == "Popup_Caution")
 	{
-		// question was "show again" so invert value to get "ignore"
-		check = !check;
+		params.bg_image.name = "Yellow_Gradient";
+		params.text_color = LLColor4::black;
 	}
-	mCurNotification->setIgnored(check);
-}
-
-void LLMediaCtrl::onClickNotificationButton(const std::string& name)
-{
-	if (!mCurNotification) return;
-
-	LLSD response = mCurNotification->getResponseTemplate();
-	response[name] = true;
-
-	mCurNotification->respond(response); 
-}
-
-void LLMediaCtrl::showNotification(LLNotificationPtr notify)
-{
-	mCurNotification = notify;
-
-	// add popup here
-	LLSD payload = notify->getPayload();
-
-	LLNotificationFormPtr formp = notify->getForm();
-	LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area");
-	panel.setVisible(true);
-	panel.getChild<LLUICtrl>("notification_icon")->setValue(notify->getIcon());
-	panel.getChild<LLUICtrl>("notification_text")->setValue(notify->getMessage());
-	panel.getChild<LLUICtrl>("notification_text")->setToolTip(notify->getMessage());
-	LLNotificationForm::EIgnoreType ignore_type = formp->getIgnoreType(); 
-	LLLayoutPanel& form_elements = panel.getChildRef<LLLayoutPanel>("form_elements");
-	form_elements.deleteAllChildren();
-
-	const S32 FORM_PADDING_HORIZONTAL = 10;
-	const S32 FORM_PADDING_VERTICAL = 3;
-	S32 cur_x = FORM_PADDING_HORIZONTAL;
-
-	if (ignore_type != LLNotificationForm::IGNORE_NO)
+	else
+	//HACK: another one since XUI doesn't support what we need right now
+	if (notify->getName() == "AuthRequest")
 	{
-		LLCheckBoxCtrl::Params checkbox_p;
-		checkbox_p.name = "ignore_check";
-		checkbox_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL);
-		checkbox_p.label = formp->getIgnoreMessage();
-		checkbox_p.label_text.text_color = LLColor4::black;
-		checkbox_p.commit_callback.function = boost::bind(&LLMediaCtrl::onClickIgnore, this, _1);
-		checkbox_p.initial_value = formp->getIgnored();
-
-		LLCheckBoxCtrl* check = LLUICtrlFactory::create<LLCheckBoxCtrl>(checkbox_p);
-		check->setRect(check->getBoundingRect());
-		form_elements.addChild(check);
-		cur_x = check->getRect().mRight + FORM_PADDING_HORIZONTAL;
+		params.bg_image.name = "Yellow_Gradient";
+		params.text_color = LLColor4::black;
+		params.can_close = false;
 	}
-
-	for (S32 i = 0; i < formp->getNumElements(); i++)
+	else
 	{
-		LLSD form_element = formp->getElement(i);
-		if (form_element["type"].asString() == "button")
-		{
-			LLButton::Params button_p;
-			button_p.name = form_element["name"];
-			button_p.label = form_element["text"];
-			button_p.rect = LLRect(cur_x, form_elements.getRect().getHeight() - FORM_PADDING_VERTICAL, cur_x, FORM_PADDING_VERTICAL);
-			button_p.click_callback.function = boost::bind(&LLMediaCtrl::onClickNotificationButton, this, form_element["name"].asString());
-			button_p.auto_resize = true;
-
-			LLButton* button = LLUICtrlFactory::create<LLButton>(button_p);
-			button->autoResize();
-			form_elements.addChild(button);
-
-			cur_x = button->getRect().mRight + FORM_PADDING_HORIZONTAL;
-		}
+		//HACK: make this a property of the notification itself, "cancellable"
+		params.can_close = false;
+		params.text_color.control = "LabelTextColor";
 	}
 
+	mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
 
-	form_elements.reshape(cur_x, form_elements.getRect().getHeight());
-
-	//LLWeb::loadURL(payload["url"], payload["target"]);
+	addChild(mWindowShade);
+	mWindowShade->show();
 }
 
 void LLMediaCtrl::hideNotification()
 {
-	LLLayoutPanel& panel = getChildRef<LLLayoutPanel>("notification_area");
-	panel.setVisible(FALSE);
-
-	mCurNotification.reset();
+	if (mWindowShade)
+	{
+		mWindowShade->hide();
+	}
 }
diff --git a/indra/newview/llmediactrl.h b/indra/newview/llmediactrl.h
index 65dfbbff7864732ad2df9a2523b5198f6671aaee..38a74f90d3cf6a2ed5040ced04d1e78bc2ce44d0 100644
--- a/indra/newview/llmediactrl.h
+++ b/indra/newview/llmediactrl.h
@@ -53,7 +53,8 @@ class LLMediaCtrl :
 								ignore_ui_scale,
 								hide_loading,
 								decouple_texture_size,
-								trusted_content;
+								trusted_content,
+								focus_on_click;
 								
 		Optional<S32>			texture_width,
 								texture_height;
@@ -89,6 +90,7 @@ class LLMediaCtrl :
 		virtual BOOL handleRightMouseUp(S32 x, S32 y, MASK mask);
 		virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
 		virtual BOOL handleScrollWheel( S32 x, S32 y, S32 clicks );
+		virtual BOOL handleToolTip(S32 x, S32 y, MASK mask);
 
 		// navigation
 		void navigateTo( std::string url_in, std::string mime_type = "");
@@ -167,9 +169,6 @@ class LLMediaCtrl :
 	private:
 		void onVisibilityChange ( const LLSD& new_visibility );
 		void onPopup(const LLSD& notification, const LLSD& response);
-		void onCloseNotification();
-		void onClickNotificationButton(const std::string& name);
-		void onClickIgnore(LLUICtrl* ctrl);
 
 		const S32 mTextureDepthBytes;
 		LLUUID mMediaTextureID;
@@ -193,7 +192,8 @@ class LLMediaCtrl :
 		S32 mTextureWidth;
 		S32 mTextureHeight;
 		bool mClearCache;
-		boost::shared_ptr<class LLNotification> mCurNotification;
+		class LLWindowShade* mWindowShade;
+		bool mHoverTextChanged;
 };
 
 #endif // LL_LLMediaCtrl_H
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 6658e1d7e89b6eefeae012e711ad50ed616a4b6d..142ee40cc8a5cde68584b988ce5dea40753e8558 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -94,6 +94,7 @@ BOOL LLFloaterMove::postBuild()
 {
 	setIsChrome(TRUE);
 	setTitleVisible(TRUE); // restore title visibility after chrome applying
+	updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)
 	
 	LLDockableFloater::postBuild();
 	
@@ -448,17 +449,20 @@ void LLFloaterMove::updatePosition()
 	LLBottomTray* tray = LLBottomTray::getInstance();
 	if (!tray) return;
 
-	LLButton* movement_btn = tray->getChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME);
+	LLButton* movement_btn = tray->findChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME);
 
-	//align centers of a button and a floater
-	S32 x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2;
-
-	S32 y = 0;
-	if (!mModeActionsPanel->getVisible())
+	if (movement_btn)
 	{
-		y = mModeActionsPanel->getRect().getHeight();
+		//align centers of a button and a floater
+		S32 x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2;
+
+		S32 y = 0;
+		if (!mModeActionsPanel->getVisible())
+		{
+			y = mModeActionsPanel->getRect().getHeight();
+		}
+		setOrigin(x, y);
 	}
-	setOrigin(x, y);
 }
 
 //static
@@ -552,7 +556,7 @@ LLPanelStandStopFlying::LLPanelStandStopFlying() :
 }
 
 // static
-inline LLPanelStandStopFlying* LLPanelStandStopFlying::getInstance()
+LLPanelStandStopFlying* LLPanelStandStopFlying::getInstance()
 {
 	static LLPanelStandStopFlying* panel = getStandStopFlyingPanel();
 	return panel;
@@ -735,10 +739,18 @@ void LLPanelStandStopFlying::updatePosition()
 	LLBottomTray* tray = LLBottomTray::getInstance();
 	if (!tray || mAttached) return;
 
-	LLButton* movement_btn = tray->getChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME);
+	LLButton* movement_btn = tray->findChild<LLButton>(BOTTOM_TRAY_BUTTON_NAME);
 
-	// Align centers of the button and the panel.
-	S32 x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2;
+	S32 x = 0;
+	if (movement_btn)
+	{
+		// Align centers of the button and the panel.
+		x = movement_btn->calcScreenRect().getCenterX() - getRect().getWidth()/2;
+	}
+	else
+	{
+		x = tray->calcScreenRect().getCenterX() - getRect().getWidth()/2;
+	}
 	setOrigin(x, 0);
 }
 
diff --git a/indra/newview/llnavigationbar.cpp b/indra/newview/llnavigationbar.cpp
index 58849393b40ab5aca3f3cc5a39733def909426eb..e4f83ce6b99495bfced31e95fd0ed987e93d5920 100644
--- a/indra/newview/llnavigationbar.cpp
+++ b/indra/newview/llnavigationbar.cpp
@@ -276,9 +276,6 @@ LLNavigationBar::LLNavigationBar()
 
 	// set a listener function for LoginComplete event
 	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLNavigationBar::handleLoginComplete, this));
-
-	// Necessary for focus movement among child controls
-	setFocusRoot(TRUE);
 }
 
 LLNavigationBar::~LLNavigationBar()
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
index 180695e40bb7b136c5330c9ffbcb5f8a1e1269f5..572eeb8fc7702c0ae437524b3d6565cb854e9cf4 100644
--- a/indra/newview/llnearbychat.cpp
+++ b/indra/newview/llnearbychat.cpp
@@ -365,3 +365,16 @@ BOOL	LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
 		mChatHistory->setFocus(TRUE);
 	return LLDockableFloater::handleMouseDown(x, y, mask);
 }
+
+void LLNearbyChat::draw()
+{
+	// *HACK: Update transparency type depending on whether our children have focus.
+	// This is needed because this floater is chrome and thus cannot accept focus, so
+	// the transparency type setting code from LLFloater::setFocus() isn't reached.
+	if (getTransparencyType() != TT_DEFAULT)
+	{
+		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
+	}
+
+	LLDockableFloater::draw();
+}
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
index 1e62910385f7238f38c6a932e1f83e25e812a295..2ea79797f8e338c32fc57b77b47f70cc039634f1 100644
--- a/indra/newview/llnearbychat.h
+++ b/indra/newview/llnearbychat.h
@@ -48,6 +48,7 @@ class LLNearbyChat: public LLDockableFloater
 	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata);
 
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
+	virtual void	draw();
 
 	// focus overrides
 	/*virtual*/ void	onFocusLost();
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index 932ad75f298d43486d76b9c0d634b6d81c526c3d..836ae9a0cfc49f7cbf88e0a214c0041828387736 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -94,15 +94,19 @@ class LLGestureScrollListCtrl: public LLScrollListCtrl
 
 LLGestureComboList::Params::Params()
 :	combo_button("combo_button"),
-	combo_list("combo_list")
+	combo_list("combo_list"),
+	get_more("get_more", true),
+	view_all("view_all", true)
 {
 }
 
 LLGestureComboList::LLGestureComboList(const LLGestureComboList::Params& p)
-:	LLUICtrl(p)
-	, mLabel(p.label)
-	, mViewAllItemIndex(0)
-	, mGetMoreItemIndex(0)
+:	LLUICtrl(p),
+	mLabel(p.label),
+	mViewAllItemIndex(-1),
+	mGetMoreItemIndex(-1),
+	mShowViewAll(p.view_all),
+	mShowGetMore(p.get_more)
 {
 	LLBottomtrayButton::Params button_params = p.combo_button;
 	button_params.follows.flags(FOLLOWS_LEFT|FOLLOWS_BOTTOM|FOLLOWS_RIGHT);
@@ -286,12 +290,16 @@ void LLGestureComboList::refreshGestures()
 	sortByName();
 
 	// store indices for Get More and View All items (idx is the index followed by the last added Gesture)
-	mGetMoreItemIndex = idx;
-	mViewAllItemIndex = idx + 1;
-
-	// add Get More and View All items at the bottom
-	mList->addSimpleElement(LLTrans::getString("GetMoreGestures"), ADD_BOTTOM, LLSD(mGetMoreItemIndex));
-	mList->addSimpleElement(LLTrans::getString("ViewAllGestures"), ADD_BOTTOM, LLSD(mViewAllItemIndex));
+	if (mShowGetMore)
+	{
+		mGetMoreItemIndex = idx;
+		mList->addSimpleElement(LLTrans::getString("GetMoreGestures"), ADD_BOTTOM, LLSD(mGetMoreItemIndex));
+	}
+	if (mShowViewAll)
+	{
+		mViewAllItemIndex = idx + 1;
+		mList->addSimpleElement(LLTrans::getString("ViewAllGestures"), ADD_BOTTOM, LLSD(mViewAllItemIndex));
+	}
 
 	// Insert label after sorting, at top, with separator below it
 	mList->addSeparator(ADD_TOP);	
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llnearbychatbar.h
index cc905736fd315ebe9f6ad479752137845618228e..033d1dd5a2c8d1962d23fb210888fad8774b5223 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llnearbychatbar.h
@@ -46,6 +46,8 @@ class LLGestureComboList
 	{
 		Optional<LLBottomtrayButton::Params>			combo_button;
 		Optional<LLScrollListCtrl::Params>	combo_list;
+		Optional<bool>						get_more,
+											view_all;
 		
 		Params();
 	};
@@ -56,6 +58,8 @@ class LLGestureComboList
 	LLGestureComboList(const Params&);
 	std::vector<LLMultiGesture*> mGestures;
 	std::string mLabel;
+	bool			mShowViewAll;
+	bool			mShowGetMore;
 	LLSD::Integer mViewAllItemIndex;
 	LLSD::Integer mGetMoreItemIndex;
 
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llnearbychathandler.cpp
index d2ad78f140cc3ae7911b754d656adedf851fc277..cebfac86e71effb2e97234041aeb6a07c977c003 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llnearbychathandler.cpp
@@ -121,7 +121,7 @@ class LLNearbyChatScreenChannel: public LLScreenChannelBase
 		if (!toast) return;
 		LL_DEBUGS("NearbyChat") << "Pooling toast" << llendl;
 		toast->setVisible(FALSE);
-		toast->stopFading();
+		toast->stopTimer();
 		toast->setIsHidden(true);
 
 		// Nearby chat toasts that are hidden, not destroyed. They are collected to the toast pool, so that
@@ -296,7 +296,7 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
 			{
 				panel->addMessage(notification);
 				toast->reshapeToPanel();
-				toast->startFading();
+				toast->startTimer();
 	  
 				arrangeToasts();
 				return;
@@ -341,7 +341,7 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
 	panel->init(notification);
 
 	toast->reshapeToPanel();
-	toast->startFading();
+	toast->startTimer();
 	
 	m_active_toasts.push_back(toast->getHandle());
 
@@ -382,7 +382,10 @@ void LLNearbyChatScreenChannel::showToastsBottom()
 		return;
 
 	LLRect	toast_rect;	
-	S32		bottom = getRect().mBottom;
+	updateBottom();
+	S32 channel_bottom = getRect().mBottom;
+
+	S32		bottom = channel_bottom;
 	S32		margin = gSavedSettings.getS32("ToastGap");
 
 	//sort active toasts
@@ -514,6 +517,14 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)
 	}
 
 	nearby_chat->addMessage(chat_msg, true, args);
+
+	if(chat_msg.mSourceType == CHAT_SOURCE_AGENT 
+		&& chat_msg.mFromID.notNull() 
+		&& chat_msg.mFromID != gAgentID)
+	{
+ 		LLFirstUse::otherAvatarChatFirst();
+	}
+
 	if( nearby_chat->getVisible()
 		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
 			&& gSavedSettings.getBOOL("UseChatBubbles") ) )
@@ -573,13 +584,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg, const LLSD &args)
 		notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
 		channel->addNotification(notification);	
 	}
-	
-	if(chat_msg.mSourceType == CHAT_SOURCE_AGENT 
-		&& chat_msg.mFromID.notNull() 
-		&& chat_msg.mFromID != gAgentID)
-	{
- 		LLFirstUse::otherAvatarChatFirst();
-	}
+
 }
 
 void LLNearbyChatHandler::onDeleteToast(LLToast* toast)
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 57180f63b5189cb4f3eb90e1321ffedb4177af7c..a9bcdef47cf93b70f13021e19742c43b26216e7e 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -34,6 +34,7 @@
 #include "llcombobox.h"
 #include "lldateutil.h"			// ageFromDate()
 #include "llimview.h"
+#include "llmenubutton.h"
 #include "llnotificationsutil.h"
 #include "lltexteditor.h"
 #include "lltexturectrl.h"
@@ -340,10 +341,11 @@ LLPanelAvatarNotes::~LLPanelAvatarNotes()
 	if(getAvatarId().notNull())
 	{
 		LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
-		if(LLVoiceClient::instanceExists())
-		{
-			LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
-		}
+	}
+
+	if(LLVoiceClient::instanceExists())
+	{
+		LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
 	}
 }
 
@@ -479,7 +481,6 @@ BOOL LLPanelAvatarProfile::postBuild()
 	childSetCommitCallback("im",(boost::bind(&LLPanelAvatarProfile::onIMButtonClick,this)),NULL);
 	childSetCommitCallback("call",(boost::bind(&LLPanelAvatarProfile::onCallButtonClick,this)),NULL);
 	childSetCommitCallback("teleport",(boost::bind(&LLPanelAvatarProfile::onTeleportButtonClick,this)),NULL);
-	childSetCommitCallback("overflow_btn", boost::bind(&LLPanelAvatarProfile::onOverflowButtonClicked, this), NULL);
 	childSetCommitCallback("share",(boost::bind(&LLPanelAvatarProfile::onShareButtonClick,this)),NULL);
 	childSetCommitCallback("show_on_map_btn", (boost::bind(
 			&LLPanelAvatarProfile::onMapButtonClick, this)), NULL);
@@ -500,7 +501,8 @@ BOOL LLPanelAvatarProfile::postBuild()
 	enable.add("Profile.EnableBlock", boost::bind(&LLPanelAvatarProfile::enableBlock, this));
 	enable.add("Profile.EnableUnblock", boost::bind(&LLPanelAvatarProfile::enableUnblock, this));
 
-	mProfileMenu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_profile_overflow.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	LLToggleableMenu* profile_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_profile_overflow.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	getChild<LLMenuButton>("overflow_btn")->setMenu(profile_menu, LLMenuButton::MP_TOP_RIGHT);
 
 	LLVoiceClient::getInstance()->addObserver((LLVoiceClientStatusObserver*)this);
 
@@ -752,32 +754,16 @@ void LLPanelAvatarProfile::onShareButtonClick()
 	//*TODO not implemented
 }
 
-void LLPanelAvatarProfile::onOverflowButtonClicked()
-{
-	if (!mProfileMenu->toggleVisibility())
-		return;
-
-	LLView* btn = getChild<LLView>("overflow_btn");
-
-	if (mProfileMenu->getButtonRect().isEmpty())
-	{
-		mProfileMenu->setButtonRect(btn);
-	}
-	mProfileMenu->updateParent(LLMenuGL::sMenuContainer);
-
-	LLRect rect = btn->getRect();
-	LLMenuGL::showPopup(this, mProfileMenu, rect.mRight, rect.mTop);
-}
-
 LLPanelAvatarProfile::~LLPanelAvatarProfile()
 {
 	if(getAvatarId().notNull())
 	{
 		LLAvatarTracker::instance().removeParticularFriendObserver(getAvatarId(), this);
-		if(LLVoiceClient::instanceExists())
-		{
-			LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
-		}
+	}
+
+	if(LLVoiceClient::instanceExists())
+	{
+		LLVoiceClient::getInstance()->removeObserver((LLVoiceClientStatusObserver*)this);
 	}
 }
 
diff --git a/indra/newview/llpanelavatar.h b/indra/newview/llpanelavatar.h
index 11c77163229b5e22e48943dbeed64dc8d06ad357..71d9d0a95a159ddac9e31bb1e71945bd63d36fca 100644
--- a/indra/newview/llpanelavatar.h
+++ b/indra/newview/llpanelavatar.h
@@ -34,7 +34,6 @@
 
 class LLComboBox;
 class LLLineEditor;
-class LLToggleableMenu;
 
 enum EOnlineStatus
 {
@@ -207,14 +206,11 @@ class LLPanelAvatarProfile
 	void onCallButtonClick();
 	void onTeleportButtonClick();
 	void onShareButtonClick();
-	void onOverflowButtonClicked();
 
 private:
 
 	typedef std::map< std::string,LLUUID>	group_map_t;
 	group_map_t 			mGroups;
-
-	LLToggleableMenu*		mProfileMenu;
 };
 
 /**
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index 87acd83b23bdd0d1bc88682bf47f0c4165817752..c57746ec00abe8a5f31992612fc18c1b1c8256ca 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -180,6 +180,9 @@ void LLPanelLandmarkInfo::setInfoType(EInfoType type)
 
 	populateFoldersList();
 
+	// Prevent the floater from losing focus (if the sidepanel is undocked).
+	setFocus(TRUE);
+
 	LLPanelPlaceInfo::setInfoType(type);
 }
 
@@ -330,6 +333,9 @@ void LLPanelLandmarkInfo::toggleLandmarkEditMode(BOOL enabled)
 		// when it was enabled/disabled we set the text once again.
 		mNotesEditor->setText(mNotesEditor->getText());
 	}
+
+	// Prevent the floater from losing focus (if the sidepanel is undocked).
+	setFocus(TRUE);
 }
 
 const std::string& LLPanelLandmarkInfo::getLandmarkTitle() const
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index d25b8e0e024e11f25754268dc6b10da5748d6346..e8c8273a9d038e0f64f143183bf9eda2a1eb4f27 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -520,9 +520,6 @@ void LLLandmarksPanel::setParcelID(const LLUUID& parcel_id)
 {
 	if (!parcel_id.isNull())
 	{
-        //ext-4655, defensive. remove now incase this gets called twice without a remove
-        LLRemoteParcelInfoProcessor::getInstance()->removeObserver(parcel_id, this);
-        
 		LLRemoteParcelInfoProcessor::getInstance()->addObserver(parcel_id, this);
 		LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(parcel_id);
 	}
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 467aefc60f44edae403d945663775025d1aa2e69..5f89097c1787c9f122d0adff740cee5af84e54c4 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -73,7 +73,6 @@
 #endif  // LL_WINDOWS
 
 #include "llsdserialize.h"
-#define USE_VIEWER_AUTH 0
 
 const S32 BLACK_BORDER_HEIGHT = 160;
 const S32 MAX_PASSWORD = 16;
@@ -163,8 +162,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 	mHtmlAvailable( TRUE ),
 	mListener(new LLPanelLoginListener(this))
 {
-	setFocusRoot(TRUE);
-
 	setBackgroundVisible(FALSE);
 	setBackgroundOpaque(TRUE);
 
@@ -181,18 +178,17 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 	mPasswordModified = FALSE;
 	LLPanelLogin::sInstance = this;
 
-	// add to front so we are the bottom-most child
-	gViewerWindow->getRootView()->addChildInBack(this);
+	LLView* login_holder = gViewerWindow->getLoginPanelHolder();
+	if (login_holder)
+	{
+		login_holder->addChild(this);
+	}
 
 	// Logo
 	mLogoImage = LLUI::getUIImage("startup_logo");
 
 	buildFromFile( "panel_login.xml");
 	
-#if USE_VIEWER_AUTH
-	//leave room for the login menu bar
-	setRect(LLRect(0, rect.getHeight()-18, rect.getWidth(), 0)); 
-#endif
 	// Legacy login web page is hidden under the menu bar.
 	// Adjust reg-in-client web browser widget to not be hidden.
 	if (gSavedSettings.getBOOL("RegInClient"))
@@ -204,16 +200,12 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 		reshape(rect.getWidth(), rect.getHeight());
 	}
 
-#if !USE_VIEWER_AUTH
 	getChild<LLLineEditor>("password_edit")->setKeystrokeCallback(onPassKey, this);
 
 	// change z sort of clickable text to be behind buttons
 	//sendChildToBack(getChildView("channel_text"));
 	sendChildToBack(getChildView("forgot_password_text"));
 
-	LLLineEditor* edit = getChild<LLLineEditor>("password_edit");
-	if (edit) edit->setDrawAsterixes(TRUE);
-
 	if(LLStartUp::getStartSLURL().getType() != LLSLURL::LOCATION)
 	{
 		LLSLURL slurl(gSavedSettings.getString("LoginLocation"));
@@ -230,7 +222,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 
 	getChild<LLPanel>("login")->setDefaultBtn("connect_btn");
 
-	std::string channel = gSavedSettings.getString("VersionChannelName");
+	std::string channel = LLVersionInfo::getChannel();
 	std::string version = llformat("%s (%d)",
 								   LLVersionInfo::getShortVersion().c_str(),
 								   LLVersionInfo::getBuild());
@@ -247,7 +239,6 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 
 	LLTextBox* need_help_text = getChild<LLTextBox>("login_help");
 	need_help_text->setClickedCallback(onClickHelp, NULL);
-#endif    
 	
 	// get the web browser control
 	LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
@@ -274,15 +265,9 @@ void LLPanelLogin::reshapeBrowser()
 	LLMediaCtrl* web_browser = getChild<LLMediaCtrl>("login_html");
 	LLRect rect = gViewerWindow->getWindowRectScaled();
 	LLRect html_rect;
-#if USE_VIEWER_AUTH
-	html_rect.setCenterAndSize( 
-		rect.getCenterX() - 2, rect.getCenterY(), 
-		rect.getWidth() + 6, rect.getHeight());
-#else
 	html_rect.setCenterAndSize(
 		rect.getCenterX() - 2, rect.getCenterY() + 40,
 		rect.getWidth() + 6, rect.getHeight() - 78 );
-#endif
 	web_browser->setRect( html_rect );
 	web_browser->reshape( html_rect.getWidth(), html_rect.getHeight(), TRUE );
 	reshape( rect.getWidth(), rect.getHeight(), 1 );
@@ -305,7 +290,6 @@ void LLPanelLogin::setSiteIsAlive( bool alive )
 	else
 	// the site is not available (missing page, server down, other badness)
 	{
-#if !USE_VIEWER_AUTH
 		if ( web_browser )
 		{
 			// hide browser control (revealing default one)
@@ -314,16 +298,6 @@ void LLPanelLogin::setSiteIsAlive( bool alive )
 			// mark as unavailable
 			mHtmlAvailable = FALSE;
 		}
-#else
-
-		if ( web_browser )
-		{	
-			web_browser->navigateToLocalPage( "loading-error" , "index.html" );
-
-			// mark as available
-			mHtmlAvailable = TRUE;
-		}
-#endif
 	}
 }
 
@@ -363,7 +337,6 @@ void LLPanelLogin::draw()
 
 		if ( mHtmlAvailable )
 		{
-#if !USE_VIEWER_AUTH
 			if (getChild<LLView>("login_widgets")->getVisible())
 			{
 				// draw a background box in black
@@ -372,7 +345,6 @@ void LLPanelLogin::draw()
 				// just the blue background to the native client UI
 				mLogoImage->draw(0, -264, width + 8, mLogoImage->getHeight());
 			}
-#endif
 		}
 		else
 		{
@@ -418,12 +390,6 @@ void LLPanelLogin::setFocus(BOOL b)
 // static
 void LLPanelLogin::giveFocus()
 {
-#if USE_VIEWER_AUTH
-	if (sInstance)
-	{
-		sInstance->setFocus(TRUE);
-	}
-#else
 	if( sInstance )
 	{
 		// Grab focus and move cursor to first blank input field
@@ -452,17 +418,18 @@ void LLPanelLogin::giveFocus()
 			edit->selectAll();
 		}
 	}
-#endif
 }
 
 // static
 void LLPanelLogin::showLoginWidgets()
 {
+	// *NOTE: Mani - This may or may not be obselete code.
+	// It seems to be part of the defunct? reg-in-client project.
 	sInstance->getChildView("login_widgets")->setVisible( true);
 	LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
 	sInstance->reshapeBrowser();
 	// *TODO: Append all the usual login parameters, like first_login=Y etc.
-	std::string splash_screen_url = sInstance->getString("real_url");
+	std::string splash_screen_url = LLGridManager::getInstance()->getLoginPage();
 	web_browser->navigateTo( splash_screen_url, "text/html" );
 	LLUICtrl* username_edit = sInstance->getChild<LLUICtrl>("username_edit");
 	username_edit->setFocus(TRUE);
@@ -761,7 +728,7 @@ void LLPanelLogin::closePanel()
 {
 	if (sInstance)
 	{
-		gViewerWindow->getRootView()->removeChild( LLPanelLogin::sInstance );
+		LLPanelLogin::sInstance->getParent()->removeChild( LLPanelLogin::sInstance );
 
 		delete sInstance;
 		sInstance = NULL;
@@ -817,7 +784,7 @@ void LLPanelLogin::loadLoginPage()
 								   LLVersionInfo::getShortVersion().c_str(),
 								   LLVersionInfo::getBuild());
 
-	char* curl_channel = curl_escape(gSavedSettings.getString("VersionChannelName").c_str(), 0);
+	char* curl_channel = curl_escape(LLVersionInfo::getChannel().c_str(), 0);
 	char* curl_version = curl_escape(version.c_str(), 0);
 
 	oStr << "&channel=" << curl_channel;
@@ -832,73 +799,6 @@ void LLPanelLogin::loadLoginPage()
 	curl_free(curl_grid);
 	gViewerWindow->setMenuBackgroundColor(false, !LLGridManager::getInstance()->isInProductionGrid());
 	gLoginMenuBarView->setBackgroundColor(gMenuBarView->getBackgroundColor());
-
-
-#if USE_VIEWER_AUTH
-	LLURLSimString::sInstance.parse();
-
-	std::string location;
-	std::string region;
-	std::string password;
-	
-	if (LLURLSimString::parse())
-	{
-		std::ostringstream oRegionStr;
-		location = "specify";
-		oRegionStr << LLURLSimString::sInstance.mSimName << "/" << LLURLSimString::sInstance.mX << "/"
-			 << LLURLSimString::sInstance.mY << "/"
-			 << LLURLSimString::sInstance.mZ;
-		region = oRegionStr.str();
-	}
-	else
-	{
-		location = gSavedSettings.getString("LoginLocation");
-	}
-	
-	std::string username;
-
-    if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
-    {
-        LLSD cmd_line_login = gSavedSettings.getLLSD("UserLoginInfo");
-		username = cmd_line_login[0].asString() + " " + cmd_line_login[1];
-        password = cmd_line_login[2].asString();
-    }
-    	
-	
-	char* curl_region = curl_escape(region.c_str(), 0);
-
-	oStr <<"username=" << username <<
-		 "&location=" << location <<	"&region=" << curl_region;
-	
-	curl_free(curl_region);
-
-	if (!password.empty())
-	{
-		oStr << "&password=" << password;
-	}
-	else if (!(password = load_password_from_disk()).empty())
-	{
-		oStr << "&password=$1$" << password;
-	}
-	if (gAutoLogin)
-	{
-		oStr << "&auto_login=TRUE";
-	}
-	if (gSavedSettings.getBOOL("ShowStartLocation"))
-	{
-		oStr << "&show_start_location=TRUE";
-	}	
-	if (gSavedSettings.getBOOL("RememberPassword"))
-	{
-		oStr << "&remember_password=TRUE";
-	}	
-#ifndef	LL_RELEASE_FOR_DOWNLOAD
-	oStr << "&show_grid=TRUE";
-#else
-	if (gSavedSettings.getBOOL("ForceShowGrid"))
-		oStr << "&show_grid=TRUE";
-#endif
-#endif
 	
 	LLMediaCtrl* web_browser = sInstance->getChild<LLMediaCtrl>("login_html");
 
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index 904e3dabcc6adc4f5d59efb8c48f356e813cbd92..17433a557b91d805bf4bd601c67b5dfef2b13ce0 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -329,15 +329,23 @@ void LLPanelMainInventory::setSortBy(const LLSD& userdata)
 	if (sort_field == "name")
 	{
 		U32 order = getActivePanel()->getSortOrder();
-		getActivePanel()->setSortOrder( order & ~LLInventoryFilter::SO_DATE );
-			
+		order &= ~LLInventoryFilter::SO_DATE;
+
+		getActivePanel()->setSortOrder( order );
+
+		gSavedSettings.setU32("InventorySortOrder", order);
+
 		gSavedSettings.setBOOL("Inventory.SortByName", TRUE );
 		gSavedSettings.setBOOL("Inventory.SortByDate", FALSE );
 	}
 	else if (sort_field == "date")
 	{
 		U32 order = getActivePanel()->getSortOrder();
-		getActivePanel()->setSortOrder( order | LLInventoryFilter::SO_DATE );
+		order |= LLInventoryFilter::SO_DATE;
+
+		getActivePanel()->setSortOrder( order );
+
+		gSavedSettings.setU32("InventorySortOrder", order);
 
 		gSavedSettings.setBOOL("Inventory.SortByName", FALSE );
 		gSavedSettings.setBOOL("Inventory.SortByDate", TRUE );
@@ -375,6 +383,8 @@ void LLPanelMainInventory::setSortBy(const LLSD& userdata)
 			gSavedSettings.setBOOL("Inventory.SystemFoldersToTop", TRUE );
 		}
 		getActivePanel()->setSortOrder( order );
+
+		gSavedSettings.setU32("InventorySortOrder", order);
 	}
 }
 
@@ -915,6 +925,7 @@ void LLPanelMainInventory::initListCommandsHandlers()
 			));
 
 	mCommitCallbackRegistrar.add("Inventory.GearDefault.Custom.Action", boost::bind(&LLPanelMainInventory::onCustomAction, this, _2));
+	mEnableCallbackRegistrar.add("Inventory.GearDefault.Check", boost::bind(&LLPanelMainInventory::isActionChecked, this, _2));
 	mEnableCallbackRegistrar.add("Inventory.GearDefault.Enable", boost::bind(&LLPanelMainInventory::isActionEnabled, this, _2));
 	mMenuGearDefault = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_inventory_gear_default.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 	mGearMenuButton->setMenu(mMenuGearDefault);
@@ -1000,6 +1011,11 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		const LLSD arg = "date";
 		setSortBy(arg);
 	}
+	if (command_name == "sort_system_folders_to_top")
+	{
+		const LLSD arg = "systemfolderstotop";
+		setSortBy(arg);
+	}
 	if (command_name == "show_filters")
 	{
 		toggleFindOptions();
@@ -1173,6 +1189,31 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	return TRUE;
 }
 
+BOOL LLPanelMainInventory::isActionChecked(const LLSD& userdata)
+{
+	const std::string command_name = userdata.asString();
+
+	if (command_name == "sort_by_name")
+	{
+		U32 order = getActivePanel()->getSortOrder();
+		return ~order & LLInventoryFilter::SO_DATE;
+	}
+
+	if (command_name == "sort_by_recent")
+	{
+		U32 order = getActivePanel()->getSortOrder();
+		return order & LLInventoryFilter::SO_DATE;
+	}
+
+	if (command_name == "sort_system_folders_to_top")
+	{
+		U32 order = getActivePanel()->getSortOrder();
+		return order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP;
+	}
+
+	return FALSE;
+}
+
 bool LLPanelMainInventory::handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept)
 {
 	*accept = ACCEPT_NO;
diff --git a/indra/newview/llpanelmaininventory.h b/indra/newview/llpanelmaininventory.h
index d136e2d32ea686cf7242df0732920ba33f65a1c7..c2b78ff9ea0370e26a9fc9b5ddc13b6efdb317b7 100644
--- a/indra/newview/llpanelmaininventory.h
+++ b/indra/newview/llpanelmaininventory.h
@@ -136,6 +136,7 @@ class LLPanelMainInventory : public LLPanel, LLInventoryObserver
 	void onTrashButtonClick();
 	void onClipboardAction(const LLSD& userdata);
 	BOOL isActionEnabled(const LLSD& command_name);
+	BOOL isActionChecked(const LLSD& userdata);
 	void onCustomAction(const LLSD& command_name);
 	bool handleDragAndDropToTrash(BOOL drop, EDragAndDropType cargo_type, EAcceptance* accept);
 	/**
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index d756a1b931abd4f508728ee86b7055b36d2bb4cb..a0c320ba19d749ded2acf86acd39185188f4dbc7 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -1695,10 +1695,10 @@ void LLPanelObject::sendPosition(BOOL btn_down)
 
 	LLVector3 newpos(mCtrlPosX->get(), mCtrlPosY->get(), mCtrlPosZ->get());
 	LLViewerRegion* regionp = mObject->getRegion();
-		
+
 	// Clamp the Z height
 	const F32 height = newpos.mV[VZ];
-	const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject);
+	const F32 min_height = LLWorld::getInstance()->getMinAllowedZ(mObject, mObject->getPositionGlobal());
 	const F32 max_height = LLWorld::getInstance()->getRegionMaxHeight();
 
 	if (!mObject->isAttachment())
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index ce9b1c66d742462550c0423ae39b784368a10c28..c10c21683b4faafc5c1404c989326b8c8f48b724 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -186,14 +186,8 @@ class LLPanelOutfitEditGearMenu
 	// Populate the menu with items like "New Skin", "New Pants", etc.
 	static void populateCreateWearableSubmenus(LLMenuGL* menu)
 	{
-		LLView* menu_clothes	= gMenuHolder->findChildView("COF.Gear.New_Clothes", FALSE);
-		LLView* menu_bp			= gMenuHolder->findChildView("COF.Geear.New_Body_Parts", FALSE);
-
-		if (!menu_clothes || !menu_bp)
-		{
-			llassert(menu_clothes && menu_bp);
-			return;
-		}
+		LLView* menu_clothes	= gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE);
+		LLView* menu_bp			= gMenuHolder->getChildView("COF.Geear.New_Body_Parts", FALSE);
 
 		for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i)
 		{
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 71c812efe25229a9c6fa2184d67c2ae2c9278c44..54198d6aa486fd208d73567682d7f5efcd0595e2 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -231,7 +231,7 @@ class LLPanelPeople::Updater
 	virtual void setActive(bool) {}
 
 protected:
-	void updateList()
+	void update()
 	{
 		mCallback();
 	}
@@ -239,6 +239,30 @@ class LLPanelPeople::Updater
 	callback_t		mCallback;
 };
 
+/**
+ * Update buttons on changes in our friend relations (STORM-557).
+ */
+class LLButtonsUpdater : public LLPanelPeople::Updater, public LLFriendObserver
+{
+public:
+	LLButtonsUpdater(callback_t cb)
+	:	LLPanelPeople::Updater(cb)
+	{
+		LLAvatarTracker::instance().addObserver(this);
+	}
+
+	~LLButtonsUpdater()
+	{
+		LLAvatarTracker::instance().removeObserver(this);
+	}
+
+	/*virtual*/ void changed(U32 mask)
+	{
+		(void) mask;
+		update();
+	}
+};
+
 class LLAvatarListUpdater : public LLPanelPeople::Updater, public LLEventTimer
 {
 public:
@@ -306,7 +330,7 @@ class LLFriendListUpdater : public LLAvatarListUpdater, public LLFriendObserver
 
 		if (mMask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE | LLFriendObserver::ONLINE))
 		{
-			updateList();
+			update();
 		}
 
 		// Stop updates.
@@ -421,7 +445,7 @@ class LLNearbyListUpdater : public LLAvatarListUpdater
 		if (val)
 		{
 			// update immediately and start regular updates
-			updateList();
+			update();
 			mEventTimer.start(); 
 		}
 		else
@@ -433,7 +457,7 @@ class LLNearbyListUpdater : public LLAvatarListUpdater
 
 	/*virtual*/ BOOL tick()
 	{
-		updateList();
+		update();
 		return FALSE;
 	}
 private:
@@ -450,7 +474,7 @@ class LLRecentListUpdater : public LLAvatarListUpdater, public boost::signals2::
 	LLRecentListUpdater(callback_t cb)
 	:	LLAvatarListUpdater(cb, 0)
 	{
-		LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::updateList, this));
+		LLRecentPeople::instance().setChangedCallback(boost::bind(&LLRecentListUpdater::update, this));
 	}
 };
 
@@ -475,11 +499,13 @@ LLPanelPeople::LLPanelPeople()
 	mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList,	this));
 	mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList,	this));
 	mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList,	this));
+	mButtonsUpdater = new LLButtonsUpdater(boost::bind(&LLPanelPeople::updateButtons, this));
 	mCommitCallbackRegistrar.add("People.addFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
 }
 
 LLPanelPeople::~LLPanelPeople()
 {
+	delete mButtonsUpdater;
 	delete mNearbyListUpdater;
 	delete mFriendListUpdater;
 	delete mRecentListUpdater;
@@ -1367,9 +1393,6 @@ void LLPanelPeople::onMoreButtonClicked()
 void	LLPanelPeople::onOpen(const LLSD& key)
 {
 	std::string tab_name = key["people_panel_tab_name"];
-	mFilterEditor -> clear();
-	onFilterEdit("");
-	
 	if (!tab_name.empty())
 		mTabContainer->selectTabByName(tab_name);
 }
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 4412aed0628b2aab30c266a22b088d0b4d73eb5e..b496bb3779ec132c8da2235cf80d5dbbd9950fad 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -152,6 +152,7 @@ class LLPanelPeople
 	Updater*				mFriendListUpdater;
 	Updater*				mNearbyListUpdater;
 	Updater*				mRecentListUpdater;
+	Updater*				mButtonsUpdater;
 
 	LLMenuButton*			mNearbyGearButton;
 	LLMenuButton*			mFriendsGearButton;
diff --git a/indra/newview/llpanelpick.cpp b/indra/newview/llpanelpick.cpp
index 271728220cc7544a9c215bdfad04f68f979064aa..44cca21a76a019a0e226c367af9e57f628805060 100644
--- a/indra/newview/llpanelpick.cpp
+++ b/indra/newview/llpanelpick.cpp
@@ -204,9 +204,6 @@ void LLPanelPickInfo::sendParcelInfoRequest()
 {
 	if (mParcelId != mRequestedId)
 	{
-        //ext-4655, remove now incase this gets called twice without a remove
-        LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedId, this);
-        
 		LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelId, this);
 		LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelId);
 
diff --git a/indra/newview/llpanelpicks.cpp b/indra/newview/llpanelpicks.cpp
index ccef5635444283f16fe1e9edfc4a8c2cc55aaa56..15e826ac2c70018eeae5a7355144af499f0374a0 100644
--- a/indra/newview/llpanelpicks.cpp
+++ b/indra/newview/llpanelpicks.cpp
@@ -212,7 +212,8 @@ void LLPanelPicks::updateData()
 		mNoPicks = false;
 		mNoClassifieds = false;
 
-		getChild<LLUICtrl>("picks_panel_text")->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
+		mNoItemsLabel->setValue(LLTrans::getString("PicksClassifiedsLoadingText"));
+		mNoItemsLabel->setVisible(TRUE);
 
 		mPicksList->clear();
 		LLAvatarPropertiesProcessor::getInstance()->sendAvatarPicksRequest(getAvatarId());
@@ -314,15 +315,17 @@ void LLPanelPicks::processProperties(void* data, EAvatarProcessorType type)
 		mNoClassifieds = !mClassifiedsList->size();
 	}
 
-	if (mNoPicks && mNoClassifieds)
+	bool no_data = mNoPicks && mNoClassifieds;
+	mNoItemsLabel->setVisible(no_data);
+	if (no_data)
 	{
 		if(getAvatarId() == gAgentID)
 		{
-			getChild<LLUICtrl>("picks_panel_text")->setValue(LLTrans::getString("NoPicksClassifiedsText"));
+			mNoItemsLabel->setValue(LLTrans::getString("NoPicksClassifiedsText"));
 		}
 		else
 		{
-			getChild<LLUICtrl>("picks_panel_text")->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText"));
+			mNoItemsLabel->setValue(LLTrans::getString("NoAvatarPicksClassifiedsText"));
 		}
 	}
 }
@@ -359,6 +362,8 @@ BOOL LLPanelPicks::postBuild()
 	mPicksList->setNoItemsCommentText(getString("no_picks"));
 	mClassifiedsList->setNoItemsCommentText(getString("no_classifieds"));
 
+	mNoItemsLabel = getChild<LLUICtrl>("picks_panel_text");
+
 	childSetAction(XML_BTN_NEW, boost::bind(&LLPanelPicks::onClickPlusBtn, this));
 	childSetAction(XML_BTN_DELETE, boost::bind(&LLPanelPicks::onClickDelete, this));
 	childSetAction(XML_BTN_TELEPORT, boost::bind(&LLPanelPicks::onClickTeleport, this));
@@ -781,7 +786,7 @@ void LLPanelPicks::showAccordion(const std::string& name, bool show)
 
 void LLPanelPicks::onPanelPickClose(LLPanel* panel)
 {
-	panel->setVisible(FALSE);
+	getProfilePanel()->closePanel(panel);
 }
 
 void LLPanelPicks::onPanelPickSave(LLPanel* panel)
diff --git a/indra/newview/llpanelpicks.h b/indra/newview/llpanelpicks.h
index 526ba48dcbce53906dfe8eac5b8cbf239c7dca55..a02ed81bb06e1055fda0b6f52367f58153e4df51 100644
--- a/indra/newview/llpanelpicks.h
+++ b/indra/newview/llpanelpicks.h
@@ -149,6 +149,7 @@ class LLPanelPicks
 	LLPanelClassifiedInfo* mPanelClassifiedInfo;
 	LLPanelPickEdit* mPanelPickEdit;
 	LLToggleableMenu* mPlusMenu;
+	LLUICtrl* mNoItemsLabel;
 
 	// <classified_id, edit_panel>
 	typedef std::map<LLUUID, LLPanelClassifiedEdit*> panel_classified_edit_map_t;
diff --git a/indra/newview/llpanelplaceinfo.cpp b/indra/newview/llpanelplaceinfo.cpp
index 9cbb512e7022a31d40cb17ed08a893a323165a0c..4ae0c0eb1252c7c595b47333f3f75c89d61bb335 100644
--- a/indra/newview/llpanelplaceinfo.cpp
+++ b/indra/newview/llpanelplaceinfo.cpp
@@ -128,10 +128,6 @@ void LLPanelPlaceInfo::sendParcelInfoRequest()
 {
 	if (mParcelID != mRequestedID)
 	{
-        //ext-4655, defensive. remove now incase this gets called twice without a remove
-        //as panel never closes its ok atm (but wrong :) 
-        LLRemoteParcelInfoProcessor::getInstance()->removeObserver(mRequestedID, this);
-
 		LLRemoteParcelInfoProcessor::getInstance()->addObserver(mParcelID, this);
 		LLRemoteParcelInfoProcessor::getInstance()->sendParcelInfoRequest(mParcelID);
 
diff --git a/indra/newview/llpanelplaces.cpp b/indra/newview/llpanelplaces.cpp
index f0e60386b6d92dfea17602e4bb8911c53f0c9a59..00ac34efa5ce70cb9a6ba863fec87a190bbd3b35 100644
--- a/indra/newview/llpanelplaces.cpp
+++ b/indra/newview/llpanelplaces.cpp
@@ -39,6 +39,7 @@
 #include "llfiltereditor.h"
 #include "llfirstuse.h"
 #include "llfloaterreg.h"
+#include "llmenubutton.h"
 #include "llnotificationsutil.h"
 #include "lltabcontainer.h"
 #include "lltexteditor.h"
@@ -282,8 +283,8 @@ BOOL LLPanelPlaces::postBuild()
 	mCloseBtn = getChild<LLButton>("close_btn");
 	mCloseBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
 
-	mOverflowBtn = getChild<LLButton>("overflow_btn");
-	mOverflowBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this));
+	mOverflowBtn = getChild<LLMenuButton>("overflow_btn");
+	mOverflowBtn->setMouseDownCallback(boost::bind(&LLPanelPlaces::onOverflowButtonClicked, this));
 
 	mPlaceInfoBtn = getChild<LLButton>("profile_btn");
 	mPlaceInfoBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onProfileButtonClicked, this));
@@ -330,8 +331,7 @@ BOOL LLPanelPlaces::postBuild()
 	mPlaceProfileBackBtn = mPlaceProfile->getChild<LLButton>("back_btn");
 	mPlaceProfileBackBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
 
-	mLandmarkInfoBackBtn = mLandmarkInfo->getChild<LLButton>("back_btn");
-	mLandmarkInfoBackBtn->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
+	mLandmarkInfo->getChild<LLButton>("back_btn")->setClickedCallback(boost::bind(&LLPanelPlaces::onBackButtonClicked, this));
 
 	LLLineEditor* title_editor = mLandmarkInfo->getChild<LLLineEditor>("title_editor");
 	title_editor->setKeystrokeCallback(boost::bind(&LLPanelPlaces::onEditButtonClicked, this), NULL);
@@ -347,8 +347,6 @@ BOOL LLPanelPlaces::postBuild()
 
 void LLPanelPlaces::onOpen(const LLSD& key)
 {
-	LLFirstUse::notUsingDestinationGuide(false);
-
 	if (!mPlaceProfile || !mLandmarkInfo)
 		return;
 
@@ -384,12 +382,7 @@ void LLPanelPlaces::onOpen(const LLSD& key)
 
 			mLandmarkInfo->displayParcelInfo(LLUUID(), mPosGlobal);
 
-			// Disabling "Save", "Close" and "Back" buttons to prevent closing "Create Landmark"
-			// panel before created landmark is loaded.
-			// These buttons will be enabled when created landmark is added to inventory.
 			mSaveBtn->setEnabled(FALSE);
-			mCloseBtn->setEnabled(FALSE);
-			mLandmarkInfoBackBtn->setEnabled(FALSE);
 		}
 		else if (mPlaceInfoType == LANDMARK_INFO_TYPE)
 		{
@@ -497,8 +490,6 @@ void LLPanelPlaces::setItem(LLInventoryItem* item)
 
 	mEditBtn->setEnabled(is_landmark_editable);
 	mSaveBtn->setEnabled(is_landmark_editable);
-	mCloseBtn->setEnabled(TRUE);
-	mLandmarkInfoBackBtn->setEnabled(TRUE);
 
 	if (is_landmark_editable)
 	{
@@ -762,6 +753,11 @@ void LLPanelPlaces::onOverflowButtonClicked()
 		// there is no landmark already pointing to that parcel in agent's inventory.
 		menu->getChild<LLMenuItemCallGL>("landmark")->setEnabled(is_agent_place_info_visible &&
 																 !LLLandmarkActions::landmarkAlreadyExists());
+		// STORM-411
+		// Creating landmarks for remote locations is impossible.
+		// So hide menu item "Make a Landmark" in "Teleport History Profile" panel.
+		menu->setItemVisible("landmark", mPlaceInfoType != TELEPORT_HISTORY_INFO_TYPE);
+		menu->arrangeAndClear();
 	}
 	else if (mPlaceInfoType == LANDMARK_INFO_TYPE && mLandmarkMenu != NULL)
 	{
@@ -783,16 +779,7 @@ void LLPanelPlaces::onOverflowButtonClicked()
 		return;
 	}
 
-	if (!menu->toggleVisibility())
-		return;
-
-	if (menu->getButtonRect().isEmpty())
-	{
-		menu->setButtonRect(mOverflowBtn);
-	}
-	menu->updateParent(LLMenuGL::sMenuContainer);
-	LLRect rect = mOverflowBtn->getRect();
-	LLMenuGL::showPopup(this, menu, rect.mRight, rect.mTop);
+	mOverflowBtn->setMenu(menu, LLMenuButton::MP_TOP_RIGHT);
 }
 
 void LLPanelPlaces::onProfileButtonClicked()
@@ -1137,13 +1124,6 @@ void LLPanelPlaces::updateVerbs()
 		{
 			mTeleportBtn->setEnabled(have_3d_pos);
 		}
-
-		// Do not enable landmark info Back button when we are waiting
-		// for newly created landmark to load.
-		if (!is_create_landmark_visible)
-		{
-			mLandmarkInfoBackBtn->setEnabled(TRUE);
-		}
 	}
 	else
 	{
diff --git a/indra/newview/llpanelplaces.h b/indra/newview/llpanelplaces.h
index c3b2ab806f13211ecda30f463412ef5ea6ba8b7e..b335f88a48451c14598561443302b1e6b85000e3 100644
--- a/indra/newview/llpanelplaces.h
+++ b/indra/newview/llpanelplaces.h
@@ -47,6 +47,7 @@ class LLPlacesParcelObserver;
 class LLRemoteParcelInfoObserver;
 class LLTabContainer;
 class LLToggleableMenu;
+class LLMenuButton;
 
 typedef std::pair<LLUUID, std::string>	folder_pair_t;
 
@@ -116,14 +117,13 @@ class LLPanelPlaces : public LLPanel
 	LLToggleableMenu*			mLandmarkMenu;
 
 	LLButton*					mPlaceProfileBackBtn;
-	LLButton*					mLandmarkInfoBackBtn;
 	LLButton*					mTeleportBtn;
 	LLButton*					mShowOnMapBtn;
 	LLButton*					mEditBtn;
 	LLButton*					mSaveBtn;
 	LLButton*					mCancelBtn;
 	LLButton*					mCloseBtn;
-	LLButton*					mOverflowBtn;
+	LLMenuButton*				mOverflowBtn;
 	LLButton*					mPlaceInfoBtn;
 
 	LLPlacesInventoryObserver*	mInventoryObserver;
diff --git a/indra/newview/llpanelprimmediacontrols.cpp b/indra/newview/llpanelprimmediacontrols.cpp
index b04971f9803036c7c2c47f15e3e120b390181d4b..8ae3553857640f2461a665f6a341c3d340c50cfe 100644
--- a/indra/newview/llpanelprimmediacontrols.cpp
+++ b/indra/newview/llpanelprimmediacontrols.cpp
@@ -59,6 +59,7 @@
 #include "llvovolume.h"
 #include "llweb.h"
 #include "llwindow.h"
+#include "llwindowshade.h"
 #include "llfloatertools.h"  // to enable hide if build tools are up
 
 // Functions pulled from pipeline.cpp
@@ -90,7 +91,8 @@ LLPanelPrimMediaControls::LLPanelPrimMediaControls() :
 	mTargetObjectNormal(LLVector3::zero),
 	mZoomObjectID(LLUUID::null),
 	mZoomObjectFace(0),
-	mVolumeSliderVisible(0)
+	mVolumeSliderVisible(0),
+	mWindowShade(NULL)
 {
 	mCommitCallbackRegistrar.add("MediaCtrl.Close",		boost::bind(&LLPanelPrimMediaControls::onClickClose, this));
 	mCommitCallbackRegistrar.add("MediaCtrl.Back",		boost::bind(&LLPanelPrimMediaControls::onClickBack, this));
@@ -205,6 +207,9 @@ BOOL LLPanelPrimMediaControls::postBuild()
 		
 	mMediaAddress->setFocusReceivedCallback(boost::bind(&LLPanelPrimMediaControls::onInputURL, _1, this ));
 	
+	LLWindowShade::Params window_shade_params;
+	window_shade_params.name = "window_shade";
+
 	mCurrentZoom = ZOOM_NONE;
 	// clicks on buttons do not remove keyboard focus from media
 	setIsChrome(TRUE);
@@ -519,7 +524,7 @@ void LLPanelPrimMediaControls::updateShape()
 			if(LLPluginClassMediaOwner::MEDIA_LOADING == media_plugin->getStatus())
 			{	
 				mMediaProgressPanel->setVisible(true);
-				mMediaProgressBar->setPercent(media_plugin->getProgressPercent());
+				mMediaProgressBar->setValue(media_plugin->getProgressPercent());
 			}
 			else
 			{
@@ -620,12 +625,12 @@ void LLPanelPrimMediaControls::updateShape()
 		// convert screenspace bbox to pixels (in screen coords)
 		LLRect window_rect = gViewerWindow->getWorldViewRectScaled();
 		LLCoordGL screen_min;
-		screen_min.mX = llround((F32)window_rect.getWidth() * (min.mV[VX] + 1.f) * 0.5f);
-		screen_min.mY = llround((F32)window_rect.getHeight() * (min.mV[VY] + 1.f) * 0.5f);
+		screen_min.mX = llround((F32)window_rect.mLeft + (F32)window_rect.getWidth() * (min.mV[VX] + 1.f) * 0.5f);
+		screen_min.mY = llround((F32)window_rect.mBottom + (F32)window_rect.getHeight() * (min.mV[VY] + 1.f) * 0.5f);
 		
 		LLCoordGL screen_max;
-		screen_max.mX = llround((F32)window_rect.getWidth() * (max.mV[VX] + 1.f) * 0.5f);
-		screen_max.mY = llround((F32)window_rect.getHeight() * (max.mV[VY] + 1.f) * 0.5f);
+		screen_max.mX = llround((F32)window_rect.mLeft + (F32)window_rect.getWidth() * (max.mV[VX] + 1.f) * 0.5f);
+		screen_max.mY = llround((F32)window_rect.mBottom + (F32)window_rect.getHeight() * (max.mV[VY] + 1.f) * 0.5f);
 		
 		// grow panel so that screenspace bounding box fits inside "media_region" element of panel
 		LLRect media_panel_rect;
@@ -698,6 +703,24 @@ void LLPanelPrimMediaControls::updateShape()
 /*virtual*/
 void LLPanelPrimMediaControls::draw()
 {
+	LLViewerMediaImpl* impl = getTargetMediaImpl();
+	if (impl)
+	{
+		LLNotificationPtr notification = impl->getCurrentNotification();
+		if (notification != mActiveNotification)
+		{
+			mActiveNotification = notification;
+			if (notification)
+			{
+				showNotification(notification);
+			}
+			else
+			{
+				hideNotification();
+			}
+		}
+	}
+
 	F32 alpha = getDrawContext().mAlpha;
 	if(mFadeTimer.getStarted())
 	{
@@ -1295,3 +1318,38 @@ bool LLPanelPrimMediaControls::shouldVolumeSliderBeVisible()
 {
 	return mVolumeSliderVisible > 0;
 }
+
+void LLPanelPrimMediaControls::showNotification(LLNotificationPtr notify)
+{
+	delete mWindowShade;
+	LLWindowShade::Params params;
+	params.rect = mMediaRegion->getLocalRect();
+	params.follows.flags = FOLLOWS_ALL;
+	params.notification = notify;
+
+	//HACK: don't hardcode this
+	if (notify->getIcon() == "Popup_Caution")
+	{
+		params.bg_image.name = "Yellow_Gradient";
+		params.text_color = LLColor4::black;
+	}
+	else
+	{
+		//HACK: make this a property of the notification itself, "cancellable"
+		params.can_close = false;
+		params.text_color.control = "LabelTextColor";
+	}
+
+	mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
+
+	mMediaRegion->addChild(mWindowShade);
+	mWindowShade->show();
+}
+
+void LLPanelPrimMediaControls::hideNotification()
+{
+	if (mWindowShade)
+	{
+		mWindowShade->hide();
+	}
+}
diff --git a/indra/newview/llpanelprimmediacontrols.h b/indra/newview/llpanelprimmediacontrols.h
index 3ec24f0e24a8a2d04420f1f75ff812b1693c1d87..0b9664359c6ff7728d2542f1de1901fb1587f1c6 100644
--- a/indra/newview/llpanelprimmediacontrols.h
+++ b/indra/newview/llpanelprimmediacontrols.h
@@ -29,6 +29,7 @@
 
 #include "llpanel.h"
 #include "llviewermedia.h"
+#include "llnotificationptr.h"
 
 class LLButton;
 class LLCoordWindow;
@@ -37,6 +38,7 @@ class LLLayoutStack;
 class LLProgressBar;
 class LLSliderCtrl;
 class LLViewerMediaImpl;
+class LLWindowShade;
 
 class LLPanelPrimMediaControls : public LLPanel
 {
@@ -54,6 +56,9 @@ class LLPanelPrimMediaControls : public LLPanel
 	void updateShape();
 	bool isMouseOver();
 	
+	void showNotification(LLNotificationPtr notify);
+	void hideNotification();
+
 	enum EZoomLevel
 	{
 		ZOOM_NONE = 0,
@@ -162,6 +167,7 @@ class LLPanelPrimMediaControls : public LLPanel
 	LLUICtrl *mRightBookend;
 	LLUIImage* mBackgroundImage;
 	LLUIImage* mVolumeSliderBackgroundImage;
+	LLWindowShade* mWindowShade;
 	F32 mSkipStep;
 	S32 mMinWidth;
 	S32 mMinHeight;
@@ -204,6 +210,8 @@ class LLPanelPrimMediaControls : public LLPanel
 	S32 mZoomObjectFace;
 	
 	S32 mVolumeSliderVisible;
+
+	LLNotificationPtr mActiveNotification;
 };
 
 #endif // LL_PANELPRIMMEDIACONTROLS_H
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 4e6356397923769e39c426081cf770af2cf11f06..b035d7d4733c007ea7c0088367afbf730c3f0513 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -114,11 +114,109 @@ class LLAgentHandler : public LLCommandHandler
 LLAgentHandler gAgentHandler;
 
 
+//-- LLPanelProfile::ChildStack begins ----------------------------------------
+LLPanelProfile::ChildStack::ChildStack()
+:	mParent(NULL)
+{
+}
+
+void LLPanelProfile::ChildStack::setParent(LLPanel* parent)
+{
+	llassert_always(parent != NULL);
+	mParent = parent;
+}
+
+/// Save current parent's child views and remove them from the child list.
+bool LLPanelProfile::ChildStack::push()
+{
+	view_list_t vlist = *mParent->getChildList();
+
+	for (view_list_t::const_iterator it = vlist.begin(); it != vlist.end(); ++it)
+	{
+		LLView* viewp = *it;
+		mParent->removeChild(viewp);
+	}
+
+	mStack.push_back(vlist);
+	dump();
+	return true;
+}
+
+/// Restore saved children (adding them back to the child list).
+bool LLPanelProfile::ChildStack::pop()
+{
+	if (mStack.size() == 0)
+	{
+		llwarns << "Empty stack" << llendl;
+		llassert(mStack.size() == 0);
+		return false;
+	}
+
+	view_list_t& top = mStack.back();
+	for (view_list_t::const_iterator it = top.begin(); it != top.end(); ++it)
+	{
+		LLView* viewp = *it;
+		mParent->addChild(viewp);
+	}
+
+	mStack.pop_back();
+	dump();
+	return true;
+}
+
+/// Temporarily add all saved children back.
+void LLPanelProfile::ChildStack::preParentReshape()
+{
+	mSavedStack = mStack;
+	while(mStack.size() > 0)
+	{
+		pop();
+	}
+}
+
+/// Add the temporarily saved children back.
+void LLPanelProfile::ChildStack::postParentReshape()
+{
+	mStack = mSavedStack;
+	mSavedStack = stack_t();
+
+	for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it)
+	{
+		const view_list_t& vlist = (*stack_it);
+		for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
+		{
+			LLView* viewp = *list_it;
+			lldebugs << "removing " << viewp->getName() << llendl;
+			mParent->removeChild(viewp);
+		}
+	}
+}
+
+void LLPanelProfile::ChildStack::dump()
+{
+	unsigned lvl = 0;
+	lldebugs << "child stack dump:" << llendl;
+	for (stack_t::const_iterator stack_it = mStack.begin(); stack_it != mStack.end(); ++stack_it, ++lvl)
+	{
+		std::ostringstream dbg_line;
+		dbg_line << "lvl #" << lvl << ":";
+		const view_list_t& vlist = (*stack_it);
+		for (view_list_t::const_iterator list_it = vlist.begin(); list_it != vlist.end(); ++list_it)
+		{
+			dbg_line << " " << (*list_it)->getName();
+		}
+		lldebugs << dbg_line.str() << llendl;
+	}
+}
+
+//-- LLPanelProfile::ChildStack ends ------------------------------------------
+
 LLPanelProfile::LLPanelProfile()
  : LLPanel()
  , mTabCtrl(NULL)
  , mAvatarId(LLUUID::null)
 {
+	mChildStack.setParent(this);
 }
 
 BOOL LLPanelProfile::postBuild()
@@ -136,6 +234,15 @@ BOOL LLPanelProfile::postBuild()
 	return TRUE;
 }
 
+// virtual
+void LLPanelProfile::reshape(S32 width, S32 height, BOOL called_from_parent)
+{
+	// Temporarily add saved children back and reshape them.
+	mChildStack.preParentReshape();
+	LLPanel::reshape(width, height, called_from_parent);
+	mChildStack.postParentReshape();
+}
+
 void LLPanelProfile::onOpen(const LLSD& key)
 {
 	// open the desired panel
@@ -177,7 +284,6 @@ void LLPanelProfile::onOpen(const LLSD& key)
 	}
 }
 
-//*TODO redo panel toggling
 void LLPanelProfile::togglePanel(LLPanel* panel, const LLSD& key)
 {
 	// TRUE - we need to open/expand "panel"
@@ -204,19 +310,12 @@ void LLPanelProfile::onTabSelected(const LLSD& param)
 	}
 }
 
-void LLPanelProfile::setAllChildrenVisible(BOOL visible)
-{
-	const child_list_t* child_list = getChildList();
-	child_list_const_iter_t child_it = child_list->begin();
-	for (; child_it != child_list->end(); ++child_it)
-	{
-		LLView* viewp = *child_it;
-		viewp->setVisible(visible);
-	}
-}
-
 void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params)
 {
+	// Hide currently visible panel (STORM-690).
+	mChildStack.push();
+
+	// Add the panel or bring it to front.
 	if (panel->getParent() != this)
 	{
 		addChild(panel);
@@ -227,7 +326,7 @@ void LLPanelProfile::openPanel(LLPanel* panel, const LLSD& params)
 	}
 
 	panel->setVisible(TRUE);
-
+	panel->setFocus(TRUE); // prevent losing focus by the floater
 	panel->onOpen(params);
 
 	LLRect new_rect = getRect();
@@ -243,6 +342,20 @@ void LLPanelProfile::closePanel(LLPanel* panel)
 	if (panel->getParent() == this) 
 	{
 		removeChild(panel);
+
+		// Make the underlying panel visible.
+		mChildStack.pop();
+
+		// Prevent losing focus by the floater
+		const child_list_t* child_list = getChildList();
+		if (child_list->size() > 0)
+		{
+			child_list->front()->setFocus(TRUE);
+		}
+		else
+		{
+			llwarns << "No underlying panel to focus." << llendl;
+		}
 	}
 }
 
diff --git a/indra/newview/llpanelprofile.h b/indra/newview/llpanelprofile.h
index d2bcee80760344a64b5bd5c0bb1c4a6fd7ad8fba..0a572e6f25a58ae9326549f6b24f75dc72987b9b 100644
--- a/indra/newview/llpanelprofile.h
+++ b/indra/newview/llpanelprofile.h
@@ -41,7 +41,7 @@ class LLPanelProfile : public LLPanel
 
 public:
 	/*virtual*/ BOOL postBuild();
-
+	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 	/*virtual*/ void onOpen(const LLSD& key);
 
 	virtual void togglePanel(LLPanel*, const LLSD& key = LLSD());
@@ -58,8 +58,6 @@ class LLPanelProfile : public LLPanel
 
 	virtual void onTabSelected(const LLSD& param);
 
-	virtual void setAllChildrenVisible(BOOL visible);
-
 	LLTabContainer* getTabCtrl() { return mTabCtrl; }
 
 	const LLUUID& getAvatarId() { return mAvatarId; }
@@ -72,8 +70,34 @@ class LLPanelProfile : public LLPanel
 
 private:
 
+	//-- ChildStack begins ----------------------------------------------------
+	class ChildStack
+	{
+		LOG_CLASS(LLPanelProfile::ChildStack);
+	public:
+		ChildStack();
+		void setParent(LLPanel* parent);
+
+		bool push();
+		bool pop();
+		void preParentReshape();
+		void postParentReshape();
+
+	private:
+		void dump();
+
+		typedef LLView::child_list_t view_list_t;
+		typedef std::list<view_list_t> stack_t;
+
+		stack_t		mStack;
+		stack_t		mSavedStack;
+		LLPanel*	mParent;
+	};
+	//-- ChildStack ends ------------------------------------------------------
+
 	LLTabContainer* mTabCtrl;	
 	profile_tabs_t mTabContainer;
+	ChildStack		mChildStack;
 	LLUUID mAvatarId;
 };
 
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index fff8ccb912b04b14b265d24cba6375a1571171df..9b35e78134a5d59faa992a703e7a97b00113ef48 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -181,9 +181,11 @@ void LLTeleportHistoryFlatItem::setRegionName(const std::string& name)
 
 void LLTeleportHistoryFlatItem::updateTitle()
 {
+	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", LLColor4U(255, 255, 255));
+
 	LLTextUtil::textboxSetHighlightedVal(
 		mTitle,
-		LLStyle::Params(),
+		LLStyle::Params().color(sFgColor),
 		mRegionName,
 		mHighlight);
 }
diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp
index a9ca7314ce878429928420591a7e78b09993a0eb..30949f8f02e15d10e45ca07de268db9b3f657808 100644
--- a/indra/newview/llpaneltopinfobar.cpp
+++ b/indra/newview/llpaneltopinfobar.cpp
@@ -38,6 +38,7 @@
 #include "llsidetray.h"
 #include "llslurl.h"
 #include "llstatusbar.h"
+#include "lltrans.h"
 #include "llviewercontrol.h"
 #include "llviewerinventory.h"
 #include "llviewermenu.h"
@@ -102,6 +103,13 @@ void LLPanelTopInfoBar::initParcelIcons()
 	mParcelIcon[SCRIPTS_ICON] = getChild<LLIconCtrl>("scripts_icon");
 	mParcelIcon[DAMAGE_ICON] = getChild<LLIconCtrl>("damage_icon");
 
+	mParcelIcon[VOICE_ICON]->setToolTip(LLTrans::getString("LocationCtrlVoiceTooltip"));
+	mParcelIcon[FLY_ICON]->setToolTip(LLTrans::getString("LocationCtrlFlyTooltip"));
+	mParcelIcon[PUSH_ICON]->setToolTip(LLTrans::getString("LocationCtrlPushTooltip"));
+	mParcelIcon[BUILD_ICON]->setToolTip(LLTrans::getString("LocationCtrlBuildTooltip"));
+	mParcelIcon[SCRIPTS_ICON]->setToolTip(LLTrans::getString("LocationCtrlScriptsTooltip"));
+	mParcelIcon[DAMAGE_ICON]->setToolTip(LLTrans::getString("LocationCtrlDamageTooltip"));
+
 	mParcelIcon[VOICE_ICON]->setMouseDownCallback(boost::bind(&LLPanelTopInfoBar::onParcelIconClick, this, VOICE_ICON));
 	mParcelIcon[FLY_ICON]->setMouseDownCallback(boost::bind(&LLPanelTopInfoBar::onParcelIconClick, this, FLY_ICON));
 	mParcelIcon[PUSH_ICON]->setMouseDownCallback(boost::bind(&LLPanelTopInfoBar::onParcelIconClick, this, PUSH_ICON));
@@ -129,6 +137,7 @@ BOOL LLPanelTopInfoBar::postBuild()
 {
 	mInfoBtn = getChild<LLButton>("place_info_btn");
 	mInfoBtn->setClickedCallback(boost::bind(&LLPanelTopInfoBar::onInfoButtonClicked, this));
+	mInfoBtn->setToolTip(LLTrans::getString("LocationCtrlInfoBtnTooltip"));
 
 	mParcelInfoText = getChild<LLTextBox>("parcel_info_text");
 	mDamageText = getChild<LLTextBox>("damage_text");
diff --git a/indra/newview/llpopupview.cpp b/indra/newview/llpopupview.cpp
index 499b6a8f5fbfb38c4132483c5d3f1f34d1c44739..9fbb67a63aa436447a7f0fb5e8baa6a699d61330 100644
--- a/indra/newview/llpopupview.cpp
+++ b/indra/newview/llpopupview.cpp
@@ -40,7 +40,8 @@ bool view_visible(LLView* viewp)
 }
 
 
-LLPopupView::LLPopupView()
+LLPopupView::LLPopupView(const LLPopupView::Params& p)
+: LLPanel(p)
 {
 	// register ourself as handler of UI popups
 	LLUI::setPopupFuncs(boost::bind(&LLPopupView::addPopup, this, _1), boost::bind(&LLPopupView::removePopup, this, _1), boost::bind(&LLPopupView::clearPopups, this));
@@ -137,64 +138,102 @@ BOOL LLPopupView::handleMouseEvent(boost::function<BOOL(LLView*, S32, S32)> func
 
 BOOL LLPopupView::handleMouseDown(S32 x, S32 y, MASK mask)
 {
-	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true))
+	BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true);
+	if (!handled)
 	{
-		return FALSE;
+		handled = LLPanel::handleMouseDown(x, y, mask);
 	}
-	return TRUE;
+	return handled;
 }
 
 BOOL LLPopupView::handleMouseUp(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
+	BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
+	if (!handled)
+	{
+		handled = LLPanel::handleMouseUp(x, y, mask);
+	}
+	return handled;
 }
 
 BOOL LLPopupView::handleMiddleMouseDown(S32 x, S32 y, MASK mask)
 {
-	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true))
+	BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true);
+	if (!handled)
 	{
-		return FALSE;
+		handled = LLPanel::handleMiddleMouseDown(x, y, mask);
 	}
-	return TRUE;
+	return handled;	
 }
 
 BOOL LLPopupView::handleMiddleMouseUp(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
+	BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleMiddleMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
+	if (!handled)
+	{
+		handled = LLPanel::handleMiddleMouseUp(x, y, mask);
+	}
+	return handled;	
 }
 
 BOOL LLPopupView::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
-	if (!handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true))
+	BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseDown, _1, _2, _3, mask), view_visible_and_enabled, x, y, true);
+	if (!handled)
 	{
-		return FALSE;
+		handled = LLPanel::handleRightMouseDown(x, y, mask);
 	}
-	return TRUE;
+	return handled;	
 }
 
 BOOL LLPopupView::handleRightMouseUp(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
+	BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleRightMouseUp, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
+	if (!handled)
+	{
+		handled = LLPanel::handleRightMouseUp(x, y, mask);
+	}
+	return handled;	
 }
 
 BOOL LLPopupView::handleDoubleClick(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleDoubleClick, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
+	BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleDoubleClick, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
+	if (!handled)
+	{
+		handled = LLPanel::handleDoubleClick(x, y, mask);
+	}
+	return handled;	
 }
 
 BOOL LLPopupView::handleHover(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleHover, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
+	BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleHover, _1, _2, _3, mask), view_visible_and_enabled, x, y, false);
+	if (!handled)
+	{
+		handled = LLPanel::handleHover(x, y, mask);
+	}
+	return handled;	
 }
 
 BOOL LLPopupView::handleScrollWheel(S32 x, S32 y, S32 clicks)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleScrollWheel, _1, _2, _3, clicks), view_visible_and_enabled, x, y, false);
+	BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleScrollWheel, _1, _2, _3, clicks), view_visible_and_enabled, x, y, false);
+	if (!handled)
+	{
+		handled = LLPanel::handleScrollWheel(x, y, clicks);
+	}
+	return handled;	
 }
 
 BOOL LLPopupView::handleToolTip(S32 x, S32 y, MASK mask)
 {
-	return handleMouseEvent(boost::bind(&LLMouseHandler::handleToolTip, _1, _2, _3, mask), view_visible, x, y, false);
+	BOOL handled = handleMouseEvent(boost::bind(&LLMouseHandler::handleToolTip, _1, _2, _3, mask), view_visible, x, y, false);
+	if (!handled)
+	{
+		handled = LLPanel::handleToolTip(x, y, mask);
+	}
+	return handled;
 }
 
 void LLPopupView::addPopup(LLView* popup)
diff --git a/indra/newview/llpopupview.h b/indra/newview/llpopupview.h
index fec4afd79cfb690b87796091c8c9ef9a4bfa34b3..b378f6198428eb7abf52e1ebd66137b21c62133a 100644
--- a/indra/newview/llpopupview.h
+++ b/indra/newview/llpopupview.h
@@ -32,7 +32,7 @@
 class LLPopupView : public LLPanel
 {
 public:
-	LLPopupView();
+	LLPopupView(const Params& p = LLPanel::Params());
 	~LLPopupView();
 
 	/*virtual*/ void draw();
diff --git a/indra/newview/llpreview.cpp b/indra/newview/llpreview.cpp
index 69542764d2f03607a0c47bf437693e7004eae374..a90f23d63707224732b5e1ac10ce2be9dd66360d 100644
--- a/indra/newview/llpreview.cpp
+++ b/indra/newview/llpreview.cpp
@@ -454,12 +454,13 @@ LLMultiPreview::LLMultiPreview()
 	{
 		// start with a rect in the top-left corner ; will get resized
 		LLRect rect;
-		rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 200, 200);
+		rect.setLeftTopAndSize(0, gViewerWindow->getWindowHeightScaled(), 200, 400);
 		setRect(rect);
 	}
 	setTitle(LLTrans::getString("MultiPreviewTitle"));
 	buildTabContainer();
 	setCanResize(TRUE);
+	mAutoResize = FALSE;
 }
 
 void LLMultiPreview::onOpen(const LLSD& key)
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index cf2ea3828808d0c4d53f5a1296386f1e62d12280..d0ebf047e8a314de691a4f8e7f301ca372eab3c5 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -34,11 +34,13 @@
 #include "llcheckboxctrl.h"
 #include "llcombobox.h"
 #include "lldir.h"
+#include "llexternaleditor.h"
 #include "llfloaterreg.h"
 #include "llinventorydefines.h"
 #include "llinventorymodel.h"
 #include "llkeyboard.h"
 #include "lllineeditor.h"
+#include "lllivefile.h"
 #include "llhelp.h"
 #include "llnotificationsutil.h"
 #include "llresmgr.h"
@@ -115,6 +117,54 @@ static bool have_script_upload_cap(LLUUID& object_id)
 	return object && (! object->getRegion()->getCapability("UpdateScriptTask").empty());
 }
 
+/// ---------------------------------------------------------------------------
+/// LLLiveLSLFile
+/// ---------------------------------------------------------------------------
+class LLLiveLSLFile : public LLLiveFile
+{
+public:
+	LLLiveLSLFile(std::string file_path, LLLiveLSLEditor* parent);
+	~LLLiveLSLFile();
+
+	void ignoreNextUpdate() { mIgnoreNextUpdate = true; }
+
+protected:
+	/*virtual*/ bool loadFile();
+
+	LLLiveLSLEditor*	mParent;
+	bool				mIgnoreNextUpdate;
+};
+
+LLLiveLSLFile::LLLiveLSLFile(std::string file_path, LLLiveLSLEditor* parent)
+:	mParent(parent)
+,	mIgnoreNextUpdate(false)
+,	LLLiveFile(file_path, 1.0)
+{
+}
+
+LLLiveLSLFile::~LLLiveLSLFile()
+{
+	LLFile::remove(filename());
+}
+
+bool LLLiveLSLFile::loadFile()
+{
+	if (mIgnoreNextUpdate)
+	{
+		mIgnoreNextUpdate = false;
+		return true;
+	}
+
+	if (!mParent->loadScriptText(filename()))
+	{
+		return false;
+	}
+
+	// Disable sync to avoid recursive load->save->load calls.
+	mParent->saveIfNeeded(false);
+	return true;
+}
+
 /// ---------------------------------------------------------------------------
 /// LLFloaterScriptSearch
 /// ---------------------------------------------------------------------------
@@ -281,6 +331,7 @@ LLScriptEdCore::LLScriptEdCore(
 	const LLHandle<LLFloater>& floater_handle,
 	void (*load_callback)(void*),
 	void (*save_callback)(void*, BOOL),
+	void (*edit_callback)(void*),
 	void (*search_replace_callback) (void* userdata),
 	void* userdata,
 	S32 bottom_pad)
@@ -290,6 +341,7 @@ LLScriptEdCore::LLScriptEdCore(
 	mEditor( NULL ),
 	mLoadCallback( load_callback ),
 	mSaveCallback( save_callback ),
+	mEditCallback( edit_callback ),
 	mSearchReplaceCallback( search_replace_callback ),
 	mUserdata( userdata ),
 	mForceClose( FALSE ),
@@ -329,6 +381,7 @@ BOOL LLScriptEdCore::postBuild()
 
 	childSetCommitCallback("lsl errors", &LLScriptEdCore::onErrorList, this);
 	childSetAction("Save_btn", boost::bind(&LLScriptEdCore::doSave,this,FALSE));
+	childSetAction("Edit_btn", boost::bind(&LLScriptEdCore::onEditButtonClick, this));
 
 	initMenu();
 
@@ -809,6 +862,13 @@ void LLScriptEdCore::doSave( BOOL close_after_save )
 	}
 }
 
+void LLScriptEdCore::onEditButtonClick()
+{
+	if (mEditCallback)
+	{
+		mEditCallback(mUserdata);
+	}
+}
 
 void LLScriptEdCore::onBtnUndoChanges()
 {
@@ -949,6 +1009,7 @@ void* LLPreviewLSL::createScriptEdPanel(void* userdata)
 								   self->getHandle(),
 								   LLPreviewLSL::onLoad,
 								   LLPreviewLSL::onSave,
+								   NULL, // no edit callback
 								   LLPreviewLSL::onSearchReplace,
 								   self,
 								   0);
@@ -1417,6 +1478,7 @@ void* LLLiveLSLEditor::createScriptEdPanel(void* userdata)
 								   self->getHandle(),
 								   &LLLiveLSLEditor::onLoad,
 								   &LLLiveLSLEditor::onSave,
+								   &LLLiveLSLEditor::onEdit,
 								   &LLLiveLSLEditor::onSearchReplace,
 								   self,
 								   0);
@@ -1433,6 +1495,7 @@ LLLiveLSLEditor::LLLiveLSLEditor(const LLSD& key) :
 	mCloseAfterSave(FALSE),
 	mPendingUploads(0),
 	mIsModifiable(FALSE),
+	mLiveFile(NULL),
 	mIsNew(false)
 {
 	mFactoryMap["script ed panel"] = LLCallbackMap(LLLiveLSLEditor::createScriptEdPanel, this);
@@ -1458,6 +1521,7 @@ BOOL LLLiveLSLEditor::postBuild()
 
 LLLiveLSLEditor::~LLLiveLSLEditor()
 {
+	delete mLiveFile;
 }
 
 // virtual
@@ -1639,38 +1703,39 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id,
 	delete xored_id;
 }
 
-// unused
-// void LLLiveLSLEditor::loadScriptText(const std::string& filename)
-// {
-// 	if(!filename)
-// 	{
-// 		llerrs << "Filename is Empty!" << llendl;
-// 		return;
-// 	}
-// 	LLFILE* file = LLFile::fopen(filename, "rb");		/*Flawfinder: ignore*/
-// 	if(file)
-// 	{
-// 		// read in the whole file
-// 		fseek(file, 0L, SEEK_END);
-// 		long file_length = ftell(file);
-// 		fseek(file, 0L, SEEK_SET);
-// 		char* buffer = new char[file_length+1];
-// 		size_t nread = fread(buffer, 1, file_length, file);
-// 		if (nread < (size_t) file_length)
-// 		{
-// 			llwarns << "Short read" << llendl;
-// 		}
-// 		buffer[nread] = '\0';
-// 		fclose(file);
-// 		mScriptEd->mEditor->setText(LLStringExplicit(buffer));
-// 		mScriptEd->mEditor->makePristine();
-// 		delete[] buffer;
-// 	}
-// 	else
-// 	{
-// 		llwarns << "Error opening " << filename << llendl;
-// 	}
-// }
+ bool LLLiveLSLEditor::loadScriptText(const std::string& filename)
+ {
+ 	if (filename.empty())
+ 	{
+ 		llwarns << "Empty file name" << llendl;
+ 		return false;
+ 	}
+
+ 	LLFILE* file = LLFile::fopen(filename, "rb");		/*Flawfinder: ignore*/
+ 	if (!file)
+ 	{
+ 		llwarns << "Error opening " << filename << llendl;
+ 		return false;
+ 	}
+
+ 	// read in the whole file
+	fseek(file, 0L, SEEK_END);
+	size_t file_length = (size_t) ftell(file);
+	fseek(file, 0L, SEEK_SET);
+	char* buffer = new char[file_length+1];
+	size_t nread = fread(buffer, 1, file_length, file);
+	if (nread < file_length)
+	{
+		llwarns << "Short read" << llendl;
+	}
+	buffer[nread] = '\0';
+	fclose(file);
+	mScriptEd->mEditor->setText(LLStringExplicit(buffer));
+	//mScriptEd->mEditor->makePristine();
+	delete[] buffer;
+
+	return true;
+ }
 
 void LLLiveLSLEditor::loadScriptText(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type)
 {
@@ -1825,9 +1890,8 @@ LLLiveLSLSaveData::LLLiveLSLSaveData(const LLUUID& id,
 	mItem = new LLViewerInventoryItem(item);
 }
 
-void LLLiveLSLEditor::saveIfNeeded()
+void LLLiveLSLEditor::saveIfNeeded(bool sync)
 {
-	llinfos << "LLLiveLSLEditor::saveIfNeeded()" << llendl;
 	LLViewerObject* object = gObjectList.findObject(mObjectUUID);
 	if(!object)
 	{
@@ -1877,9 +1941,74 @@ void LLLiveLSLEditor::saveIfNeeded()
 	mItem->setAssetUUID(asset_id);
 	mItem->setTransactionID(tid);
 
-	// write out the data, and store it in the asset database
+	writeToFile(filename);
+
+	if (sync)
+	{
+		// Sync with external ed2itor.
+		std::string tmp_file = getTmpFileName();
+		llstat s;
+		if (LLFile::stat(tmp_file, &s) == 0) // file exists
+		{
+			if (mLiveFile) mLiveFile->ignoreNextUpdate();
+			writeToFile(tmp_file);
+		}
+	}
+	
+	// save it out to asset server
+	std::string url = object->getRegion()->getCapability("UpdateScriptTask");
+	getWindow()->incBusyCount();
+	mPendingUploads++;
+	BOOL is_running = getChild<LLCheckBoxCtrl>( "running")->get();
+	if (!url.empty())
+	{
+		uploadAssetViaCaps(url, filename, mObjectUUID, mItemUUID, is_running);
+	}
+	else if (gAssetStorage)
+	{
+		uploadAssetLegacy(filename, object, tid, is_running);
+	}
+}
+
+void LLLiveLSLEditor::openExternalEditor()
+{
+	LLViewerObject* object = gObjectList.findObject(mObjectUUID);
+	if(!object)
+	{
+		LLNotificationsUtil::add("SaveScriptFailObjectNotFound");
+		return;
+	}
+
+	delete mLiveFile; // deletes file
+
+	// Save the script to a temporary file.
+	std::string filename = getTmpFileName();
+	writeToFile(filename);
+
+	// Start watching file changes.
+	mLiveFile = new LLLiveLSLFile(filename, this);
+	mLiveFile->addToEventTimer();
+
+	// Open it in external editor.
+	{
+		LLExternalEditor ed;
+
+		if (!ed.setCommand("LL_SCRIPT_EDITOR"))
+		{
+			std::string msg = "Select an editor by setting the environment variable LL_SCRIPT_EDITOR "
+				"or the ExternalEditor setting"; // *TODO: localize
+			LLNotificationsUtil::add("GenericAlert", LLSD().with("MESSAGE", msg));
+			return;
+		}
+
+		ed.run(filename);
+	}
+}
+
+bool LLLiveLSLEditor::writeToFile(const std::string& filename)
+{
 	LLFILE* fp = LLFile::fopen(filename, "wb");
-	if(!fp)
+	if (!fp)
 	{
 		llwarns << "Unable to write to " << filename << llendl;
 
@@ -1887,33 +2016,35 @@ void LLLiveLSLEditor::saveIfNeeded()
 		row["columns"][0]["value"] = "Error writing to local file. Is your hard drive full?";
 		row["columns"][0]["font"] = "SANSSERIF_SMALL";
 		mScriptEd->mErrorList->addElement(row);
-		return;
+		return false;
 	}
+
 	std::string utf8text = mScriptEd->mEditor->getText();
 
 	// Special case for a completely empty script - stuff in one space so it can store properly.  See SL-46889
-	if ( utf8text.size() == 0 )
+	if (utf8text.size() == 0)
 	{
 		utf8text = " ";
 	}
 
 	fputs(utf8text.c_str(), fp);
 	fclose(fp);
-	fp = NULL;
-	
-	// save it out to asset server
-	std::string url = object->getRegion()->getCapability("UpdateScriptTask");
-	getWindow()->incBusyCount();
-	mPendingUploads++;
-	BOOL is_running = getChild<LLCheckBoxCtrl>( "running")->get();
-	if (!url.empty())
-	{
-		uploadAssetViaCaps(url, filename, mObjectUUID, mItemUUID, is_running);
-	}
-	else if (gAssetStorage)
-	{
-		uploadAssetLegacy(filename, object, tid, is_running);
-	}
+	return true;
+}
+
+std::string LLLiveLSLEditor::getTmpFileName()
+{
+	// Take script inventory item id (within the object inventory)
+	// to consideration so that it's possible to edit multiple scripts
+	// in the same object inventory simultaneously (STORM-781).
+	std::string script_id = mObjectUUID.asString() + "_" + mItemUUID.asString();
+
+	// Use MD5 sum to make the file name shorter and not exceed maximum path length.
+	char script_id_hash_str[33];               /* Flawfinder: ignore */
+	LLMD5 script_id_hash((const U8 *)script_id.c_str());
+	script_id_hash.hex_digest(script_id_hash_str);
+
+	return std::string(LLFile::tmpdir()) + "sl_script_" + script_id_hash_str + ".lsl";
 }
 
 void LLLiveLSLEditor::uploadAssetViaCaps(const std::string& url,
@@ -2138,6 +2269,14 @@ void LLLiveLSLEditor::onSave(void* userdata, BOOL close_after_save)
 	self->saveIfNeeded();
 }
 
+
+// static
+void LLLiveLSLEditor::onEdit(void* userdata)
+{
+	LLLiveLSLEditor* self = (LLLiveLSLEditor*)userdata;
+	self->openExternalEditor();
+}
+
 // static
 void LLLiveLSLEditor::processScriptRunningReply(LLMessageSystem* msg, void**)
 {
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index f4b31e5962f5a4b5926c661ec058f7829ad70855..d35c6b85283b0445ee09b2b69f3f414f76b64544 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -35,6 +35,7 @@
 #include "lliconctrl.h"
 #include "llframetimer.h"
 
+class LLLiveLSLFile;
 class LLMessageSystem;
 class LLTextEditor;
 class LLButton;
@@ -62,6 +63,7 @@ class LLScriptEdCore : public LLPanel
 		const LLHandle<LLFloater>& floater_handle,
 		void (*load_callback)(void* userdata),
 		void (*save_callback)(void* userdata, BOOL close_after_save),
+		void (*edit_callback)(void*),
 		void (*search_replace_callback)(void* userdata),
 		void* userdata,
 		S32 bottom_pad = 0);	// pad below bottom row of buttons
@@ -80,6 +82,8 @@ class LLScriptEdCore : public LLPanel
 	bool			handleSaveChangesDialog(const LLSD& notification, const LLSD& response);
 	bool			handleReloadFromServerDialog(const LLSD& notification, const LLSD& response);
 
+	void			onEditButtonClick();
+
 	static void		onCheckLock(LLUICtrl*, void*);
 	static void		onHelpComboCommit(LLUICtrl* ctrl, void* userdata);
 	static void		onClickBack(void* userdata);
@@ -114,6 +118,7 @@ class LLScriptEdCore : public LLPanel
 	LLTextEditor*	mEditor;
 	void			(*mLoadCallback)(void* userdata);
 	void			(*mSaveCallback)(void* userdata, BOOL close_after_save);
+	void			(*mEditCallback)(void* userdata);
 	void			(*mSearchReplaceCallback) (void* userdata);
 	void*			mUserdata;
 	LLComboBox		*mFunctions;
@@ -179,6 +184,7 @@ class LLPreviewLSL : public LLPreview
 // Used to view and edit an LSL that is attached to an object.
 class LLLiveLSLEditor : public LLPreview
 {
+	friend class LLLiveLSLFile;
 public: 
 	LLLiveLSLEditor(const LLSD& key);
 	~LLLiveLSLEditor();
@@ -202,7 +208,10 @@ class LLLiveLSLEditor : public LLPreview
 
 	virtual void loadAsset();
 	void loadAsset(BOOL is_new);
-	void saveIfNeeded();
+	void saveIfNeeded(bool sync = true);
+	void openExternalEditor();
+	std::string getTmpFileName();
+	bool writeToFile(const std::string& filename);
 	void uploadAssetViaCaps(const std::string& url,
 							const std::string& filename, 
 							const LLUUID& task_id,
@@ -218,6 +227,7 @@ class LLLiveLSLEditor : public LLPreview
 	static void onSearchReplace(void* userdata);
 	static void onLoad(void* userdata);
 	static void onSave(void* userdata, BOOL close_after_save);
+	static void onEdit(void* userdata);
 
 	static void onLoadComplete(LLVFS *vfs, const LLUUID& asset_uuid,
 							   LLAssetType::EType type,
@@ -227,7 +237,7 @@ class LLLiveLSLEditor : public LLPreview
 	static void onRunningCheckboxClicked(LLUICtrl*, void* userdata);
 	static void onReset(void* userdata);
 
-// 	void loadScriptText(const std::string& filename); // unused
+ 	bool loadScriptText(const std::string& filename);
 	void loadScriptText(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type);
 
 	static void onErrorList(LLUICtrl*, void* user_data);
@@ -253,6 +263,7 @@ class LLLiveLSLEditor : public LLPreview
 	
 	LLCheckBoxCtrl*	mMonoCheckbox;
 	BOOL mIsModifiable;
+	LLLiveLSLFile*		mLiveFile;
 };
 
 #endif  // LL_LLPREVIEWSCRIPT_H
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index fd6b326ef16fa7df9bb17e1f6480585e145bca8d..7657cccd4ea3b5f6602d15d6e98f6fd9e8d28ed3 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -318,7 +318,7 @@ void LLPreviewTexture::reshape(S32 width, S32 height, BOOL called_from_parent)
 		}
 	}
 
-	mClientRect.setLeftTopAndSize(client_rect.getCenterX() - (client_width / 2), client_rect.getCenterY() +  (client_height / 2), client_width, client_height);	
+	mClientRect.setLeftTopAndSize(client_rect.getCenterX() - (client_width / 2), client_rect.getCenterY() +  (client_height / 2), client_width, client_height);
 
 }
 
@@ -400,7 +400,6 @@ void LLPreviewTexture::updateDimensions()
 	{
 		return;
 	}
-
 	
 	mUpdateDimensions = FALSE;
 
@@ -408,80 +407,12 @@ void LLPreviewTexture::updateDimensions()
 	getChild<LLUICtrl>("dimensions")->setTextArg("[HEIGHT]", llformat("%d", mImage->getFullHeight()));
 
 	
-	LLRect dim_rect(getChildView("dimensions")->getRect());
-
-	S32 horiz_pad = 2 * (LLPANEL_BORDER_WIDTH + PREVIEW_PAD) + PREVIEW_RESIZE_HANDLE_SIZE;
-
-	// add space for dimensions and aspect ratio
-	S32 info_height = dim_rect.mTop + CLIENT_RECT_VPAD;
-
-	S32 screen_width = gFloaterView->getSnapRect().getWidth();
-	S32 screen_height = gFloaterView->getSnapRect().getHeight();
-
-	S32 max_image_width = screen_width - 2*horiz_pad;
-	S32 max_image_height = screen_height - (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD) 
-		- (PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height);
-
-	S32 client_width = llmin(max_image_width,mImage->getFullWidth());
-	S32 client_height = llmin(max_image_height,mImage->getFullHeight());
-
-	if (mAspectRatio > 0.f)
-	{
-		if(mAspectRatio > 1.f)
-		{
-			client_height = llceil((F32)client_width / mAspectRatio);
-			if(client_height > max_image_height)
-			{
-				client_height = max_image_height;
-				client_width = llceil((F32)client_height * mAspectRatio);
-			}
-		}
-		else//mAspectRatio < 1.f
-		{
-			client_width = llceil((F32)client_height * mAspectRatio);
-			if(client_width > max_image_width)
-			{
-				client_width = max_image_width;
-				client_height = llceil((F32)client_width / mAspectRatio);
-			}
-		}
-	}
-	else
-	{
-
-		if(client_height > max_image_height)
-		{
-			F32 ratio = (F32)max_image_height/client_height;
-			client_height = max_image_height;
-			client_width = llceil((F32)client_height * ratio);
-		}
-		
-		if(client_width > max_image_width)
-		{
-			F32 ratio = (F32)max_image_width/client_width;
-			client_width = max_image_width;
-			client_height = llceil((F32)client_width * ratio);
-		}
-	}
-
-	//now back to whole floater
-	S32 floater_width = llmax(getMinWidth(),client_width + 2*horiz_pad);
-	S32 floater_height = llmax(getMinHeight(),client_height + (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD)
-		+ (PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height));
-
 	//reshape floater
-	reshape( floater_width, floater_height );
-	gFloaterView->adjustToFitScreen(this, FALSE);
+	reshape(getRect().getWidth(), getRect().getHeight());
 
-	//setup image rect...
-	LLRect client_rect(horiz_pad, getRect().getHeight(), getRect().getWidth() - horiz_pad, 0);
-	client_rect.mTop -= (PREVIEW_HEADER_SIZE + CLIENT_RECT_VPAD);
-	client_rect.mBottom += PREVIEW_BORDER + CLIENT_RECT_VPAD + info_height ;
-
-	mClientRect.setLeftTopAndSize(client_rect.getCenterX() - (client_width / 2), client_rect.getCenterY() +  (client_height / 2), client_width, client_height);	
+	gFloaterView->adjustToFitScreen(this, FALSE);
 
-	// Hide the aspect ratio label if the window is too narrow
-	// Assumes the label should be to the right of the dimensions
+	LLRect dim_rect(getChildView("dimensions")->getRect());
 	LLRect aspect_label_rect(getChildView("aspect_ratio")->getRect());
 	getChildView("aspect_ratio")->setVisible( dim_rect.mRight < aspect_label_rect.mLeft);
 }
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index e9504cbba07670402edec02e2c6af85741b6e625..31fde5d58aedfd401c40c46aa6069055ad420a11 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -133,13 +133,13 @@ void LLProgressView::setVisible(BOOL visible)
 		mFadeTimer.start();
 	}
 	// showing progress view
-	else if (!getVisible() && visible)
+	else if (visible && (!getVisible() || mFadeTimer.getStarted()))
 	{
 		setFocus(TRUE);
 		mFadeTimer.stop();
 		mProgressTimer.start();
 		LLPanel::setVisible(TRUE);
-	}
+	} 
 }
 
 
@@ -207,7 +207,7 @@ void LLProgressView::setText(const std::string& text)
 
 void LLProgressView::setPercent(const F32 percent)
 {
-	mProgressBar->setPercent(percent);
+	mProgressBar->setValue(percent);
 }
 
 void LLProgressView::setMessage(const std::string& msg)
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index d63a48647d558fad659ef2b058ff50f5e8cb3502..e5ef51bdd18c6b54c1ac0e801fa3567f6f15ec87 100644
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -77,23 +77,20 @@ void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason
 
 void LLRemoteParcelInfoProcessor::addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer)
 {
-	// Check if the observer is already in observers list for this UUID
 	observer_multimap_t::iterator it;
+	observer_multimap_t::iterator start = mObservers.lower_bound(parcel_id);
+	observer_multimap_t::iterator end = mObservers.upper_bound(parcel_id);
 
-	it = mObservers.find(parcel_id);
-	while (it != mObservers.end())
+	// Check if the observer is already in observers list for this UUID
+	for(it = start; it != end; ++it)
 	{
-		if (it->second == observer)
+		if (it->second.get() == observer)
 		{
 			return;
 		}
-		else
-		{
-			++it;
-		}
 	}
 
-	mObservers.insert(std::pair<LLUUID, LLRemoteParcelInfoObserver*>(parcel_id, observer));
+	mObservers.insert(std::make_pair(parcel_id, observer->getObserverHandle()));
 }
 
 void LLRemoteParcelInfoProcessor::removeObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer)
@@ -104,19 +101,16 @@ void LLRemoteParcelInfoProcessor::removeObserver(const LLUUID& parcel_id, LLRemo
 	}
 
 	observer_multimap_t::iterator it;
+	observer_multimap_t::iterator start = mObservers.lower_bound(parcel_id);
+	observer_multimap_t::iterator end = mObservers.upper_bound(parcel_id);
 
-	it = mObservers.find(parcel_id);
-	while (it != mObservers.end())
+	for(it = start; it != end; ++it)
 	{
-		if (it->second == observer)
+		if (it->second.get() == observer)
 		{
 			mObservers.erase(it);
 			break;
 		}
-		else
-		{
-			++it;
-		}
 	}
 }
 
@@ -141,13 +135,38 @@ void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, v
 	msg->getS32		("Data", "SalePrice", parcel_data.sale_price);
 	msg->getS32		("Data", "AuctionID", parcel_data.auction_id);
 
-	LLRemoteParcelInfoProcessor::observer_multimap_t observers = LLRemoteParcelInfoProcessor::getInstance()->mObservers;
+	LLRemoteParcelInfoProcessor::observer_multimap_t & observers = LLRemoteParcelInfoProcessor::getInstance()->mObservers;
 
-	observer_multimap_t::iterator oi = observers.find(parcel_data.parcel_id);
+	typedef std::vector<observer_multimap_t::iterator> deadlist_t;
+	deadlist_t dead_iters;
+
+	observer_multimap_t::iterator oi = observers.lower_bound(parcel_data.parcel_id);
 	observer_multimap_t::iterator end = observers.upper_bound(parcel_data.parcel_id);
-	for (; oi != end; ++oi)
+
+	while (oi != end)
+	{
+		// increment the loop iterator now since it may become invalid below
+		observer_multimap_t::iterator cur_oi = oi++;
+
+		LLRemoteParcelInfoObserver * observer = cur_oi->second.get();
+		if(observer)
+		{
+			// may invalidate cur_oi if the observer removes itself 
+			observer->processParcelInfo(parcel_data);
+		}
+		else
+		{
+			// the handle points to an expired observer, so don't keep it
+			// around anymore
+			dead_iters.push_back(cur_oi);
+		}
+	}
+
+	deadlist_t::iterator i;
+	deadlist_t::iterator end_dead = dead_iters.end();
+	for(i = dead_iters.begin(); i != end_dead; ++i)
 	{
-		oi->second->processParcelInfo(parcel_data);
+		observers.erase(*i);
 	}
 }
 
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index a6c62995a91b169906a5ca6340c39f8b2436f2c8..74cf1616dfada4296020107f8eedcbc79c290b03 100644
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -98,7 +98,7 @@ class LLRemoteParcelInfoProcessor : public LLSingleton<LLRemoteParcelInfoProcess
 	static void processParcelInfoReply(LLMessageSystem* msg, void**);
 
 private:
-	typedef std::multimap<LLUUID, LLRemoteParcelInfoObserver*> observer_multimap_t;
+	typedef std::multimap<LLUUID, LLHandle<LLRemoteParcelInfoObserver> > observer_multimap_t;
 	observer_multimap_t mObservers;
 };
 
diff --git a/indra/newview/llrootview.h b/indra/newview/llrootview.h
index 4b1ba15a0b7c9b3efcd5914f7b01bc1e69f2e769..5223a314f39b392b3c74cdd5d29a6eaec6d42011 100644
--- a/indra/newview/llrootview.h
+++ b/indra/newview/llrootview.h
@@ -42,27 +42,5 @@ class LLRootView : public LLView
 	LLRootView(const Params& p)
 	:	LLView(p)
 	{}
-
-	// added to provide possibility to handle mouse click event inside all application
-	// window without creating any floater
-	typedef boost::signals2::signal<void(S32 x, S32 y, MASK mask)>
-			mouse_signal_t;
-
-	private:
-		mouse_signal_t mMouseDownSignal;
-
-	public:
-	/*virtual*/
-	BOOL handleMouseDown(S32 x, S32 y, MASK mask)
-	{
-		mMouseDownSignal(x, y, mask);
-		return LLView::handleMouseDown(x, y, mask);
-	}
-
-	boost::signals2::connection addMouseDownCallback(
-			const mouse_signal_t::slot_type& cb)
-	{
-		return mMouseDownSignal.connect(cb);
-	}
 };
 #endif //LL_LLROOTVIEW_H
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 61f4897ed089dde0b0656b33f7f58f7659803364..e3bc67a4147993880551d641918da4ee67d719eb 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -83,11 +83,10 @@ bool  LLScreenChannelBase::isHovering()
 	return mHoveredToast->isHovered();
 }
 
-bool LLScreenChannelBase::resetPositionAndSize(const LLSD& newvalue)
+void LLScreenChannelBase::resetPositionAndSize()
 {
 	LLRect rc = gViewerWindow->getWorldViewRectScaled();
 	updatePositionAndSize(rc, rc);
-	return true;
 }
 
 void LLScreenChannelBase::updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect)
@@ -99,10 +98,7 @@ void LLScreenChannelBase::updatePositionAndSize(LLRect old_world_rect, LLRect ne
 	if (gSavedSettings.getBOOL("SidebarCameraMovement") == FALSE
 		&& LLSideTray::instanceCreated	())
 	{
-		LLSideTray*	side_bar = LLSideTray::getInstance();
-
-		if (side_bar->getVisible() && !side_bar->getCollapsed())
-			world_rect_padding += side_bar->getRect().getWidth();
+		world_rect_padding += LLSideTray::getInstance()->getVisibleWidth();
 	}
 
 
@@ -133,15 +129,25 @@ void LLScreenChannelBase::init(S32 channel_left, S32 channel_right)
 	if(LLSideTray::instanceCreated())
 	{
 		LLSideTray*	side_bar = LLSideTray::getInstance();
-		side_bar->getCollapseSignal().connect(boost::bind(&LLScreenChannelBase::resetPositionAndSize, this, _2));
+		side_bar->setVisibleWidthChangeCallback(boost::bind(&LLScreenChannelBase::resetPositionAndSize, this));
 	}
 
+	// top and bottom set by updateBottom()
+	setRect(LLRect(channel_left, 0, channel_right, 0));
+	updateBottom();
+	setVisible(TRUE);
+}
+
+void	LLScreenChannelBase::updateBottom()
+{
 	S32 channel_top = gViewerWindow->getWorldViewRectScaled().getHeight();
-	S32 channel_bottom = gViewerWindow->getWorldViewRectScaled().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");
+	S32 channel_bottom = gSavedSettings.getS32("ChannelBottomPanelMargin");
+	S32 channel_left = getRect().mLeft;
+	S32 channel_right = getRect().mRight;
 	setRect(LLRect(channel_left, channel_top, channel_right, channel_bottom));
-	setVisible(TRUE);
 }
 
+
 //--------------------------------------------------------------------------
 //////////////////////
 // LLScreenChannel
@@ -204,10 +210,7 @@ void LLScreenChannel::updatePositionAndSize(LLRect old_world_rect, LLRect new_wo
 	if (gSavedSettings.getBOOL("SidebarCameraMovement") == FALSE 
 		&& LLSideTray::instanceCreated	())
 	{
-		LLSideTray*	side_bar = LLSideTray::getInstance();
-
-		if (side_bar->getVisible() && !side_bar->getCollapsed())
-			world_rect_padding += side_bar->getRect().getWidth();
+		world_rect_padding += LLSideTray::getInstance()->getVisibleWidth();
 	}
 
 
@@ -253,8 +256,8 @@ void LLScreenChannel::addToast(const LLToast::Params& p)
 	if(mControlHovering)
 	{
 		new_toast_elem.toast->setOnToastHoverCallback(boost::bind(&LLScreenChannel::onToastHover, this, _1, _2));
-		new_toast_elem.toast->setMouseEnterCallback(boost::bind(&LLScreenChannel::stopFadingToast, this, new_toast_elem.toast));
-		new_toast_elem.toast->setMouseLeaveCallback(boost::bind(&LLScreenChannel::startFadingToast, this, new_toast_elem.toast));
+		new_toast_elem.toast->setMouseEnterCallback(boost::bind(&LLScreenChannel::stopToastTimer, this, new_toast_elem.toast));
+		new_toast_elem.toast->setMouseLeaveCallback(boost::bind(&LLScreenChannel::startToastTimer, this, new_toast_elem.toast));
 	}
 	
 	if(show_toast)
@@ -369,7 +372,7 @@ void LLScreenChannel::loadStoredToastsToChannel()
 	for(it = mStoredToastList.begin(); it != mStoredToastList.end(); ++it)
 	{
 		(*it).toast->setIsHidden(false);
-		(*it).toast->startFading();
+		(*it).toast->startTimer();
 		mToastList.push_back((*it));
 	}
 
@@ -394,7 +397,7 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id)
 	}
 
 	toast->setIsHidden(false);
-	toast->startFading();
+	toast->startTimer();
 	mToastList.push_back((*it));
 
 	redrawToasts();
@@ -477,7 +480,7 @@ void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel)
 		toast->removeChild(old_panel);
 		delete old_panel;
 		toast->insertPanel(panel);
-		toast->startFading();
+		toast->startTimer();
 		redrawToasts();
 	}
 }
@@ -485,7 +488,7 @@ void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel)
 //--------------------------------------------------------------------------
 void LLScreenChannel::redrawToasts()
 {
-	if(mToastList.size() == 0 || isHovering())
+	if(mToastList.size() == 0)
 		return;
 
 	switch(mToastAlignment)
@@ -511,6 +514,8 @@ void LLScreenChannel::showToastsBottom()
 	S32		toast_margin = 0;
 	std::vector<ToastElem>::reverse_iterator it;
 
+	updateBottom();
+
 	LLDockableFloater* floater = dynamic_cast<LLDockableFloater*>(LLDockableFloater::getInstanceHandle().get());
 
 	for(it = mToastList.rbegin(); it != mToastList.rend(); ++it)
@@ -583,20 +588,15 @@ void LLScreenChannel::showToastsBottom()
 		}
 	}
 
+	// Dismiss toasts we don't have space for (STORM-391).
 	if(it != mToastList.rend())
 	{
 		mHiddenToastsNum = 0;
 		for(; it != mToastList.rend(); it++)
 		{
-			(*it).toast->stopFading();
-			(*it).toast->setVisible(FALSE);
-			mHiddenToastsNum++;
+			(*it).toast->hide();
 		}
 	}
-	else
-	{
-		closeOverflowToastPanel();
-	}
 }
 
 //--------------------------------------------------------------------------
@@ -697,15 +697,15 @@ void LLScreenChannel::closeStartUpToast()
 	}
 }
 
-void LLNotificationsUI::LLScreenChannel::stopFadingToast(LLToast* toast)
+void LLNotificationsUI::LLScreenChannel::stopToastTimer(LLToast* toast)
 {
 	if (!toast || toast != mHoveredToast) return;
 
 	// Pause fade timer of the hovered toast.
-	toast->stopFading();
+	toast->stopTimer();
 }
 
-void LLNotificationsUI::LLScreenChannel::startFadingToast(LLToast* toast)
+void LLNotificationsUI::LLScreenChannel::startToastTimer(LLToast* toast)
 {
 	if (!toast || toast == mHoveredToast)
 	{
@@ -713,13 +713,12 @@ void LLNotificationsUI::LLScreenChannel::startFadingToast(LLToast* toast)
 	}
 
 	// Reset its fade timer.
-	toast->startFading();
+	toast->startTimer();
 }
 
 //--------------------------------------------------------------------------
 void LLScreenChannel::hideToastsFromScreen()
 {
-	closeOverflowToastPanel();
 	for(std::vector<ToastElem>::iterator it = mToastList.begin(); it != mToastList.end(); it++)
 		(*it).toast->setVisible(FALSE);
 }
@@ -835,8 +834,7 @@ void LLScreenChannel::onToastHover(LLToast* toast, bool mouse_enter)
 		}
 	}
 
-	if(!isHovering())
-		redrawToasts();
+	redrawToasts();
 }
 
 //--------------------------------------------------------------------------
@@ -850,13 +848,7 @@ void LLScreenChannel::updateShowToastsState()
 		return;
 	}
 
-	S32 channel_bottom = gViewerWindow->getWorldViewRectScaled().mBottom + gSavedSettings.getS32("ChannelBottomPanelMargin");;
-	LLRect this_rect = getRect();
-
-	if(channel_bottom != this_rect.mBottom)
-	{
-		setRect(LLRect(this_rect.mLeft, this_rect.mTop, this_rect.mRight, channel_bottom));
-	}
+	updateBottom();
 }
 
 //--------------------------------------------------------------------------
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index a1fdd6e32ca1f8b92d13fa1b42cca431157ff1d4..d207d139819cc63242e3c490f12bac8b6a2c0097 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -59,8 +59,8 @@ class LLScreenChannelBase : public LLUICtrl
 	// Channel's outfit-functions
 	// update channel's size and position in the World View
 	virtual void		updatePositionAndSize(LLRect old_world_rect, LLRect new_world_rect);
+	void				resetPositionAndSize();
 
-	bool resetPositionAndSize(const LLSD& newvalue);
 	// initialization of channel's shape and position
 	virtual void		init(S32 channel_left, S32 channel_right);
 
@@ -81,9 +81,6 @@ class LLScreenChannelBase : public LLUICtrl
 	// show all toasts in a channel
 	virtual void		redrawToasts() {};
 
-	virtual void 		closeOverflowToastPanel() {};
-	virtual void 		hideOverflowToastPanel() {};
-
 	
 	// Channel's behavior-functions
 	// set whether a channel will control hovering inside itself or not
@@ -111,6 +108,8 @@ class LLScreenChannelBase : public LLUICtrl
 	LLUUID	getChannelID() { return mID; }
 
 protected:
+	void	updateBottom();
+
 	// Channel's flags
 	bool		mControlHovering;
 	LLToast*		mHoveredToast;
@@ -194,10 +193,10 @@ class LLScreenChannel : public LLScreenChannelBase
 
 
 	/** Stop fading given toast */
-	virtual void stopFadingToast(LLToast* toast);
+	virtual void stopToastTimer(LLToast* toast);
 
 	/** Start fading given toast */
-	virtual void startFadingToast(LLToast* toast);
+	virtual void startToastTimer(LLToast* toast);
 
 	// get StartUp Toast's state
 	static bool	getStartUpToastShown() { return mWasStartUpToastShown; }
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index 2334f0cde5544ad7592c73acaab1bd6f56974cd3..170e23e4c5d98c1583162c8ee3466e942970defa 100644
--- a/indra/newview/llscriptfloater.cpp
+++ b/indra/newview/llscriptfloater.cpp
@@ -32,11 +32,13 @@
 #include "llchannelmanager.h"
 #include "llchiclet.h"
 #include "llfloaterreg.h"
+#include "lllslconstants.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llscreenchannel.h"
 #include "llsyswellwindow.h"
 #include "lltoastnotifypanel.h"
+#include "lltoastscripttextbox.h"
 #include "lltrans.h"
 #include "llviewerwindow.h"
 #include "llimfloater.h"
@@ -151,10 +153,18 @@ void LLScriptFloater::createForm(const LLUUID& notification_id)
 
 	// create new form
 	LLRect toast_rect = getRect();
-	// LLToastNotifyPanel will fit own content in vertical direction,
-	// but it needs an initial rect to properly calculate  its width
- 	// Use an initial rect of the script floater to make the floater window more configurable.
-	mScriptForm = new LLToastNotifyPanel(notification, toast_rect); 
+	if (isScriptTextbox(notification))
+	{
+		mScriptForm = new LLToastScriptTextbox(notification);
+	}
+	else
+	{
+		// LLToastNotifyPanel will fit own content in vertical direction,
+		// but it needs an initial rect to properly calculate  its width
+		// Use an initial rect of the script floater to make the floater
+		// window more configurable.
+		mScriptForm = new LLToastNotifyPanel(notification, toast_rect); 
+	}
 	addChild(mScriptForm);
 
 	// position form on floater
@@ -564,4 +574,32 @@ void LLScriptFloaterManager::setFloaterVisible(const LLUUID& notification_id, bo
 	}
 }
 
+//////////////////////////////////////////////////////////////////
+
+bool LLScriptFloater::isScriptTextbox(LLNotificationPtr notification)
+{
+	// get a form for the notification
+	LLNotificationFormPtr form(notification->getForm());
+
+	if (form)
+	{
+		// get number of elements in the form
+		int num_options = form->getNumElements();
+	
+		// if ANY of the buttons have the magic lltextbox string as
+		// name, then treat the whole dialog as a simple text entry
+		// box (i.e. mixed button and textbox forms are not supported)
+		for (int i=0; i<num_options; ++i)
+		{
+			LLSD form_element = form->getElement(i);
+			if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN)
+			{
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
 // EOF
diff --git a/indra/newview/llscriptfloater.h b/indra/newview/llscriptfloater.h
index da70bb4334680598c648fc7ddfb2d07eb94ad1c9..8e959a3d0e22eb12c53d649e7d491252e7699a03 100644
--- a/indra/newview/llscriptfloater.h
+++ b/indra/newview/llscriptfloater.h
@@ -28,8 +28,9 @@
 #define LL_SCRIPTFLOATER_H
 
 #include "lltransientdockablefloater.h"
+#include "llnotificationptr.h"
 
-class LLToastNotifyPanel;
+class LLToastPanel;
 
 /**
  * Handles script notifications ("ScriptDialog" and "ScriptDialogGroup")
@@ -203,7 +204,9 @@ class LLScriptFloater : public LLDockableFloater
 	void dockToChiclet(bool dock);
 
 private:
-	LLToastNotifyPanel* mScriptForm;
+	bool isScriptTextbox(LLNotificationPtr notification);
+
+	LLToastPanel* mScriptForm;
 	LLUUID mNotificationId;
 	LLUUID mObjectId;
 	bool mSaveFloaterPosition;
diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp
index 05b273cd29c4f14b45bb731f6824442f075e8b1d..f8c20dada07429cef4a4b1e5689558b31efd2442 100644
--- a/indra/newview/llscrollingpanelparam.cpp
+++ b/indra/newview/llscrollingpanelparam.cpp
@@ -165,12 +165,16 @@ void LLScrollingPanelParam::draw()
 	getChildView("max param text")->setVisible( FALSE );
 	LLPanel::draw();
 
+	// If we're in a focused floater, don't apply the floater's alpha to visual param hint,
+	// making its behavior similar to texture controls'.
+	F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
+
 	// Draw the hints over the "less" and "more" buttons.
 	gGL.pushUIMatrix();
 	{
 		const LLRect& r = mHintMin->getRect();
 		gGL.translateUI((F32)r.mLeft, (F32)r.mBottom, 0.f);
-		mHintMin->draw();
+		mHintMin->draw(alpha);
 	}
 	gGL.popUIMatrix();
 
@@ -178,7 +182,7 @@ void LLScrollingPanelParam::draw()
 	{
 		const LLRect& r = mHintMax->getRect();
 		gGL.translateUI((F32)r.mLeft, (F32)r.mBottom, 0.f);
-		mHintMax->draw();
+		mHintMax->draw(alpha);
 	}
 	gGL.popUIMatrix();
 
diff --git a/indra/newview/llsearchcombobox.cpp b/indra/newview/llsearchcombobox.cpp
index db531b56959ce44d61584c96fa9b2c0b30c8e51e..6558c9a7fac6955672f3cc86f85232e4e79ca54c 100644
--- a/indra/newview/llsearchcombobox.cpp
+++ b/indra/newview/llsearchcombobox.cpp
@@ -131,6 +131,9 @@ void LLSearchComboBox::focusTextEntry()
 	if (mTextEntry)
 	{
 		gFocusMgr.setKeyboardFocus(mTextEntry);
+
+		// Let the editor handle editing hotkeys (STORM-431).
+		LLEditMenuHandler::gEditMenuHandler = mTextEntry;
 	}
 }
 
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 1999f148280dbf2efd96a413f833e26f5f9ee824..b316171604a52ca57471c8d6e464b314952cef48 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -183,12 +183,15 @@ void LLSidepanelAppearance::onOpen(const LLSD& key)
 
 void LLSidepanelAppearance::onVisibilityChange(const LLSD &new_visibility)
 {
-	updateToVisibility(new_visibility);
+	LLSD visibility;
+	visibility["visible"] = new_visibility.asBoolean();
+	visibility["reset_accordion"] = true;
+	updateToVisibility(visibility);
 }
 
 void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
 {
-	if (new_visibility.asBoolean())
+	if (new_visibility["visible"].asBoolean())
 	{
 		bool is_outfit_edit_visible = mOutfitEdit && mOutfitEdit->getVisible();
 		bool is_wearable_edit_visible = mEditWearable && mEditWearable->getVisible();
@@ -209,7 +212,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
 				}
 			}
 
-			if (is_outfit_edit_visible)
+			if (is_outfit_edit_visible && new_visibility["reset_accordion"].asBoolean())
 			{
 				mOutfitEdit->resetAccordionState();
 			}
diff --git a/indra/newview/llsidepaneliteminfo.cpp b/indra/newview/llsidepaneliteminfo.cpp
index be797ea937defcb084cf596abd66b6d21797f707..c8c6858b81d2f829a4a996fa8b1f4b19a3174350 100644
--- a/indra/newview/llsidepaneliteminfo.cpp
+++ b/indra/newview/llsidepaneliteminfo.cpp
@@ -71,12 +71,12 @@ void LLItemPropertiesObserver::changed(U32 mask)
 	const std::set<LLUUID>& mChangedItemIDs = gInventory.getChangedIDs();
 	std::set<LLUUID>::const_iterator it;
 
-	const LLUUID& object_id = mFloater->getObjectID();
+	const LLUUID& item_id = mFloater->getItemID();
 
 	for (it = mChangedItemIDs.begin(); it != mChangedItemIDs.end(); it++)
 	{
 		// set dirty for 'item profile panel' only if changed item is the item for which 'item profile panel' is shown (STORM-288)
-		if (*it == object_id)
+		if (*it == item_id)
 		{
 			// if there's a change we're interested in.
 			if((mask & (LLInventoryObserver::LABEL | LLInventoryObserver::INTERNAL | LLInventoryObserver::REMOVE)) != 0)
@@ -196,6 +196,11 @@ const LLUUID& LLSidepanelItemInfo::getObjectID() const
 	return mObjectID;
 }
 
+const LLUUID& LLSidepanelItemInfo::getItemID() const
+{
+	return mItemID;
+}
+
 void LLSidepanelItemInfo::reset()
 {
 	LLSidepanelInventorySubpanel::reset();
diff --git a/indra/newview/llsidepaneliteminfo.h b/indra/newview/llsidepaneliteminfo.h
index 6416e2cfe40342b9a1922cd01e8c465d58139d73..25be145f64dd1e8154519830d048a1a6f726a714 100644
--- a/indra/newview/llsidepaneliteminfo.h
+++ b/indra/newview/llsidepaneliteminfo.h
@@ -55,6 +55,7 @@ class LLSidepanelItemInfo : public LLSidepanelInventorySubpanel
 	void setEditMode(BOOL edit);
 
 	const LLUUID& getObjectID() const;
+	const LLUUID& getItemID() const;
 
 protected:
 	/*virtual*/ void refresh();
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 81b2fc0ae09a9fd9ceb870400f67fe1b089dec9e..aef665a35cd4db8079689d71296109b8f8dc4c40 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -118,7 +118,7 @@ class LLSideTrayTab: public LLPanel
 protected:
 	LLSideTrayTab(const Params& params);
 	
-	void			dock();
+	void			dock(LLFloater* floater_tab);
 	void			undock(LLFloater* floater_tab);
 
 	LLSideTray*		getSideTray();
@@ -159,8 +159,6 @@ LLSideTrayTab::LLSideTrayTab(const Params& p)
 	mDescription(p.description),
 	mMainPanel(NULL)
 {
-	// Necessary for focus movement among child controls
-	setFocusRoot(TRUE);
 }
 
 LLSideTrayTab::~LLSideTrayTab()
@@ -259,7 +257,7 @@ void LLSideTrayTab::toggleTabDocked()
 
 	if (docking)
 	{
-		dock();
+		dock(floater_tab);
 	}
 	else
 	{
@@ -271,11 +269,14 @@ void LLSideTrayTab::toggleTabDocked()
 	LLFloaterReg::toggleInstance("side_bar_tab", tab_name);
 }
 
-void LLSideTrayTab::dock()
+void LLSideTrayTab::dock(LLFloater* floater_tab)
 {
 	LLSideTray* side_tray = getSideTray();
 	if (!side_tray) return;
 
+	// Before docking the tab, reset its (and its children's) transparency to default (STORM-688).
+	floater_tab->updateTransparency(TT_DEFAULT);
+
 	if (!side_tray->addTab(this))
 	{
 		llwarns << "Failed to add tab " << getName() << " to side tray" << llendl;
@@ -298,7 +299,11 @@ static void on_minimize(LLSidepanelAppearance* panel, LLSD minimized)
 {
 	if (!panel) return;
 	bool visible = !minimized.asBoolean();
-	panel->updateToVisibility(LLSD(visible));	
+	LLSD visibility;
+	visibility["visible"] = visible;
+	// Do not reset accordion state on minimize (STORM-375)
+	visibility["reset_accordion"] = false;
+	panel->updateToVisibility(visibility);
 }
 
 void LLSideTrayTab::undock(LLFloater* floater_tab)
@@ -556,7 +561,7 @@ BOOL LLSideTray::postBuild()
 	{
 		if ((*it).channel)
 		{
-			getCollapseSignal().connect(boost::bind(&LLScreenChannelBase::resetPositionAndSize, (*it).channel, _2));
+			setVisibleWidthChangeCallback(boost::bind(&LLScreenChannelBase::resetPositionAndSize, (*it).channel));
 		}
 	}
 
@@ -910,7 +915,6 @@ void	LLSideTray::createButtons	()
 		}
 	}
 	LLHints::registerHintTarget("inventory_btn", mTabButtons["sidebar_inventory"]->getHandle());
-	LLHints::registerHintTarget("dest_guide_btn", mTabButtons["sidebar_places"]->getHandle());
 }
 
 void		LLSideTray::processTriState ()
@@ -976,9 +980,6 @@ void LLSideTray::reflectCollapseChange()
 	}
 
 	gFloaterView->refresh();
-	
-	LLSD new_value = mCollapsed;
-	mCollapseSignal(this,new_value);
 }
 
 void LLSideTray::arrange()
@@ -1028,7 +1029,8 @@ void LLSideTray::arrange()
 	}
 
 	// The tab buttons should be shown only if there is at least one non-detached tab.
-	mButtonsPanel->setVisible(hasTabs());
+	// Also hide them in mouse-look mode.
+	mButtonsPanel->setVisible(hasTabs() && !gAgentCamera.cameraMouselook());
 }
 
 // Detach those tabs that were detached when the viewer exited last time.
@@ -1257,9 +1259,29 @@ bool		LLSideTray::isPanelActive(const std::string& panel_name)
 void	LLSideTray::updateSidetrayVisibility()
 {
 	// set visibility of parent container based on collapsed state
-	if (getParent())
+	LLView* parent = getParent();
+	if (parent)
 	{
-		getParent()->setVisible(!mCollapsed && !gAgentCamera.cameraMouselook());
+		bool old_visibility = parent->getVisible();
+		bool new_visibility = !mCollapsed && !gAgentCamera.cameraMouselook();
+
+		if (old_visibility != new_visibility)
+		{
+			parent->setVisible(new_visibility);
+
+			// Signal change of visible width.
+			llinfos << "Visible: " << new_visibility << llendl;
+			mVisibleWidthChangeSignal(this, new_visibility);
+		}
 	}
 }
 
+S32 LLSideTray::getVisibleWidth()
+{
+	return (isInVisibleChain() && !mCollapsed) ? getRect().getWidth() : 0;
+}
+
+void LLSideTray::setVisibleWidthChangeCallback(const commit_signal_t::slot_type& cb)
+{
+	mVisibleWidthChangeSignal.connect(cb);
+}
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index 4c23a1920b1e2f27ad7282db7ab71ffdf048c60f..184d78845f8a7fd7e88d26e00fe416394d87121f 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -40,6 +40,8 @@ class LLSideTray : public LLPanel, private LLDestroyClass<LLSideTray>
 {
 	friend class LLUICtrlFactory;
 	friend class LLDestroyClass<LLSideTray>;
+	friend class LLSideTrayTab;
+	friend class LLSideTrayButton;
 public:
 
 	LOG_CLASS(LLSideTray);
@@ -125,11 +127,6 @@ class LLSideTray : public LLPanel, private LLDestroyClass<LLSideTray>
 		return panel;
 	}
 
-	/*
-	 * get currently active tab
-	 */
-    const LLSideTrayTab*	getActiveTab() const { return mActiveTab; }
-
 	/*
      * collapse SideBar, hiding visible tab and moving tab buttons
      * to the right corner of the screen
@@ -163,32 +160,37 @@ class LLSideTray : public LLPanel, private LLDestroyClass<LLSideTray>
 
     virtual BOOL postBuild();
 
-	void		onTabButtonClick(std::string name);
-	void		onToggleCollapse();
-
-	bool		addChild		(LLView* view, S32 tab_group);
-	bool		removeTab		(LLSideTrayTab* tab); // Used to detach tabs temporarily
-	bool		addTab			(LLSideTrayTab* tab); // Used to re-attach tabs
-
 	BOOL		handleMouseDown	(S32 x, S32 y, MASK mask);
 	
 	void		reshape			(S32 width, S32 height, BOOL called_from_parent = TRUE);
 
-	void		processTriState ();
-	
-	void		updateSidetrayVisibility();
 
-	commit_signal_t& getCollapseSignal() { return mCollapseSignal; }
+	/**
+	 * @return side tray width if it's visible and expanded, 0 otherwise.
+	 *
+	 * Not that width of the tab buttons is not included.
+	 *
+	 * @see setVisibleWidthChangeCallback()
+	 */
+	S32			getVisibleWidth();
 
-	void		handleLoginComplete();
+	void		setVisibleWidthChangeCallback(const commit_signal_t::slot_type& cb);
 
-	LLSideTrayTab* getTab		(const std::string& name);
+	void		updateSidetrayVisibility();
+
+	void		handleLoginComplete();
 
 	bool 		isTabAttached	(const std::string& name);
 
 protected:
+	bool		addChild		(LLView* view, S32 tab_group);
+	bool		removeTab		(LLSideTrayTab* tab); // Used to detach tabs temporarily
+	bool		addTab			(LLSideTrayTab* tab); // Used to re-attach tabs
 	bool		hasTabs			();
 
+	const LLSideTrayTab*	getActiveTab() const { return mActiveTab; }
+	LLSideTrayTab* 			getTab(const std::string& name);
+
 	void		createButtons	();
 
 	LLButton*	createButton	(const std::string& name,const std::string& image,const std::string& tooltip,
@@ -196,11 +198,15 @@ class LLSideTray : public LLPanel, private LLDestroyClass<LLSideTray>
 	void		arrange			();
 	void		detachTabs		();
 	void		reflectCollapseChange();
+	void		processTriState ();
 
 	void		toggleTabButton	(LLSideTrayTab* tab);
 
 	LLPanel*	openChildPanel	(LLSideTrayTab* tab, const std::string& panel_name, const LLSD& params);
 
+	void		onTabButtonClick(std::string name);
+	void		onToggleCollapse();
+
 private:
 	// Implementation of LLDestroyClass<LLSideTray>
 	static void destroyClass()
@@ -219,7 +225,7 @@ class LLSideTray : public LLPanel, private LLDestroyClass<LLSideTray>
 	tab_order_vector_t				mOriginalTabOrder;
 	LLSideTrayTab*					mActiveTab;	
 	
-	commit_signal_t					mCollapseSignal;
+	commit_signal_t					mVisibleWidthChangeSignal;
 
 	LLButton*						mCollapseButton;
 	bool							mCollapsed;
diff --git a/indra/newview/llsimplestat.h b/indra/newview/llsimplestat.h
new file mode 100644
index 0000000000000000000000000000000000000000..a90e503adba7a429dd484ddf5eb13bce23e17d72
--- /dev/null
+++ b/indra/newview/llsimplestat.h
@@ -0,0 +1,158 @@
+/** 
+ * @file llsimplestat.h
+ * @brief Runtime statistics accumulation.
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_SIMPLESTAT_H
+#define LL_SIMPLESTAT_H
+
+// History
+//
+// The original source for this code is the server repositories'
+// llcommon/llstat.h file.  This particular code was added after the
+// viewer/server code schism but before the effort to convert common
+// code to libraries was complete.  Rather than add to merge issues,
+// the needed code was cut'n'pasted into this new header as it isn't
+// too awful a burden.  Post-modularization, we can look at removing
+// this redundancy.
+
+
+/**
+ * @class LLSimpleStatCounter
+ * @brief Just counts events.
+ *
+ * Really not needed but have a pattern in mind in the future.
+ * Interface limits what can be done at that's just fine.
+ *
+ * *TODO:  Update/transfer unit tests
+ * Unit tests:  indra/test/llcommon_llstat_tut.cpp
+ */
+class LLSimpleStatCounter
+{
+public:
+	inline LLSimpleStatCounter()		{ reset(); }
+	// Default destructor and assignment operator are valid
+
+	inline void reset()					{ mCount = 0; }
+
+	inline void merge(const LLSimpleStatCounter & src)
+										{ mCount += src.mCount; }
+	
+	inline U32 operator++()				{ return ++mCount; }
+
+	inline U32 getCount() const			{ return mCount; }
+		
+protected:
+	U32			mCount;
+};
+
+
+/**
+ * @class LLSimpleStatMMM
+ * @brief Templated collector of min, max and mean data for stats.
+ *
+ * Fed a stream of data samples, keeps a running account of the
+ * min, max and mean seen since construction or the last reset()
+ * call.  A freshly-constructed or reset instance returns counts
+ * and values of zero.
+ *
+ * Overflows and underflows (integer, inf or -inf) and NaN's
+ * are the caller's problem.  As is loss of precision when
+ * the running sum's exponent (when parameterized by a floating
+ * point of some type) differs from a given data sample's.
+ *
+ * Unit tests:  indra/test/llcommon_llstat_tut.cpp
+ */
+template <typename VALUE_T = F32>
+class LLSimpleStatMMM
+{
+public:
+	typedef VALUE_T Value;
+	
+public:
+	LLSimpleStatMMM()				{ reset(); }
+	// Default destructor and assignment operator are valid
+
+	/**
+	 * Resets the object returning all counts and derived
+	 * values back to zero.
+	 */
+	void reset()
+		{
+			mCount = 0;
+			mMin = Value(0);
+			mMax = Value(0);
+			mTotal = Value(0);
+		}
+
+	void record(Value v)
+		{
+			if (mCount)
+			{
+				mMin = llmin(mMin, v);
+				mMax = llmax(mMax, v);
+			}
+			else
+			{
+				mMin = v;
+				mMax = v;
+			}
+			mTotal += v;
+			++mCount;
+		}
+
+	void merge(const LLSimpleStatMMM<VALUE_T> & src)
+		{
+			if (! mCount)
+			{
+				*this = src;
+			}
+			else if (src.mCount)
+			{
+				mMin = llmin(mMin, src.mMin);
+				mMax = llmax(mMax, src.mMax);
+				mCount += src.mCount;
+				mTotal += src.mTotal;
+			}
+		}
+	
+	inline U32 getCount() const		{ return mCount; }
+	inline Value getMin() const		{ return mMin; }
+	inline Value getMax() const		{ return mMax; }
+	inline Value getMean() const	{ return mCount ? mTotal / mCount : mTotal; }
+		
+protected:
+	U32			mCount;
+	Value		mMin;
+	Value		mMax;
+	Value		mTotal;
+};
+
+#endif // LL_SIMPLESTAT_H
diff --git a/indra/newview/llspeakbutton.cpp b/indra/newview/llspeakbutton.cpp
index 3dce66f394d49fef75b17a0e77188d710c656052..c76ecae4a2b513d613ae616999d6f489269a9ddc 100644
--- a/indra/newview/llspeakbutton.cpp
+++ b/indra/newview/llspeakbutton.cpp
@@ -134,8 +134,11 @@ LLSpeakButton::LLSpeakButton(const Params& p)
 
 LLSpeakButton::~LLSpeakButton()
 {
-	LLTransientFloaterMgr::getInstance()->removeControlView(mSpeakBtn);
-	LLTransientFloaterMgr::getInstance()->removeControlView(mShowBtn);
+	if(LLTransientFloaterMgr::instanceExists())
+	{
+		LLTransientFloaterMgr::getInstance()->removeControlView(mSpeakBtn);
+		LLTransientFloaterMgr::getInstance()->removeControlView(mShowBtn);
+	}
 }
 
 void LLSpeakButton::setSpeakToolTip(const std::string& msg)
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index ede1d6bebee7c02795af170fd95b01dffd54f34c..9b38bf22ffe03ec7cea5ca373633c7f807ecb5f2 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -308,7 +308,10 @@ void LLSpeakingIndicatorManager::registerSpeakingIndicator(const LLUUID& speaker
 
 void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator)
 {
-	SpeakingIndicatorManager::instance().unregisterSpeakingIndicator(speaker_id, speaking_indicator);
+	if(SpeakingIndicatorManager::instanceExists())
+	{
+		SpeakingIndicatorManager::instance().unregisterSpeakingIndicator(speaker_id, speaking_indicator);
+	}
 }
 
 // EOF
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 5ee45992000daf7eed4d0bf97e2668f1a2b8f6ce..611f9de2e6db8dcdb24f2edf9fe9789c0bcd6684 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -198,6 +198,7 @@
 // exported globals
 //
 bool gAgentMovementCompleted = false;
+S32  gMaxAgentGroups;
 
 std::string SCREEN_HOME_FILENAME = "screen_home.bmp";
 std::string SCREEN_LAST_FILENAME = "screen_last.bmp";
@@ -232,6 +233,8 @@ static LLHost gFirstSim;
 static std::string gFirstSimSeedCap;
 static LLVector3 gAgentStartLookAt(1.0f, 0.f, 0.f);
 static std::string gAgentStartLocation = "safe";
+static bool mLoginStatePastUI = false;
+
 
 boost::scoped_ptr<LLEventPump> LLStartUp::sStateWatcher(new LLEventStream("StartupState"));
 boost::scoped_ptr<LLStartupListener> LLStartUp::sListener(new LLStartupListener());
@@ -705,7 +708,15 @@ bool idle_startup()
 	if (STATE_LOGIN_SHOW == LLStartUp::getStartupState())
 	{
 		LL_DEBUGS("AppInit") << "Initializing Window" << LL_ENDL;
-		
+
+		// if we've gone backwards in the login state machine, to this state where we show the UI
+		// AND the debug setting to exit in this case is true, then go ahead and bail quickly
+		if ( mLoginStatePastUI && gSavedSettings.getBOOL("QuitOnLoginActivated") )
+		{
+			// no requirement for notification here - just exit
+			LLAppViewer::instance()->earlyExitNoNotify();
+		}
+
 		gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
 
 		timeout_count = 0;
@@ -783,6 +794,11 @@ bool idle_startup()
 
 	if (STATE_LOGIN_WAIT == LLStartUp::getStartupState())
 	{
+		// when we get to this state, we've already been past the login UI
+		// (possiblely automatically) - flag this so we can test in the 
+		// STATE_LOGIN_SHOW state if we've gone backwards
+		mLoginStatePastUI = true;
+
 		// Don't do anything.  Wait for the login view to call the login_callback,
 		// which will push us to the next state.
 
@@ -809,6 +825,11 @@ bool idle_startup()
 			gKeyboard->resetKeys();
 		}
 
+		// when we get to this state, we've already been past the login UI
+		// (possiblely automatically) - flag this so we can test in the 
+		// STATE_LOGIN_SHOW state if we've gone backwards
+		mLoginStatePastUI = true;
+
 		// save the credentials                                                                                        
 		std::string userid = "unknown";                                                                                
 		if(gUserCredential.notNull())                                                                                  
@@ -3074,7 +3095,16 @@ bool process_login_success_response()
 	std::string map_server_url = response["map-server-url"];
 	if(!map_server_url.empty())
 	{
-		gSavedSettings.setString("MapServerURL", map_server_url); 
+		// We got an answer from the grid -> use that for map for the current session
+		gSavedSettings.setString("CurrentMapServerURL", map_server_url); 
+		LL_INFOS("LLStartup") << "map-server-url : we got an answer from the grid : " << map_server_url << LL_ENDL;
+	}
+	else
+	{
+		// No answer from the grid -> use the default setting for current session 
+		map_server_url = gSavedSettings.getString("MapServerURL"); 
+		gSavedSettings.setString("CurrentMapServerURL", map_server_url); 
+		LL_INFOS("LLStartup") << "map-server-url : no map-server-url answer, we use the default setting for the map : " << map_server_url << LL_ENDL;
 	}
 	
 	// Default male and female avatars allowing the user to choose their avatar on first login.
@@ -3151,6 +3181,18 @@ bool process_login_success_response()
 		LLViewerMedia::openIDSetup(openid_url, openid_token);
 	}
 
+	if(response.has("max-agent-groups")) {		
+		std::string max_agent_groups(response["max-agent-groups"]);
+		gMaxAgentGroups = atoi(max_agent_groups.c_str());
+		LL_INFOS("LLStartup") << "gMaxAgentGroups read from login.cgi: "
+							  << gMaxAgentGroups << LL_ENDL;
+	}
+	else {
+		gMaxAgentGroups = DEFAULT_MAX_AGENT_GROUPS;
+		LL_INFOS("LLStartup") << "using gMaxAgentGroups default: "
+							  << gMaxAgentGroups << LL_ENDL;
+	}
+		
 	bool success = false;
 	// JC: gesture loading done below, when we have an asset system
 	// in place.  Don't delete/clear gUserCredentials until then.
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index be1043cf910a05c8f1f22f7b97d1e3d9b2d7e385..b3d9ef1dcc7805b9a3003ba87fe70c42d3f51c2f 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -70,6 +70,7 @@ typedef enum {
 
 // exported symbols
 extern bool gAgentMovementCompleted;
+extern S32  gMaxAgentGroups;
 extern LLPointer<LLViewerTexture> gStartTexture;
 
 class LLStartUp
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index e9fc25404a56cce34049a97b6a918d95fbec8442..1b8be7a5b23805be39b9b9e530ecbadf52055fe1 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -115,6 +115,7 @@ LLStatusBar::LLStatusBar(const LLRect& rect)
 	mSGBandwidth(NULL),
 	mSGPacketLoss(NULL),
 	mBtnVolume(NULL),
+	mBoxBalance(NULL),
 	mBalance(0),
 	mHealth(100),
 	mSquareMetersCredit(0),
@@ -168,6 +169,9 @@ BOOL LLStatusBar::postBuild()
 	getChild<LLUICtrl>("buyL")->setCommitCallback(
 		boost::bind(&LLStatusBar::onClickBuyCurrency, this));
 
+	mBoxBalance = getChild<LLTextBox>("balance");
+	mBoxBalance->setClickedCallback( &LLStatusBar::onClickBalance, this );
+
 	mBtnVolume = getChild<LLButton>( "volume_btn" );
 	mBtnVolume->setClickedCallback( onClickVolume, this );
 	mBtnVolume->setMouseEnterCallback(boost::bind(&LLStatusBar::onMouseEnterVolume, this));
@@ -304,6 +308,7 @@ void LLStatusBar::setVisibleForMouselook(bool visible)
 {
 	mTextTime->setVisible(visible);
 	getChild<LLUICtrl>("balance_bg")->setVisible(visible);
+	mBoxBalance->setVisible(visible);
 	mBtnVolume->setVisible(visible);
 	mMediaToggle->setVisible(visible);
 	mSGBandwidth->setVisible(visible);
@@ -330,16 +335,15 @@ void LLStatusBar::setBalance(S32 balance)
 
 	std::string money_str = LLResMgr::getInstance()->getMonetaryString( balance );
 
-	LLTextBox* balance_box = getChild<LLTextBox>("balance");
 	LLStringUtil::format_map_t string_args;
 	string_args["[AMT]"] = llformat("%s", money_str.c_str());
 	std::string label_str = getString("buycurrencylabel", string_args);
-	balance_box->setValue(label_str);
+	mBoxBalance->setValue(label_str);
 
 	// Resize the L$ balance background to be wide enough for your balance plus the buy button
 	{
 		const S32 HPAD = 24;
-		LLRect balance_rect = balance_box->getTextBoundingRect();
+		LLRect balance_rect = mBoxBalance->getTextBoundingRect();
 		LLRect buy_rect = getChildView("buyL")->getRect();
 		LLView* balance_bg_view = getChildView("balance_bg");
 		LLRect balance_bg_rect = balance_bg_view->getRect();
@@ -505,6 +509,14 @@ static void onClickVolume(void* data)
 	LLAppViewer::instance()->setMasterSystemAudioMute(!mute_audio);	
 }
 
+//static 
+void LLStatusBar::onClickBalance(void* )
+{
+	// Force a balance request message:
+	LLStatusBar::sendMoneyBalanceRequest();
+	// The refresh of the display (call to setBalance()) will be done by process_money_balance_reply()
+}
+
 //static 
 void LLStatusBar::onClickMediaToggle(void* data)
 {
diff --git a/indra/newview/llstatusbar.h b/indra/newview/llstatusbar.h
index 2388aeb0c85e74c9f0b2fb25947a5a8e195e150c..4ea3183d1820a4c606bbadb45e78ff64923bdd66 100644
--- a/indra/newview/llstatusbar.h
+++ b/indra/newview/llstatusbar.h
@@ -94,6 +94,7 @@ class LLStatusBar
 	void onClickScreen(S32 x, S32 y);
 
 	static void onClickMediaToggle(void* data);
+	static void onClickBalance(void* data);
 
 private:
 	LLTextBox	*mTextTime;
@@ -102,6 +103,7 @@ class LLStatusBar
 	LLStatGraph *mSGPacketLoss;
 
 	LLButton	*mBtnVolume;
+	LLTextBox	*mBoxBalance;
 	LLButton	*mMediaToggle;
 	LLView*		mScriptOut;
 	LLFrameTimer	mClockUpdateTimer;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 328298bda43999c6e9418759072871df88a17327..56e97393508d2c152f46bba7e22ef67274933716 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -564,25 +564,27 @@ void LLFloaterTexturePicker::draw()
 		LLRect interior = border;
 		interior.stretch( -1 ); 
 
+		// If the floater is focused, don't apply its alpha to the texture (STORM-677).
+		const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
 		if( mTexturep )
 		{
 			if( mTexturep->getComponents() == 4 )
 			{
-				gl_rect_2d_checkerboard( interior );
+				gl_rect_2d_checkerboard( interior, alpha );
 			}
 
-			gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep );
+			gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha );
 
 			// Pump the priority
 			mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
 		}
 		else if (!mFallbackImage.isNull())
 		{
-			mFallbackImage->draw(interior);
+			mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha);
 		}
 		else
 		{
-			gl_rect_2d( interior, LLColor4::grey, TRUE );
+			gl_rect_2d( interior, LLColor4::grey % alpha, TRUE );
 
 			// Draw X
 			gl_draw_x(interior, LLColor4::black );
@@ -1263,23 +1265,25 @@ void LLTextureCtrl::draw()
 	LLRect interior = border;
 	interior.stretch( -1 ); 
 
+	// If we're in a focused floater, don't apply the floater's alpha to the texture (STORM-677).
+	const F32 alpha = getTransparencyType() == TT_ACTIVE ? 1.0f : getCurrentTransparency();
 	if( mTexturep )
 	{
 		if( mTexturep->getComponents() == 4 )
 		{
-			gl_rect_2d_checkerboard( interior );
+			gl_rect_2d_checkerboard( interior, alpha );
 		}
 		
-		gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep);
+		gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), mTexturep, UI_VERTEX_COLOR % alpha);
 		mTexturep->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
 	}
 	else if (!mFallbackImage.isNull())
 	{
-		mFallbackImage->draw(interior);
+		mFallbackImage->draw(interior, UI_VERTEX_COLOR % alpha);
 	}
 	else
 	{
-		gl_rect_2d( interior, LLColor4::grey, TRUE );
+		gl_rect_2d( interior, LLColor4::grey % alpha, TRUE );
 
 		// Draw X
 		gl_draw_x( interior, LLColor4::black );
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 13fd51f473f9aa44f43adee8068fb8d1f94e7105..4f63abb152dc59faaca838d5938d28e056034f81 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -27,6 +27,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include <iostream>
+#include <map>
 
 #include "llstl.h"
 
@@ -49,6 +50,7 @@
 #include "llviewertexture.h"
 #include "llviewerregion.h"
 #include "llviewerstats.h"
+#include "llviewerassetstats.h"
 #include "llworld.h"
 
 //////////////////////////////////////////////////////////////////////////////
@@ -143,7 +145,7 @@ class LLTextureFetchWorker : public LLWorkerClass
 	/*virtual*/ bool deleteOK(); // called from update() (WORK THREAD)
 
 	~LLTextureFetchWorker();
-	void relese() { --mActiveCount; }
+	// void relese() { --mActiveCount; }
 
 	S32 callbackHttpGet(const LLChannelDescriptors& channels,
 						 const LLIOPipe::buffer_ptr_t& buffer,
@@ -161,9 +163,11 @@ class LLTextureFetchWorker : public LLWorkerClass
 		mGetReason = reason;
 	}
 
-	void setCanUseHTTP(bool can_use_http) {mCanUseHTTP = can_use_http;}
-	bool getCanUseHTTP()const {return mCanUseHTTP ;}
+	void setCanUseHTTP(bool can_use_http) { mCanUseHTTP = can_use_http; }
+	bool getCanUseHTTP() const { return mCanUseHTTP; }
 
+	LLTextureFetch & getFetcher() { return *mFetcher; }
+	
 protected:
 	LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host,
 						 F32 priority, S32 discard, S32 size);
@@ -277,6 +281,8 @@ class LLTextureFetchWorker : public LLWorkerClass
 	S32 mLastPacket;
 	U16 mTotalPackets;
 	U8 mImageCodec;
+
+	LLViewerAssetStats::duration_t mMetricsStartTime;
 };
 
 //////////////////////////////////////////////////////////////////////////////
@@ -344,6 +350,18 @@ class HTTPGetResponder : public LLCurl::Responder
 			}
 
 			mFetcher->removeFromHTTPQueue(mID, data_size);
+
+			if (worker->mMetricsStartTime)
+			{
+				LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE,
+															  true,
+															  LLImageBase::TYPE_AVATAR_BAKE == worker->mType,
+															  LLViewerAssetStatsFF::get_timestamp() - worker->mMetricsStartTime);
+				worker->mMetricsStartTime = 0;
+			}
+			LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE,
+														 true,
+														 LLImageBase::TYPE_AVATAR_BAKE == worker->mType);
 		}
 		else
 		{
@@ -366,6 +384,229 @@ class HTTPGetResponder : public LLCurl::Responder
 	bool mFollowRedir;
 };
 
+//////////////////////////////////////////////////////////////////////////////
+
+// Cross-thread messaging for asset metrics.
+
+/**
+ * @brief Base class for cross-thread requests made of the fetcher
+ *
+ * I believe the intent of the LLQueuedThread class was to
+ * have these operations derived from LLQueuedThread::QueuedRequest
+ * but the texture fetcher has elected to manage the queue
+ * in its own manner.  So these are free-standing objects which are
+ * managed in simple FIFO order on the mCommands queue of the
+ * LLTextureFetch object.
+ *
+ * What each represents is a simple command sent from an
+ * outside thread into the TextureFetch thread to be processed
+ * in order and in a timely fashion (though not an absolute
+ * higher priority than other operations of the thread).
+ * Each operation derives a new class from the base customizing
+ * members, constructors and the doWork() method to effect
+ * the command.
+ *
+ * The flow is one-directional.  There are two global instances
+ * of the LLViewerAssetStats collector, one for the main program's
+ * thread pointed to by gViewerAssetStatsMain and one for the
+ * TextureFetch thread pointed to by gViewerAssetStatsThread1.
+ * Common operations has each thread recording metrics events
+ * into the respective collector unconcerned with locking and
+ * the state of any other thread.  But when the agent moves into
+ * a different region or the metrics timer expires and a report
+ * needs to be sent back to the grid, messaging across threads
+ * is required to distribute data and perform global actions.
+ * In pseudo-UML, it looks like:
+ *
+ *                       Main                 Thread1
+ *                        .                      .
+ *                        .                      .
+ *                     +-----+                   .
+ *                     | AM  |                   .
+ *                     +--+--+                   .
+ *      +-------+         |                      .
+ *      | Main  |      +--+--+                   .
+ *      |       |      | SRE |---.               .
+ *      | Stats |      +-----+    \              .
+ *      |       |         |        \  (uuid)  +-----+
+ *      | Coll. |      +--+--+      `-------->| SR  |
+ *      +-------+      | MSC |                +--+--+
+ *         | ^         +-----+                   |
+ *         | |  (uuid)  / .                   +-----+ (uuid)
+ *         |  `--------'  .                   | MSC |---------.
+ *         |              .                   +-----+         |
+ *         |           +-----+                   .            v
+ *         |           | TE  |                   .        +-------+
+ *         |           +--+--+                   .        | Thd1  |
+ *         |              |                      .        |       |
+ *         |           +-----+                   .        | Stats |
+ *          `--------->| RSC |                   .        |       |
+ *                     +--+--+                   .        | Coll. |
+ *                        |                      .        +-------+
+ *                     +--+--+                   .            |
+ *                     | SME |---.               .            |
+ *                     +-----+    \              .            |
+ *                        .        \ (clone)  +-----+         |
+ *                        .         `-------->| SM  |         |
+ *                        .                   +--+--+         |
+ *                        .                      |            |
+ *                        .                   +-----+         |
+ *                        .                   | RSC |<--------'
+ *                        .                   +-----+
+ *                        .                      |
+ *                        .                   +-----+
+ *                        .                   | CP  |--> HTTP POST
+ *                        .                   +-----+
+ *                        .                      .
+ *                        .                      .
+ *
+ *
+ * Key:
+ *
+ * SRE - Set Region Enqueued.  Enqueue a 'Set Region' command in
+ *       the other thread providing the new UUID of the region.
+ *       TFReqSetRegion carries the data.
+ * SR  - Set Region.  New region UUID is sent to the thread-local
+ *       collector.
+ * SME - Send Metrics Enqueued.  Enqueue a 'Send Metrics' command
+ *       including an ownership transfer of a cloned LLViewerAssetStats.
+ *       TFReqSendMetrics carries the data.
+ * SM  - Send Metrics.  Global metrics reporting operation.  Takes
+ *       the cloned stats from the command, merges it with the
+ *       thread's local stats, converts to LLSD and sends it on
+ *       to the grid.
+ * AM  - Agent Moved.  Agent has completed some sort of move to a
+ *       new region.
+ * TE  - Timer Expired.  Metrics timer has expired (on the order
+ *       of 10 minutes).
+ * CP  - CURL Post
+ * MSC - Modify Stats Collector.  State change in the thread-local
+ *       collector.  Typically a region change which affects the
+ *       global pointers used to find the 'current stats'.
+ * RSC - Read Stats Collector.  Extract collector data cloning it
+ *       (i.e. deep copy) when necessary.
+ *
+ */
+class LLTextureFetch::TFRequest // : public LLQueuedThread::QueuedRequest
+{
+public:
+	// Default ctors and assignment operator are correct.
+
+	virtual ~TFRequest()
+		{}
+
+	// Patterned after QueuedRequest's method but expected behavior
+	// is different.  Always expected to complete on the first call
+	// and work dispatcher will assume the same and delete the
+	// request after invocation.
+	virtual bool doWork(LLTextureFetch * fetcher) = 0;
+};
+
+namespace 
+{
+
+/**
+ * @brief Implements a 'Set Region' cross-thread command.
+ *
+ * When an agent moves to a new region, subsequent metrics need
+ * to be binned into a new or existing stats collection in 1:1
+ * relationship with the region.  We communicate this region
+ * change across the threads involved in the communication with
+ * this message.
+ *
+ * Corresponds to LLTextureFetch::commandSetRegion()
+ */
+class TFReqSetRegion : public LLTextureFetch::TFRequest
+{
+public:
+	TFReqSetRegion(U64 region_handle)
+		: LLTextureFetch::TFRequest(),
+		  mRegionHandle(region_handle)
+		{}
+	TFReqSetRegion & operator=(const TFReqSetRegion &);	// Not defined
+
+	virtual ~TFReqSetRegion()
+		{}
+
+	virtual bool doWork(LLTextureFetch * fetcher);
+		
+public:
+	const U64 mRegionHandle;
+};
+
+
+/**
+ * @brief Implements a 'Send Metrics' cross-thread command.
+ *
+ * This is the big operation.  The main thread gathers metrics
+ * for a period of minutes into LLViewerAssetStats and other
+ * objects then makes a snapshot of the data by cloning the
+ * collector.  This command transfers the clone, along with a few
+ * additional arguments (UUIDs), handing ownership to the
+ * TextureFetch thread.  It then merges its own data into the
+ * cloned copy, converts to LLSD and kicks off an HTTP POST of
+ * the resulting data to the currently active metrics collector.
+ *
+ * Corresponds to LLTextureFetch::commandSendMetrics()
+ */
+class TFReqSendMetrics : public LLTextureFetch::TFRequest
+{
+public:
+    /**
+	 * Construct the 'Send Metrics' command to have the TextureFetch
+	 * thread add and log metrics data.
+	 *
+	 * @param	caps_url		URL of a "ViewerMetrics" Caps target
+	 *							to receive the data.  Does not have to
+	 *							be associated with a particular region.
+	 *
+	 * @param	session_id		UUID of the agent's session.
+	 *
+	 * @param	agent_id		UUID of the agent.  (Being pure here...)
+	 *
+	 * @param	main_stats		Pointer to a clone of the main thread's
+	 *							LLViewerAssetStats data.  Thread1 takes
+	 *							ownership of the copy and disposes of it
+	 *							when done.
+	 */
+	TFReqSendMetrics(const std::string & caps_url,
+					 const LLUUID & session_id,
+					 const LLUUID & agent_id,
+					 LLViewerAssetStats * main_stats)
+		: LLTextureFetch::TFRequest(),
+		  mCapsURL(caps_url),
+		  mSessionID(session_id),
+		  mAgentID(agent_id),
+		  mMainStats(main_stats)
+		{}
+	TFReqSendMetrics & operator=(const TFReqSendMetrics &);	// Not defined
+
+	virtual ~TFReqSendMetrics();
+
+	virtual bool doWork(LLTextureFetch * fetcher);
+		
+public:
+	const std::string mCapsURL;
+	const LLUUID mSessionID;
+	const LLUUID mAgentID;
+	LLViewerAssetStats * mMainStats;
+};
+
+/*
+ * Examines the merged viewer metrics report and if found to be too long,
+ * will attempt to truncate it in some reasonable fashion.
+ *
+ * @param		max_regions		Limit of regions allowed in report.
+ *
+ * @param		metrics			Full, merged viewer metrics report.
+ *
+ * @returns		If data was truncated, returns true.
+ */
+bool truncate_viewer_metrics(int max_regions, LLSD & metrics);
+
+} // end of anonymous namespace
+
+
 //////////////////////////////////////////////////////////////////////////////
 
 //static
@@ -385,6 +626,9 @@ const char* LLTextureFetchWorker::sStateDescs[] = {
 	"DONE",
 };
 
+// static
+volatile bool LLTextureFetch::svMetricsDataBreak(true);	// Start with a data break
+
 // called from MAIN THREAD
 
 LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
@@ -434,7 +678,8 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mFirstPacket(0),
 	  mLastPacket(-1),
 	  mTotalPackets(0),
-	  mImageCodec(IMG_CODEC_INVALID)
+	  mImageCodec(IMG_CODEC_INVALID),
+	  mMetricsStartTime(0)
 {
 	mCanUseNET = mUrl.empty() ;
 
@@ -602,6 +847,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			return true; // abort
 		}
 	}
+
 	if(mImagePriority < F_ALMOST_ZERO)
 	{
 		if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
@@ -811,7 +1057,15 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			mRequestedDiscard = mDesiredDiscard;
 			mSentRequest = QUEUED;
 			mFetcher->addToNetworkQueue(this);
+			if (! mMetricsStartTime)
+			{
+				mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
+			}
+			LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE,
+														 false,
+														 LLImageBase::TYPE_AVATAR_BAKE == mType);
 			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+			
 			return false;
 		}
 		else
@@ -820,6 +1074,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			//llassert_always(mFetcher->mNetworkQueue.find(mID) != mFetcher->mNetworkQueue.end());
 			// Make certain this is in the network queue
 			//mFetcher->addToNetworkQueue(this);
+			//if (! mMetricsStartTime)
+			//{
+			//   mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
+			//}
+			//LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE, false,
+			//                                             LLImageBase::TYPE_AVATAR_BAKE == mType);
 			//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
 			return false;
 		}
@@ -843,11 +1103,30 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			}
 			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 			mState = DECODE_IMAGE;
-			mWriteToCacheState = SHOULD_WRITE ;
+			mWriteToCacheState = SHOULD_WRITE;
+
+			if (mMetricsStartTime)
+			{
+				LLViewerAssetStatsFF::record_response_thread1(LLViewerAssetType::AT_TEXTURE,
+															  false,
+															  LLImageBase::TYPE_AVATAR_BAKE == mType,
+															  LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime);
+				mMetricsStartTime = 0;
+			}
+			LLViewerAssetStatsFF::record_dequeue_thread1(LLViewerAssetType::AT_TEXTURE,
+														 false,
+														 LLImageBase::TYPE_AVATAR_BAKE == mType);
 		}
 		else
 		{
 			mFetcher->addToNetworkQueue(this); // failsafe
+			if (! mMetricsStartTime)
+			{
+				mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
+			}
+			LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE,
+														 false,
+														 LLImageBase::TYPE_AVATAR_BAKE == mType);
 			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
 		}
 		return false;
@@ -909,6 +1188,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				mState = WAIT_HTTP_REQ;	
 
 				mFetcher->addToHTTPQueue(mID);
+				if (! mMetricsStartTime)
+				{
+					mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
+				}
+				LLViewerAssetStatsFF::record_enqueue_thread1(LLViewerAssetType::AT_TEXTURE,
+															 true,
+															 LLImageBase::TYPE_AVATAR_BAKE == mType);
+
 				// Will call callbackHttpGet when curl request completes
 				std::vector<std::string> headers;
 				headers.push_back("Accept: image/x-j2c");
@@ -1523,7 +1810,7 @@ bool LLTextureFetchWorker::writeToCacheComplete()
 //////////////////////////////////////////////////////////////////////////////
 // public
 
-LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded)
+LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode)
 	: LLWorkerThread("TextureFetch", threaded),
 	  mDebugCount(0),
 	  mDebugPause(FALSE),
@@ -1535,8 +1822,10 @@ LLTextureFetch::LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* image
 	  mImageDecodeThread(imagedecodethread),
 	  mTextureBandwidth(0),
 	  mHTTPTextureBits(0),
-	  mCurlGetRequest(NULL)
+	  mCurlGetRequest(NULL),
+	  mQAMode(qa_mode)
 {
+	mCurlPOSTRequestCount = 0;
 	mMaxBandwidth = gSavedSettings.getF32("ThrottleBandwidthKBPS");
 	mTextureInfo.setUpLogging(gSavedSettings.getBOOL("LogTextureDownloadsToViewerLog"), gSavedSettings.getBOOL("LogTextureDownloadsToSimulator"), gSavedSettings.getU32("TextureLoggingThreshold"));
 }
@@ -1545,6 +1834,13 @@ LLTextureFetch::~LLTextureFetch()
 {
 	clearDeleteList() ;
 
+	while (! mCommands.empty())
+	{
+		TFRequest * req(mCommands.front());
+		mCommands.erase(mCommands.begin());
+		delete req;
+	}
+	
 	// ~LLQueuedThread() called here
 }
 
@@ -1825,8 +2121,76 @@ bool LLTextureFetch::updateRequestPriority(const LLUUID& id, F32 priority)
 	return res;
 }
 
+// Replicates and expands upon the base class's
+// getPending() implementation.  getPending() and
+// runCondition() replicate one another's logic to
+// an extent and are sometimes used for the same
+// function (deciding whether or not to sleep/pause
+// a thread).  So the implementations need to stay
+// in step, at least until this can be refactored and
+// the redundancy eliminated.
+//
+// May be called from any thread
+
+//virtual
+S32 LLTextureFetch::getPending()
+{
+	S32 res;
+	lockData();
+    {
+        LLMutexLock lock(&mQueueMutex);
+        
+        res = mRequestQueue.size();
+        res += mCurlPOSTRequestCount;
+        res += mCommands.size();
+    }
+	unlockData();
+	return res;
+}
+
+// virtual
+bool LLTextureFetch::runCondition()
+{
+	// Caller is holding the lock on LLThread's condition variable.
+	
+	// LLQueuedThread, unlike its base class LLThread, makes this a
+	// private method which is unfortunate.  I want to use it directly
+	// but I'm going to have to re-implement the logic here (or change
+	// declarations, which I don't want to do right now).
+	//
+	// Changes here may need to be reflected in getPending().
+	
+	bool have_no_commands(false);
+	{
+		LLMutexLock lock(&mQueueMutex);
+		
+		have_no_commands = mCommands.empty();
+	}
+	
+    bool have_no_curl_requests(0 == mCurlPOSTRequestCount);
+	
+	return ! (have_no_commands
+			  && have_no_curl_requests
+			  && (mRequestQueue.empty() && mIdleThread));		// From base class
+}
+
 //////////////////////////////////////////////////////////////////////////////
 
+// MAIN THREAD (unthreaded envs), WORKER THREAD (threaded envs)
+void LLTextureFetch::commonUpdate()
+{
+	// Run a cross-thread command, if any.
+	cmdDoWork();
+	
+	// Update Curl on same thread as mCurlGetRequest was constructed
+	S32 processed = mCurlGetRequest->process();
+	if (processed > 0)
+	{
+		lldebugs << "processed: " << processed << " messages." << llendl;
+	}
+}
+
+
 // MAIN THREAD
 //virtual
 S32 LLTextureFetch::update(U32 max_time_ms)
@@ -1852,12 +2216,7 @@ S32 LLTextureFetch::update(U32 max_time_ms)
 
 	if (!mThreaded)
 	{
-		// Update Curl on same thread as mCurlGetRequest was constructed
-		S32 processed = mCurlGetRequest->process();
-		if (processed > 0)
-		{
-			lldebugs << "processed: " << processed << " messages." << llendl;
-		}
+		commonUpdate();
 	}
 
 	return res;
@@ -1912,12 +2271,7 @@ void LLTextureFetch::threadedUpdate()
 	}
 	process_timer.reset();
 	
-	// Update Curl on same thread as mCurlGetRequest was constructed
-	S32 processed = mCurlGetRequest->process();
-	if (processed > 0)
-	{
-		lldebugs << "processed: " << processed << " messages." << llendl;
-	}
+	commonUpdate();
 
 #if 0
 	const F32 INFO_TIME = 1.0f; 
@@ -2367,3 +2721,280 @@ void LLTextureFetch::dump()
 	}
 }
 
+//////////////////////////////////////////////////////////////////////////////
+
+// cross-thread command methods
+
+void LLTextureFetch::commandSetRegion(U64 region_handle)
+{
+	TFReqSetRegion * req = new TFReqSetRegion(region_handle);
+
+	cmdEnqueue(req);
+}
+
+void LLTextureFetch::commandSendMetrics(const std::string & caps_url,
+										const LLUUID & session_id,
+										const LLUUID & agent_id,
+										LLViewerAssetStats * main_stats)
+{
+	TFReqSendMetrics * req = new TFReqSendMetrics(caps_url, session_id, agent_id, main_stats);
+
+	cmdEnqueue(req);
+}
+
+void LLTextureFetch::commandDataBreak()
+{
+	// The pedantically correct way to implement this is to create a command
+	// request object in the above fashion and enqueue it.  However, this is
+	// simple data of an advisorial not operational nature and this case
+	// of shared-write access is tolerable.
+
+	LLTextureFetch::svMetricsDataBreak = true;
+}
+
+void LLTextureFetch::cmdEnqueue(TFRequest * req)
+{
+	lockQueue();
+	mCommands.push_back(req);
+	unlockQueue();
+
+	unpause();
+}
+
+LLTextureFetch::TFRequest * LLTextureFetch::cmdDequeue()
+{
+	TFRequest * ret = 0;
+	
+	lockQueue();
+	if (! mCommands.empty())
+	{
+		ret = mCommands.front();
+		mCommands.erase(mCommands.begin());
+	}
+	unlockQueue();
+
+	return ret;
+}
+
+void LLTextureFetch::cmdDoWork()
+{
+	if (mDebugPause)
+	{
+		return;  // debug: don't do any work
+	}
+
+	TFRequest * req = cmdDequeue();
+	if (req)
+	{
+		// One request per pass should really be enough for this.
+		req->doWork(this);
+		delete req;
+	}
+}
+
+
+//////////////////////////////////////////////////////////////////////////////
+
+// Private (anonymous) class methods implementing the command scheme.
+
+namespace
+{
+
+/**
+ * Implements the 'Set Region' command.
+ *
+ * Thread:  Thread1 (TextureFetch)
+ */
+bool
+TFReqSetRegion::doWork(LLTextureFetch *)
+{
+	LLViewerAssetStatsFF::set_region_thread1(mRegionHandle);
+
+	return true;
+}
+
+
+TFReqSendMetrics::~TFReqSendMetrics()
+{
+	delete mMainStats;
+	mMainStats = 0;
+}
+
+
+/**
+ * Implements the 'Send Metrics' command.  Takes over
+ * ownership of the passed LLViewerAssetStats pointer.
+ *
+ * Thread:  Thread1 (TextureFetch)
+ */
+bool
+TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
+{
+	/*
+	 * HTTP POST responder.  Doesn't do much but tries to
+	 * detect simple breaks in recording the metrics stream.
+	 *
+	 * The 'volatile' modifiers don't indicate signals,
+	 * mmap'd memory or threads, really.  They indicate that
+	 * the referenced data is part of a pseudo-closure for
+	 * this responder rather than being required for correct
+	 * operation.
+     *
+     * We don't try very hard with the POST request.  We give
+     * it one shot and that's more-or-less it.  With a proper
+     * refactoring of the LLQueuedThread usage, these POSTs
+     * could be put in a request object and made more reliable.
+	 */
+	class lcl_responder : public LLCurl::Responder
+	{
+	public:
+		lcl_responder(LLTextureFetch * fetcher,
+					  S32 expected_sequence,
+                      volatile const S32 & live_sequence,
+                      volatile bool & reporting_break,
+					  volatile bool & reporting_started)
+			: LLCurl::Responder(),
+			  mFetcher(fetcher),
+              mExpectedSequence(expected_sequence),
+              mLiveSequence(live_sequence),
+			  mReportingBreak(reporting_break),
+			  mReportingStarted(reporting_started)
+			{
+                mFetcher->incrCurlPOSTCount();
+            }
+        
+        ~lcl_responder()
+            {
+                mFetcher->decrCurlPOSTCount();
+            }
+
+		// virtual
+		void error(U32 status_num, const std::string & reason)
+			{
+                if (mLiveSequence == mExpectedSequence)
+                {
+                    mReportingBreak = true;
+                }
+				LL_WARNS("Texture") << "Break in metrics stream due to POST failure to metrics collection service.  Reason:  "
+									<< reason << LL_ENDL;
+			}
+
+		// virtual
+		void result(const LLSD & content)
+			{
+                if (mLiveSequence == mExpectedSequence)
+                {
+                    mReportingBreak = false;
+                    mReportingStarted = true;
+                }
+			}
+
+	private:
+		LLTextureFetch * mFetcher;
+        S32 mExpectedSequence;
+        volatile const S32 & mLiveSequence;
+		volatile bool & mReportingBreak;
+		volatile bool & mReportingStarted;
+
+	}; // class lcl_responder
+	
+	if (! gViewerAssetStatsThread1)
+		return true;
+
+	static volatile bool reporting_started(false);
+	static volatile S32 report_sequence(0);
+    
+	// We've taken over ownership of the stats copy at this
+	// point.  Get a working reference to it for merging here
+	// but leave it in 'this'.  Destructor will rid us of it.
+	LLViewerAssetStats & main_stats = *mMainStats;
+
+	// Merge existing stats into those from main, convert to LLSD
+	main_stats.merge(*gViewerAssetStatsThread1);
+	LLSD merged_llsd = main_stats.asLLSD(true);
+
+	// Add some additional meta fields to the content
+	merged_llsd["session_id"] = mSessionID;
+	merged_llsd["agent_id"] = mAgentID;
+	merged_llsd["message"] = "ViewerAssetMetrics";					// Identifies the type of metrics
+	merged_llsd["sequence"] = report_sequence;						// Sequence number
+	merged_llsd["initial"] = ! reporting_started;					// Initial data from viewer
+	merged_llsd["break"] = LLTextureFetch::svMetricsDataBreak;		// Break in data prior to this report
+		
+	// Update sequence number
+	if (S32_MAX == ++report_sequence)
+		report_sequence = 0;
+
+	// Limit the size of the stats report if necessary.
+	merged_llsd["truncated"] = truncate_viewer_metrics(10, merged_llsd);
+
+	if (! mCapsURL.empty())
+	{
+		LLCurlRequest::headers_t headers;
+		fetcher->getCurlRequest().post(mCapsURL,
+									   headers,
+									   merged_llsd,
+									   new lcl_responder(fetcher,
+														 report_sequence,
+                                                         report_sequence,
+                                                         LLTextureFetch::svMetricsDataBreak,
+														 reporting_started));
+	}
+	else
+	{
+		LLTextureFetch::svMetricsDataBreak = true;
+	}
+
+	// In QA mode, Metrics submode, log the result for ease of testing
+	if (fetcher->isQAMode())
+	{
+		LL_INFOS("Textures") << merged_llsd << LL_ENDL;
+	}
+
+	gViewerAssetStatsThread1->reset();
+
+	return true;
+}
+
+
+bool
+truncate_viewer_metrics(int max_regions, LLSD & metrics)
+{
+	static const LLSD::String reg_tag("regions");
+	static const LLSD::String duration_tag("duration");
+	
+	LLSD & reg_map(metrics[reg_tag]);
+	if (reg_map.size() <= max_regions)
+	{
+		return false;
+	}
+
+	// Build map of region hashes ordered by duration
+	typedef std::multimap<LLSD::Real, int> reg_ordered_list_t;
+	reg_ordered_list_t regions_by_duration;
+
+	int ind(0);
+	LLSD::array_const_iterator it_end(reg_map.endArray());
+	for (LLSD::array_const_iterator it(reg_map.beginArray()); it_end != it; ++it, ++ind)
+	{
+		LLSD::Real duration = (*it)[duration_tag].asReal();
+		regions_by_duration.insert(reg_ordered_list_t::value_type(duration, ind));
+	}
+
+	// Build a replacement regions array with the longest-persistence regions
+	LLSD new_region(LLSD::emptyArray());
+	reg_ordered_list_t::const_reverse_iterator it2_end(regions_by_duration.rend());
+	reg_ordered_list_t::const_reverse_iterator it2(regions_by_duration.rbegin());
+	for (int i(0); i < max_regions && it2_end != it2; ++i, ++it2)
+	{
+		new_region.append(reg_map[it2->second]);
+	}
+	reg_map = new_region;
+	
+	return true;
+}
+
+} // end of anonymous namespace
+
+
+
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 796109df067b87d0d0214ad9d4ead01bffe705b1..ad00a7ea36fdb6aec9d13e549e1f26b8bcb25f47 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -33,6 +33,7 @@
 #include "llworkerthread.h"
 #include "llcurl.h"
 #include "lltextureinfo.h"
+#include "llapr.h"
 
 class LLViewerTexture;
 class LLTextureFetchWorker;
@@ -40,6 +41,7 @@ class HTTPGetResponder;
 class LLTextureCache;
 class LLImageDecodeThread;
 class LLHost;
+class LLViewerAssetStats;
 
 // Interface class
 class LLTextureFetch : public LLWorkerThread
@@ -48,9 +50,11 @@ class LLTextureFetch : public LLWorkerThread
 	friend class HTTPGetResponder;
 	
 public:
-	LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded);
+	LLTextureFetch(LLTextureCache* cache, LLImageDecodeThread* imagedecodethread, bool threaded, bool qa_mode);
 	~LLTextureFetch();
 
+	class TFRequest;
+	
 	/*virtual*/ S32 update(U32 max_time_ms);	
 	void shutDownTextureCacheThread() ; //called in the main thread after the TextureCacheThread shuts down.
 	void shutDownImageDecodeThread() ;  //called in the main thread after the ImageDecodeThread shuts down.
@@ -77,28 +81,77 @@ class LLTextureFetch : public LLWorkerThread
 	S32 getNumHTTPRequests() ;
 	
 	// Public for access by callbacks
+    S32 getPending();
 	void lockQueue() { mQueueMutex.lock(); }
 	void unlockQueue() { mQueueMutex.unlock(); }
 	LLTextureFetchWorker* getWorker(const LLUUID& id);
 	LLTextureFetchWorker* getWorkerAfterLock(const LLUUID& id);
 
 	LLTextureInfo* getTextureInfo() { return &mTextureInfo; }
-	
+
+	// Commands available to other threads to control metrics gathering operations.
+	void commandSetRegion(U64 region_handle);
+	void commandSendMetrics(const std::string & caps_url,
+							const LLUUID & session_id,
+							const LLUUID & agent_id,
+							LLViewerAssetStats * main_stats);
+	void commandDataBreak();
+
+	LLCurlRequest & getCurlRequest()	{ return *mCurlGetRequest; }
+
+	bool isQAMode() const				{ return mQAMode; }
+
+	// Curl POST counter maintenance
+	inline void incrCurlPOSTCount()		{ mCurlPOSTRequestCount++; }
+	inline void decrCurlPOSTCount()		{ mCurlPOSTRequestCount--; }
+
 protected:
 	void addToNetworkQueue(LLTextureFetchWorker* worker);
 	void removeFromNetworkQueue(LLTextureFetchWorker* worker, bool cancel);
 	void addToHTTPQueue(const LLUUID& id);
 	void removeFromHTTPQueue(const LLUUID& id, S32 received_size = 0);
 	void removeRequest(LLTextureFetchWorker* worker, bool cancel);
-	// Called from worker thread (during doWork)
-	void processCurlRequests();	
+
+	// Overrides from the LLThread tree
+	bool runCondition();
 
 private:
 	void sendRequestListToSimulators();
 	/*virtual*/ void startThread(void);
 	/*virtual*/ void endThread(void);
 	/*virtual*/ void threadedUpdate(void);
-
+	void commonUpdate();
+
+	// Metrics command helpers
+	/**
+	 * Enqueues a command request at the end of the command queue
+	 * and wakes up the thread as needed.
+	 *
+	 * Takes ownership of the TFRequest object.
+	 *
+	 * Method locks the command queue.
+	 */
+	void cmdEnqueue(TFRequest *);
+
+	/**
+	 * Returns the first TFRequest object in the command queue or
+	 * NULL if none is present.
+	 *
+	 * Caller acquires ownership of the object and must dispose of it.
+	 *
+	 * Method locks the command queue.
+	 */
+	TFRequest * cmdDequeue();
+
+	/**
+	 * Processes the first command in the queue disposing of the
+	 * request on completion.  Successive calls are needed to perform
+	 * additional commands.
+	 *
+	 * Method locks the command queue.
+	 */
+	void cmdDoWork();
+	
 public:
 	LLUUID mDebugID;
 	S32 mDebugCount;
@@ -107,7 +160,7 @@ class LLTextureFetch : public LLWorkerThread
 	S32 mBadPacketCount;
 	
 private:
-	LLMutex mQueueMutex;        //to protect mRequestMap only
+	LLMutex mQueueMutex;        //to protect mRequestMap and mCommands only
 	LLMutex mNetworkQueueMutex; //to protect mNetworkQueue, mHTTPTextureQueue and mCancelQueue.
 
 	LLTextureCache* mTextureCache;
@@ -129,6 +182,29 @@ class LLTextureFetch : public LLWorkerThread
 	LLTextureInfo mTextureInfo;
 
 	U32 mHTTPTextureBits;
+
+	// Out-of-band cross-thread command queue.  This command queue
+	// is logically tied to LLQueuedThread's list of
+	// QueuedRequest instances and so must be covered by the
+	// same locks.
+	typedef std::vector<TFRequest *> command_queue_t;
+	command_queue_t mCommands;
+
+	// If true, modifies some behaviors that help with QA tasks.
+	const bool mQAMode;
+
+	// Count of POST requests outstanding.  We maintain the count
+	// indirectly in the CURL request responder's ctor and dtor and
+	// use it when determining whether or not to sleep the thread.  Can't
+	// use the LLCurl module's request counter as it isn't thread compatible.
+	// *NOTE:  Don't mix Atomic and static, apr_initialize must be called first.
+	LLAtomic32<S32> mCurlPOSTRequestCount;
+	
+public:
+	// A probabilistically-correct indicator that the current
+	// attempt to log metrics follows a break in the metrics stream
+	// reporting due to either startup or a problem POSTing data.
+	static volatile bool svMetricsDataBreak;
 };
 
 #endif // LL_LLTEXTUREFETCH_H
diff --git a/indra/newview/lltoast.cpp b/indra/newview/lltoast.cpp
index 8176b8c1f96aea6081e6059488303ceb35d695c9..fd5582d6f70109995b7bb434a170625239514a5e 100644
--- a/indra/newview/lltoast.cpp
+++ b/indra/newview/lltoast.cpp
@@ -113,7 +113,7 @@ LLToast::LLToast(const LLToast::Params& p)
 	mHideBtnPressed(false),
 	mIsTip(p.is_tip),
 	mWrapperPanel(NULL),
-	mIsTransparent(false)
+	mIsFading(false)
 {
 	mTimer.reset(new LLToastLifeTimer(this, p.lifetime_secs));
 
@@ -125,6 +125,9 @@ LLToast::LLToast(const LLToast::Params& p)
 	mWrapperPanel->setMouseEnterCallback(boost::bind(&LLToast::onToastMouseEnter, this));
 	mWrapperPanel->setMouseLeaveCallback(boost::bind(&LLToast::onToastMouseLeave, this));
 
+	setBackgroundOpaque(TRUE); // *TODO: obsolete
+	updateTransparency();
+
 	if(mPanel)
 	{
 		insertPanel(mPanel);
@@ -141,10 +144,6 @@ LLToast::LLToast(const LLToast::Params& p)
 	// init callbacks if present
 	if(!p.on_delete_toast().empty())
 		mOnDeleteToastSignal.connect(p.on_delete_toast());
-
-	// *TODO: This signal doesn't seem to be used at all.
-	if(!p.on_mouse_enter().empty())
-		mOnMouseEnterSignal.connect(p.on_mouse_enter());
 }
 
 void LLToast::reshape(S32 width, S32 height, BOOL called_from_parent)
@@ -183,7 +182,7 @@ LLToast::~LLToast()
 void LLToast::hide()
 {
 	setVisible(FALSE);
-	setTransparentState(false);
+	setFading(false);
 	mTimer->stop();
 	mIsHidden = true;
 	mOnFadeSignal(this); 
@@ -194,7 +193,7 @@ void LLToast::onFocusLost()
 	if(mWrapperPanel && !isBackgroundVisible())
 	{
 		// Lets make wrapper panel behave like a floater
-		setBackgroundOpaque(FALSE);
+		updateTransparency();
 	}
 }
 
@@ -203,7 +202,7 @@ void LLToast::onFocusReceived()
 	if(mWrapperPanel && !isBackgroundVisible())
 	{
 		// Lets make wrapper panel behave like a floater
-		setBackgroundOpaque(TRUE);
+		updateTransparency();
 	}
 }
 
@@ -248,22 +247,24 @@ void LLToast::expire()
 {
 	if (mCanFade)
 	{
-		if (mIsTransparent)
+		if (mIsFading)
 		{
+			// Fade timer expired. Time to hide.
 			hide();
 		}
 		else
 		{
-			setTransparentState(true);
+			// "Life" time has ended. Time to fade.
+			setFading(true);
 			mTimer->restart();
 		}
 	}
 }
 
-void LLToast::setTransparentState(bool transparent)
+void LLToast::setFading(bool transparent)
 {
-	setBackgroundOpaque(!transparent);
-	mIsTransparent = transparent;
+	mIsFading = transparent;
+	updateTransparency();
 
 	if (transparent)
 	{
@@ -279,7 +280,7 @@ F32 LLToast::getTimeLeftToLive()
 {
 	F32 time_to_live = mTimer->getRemainingTimeF32();
 
-	if (!mIsTransparent)
+	if (!mIsFading)
 	{
 		time_to_live += mToastFadingTime;
 	}
@@ -351,7 +352,6 @@ void LLToast::setVisible(BOOL show)
 
 	if(show)
 	{
-		setBackgroundOpaque(TRUE);
 		if(!mTimer->getStarted() && mCanFade)
 		{
 			mTimer->start();
@@ -393,7 +393,7 @@ void LLToast::onToastMouseEnter()
 	{
 		mOnToastHoverSignal(this, MOUSE_ENTER);
 
-		setBackgroundOpaque(TRUE);
+		updateTransparency();
 
 		//toasts fading is management by Screen Channel
 
@@ -402,7 +402,6 @@ void LLToast::onToastMouseEnter()
 		{
 			mHideBtn->setVisible(TRUE);
 		}
-		mOnMouseEnterSignal(this);
 		mToastMouseEnterSignal(this, getValue());
 	}
 }
@@ -423,6 +422,8 @@ void LLToast::onToastMouseLeave()
 	{
 		mOnToastHoverSignal(this, MOUSE_LEAVE);
 
+		updateTransparency();
+
 		//toasts fading is management by Screen Channel
 
 		if(mHideBtn && mHideBtn->getEnabled())
@@ -450,20 +451,45 @@ void LLToast::setBackgroundOpaque(BOOL b)
 	}
 }
 
-void LLNotificationsUI::LLToast::stopFading()
+void LLToast::updateTransparency()
+{
+	ETypeTransparency transparency_type;
+
+	if (mCanFade)
+	{
+		// Notification toasts (including IM/chat toasts) change their transparency on hover.
+		if (isHovered())
+		{
+			transparency_type = TT_ACTIVE;
+		}
+		else
+		{
+			transparency_type = mIsFading ? TT_FADING : TT_INACTIVE;
+		}
+	}
+	else
+	{
+		// Transparency of alert toasts depends on focus.
+		transparency_type = hasFocus() ? TT_ACTIVE : TT_INACTIVE;
+	}
+
+	LLFloater::updateTransparency(transparency_type);
+}
+
+void LLNotificationsUI::LLToast::stopTimer()
 {
 	if(mCanFade)
 	{
-		setTransparentState(false);
+		setFading(false);
 		mTimer->stop();
 	}
 }
 
-void LLNotificationsUI::LLToast::startFading()
+void LLNotificationsUI::LLToast::startTimer()
 {
 	if(mCanFade)
 	{
-		setTransparentState(false);
+		setFading(false);
 		mTimer->start();
 	}
 }
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index fb534561c93b17589850793a8f9b37a3e4e888a7..242f786bf2e9dfbbd34d49111e7e93304adbaac4 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -90,8 +90,7 @@ class LLToast : public LLModalDialog
 										fading_time_secs; // Number of seconds while a toast is transparent
 
 
-		Optional<toast_callback_t>		on_delete_toast,
-										on_mouse_enter;
+		Optional<toast_callback_t>		on_delete_toast;
 		Optional<bool>					can_fade,
 										can_be_stored,
 										enable_hide_btn,
@@ -115,11 +114,11 @@ class LLToast : public LLModalDialog
 
 	//Fading
 
-	/** Stop fading timer */
-	virtual void stopFading();
+	/** Stop lifetime/fading timer */
+	virtual void stopTimer();
 
-	/** Start fading timer */
-	virtual void startFading();
+	/** Start lifetime/fading timer */
+	virtual void startTimer();
 
 	bool isHovered();
 
@@ -182,7 +181,6 @@ class LLToast : public LLModalDialog
 
 	// Registers signals/callbacks for events
 	toast_signal_t mOnFadeSignal;
-	toast_signal_t mOnMouseEnterSignal;
 	toast_signal_t mOnDeleteToastSignal;
 	toast_signal_t mOnToastDestroyedSignal;
 	boost::signals2::connection setOnFadeCallback(toast_callback_t cb) { return mOnFadeSignal.connect(cb); }
@@ -200,6 +198,9 @@ class LLToast : public LLModalDialog
 
 	LLHandle<LLToast> getHandle() { mHandle.bind(this); return mHandle; }
 
+protected:
+	void updateTransparency();
+
 private:
 
 	void onToastMouseEnter();
@@ -208,7 +209,7 @@ class LLToast : public LLModalDialog
 
 	void expire();
 
-	void setTransparentState(bool transparent);
+	void setFading(bool fading);
 
 	LLUUID				mNotificationID;
 	LLUUID				mSessionID;
@@ -234,7 +235,7 @@ class LLToast : public LLModalDialog
 	bool		mHideBtnPressed;
 	bool		mIsHidden;  // this flag is TRUE when a toast has faded or was hidden with (x) button (EXT-1849)
 	bool		mIsTip;
-	bool		mIsTransparent;
+	bool		mIsFading;
 
 	commit_signal_t mToastMouseEnterSignal;
 	commit_signal_t mToastMouseLeaveSignal;
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 371aad64bbd3950e2ce4095769380750c63feccf..75178a6ef8a6fcaa8a560d795d90742be6084636 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -60,7 +60,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
 	LLGroupData groupData;
 	if (!gAgent.getGroupData(payload["group_id"].asUUID(),groupData))
 	{
-		llwarns << "Group notice for unkown group: " << payload["group_id"].asUUID() << llendl;
+		llwarns << "Group notice for unknown group: " << payload["group_id"].asUUID() << llendl;
 	}
 
 	//group icon
@@ -77,6 +77,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
 	from << from_name << "/" << groupData.mName;
 	LLTextBox* pTitleText = getChild<LLTextBox>("title");
 	pTitleText->setValue(from.str());
+	pTitleText->setToolTip(from.str());
 
 	//message subject
 	const std::string& subject = payload["subject"].asString();
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 9017f5ec5574e175e0f07295a15ae28695fd2bfc..3f7dc24ade072686fe286c42806b2e9f4501a63b 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -33,6 +33,7 @@
 
 // library includes
 #include "lldbstrings.h"
+#include "lllslconstants.h"
 #include "llnotifications.h"
 #include "lluiconstants.h"
 #include "llrect.h"
@@ -70,11 +71,11 @@ mCloseNotificationOnDestroy(true)
 	mControlPanel = getChild<LLPanel>("control_panel");
 	BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
 	// customize panel's attributes
-	// is it intended for displaying a tip
+	// is it intended for displaying a tip?
 	mIsTip = notification->getType() == "notifytip";
-	// is it a script dialog
+	// is it a script dialog?
 	mIsScriptDialog = (notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup");
-	// is it a caution
+	// is it a caution?
 	//
 	// caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the
 	// notify xml template specifies that it is a caution
@@ -139,6 +140,12 @@ mCloseNotificationOnDestroy(true)
 			LLSD form_element = form->getElement(i);
 			if (form_element["type"].asString() != "button")
 			{
+				// not a button.
+				continue;
+			}
+			if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN)
+			{
+				// a textbox pretending to be a button.
 				continue;
 			}
 			LLButton* new_button = createButton(form_element, TRUE);
@@ -159,7 +166,7 @@ mCloseNotificationOnDestroy(true)
 			if(h_pad < 2*HPAD)
 			{
 				/*
-				 * Probably it is  a scriptdialog toast
+				 * Probably it is a scriptdialog toast
 				 * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
 				 * In last case set default h_pad to avoid heaping of buttons 
 				 */
@@ -261,7 +268,7 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt
 	}
 	else if (mIsScriptDialog && is_ignore_btn)
 	{
-		// this is ignore button,make it smaller
+		// this is ignore button, make it smaller
 		p.rect.height = BTN_HEIGHT_SMALL;
 		p.rect.width = 1;
 		p.auto_resize = true;
diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2529ec865a9b937f6dd4c96a3c91bd7909d5cfca
--- /dev/null
+++ b/indra/newview/lltoastscripttextbox.cpp
@@ -0,0 +1,121 @@
+/**
+ * @file lltoastscripttextbox.cpp
+ * @brief Panel for script llTextBox dialogs
+ *
+ * $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$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "lltoastscripttextbox.h"
+
+#include "llfocusmgr.h"
+
+#include "llbutton.h"
+#include "llnotifications.h"
+#include "llviewertexteditor.h"
+
+#include "llavatarnamecache.h"
+#include "lluiconstants.h"
+#include "llui.h"
+#include "llviewercontrol.h"
+#include "lltrans.h"
+#include "llstyle.h"
+
+#include "llglheaders.h"
+#include "llagent.h"
+
+const S32 LLToastScriptTextbox::DEFAULT_MESSAGE_MAX_LINE_COUNT= 7;
+
+LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification)
+:	LLToastPanel(notification)
+{
+	buildFromFile( "panel_notify_textbox.xml");
+
+	LLTextEditor* text_editorp = getChild<LLTextEditor>("text_editor_box");
+	text_editorp->setValue(notification->getMessage());
+
+	getChild<LLButton>("ignore_btn")->setClickedCallback(boost::bind(&LLToastScriptTextbox::onClickIgnore, this));
+
+	const LLSD& payload = notification->getPayload();
+
+	//message body
+	const std::string& message = payload["message"].asString();
+
+	LLViewerTextEditor* pMessageText = getChild<LLViewerTextEditor>("message");
+	pMessageText->clear();
+
+	LLStyle::Params style;
+	style.font = pMessageText->getDefaultFont();
+	pMessageText->appendText(message, TRUE, style);
+
+	//submit button
+	LLButton* pSubmitBtn = getChild<LLButton>("btn_submit");
+	pSubmitBtn->setClickedCallback((boost::bind(&LLToastScriptTextbox::onClickSubmit, this)));
+	setDefaultBtn(pSubmitBtn);
+
+	S32 maxLinesCount;
+	std::istringstream ss( getString("message_max_lines_count") );
+	if (!(ss >> maxLinesCount))
+	{
+		maxLinesCount = DEFAULT_MESSAGE_MAX_LINE_COUNT;
+	}
+	//snapToMessageHeight(pMessageText, maxLinesCount);
+}
+
+// virtual
+LLToastScriptTextbox::~LLToastScriptTextbox()
+{
+}
+
+void LLToastScriptTextbox::close()
+{
+	die();
+}
+
+#include "lllslconstants.h"
+void LLToastScriptTextbox::onClickSubmit()
+{
+	LLViewerTextEditor* pMessageText = getChild<LLViewerTextEditor>("message");
+
+	if (pMessageText)
+	{
+		LLSD response = mNotification->getResponseTemplate();
+		response[TEXTBOX_MAGIC_TOKEN] = pMessageText->getText();
+		if (response[TEXTBOX_MAGIC_TOKEN].asString().empty())
+		{
+			// so we can distinguish between a successfully
+			// submitted blank textbox, and an ignored toast
+			response[TEXTBOX_MAGIC_TOKEN] = true;
+		}
+		mNotification->respond(response);
+		close();
+		llwarns << response << llendl;
+	}
+}
+
+void LLToastScriptTextbox::onClickIgnore()
+{
+	LLSD response = mNotification->getResponseTemplate();
+	mNotification->respond(response);
+	close();
+}
diff --git a/indra/newview/lltoastscripttextbox.h b/indra/newview/lltoastscripttextbox.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e69d8834d8c6572050fdd75883de5594ed71612
--- /dev/null
+++ b/indra/newview/lltoastscripttextbox.h
@@ -0,0 +1,59 @@
+/**
+ * @file lltoastscripttextbox.h
+ * @brief Panel for script llTextBox dialogs
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLTOASTSCRIPTTEXTBOX_H
+#define LL_LLTOASTSCRIPTTEXTBOX_H
+
+#include "lltoastnotifypanel.h"
+#include "llnotificationptr.h"
+
+/**
+ * Toast panel for scripted llTextbox notifications.
+ */
+class LLToastScriptTextbox
+:	public LLToastPanel
+{
+public:
+	void close();
+
+	static bool onNewNotification(const LLSD& notification);
+
+	// Non-transient messages.  You can specify non-default button
+	// layouts (like one for script dialogs) by passing various
+	// numbers in for "layout".
+	LLToastScriptTextbox(const LLNotificationPtr& notification);
+
+	/*virtual*/ ~LLToastScriptTextbox();
+
+private:
+
+	void onClickSubmit();
+	void onClickIgnore();
+
+	static const S32 DEFAULT_MESSAGE_MAX_LINE_COUNT;
+};
+
+#endif
diff --git a/indra/newview/lltool.cpp b/indra/newview/lltool.cpp
index 282d4e19c667a636a733d36ad5f4702989531605..2d8ce95347657a412485416dbdfe91a45e46f0a7 100644
--- a/indra/newview/lltool.cpp
+++ b/indra/newview/lltool.cpp
@@ -33,6 +33,7 @@
 #include "llview.h"
 
 #include "llviewerwindow.h"
+#include "llviewercontrol.h"
 #include "lltoolcomp.h"
 #include "lltoolfocus.h"
 #include "llfocusmgr.h"
@@ -190,9 +191,12 @@ LLTool* LLTool::getOverrideTool(MASK mask)
 	{
 		return NULL;
 	}
-	if (mask & MASK_ALT)
+	if (gSavedSettings.getBOOL("EnableAltZoom"))
 	{
-		return LLToolCamera::getInstance();
+		if (mask & MASK_ALT)
+		{
+			return LLToolCamera::getInstance();
+		}
 	}
 	return NULL;
 }
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index ca80a1db795752f7439e45b9e16e37df007840aa..964b17d3a665b1bc1f3cadc4d12cb86a30db15d8 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -244,13 +244,13 @@ BOOL LLVisualParamHint::render()
 //-----------------------------------------------------------------------------
 // draw()
 //-----------------------------------------------------------------------------
-void LLVisualParamHint::draw()
+void LLVisualParamHint::draw(F32 alpha)
 {
 	if (!mIsVisible) return;
 
 	gGL.getTexUnit(0)->bind(this);
 
-	gGL.color4f(1.f, 1.f, 1.f, 1.f);
+	gGL.color4f(1.f, 1.f, 1.f, alpha);
 
 	LLGLSUIDefault gls_ui;
 	gGL.begin(LLRender::QUADS);
diff --git a/indra/newview/lltoolmorph.h b/indra/newview/lltoolmorph.h
index 59201233ae721ee7a714b7d84a83027d4c2fefa6..a6889be1510c0b57901a95c4d558ecee13e6990d 100644
--- a/indra/newview/lltoolmorph.h
+++ b/indra/newview/lltoolmorph.h
@@ -68,7 +68,7 @@ class LLVisualParamHint : public LLViewerDynamicTexture
 	BOOL					render();
 	void					requestUpdate( S32 delay_frames ) {mNeedsUpdate = TRUE; mDelayFrames = delay_frames; }
 	void					setUpdateDelayFrames( S32 delay_frames ) { mDelayFrames = delay_frames; }
-	void					draw();
+	void					draw(F32 alpha);
 	
 	LLViewerVisualParam*	getVisualParam() { return mVisualParam; }
 	F32						getVisualParamWeight() { return mVisualParamWeight; }
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index d992d808c7d4a07a9939f0e7e84a49ad09cd1e22..562b9219b4427dfd1cbf0277a1ab71987d2ad9ae 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -81,9 +81,11 @@ LLToolPie::LLToolPie()
 :	LLTool(std::string("Pie")),
 	mGrabMouseButtonDown( FALSE ),
 	mMouseOutsideSlop( FALSE ),
-	mClickAction(0)
-{ }
-
+	mClickAction(0),
+	mClickActionBuyEnabled( gSavedSettings.getBOOL("ClickActionBuyEnabled") ),
+	mClickActionPayEnabled( gSavedSettings.getBOOL("ClickActionPayEnabled") )
+{
+}
 
 BOOL LLToolPie::handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down)
 {
@@ -211,12 +213,28 @@ BOOL LLToolPie::pickLeftMouseDownCallback()
 				} // else nothing (fall through to touch)
 			}
 		case CLICK_ACTION_PAY:
-			if ((object && object->flagTakesMoney())
-				|| (parent && parent->flagTakesMoney()))
+			if ( mClickActionPayEnabled )
+			{
+				if ((object && object->flagTakesMoney())
+					|| (parent && parent->flagTakesMoney()))
+				{
+					// pay event goes to object actually clicked on
+					mClickActionObject = object;
+					mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);
+					if (LLSelectMgr::getInstance()->selectGetAllValid())
+					{
+						// call this right away, since we have all the info we need to continue the action
+						selectionPropertiesReceived();
+					}
+					return TRUE;
+				}
+			}
+			break;
+		case CLICK_ACTION_BUY:
+			if ( mClickActionBuyEnabled )
 			{
-				// pay event goes to object actually clicked on
-				mClickActionObject = object;
-				mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);
+				mClickActionObject = parent;
+				mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE, TRUE);
 				if (LLSelectMgr::getInstance()->selectGetAllValid())
 				{
 					// call this right away, since we have all the info we need to continue the action
@@ -225,15 +243,6 @@ BOOL LLToolPie::pickLeftMouseDownCallback()
 				return TRUE;
 			}
 			break;
-		case CLICK_ACTION_BUY:
-			mClickActionObject = parent;
-			mLeftClickSelection = LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE, TRUE);
-			if (LLSelectMgr::getInstance()->selectGetAllValid())
-			{
-				// call this right away, since we have all the info we need to continue the action
-				selectionPropertiesReceived();
-			}
-			return TRUE;
 		case CLICK_ACTION_OPEN:
 			if (parent && parent->allowOpen())
 			{
@@ -393,7 +402,7 @@ U8 final_click_action(LLViewerObject* obj)
 	return click_action;
 }
 
-ECursorType cursor_from_object(LLViewerObject* object)
+ECursorType LLToolPie::cursorFromObject(LLViewerObject* object)
 {
 	LLViewerObject* parent = NULL;
 	if (object)
@@ -413,7 +422,10 @@ ECursorType cursor_from_object(LLViewerObject* object)
 		}
 		break;
 	case CLICK_ACTION_BUY:
-		cursor = UI_CURSOR_TOOLBUY;
+		if ( mClickActionBuyEnabled )
+		{
+			cursor = UI_CURSOR_TOOLBUY;
+		}
 		break;
 	case CLICK_ACTION_OPEN:
 		// Open always opens the parent.
@@ -423,10 +435,13 @@ ECursorType cursor_from_object(LLViewerObject* object)
 		}
 		break;
 	case CLICK_ACTION_PAY:	
-		if ((object && object->flagTakesMoney())
-			|| (parent && parent->flagTakesMoney()))
+		if ( mClickActionPayEnabled )
 		{
-			cursor = UI_CURSOR_TOOLBUY;
+			if ((object && object->flagTakesMoney())
+				|| (parent && parent->flagTakesMoney()))
+			{
+				cursor = UI_CURSOR_TOOLBUY;
+			}
 		}
 		break;
 	case CLICK_ACTION_ZOOM:
@@ -474,10 +489,16 @@ void LLToolPie::selectionPropertiesReceived()
 			switch (click_action)
 			{
 			case CLICK_ACTION_BUY:
-				handle_buy();
+				if ( LLToolPie::getInstance()->mClickActionBuyEnabled )
+				{
+					handle_buy();
+				}
 				break;
 			case CLICK_ACTION_PAY:
-				handle_give_money_dialog();
+				if ( LLToolPie::getInstance()->mClickActionPayEnabled )
+				{
+					handle_give_money_dialog();
+				}
 				break;
 			case CLICK_ACTION_OPEN:
 				LLFloaterReg::showInstance("openobject");
@@ -518,7 +539,7 @@ BOOL LLToolPie::handleHover(S32 x, S32 y, MASK mask)
 	else if (click_action_object && useClickAction(mask, click_action_object, click_action_object->getRootEdit()))
 	{
 		show_highlight = true;
-		ECursorType cursor = cursor_from_object(click_action_object);
+		ECursorType cursor = cursorFromObject(click_action_object);
 		gViewerWindow->setCursor(cursor);
 		lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPie (inactive)" << llendl;
 	}
@@ -571,7 +592,9 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
 	{
 		switch(click_action)
 		{
+			// NOTE: mClickActionBuyEnabled flag enables/disables BUY action but setting cursor to default is okay
 		case CLICK_ACTION_BUY:
+			// NOTE: mClickActionPayEnabled flag enables/disables PAY action but setting cursor to default is okay
 		case CLICK_ACTION_PAY:
 		case CLICK_ACTION_OPEN:
 		case CLICK_ACTION_ZOOM:
@@ -1228,15 +1251,17 @@ void LLToolPie::handleDeselect()
 
 LLTool* LLToolPie::getOverrideTool(MASK mask)
 {
-	if (mask == MASK_CONTROL)
+	if (gSavedSettings.getBOOL("EnableGrab"))
 	{
-		return LLToolGrab::getInstance();
-	}
-	else if (mask == (MASK_CONTROL | MASK_SHIFT))
-	{
-		return LLToolGrab::getInstance();
+		if (mask == MASK_CONTROL)
+		{
+			return LLToolGrab::getInstance();
+		}
+		else if (mask == (MASK_CONTROL | MASK_SHIFT))
+		{
+			return LLToolGrab::getInstance();
+		}
 	}
-
 	return LLTool::getOverrideTool(mask);
 }
 
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 65cb3e36a768d140375a97090a48f295c4d185b5..77200a1da40a2bcc1c52e66aa031291959e6a85f 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -80,6 +80,7 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
 	BOOL useClickAction		(MASK mask, LLViewerObject* object,LLViewerObject* parent);
 	
 	void showVisualContextMenuEffect();
+	ECursorType cursorFromObject(LLViewerObject* object);
 
 	bool handleMediaClick(const LLPickInfo& info);
 	bool handleMediaHover(const LLPickInfo& info);
@@ -96,8 +97,8 @@ class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
 	LLPointer<LLViewerObject> mClickActionObject;
 	U8					mClickAction;
 	LLSafeHandle<LLObjectSelection> mLeftClickSelection;
-
+	BOOL				mClickActionBuyEnabled;
+	BOOL				mClickActionPayEnabled;
 };
 
-
 #endif
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index c3dd17def90f98d9391db9c7f1ea867db50c18b3..983108391f8fa904156fbd018a8e08576be79d3c 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -109,6 +109,8 @@ void LLTracker::stopTracking(void* userdata)
 // static virtual
 void LLTracker::drawHUDArrow()
 {
+	if (!gSavedSettings.getBOOL("RenderTrackerBeacon")) return;
+
 	static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
 	
 	/* tracking autopilot destination has been disabled 
@@ -155,7 +157,7 @@ void LLTracker::drawHUDArrow()
 // static 
 void LLTracker::render3D()
 {
-	if (!gFloaterWorldMap)
+	if (!gFloaterWorldMap || !gSavedSettings.getBOOL("RenderTrackerBeacon"))
 	{
 		return;
 	}
diff --git a/indra/newview/lltransientfloatermgr.cpp b/indra/newview/lltransientfloatermgr.cpp
index 78dd602f39bbde39b9bdd3f514882fedde3d20fe..c648a6a28adc892ced97913667ebcf0cb61c36b3 100644
--- a/indra/newview/lltransientfloatermgr.cpp
+++ b/indra/newview/lltransientfloatermgr.cpp
@@ -36,8 +36,11 @@
 
 LLTransientFloaterMgr::LLTransientFloaterMgr()
 {
-	gViewerWindow->getRootView()->addMouseDownCallback(boost::bind(
-			&LLTransientFloaterMgr::leftMouseClickCallback, this, _1, _2, _3));
+	if(gViewerWindow)
+	{
+		gViewerWindow->getRootView()->getChild<LLUICtrl>("popup_holder")->setMouseDownCallback(boost::bind(
+			&LLTransientFloaterMgr::leftMouseClickCallback, this, _2, _3, _4));
+	}
 
 	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(GLOBAL, std::set<LLView*>()));
 	mGroupControls.insert(std::pair<ETransientGroup, std::set<LLView*> >(DOCKED, std::set<LLView*>()));
diff --git a/indra/newview/lltranslate.cpp b/indra/newview/lltranslate.cpp
index 050e34ade9ab137afb56fc864a8e437591998e7c..8ccfdb071b663a0c5d73955c0c3dafef5f13976b 100644
--- a/indra/newview/lltranslate.cpp
+++ b/indra/newview/lltranslate.cpp
@@ -36,7 +36,7 @@
 
 #include "llbufferstream.h"
 #include "llui.h"
-#include "llversionviewer.h"
+#include "llversioninfo.h"
 #include "llviewercontrol.h"
 
 #include "jsoncpp/reader.h"
@@ -64,11 +64,11 @@ void LLTranslate::translateMessage(LLHTTPClient::ResponderPtr &result, const std
 	getTranslateUrl(url, from_lang, to_lang, mesg);
 
     std::string user_agent = llformat("%s %d.%d.%d (%d)",
-		LL_CHANNEL,
-		LL_VERSION_MAJOR,
-		LL_VERSION_MINOR,
-		LL_VERSION_PATCH,
-		LL_VERSION_BUILD );
+		LLVersionInfo::getChannel().c_str(),
+		LLVersionInfo::getMajor(),
+		LLVersionInfo::getMinor(),
+		LLVersionInfo::getPatch(),
+		LLVersionInfo::getBuild());
 
 	if (!m_Header.size())
 	{
diff --git a/indra/newview/llversioninfo.cpp b/indra/newview/llversioninfo.cpp
index 733d05834a13d89d34462cbc2c3c3023a78f8481..673d0c24cf33ebea80d0a5ad98cfa191254f1bff 100644
--- a/indra/newview/llversioninfo.cpp
+++ b/indra/newview/llversioninfo.cpp
@@ -95,9 +95,42 @@ const std::string &LLVersionInfo::getShortVersion()
 	return version;
 }
 
+namespace
+{
+	/// Storage of the channel name the viewer is using.
+	//  The channel name is set by hardcoded constant, 
+	//  or by calling LLVersionInfo::resetChannel()
+	std::string sWorkingChannelName(LL_CHANNEL);
+
+	// Storage for the "version and channel" string.
+	// This will get reset too.
+	std::string sVersionChannel("");
+}
+
+//static
+const std::string &LLVersionInfo::getChannelAndVersion()
+{
+	if (sVersionChannel.empty())
+	{
+		// cache the version string
+		std::ostringstream stream;
+		stream << LLVersionInfo::getChannel()
+			   << " "
+			   << LLVersionInfo::getVersion();
+		sVersionChannel = stream.str();
+	}
+
+	return sVersionChannel;
+}
+
 //static
 const std::string &LLVersionInfo::getChannel()
 {
-	static std::string name(LL_CHANNEL);
-	return name;
+	return sWorkingChannelName;
+}
+
+void LLVersionInfo::resetChannel(const std::string& channel)
+{
+	sWorkingChannelName = channel;
+	sVersionChannel.clear(); // Reset version and channel string til next use.
 }
diff --git a/indra/newview/llversioninfo.h b/indra/newview/llversioninfo.h
index e468b6ae4ec9707068adff45176018af16edfc12..6f64544f3bedaf5f57bcc27cbf73dbcc7e82618d 100644
--- a/indra/newview/llversioninfo.h
+++ b/indra/newview/llversioninfo.h
@@ -58,8 +58,15 @@ class LLVersionInfo
 	/// return the viewer version as a string like "2.0.0"
 	static const std::string &getShortVersion();
 
+	/// return the viewer version and channel as a string
+	/// like "Second Life Release 2.0.0.200030"
+	static const std::string &getChannelAndVersion();
+
 	/// return the channel name, e.g. "Second Life"
 	static const std::string &getChannel();
+	
+	/// reset the channel name used by the viewer.
+	static void resetChannel(const std::string& channel);
 };
 
 #endif
diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ad7725b3e381b79d06e61bbb86accf1f7d27abd
--- /dev/null
+++ b/indra/newview/llviewerassetstats.cpp
@@ -0,0 +1,619 @@
+/** 
+ * @file llviewerassetstats.cpp
+ * @brief 
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewerassetstats.h"
+#include "llregionhandle.h"
+
+#include "stdtypes.h"
+
+/*
+ * Classes and utility functions for per-thread and per-region
+ * asset and experiential metrics to be aggregated grid-wide.
+ *
+ * The basic metrics grouping is LLViewerAssetStats::PerRegionStats.
+ * This provides various counters and simple statistics for asset
+ * fetches binned into a few categories.  One of these is maintained
+ * for each region encountered and the 'current' region is available
+ * as a simple reference.  Each thread (presently two) interested
+ * in participating in these stats gets an instance of the
+ * LLViewerAssetStats class so that threads are completely
+ * independent.
+ *
+ * The idea of a current region is used for simplicity and speed
+ * of categorization.  Each metrics event could have taken a
+ * region uuid argument resulting in a suitable lookup.  Arguments
+ * against this design include:
+ *
+ *  -  Region uuid not trivially available to caller.
+ *  -  Cost (cpu, disruption in real work flow) too high.
+ *  -  Additional precision not really meaningful.
+ *
+ * By itself, the LLViewerAssetStats class is thread- and
+ * viewer-agnostic and can be used anywhere without assumptions
+ * of global pointers and other context.  For the viewer,
+ * a set of free functions are provided in the namespace
+ * LLViewerAssetStatsFF which *do* implement viewer-native
+ * policies about per-thread globals and will do correct
+ * defensive tests of same.
+ *
+ * References
+ *
+ * Project:
+ *   <TBD>
+ *
+ * Test Plan:
+ *   <TBD>
+ *
+ * Jiras:
+ *   <TBD>
+ *
+ * Unit Tests:
+ *   indra/newview/tests/llviewerassetstats_test.cpp
+ *
+ */
+
+
+// ------------------------------------------------------
+// Global data definitions
+// ------------------------------------------------------
+LLViewerAssetStats * gViewerAssetStatsMain(0);
+LLViewerAssetStats * gViewerAssetStatsThread1(0);
+
+
+// ------------------------------------------------------
+// Local declarations
+// ------------------------------------------------------
+namespace
+{
+
+static LLViewerAssetStats::EViewerAssetCategories
+asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp);
+
+}
+
+// ------------------------------------------------------
+// LLViewerAssetStats::PerRegionStats struct definition
+// ------------------------------------------------------
+void
+LLViewerAssetStats::PerRegionStats::reset()
+{
+	for (int i(0); i < LL_ARRAY_SIZE(mRequests); ++i)
+	{
+		mRequests[i].mEnqueued.reset();
+		mRequests[i].mDequeued.reset();
+		mRequests[i].mResponse.reset();
+	}
+	mFPS.reset();
+	
+	mTotalTime = 0;
+	mStartTimestamp = LLViewerAssetStatsFF::get_timestamp();
+}
+
+
+void
+LLViewerAssetStats::PerRegionStats::merge(const LLViewerAssetStats::PerRegionStats & src)
+{
+	// mRegionHandle, mTotalTime, mStartTimestamp are left alone.
+	
+	// mFPS
+	if (src.mFPS.getCount() && mFPS.getCount())
+	{
+		mFPS.merge(src.mFPS);
+	}
+
+	// Requests
+	for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i)
+	{
+		mRequests[i].mEnqueued.merge(src.mRequests[i].mEnqueued);
+		mRequests[i].mDequeued.merge(src.mRequests[i].mDequeued);
+		mRequests[i].mResponse.merge(src.mRequests[i].mResponse);
+	}
+}
+
+
+void
+LLViewerAssetStats::PerRegionStats::accumulateTime(duration_t now)
+{
+	mTotalTime += (now - mStartTimestamp);
+	mStartTimestamp = now;
+}
+
+
+// ------------------------------------------------------
+// LLViewerAssetStats class definition
+// ------------------------------------------------------
+LLViewerAssetStats::LLViewerAssetStats()
+	: mRegionHandle(U64(0))
+{
+	reset();
+}
+
+
+LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src)
+	: mRegionHandle(src.mRegionHandle),
+	  mResetTimestamp(src.mResetTimestamp)
+{
+	const PerRegionContainer::const_iterator it_end(src.mRegionStats.end());
+	for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it)
+	{
+		mRegionStats[it->first] = new PerRegionStats(*it->second);
+	}
+	mCurRegionStats = mRegionStats[mRegionHandle];
+}
+
+
+void
+LLViewerAssetStats::reset()
+{
+	// Empty the map of all region stats
+	mRegionStats.clear();
+
+	// If we have a current stats, reset it, otherwise, as at construction,
+	// create a new one as we must always have a current stats block.
+	if (mCurRegionStats)
+	{
+		mCurRegionStats->reset();
+	}
+	else
+	{
+		mCurRegionStats = new PerRegionStats(mRegionHandle);
+	}
+
+	// And add reference to map
+	mRegionStats[mRegionHandle] = mCurRegionStats;
+
+	// Start timestamp consistent with per-region collector
+	mResetTimestamp = mCurRegionStats->mStartTimestamp;
+}
+
+
+void
+LLViewerAssetStats::setRegion(region_handle_t region_handle)
+{
+	if (region_handle == mRegionHandle)
+	{
+		// Already active, ignore.
+		return;
+	}
+
+	// Get duration for current set
+	const duration_t now = LLViewerAssetStatsFF::get_timestamp();
+	mCurRegionStats->accumulateTime(now);
+
+	// Prepare new set
+	PerRegionContainer::iterator new_stats = mRegionStats.find(region_handle);
+	if (mRegionStats.end() == new_stats)
+	{
+		// Haven't seen this region_id before, create a new block and make it current.
+		mCurRegionStats = new PerRegionStats(region_handle);
+		mRegionStats[region_handle] = mCurRegionStats;
+	}
+	else
+	{
+		mCurRegionStats = new_stats->second;
+	}
+	mCurRegionStats->mStartTimestamp = now;
+	mRegionHandle = region_handle;
+}
+
+
+void
+LLViewerAssetStats::recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp)
+{
+	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
+	
+	++(mCurRegionStats->mRequests[int(eac)].mEnqueued);
+}
+	
+void
+LLViewerAssetStats::recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp)
+{
+	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
+
+	++(mCurRegionStats->mRequests[int(eac)].mDequeued);
+}
+
+void
+LLViewerAssetStats::recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, duration_t duration)
+{
+	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
+
+	mCurRegionStats->mRequests[int(eac)].mResponse.record(duration);
+}
+
+void
+LLViewerAssetStats::recordFPS(F32 fps)
+{
+	mCurRegionStats->mFPS.record(fps);
+}
+
+LLSD
+LLViewerAssetStats::asLLSD(bool compact_output)
+{
+	// Top-level tags
+	static const LLSD::String tags[EVACCount] = 
+		{
+			LLSD::String("get_texture_temp_http"),
+			LLSD::String("get_texture_temp_udp"),
+			LLSD::String("get_texture_non_temp_http"),
+			LLSD::String("get_texture_non_temp_udp"),
+			LLSD::String("get_wearable_udp"),
+			LLSD::String("get_sound_udp"),
+			LLSD::String("get_gesture_udp"),
+			LLSD::String("get_other")
+		};
+
+	// Stats Group Sub-tags.
+	static const LLSD::String enq_tag("enqueued");
+	static const LLSD::String deq_tag("dequeued");
+	static const LLSD::String rcnt_tag("resp_count");
+	static const LLSD::String rmin_tag("resp_min");
+	static const LLSD::String rmax_tag("resp_max");
+	static const LLSD::String rmean_tag("resp_mean");
+
+	// MMM Group Sub-tags.
+	static const LLSD::String cnt_tag("count");
+	static const LLSD::String min_tag("min");
+	static const LLSD::String max_tag("max");
+	static const LLSD::String mean_tag("mean");
+
+	const duration_t now = LLViewerAssetStatsFF::get_timestamp();
+	mCurRegionStats->accumulateTime(now);
+
+	LLSD regions = LLSD::emptyArray();
+	for (PerRegionContainer::iterator it = mRegionStats.begin();
+		 mRegionStats.end() != it;
+		 ++it)
+	{
+		if (0 == it->first)
+		{
+			// Never emit NULL UUID/handle in results.
+			continue;
+		}
+
+		PerRegionStats & stats = *it->second;
+		
+		LLSD reg_stat = LLSD::emptyMap();
+		
+		for (int i = 0; i < LL_ARRAY_SIZE(tags); ++i)
+		{
+			PerRegionStats::prs_group & group(stats.mRequests[i]);
+			
+			if ((! compact_output) ||
+				group.mEnqueued.getCount() ||
+				group.mDequeued.getCount() ||
+				group.mResponse.getCount())
+			{
+				LLSD & slot = reg_stat[tags[i]];
+				slot = LLSD::emptyMap();
+				slot[enq_tag] = LLSD(S32(stats.mRequests[i].mEnqueued.getCount()));
+				slot[deq_tag] = LLSD(S32(stats.mRequests[i].mDequeued.getCount()));
+				slot[rcnt_tag] = LLSD(S32(stats.mRequests[i].mResponse.getCount()));
+				slot[rmin_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMin() * 1.0e-6));
+				slot[rmax_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMax() * 1.0e-6));
+				slot[rmean_tag] = LLSD(F64(stats.mRequests[i].mResponse.getMean() * 1.0e-6));
+			}
+		}
+
+		if ((! compact_output) || stats.mFPS.getCount())
+		{
+			LLSD & slot = reg_stat["fps"];
+			slot = LLSD::emptyMap();
+			slot[cnt_tag] = LLSD(S32(stats.mFPS.getCount()));
+			slot[min_tag] = LLSD(F64(stats.mFPS.getMin()));
+			slot[max_tag] = LLSD(F64(stats.mFPS.getMax()));
+			slot[mean_tag] = LLSD(F64(stats.mFPS.getMean()));
+		}
+
+		U32 grid_x(0), grid_y(0);
+		grid_from_region_handle(it->first, &grid_x, &grid_y);
+		reg_stat["grid_x"] = LLSD::Integer(grid_x);
+		reg_stat["grid_y"] = LLSD::Integer(grid_y);
+		reg_stat["duration"] = LLSD::Real(stats.mTotalTime * 1.0e-6);		
+		regions.append(reg_stat);
+	}
+
+	LLSD ret = LLSD::emptyMap();
+	ret["regions"] = regions;
+	ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6);
+	
+	return ret;
+}
+
+void
+LLViewerAssetStats::merge(const LLViewerAssetStats & src)
+{
+	// mRegionHandle, mCurRegionStats and mResetTimestamp are left untouched.
+	// Just merge the stats bodies
+
+	const PerRegionContainer::const_iterator it_end(src.mRegionStats.end());
+	for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it)
+	{
+		PerRegionContainer::iterator dst(mRegionStats.find(it->first));
+		if (mRegionStats.end() == dst)
+		{
+			// Destination is missing data, just make a private copy
+			mRegionStats[it->first] = new PerRegionStats(*it->second);
+		}
+		else
+		{
+			dst->second->merge(*it->second);
+		}
+	}
+}
+
+
+// ------------------------------------------------------
+// Global free-function definitions (LLViewerAssetStatsFF namespace)
+// ------------------------------------------------------
+
+namespace LLViewerAssetStatsFF
+{
+
+//
+// Target thread is elaborated in the function name.  This could
+// have been something 'templatey' like specializations iterated
+// over a set of constants but with so few, this is clearer I think.
+//
+// As for the threads themselves... rather than do fine-grained
+// locking as we gather statistics, this code creates a collector
+// for each thread, allocated and run independently.  Logging
+// happens at relatively infrequent intervals and at that time
+// the data is sent to a single thread to be aggregated into
+// a single entity with locks, thread safety and other niceties.
+//
+// A particularly fussy implementation would distribute the
+// per-thread pointers across separate cache lines.  But that should
+// be beyond current requirements.
+//
+
+// 'main' thread - initial program thread
+
+void
+set_region_main(LLViewerAssetStats::region_handle_t region_handle)
+{
+	if (! gViewerAssetStatsMain)
+		return;
+
+	gViewerAssetStatsMain->setRegion(region_handle);
+}
+
+void
+record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp)
+{
+	if (! gViewerAssetStatsMain)
+		return;
+
+	gViewerAssetStatsMain->recordGetEnqueued(at, with_http, is_temp);
+}
+
+void
+record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp)
+{
+	if (! gViewerAssetStatsMain)
+		return;
+
+	gViewerAssetStatsMain->recordGetDequeued(at, with_http, is_temp);
+}
+
+void
+record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration)
+{
+	if (! gViewerAssetStatsMain)
+		return;
+
+	gViewerAssetStatsMain->recordGetServiced(at, with_http, is_temp, duration);
+}
+
+void
+record_fps_main(F32 fps)
+{
+	if (! gViewerAssetStatsMain)
+		return;
+
+	gViewerAssetStatsMain->recordFPS(fps);
+}
+
+
+// 'thread1' - should be for TextureFetch thread
+
+void
+set_region_thread1(LLViewerAssetStats::region_handle_t region_handle)
+{
+	if (! gViewerAssetStatsThread1)
+		return;
+
+	gViewerAssetStatsThread1->setRegion(region_handle);
+}
+
+void
+record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp)
+{
+	if (! gViewerAssetStatsThread1)
+		return;
+
+	gViewerAssetStatsThread1->recordGetEnqueued(at, with_http, is_temp);
+}
+
+void
+record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp)
+{
+	if (! gViewerAssetStatsThread1)
+		return;
+
+	gViewerAssetStatsThread1->recordGetDequeued(at, with_http, is_temp);
+}
+
+void
+record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration)
+{
+	if (! gViewerAssetStatsThread1)
+		return;
+
+	gViewerAssetStatsThread1->recordGetServiced(at, with_http, is_temp, duration);
+}
+
+
+void
+init()
+{
+	if (! gViewerAssetStatsMain)
+	{
+		gViewerAssetStatsMain = new LLViewerAssetStats();
+	}
+	if (! gViewerAssetStatsThread1)
+	{
+		gViewerAssetStatsThread1 = new LLViewerAssetStats();
+	}
+}
+
+void
+cleanup()
+{
+	delete gViewerAssetStatsMain;
+	gViewerAssetStatsMain = 0;
+
+	delete gViewerAssetStatsThread1;
+	gViewerAssetStatsThread1 = 0;
+}
+
+
+} // namespace LLViewerAssetStatsFF
+
+
+// ------------------------------------------------------
+// Local function definitions
+// ------------------------------------------------------
+
+namespace
+{
+
+LLViewerAssetStats::EViewerAssetCategories
+asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp)
+{
+	// For statistical purposes, we divide GETs into several
+	// populations of asset fetches:
+	//  - textures which are de-prioritized in the asset system
+	//  - wearables (clothing, bodyparts) which directly affect
+	//    user experiences when they log in
+	//  - sounds
+	//  - gestures
+	//  - everything else.
+	//
+	llassert_always(26 == LLViewerAssetType::AT_COUNT);
+
+	// Multiple asset definitions are floating around so this requires some
+	// maintenance and attention.
+	static const LLViewerAssetStats::EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] =
+		{
+			LLViewerAssetStats::EVACTextureTempHTTPGet,			// (0) AT_TEXTURE
+			LLViewerAssetStats::EVACSoundUDPGet,				// AT_SOUND
+			LLViewerAssetStats::EVACOtherGet,					// AT_CALLINGCARD
+			LLViewerAssetStats::EVACOtherGet,					// AT_LANDMARK
+			LLViewerAssetStats::EVACOtherGet,					// AT_SCRIPT
+			LLViewerAssetStats::EVACWearableUDPGet,				// AT_CLOTHING
+			LLViewerAssetStats::EVACOtherGet,					// AT_OBJECT
+			LLViewerAssetStats::EVACOtherGet,					// AT_NOTECARD
+			LLViewerAssetStats::EVACOtherGet,					// AT_CATEGORY
+			LLViewerAssetStats::EVACOtherGet,					// AT_ROOT_CATEGORY
+			LLViewerAssetStats::EVACOtherGet,					// (10) AT_LSL_TEXT
+			LLViewerAssetStats::EVACOtherGet,					// AT_LSL_BYTECODE
+			LLViewerAssetStats::EVACOtherGet,					// AT_TEXTURE_TGA
+			LLViewerAssetStats::EVACWearableUDPGet,				// AT_BODYPART
+			LLViewerAssetStats::EVACOtherGet,					// AT_TRASH
+			LLViewerAssetStats::EVACOtherGet,					// AT_SNAPSHOT_CATEGORY
+			LLViewerAssetStats::EVACOtherGet,					// AT_LOST_AND_FOUND
+			LLViewerAssetStats::EVACSoundUDPGet,				// AT_SOUND_WAV
+			LLViewerAssetStats::EVACOtherGet,					// AT_IMAGE_TGA
+			LLViewerAssetStats::EVACOtherGet,					// AT_IMAGE_JPEG
+			LLViewerAssetStats::EVACGestureUDPGet,				// (20) AT_ANIMATION
+			LLViewerAssetStats::EVACGestureUDPGet,				// AT_GESTURE
+			LLViewerAssetStats::EVACOtherGet,					// AT_SIMSTATE
+			LLViewerAssetStats::EVACOtherGet,					// AT_FAVORITE
+			LLViewerAssetStats::EVACOtherGet,					// AT_LINK
+			LLViewerAssetStats::EVACOtherGet,					// AT_LINK_FOLDER
+#if 0
+			// When LLViewerAssetType::AT_COUNT == 49
+			LLViewerAssetStats::EVACOtherGet,					// AT_FOLDER_ENSEMBLE_START
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// (30)
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// (40)
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// 
+			LLViewerAssetStats::EVACOtherGet,					// AT_FOLDER_ENSEMBLE_END
+			LLViewerAssetStats::EVACOtherGet,					// AT_CURRENT_OUTFIT
+			LLViewerAssetStats::EVACOtherGet,					// AT_OUTFIT
+			LLViewerAssetStats::EVACOtherGet					// AT_MY_OUTFITS
+#endif
+		};
+	
+	if (at < 0 || at >= LLViewerAssetType::AT_COUNT)
+	{
+		return LLViewerAssetStats::EVACOtherGet;
+	}
+	LLViewerAssetStats::EViewerAssetCategories ret(asset_to_bin_map[at]);
+	if (LLViewerAssetStats::EVACTextureTempHTTPGet == ret)
+	{
+		// Indexed with [is_temp][with_http]
+		static const LLViewerAssetStats::EViewerAssetCategories texture_bin_map[2][2] =
+			{
+				{
+					LLViewerAssetStats::EVACTextureNonTempUDPGet,
+					LLViewerAssetStats::EVACTextureNonTempHTTPGet,
+				},
+				{
+					LLViewerAssetStats::EVACTextureTempUDPGet,
+					LLViewerAssetStats::EVACTextureTempHTTPGet,
+				}
+			};
+
+		ret = texture_bin_map[is_temp][with_http];
+	}
+	return ret;
+}
+
+} // anonymous namespace
diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h
new file mode 100644
index 0000000000000000000000000000000000000000..905ceefad511a45850b78315c12512a2b1e4614b
--- /dev/null
+++ b/indra/newview/llviewerassetstats.h
@@ -0,0 +1,334 @@
+/** 
+ * @file llviewerassetstats.h
+ * @brief Client-side collection of asset request statistics
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLVIEWERASSETSTATUS_H
+#define	LL_LLVIEWERASSETSTATUS_H
+
+
+#include "linden_common.h"
+
+#include "llpointer.h"
+#include "llrefcount.h"
+#include "llviewerassettype.h"
+#include "llviewerassetstorage.h"
+#include "llsimplestat.h"
+#include "llsd.h"
+
+/**
+ * @class LLViewerAssetStats
+ * @brief Records performance aspects of asset access operations.
+ *
+ * This facility is derived from a very similar simulator-based
+ * one, LLSimAssetStats.  It's function is to count asset access
+ * operations and characterize response times.  Collected data
+ * are binned in several dimensions:
+ *
+ *  - Asset types collapsed into a few aggregated categories
+ *  - By simulator UUID
+ *  - By transport mechanism (HTTP vs MessageSystem)
+ *  - By persistence (temp vs non-temp)
+ *
+ * Statistics collected are fairly basic at this point:
+ *
+ *  - Counts of enqueue and dequeue operations
+ *  - Min/Max/Mean of asset transfer operations
+ *
+ * This collector differs from the simulator-based on in a
+ * number of ways:
+ *
+ *  - The front-end/back-end distinction doesn't exist in viewer
+ *    code
+ *  - Multiple threads must be safely accomodated in the viewer
+ *
+ * Access to results is by conversion to an LLSD with some standardized
+ * key names.  The intent of this structure is that it be emitted as
+ * standard syslog-based metrics formatting where it can be picked
+ * up by interested parties.
+ *
+ * For convenience, a set of free functions in namespace
+ * LLViewerAssetStatsFF is provided for conditional test-and-call
+ * operations.
+ */
+class LLViewerAssetStats
+{
+public:
+	enum EViewerAssetCategories
+	{
+		EVACTextureTempHTTPGet,			//< Texture GETs - temp/baked, HTTP
+		EVACTextureTempUDPGet,			//< Texture GETs - temp/baked, UDP
+		EVACTextureNonTempHTTPGet,		//< Texture GETs - perm, HTTP
+		EVACTextureNonTempUDPGet,		//< Texture GETs - perm, UDP
+		EVACWearableUDPGet,				//< Wearable GETs
+		EVACSoundUDPGet,				//< Sound GETs
+		EVACGestureUDPGet,				//< Gesture GETs
+		EVACOtherGet,					//< Other GETs
+		
+		EVACCount						// Must be last
+	};
+
+	/**
+	 * Type for duration and other time values in the metrics.  Selected
+	 * for compatibility with the pre-existing timestamp on the texture
+	 * fetcher class, LLTextureFetch.
+	 */
+	typedef U64 duration_t;
+
+	/**
+	 * Type for the region identifier used in stats.  Currently uses
+	 * the region handle's type (a U64) rather than the regions's LLUUID
+	 * as the latter isn't available immediately.
+	 */
+	typedef U64 region_handle_t;
+
+	/**
+	 * @brief Collected data for a single region visited by the avatar.
+	 *
+	 * Fairly simple, for each asset bin enumerated above a count
+	 * of enqueue and dequeue operations and simple stats on response
+	 * times for completed requests.
+	 */
+	class PerRegionStats : public LLRefCount
+	{
+	public:
+		PerRegionStats(const region_handle_t region_handle)
+			: LLRefCount(),
+			  mRegionHandle(region_handle)
+			{
+				reset();
+			}
+
+		PerRegionStats(const PerRegionStats & src)
+			: LLRefCount(),
+			  mRegionHandle(src.mRegionHandle),
+			  mTotalTime(src.mTotalTime),
+			  mStartTimestamp(src.mStartTimestamp),
+			  mFPS(src.mFPS)
+			{
+				for (int i = 0; i < LL_ARRAY_SIZE(mRequests); ++i)
+				{
+					mRequests[i] = src.mRequests[i];
+				}
+			}
+
+		// Default assignment and destructor are correct.
+		
+		void reset();
+
+		void merge(const PerRegionStats & src);
+		
+		// Apply current running time to total and reset start point.
+		// Return current timestamp as a convenience.
+		void accumulateTime(duration_t now);
+		
+	public:
+		region_handle_t		mRegionHandle;
+		duration_t			mTotalTime;
+		duration_t			mStartTimestamp;
+		LLSimpleStatMMM<>	mFPS;
+		
+		struct prs_group
+		{
+			LLSimpleStatCounter			mEnqueued;
+			LLSimpleStatCounter			mDequeued;
+			LLSimpleStatMMM<duration_t>	mResponse;
+		}
+		mRequests [EVACCount];
+	};
+
+public:
+	LLViewerAssetStats();
+	LLViewerAssetStats(const LLViewerAssetStats &);
+	// Default destructor is correct.
+	LLViewerAssetStats & operator=(const LLViewerAssetStats &);			// Not defined
+
+	// Clear all metrics data.  This leaves the currently-active region
+	// in place but with zero'd data for all metrics.  All other regions
+	// are removed from the collection map.
+	void reset();
+
+	// Set hidden region argument and establish context for subsequent
+	// collection calls.
+	void setRegion(region_handle_t region_handle);
+
+	// Asset GET Requests
+	void recordGetEnqueued(LLViewerAssetType::EType at, bool with_http, bool is_temp);
+	void recordGetDequeued(LLViewerAssetType::EType at, bool with_http, bool is_temp);
+	void recordGetServiced(LLViewerAssetType::EType at, bool with_http, bool is_temp, duration_t duration);
+
+	// Frames-Per-Second Samples
+	void recordFPS(F32 fps);
+
+	// Merge a source instance into a destination instance.  This is
+	// conceptually an 'operator+=()' method:
+	// - counts are added
+	// - minimums are min'd
+	// - maximums are max'd
+	// - other scalars are ignored ('this' wins)
+	//
+	void merge(const LLViewerAssetStats & src);
+	
+	// Retrieve current metrics for all visited regions (NULL region UUID/handle excluded)
+    // Returned LLSD is structured as follows:
+	//
+	// &stats_group = {
+	//   enqueued   : int,
+	//   dequeued   : int,
+	//   resp_count : int,
+	//   resp_min   : float,
+	//   resp_max   : float,
+	//   resp_mean  : float
+	// }
+	//
+	// &mmm_group = {
+	//   count : int,
+	//   min   : float,
+	//   max   : float,
+	//   mean  : float
+	// }
+	//
+	// {
+	//   duration: int
+	//   regions: {
+	//     $: {			// Keys are strings of the region's handle in hex
+	//       duration:                 : int,
+	//		 fps:					   : &mmm_group,
+	//       get_texture_temp_http     : &stats_group,
+	//       get_texture_temp_udp      : &stats_group,
+	//       get_texture_non_temp_http : &stats_group,
+	//       get_texture_non_temp_udp  : &stats_group,
+	//       get_wearable_udp          : &stats_group,
+	//       get_sound_udp             : &stats_group,
+	//       get_gesture_udp           : &stats_group,
+	//       get_other                 : &stats_group
+	//     }
+	//   }
+	// }
+	//
+	// @param	compact_output		If true, omits from conversion any mmm_block
+	//								or stats_block that would contain all zero data.
+	//								Useful for transmission when the receiver knows
+	//								what is expected and will assume zero for missing
+	//								blocks.
+	LLSD asLLSD(bool compact_output);
+
+protected:
+	typedef std::map<region_handle_t, LLPointer<PerRegionStats> > PerRegionContainer;
+
+	// Region of the currently-active region.  Always valid but may
+	// be zero after construction or when explicitly set.  Unchanged
+	// by a reset() call.
+	region_handle_t mRegionHandle;
+
+	// Pointer to metrics collection for currently-active region.  Always
+	// valid and unchanged after reset() though contents will be changed.
+	// Always points to a collection contained in mRegionStats.
+	LLPointer<PerRegionStats> mCurRegionStats;
+
+	// Metrics data for all regions during one collection cycle
+	PerRegionContainer mRegionStats;
+
+	// Time of last reset
+	duration_t mResetTimestamp;
+};
+
+
+/**
+ * Global stats collectors one for each independent thread where
+ * assets and other statistics are gathered.  The globals are
+ * expected to be created at startup time and then picked up by
+ * their respective threads afterwards.  A set of free functions
+ * are provided to access methods behind the globals while both
+ * minimally disrupting visual flow and supplying a description
+ * of intent.
+ *
+ * Expected thread assignments:
+ *
+ *  - Main:  main() program execution thread
+ *  - Thread1:  TextureFetch worker thread
+ */
+extern LLViewerAssetStats * gViewerAssetStatsMain;
+
+extern LLViewerAssetStats * gViewerAssetStatsThread1;
+
+namespace LLViewerAssetStatsFF
+{
+/**
+ * @brief Allocation and deallocation of globals.
+ *
+ * init() should be called before threads are started that will access it though
+ * you'll likely get away with calling it afterwards.  cleanup() should only be
+ * called after threads are shutdown to prevent races on the global pointers.
+ */
+void init();
+
+void cleanup();
+
+/**
+ * We have many timers, clocks etc. in the runtime.  This is the
+ * canonical timestamp for these metrics which is compatible with
+ * the pre-existing timestamping in the texture fetcher.
+ */
+inline LLViewerAssetStats::duration_t get_timestamp()
+{
+	return LLTimer::getTotalTime();
+}
+
+/**
+ * Region context, event and duration loggers for the Main thread.
+ */
+void set_region_main(LLViewerAssetStats::region_handle_t region_handle);
+
+void record_enqueue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp);
+
+void record_dequeue_main(LLViewerAssetType::EType at, bool with_http, bool is_temp);
+
+void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_temp,
+						  LLViewerAssetStats::duration_t duration);
+
+void record_fps_main(F32 fps);
+
+
+/**
+ * Region context, event and duration loggers for Thread 1.
+ */
+void set_region_thread1(LLViewerAssetStats::region_handle_t region_handle);
+
+void record_enqueue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp);
+
+void record_dequeue_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp);
+
+void record_response_thread1(LLViewerAssetType::EType at, bool with_http, bool is_temp,
+						  LLViewerAssetStats::duration_t duration);
+
+} // namespace LLViewerAssetStatsFF
+
+#endif // LL_LLVIEWERASSETSTATUS_H
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 2e7ef0fec3dffa8f356be07ec73100e5f6be0260..36c8b42a5223eab5369e9d4b2bca9728da8bc03f 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -33,6 +33,61 @@
 #include "message.h"
 
 #include "llagent.h"
+#include "lltransfersourceasset.h"
+#include "lltransfertargetvfile.h"
+#include "llviewerassetstats.h"
+
+///----------------------------------------------------------------------------
+/// LLViewerAssetRequest
+///----------------------------------------------------------------------------
+
+/**
+ * @brief Local class to encapsulate asset fetch requests with a timestamp.
+ *
+ * Derived from the common LLAssetRequest class, this is currently used
+ * only for fetch/get operations and its only function is to wrap remote
+ * asset fetch requests so that they can be timed.
+ */
+class LLViewerAssetRequest : public LLAssetRequest
+{
+public:
+	LLViewerAssetRequest(const LLUUID &uuid, const LLAssetType::EType type)
+		: LLAssetRequest(uuid, type),
+		  mMetricsStartTime(0)
+		{
+		}
+	
+	LLViewerAssetRequest & operator=(const LLViewerAssetRequest &);	// Not defined
+	// Default assignment operator valid
+	
+	// virtual
+	~LLViewerAssetRequest()
+		{
+			recordMetrics();
+		}
+
+protected:
+	void recordMetrics()
+		{
+			if (mMetricsStartTime)
+			{
+				// Okay, it appears this request was used for useful things.  Record
+				// the expected dequeue and duration of request processing.
+				LLViewerAssetStatsFF::record_dequeue_main(mType, false, false);
+				LLViewerAssetStatsFF::record_response_main(mType, false, false,
+														   (LLViewerAssetStatsFF::get_timestamp()
+															- mMetricsStartTime));
+				mMetricsStartTime = 0;
+			}
+		}
+	
+public:
+	LLViewerAssetStats::duration_t		mMetricsStartTime;
+};
+
+///----------------------------------------------------------------------------
+/// LLViewerAssetStorage
+///----------------------------------------------------------------------------
 
 LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
 										   LLVFS *vfs, LLVFS *static_vfs, 
@@ -258,3 +313,77 @@ void LLViewerAssetStorage::storeAssetData(
 		}
 	}
 }
+
+
+/**
+ * @brief Allocate and queue an asset fetch request for the viewer
+ *
+ * This is a nearly-verbatim copy of the base class's implementation
+ * with the following changes:
+ *  -  Use a locally-derived request class
+ *  -  Start timing for metrics when request is queued
+ *
+ * This is an unfortunate implementation choice but it's forced by
+ * current conditions.  A refactoring that might clean up the layers
+ * of responsibility or introduce factories or more virtualization
+ * of methods would enable a more attractive solution.
+ *
+ * If LLAssetStorage::_queueDataRequest changes, this must change
+ * as well.
+ */
+
+// virtual
+void LLViewerAssetStorage::_queueDataRequest(
+	const LLUUID& uuid,
+	LLAssetType::EType atype,
+	LLGetAssetCallback callback,
+	void *user_data,
+	BOOL duplicate,
+	BOOL is_priority)
+{
+	if (mUpstreamHost.isOk())
+	{
+		// stash the callback info so we can find it after we get the response message
+		LLViewerAssetRequest *req = new LLViewerAssetRequest(uuid, atype);
+		req->mDownCallback = callback;
+		req->mUserData = user_data;
+		req->mIsPriority = is_priority;
+		if (!duplicate)
+		{
+			// Only collect metrics for non-duplicate requests.  Others 
+			// are piggy-backing and will artificially lower averages.
+			req->mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
+		}
+		
+		mPendingDownloads.push_back(req);
+	
+		if (!duplicate)
+		{
+			// send request message to our upstream data provider
+			// Create a new asset transfer.
+			LLTransferSourceParamsAsset spa;
+			spa.setAsset(uuid, atype);
+
+			// Set our destination file, and the completion callback.
+			LLTransferTargetParamsVFile tpvf;
+			tpvf.setAsset(uuid, atype);
+			tpvf.setCallback(downloadCompleteCallback, req);
+
+			llinfos << "Starting transfer for " << uuid << llendl;
+			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET);
+			ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f));
+
+			LLViewerAssetStatsFF::record_enqueue_main(atype, false, false);
+		}
+	}
+	else
+	{
+		// uh-oh, we shouldn't have gotten here
+		llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl;
+		if (callback)
+		{
+			callback(mVFS, uuid, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
+		}
+	}
+}
+
diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h
index 6346b79f0310b0797799e932c67ca5c639cd19e5..ca9b9943fa8decb19edb22c974233bf6e966a46f 100644
--- a/indra/newview/llviewerassetstorage.h
+++ b/indra/newview/llviewerassetstorage.h
@@ -63,6 +63,17 @@ class LLViewerAssetStorage : public LLAssetStorage
 		bool is_priority = false,
 		bool user_waiting=FALSE,
 		F64 timeout=LL_ASSET_STORAGE_TIMEOUT);
+
+protected:
+	using LLAssetStorage::_queueDataRequest;
+
+	// virtual
+	void _queueDataRequest(const LLUUID& uuid,
+						   LLAssetType::EType type,
+						   void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
+						   void *user_data,
+						   BOOL duplicate,
+						   BOOL is_priority);
 };
 
 #endif
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index fbec2a7b9e6e36571bd3b21bee612a20db82a5e8..8c5a52c1878b3ba475d7761b4d96325a643711fc 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -70,6 +70,7 @@
 #include "llpaneloutfitsinventory.h"
 #include "llpanellogin.h"
 #include "llpaneltopinfobar.h"
+#include "llupdaterservice.h"
 
 #ifdef TOGGLE_HACKED_GODLIKE_VIEWER
 BOOL 				gHackGodmode = FALSE;
@@ -82,7 +83,6 @@ LLControlGroup gCrashSettings("CrashSettings");	// saved at end of session
 LLControlGroup gWarningSettings("Warnings"); // persists ignored dialogs/warnings
 
 std::string gLastRunVersion;
-std::string gCurrentVersion;
 
 extern BOOL gResizeScreenTexture;
 extern BOOL gDebugGL;
@@ -117,10 +117,23 @@ static bool handleSetShaderChanged(const LLSD& newvalue)
 	gBumpImageList.destroyGL();
 	gBumpImageList.restoreGL();
 
+	// Changing shader also changes the terrain detail to high, reflect that change here
+	if (newvalue.asBoolean())
+	{
+		// shaders enabled, set terrain detail to high
+		gSavedSettings.setS32("RenderTerrainDetail", 1);
+	}
+	// else, leave terrain detail as is
 	LLViewerShaderMgr::instance()->setShaders();
 	return true;
 }
 
+bool handleRenderTransparentWaterChanged(const LLSD& newvalue)
+{
+	LLWorld::getInstance()->updateWaterObjects();
+	return true;
+}
+
 static bool handleReleaseGLBufferChanged(const LLSD& newvalue)
 {
 	if (gPipeline.isInit())
@@ -489,6 +502,19 @@ bool toggle_show_object_render_cost(const LLSD& newvalue)
 	return true;
 }
 
+void toggle_updater_service_active(LLControlVariable* control, const LLSD& new_value)
+{
+    if(new_value.asInteger())
+    {
+		LLUpdaterService update_service;
+		if(!update_service.isChecking()) update_service.startChecking();
+    }
+    else
+    {
+        LLUpdaterService().stopChecking();
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////
 
 void settings_setup_listeners()
@@ -636,7 +662,9 @@ void settings_setup_listeners()
 	gSavedSettings.getControl("ShowNavbarFavoritesPanel")->getSignal()->connect(boost::bind(&toggle_show_favorites_panel, _2));
 	gSavedSettings.getControl("ShowMiniLocationPanel")->getSignal()->connect(boost::bind(&toggle_show_mini_location_panel, _2));
 	gSavedSettings.getControl("ShowObjectRenderingCost")->getSignal()->connect(boost::bind(&toggle_show_object_render_cost, _2));
+	gSavedSettings.getControl("UpdaterServiceSetting")->getSignal()->connect(&toggle_updater_service_active);
 	gSavedSettings.getControl("ForceShowGrid")->getSignal()->connect(boost::bind(&handleForceShowGrid, _2));
+	gSavedSettings.getControl("RenderTransparentWater")->getSignal()->connect(boost::bind(&handleRenderTransparentWaterChanged, _2));
 }
 
 #if TEST_CACHED_CONTROL
diff --git a/indra/newview/llviewercontrol.h b/indra/newview/llviewercontrol.h
index 22b48f8906b1ec26ebb2e88bea9ff134b2d767f0..d7191f5c8d5d8703ec7d76b80fdb8ab9a2c49259 100644
--- a/indra/newview/llviewercontrol.h
+++ b/indra/newview/llviewercontrol.h
@@ -57,7 +57,5 @@ extern LLControlGroup gCrashSettings;
 
 // Set after settings loaded
 extern std::string gLastRunVersion;
-extern std::string gCurrentVersion;
-
 
 #endif // LL_LLVIEWERCONTROL_H
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index b3f14b441d4e468c2dfacee9f720b1601688b765..dca1e33e609fac9f0539631c0c74511fee972b71 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -60,6 +60,7 @@
 #include "llfloaterhardwaresettings.h"
 #include "llfloaterhelpbrowser.h"
 #include "llfloatermediabrowser.h"
+#include "llfloaterwebcontent.h"
 #include "llfloatermediasettings.h"
 #include "llfloaterhud.h"
 #include "llfloaterimagepreview.h"
@@ -81,6 +82,7 @@
 #include "llfloaterpostprocess.h"
 #include "llfloaterpreference.h"
 #include "llfloaterproperties.h"
+#include "llfloaterregiondebugconsole.h"
 #include "llfloaterregioninfo.h"
 #include "llfloaterreporter.h"
 #include "llfloaterscriptdebug.h"
@@ -227,6 +229,7 @@ void LLViewerFloaterReg::registerFloaters()
 	
 	LLFloaterReg::add("reporter", "floater_report_abuse.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterReporter>);
 	LLFloaterReg::add("reset_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterResetQueue>);
+	LLFloaterReg::add("region_debug_console", "floater_region_debug_console.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRegionDebugConsole>);
 	LLFloaterReg::add("region_info", "floater_region_info.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRegionInfo>);
 	
 	LLFloaterReg::add("script_debug", "floater_script_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptDebug>);
@@ -250,6 +253,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>);
 	LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>);
 
+	LLFloaterReg::add("web_content", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWebContent>);	
 	LLFloaterReg::add("whitelist_entry", "floater_whitelist_entry.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWhiteListEntry>);	
 	LLFloaterWindowSizeUtil::registerFloater();
 	LLFloaterReg::add("world_map", "floater_world_map.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterWorldMap>);	
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index d7e15e7d6cda6bd87d41a9a581a41c5ab56e081f..1aa9fd8a45d5a52db01e09a736a06aa4cbcdc78b 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -40,6 +40,7 @@
 #include "llviewerwindow.h"
 #include "llvoavatarself.h"
 #include "llfloatercamera.h"
+#include "llinitparam.h"
 
 //
 // Constants
@@ -53,6 +54,11 @@ const S32 NUDGE_FRAMES = 2;
 const F32 ORBIT_NUDGE_RATE = 0.05f;  // fraction of normal speed
 const F32 YAW_NUDGE_RATE = 0.05f;  // fraction of normal speed
 
+struct LLKeyboardActionRegistry 
+:	public LLRegistrySingleton<std::string, boost::function<void (EKeystate keystate)>, LLKeyboardActionRegistry>
+{
+};
+
 LLViewerKeyboard gViewerKeyboard;
 
 void agent_jump( EKeystate s )
@@ -550,52 +556,50 @@ void start_gesture( EKeystate s )
 	}
 }
 
-void bind_keyboard_functions()
-{
-	gViewerKeyboard.bindNamedFunction("jump", agent_jump);
-	gViewerKeyboard.bindNamedFunction("push_down", agent_push_down);
-	gViewerKeyboard.bindNamedFunction("push_forward", agent_push_forward);
-	gViewerKeyboard.bindNamedFunction("push_backward", agent_push_backward);
-	gViewerKeyboard.bindNamedFunction("look_up", agent_look_up);
-	gViewerKeyboard.bindNamedFunction("look_down", agent_look_down);
-	gViewerKeyboard.bindNamedFunction("toggle_fly", agent_toggle_fly);
-	gViewerKeyboard.bindNamedFunction("turn_left", agent_turn_left);
-	gViewerKeyboard.bindNamedFunction("turn_right", agent_turn_right);
-	gViewerKeyboard.bindNamedFunction("slide_left", agent_slide_left);
-	gViewerKeyboard.bindNamedFunction("slide_right", agent_slide_right);
-	gViewerKeyboard.bindNamedFunction("spin_around_ccw", camera_spin_around_ccw);
-	gViewerKeyboard.bindNamedFunction("spin_around_cw", camera_spin_around_cw);
-	gViewerKeyboard.bindNamedFunction("spin_around_ccw_sitting", camera_spin_around_ccw_sitting);
-	gViewerKeyboard.bindNamedFunction("spin_around_cw_sitting", camera_spin_around_cw_sitting);
-	gViewerKeyboard.bindNamedFunction("spin_over", camera_spin_over);
-	gViewerKeyboard.bindNamedFunction("spin_under", camera_spin_under);
-	gViewerKeyboard.bindNamedFunction("spin_over_sitting", camera_spin_over_sitting);
-	gViewerKeyboard.bindNamedFunction("spin_under_sitting", camera_spin_under_sitting);
-	gViewerKeyboard.bindNamedFunction("move_forward", camera_move_forward);
-	gViewerKeyboard.bindNamedFunction("move_backward", camera_move_backward);
-	gViewerKeyboard.bindNamedFunction("move_forward_sitting", camera_move_forward_sitting);
-	gViewerKeyboard.bindNamedFunction("move_backward_sitting", camera_move_backward_sitting);
-	gViewerKeyboard.bindNamedFunction("pan_up", camera_pan_up);
-	gViewerKeyboard.bindNamedFunction("pan_down", camera_pan_down);
-	gViewerKeyboard.bindNamedFunction("pan_left", camera_pan_left);
-	gViewerKeyboard.bindNamedFunction("pan_right", camera_pan_right);
-	gViewerKeyboard.bindNamedFunction("pan_in", camera_pan_in);
-	gViewerKeyboard.bindNamedFunction("pan_out", camera_pan_out);
-	gViewerKeyboard.bindNamedFunction("move_forward_fast", camera_move_forward_fast);
-	gViewerKeyboard.bindNamedFunction("move_backward_fast", camera_move_backward_fast);
-	gViewerKeyboard.bindNamedFunction("edit_avatar_spin_ccw", edit_avatar_spin_ccw);
-	gViewerKeyboard.bindNamedFunction("edit_avatar_spin_cw", edit_avatar_spin_cw);
-	gViewerKeyboard.bindNamedFunction("edit_avatar_spin_over", edit_avatar_spin_over);
-	gViewerKeyboard.bindNamedFunction("edit_avatar_spin_under", edit_avatar_spin_under);
-	gViewerKeyboard.bindNamedFunction("edit_avatar_move_forward", edit_avatar_move_forward);
-	gViewerKeyboard.bindNamedFunction("edit_avatar_move_backward", edit_avatar_move_backward);
-	gViewerKeyboard.bindNamedFunction("stop_moving", stop_moving);
-	gViewerKeyboard.bindNamedFunction("start_chat", start_chat);
-	gViewerKeyboard.bindNamedFunction("start_gesture", start_gesture);
-}
-
-LLViewerKeyboard::LLViewerKeyboard() :
-	mNamedFunctionCount(0)
+#define REGISTER_KEYBOARD_ACTION(KEY, ACTION) LLREGISTER_STATIC(LLKeyboardActionRegistry, KEY, ACTION);
+REGISTER_KEYBOARD_ACTION("jump", agent_jump);
+REGISTER_KEYBOARD_ACTION("push_down", agent_push_down);
+REGISTER_KEYBOARD_ACTION("push_forward", agent_push_forward);
+REGISTER_KEYBOARD_ACTION("push_backward", agent_push_backward);
+REGISTER_KEYBOARD_ACTION("look_up", agent_look_up);
+REGISTER_KEYBOARD_ACTION("look_down", agent_look_down);
+REGISTER_KEYBOARD_ACTION("toggle_fly", agent_toggle_fly);
+REGISTER_KEYBOARD_ACTION("turn_left", agent_turn_left);
+REGISTER_KEYBOARD_ACTION("turn_right", agent_turn_right);
+REGISTER_KEYBOARD_ACTION("slide_left", agent_slide_left);
+REGISTER_KEYBOARD_ACTION("slide_right", agent_slide_right);
+REGISTER_KEYBOARD_ACTION("spin_around_ccw", camera_spin_around_ccw);
+REGISTER_KEYBOARD_ACTION("spin_around_cw", camera_spin_around_cw);
+REGISTER_KEYBOARD_ACTION("spin_around_ccw_sitting", camera_spin_around_ccw_sitting);
+REGISTER_KEYBOARD_ACTION("spin_around_cw_sitting", camera_spin_around_cw_sitting);
+REGISTER_KEYBOARD_ACTION("spin_over", camera_spin_over);
+REGISTER_KEYBOARD_ACTION("spin_under", camera_spin_under);
+REGISTER_KEYBOARD_ACTION("spin_over_sitting", camera_spin_over_sitting);
+REGISTER_KEYBOARD_ACTION("spin_under_sitting", camera_spin_under_sitting);
+REGISTER_KEYBOARD_ACTION("move_forward", camera_move_forward);
+REGISTER_KEYBOARD_ACTION("move_backward", camera_move_backward);
+REGISTER_KEYBOARD_ACTION("move_forward_sitting", camera_move_forward_sitting);
+REGISTER_KEYBOARD_ACTION("move_backward_sitting", camera_move_backward_sitting);
+REGISTER_KEYBOARD_ACTION("pan_up", camera_pan_up);
+REGISTER_KEYBOARD_ACTION("pan_down", camera_pan_down);
+REGISTER_KEYBOARD_ACTION("pan_left", camera_pan_left);
+REGISTER_KEYBOARD_ACTION("pan_right", camera_pan_right);
+REGISTER_KEYBOARD_ACTION("pan_in", camera_pan_in);
+REGISTER_KEYBOARD_ACTION("pan_out", camera_pan_out);
+REGISTER_KEYBOARD_ACTION("move_forward_fast", camera_move_forward_fast);
+REGISTER_KEYBOARD_ACTION("move_backward_fast", camera_move_backward_fast);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_ccw", edit_avatar_spin_ccw);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_cw", edit_avatar_spin_cw);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_over", edit_avatar_spin_over);
+REGISTER_KEYBOARD_ACTION("edit_avatar_spin_under", edit_avatar_spin_under);
+REGISTER_KEYBOARD_ACTION("edit_avatar_move_forward", edit_avatar_move_forward);
+REGISTER_KEYBOARD_ACTION("edit_avatar_move_backward", edit_avatar_move_backward);
+REGISTER_KEYBOARD_ACTION("stop_moving", stop_moving);
+REGISTER_KEYBOARD_ACTION("start_chat", start_chat);
+REGISTER_KEYBOARD_ACTION("start_gesture", start_gesture);
+#undef REGISTER_KEYBOARD_ACTION
+
+LLViewerKeyboard::LLViewerKeyboard()
 {
 	for (S32 i = 0; i < MODE_COUNT; i++)
 	{
@@ -613,16 +617,6 @@ LLViewerKeyboard::LLViewerKeyboard() :
 	}
 }
 
-
-void LLViewerKeyboard::bindNamedFunction(const std::string& name, LLKeyFunc func)
-{
-	S32 i = mNamedFunctionCount;
-	mNamedFunctions[i].mName = name;
-	mNamedFunctions[i].mFunction = func;
-	mNamedFunctionCount++;
-}
-
-
 BOOL LLViewerKeyboard::modeFromString(const std::string& string, S32 *mode)
 {
 	if (string == "FIRST_PERSON")
@@ -695,8 +689,9 @@ BOOL LLViewerKeyboard::handleKey(KEY translated_key,  MASK translated_mask, BOOL
 
 BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name)
 {
-	S32 i,index;
-	void (*function)(EKeystate keystate) = NULL;
+	S32 index;
+	typedef boost::function<void(EKeystate)> function_t;
+	function_t function = NULL;
 	std::string name;
 
 	// Allow remapping of F2-F12
@@ -719,13 +714,11 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c
 	}
 
 	// Not remapped, look for a function
-	for (i = 0; i < mNamedFunctionCount; i++)
+	
+	function_t* result = LLKeyboardActionRegistry::getValue(function_name);
+	if (result)
 	{
-		if (function_name == mNamedFunctions[i].mName)
-		{
-			function = mNamedFunctions[i].mFunction;
-			name = mNamedFunctions[i].mName;
-		}
+		function = *result;
 	}
 
 	if (!function)
@@ -755,7 +748,6 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c
 
 	mBindings[mode][index].mKey = key;
 	mBindings[mode][index].mMask = mask;
-// 	mBindings[mode][index].mName = name;
 	mBindings[mode][index].mFunction = function;
 
 	if (index == mBindingCount[mode])
@@ -764,6 +756,61 @@ BOOL LLViewerKeyboard::bindKey(const S32 mode, const KEY key, const MASK mask, c
 	return TRUE;
 }
 
+LLViewerKeyboard::KeyBinding::KeyBinding()
+:	key("key"),
+	mask("mask"),
+	command("command")
+{}
+
+LLViewerKeyboard::KeyMode::KeyMode(EKeyboardMode _mode)
+:	bindings("binding"),
+	mode(_mode)
+{}
+
+LLViewerKeyboard::Keys::Keys()
+:	first_person("first_person", KeyMode(MODE_FIRST_PERSON)),
+	third_person("third_person", KeyMode(MODE_THIRD_PERSON)),
+	edit("edit", KeyMode(MODE_EDIT)),
+	sitting("sitting", KeyMode(MODE_SITTING)),
+	edit_avatar("edit_avatar", KeyMode(MODE_EDIT_AVATAR))
+{}
+
+S32 LLViewerKeyboard::loadBindingsXML(const std::string& filename)
+{
+	S32 binding_count = 0;
+	Keys keys;
+	LLSimpleXUIParser parser;
+
+	if (parser.readXUI(filename, keys) 
+		&& keys.validateBlock())
+	{
+		binding_count += loadBindingMode(keys.first_person);
+		binding_count += loadBindingMode(keys.third_person);
+		binding_count += loadBindingMode(keys.edit);
+		binding_count += loadBindingMode(keys.sitting);
+		binding_count += loadBindingMode(keys.edit_avatar);
+	}
+	return binding_count;
+}
+
+S32 LLViewerKeyboard::loadBindingMode(const LLViewerKeyboard::KeyMode& keymode)
+{
+	S32 binding_count = 0;
+	for (LLInitParam::ParamIterator<KeyBinding>::const_iterator it = keymode.bindings.begin(), 
+			end_it = keymode.bindings.end();
+		it != end_it;
+		++it)
+	{
+		KEY key;
+		MASK mask;
+		LLKeyboard::keyFromString(it->key, &key);
+		LLKeyboard::maskFromString(it->mask, &mask);
+		bindKey(keymode.mode, key, mask, it->command);
+		binding_count++;
+	}
+
+	return binding_count;
+}
 
 S32 LLViewerKeyboard::loadBindings(const std::string& filename)
 {
@@ -912,18 +959,18 @@ void LLViewerKeyboard::scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_lev
 				if (key_down && !repeat)
 				{
 					// ...key went down this frame, call function
-					(*binding[i].mFunction)( KEYSTATE_DOWN );
+					binding[i].mFunction( KEYSTATE_DOWN );
 				}
 				else if (key_up)
 				{
 					// ...key went down this frame, call function
-					(*binding[i].mFunction)( KEYSTATE_UP );
+					binding[i].mFunction( KEYSTATE_UP );
 				}
 				else if (key_level)
 				{
 					// ...key held down from previous frame
 					// Not windows, just call the function.
-					(*binding[i].mFunction)( KEYSTATE_LEVEL );
+					binding[i].mFunction( KEYSTATE_LEVEL );
 				}//if
 			}//if
 		}//for
diff --git a/indra/newview/llviewerkeyboard.h b/indra/newview/llviewerkeyboard.h
index 2fa5d5dfa69560dbdc09903210829133615326f9..925244e89bcc28295799df7f18b81ed064a1234c 100644
--- a/indra/newview/llviewerkeyboard.h
+++ b/indra/newview/llviewerkeyboard.h
@@ -55,26 +55,51 @@ typedef enum e_keyboard_mode
 
 void bind_keyboard_functions();
 
-
 class LLViewerKeyboard
 {
 public:
+	struct KeyBinding : public LLInitParam::Block<KeyBinding>
+	{
+		Mandatory<std::string>	key,
+								mask,
+								command;
+
+		KeyBinding();
+	};
+
+	struct KeyMode : public LLInitParam::Block<KeyMode>
+	{
+		Multiple<KeyBinding>		bindings;
+		EKeyboardMode				mode;
+		KeyMode(EKeyboardMode mode);
+	};
+
+	struct Keys : public LLInitParam::Block<Keys>
+	{
+		Optional<KeyMode>	first_person,
+							third_person,
+							edit,
+							sitting,
+							edit_avatar;
+
+		Keys();
+	};
+
 	LLViewerKeyboard();
 
 	BOOL			handleKey(KEY key, MASK mask, BOOL repeated);
 
-	void			bindNamedFunction(const std::string& name, LLKeyFunc func);
-
 	S32				loadBindings(const std::string& filename);										// returns number bound, 0 on error
+	S32				loadBindingsXML(const std::string& filename);										// returns number bound, 0 on error
 	EKeyboardMode	getMode();
 
 	BOOL			modeFromString(const std::string& string, S32 *mode);			// False on failure
 
 	void			scanKey(KEY key, BOOL key_down, BOOL key_up, BOOL key_level);
-protected:
+
+private:
+	S32				loadBindingMode(const LLViewerKeyboard::KeyMode& keymode);
 	BOOL			bindKey(const S32 mode, const KEY key, const MASK mask, const std::string& function_name);
-	S32				mNamedFunctionCount;
-	LLNamedFunction	mNamedFunctions[MAX_NAMED_FUNCTIONS];
 
 	// Hold all the ugly stuff torn out to make LLKeyboard non-viewer-specific here
 	S32				mBindingCount[MODE_COUNT];
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 48ab122edffe7c8d6314066a622212a92ac4c6a3..d3b6dcd86f2f937121d61890f9c997ae0869fd08 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -52,6 +52,7 @@
 #include "llviewerregion.h"
 #include "llwebsharing.h"	// For LLWebSharing::setOpenIDCookie(), *TODO: find a better way to do this!
 #include "llfilepicker.h"
+#include "llnotifications.h"
 
 #include "llevent.h"		// LLSimpleListener
 #include "llnotificationsutil.h"
@@ -62,6 +63,7 @@
 #include "llwindow.h"
 
 #include "llfloatermediabrowser.h"	// for handling window close requests and geometry change requests in media browser windows.
+#include "llfloaterwebcontent.h"	// for handling window close requests and geometry change requests in media browser windows.
 
 #include <boost/bind.hpp>	// for SkinFolder listener
 #include <boost/signals2.hpp>
@@ -293,6 +295,7 @@ LOG_CLASS(LLViewerMediaOpenIDResponder);
 LLPluginCookieStore *LLViewerMedia::sCookieStore = NULL;
 LLURL LLViewerMedia::sOpenIDURL;
 std::string LLViewerMedia::sOpenIDCookie;
+LLPluginClassMedia* LLViewerMedia::sSpareBrowserMediaSource = NULL;
 static LLViewerMedia::impl_list sViewerMediaImplList;
 static LLViewerMedia::impl_id_map sViewerMediaTextureIDMap;
 static LLTimer sMediaCreateTimer;
@@ -492,7 +495,7 @@ std::string LLViewerMedia::getCurrentUserAgent()
 
 	// Just in case we need to check browser differences in A/B test
 	// builds.
-	std::string channel = gSavedSettings.getString("VersionChannelName");
+	std::string channel = LLVersionInfo::getChannel();
 
 	// append our magic version number string to the browser user agent id
 	// See the HTTP 1.0 and 1.1 specifications for allowed formats:
@@ -742,6 +745,9 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 	// Enable/disable the plugin read thread
 	LLPluginProcessParent::setUseReadThread(gSavedSettings.getBOOL("PluginUseReadThread"));
 	
+	// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
+	createSpareBrowserMediaSource();
+	
 	sAnyMediaShowing = false;
 	sUpdatedCookies = getCookieStore()->getChangedCookies();
 	if(!sUpdatedCookies.empty())
@@ -759,6 +765,12 @@ void LLViewerMedia::updateMedia(void *dummy_arg)
 		pimpl->update();
 		pimpl->calculateInterest();
 	}
+	
+	// Let the spare media source actually launch
+	if(sSpareBrowserMediaSource)
+	{
+		sSpareBrowserMediaSource->idle();
+	}
 		
 	// Sort the static instance list using our interest criteria
 	sViewerMediaImplList.sort(priorityComparitor);
@@ -1034,6 +1046,26 @@ bool LLViewerMedia::isParcelAudioPlaying()
 	return (LLViewerMedia::hasParcelAudio() && gAudiop && LLAudioEngine::AUDIO_PLAYING == gAudiop->isInternetStreamPlaying());
 }
 
+void LLViewerMedia::onAuthSubmit(const LLSD& notification, const LLSD& response)
+{
+	LLViewerMediaImpl *impl = LLViewerMedia::getMediaImplFromTextureID(notification["payload"]["media_id"]);
+	if(impl)
+	{
+		LLPluginClassMedia* media = impl->getMediaPlugin();
+		if(media)
+		{
+			if (response["ok"])
+			{
+				media->sendAuthResponse(true, response["username"], response["password"]);
+			}
+			else
+			{
+				media->sendAuthResponse(false, "", "");
+			}
+		}
+	}
+}
+
 /////////////////////////////////////////////////////////////////////////////////////////
 // static
 void LLViewerMedia::clearAllCookies()
@@ -1083,7 +1115,7 @@ void LLViewerMedia::clearAllCookies()
 	}
 	
 	// the hard part: iterate over all user directories and delete the cookie file from each one
-	while(gDirUtilp->getNextFileInDir(base_dir, "*_*", filename, false))
+	while(gDirUtilp->getNextFileInDir(base_dir, "*_*", filename))
 	{
 		target = base_dir;
 		target += filename;
@@ -1400,6 +1432,29 @@ void LLViewerMedia::proxyWindowClosed(const std::string &uuid)
 	}
 }
 
+/////////////////////////////////////////////////////////////////////////////////////////
+// static
+void LLViewerMedia::createSpareBrowserMediaSource()
+{
+	if(!sSpareBrowserMediaSource)
+	{
+		// If we don't have a spare browser media source, create one.
+		// The null owner will keep the browser plugin from fully initializing 
+		// (specifically, it keeps LLPluginClassMedia from negotiating a size change, 
+		// which keeps MediaPluginWebkit::initBrowserWindow from doing anything until we have some necessary data, like the background color)
+		sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType("text/html", NULL, 0, 0);
+	}
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// static
+LLPluginClassMedia* LLViewerMedia::getSpareBrowserMediaSource() 
+{
+	LLPluginClassMedia* result = sSpareBrowserMediaSource;
+	sSpareBrowserMediaSource = NULL;
+	return result; 
+};
+
 bool LLViewerMedia::hasInWorldMedia()
 {
 	if (sInWorldMediaDisabled) return false;
@@ -1636,6 +1691,21 @@ void LLViewerMediaImpl::setMediaType(const std::string& media_type)
 LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, const std::string target)
 {
 	std::string plugin_basename = LLMIMETypes::implType(media_type);
+	LLPluginClassMedia* media_source = NULL;
+	
+	// HACK: we always try to keep a spare running webkit plugin around to improve launch times.
+	if(plugin_basename == "media_plugin_webkit")
+	{
+		media_source = LLViewerMedia::getSpareBrowserMediaSource();
+		if(media_source)
+		{
+			media_source->setOwner(owner);
+			media_source->setTarget(target);
+			media_source->setSize(default_width, default_height);
+						
+			return media_source;
+		}
+	}
 	
 	if(plugin_basename.empty())
 	{
@@ -1673,7 +1743,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 		}
 		else
 		{
-			LLPluginClassMedia* media_source = new LLPluginClassMedia(owner);
+			media_source = new LLPluginClassMedia(owner);
 			media_source->setSize(default_width, default_height);
 			media_source->setUserDataPath(user_data_path);
 			media_source->setLanguageCode(LLUI::getLanguage());
@@ -1753,6 +1823,22 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
 		media_source->focus(mHasFocus);
 		media_source->setBackgroundColor(mBackgroundColor);
 		
+		if(gSavedSettings.getBOOL("BrowserIgnoreSSLCertErrors"))
+		{
+			media_source->ignore_ssl_cert_errors(true);
+		}
+
+		// start by assuming the default CA file will be used
+		std::string ca_path = gDirUtilp->getExpandedFilename( LL_PATH_APP_SETTINGS, "lindenlab.pem" );
+	
+		// default turned off so pick up the user specified path
+		if( ! gSavedSettings.getBOOL("BrowserUseDefaultCAFile"))
+		{
+			ca_path = gSavedSettings.getString("BrowserCAFilePath");
+		}
+		// set the path to the CA.pem file
+		media_source->addCertificateFilePath( ca_path );
+
 		media_source->proxy_setup(gSavedSettings.getBOOL("BrowserProxyEnabled"), gSavedSettings.getString("BrowserProxyAddress"), gSavedSettings.getS32("BrowserProxyPort"));
 		
 		if(mClearCache)
@@ -1848,6 +1934,18 @@ void LLViewerMediaImpl::setSize(int width, int height)
 	}
 }
 
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::showNotification(LLNotificationPtr notify)
+{
+	mNotification = notify;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////
+void LLViewerMediaImpl::hideNotification()
+{
+	mNotification.reset();
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 void LLViewerMediaImpl::play()
 {
@@ -2850,7 +2948,6 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 			LL_DEBUGS("Media") << "MEDIA_EVENT_CLICK_LINK_NOFOLLOW, uri is: " << plugin->getClickURL() << LL_ENDL; 
 			std::string url = plugin->getClickURL();
 			LLURLDispatcher::dispatch(url, NULL, mTrustedBrowser);
-
 		}
 		break;
 		case MEDIA_EVENT_CLICK_LINK_HREF:
@@ -2913,6 +3010,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 		case LLViewerMediaObserver::MEDIA_EVENT_NAVIGATE_BEGIN:
 		{
 			LL_DEBUGS("Media") << "MEDIA_EVENT_NAVIGATE_BEGIN, uri is: " << plugin->getNavigateURI() << LL_ENDL;
+			hideNotification();
 
 			if(getNavState() == MEDIANAVSTATE_SERVER_SENT)
 			{
@@ -3003,7 +3101,26 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 			plugin->sendPickFileResponse(response);
 		}
 		break;
-		
+
+
+		case LLViewerMediaObserver::MEDIA_EVENT_AUTH_REQUEST:
+		{
+			LLNotification::Params auth_request_params;
+			auth_request_params.name = "AuthRequest";
+
+			// pass in host name and realm for site (may be zero length but will always exist)
+			LLSD args;
+			LLURL raw_url( plugin->getAuthURL().c_str() );
+			args["HOST_NAME"] = raw_url.getAuthority();
+			args["REALM"] = plugin->getAuthRealm();
+			auth_request_params.substitutions = args;
+
+			auth_request_params.payload = LLSD().with("media_id", mTextureId);
+			auth_request_params.functor.function = boost::bind(&LLViewerMedia::onAuthSubmit, _1, _2);
+			LLNotifications::instance().add(auth_request_params);
+		};
+		break;
+
 		case LLViewerMediaObserver::MEDIA_EVENT_CLOSE_REQUEST:
 		{
 			std::string uuid = plugin->getClickUUID();
@@ -3019,6 +3136,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 				// This close request is directed at another instance
 				pass_through = false;
 				LLFloaterMediaBrowser::closeRequest(uuid);
+				LLFloaterWebContent::closeRequest(uuid);
 			}
 		}
 		break;
@@ -3038,6 +3156,7 @@ void LLViewerMediaImpl::handleMediaEvent(LLPluginClassMedia* plugin, LLPluginCla
 				// This request is directed at another instance
 				pass_through = false;
 				LLFloaterMediaBrowser::geometryChanged(uuid, plugin->getGeometryX(), plugin->getGeometryY(), plugin->getGeometryWidth(), plugin->getGeometryHeight());
+				LLFloaterWebContent::geometryChanged(uuid, plugin->getGeometryX(), plugin->getGeometryY(), plugin->getGeometryWidth(), plugin->getGeometryHeight());
 			}
 		}
 		break;
@@ -3521,6 +3640,11 @@ bool LLViewerMediaImpl::isInAgentParcel() const
 	return result;
 }
 
+LLNotificationPtr LLViewerMediaImpl::getCurrentNotification() const
+{
+	return mNotification;
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 //
 // static
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 4025a4484ff0437edb7d708893b8fb1e93c3f772..e2e342cc454e7e73892979012eed48434a33ef76 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -37,6 +37,7 @@
 
 #include "llpluginclassmedia.h"
 #include "v4color.h"
+#include "llnotificationptr.h"
 
 #include "llurl.h"
 
@@ -130,6 +131,8 @@ class LLViewerMedia
 	static bool isParcelMediaPlaying();
 	static bool isParcelAudioPlaying();
 	
+	static void onAuthSubmit(const LLSD& notification, const LLSD& response);
+
 	// Clear all cookies for all plugins
 	static void clearAllCookies();
 	
@@ -155,6 +158,9 @@ class LLViewerMedia
 	static void proxyWindowOpened(const std::string &target, const std::string &uuid);
 	static void proxyWindowClosed(const std::string &uuid);
 	
+	static void createSpareBrowserMediaSource();
+	static LLPluginClassMedia* getSpareBrowserMediaSource();
+	
 private:
 	static void setOpenIDCookie();
 	static void onTeleportFinished();
@@ -162,6 +168,7 @@ class LLViewerMedia
 	static LLPluginCookieStore *sCookieStore;
 	static LLURL sOpenIDURL;
 	static std::string sOpenIDCookie;
+	static LLPluginClassMedia* sSpareBrowserMediaSource;
 };
 
 // Implementation functions not exported into header file
@@ -195,6 +202,9 @@ class LLViewerMediaImpl
 	LLPluginClassMedia* getMediaPlugin() { return mMediaSource; }
 	void setSize(int width, int height);
 
+	void showNotification(LLNotificationPtr notify);
+	void hideNotification();
+
 	void play();
 	void stop();
 	void pause();
@@ -387,6 +397,9 @@ class LLViewerMediaImpl
 	// Is this media in the agent's parcel?
 	bool isInAgentParcel() const;
 
+	// get currently active notification associated with this media instance
+	LLNotificationPtr getCurrentNotification() const;
+
 private:
 	bool isAutoPlayable() const;
 	bool shouldShowBasedOnClass() const;
@@ -444,7 +457,8 @@ class LLViewerMediaImpl
 	bool mNavigateSuspendedDeferred;
 	bool mTrustedBrowser;
 	std::string mTarget;
-	
+	LLNotificationPtr mNotification;
+
 private:
 	BOOL mIsUpdated ;
 	std::list< LLVOVolume* > mObjectList ;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 2874a6ec7935ba82792318255d2ae00fe5093271..9e16bf2fbb0fc362ceae59b1e2e7a523f4c3d07f 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -45,7 +45,7 @@
 #include "llconsole.h"
 #include "lldebugview.h"
 #include "llfilepicker.h"
-//#include "llfirstuse.h"
+#include "llfirstuse.h"
 #include "llfloaterbuy.h"
 #include "llfloaterbuycontents.h"
 #include "llbuycurrencyhtml.h"
@@ -191,6 +191,8 @@ BOOL is_selection_buy_not_take();
 S32 selection_price();
 BOOL enable_take();
 void handle_take();
+void handle_object_show_inspector();
+void handle_avatar_show_inspector();
 bool confirm_take(const LLSD& notification, const LLSD& response);
 
 void handle_buy_object(LLSaleInfo sale_info);
@@ -841,6 +843,35 @@ class LLAdvancedCheckFeature : public view_listener_t
 }
 };
 
+void LLDestinationAndAvatarShow(const LLSD& value)
+{
+	S32 panel_idx = value.isDefined() ? value.asInteger() : -1;
+	LLView* container = gViewerWindow->getRootView()->getChildView("avatar_picker_and_destination_guide_container");
+	LLMediaCtrl* destinations = container->findChild<LLMediaCtrl>("destination_guide_contents");
+	LLMediaCtrl* avatar_picker = container->findChild<LLMediaCtrl>("avatar_picker_contents");
+
+	switch(panel_idx)
+	{
+	case 0:
+		container->setVisible(true);
+		destinations->setVisible(true);
+		avatar_picker->setVisible(false);
+		LLFirstUse::notUsingDestinationGuide(false);
+		break;
+	case 1:
+		container->setVisible(true);
+		destinations->setVisible(false);
+		avatar_picker->setVisible(true);
+		LLFirstUse::notUsingAvatarPicker(false);
+		break;
+	default:
+		container->setVisible(false);
+		destinations->setVisible(false);
+		avatar_picker->setVisible(false);
+		break;
+	}
+};
+
 
 //////////////////
 // INFO DISPLAY //
@@ -4294,6 +4325,33 @@ void handle_take()
 	}
 }
 
+void handle_object_show_inspector()
+{
+	LLObjectSelectionHandle selection = LLSelectMgr::getInstance()->getSelection();
+	LLViewerObject* objectp = selection->getFirstRootObject(TRUE);
+ 	if (!objectp)
+ 	{
+ 		return;
+ 	}
+
+	LLSD params;
+	params["object_id"] = objectp->getID();
+	LLFloaterReg::showInstance("inspect_object", params);
+}
+
+void handle_avatar_show_inspector()
+{
+	LLVOAvatar* avatar = find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+	if(avatar)
+	{
+		LLSD params;
+		params["avatar_id"] = avatar->getID();
+		LLFloaterReg::showInstance("inspect_avatar", params);
+	}
+}
+
+
+
 bool confirm_take(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@@ -6500,16 +6558,6 @@ class LLToggleControl : public view_listener_t
 		std::string control_name = userdata.asString();
 		BOOL checked = gSavedSettings.getBOOL( control_name );
 		gSavedSettings.setBOOL( control_name, !checked );
-
-        // Doubleclick actions - there can be only one
-        if ((control_name == "DoubleClickAutoPilot") && !checked)
-        {
-			gSavedSettings.setBOOL( "DoubleClickTeleport", FALSE );
-        }
-        else if ((control_name == "DoubleClickTeleport") && !checked)
-        {
-			gSavedSettings.setBOOL( "DoubleClickAutoPilot", FALSE );
-        }
 		return true;
 	}
 };
@@ -7175,6 +7223,12 @@ void handle_web_browser_test(const LLSD& param)
 	LLWeb::loadURLInternal(url);
 }
 
+void handle_web_content_test(const LLSD& param)
+{
+	std::string url = param.asString();
+	LLWeb::loadWebURLInternal(url);
+}
+
 void handle_buy_currency_test(void*)
 {
 	std::string url =
@@ -7805,6 +7859,9 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType");
 	view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
 
+	// Me > Movement
+	view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
+	
 	// World menu
 	commit.add("World.Chat", boost::bind(&handle_chat, (void*)NULL));
 	view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
@@ -7878,9 +7935,6 @@ void initialize_menus()
 
 	// Advanced Other Settings	
 	view_listener_t::addMenu(new LLAdvancedClearGroupCache(), "Advanced.ClearGroupCache");
-
-	// Advanced > Shortcuts
-	view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
 	
 	// Advanced > Render > Types
 	view_listener_t::addMenu(new LLAdvancedToggleRenderType(), "Advanced.ToggleRenderType");
@@ -7925,7 +7979,8 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLAdvancedDumpRegionObjectCache(), "Advanced.DumpRegionObjectCache");
 
 	// Advanced > UI
-	commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test, _2));
+	commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test,	_2));	// sigh! this one opens the MEDIA browser
+	commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2));	// this one opens the Web Content floater
 	view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
 	view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
 	view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
@@ -8056,6 +8111,7 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLAvatarVisibleDebug(), "Avatar.VisibleDebug");
 	view_listener_t::addMenu(new LLAvatarInviteToGroup(), "Avatar.InviteToGroup");
 	commit.add("Avatar.Eject", boost::bind(&handle_avatar_eject, LLSD()));
+	commit.add("Avatar.ShowInspector", boost::bind(&handle_avatar_show_inspector));
 	view_listener_t::addMenu(new LLAvatarSendIM(), "Avatar.SendIM");
 	view_listener_t::addMenu(new LLAvatarCall(), "Avatar.Call");
 	enable.add("Avatar.EnableCall", boost::bind(&LLAvatarActions::canCall));
@@ -8083,6 +8139,7 @@ void initialize_menus()
 	commit.add("Object.Inspect", boost::bind(&handle_object_inspect));
 	commit.add("Object.Open", boost::bind(&handle_object_open));
 	commit.add("Object.Take", boost::bind(&handle_take));
+	commit.add("Object.ShowInspector", boost::bind(&handle_object_show_inspector));
 	enable.add("Object.EnableOpen", boost::bind(&enable_object_open));
 	enable.add("Object.EnableTouch", boost::bind(&enable_object_touch, _1));
 	enable.add("Object.EnableDelete", boost::bind(&enable_object_delete));
@@ -8142,4 +8199,6 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLEditableSelectedMono(), "EditableSelectedMono");
 
 	view_listener_t::addMenu(new LLToggleUIHints(), "ToggleUIHints");
+
+	commit.add("DestinationAndAvatar.show", boost::bind(&LLDestinationAndAvatarShow, _2));
 }
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 237aa39e6e6ce4bf07ef63c533e5bae51f825b77..fda291f3c1ce9e29f0e70b44a5ba7c60469ba77f 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -507,7 +507,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
 				"No file extension for the file: '%s'\nPlease make sure the file has a correct file extension",
 				short_name.c_str());
 		args["FILE"] = short_name;
- 		upload_error(error_message, "NofileExtension", filename, args);
+ 		upload_error(error_message, "NoFileExtension", filename, args);
 		return;
 	}
 	else if( exten == "bmp")
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 0ca30d5f3dc3db5a4537e40d3e454ad3f5f24dcb..7dc5d96689d4449471ee7a736ca676137f444bf4 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -39,6 +39,7 @@
 #include "llfloaterreg.h"
 #include "llfollowcamparams.h"
 #include "llinventorydefines.h"
+#include "lllslconstants.h"
 #include "llregionhandle.h"
 #include "llsdserialize.h"
 #include "llteleportflags.h"
@@ -170,6 +171,31 @@ const BOOL SCRIPT_QUESTION_IS_CAUTION[SCRIPT_PERMISSION_EOF] =
 	FALSE	// ControlYourCamera
 };
 
+// Extract channel and version from a string like "SL Web Viewer Beta 10.11.29.215604".
+// (channel: "SL Web Viewer Beta", version: "10.11.29.215604")
+static bool parse_version_info(const std::string& version_info, std::string& channel, std::string& ver)
+{
+	size_t last_space = version_info.rfind(" ");
+	channel = version_info;
+
+	if (last_space != std::string::npos)
+	{
+		try
+		{
+			ver = version_info.substr(last_space + 1);
+			channel.replace(last_space, ver.length() + 1, ""); // strip version
+		}
+		catch (std::out_of_range)
+		{
+			return false;
+		}
+
+		return true;
+	}
+
+	return false;
+}
+
 bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@@ -638,7 +664,7 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
 	if(option == 0 && !group_id.isNull())
 	{
 		// check for promotion or demotion.
-		S32 max_groups = MAX_AGENT_GROUPS;
+		S32 max_groups = gMaxAgentGroups;
 		if(gAgent.isInGroup(group_id)) ++max_groups;
 
 		if(gAgent.mGroups.count() < max_groups)
@@ -3031,6 +3057,7 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
 		}
 		else
 		{
+			args["NAME"] = source_name;
 			LLNotificationsUtil::add("OfferCallingCard", args, payload);
 		}
 	}
@@ -3345,6 +3372,8 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 // then this info is news to us.
 void process_teleport_start(LLMessageSystem *msg, void**)
 {
+	// on teleport, don't tell them about destination guide anymore
+	LLFirstUse::notUsingDestinationGuide(false);
 	U32 teleport_flags = 0x0;
 	msg->getU32("Info", "TeleportFlags", teleport_flags);
 
@@ -3821,28 +3850,22 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 
 	if (!gLastVersionChannel.empty())
 	{
-		// work out the URL for this server's Release Notes
-		std::string url ="http://wiki.secondlife.com/wiki/Release_Notes/";
-		std::string server_version = version_channel;
-		std::vector<std::string> s_vect;
-		boost::algorithm::split(s_vect, server_version, isspace);
-		for(U32 i = 0; i < s_vect.size(); i++)
+		std::string url = regionp->getCapability("ServerReleaseNotes");
+		if (url.empty())
 		{
-			if (i != (s_vect.size() - 1))
+			// The capability hasn't arrived yet or is not supported,
+			// fall back to parsing server version channel.
+			std::string channel, ver;
+			if (!parse_version_info(version_channel, channel, ver))
 			{
-				if(i != (s_vect.size() - 2))
-				{
-				   url += s_vect[i] + "_";
-				}
-				else
-				{
-					url += s_vect[i] + "/";
-				}
-			}
-			else
-			{
-				url += s_vect[i].substr(0,4);
+				llwarns << "Failed to parse server version channel (" << version_channel << ")" << llendl;
 			}
+
+			url = gSavedSettings.getString("ReleaseNotesURL");
+			LLSD args;
+			args["CHANNEL"] = LLWeb::escapeURL(channel);
+			args["VERSION"] = LLWeb::escapeURL(ver);
+			LLStringUtil::format(url, args);
 		}
 
 		LLSD args;
@@ -3866,6 +3889,7 @@ void process_crossed_region(LLMessageSystem* msg, void**)
 		return;
 	}
 	LL_INFOS("Messaging") << "process_crossed_region()" << LL_ENDL;
+	gAgentAvatarp->resetRegionCrossingTimer();
 
 	U32 sim_ip;
 	msg->getIPAddrFast(_PREHASH_RegionData, _PREHASH_SimIP, sim_ip);
@@ -6301,6 +6325,9 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response)
 				payload["from_id"] = target_id;
 				payload["SUPPRESS_TOAST"] = true;
 				LLNotificationsUtil::add("TeleportOfferSent", args, payload);
+
+				// Add the recepient to the recent people list.
+				LLRecentPeople::instance().add(target_id);
 			}
 		}
 		gAgent.sendReliableMessage();
@@ -6434,8 +6461,22 @@ const char* SCRIPT_DIALOG_HEADER = "Script Dialog:\n";
 bool callback_script_dialog(const LLSD& notification, const LLSD& response)
 {
 	LLNotificationForm form(notification["form"]);
-	std::string button = LLNotification::getSelectedOptionName(response);
-	S32 button_idx = LLNotification::getSelectedOption(notification, response);
+
+	std::string rtn_text;
+	S32 button_idx;
+	button_idx = LLNotification::getSelectedOption(notification, response);
+	if (response[TEXTBOX_MAGIC_TOKEN].isDefined())
+	{
+		if (response[TEXTBOX_MAGIC_TOKEN].isString())
+			rtn_text = response[TEXTBOX_MAGIC_TOKEN].asString();
+		else
+			rtn_text.clear(); // bool marks empty string
+	}
+	else
+	{
+		rtn_text = LLNotification::getSelectedOptionName(response);
+	}
+
 	// Didn't click "Ignore"
 	if (button_idx != -1)
 	{
@@ -6448,7 +6489,7 @@ bool callback_script_dialog(const LLSD& notification, const LLSD& response)
 		msg->addUUID("ObjectID", notification["payload"]["object_id"].asUUID());
 		msg->addS32("ChatChannel", notification["payload"]["chat_channel"].asInteger());
 		msg->addS32("ButtonIndex", button_idx);
-		msg->addString("ButtonLabel", button);
+		msg->addString("ButtonLabel", rtn_text);
 		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
 	}
 
@@ -6669,6 +6710,8 @@ void process_initiate_download(LLMessageSystem* msg, void**)
 
 void process_script_teleport_request(LLMessageSystem* msg, void**)
 {
+	if (!gSavedSettings.getBOOL("ScriptsCanShowUI")) return;
+
 	std::string object_name;
 	std::string sim_name;
 	LLVector3 pos;
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index 6ff893f543c21875a509b5a6e80926c50543b98b..b4a9b8e6773580897b478e8bc62c6c2b5d523cc3 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -117,7 +117,6 @@ void process_alert_core(const std::string& message, BOOL modal);
 typedef std::list<LLMeanCollisionData*> mean_collision_list_t;
 extern mean_collision_list_t gMeanCollisionList;
 
-void handle_show_mean_events(void *);
 void process_mean_collision_alert_message(LLMessageSystem* msg, void**);
 
 void process_frozen_message(LLMessageSystem* msg, void**);
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 0e1553c421eaedf94121e79de7995ba819f16c71..1804fac1b3dbfc3765a4c8b0a2bc4254c29ebb74 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -103,8 +103,8 @@
 
 //#define DEBUG_UPDATE_TYPE
 
-BOOL gVelocityInterpolate = TRUE;
-BOOL gPingInterpolate = TRUE; 
+BOOL		LLViewerObject::sVelocityInterpolate = TRUE;
+BOOL		LLViewerObject::sPingInterpolate = TRUE; 
 
 U32			LLViewerObject::sNumZombieObjects = 0;
 S32			LLViewerObject::sNumObjects = 0;
@@ -115,6 +115,11 @@ S32			LLViewerObject::sAxisArrowLength(50);
 BOOL		LLViewerObject::sPulseEnabled(FALSE);
 BOOL		LLViewerObject::sUseSharedDrawables(FALSE); // TRUE
 
+// sMaxUpdateInterpolationTime must be greater than sPhaseOutUpdateInterpolationTime
+F64			LLViewerObject::sMaxUpdateInterpolationTime = 3.0;		// For motion interpolation: after X seconds with no updates, don't predict object motion
+F64			LLViewerObject::sPhaseOutUpdateInterpolationTime = 2.0;	// For motion interpolation: after Y seconds with no updates, taper off motion prediction
+
+
 static LLFastTimer::DeclareTimer FTM_CREATE_OBJECT("Create Object");
 
 // static
@@ -205,6 +210,7 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	mLastInterpUpdateSecs(0.f),
 	mLastMessageUpdateSecs(0.f),
 	mLatestRecvPacketID(0),
+	mCircuitPacketCount(0),
 	mData(NULL),
 	mAudioSourcep(NULL),
 	mAudioGain(1.f),
@@ -1841,7 +1847,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 
 	new_rot.normQuat();
 
-	if (gPingInterpolate)
+	if (sPingInterpolate)
 	{ 
 		LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(mesgsys->getSender());
 		if (cdp)
@@ -1862,6 +1868,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 	//
 	//
 
+	// WTF?   If we're going to skip this message, why are we 
+	// doing all the parenting, etc above?
 	U32 packet_id = mesgsys->getCurrentRecvPacketID(); 
 	if (packet_id < mLatestRecvPacketID && 
 		mLatestRecvPacketID - packet_id < 65536)
@@ -1871,6 +1879,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 	}
 
 	mLatestRecvPacketID = packet_id;
+	mCircuitPacketCount = 0;
 
 	// Set the change flags for scale
 	if (new_scale != getScale())
@@ -2002,7 +2011,7 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 
 //	U32 ping_delay = mesgsys->mCircuitInfo.getPingDelay();
 	mLastInterpUpdateSecs = LLFrameTimer::getElapsedSeconds();
-	mLastMessageUpdateSecs = LLFrameTimer::getElapsedSeconds();
+	mLastMessageUpdateSecs = mLastInterpUpdateSecs;
 	if (mDrawable.notNull())
 	{
 		// Don't clear invisibility flag on update if still orphaned!
@@ -2029,6 +2038,8 @@ BOOL LLViewerObject::isActive() const
 	return TRUE;
 }
 
+
+
 BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 {
 	static LLFastTimer::DeclareTimer ftm("Viewer Object");
@@ -2042,7 +2053,7 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 
 	// CRO - don't velocity interp linked objects!
 	// Leviathan - but DO velocity interp joints
-	if (!mStatic && gVelocityInterpolate && !isSelected())
+	if (!mStatic && sVelocityInterpolate && !isSelected())
 	{
 		// calculate dt from last update
 		F32 dt_raw = (F32)(time - mLastInterpUpdateSecs);
@@ -2132,33 +2143,8 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 			return TRUE;
 		}
 		else
-		{
-			// linear motion
-			// PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object
-			// updates represents the average velocity of the last timestep, rather than the final velocity.
-			// the time dilation above should guarantee that dt is never less than PHYSICS_TIMESTEP, theoretically
-			// 
-			// There is a problem here if dt is negative. . .
-
-			// *TODO: should also wrap linear accel/velocity in check
-			// to see if object is selected, instead of explicitly
-			// zeroing it out	
-			LLVector3 accel = getAcceleration();
-			LLVector3 vel 	= getVelocity();
-			
-			if (!(accel.isExactlyZero() && vel.isExactlyZero()))
-			{
-				LLVector3 pos 	= (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;	
-			
-				// region local  
-				setPositionRegion(pos + getPositionRegion());
-				setVelocity(vel + accel*dt);	
-				
-				// for objects that are spinning but not translating, make sure to flag them as having moved
-				setChanged(MOVED | SILHOUETTE);
-			}
-			
-			mLastInterpUpdateSecs = time;
+		{	// Move object based on it's velocity and rotation
+			interpolateLinearMotion(time, dt);
 		}
 	}
 
@@ -2174,6 +2160,158 @@ BOOL LLViewerObject::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 }
 
 
+// Move an object due to idle-time viewer side updates by iterpolating motion
+void LLViewerObject::interpolateLinearMotion(const F64 & time, const F32 & dt)
+{
+	// linear motion
+	// PHYSICS_TIMESTEP is used below to correct for the fact that the velocity in object
+	// updates represents the average velocity of the last timestep, rather than the final velocity.
+	// the time dilation above should guarantee that dt is never less than PHYSICS_TIMESTEP, theoretically
+	// 
+	// *TODO: should also wrap linear accel/velocity in check
+	// to see if object is selected, instead of explicitly
+	// zeroing it out	
+
+	F64 time_since_last_update = time - mLastMessageUpdateSecs;
+	if (time_since_last_update <= 0.0 || dt <= 0.f)
+	{
+		return;
+	}
+
+	LLVector3 accel = getAcceleration();
+	LLVector3 vel 	= getVelocity();
+	
+	if (sMaxUpdateInterpolationTime <= 0.0)
+	{	// Old code path ... unbounded, simple interpolation
+		if (!(accel.isExactlyZero() && vel.isExactlyZero()))
+		{
+			LLVector3 pos   = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;  
+		
+			// region local  
+			setPositionRegion(pos + getPositionRegion());
+			setVelocity(vel + accel*dt);	
+			
+			// for objects that are spinning but not translating, make sure to flag them as having moved
+			setChanged(MOVED | SILHOUETTE);
+		}
+	}
+	else if (!accel.isExactlyZero() || !vel.isExactlyZero())		// object is moving
+	{	// Object is moving, and hasn't been too long since we got an update from the server
+		
+		// Calculate predicted position and velocity
+		LLVector3 new_pos = (vel + (0.5f * (dt-PHYSICS_TIMESTEP)) * accel) * dt;	
+		LLVector3 new_v = accel * dt;
+
+		if (time_since_last_update > sPhaseOutUpdateInterpolationTime)
+		{	// Haven't seen a viewer update in a while, check to see if the ciruit is still active
+			if (mRegionp)
+			{	// The simulator will NOT send updates if the object continues normally on the path
+				// predicted by the velocity and the acceleration (often gravity) sent to the viewer
+				// So check to see if the circuit is blocked, which means the sim is likely in a long lag
+				LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit( mRegionp->getHost() );
+				if (cdp)
+				{
+					if (!cdp->isAlive() ||		// Circuit is dead or blocked
+						 cdp->isBlocked() ||	// or doesn't seem to be getting any packets
+						 (mCircuitPacketCount > 0 && mCircuitPacketCount == cdp->getPacketsIn()))
+					{
+						// Start to reduce motion interpolation since we haven't seen a server update in a while
+						F64 time_since_last_interpolation = time - mLastInterpUpdateSecs;
+						F64 phase_out = 1.0;
+						if (time_since_last_update > sMaxUpdateInterpolationTime)
+						{	// Past the time limit, so stop the object
+							phase_out = 0.0;
+							//llinfos << "Motion phase out to zero" << llendl;
+
+							// Kill angular motion as well.  Note - not adding this due to paranoia
+							// about stopping rotation for llTargetOmega objects and not having it restart
+							// setAngularVelocity(LLVector3::zero);
+						}
+						else if (mLastInterpUpdateSecs - mLastMessageUpdateSecs > sPhaseOutUpdateInterpolationTime)
+						{	// Last update was already phased out a bit
+							phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) / 
+										(sMaxUpdateInterpolationTime - time_since_last_interpolation);
+							//llinfos << "Continuing motion phase out of " << (F32) phase_out << llendl;
+						}
+						else
+						{	// Phase out from full value
+							phase_out = (sMaxUpdateInterpolationTime - time_since_last_update) / 
+										(sMaxUpdateInterpolationTime - sPhaseOutUpdateInterpolationTime);
+							//llinfos << "Starting motion phase out of " << (F32) phase_out << llendl;
+						}
+						phase_out = llclamp(phase_out, 0.0, 1.0);
+
+						new_pos = new_pos * ((F32) phase_out);
+						new_v = new_v * ((F32) phase_out);
+					}
+
+					// Save current circuit packet count to see if it changes 
+					mCircuitPacketCount = cdp->getPacketsIn();
+				}
+			}
+		}
+
+		new_pos = new_pos + getPositionRegion();
+		new_v = new_v + vel;
+
+
+		// Clamp interpolated position to minimum underground and maximum region height
+		LLVector3d new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos);
+		F32 min_height;
+		if (isAvatar())
+		{	// Make a better guess about AVs not going underground
+			min_height = LLWorld::getInstance()->resolveLandHeightGlobal(new_pos_global);
+			min_height += (0.5f * getScale().mV[VZ]);
+		}
+		else
+		{	// This will put the object underground, but we can't tell if it will stop 
+			// at ground level or not
+			min_height = LLWorld::getInstance()->getMinAllowedZ(this, new_pos_global);
+		}
+
+		new_pos.mV[VZ] = llmax(min_height, new_pos.mV[VZ]);
+		new_pos.mV[VZ] = llmin(LLWorld::getInstance()->getRegionMaxHeight(), new_pos.mV[VZ]);
+
+		// Check to see if it's going off the region
+		LLVector3 temp(new_pos);
+		if (temp.clamp(0.f, mRegionp->getWidth()))
+		{	// Going off this region, so see if we might end up on another region
+			LLVector3d old_pos_global = mRegionp->getPosGlobalFromRegion(getPositionRegion());
+			new_pos_global = mRegionp->getPosGlobalFromRegion(new_pos);		// Re-fetch in case it got clipped above
+
+			// Clip the positions to known regions
+			LLVector3d clip_pos_global = LLWorld::getInstance()->clipToVisibleRegions(old_pos_global, new_pos_global);
+			if (clip_pos_global != new_pos_global)
+			{	// Was clipped, so this means we hit a edge where there is no region to enter
+				
+				//llinfos << "Hit empty region edge, clipped predicted position to " << mRegionp->getPosRegionFromGlobal(clip_pos_global)
+				//	<< " from " << new_pos << llendl;
+				new_pos = mRegionp->getPosRegionFromGlobal(clip_pos_global);
+				
+				// Stop motion and get server update for bouncing on the edge
+				new_v.clear();
+				setAcceleration(LLVector3::zero);
+			}
+			else
+			{	// Let predicted movement cross into another region
+				//llinfos << "Predicting region crossing to " << new_pos << llendl;
+			}
+		}
+
+		// Set new position and velocity
+		setPositionRegion(new_pos);
+		setVelocity(new_v);	
+		
+		// for objects that are spinning but not translating, make sure to flag them as having moved
+		setChanged(MOVED | SILHOUETTE);
+	}		
+
+	// Update the last time we did anything
+	mLastInterpUpdateSecs = time;
+}
+
+
+
 BOOL LLViewerObject::setData(const U8 *datap, const U32 data_size)
 {
 	LLMemType mt(LLMemType::MTYPE_OBJECT);
@@ -4962,6 +5100,7 @@ void LLViewerObject::setRegion(LLViewerRegion *regionp)
 	}
 	
 	mLatestRecvPacketID = 0;
+	mCircuitPacketCount = 0;
 	mRegionp = regionp;
 
 	for (child_list_t::iterator i = mChildList.begin(); i != mChildList.end(); ++i)
@@ -4974,6 +5113,20 @@ void LLViewerObject::setRegion(LLViewerRegion *regionp)
 	updateDrawable(FALSE);
 }
 
+// virtual
+void	LLViewerObject::updateRegion(LLViewerRegion *regionp)
+{
+//	if (regionp)
+//	{
+//		F64 now = LLFrameTimer::getElapsedSeconds();
+//		llinfos << "Updating to region " << regionp->getName()
+//			<< ", ms since last update message: " << (F32)((now - mLastMessageUpdateSecs) * 1000.0)
+//			<< ", ms since last interpolation: " << (F32)((now - mLastInterpUpdateSecs) * 1000.0) 
+//			<< llendl;
+//	}
+}
+
+
 bool LLViewerObject::specialHoverCursor() const
 {
 	return (mFlags & FLAGS_USE_PHYSICS)
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index c2475c2709e6d13be27e983de0db30c3317b468d..fe670f882716efb39b69fa24270660384143610d 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -464,7 +464,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	bool specialHoverCursor() const;	// does it have a special hover cursor?
 
 	void			setRegion(LLViewerRegion *regionp);
-	virtual void	updateRegion(LLViewerRegion *regionp) {}
+	virtual void	updateRegion(LLViewerRegion *regionp);
 
 	void updateFlags();
 	BOOL setFlags(U32 flag, BOOL state);
@@ -510,6 +510,9 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
     // and the update wasn't due to this agent's last action.
     U32 checkMediaURL(const std::string &media_url);
 	
+	// Motion prediction between updates
+	void interpolateLinearMotion(const F64 & time, const F32 & dt);
+
 public:
 	//
 	// Viewer-side only types - use the LL_PCODE_APP mask.
@@ -612,6 +615,8 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	F64				mLastInterpUpdateSecs;			// Last update for purposes of interpolation
 	F64				mLastMessageUpdateSecs;			// Last update from a message from the simulator
 	TPACKETID		mLatestRecvPacketID;			// Latest time stamp on message from simulator
+	U32				mCircuitPacketCount;			// Packet tracking for early detection of a stopped simulator circuit
+
 	// extra data sent from the sim...currently only used for tree species info
 	U8* mData;
 
@@ -669,9 +674,21 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	mutable LLVector3		mPositionRegion;
 	mutable LLVector3		mPositionAgent;
 
+	static void setPhaseOutUpdateInterpolationTime(F32 value)	{ sPhaseOutUpdateInterpolationTime = (F64) value;	}
+	static void setMaxUpdateInterpolationTime(F32 value)		{ sMaxUpdateInterpolationTime = (F64) value;	}
+
+	static void	setVelocityInterpolate(BOOL value)		{ sVelocityInterpolate = value;	}
+	static void	setPingInterpolate(BOOL value)			{ sPingInterpolate = value;	}
+
 private:	
 	static S32 sNumObjects;
 
+	static F64 sPhaseOutUpdateInterpolationTime;	// For motion interpolation
+	static F64 sMaxUpdateInterpolationTime;			// For motion interpolation
+
+	static BOOL sVelocityInterpolate;
+	static BOOL sPingInterpolate;
+
 	//--------------------------------------------------------------------
 	// For objects that are attachments
 	//--------------------------------------------------------------------
@@ -742,7 +759,5 @@ class LLStaticViewerObject : public LLViewerObject
 	virtual void updateDrawable(BOOL force_damped);
 };
 
-extern BOOL gVelocityInterpolate;
-extern BOOL gPingInterpolate;
 
 #endif
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index a414e8686683b5e8fe694e7b8a05e6cc412f70e9..f5a32438cfef2effc43e3372208c528b924b9e0a 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -659,9 +659,24 @@ void LLViewerObjectList::updateApparentAngles(LLAgent &agent)
 void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
 {
 	LLMemType mt(LLMemType::MTYPE_OBJECT);
+
 	// Update globals
-	gVelocityInterpolate = gSavedSettings.getBOOL("VelocityInterpolate");
-	gPingInterpolate = gSavedSettings.getBOOL("PingInterpolate");
+	LLViewerObject::setVelocityInterpolate( gSavedSettings.getBOOL("VelocityInterpolate") );
+	LLViewerObject::setPingInterpolate( gSavedSettings.getBOOL("PingInterpolate") );
+	
+	F32 interp_time = gSavedSettings.getF32("InterpolationTime");
+	F32 phase_out_time = gSavedSettings.getF32("InterpolationPhaseOut");
+	if (interp_time < 0.0 || 
+		phase_out_time < 0.0 ||
+		phase_out_time > interp_time)
+	{
+		llwarns << "Invalid values for InterpolationTime or InterpolationPhaseOut, resetting to defaults" << llendl;
+		interp_time = 3.0f;
+		phase_out_time = 1.0f;
+	}
+	LLViewerObject::setPhaseOutUpdateInterpolationTime( interp_time );
+	LLViewerObject::setMaxUpdateInterpolationTime( phase_out_time );
+
 	gAnimateTextures = gSavedSettings.getBOOL("AnimateTextures");
 
 	// update global timer
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 99e869dafc153ad29347b5dbfbdde184920b1987..40f0b433132389ca31151802c440b2e80fdfd1b8 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -586,6 +586,18 @@ void LLViewerParcelMedia::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent
 			LL_DEBUGS("Media") << "Media event:  MEDIA_EVENT_GEOMETRY_CHANGE, uuid is " << self->getClickUUID() << LL_ENDL;
 		}
 		break;
+
+		case MEDIA_EVENT_AUTH_REQUEST:
+		{
+			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() << ", realm " << self->getAuthRealm() << LL_ENDL;
+		}
+		break;
+
+		case MEDIA_EVENT_LINK_HOVERED:
+		{
+			LL_DEBUGS("Media") <<  "Media event:  MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << LL_ENDL;
+		};
+		break;
 	};
 }
 
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 11de3774101344f00bef5dca9b652c98f3c13c1f..fccd1156d3f613821459969a6a74566615572461 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -850,7 +850,7 @@ LLParcel* LLViewerParcelMgr::getCollisionParcel() const
 
 void LLViewerParcelMgr::render()
 {
-	if (mSelected && mRenderSelection)
+	if (mSelected && mRenderSelection && gSavedSettings.getBOOL("RenderParcelSelection"))
 	{
 		// Rendering is done in agent-coordinates, so need to supply
 		// an appropriate offset to the render code.
@@ -1784,8 +1784,7 @@ void LLViewerParcelMgr::processParcelProperties(LLMessageSystem *msg, void **use
 
 void optionally_start_music(const std::string& music_url)
 {
-	if (gSavedSettings.getBOOL("AudioStreamingMusic") &&
-	    gSavedSettings.getBOOL("AudioStreamingMedia"))
+	if (gSavedSettings.getBOOL("AudioStreamingMusic"))
 	{
 		// only play music when you enter a new parcel if the UI control for this
 		// was not *explicitly* stopped by the user. (part of SL-4878)
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index b684206960b329d900492b2f38d23fb8bb2d490f..551ba18dd549cbd5aa92ec01460d6a6915850c44 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1400,6 +1400,8 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	capabilityNames.append("SendUserReportWithScreenshot");
 	capabilityNames.append("ServerReleaseNotes");
 	capabilityNames.append("SetDisplayName");
+	capabilityNames.append("SimConsole");
+	capabilityNames.append("SimConsoleAsync");
 	capabilityNames.append("StartGroupProposal");
 	capabilityNames.append("TextureStats");
 	capabilityNames.append("UntrustedSimulatorMessage");
@@ -1412,6 +1414,7 @@ void LLViewerRegion::setSeedCapability(const std::string& url)
 	capabilityNames.append("UpdateNotecardTaskInventory");
 	capabilityNames.append("UpdateScriptTask");
 	capabilityNames.append("UploadBakedTexture");
+	capabilityNames.append("ViewerMetrics");
 	capabilityNames.append("ViewerStartAuction");
 	capabilityNames.append("ViewerStats");
 	capabilityNames.append("WebFetchInventoryDescendents");
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 46c78e2bb4210c87a55bc605cfd6b9e2b61e467d..546ee9a334b05646dae5492aa8aa71b01326d187 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -48,6 +48,7 @@
 #include "llagent.h"
 #include "llagentcamera.h"
 #include "llviewercontrol.h"
+#include "llversioninfo.h"
 #include "llfloatertools.h"
 #include "lldebugview.h"
 #include "llfasttimerview.h"
@@ -749,7 +750,7 @@ void send_stats()
 
 	// send fps only for time app spends in foreground
 	agent["fps"] = (F32)gForegroundFrameCount / gForegroundTime.getElapsedTimeF32();
-	agent["version"] = gCurrentVersion;
+	agent["version"] = LLVersionInfo::getChannelAndVersion();
 	std::string language = LLUI::getLanguage();
 	agent["language"] = language;
 	
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 6160510c0e281e3ef77b09b744602b31b8f2c4d4..0c05a301e6be6e5bda26c09c497a4ca01017c0a9 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1494,57 +1494,56 @@ void LLViewerFetchedTexture::setKnownDrawSize(S32 width, S32 height)
 //virtual
 void LLViewerFetchedTexture::processTextureStats()
 {
-	static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes");
-
 	if(mFullyLoaded)
-	{
-		if(needsToSaveRawImage())//needs to reload
+	{		
+		if(mDesiredDiscardLevel > mMinDesiredDiscardLevel)//need to load more
 		{
+			mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel) ;
 			mFullyLoaded = FALSE ;
 		}
-		else
-		{
-			return ;
-		}
-	}
-
-	//updateVirtualSize() ;	
-	
-	if (textures_fullres)
-	{
-		mDesiredDiscardLevel = 0;
-	}
-	else if(!mFullWidth || !mFullHeight)
-	{
-		mDesiredDiscardLevel = 	llmin(getMaxDiscardLevel(), (S32)mLoadedCallbackDesiredDiscardLevel) ;
 	}
 	else
-	{	
-		if(!mKnownDrawWidth || !mKnownDrawHeight || mFullWidth <= mKnownDrawWidth || mFullHeight <= mKnownDrawHeight)
+	{
+		updateVirtualSize() ;
+		
+		static LLCachedControl<bool> textures_fullres(gSavedSettings,"TextureLoadFullRes");
+		
+		if (textures_fullres)
 		{
-			if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
+			mDesiredDiscardLevel = 0;
+		}
+		else if(!mFullWidth || !mFullHeight)
+		{
+			mDesiredDiscardLevel = 	llmin(getMaxDiscardLevel(), (S32)mLoadedCallbackDesiredDiscardLevel) ;
+		}
+		else
+		{	
+			if(!mKnownDrawWidth || !mKnownDrawHeight || mFullWidth <= mKnownDrawWidth || mFullHeight <= mKnownDrawHeight)
 			{
-				mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
+				if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
+				{
+					mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
+				}
+				else
+				{
+					mDesiredDiscardLevel = 0;
+				}
 			}
-			else
+			else if(mKnownDrawSizeChanged)//known draw size is set
+			{			
+				mDesiredDiscardLevel = (S8)llmin(log((F32)mFullWidth / mKnownDrawWidth) / log_2, 
+													 log((F32)mFullHeight / mKnownDrawHeight) / log_2) ;
+				mDesiredDiscardLevel = 	llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel()) ;
+				mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel) ;
+			}
+			mKnownDrawSizeChanged = FALSE ;
+		
+			if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel))
 			{
-				mDesiredDiscardLevel = 0;
+				mFullyLoaded = TRUE ;
 			}
 		}
-		else if(mKnownDrawSizeChanged)//known draw size is set
-		{			
-			mDesiredDiscardLevel = (S8)llmin(log((F32)mFullWidth / mKnownDrawWidth) / log_2, 
-												 log((F32)mFullHeight / mKnownDrawHeight) / log_2) ;
-			mDesiredDiscardLevel = 	llclamp(mDesiredDiscardLevel, (S8)0, (S8)getMaxDiscardLevel()) ;
-			mDesiredDiscardLevel = llmin(mDesiredDiscardLevel, mMinDesiredDiscardLevel) ;
-		}
-		mKnownDrawSizeChanged = FALSE ;
-	
-		if(getDiscardLevel() >= 0 && (getDiscardLevel() <= mDesiredDiscardLevel))
-		{
-			mFullyLoaded = TRUE ;
-		}
-	}	
+	}
 
 	if(mForceToSaveRawImage && mDesiredSavedRawDiscardLevel >= 0) //force to refetch the texture.
 	{
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index 275dfaa99605fcc790dfba0eab076218727fb1b5..10126219f8b943f1e2da0c55d780da9e8af89070 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -1531,42 +1531,45 @@ bool LLUIImageList::initFromFile()
 		return false;
 	}
 
-	std::vector<std::string> paths;
-	// path to current selected skin
-	paths.push_back(gDirUtilp->getSkinDir() 
-			+ gDirUtilp->getDirDelimiter() 
-			+ "textures"
-			+ gDirUtilp->getDirDelimiter()
-			+ "textures.xml");
-	// path to user overrides on current skin
-	paths.push_back(gDirUtilp->getUserSkinDir() 
-			+ gDirUtilp->getDirDelimiter() 
-			+ "textures"
-			+ gDirUtilp->getDirDelimiter()
-			+ "textures.xml");
-
-	// apply skinned xml files incrementally
-	for(std::vector<std::string>::iterator path_it = paths.begin();
-		path_it != paths.end();
-		++path_it)
-	{
-		// don't reapply base file to itself
-		if (!path_it->empty() && (*path_it) != base_file_path)
-		{
-			LLXMLNodePtr update_root;
-			if (LLXMLNode::parseFile(*path_it, update_root, NULL))
-			{
-				LLXMLNode::updateNode(root, update_root);
-			}
-		}
-	}
-
 	UIImageDeclarations images;
 	LLXUIParser parser;
 	parser.readXUI(root, images, base_file_path);
 
+	// add components defined in current skin
+	std::string skin_update_path = gDirUtilp->getSkinDir() 
+									+ gDirUtilp->getDirDelimiter() 
+									+ "textures"
+									+ gDirUtilp->getDirDelimiter()
+									+ "textures.xml";
+	LLXMLNodePtr update_root;
+	if (skin_update_path != base_file_path
+		&& LLXMLNode::parseFile(skin_update_path, update_root, NULL))
+	{
+		parser.readXUI(update_root, images, skin_update_path);
+	}
+
+	// add components defined in user override of current skin
+	skin_update_path = gDirUtilp->getUserSkinDir() 
+						+ gDirUtilp->getDirDelimiter() 
+						+ "textures"
+						+ gDirUtilp->getDirDelimiter()
+						+ "textures.xml";
+	if (skin_update_path != base_file_path
+		&& LLXMLNode::parseFile(skin_update_path, update_root, NULL))
+	{
+		parser.readXUI(update_root, images, skin_update_path);
+	}
+
 	if (!images.validateBlock()) return false;
 
+	std::map<std::string, UIImageDeclaration> merged_declarations;
+	for (LLInitParam::ParamIterator<UIImageDeclaration>::const_iterator image_it = images.textures.begin();
+		image_it != images.textures.end();
+		++image_it)
+	{
+		merged_declarations[image_it->name].overwriteFrom(*image_it);
+	}
+
 	enum e_decode_pass
 	{
 		PASS_DECODE_NOW,
@@ -1576,19 +1579,20 @@ bool LLUIImageList::initFromFile()
 
 	for (S32 cur_pass = PASS_DECODE_NOW; cur_pass < NUM_PASSES; cur_pass++)
 	{
-		for (LLInitParam::ParamIterator<UIImageDeclaration>::const_iterator image_it = images.textures.begin();
-			image_it != images.textures.end();
+		for (std::map<std::string, UIImageDeclaration>::const_iterator image_it = merged_declarations.begin();
+			image_it != merged_declarations.end();
 			++image_it)
 		{
-			std::string file_name = image_it->file_name.isProvided() ? image_it->file_name() : image_it->name();
+			const UIImageDeclaration& image = image_it->second;
+			std::string file_name = image.file_name.isProvided() ? image.file_name() : image.name();
 
 			// load high priority textures on first pass (to kick off decode)
-			enum e_decode_pass decode_pass = image_it->preload ? PASS_DECODE_NOW : PASS_DECODE_LATER;
+			enum e_decode_pass decode_pass = image.preload ? PASS_DECODE_NOW : PASS_DECODE_LATER;
 			if (decode_pass != cur_pass)
 			{
 				continue;
 			}
-			preloadUIImage(image_it->name, file_name, image_it->use_mips, image_it->scale);
+			preloadUIImage(image.name, file_name, image.use_mips, image.scale);
 		}
 
 		if (cur_pass == PASS_DECODE_NOW && !gSavedSettings.getBOOL("NoPreload"))
diff --git a/indra/newview/llviewerthrottle.cpp b/indra/newview/llviewerthrottle.cpp
index b614ccdbc2762142e644e227e8a1ad2652fc5347..5147272122e6c0d5d4f1b1809302c7675e0916bd 100644
--- a/indra/newview/llviewerthrottle.cpp
+++ b/indra/newview/llviewerthrottle.cpp
@@ -46,7 +46,7 @@ const F32 MAX_FRACTIONAL = 1.5f;
 const F32 MIN_FRACTIONAL = 0.2f;
 
 const F32 MIN_BANDWIDTH = 50.f;
-const F32 MAX_BANDWIDTH = 1500.f;
+const F32 MAX_BANDWIDTH = 3000.f;
 const F32 STEP_FRACTIONAL = 0.1f;
 const F32 TIGHTEN_THROTTLE_THRESHOLD = 3.0f; // packet loss % per s
 const F32 EASE_THROTTLE_THRESHOLD = 0.5f; // packet loss % per s
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 743def4a0ce7d7d5ac12867eb8e9c1288f0f97d1..c812fcf2daf512d6f8155da23d972ec5b87556d8 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1367,6 +1367,15 @@ LLViewerWindow::LLViewerWindow(
 		LL_WARNS("Window") << " Someone took over my signal/exception handler (post createWindow)!" << LL_ENDL;
 	}
 
+	LLCoordScreen scr;
+    mWindow->getSize(&scr);
+
+    if(fullscreen && ( scr.mX!=width || scr.mY!=height))
+    {
+		llwarns << "Fullscreen has forced us in to a different resolution now using "<<scr.mX<<" x "<<scr.mY<<llendl;
+		gSavedSettings.setS32("FullScreenWidth",scr.mX);
+		gSavedSettings.setS32("FullScreenHeight",scr.mY);
+    }
 
 	if (NULL == mWindow)
 	{
@@ -1378,7 +1387,7 @@ LLViewerWindow::LLViewerWindow(
 		LL_WARNS("Window") << "Unable to create window, be sure screen is set at 32-bit color in Control Panels->Display->Settings"
 				<< LL_ENDL;
 #endif
-        LLAppViewer::instance()->forceExit(1);
+        LLAppViewer::instance()->fastQuit(1);
 	}
 	
 	// Get the real window rect the window was created with (since there are various OS-dependent reasons why
@@ -1545,8 +1554,9 @@ void LLViewerWindow::initBase()
 	mWorldViewPlaceholder = main_view->getChildView("world_view_rect")->getHandle();
 	mNonSideTrayView = main_view->getChildView("non_side_tray_view")->getHandle();
 	mFloaterViewHolder = main_view->getChildView("floater_view_holder")->getHandle();
-	mPopupView = main_view->findChild<LLPopupView>("popup_holder");
+	mPopupView = main_view->getChild<LLPopupView>("popup_holder");
 	mHintHolder = main_view->getChild<LLView>("hint_holder")->getHandle();
+	mLoginPanelHolder = main_view->getChild<LLView>("login_panel_holder")->getHandle();
 
 	// Constrain floaters to inside the menu and status bar regions.
 	gFloaterView = main_view->getChild<LLFloaterView>("Floater View");
@@ -1680,7 +1690,7 @@ void LLViewerWindow::initWorldUI()
 	{
 		LLRect hud_rect = full_window;
 		hud_rect.mBottom += 50;
-		if (gMenuBarView)
+		if (gMenuBarView && gMenuBarView->isInVisibleChain())
 		{
 			hud_rect.mTop -= gMenuBarView->getRect().getHeight();
 		}
@@ -1709,6 +1719,20 @@ void LLViewerWindow::initWorldUI()
 	buttons_panel->setShape(buttons_panel_container->getLocalRect());
 	buttons_panel->setFollowsAll();
 	buttons_panel_container->addChild(buttons_panel);
+
+	LLView* avatar_picker_destination_guide_container = gViewerWindow->getRootView()->getChild<LLView>("avatar_picker_and_destination_guide_container");
+	LLMediaCtrl* destinations = avatar_picker_destination_guide_container->findChild<LLMediaCtrl>("destination_guide_contents");
+	LLMediaCtrl* avatar_picker = avatar_picker_destination_guide_container->findChild<LLMediaCtrl>("avatar_picker_contents");
+	if (destinations)
+	{
+		destinations->navigateTo(gSavedSettings.getString("DestinationGuideURL"), "text/html");
+	}
+
+	if (avatar_picker)
+	{
+		avatar_picker->navigateTo(gSavedSettings.getString("AvatarPickerURL"), "text/html");
+	}
+
 }
 
 // Destroy the UI
@@ -2266,6 +2290,20 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 		return TRUE;
 	}
 
+	// If "Pressing letter keys starts local chat" option is selected, we are not in mouselook, 
+	// no view has keyboard focus, this is a printable character key (and no modifier key is 
+	// pressed except shift), then give focus to nearby chat (STORM-560)
+	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && 
+		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
+	{
+		LLLineEditor* chat_editor = LLBottomTray::instanceExists() ? LLBottomTray::getInstance()->getNearbyChatBar()->getChatBox() : NULL;
+		if (chat_editor)
+		{
+			// passing NULL here, character will be added later when it is handled by character handler.
+			LLBottomTray::getInstance()->getNearbyChatBar()->startChat(NULL);
+			return TRUE;
+		}
+	}
 
 	// give menus a chance to handle unmodified accelerator keys
 	if ((gMenuBarView && gMenuBarView->handleAcceleratorKey(key, mask))
@@ -2466,6 +2504,10 @@ void LLViewerWindow::updateUI()
 		{
 			LLFirstUse::notUsingDestinationGuide();
 		}
+		if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("AvatarPickerHintTimeout"))
+		{
+			LLFirstUse::notUsingAvatarPicker();
+		}
 		if (gLoggedInTime.getElapsedTimeF32() > gSavedSettings.getF32("SidePanelHintTimeout"))
 		{
 			LLFirstUse::notUsingSidePanel();
@@ -2961,18 +3003,20 @@ void LLViewerWindow::updateKeyboardFocus()
 
 			LLUICtrl* parent = cur_focus->getParentUICtrl();
 			const LLUICtrl* focus_root = cur_focus->findRootMostFocusRoot();
+			bool new_focus_found = false;
 			while(parent)
 			{
-				if (parent->isCtrl() && 
-					(parent->hasTabStop() || parent == focus_root) && 
-					!parent->getIsChrome() && 
-					parent->isInVisibleChain() && 
-					parent->isInEnabledChain())
+				if (parent->isCtrl() 
+					&& (parent->hasTabStop() || parent == focus_root) 
+					&& !parent->getIsChrome() 
+					&& parent->isInVisibleChain() 
+					&& parent->isInEnabledChain())
 				{
 					if (!parent->focusFirstItem())
 					{
 						parent->setFocus(TRUE);
 					}
+					new_focus_found = true;
 					break;
 				}
 				parent = parent->getParentUICtrl();
@@ -2981,7 +3025,7 @@ void LLViewerWindow::updateKeyboardFocus()
 			// if we didn't find a better place to put focus, just release it
 			// hasFocus() will return true if and only if we didn't touch focus since we
 			// are only moving focus higher in the hierarchy
-			if (cur_focus->hasFocus())
+			if (!new_focus_found)
 			{
 				cur_focus->setFocus(FALSE);
 			}
@@ -4267,17 +4311,8 @@ void LLViewerWindow::setup3DRender()
 
 void LLViewerWindow::setup3DViewport(S32 x_offset, S32 y_offset)
 {
-	if (LLRenderTarget::getCurrentBoundTarget() != NULL)
-	{
-		// don't use translation component of mWorldViewRectRaw, as we are already in a properly sized render target
-		gGLViewport[0] = x_offset;
-		gGLViewport[1] = y_offset;
-	}
-	else
-	{
-		gGLViewport[0] = mWorldViewRectRaw.mLeft + x_offset;
-		gGLViewport[1] = mWorldViewRectRaw.mBottom + y_offset;
-	}
+	gGLViewport[0] = mWorldViewRectRaw.mLeft + x_offset;
+	gGLViewport[1] = mWorldViewRectRaw.mBottom + y_offset;
 	gGLViewport[2] = mWorldViewRectRaw.getWidth();
 	gGLViewport[3] = mWorldViewRectRaw.getHeight();
 	glViewport(gGLViewport[0], gGLViewport[1], gGLViewport[2], gGLViewport[3]);
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 47fb7c4883aa04b582bd70e39515be0367a514a3..5eeb02b080409719e36de2205151a313fc430e13 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -186,11 +186,6 @@ class LLViewerWindow : public LLWindowCallbacks
 	/*virtual*/ std::string translateString(const char* tag,
 					const std::map<std::string, std::string>& args);
 	
-	// signal on bottom tray width changed
-	typedef boost::function<void (void)> bottom_tray_callback_t;
-	typedef boost::signals2::signal<void (void)> bottom_tray_signal_t;
-	bottom_tray_signal_t mOnBottomTrayWidthChanged;
-	boost::signals2::connection setOnBottomTrayWidthChanged(bottom_tray_callback_t cb) { return mOnBottomTrayWidthChanged.connect(cb); }
 	// signal on update of WorldView rect
 	typedef boost::function<void (LLRect old_world_rect, LLRect new_world_rect)> world_rect_callback_t;
 	typedef boost::signals2::signal<void (LLRect old_world_rect, LLRect new_world_rect)> world_rect_signal_t;
@@ -288,6 +283,7 @@ class LLViewerWindow : public LLWindowCallbacks
 	LLView*			getNonSideTrayView() { return mNonSideTrayView.get(); }
 	LLView*			getFloaterViewHolder() { return mFloaterViewHolder.get(); }
 	LLView*			getHintHolder() { return mHintHolder.get(); }
+	LLView*			getLoginPanelHolder() { return mLoginPanelHolder.get(); }
 	BOOL			handleKey(KEY key, MASK mask);
 	void			handleScrollWheel	(S32 clicks);
 
@@ -447,6 +443,7 @@ class LLViewerWindow : public LLWindowCallbacks
 	LLHandle<LLView> mNonSideTrayView;		// parent of world view + bottom bar, etc...everything but the side tray
 	LLHandle<LLView> mFloaterViewHolder;	// container for floater_view
 	LLHandle<LLView> mHintHolder;			// container for hints
+	LLHandle<LLView> mLoginPanelHolder;		// container for login panel
 	LLPopupView*	mPopupView;			// container for transient popups
 	
 	class LLDebugText* mDebugText; // Internal class for debug text
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 6f3aba29c6d148a43cf4d3b0f69dfdbefd7d14ff..bb4c5b180416adbbeb2429aa66fc6efcb6eeb87a 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -2333,8 +2333,19 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 
 void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 {
-	// disable voice visualizer when in mouselook
-	mVoiceVisualizer->setVoiceEnabled( voice_enabled && !(isSelf() && gAgentCamera.cameraMouselook()) );
+	bool render_visualizer = voice_enabled;
+	
+	// Don't render the user's own voice visualizer when in mouselook, or when opening the mic is disabled.
+	if(isSelf())
+	{
+		if(gAgentCamera.cameraMouselook() || gSavedSettings.getBOOL("VoiceDisableMic"))
+		{
+			render_visualizer = false;
+		}
+	}
+	
+	mVoiceVisualizer->setVoiceEnabled(render_visualizer);
+	
 	if ( voice_enabled )
 	{		
 		//----------------------------------------------------------------
@@ -3024,7 +3035,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 				std::deque<LLChat>::iterator chat_iter = mChats.begin();
 				mNameText->clearString();
 
-		LLColor4 new_chat = LLUIColorTable::instance().getColor( "NameTagChat" );
+				LLColor4 new_chat = LLUIColorTable::instance().getColor( isSelf() ? "UserChatColor" : "AgentChatColor" );
 				LLColor4 normal_chat = lerp(new_chat, LLColor4(0.8f, 0.8f, 0.8f, 1.f), 0.7f);
 				LLColor4 old_chat = lerp(normal_chat, LLColor4(0.6f, 0.6f, 0.6f, 1.f), 0.7f);
 				if (mTyping && mChats.size() >= MAX_BUBBLE_CHAT_UTTERANCES) 
@@ -7864,6 +7875,7 @@ BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root)
 //virtual
 void LLVOAvatar::updateRegion(LLViewerRegion *regionp)
 {
+	LLViewerObject::updateRegion(regionp);
 }
 
 std::string LLVOAvatar::getFullname() const
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index e5cbf6568276d91795f003cd7fd8231bdcc17a87..5f9e34390702fb4d874706603d0fcfb29c9161cc 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -783,11 +783,19 @@ void LLVOAvatarSelf::removeMissingBakedTextures()
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
 		const S32 te = mBakedTextureDatas[i].mTextureIndex;
-		LLViewerTexture* tex = getTEImage(te) ;
+		const LLViewerTexture* tex = getTEImage(te);
+
+		// Replace with default if we can't find the asset, assuming the
+		// default is actually valid (which it should be unless something
+		// is seriously wrong).
 		if (!tex || tex->isMissingAsset())
 		{
-			setTEImage(te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR));
-			removed = TRUE;
+			LLViewerTexture *imagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
+			if (imagep)
+			{
+				setTEImage(te, imagep);
+				removed = TRUE;
+			}
 		}
 	}
 
@@ -806,7 +814,23 @@ void LLVOAvatarSelf::removeMissingBakedTextures()
 //virtual
 void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
 {
+	// Save the global position
+	LLVector3d global_pos_from_old_region = getPositionGlobal();
+
+	// Change the region
 	setRegion(regionp);
+
+	if (regionp)
+	{	// Set correct region-relative position from global coordinates
+		setPositionGlobal(global_pos_from_old_region);
+
+		// Diagnostic info
+		//LLVector3d pos_from_new_region = getPositionGlobal();
+		//llinfos << "pos_from_old_region is " << global_pos_from_old_region
+		//	<< " while pos_from_new_region is " << pos_from_new_region
+		//	<< llendl;
+	}
+
 	if (!regionp || (regionp->getHandle() != mLastRegionHandle))
 	{
 		if (mLastRegionHandle != 0)
@@ -820,6 +844,9 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
 			F64 max = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_MAX);
 			max = llmax(delta, max);
 			LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_MAX, max);
+
+			// Diagnostics
+			llinfos << "Region crossing took " << (F32)(delta * 1000.0) << " ms " << llendl;
 		}
 		if (regionp)
 		{
@@ -827,6 +854,7 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
 		}
 	}
 	mRegionCrossingTimer.reset();
+	LLViewerObject::updateRegion(regionp);
 }
 
 //--------------------------------------------------------------------
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 23a799ea3ac8b60633710fd292c265374a0a5848..d13cf5ba38fceb8a9f93bdc3d911ddf2e6b47083 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -123,6 +123,8 @@ class LLVOAvatarSelf :
 	//--------------------------------------------------------------------
 	// Region state
 	//--------------------------------------------------------------------
+	void			resetRegionCrossingTimer()	{ mRegionCrossingTimer.reset();	}
+
 private:
 	U64				mLastRegionHandle;
 	LLFrameTimer	mRegionCrossingTimer;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 6c44f639ec16fca90882fa784dc9f6367dbdfb2c..730f022c501e2dd6bb1eca6f0b9f3ee00911c5c4 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -35,6 +35,7 @@
 #include "llnotificationsutil.h"
 #include "llsdserialize.h"
 #include "llui.h"
+#include "llkeyboard.h"
 
 const F32 LLVoiceClient::OVERDRIVEN_POWER_LEVEL = 0.7f;
 
@@ -113,8 +114,18 @@ LLVoiceClient::LLVoiceClient()
 	mVoiceModule(NULL),
 	m_servicePump(NULL),
 	mVoiceEffectEnabled(LLCachedControl<bool>(gSavedSettings, "VoiceMorphingEnabled")),
-	mVoiceEffectDefault(LLCachedControl<std::string>(gSavedPerAccountSettings, "VoiceEffectDefault"))
+	mVoiceEffectDefault(LLCachedControl<std::string>(gSavedPerAccountSettings, "VoiceEffectDefault")),
+	mPTTDirty(true),
+	mPTT(true),
+	mUsePTT(true),
+	mPTTIsMiddleMouse(false),
+	mPTTKey(0),
+	mPTTIsToggle(false),
+	mUserPTTState(false),
+	mMuteMic(false),
+	mDisableMic(false)
 {
+	updateSettings();
 }
 
 //---------------------------------------------------
@@ -173,6 +184,14 @@ const LLVoiceVersionInfo LLVoiceClient::getVersion()
 
 void LLVoiceClient::updateSettings()
 {
+	setUsePTT(gSavedSettings.getBOOL("PTTCurrentlyEnabled"));
+	std::string keyString = gSavedSettings.getString("PushToTalkButton");
+	setPTTKey(keyString);
+	setPTTIsToggle(gSavedSettings.getBOOL("PushToTalkToggle"));
+	mDisableMic = gSavedSettings.getBOOL("VoiceDisableMic");
+
+	updateMicMuteLogic();
+
 	if (mVoiceModule) mVoiceModule->updateSettings();
 }
 
@@ -481,6 +500,26 @@ void LLVoiceClient::setVoiceEnabled(bool enabled)
 	if (mVoiceModule) mVoiceModule->setVoiceEnabled(enabled);
 }
 
+void LLVoiceClient::updateMicMuteLogic()
+{
+	// If not configured to use PTT, the mic should be open (otherwise the user will be unable to speak).
+	bool new_mic_mute = false;
+	
+	if(mUsePTT)
+	{
+		// If configured to use PTT, track the user state.
+		new_mic_mute = !mUserPTTState;
+	}
+
+	if(mMuteMic || mDisableMic)
+	{
+		// Either of these always overrides any other PTT setting.
+		new_mic_mute = true;
+	}
+	
+	if (mVoiceModule) mVoiceModule->setMuteMic(new_mic_mute);
+}
+
 void LLVoiceClient::setLipSyncEnabled(BOOL enabled)
 {
 	if (mVoiceModule) mVoiceModule->setLipSyncEnabled(enabled);
@@ -500,7 +539,8 @@ BOOL LLVoiceClient::lipSyncEnabled()
 
 void LLVoiceClient::setMuteMic(bool muted)
 {
-	if (mVoiceModule) mVoiceModule->setMuteMic(muted);
+	mMuteMic = muted;
+	updateMicMuteLogic();
 }
 
 
@@ -509,64 +549,116 @@ void LLVoiceClient::setMuteMic(bool muted)
 
 void LLVoiceClient::setUserPTTState(bool ptt)
 {
-	if (mVoiceModule) mVoiceModule->setUserPTTState(ptt);
+	mUserPTTState = ptt;
+	updateMicMuteLogic();
 }
 
 bool LLVoiceClient::getUserPTTState()
 {
-	if (mVoiceModule) 
-	{
-		return mVoiceModule->getUserPTTState();
-	}
-	else
-	{
-		return false;
-	}
+	return mUserPTTState;
 }
 
 void LLVoiceClient::setUsePTT(bool usePTT)
 {
-	if (mVoiceModule) mVoiceModule->setUsePTT(usePTT);
+	if(usePTT && !mUsePTT)
+	{
+		// When the user turns on PTT, reset the current state.
+		mUserPTTState = false;
+	}
+	mUsePTT = usePTT;
+	
+	updateMicMuteLogic();
 }
 
 void LLVoiceClient::setPTTIsToggle(bool PTTIsToggle)
 {
-	if (mVoiceModule) mVoiceModule->setPTTIsToggle(PTTIsToggle);
+	if(!PTTIsToggle && mPTTIsToggle)
+	{
+		// When the user turns off toggle, reset the current state.
+		mUserPTTState = false;
+	}
+	
+	mPTTIsToggle = PTTIsToggle;
+
+	updateMicMuteLogic();
 }
 
 bool LLVoiceClient::getPTTIsToggle()
 {
-	if (mVoiceModule) 
+	return mPTTIsToggle;
+}
+
+void LLVoiceClient::setPTTKey(std::string &key)
+{
+	if(key == "MiddleMouse")
 	{
-		return mVoiceModule->getPTTIsToggle();
+		mPTTIsMiddleMouse = true;
 	}
-	else {
-		return false;
+	else
+	{
+		mPTTIsMiddleMouse = false;
+		if(!LLKeyboard::keyFromString(key, &mPTTKey))
+		{
+			// If the call failed, don't match any key.
+			key = KEY_NONE;
+		}
 	}
-
 }
 
 void LLVoiceClient::inputUserControlState(bool down)
 {
-	if (mVoiceModule) mVoiceModule->inputUserControlState(down);	
+	if(mPTTIsToggle)
+	{
+		if(down) // toggle open-mic state on 'down'                                                        
+		{
+			toggleUserPTTState();
+		}
+	}
+	else // set open-mic state as an absolute                                                                  
+	{
+		setUserPTTState(down);
+	}
 }
 
 void LLVoiceClient::toggleUserPTTState(void)
 {
-	if (mVoiceModule) mVoiceModule->toggleUserPTTState();
+	setUserPTTState(!getUserPTTState());
 }
 
 void LLVoiceClient::keyDown(KEY key, MASK mask)
 {	
-	if (mVoiceModule) mVoiceModule->keyDown(key, mask);
+	if (gKeyboard->getKeyRepeated(key))
+	{
+		// ignore auto-repeat keys                                                                         
+		return;
+	}
+	
+	if(!mPTTIsMiddleMouse)
+	{
+		bool down = (mPTTKey != KEY_NONE)
+		&& gKeyboard->getKeyDown(mPTTKey);
+		inputUserControlState(down);
+	}
+	
 }
 void LLVoiceClient::keyUp(KEY key, MASK mask)
 {
-	if (mVoiceModule) mVoiceModule->keyUp(key, mask);
+	if(!mPTTIsMiddleMouse)
+	{
+		bool down = (mPTTKey != KEY_NONE)
+		&& gKeyboard->getKeyDown(mPTTKey);
+		inputUserControlState(down);
+	}
 }
 void LLVoiceClient::middleMouseState(bool down)
 {
-	if (mVoiceModule) mVoiceModule->middleMouseState(down);
+	if(mPTTIsMiddleMouse)
+	{
+        if(mPTTIsMiddleMouse)
+        {
+			inputUserControlState(down);
+        }		
+	}
 }
 
 
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index 24d7d7163ede71a79208f7f2b3498bc910b9c538..c9aeea35a95c1ea234bfeb7dc47af424013b88d4 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -191,25 +191,9 @@ class LLVoiceModuleInterface
 	virtual void setVoiceEnabled(bool enabled)=0;
 	virtual void setLipSyncEnabled(BOOL enabled)=0;
 	virtual BOOL lipSyncEnabled()=0;	
-	virtual void setMuteMic(bool muted)=0;		// Use this to mute the local mic (for when the client is minimized, etc), ignoring user PTT state.
+	virtual void setMuteMic(bool muted)=0;		// Set the mute state of the local mic.
 	//@}
-	
-	////////////////////////
-	/// @name PTT
-	//@{
-	virtual void setUserPTTState(bool ptt)=0;
-	virtual bool getUserPTTState()=0;
-	virtual void setUsePTT(bool usePTT)=0;
-	virtual void setPTTIsToggle(bool PTTIsToggle)=0;
-	virtual bool getPTTIsToggle()=0;	
-	virtual void toggleUserPTTState(void)=0;
-	virtual void inputUserControlState(bool down)=0;  // interpret any sort of up-down mic-open control input according to ptt-toggle prefs
-	
-	virtual void keyDown(KEY key, MASK mask)=0;
-	virtual void keyUp(KEY key, MASK mask)=0;
-	virtual void middleMouseState(bool down)=0;
-	//@}
-	
+		
 	//////////////////////////
 	/// @name nearby speaker accessors
 	//@{
@@ -406,6 +390,9 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
 	void setUsePTT(bool usePTT);
 	void setPTTIsToggle(bool PTTIsToggle);
 	bool getPTTIsToggle();	
+	void setPTTKey(std::string &key);
+	
+	void updateMicMuteLogic();
 	
 	BOOL lipSyncEnabled();
 	
@@ -471,6 +458,17 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
 
 	LLCachedControl<bool> mVoiceEffectEnabled;
 	LLCachedControl<std::string> mVoiceEffectDefault;
+
+	bool		mPTTDirty;
+	bool		mPTT;
+	
+	bool		mUsePTT;
+	bool		mPTTIsMiddleMouse;
+	KEY			mPTTKey;
+	bool		mPTTIsToggle;
+	bool		mUserPTTState;
+	bool		mMuteMic;
+	bool		mDisableMic;
 };
 
 /**
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 019629084fb650b71a4bc6073eeb78d8cdd82407..08e242af8eb78a4eb45223041da8c43302f1a691 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -46,7 +46,6 @@
 #include "llviewernetwork.h"		// for gGridChoice
 #include "llbase64.h"
 #include "llviewercontrol.h"
-#include "llkeyboard.h"
 #include "llappviewer.h"	// for gDisconnected, gDisableVoice
 
 // Viewer includes
@@ -326,14 +325,8 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
 	mRenderDeviceDirty(false),
 	mSpatialCoordsDirty(false),
 
-	mPTTDirty(true),
-	mPTT(true),
-	mUsePTT(true),
-	mPTTIsMiddleMouse(false),
-	mPTTKey(0),
-	mPTTIsToggle(false),
-	mUserPTTState(false),
 	mMuteMic(false),
+	mMuteMicDirty(false),
 	mFriendsListDirty(true),
 
 	mEarLocation(0),
@@ -435,10 +428,6 @@ const LLVoiceVersionInfo& LLVivoxVoiceClient::getVersion()
 void LLVivoxVoiceClient::updateSettings()
 {
 	setVoiceEnabled(gSavedSettings.getBOOL("EnableVoiceChat"));
-	setUsePTT(gSavedSettings.getBOOL("PTTCurrentlyEnabled"));
-	std::string keyString = gSavedSettings.getString("PushToTalkButton");
-	setPTTKey(keyString);
-	setPTTIsToggle(gSavedSettings.getBOOL("PushToTalkToggle"));
 	setEarLocation(gSavedSettings.getS32("VoiceEarLocation"));
 
 	std::string inputDevice = gSavedSettings.getString("VoiceInputAudioDevice");
@@ -950,7 +939,7 @@ void LLVivoxVoiceClient::stateMachine()
 				setState(stateDaemonLaunched);
 				
 				// Dirty the states we'll need to sync with the daemon when it comes up.
-				mPTTDirty = true;
+				mMuteMicDirty = true;
 				mMicVolumeDirty = true;
 				mSpeakerVolumeDirty = true;
 				mSpeakerMuteDirty = true;
@@ -1535,7 +1524,7 @@ void LLVivoxVoiceClient::stateMachine()
 			if(mAudioSession && mAudioSession->mVoiceEnabled)
 			{
 				// Dirty state that may need to be sync'ed with the daemon.
-				mPTTDirty = true;
+				mMuteMicDirty = true;
 				mSpeakerVolumeDirty = true;
 				mSpatialCoordsDirty = true;
 				
@@ -1576,35 +1565,6 @@ void LLVivoxVoiceClient::stateMachine()
 			}
 			else
 			{
-				
-				// Figure out whether the PTT state needs to change
-				{
-					bool newPTT;
-					if(mUsePTT)
-					{
-						// If configured to use PTT, track the user state.
-						newPTT = mUserPTTState;
-					}
-					else
-					{
-						// If not configured to use PTT, it should always be true (otherwise the user will be unable to speak).
-						newPTT = true;
-					}
-					
-					if(mMuteMic)
-					{
-						// This always overrides any other PTT setting.
-						newPTT = false;
-					}
-					
-					// Dirty if state changed.
-					if(newPTT != mPTT)
-					{
-						mPTT = newPTT;
-						mPTTDirty = true;
-					}
-				}
-				
 				if(!inSpatialChannel())
 				{
 					// When in a non-spatial channel, never send positional updates.
@@ -1626,7 +1586,7 @@ void LLVivoxVoiceClient::stateMachine()
 				// Send an update only if the ptt or mute state has changed (which shouldn't be able to happen that often
 				// -- the user can only click so fast) or every 10hz, whichever is sooner.
 				// Sending for every volume update causes an excessive flood of messages whenever a volume slider is dragged.
-				if((mAudioSession && mAudioSession->mMuteDirty) || mPTTDirty || mUpdateTimer.hasExpired())
+				if((mAudioSession && mAudioSession->mMuteDirty) || mMuteMicDirty || mUpdateTimer.hasExpired())
 				{
 					mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS);
 					sendPositionalUpdate();
@@ -2749,19 +2709,17 @@ void LLVivoxVoiceClient::buildLocalAudioUpdates(std::ostringstream &stream)
 
 	buildSetRenderDevice(stream);
 
-	if(mPTTDirty)
+	if(mMuteMicDirty)
 	{
-		mPTTDirty = false;
+		mMuteMicDirty = false;
 
 		// Send a local mute command.
-		// NOTE that the state of "PTT" is the inverse of "local mute".
-		//   (i.e. when PTT is true, we send a mute command with "false", and vice versa)
 		
-		LL_DEBUGS("Voice") << "Sending MuteLocalMic command with parameter " << (mPTT?"false":"true") << LL_ENDL;
+		LL_DEBUGS("Voice") << "Sending MuteLocalMic command with parameter " << (mMuteMic?"true":"false") << LL_ENDL;
 
 		stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.MuteLocalMic.1\">"
 			<< "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>"
-			<< "<Value>" << (mPTT?"false":"true") << "</Value>"
+			<< "<Value>" << (mMuteMic?"true":"false") << "</Value>"
 			<< "</Request>\n\n\n";
 		
 	}
@@ -5238,40 +5196,13 @@ void LLVivoxVoiceClient::leaveChannel(void)
 
 void LLVivoxVoiceClient::setMuteMic(bool muted)
 {
-	mMuteMic = muted;
-}
-
-void LLVivoxVoiceClient::setUserPTTState(bool ptt)
-{
-	mUserPTTState = ptt;
-}
-
-bool LLVivoxVoiceClient::getUserPTTState()
-{
-	return mUserPTTState;
-}
-
-void LLVivoxVoiceClient::inputUserControlState(bool down)
-{
-	if(mPTTIsToggle)
+	if(mMuteMic != muted)
 	{
-		if(down) // toggle open-mic state on 'down'                                                        
-		{
-			toggleUserPTTState();
-		}
-	}
-	else // set open-mic state as an absolute                                                                  
-	{
-		setUserPTTState(down);
+		mMuteMic = muted;
+		mMuteMicDirty = true;
 	}
 }
 
-
-void LLVivoxVoiceClient::toggleUserPTTState(void)
-{
-	mUserPTTState = !mUserPTTState;
-}
-
 void LLVivoxVoiceClient::setVoiceEnabled(bool enabled)
 {
 	if (enabled != mVoiceEnabled)
@@ -5320,48 +5251,6 @@ BOOL LLVivoxVoiceClient::lipSyncEnabled()
 	}
 }
 
-void LLVivoxVoiceClient::setUsePTT(bool usePTT)
-{
-	if(usePTT && !mUsePTT)
-	{
-		// When the user turns on PTT, reset the current state.
-		mUserPTTState = false;
-	}
-	mUsePTT = usePTT;
-}
-
-void LLVivoxVoiceClient::setPTTIsToggle(bool PTTIsToggle)
-{
-	if(!PTTIsToggle && mPTTIsToggle)
-	{
-		// When the user turns off toggle, reset the current state.
-		mUserPTTState = false;
-	}
-	
-	mPTTIsToggle = PTTIsToggle;
-}
-
-bool LLVivoxVoiceClient::getPTTIsToggle()
-{
-	return mPTTIsToggle;
-}
-
-void LLVivoxVoiceClient::setPTTKey(std::string &key)
-{
-	if(key == "MiddleMouse")
-	{
-		mPTTIsMiddleMouse = true;
-	}
-	else
-	{
-		mPTTIsMiddleMouse = false;
-		if(!LLKeyboard::keyFromString(key, &mPTTKey))
-		{
-			// If the call failed, don't match any key.
-			key = KEY_NONE;
-		}
-	}
-}
 
 void LLVivoxVoiceClient::setEarLocation(S32 loc)
 {
@@ -5402,44 +5291,6 @@ void LLVivoxVoiceClient::setMicGain(F32 volume)
 	}
 }
 
-void LLVivoxVoiceClient::keyDown(KEY key, MASK mask)
-{	
-	if (gKeyboard->getKeyRepeated(key))
-	{
-		// ignore auto-repeat keys                                                                         
-		return;
-	}
-	
-	if(!mPTTIsMiddleMouse)
-	{
-		bool down = (mPTTKey != KEY_NONE)
-		&& gKeyboard->getKeyDown(mPTTKey);
-		inputUserControlState(down);
-	}
-	
-	
-}
-void LLVivoxVoiceClient::keyUp(KEY key, MASK mask)
-{
-	if(!mPTTIsMiddleMouse)
-	{
-		bool down = (mPTTKey != KEY_NONE)
-		&& gKeyboard->getKeyDown(mPTTKey);
-		inputUserControlState(down);
-	}
-	
-}
-void LLVivoxVoiceClient::middleMouseState(bool down)
-{
-	if(mPTTIsMiddleMouse)
-	{
-        if(mPTTIsMiddleMouse)
-        {
-			inputUserControlState(down);
-        }		
-	}
-}
-
 /////////////////////////////
 // Accessors for data related to nearby speakers
 BOOL LLVivoxVoiceClient::getVoiceEnabled(const LLUUID& id)
@@ -7015,8 +6866,8 @@ void LLVivoxVoiceClient::captureBufferRecordStartSendMessage()
 			<< "<Value>false</Value>"
 		<< "</Request>\n\n\n";
 
-		// Dirty the PTT state so that it will get reset when we finishing previewing
-		mPTTDirty = true;
+		// Dirty the mute mic state so that it will get reset when we finishing previewing
+		mMuteMicDirty = true;
 
 		writeString(stream.str());
 	}
@@ -7030,7 +6881,7 @@ void LLVivoxVoiceClient::captureBufferRecordStopSendMessage()
 
 		LL_DEBUGS("Voice") << "Stopping audio capture to buffer." << LL_ENDL;
 
-		// Mute the mic. PTT state was dirtied at recording start, so will be reset when finished previewing.
+		// Mute the mic. Mic mute state was dirtied at recording start, so will be reset when finished previewing.
 		stream << "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Connector.MuteLocalMic.1\">"
 			<< "<ConnectorHandle>" << mConnectorHandle << "</ConnectorHandle>"
 			<< "<Value>true</Value>"
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 3ba517bf3681bfc04cb828a9498e7bdf539c6d71..471545de562cb76a3eac7818dc43b42abc931457 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -173,25 +173,9 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 	virtual void setVoiceEnabled(bool enabled);
 	virtual BOOL lipSyncEnabled();	
 	virtual void setLipSyncEnabled(BOOL enabled);
-	virtual void setMuteMic(bool muted);		// Use this to mute the local mic (for when the client is minimized, etc), ignoring user PTT state.
+	virtual void setMuteMic(bool muted);		// Set the mute state of the local mic.
 	//@}
-	
-	////////////////////////
-	/// @name PTT
-	//@{
-	virtual void setUserPTTState(bool ptt);
-	virtual bool getUserPTTState();
-	virtual void setUsePTT(bool usePTT);
-	virtual void setPTTIsToggle(bool PTTIsToggle);
-	virtual bool getPTTIsToggle();
-	virtual void inputUserControlState(bool down);  // interpret any sort of up-down mic-open control input according to ptt-toggle prefs	
-	virtual void toggleUserPTTState(void);
-	
-	virtual void keyDown(KEY key, MASK mask);
-	virtual void keyUp(KEY key, MASK mask);
-	virtual void middleMouseState(bool down);
-	//@}
-	
+		
 	//////////////////////////
 	/// @name nearby speaker accessors
 	//@{
@@ -534,9 +518,6 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 										// Use this to determine whether to show a "no speech" icon in the menu bar.
 		
 	
-	// PTT
-	void setPTTKey(std::string &key);
-	
 	/////////////////////////////
 	// Recording controls
 	void recordingLoopStart(int seconds = 3600, int deltaFramesPerControlFrame = 200);
@@ -800,15 +781,8 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 	LLVector3	mAvatarVelocity;
 	LLMatrix3	mAvatarRot;
 	
-	bool		mPTTDirty;
-	bool		mPTT;
-	
-	bool		mUsePTT;
-	bool		mPTTIsMiddleMouse;
-	KEY			mPTTKey;
-	bool		mPTTIsToggle;
-	bool		mUserPTTState;
 	bool		mMuteMic;
+	bool		mMuteMicDirty;
 			
 	// Set to true when the friends list is known to have changed.
 	bool		mFriendsListDirty;
diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp
index 9280eb8fa48ded86450bab537fc1700b7d93c049..71f08ec36d7dfcee856a86d1919fa9c5f81cecb5 100644
--- a/indra/newview/llvowater.cpp
+++ b/indra/newview/llvowater.cpp
@@ -60,8 +60,10 @@ const U32 WIDTH			= (N_RES * WAVE_STEP); //128.f //64		// width of wave tile, in
 const F32 WAVE_STEP_INV	= (1. / WAVE_STEP);
 
 
-LLVOWater::LLVOWater(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
-:	LLStaticViewerObject(id, pcode, regionp),
+LLVOWater::LLVOWater(const LLUUID &id, 
+					 const LLPCode pcode, 
+					 LLViewerRegion *regionp) :
+	LLStaticViewerObject(id, pcode, regionp),
 	mRenderType(LLPipeline::RENDER_TYPE_WATER)
 {
 	// Terrain must draw during selection passes so it can block objects behind it.
@@ -153,11 +155,17 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable)
 	LLStrider<U16> indicesp;
 	U16 index_offset;
 
-	S32 size = 16;
 
-	S32 num_quads = size*size;	
-	face->setSize(4*num_quads, 6*num_quads);
+	// A quad is 4 vertices and 6 indices (making 2 triangles)
+	static const unsigned int vertices_per_quad = 4;
+	static const unsigned int indices_per_quad = 6;
 
+	const S32 size = gSavedSettings.getBOOL("RenderTransparentWater") ? 16 : 1;
+
+	const S32 num_quads = size * size;
+	face->setSize(vertices_per_quad * num_quads,
+				  indices_per_quad * num_quads);
+	
 	if (face->mVertexBuffer.isNull())
 	{
 		face->mVertexBuffer = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW_ARB);
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
index 7314894c2eed659accf20e791cbdb5a46d2e1d6f..d239347810648188b9b7dd2917a8030d8d6d99a7 100644
--- a/indra/newview/llwaterparammanager.cpp
+++ b/indra/newview/llwaterparammanager.cpp
@@ -89,7 +89,7 @@ void LLWaterParamManager::loadAllPresets(const std::string& file_name)
 	while(found) 
 	{
 		std::string name;
-		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false);
+		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name);
 		if(found)
 		{
 
@@ -115,7 +115,7 @@ void LLWaterParamManager::loadAllPresets(const std::string& file_name)
 	while(found) 
 	{
 		std::string name;
-		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name, false);
+		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name);
 		if(found)
 		{
 			name=name.erase(name.length()-4);
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index 73a37a6993210a96a3230cad85aded0eb270fd2f..b73017a51a2141cb525a1001e35c4bdfaa29152b 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -35,6 +35,7 @@
 #include "llagent.h"
 #include "llappviewer.h"
 #include "llfloatermediabrowser.h"
+#include "llfloaterwebcontent.h"
 #include "llfloaterreg.h"
 #include "lllogininstance.h"
 #include "llparcel.h"
@@ -95,6 +96,23 @@ void LLWeb::loadURL(const std::string& url, const std::string& target, const std
 	}
 }
 
+// static
+void LLWeb::loadWebURL(const std::string& url, const std::string& target, const std::string& uuid)
+{
+	if(target == "_internal")
+	{
+		// Force load in the internal browser, as if with a blank target.
+		loadWebURLInternal(url, "", uuid);
+	}
+	else if (gSavedSettings.getBOOL("UseExternalBrowser") || (target == "_external"))
+	{
+		loadURLExternal(url);
+	}
+	else
+	{
+		loadWebURLInternal(url, target, uuid);
+	}
+}
 
 // static
 void LLWeb::loadURLInternal(const std::string &url, const std::string& target, const std::string& uuid)
@@ -102,6 +120,13 @@ void LLWeb::loadURLInternal(const std::string &url, const std::string& target, c
 	LLFloaterMediaBrowser::create(url, target, uuid);
 }
 
+// static
+// Explicitly open a Web URL using the Web content floater
+void LLWeb::loadWebURLInternal(const std::string &url, const std::string& target, const std::string& uuid)
+{
+	LLFloaterWebContent::create(url, target, uuid);
+}
+
 
 // static
 void LLWeb::loadURLExternal(const std::string& url, const std::string& uuid)
@@ -116,6 +141,13 @@ void LLWeb::loadURLExternal(const std::string& url, bool async, const std::strin
 	// Act like the proxy window was closed, since we won't be able to track targeted windows in the external browser.
 	LLViewerMedia::proxyWindowClosed(uuid);
 	
+	if(gSavedSettings.getBOOL("DisableExternalBrowser"))
+	{
+		// Don't open an external browser under any circumstances.
+		llwarns << "Blocked attempt to open external browser." << llendl;
+		return;
+	}
+	
 	LLSD payload;
 	payload["url"] = url;
 	LLNotificationsUtil::add( "WebLaunchExternalTarget", LLSD(), payload, boost::bind(on_load_url_external_response, _1, _2, async));
diff --git a/indra/newview/llweb.h b/indra/newview/llweb.h
index 291537658329e4c7f4f80fe2a012010764bba407..dc5958e57fb26cfdedc7e7fc38ec5489471ec0e7 100644
--- a/indra/newview/llweb.h
+++ b/indra/newview/llweb.h
@@ -57,6 +57,11 @@ class LLWeb
 	static void loadURLExternal(const std::string& url, const std::string& uuid);
 	static void loadURLExternal(const std::string& url, bool async, const std::string& uuid = LLStringUtil::null);
 
+	// Explicitly open a Web URL using the Web content floater vs. the more general media browser
+	static void loadWebURL(const std::string& url, const std::string& target, const std::string& uuid);
+	static void loadWebURLInternal(const std::string &url, const std::string& target, const std::string& uuid);
+	static void loadWebURLInternal(const std::string &url) { loadWebURLInternal(url, LLStringUtil::null, LLStringUtil::null); }
+
 	/// Returns escaped url (eg, " " to "%20") - used by all loadURL methods
 	static std::string escapeURL(const std::string& url);
 	/// Expands various strings like [LANG], [VERSION], etc. in a URL
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
index 9b6047395ad22da0c81217525638d6aa6838d6d6..e5f52dfc979b5ef4cd09c8366d6b5263d541b9ba 100644
--- a/indra/newview/llwlparammanager.cpp
+++ b/indra/newview/llwlparammanager.cpp
@@ -104,7 +104,7 @@ void LLWLParamManager::loadPresets(const std::string& file_name)
 	while(found) 
 	{
 		std::string name;
-		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name, false);
+		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name);
 		if(found)
 		{
 
@@ -130,7 +130,7 @@ void LLWLParamManager::loadPresets(const std::string& file_name)
 	while(found) 
 	{
 		std::string name;
-		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name, false);
+		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name);
 		if(found)
 		{
 			name=name.erase(name.length()-4);
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 8fabaaba8073b4cbc53bbfb69ba5b2196f6707d6..399442e5c43d966fe0e1c606775c91a0330403b2 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -431,14 +431,15 @@ BOOL LLWorld::positionRegionValidGlobal(const LLVector3d &pos_global)
 
 
 // Allow objects to go up to their radius underground.
-F32 LLWorld::getMinAllowedZ(LLViewerObject* object)
+F32 LLWorld::getMinAllowedZ(LLViewerObject* object, const LLVector3d &global_pos)
 {
-	F32 land_height = resolveLandHeightGlobal(object->getPositionGlobal());
+	F32 land_height = resolveLandHeightGlobal(global_pos);
 	F32 radius = 0.5f * object->getScale().length();
 	return land_height - radius;
 }
 
 
+
 LLViewerRegion* LLWorld::resolveRegionGlobal(LLVector3 &pos_region, const LLVector3d &pos_global)
 {
 	LLViewerRegion *regionp = getRegionFromPosGlobal(pos_global);
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index c60dc8dc292aaa1e2ca621ca72398b02bdc695f8..d8ab4bc5080e4b6833ba1b593307ccf34525eb05 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -89,7 +89,7 @@ class LLWorld : public LLSingleton<LLWorld>
 
 	// Return the lowest allowed Z point to prevent objects from being moved
 	// underground.
-	F32 getMinAllowedZ(LLViewerObject* object);
+	F32 getMinAllowedZ(LLViewerObject* object, const LLVector3d &global_pos);
 
 	// takes a line segment defined by point_a and point_b, then
 	// determines the closest (to point_a) point of intersection that is
diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp
index be8298daab936af4d571a831640154e2f4b6f6cc..74ed844376e2fb58e2382ae82cfa1fddb38d15a8 100644
--- a/indra/newview/llworldmipmap.cpp
+++ b/indra/newview/llworldmipmap.cpp
@@ -181,8 +181,7 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32
 LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32 grid_y, S32 level)
 {
 	// Get the grid coordinates
-	std::string imageurl = gSavedSettings.getString("MapServerURL") + llformat("map-%d-%d-%d-objects.jpg", level, grid_x, grid_y);
-
+	std::string imageurl = gSavedSettings.getString("CurrentMapServerURL") + llformat("map-%d-%d-%d-objects.jpg", level, grid_x, grid_y);
 
 	// DO NOT COMMIT!! DEBUG ONLY!!!
 	// Use a local jpeg for every tile to test map speed without S3 access
diff --git a/indra/newview/res/toolbuy.cur b/indra/newview/res/toolbuy.cur
index a1bc27811692385275b3de381f1ca087d00c4bda..65bbf01d45be371738df991d0861b45a2adb3b53 100644
Binary files a/indra/newview/res/toolbuy.cur and b/indra/newview/res/toolbuy.cur differ
diff --git a/indra/newview/res/toolopen.cur b/indra/newview/res/toolopen.cur
index a72cdfe4c056aa181897e66494daecaedc269dba..22ecbd522898bb167946a86a3beb79f87bc9afc2 100644
Binary files a/indra/newview/res/toolopen.cur and b/indra/newview/res/toolopen.cur differ
diff --git a/indra/newview/res/toolsit.cur b/indra/newview/res/toolsit.cur
index 6327bdb28104e6006ec73977346acc19a61ee84b..d26b6f8638e638cdb987ad9011f9e7e591626cd4 100644
Binary files a/indra/newview/res/toolsit.cur and b/indra/newview/res/toolsit.cur differ
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index ddd2ff196b6cc9bb52a74427a41fd86b784df47d..62441fd9841df8d9ea98aa7b9f7423302d0c9dfd 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -138,9 +138,6 @@
     <color
      name="AvatarListItemIconVoiceLeftColor"
      reference="AvatarListItemIconOfflineColor" />
-    <color
-     name="BackgroundChatColor"
-     reference="DkGray_66" />
     <color
      name="ButtonBorderColor"
      reference="Unused?" />
@@ -399,9 +396,6 @@
     <color
      name="HighlightParentColor"
      value="0.67 0.83 0.96 1" />
-    <color
-     name="IMChatColor"
-     reference="LtGray" />
     <color
      name="IMHistoryBgColor"
      reference="Unused?" />
@@ -766,9 +760,6 @@
     <color
      name="SysWellItemSelected"
      value="0.3 0.3 0.3 1.0" />
-    <color
-     name="ChatToastAgentNameColor"
-     reference="EmphasisColor" />
     <color
     name="ColorSwatchBorderColor"
     value="0.45098 0.517647 0.607843 1"/>
diff --git a/indra/newview/skins/default/textures/arrow_keys.png b/indra/newview/skins/default/textures/arrow_keys.png
new file mode 100644
index 0000000000000000000000000000000000000000..f19af59251c46159a0aa6f5ec983a66df961c703
Binary files /dev/null and b/indra/newview/skins/default/textures/arrow_keys.png differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index b2658d2525c22541277f1213d968e91c00f6671b..89611d8899d35a535d1aed8c3009cad078b9b3d8 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -371,8 +371,8 @@ with the same filename but different name
   <texture name="Play_Off" file_name="icons/Play_Off.png" preload="false" />
   <texture name="Play_Over" file_name="icons/Play_Over.png" preload="false" />
   <texture name="Play_Press" file_name="icons/Play_Press.png" preload="false" />
-
-  <texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="10" scale.right="48" scale.bottom="2" />
+  
+  <texture name="ProgressBar" file_name="widgets/ProgressBar.png" preload="true" scale.left="4" scale.top="11" scale.right="48" scale.bottom="3" />
   <texture name="ProgressTrack" file_name="widgets/ProgressTrack.png" preload="true" scale.left="4" scale.top="13" scale.right="148" scale.bottom="2" />
 
   <texture name="PushButton_Disabled" file_name="widgets/PushButton_Disabled.png" preload="true" scale.left="4" scale.top="19" scale.right="28" scale.bottom="4" />
@@ -392,7 +392,7 @@ with the same filename but different name
   <texture name="RadioButton_On_Disabled" file_name="widgets/RadioButton_On_Disabled.png" preload="true" />
 
 
-  <texture name="Refresh_Off" file_name="icons/Refresh_Off.png" preload="false" />
+  <texture name="Refresh_Off" file_name="icons/Refresh_Off.png" preload="true" />
 
   <texture name="Resize_Corner" file_name="windows/Resize_Corner.png" preload="true" />
 
@@ -468,7 +468,7 @@ with the same filename but different name
   <texture name="Stepper_Up_Off" file_name="widgets/Stepper_Up_Off.png" preload="false" />
   <texture name="Stepper_Up_Press" file_name="widgets/Stepper_Up_Press.png" preload="false" />
 
-  <texture name="Stop_Off" file_name="icons/Stop_Off.png" preload="false" />
+  <texture name="Stop_Off" file_name="icons/Stop_Off.png" preload="true" />
   <texture name="StopReload_Off" file_name="icons/StopReload_Off.png" preload="false" />
   <texture name="StopReload_Over" file_name="icons/StopReload_Over.png" preload="false" />
 
diff --git a/indra/newview/skins/default/textures/widgets/ProgressBar.png b/indra/newview/skins/default/textures/widgets/ProgressBar.png
index edf11ac1f5c4186cd9a61c11f254e051603cb979..3f0e4eba28b58235a523a36942f5cd65fb067bc5 100644
Binary files a/indra/newview/skins/default/textures/widgets/ProgressBar.png and b/indra/newview/skins/default/textures/widgets/ProgressBar.png differ
diff --git a/indra/newview/skins/default/xui/da/floater_avatar_picker.xml b/indra/newview/skins/default/xui/da/floater_avatar_picker.xml
index a337da9b51aed5bdb765f4d5b47b4de3b9eebf81..e97089f61e7237fbf31567b0939c0703744e2981 100644
--- a/indra/newview/skins/default/xui/da/floater_avatar_picker.xml
+++ b/indra/newview/skins/default/xui/da/floater_avatar_picker.xml
@@ -24,6 +24,10 @@
 				Indtast en del af beboerens navn:
 			</text>
 			<button label="Find" label_selected="Find" name="Find"/>
+			<scroll_list name="SearchResults">
+				<columns label="Navn" name="name"/>
+				<columns label="Brugernavn" name="username"/>
+			</scroll_list>
 		</panel>
 		<panel label="Venner" name="FriendsPanel">
 			<text name="InstructSelectFriend">
@@ -39,6 +43,10 @@
 				meter
 			</text>
 			<button label="Gentegn liste" label_selected="Gentegn liste" name="Refresh"/>
+			<scroll_list name="NearMe">
+				<columns label="Navn" name="name"/>
+				<columns label="Brugernavn" name="username"/>
+			</scroll_list>
 		</panel>
 	</tab_container>
 	<button label="OK" label_selected="OK" name="ok_btn"/>
diff --git a/indra/newview/skins/default/xui/da/floater_bumps.xml b/indra/newview/skins/default/xui/da/floater_bumps.xml
index d22de6e7f135ade8784adadcb99a469133e66412..6b265832cd6ae49c66310418d49cfdb4eb445a61 100644
--- a/indra/newview/skins/default/xui/da/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/da/floater_bumps.xml
@@ -4,19 +4,19 @@
 		Ingen registreret
 	</floater.string>
 	<floater.string name="bump">
-		[TIME]  [FIRST] [LAST] ramte dig
+		[TIME]  [NAME] puffede til dig
 	</floater.string>
 	<floater.string name="llpushobject">
-		[TIME]  [FIRST] [LAST] skubbede dig med et script
+		[TIME]  [NAME] skubbede til dig via et script
 	</floater.string>
 	<floater.string name="selected_object_collide">
-		[TIME]  [FIRST] [LAST] ramte dig med et objekt
+		[TIME]  [NAME] ramte dig med et objekt
 	</floater.string>
 	<floater.string name="scripted_object_collide">
-		[TIME]  [FIRST] [LAST] ramte dig med et scriptet objekt
+		[TIME]  [NAME] ramte dig med et scriptet objekt
 	</floater.string>
 	<floater.string name="physical_object_collide">
-		[TIME]  [FIRST] [LAST] ramte dig med et fysisk objekt
+		[TIME]  [NAME] ramte dig med et fysisk objekt
 	</floater.string>
 	<floater.string name="timeStr">
 		[[hour,datetime,slt]:[min,datetime,slt]]
diff --git a/indra/newview/skins/default/xui/da/floater_buy_object.xml b/indra/newview/skins/default/xui/da/floater_buy_object.xml
index f9e18dcf65a0981f9e10420c8a1537cc22e67439..7eb4787139cdc7bd3d6477ecb018be68173341aa 100644
--- a/indra/newview/skins/default/xui/da/floater_buy_object.xml
+++ b/indra/newview/skins/default/xui/da/floater_buy_object.xml
@@ -1,26 +1,29 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <floater name="contents" title="KØB KOPI AF OBJEKT">
+	<floater.string name="title_buy_text">
+		Køb
+	</floater.string>
+	<floater.string name="title_buy_copy_text">
+		Køb en kopi af
+	</floater.string>
+	<floater.string name="no_copy_text">
+		(kopiér ej)
+	</floater.string>
+	<floater.string name="no_modify_text">
+		(ændre ej)
+	</floater.string>
+	<floater.string name="no_transfer_text">
+		(videregiv ej)
+	</floater.string>
 	<text name="contents_text">
 		Indeholder:
 	</text>
 	<text name="buy_text">
-		Køb for L$[AMOUNT] fra [NAME]?
+		Køb for L$[AMOUNT] af:
+	</text>
+	<text name="buy_name_text">
+		[NAME]?
 	</text>
-	<button label="Annullér" label_selected="Annullér" name="cancel_btn"/>
 	<button label="Køb" label_selected="Køb" name="buy_btn"/>
-	<string name="title_buy_text">
-		Køb
-	</string>
-	<string name="title_buy_copy_text">
-		Køb en kopi af
-	</string>
-	<string name="no_copy_text">
-		(kopiér ej)
-	</string>
-	<string name="no_modify_text">
-		(ændre ej)
-	</string>
-	<string name="no_transfer_text">
-		(videregiv ej)
-	</string>
+	<button label="Annullér" label_selected="Annullér" name="cancel_btn"/>
 </floater>
diff --git a/indra/newview/skins/default/xui/da/floater_display_name.xml b/indra/newview/skins/default/xui/da/floater_display_name.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e848006d8b104551d26e8b407e904f6fe3842eb5
--- /dev/null
+++ b/indra/newview/skins/default/xui/da/floater_display_name.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="Display Name" title="ÆNDRE VISNINGSNAVN">
+	<text name="info_text">
+		Det navn du giver din avatar kaldes dit visningsnavn. Du kan ændre dette en gang om ugen.
+	</text>
+	<text name="lockout_text">
+		Du kan ikke ændre dit visningsnavn før: [TIME].
+	</text>
+	<text name="set_name_label">
+		Nyt visningsnavn:
+	</text>
+	<text name="name_confirm_label">
+		Indtast dit nye navn igen for at bekræfte:
+	</text>
+	<button label="Gem" name="save_btn" tool_tip="Gem dit nye visningsnavn"/>
+	<button label="Nulstil" name="reset_btn" tool_tip="Omdøb visningsnavn til samme som brugernavn"/>
+	<button label="Annullér" name="cancel_btn"/>
+</floater>
diff --git a/indra/newview/skins/default/xui/da/floater_event.xml b/indra/newview/skins/default/xui/da/floater_event.xml
index 58f2e555ddeb821d12c3457827f35364a91bc80a..a9eddaaf8d3574a746c627c5e02b595819f3904b 100644
--- a/indra/newview/skins/default/xui/da/floater_event.xml
+++ b/indra/newview/skins/default/xui/da/floater_event.xml
@@ -1,40 +1,11 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- follows="all"
- height="400"
- can_resize="true"
- help_topic="event_details"
- label="Event"
- layout="topleft"
- name="Event"
- save_rect="true"
- save_visibility="false"
- title="EVENT DETAILS" 
- width="600">
-	<floater.string
-		name="loading_text">
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater can_resize="true" follows="all" height="400" help_topic="event_details" label="Event" layout="topleft" name="Event" save_rect="true" save_visibility="false" title="EVENT DETAILS" width="600">
+	<floater.string name="loading_text">
 		Henter...
 	</floater.string>
-    <floater.string
-     name="done_text">
-        Done
-    </floater.string>
-  <web_browser
-     trusted_content="true" 
-     follows="left|right|top|bottom"
-     layout="topleft"
-     left="10"
-     name="browser"
-     height="365"
-     width="580"
-     top="0"/>
-	<text
-	 follows="bottom|left"
-	 height="16"
-	 layout="topleft"
-	 left_delta="0"
-	 name="status_text"
-	 top_pad="10"
-	 width="150" />	 
+	<floater.string name="done_text">
+		Færdig
+	</floater.string>
+	<web_browser follows="left|right|top|bottom" height="365" layout="topleft" left="10" name="browser" top="0" trusted_content="true" width="580"/>
+	<text follows="bottom|left" height="16" layout="topleft" left_delta="0" name="status_text" top_pad="10" width="150"/>
 </floater>
-
diff --git a/indra/newview/skins/default/xui/da/floater_hardware_settings.xml b/indra/newview/skins/default/xui/da/floater_hardware_settings.xml
index 2b10afe7e3385adeef67cb97118bdc1fdb261d0d..a5942eb6256ccf4ba4b5d95bae04dcb673e62743 100644
--- a/indra/newview/skins/default/xui/da/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/da/floater_hardware_settings.xml
@@ -14,6 +14,9 @@
 		<combo_box.item label="8x" name="8x"/>
 		<combo_box.item label="16x" name="16x"/>
 	</combo_box>
+	<text name="antialiasing restart">
+		(kræver genstart af din Second Life klient)
+	</text>
 	<spinner label="Gamma:" name="gamma"/>
 	<text name="(brightness, lower is brighter)">
 		(Lysstyrke, lavere er lysere, 0=benyt standard)
diff --git a/indra/newview/skins/default/xui/da/floater_incoming_call.xml b/indra/newview/skins/default/xui/da/floater_incoming_call.xml
index 7a3c3e466abdfb603c57ddb3a556cfafc1a0d4a2..dd8cb6f97a5276573e5260c36a34c4ad7ccd8fd0 100644
--- a/indra/newview/skins/default/xui/da/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/da/floater_incoming_call.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="incoming call" title="UKENDT PERSON KALDER OP">
+<floater name="incoming call" title="Indgående opkald">
 	<floater.string name="lifetime">
 		5
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/da/floater_pay.xml b/indra/newview/skins/default/xui/da/floater_pay.xml
index b2cdc0bfe78164de6ab59c18f142ea717694268f..96ec1068038134d8c6ffc5e05a110e3bf36bf27e 100644
--- a/indra/newview/skins/default/xui/da/floater_pay.xml
+++ b/indra/newview/skins/default/xui/da/floater_pay.xml
@@ -11,7 +11,7 @@
 	</text>
 	<icon name="icon_person" tool_tip="Person"/>
 	<text name="payee_name">
-		[FIRST] [LAST]
+		Test navn der er meget lang for at checke afkortning
 	</text>
 	<button label="L$1" label_selected="L$1" name="fastpay 1"/>
 	<button label="L$5" label_selected="L$5" name="fastpay 5"/>
diff --git a/indra/newview/skins/default/xui/da/floater_pay_object.xml b/indra/newview/skins/default/xui/da/floater_pay_object.xml
index 368d6786818411ff12861504b702748a29ad51bd..260b257c33311c8073cc83f7ceee189465872fa2 100644
--- a/indra/newview/skins/default/xui/da/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/da/floater_pay_object.xml
@@ -8,7 +8,7 @@
 	</string>
 	<icon name="icon_person" tool_tip="Person"/>
 	<text name="payee_name">
-		[FIRST] [LAST]
+		Ericacita Moostopolison
 	</text>
 	<text name="object_name_label">
 		Via objekt:
diff --git a/indra/newview/skins/default/xui/da/floater_preferences.xml b/indra/newview/skins/default/xui/da/floater_preferences.xml
index a53586eaaf112d9485555ec9fe9fd290b11e75f9..6caac14cf54457647d19c8b6dce87345fa7142a0 100644
--- a/indra/newview/skins/default/xui/da/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/da/floater_preferences.xml
@@ -5,10 +5,12 @@
 	<tab_container name="pref core">
 		<panel label="Generelt" name="general"/>
 		<panel label="Grafik" name="display"/>
-		<panel label="Privatliv" name="im"/>
 		<panel label="Lyd &amp; medier" name="audio"/>
 		<panel label="Chat" name="chat"/>
+		<panel label="Flyt &amp; se" name="move"/>
 		<panel label="Beskeder" name="msgs"/>
+		<panel label="Farver" name="colors"/>
+		<panel label="Privatliv" name="im"/>
 		<panel label="Opsætning" name="input"/>
 		<panel label="Avanceret" name="advanced1"/>
 	</tab_container>
diff --git a/indra/newview/skins/default/xui/da/floater_region_debug_console.xml b/indra/newview/skins/default/xui/da/floater_region_debug_console.xml
new file mode 100644
index 0000000000000000000000000000000000000000..71313f4fea8a0494a3c5998ae6d0a8dafdac0fa8
--- /dev/null
+++ b/indra/newview/skins/default/xui/da/floater_region_debug_console.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="region_debug_console" title="Debug region"/>
diff --git a/indra/newview/skins/default/xui/da/floater_tools.xml b/indra/newview/skins/default/xui/da/floater_tools.xml
index 6fda088b511ce9b05d10194433862cdcbc5a350c..781adcd50b447140ff4b8f881b593ce35374b445 100644
--- a/indra/newview/skins/default/xui/da/floater_tools.xml
+++ b/indra/newview/skins/default/xui/da/floater_tools.xml
@@ -168,13 +168,13 @@
 				Skaber:
 			</text>
 			<text name="Creator Name">
-				Thrax Linden
+				Mrs. Esbee Linden (esbee.linden)
 			</text>
 			<text name="Owner:">
 				Ejer:
 			</text>
 			<text name="Owner Name">
-				Thrax Linden
+				Mrs. Erica &quot;Moose&quot; Linden (erica.linden)
 			</text>
 			<text name="Group:">
 				Gruppe:
diff --git a/indra/newview/skins/default/xui/da/floater_voice_controls.xml b/indra/newview/skins/default/xui/da/floater_voice_controls.xml
index 4c956f13a7c03f88f9be424119069726622ca182..69de696bf56f3531e3a4be9478487902b5be5ed1 100644
--- a/indra/newview/skins/default/xui/da/floater_voice_controls.xml
+++ b/indra/newview/skins/default/xui/da/floater_voice_controls.xml
@@ -19,10 +19,10 @@
 		<layout_panel name="my_panel">
 			<text name="user_text" value="Min avatar:"/>
 		</layout_panel>
-        <layout_panel name="leave_call_panel">
+		<layout_panel name="leave_call_panel">
 			<layout_stack name="voice_effect_and_leave_call_stack">
 				<layout_panel name="leave_call_btn_panel">
-					<button label="Forlad opkald" name="leave_call_btn"/>
+					<button label="Forlad samtale" name="leave_call_btn"/>
 				</layout_panel>
 			</layout_stack>
 		</layout_panel>
diff --git a/indra/newview/skins/default/xui/da/inspect_avatar.xml b/indra/newview/skins/default/xui/da/inspect_avatar.xml
index d4bc0813e5547bcd01285f6d9a138ca603765cd6..f581210e1bf00b614565f4a1750bd150cdbb65ea 100644
--- a/indra/newview/skins/default/xui/da/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/da/inspect_avatar.xml
@@ -10,6 +10,11 @@
 	<string name="Details">
 		[SL_PROFILE]
 	</string>
+	<text name="user_name_small" value="Grumpity ProductEngine med et langt navn"/>
+	<text name="user_slid" value="james.linden"/>
+	<text name="user_details">
+		Dette er min second life beskrivelse og jeg synes den er rigtig god. Men af en eller ande grund er min beskrivelse meget lang fordi jeg taler en hel masse
+	</text>
 	<slider name="volume_slider" tool_tip="Stemme lydstyrke" value="0.5"/>
 	<button label="Tilføj ven" name="add_friend_btn"/>
 	<button label="IM" name="im_btn"/>
diff --git a/indra/newview/skins/default/xui/da/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/da/menu_inventory_gear_default.xml
index 75ce7b22f653e8b6b9c1310bd40240f589b0785d..b359d94f07d2d87e055c7576b4006b5f896b4cb0 100644
--- a/indra/newview/skins/default/xui/da/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/da/menu_inventory_gear_default.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="menu_gear_default">
+<toggleable_menu name="menu_gear_default">
 	<menu_item_call label="Nyt vindue" name="new_window"/>
-	<menu_item_call label="Sortér efter navn" name="sort_by_name"/>
-	<menu_item_call label="Sortér efter nyeste" name="sort_by_recent"/>
+	<menu_item_check label="Sortér efter navn" name="sort_by_name"/>
+	<menu_item_check label="Sortér efter nyeste" name="sort_by_recent"/>
+	<menu_item_check label="Vis System mapper øverst" name="sort_system_folders_to_top"/>
 	<menu_item_call label="Vis filtre" name="show_filters"/>
 	<menu_item_call label="Nulstil filtre" name="reset_filters"/>
 	<menu_item_call label="Luk alle mapper" name="close_folders"/>
@@ -12,4 +13,4 @@
 	<menu_item_call label="Find original" name="Find Original"/>
 	<menu_item_call label="Find alle links" name="Find All Links"/>
 	<menu_item_call label="Tøm papirkurv" name="empty_trash"/>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/da/menu_viewer.xml b/indra/newview/skins/default/xui/da/menu_viewer.xml
index 73986372cec955f2b65c6bafb87862429c95b8dd..a3dcfdf4cce629c87b3e29ae9105cb60bc1908f7 100644
--- a/indra/newview/skins/default/xui/da/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/da/menu_viewer.xml
@@ -10,6 +10,12 @@
 		<menu_item_check label="Min beholdning" name="ShowSidetrayInventory"/>
 		<menu_item_check label="Mine bevægelser" name="Gestures"/>
 		<menu_item_check label="Min stemme" name="ShowVoice"/>
+		<menu label="Bevægelser" name="Movement">
+			<menu_item_call label="Sid ned" name="Sit Down Here"/>
+			<menu_item_check label="Flyv" name="Fly"/>
+			<menu_item_check label="Løb altid" name="Always Run"/>
+			<menu_item_call label="Stop animering" name="Stop Animating My Avatar"/>
+		</menu>
 		<menu label="Min status" name="Status">
 			<menu_item_call label="Væk" name="Set Away"/>
 			<menu_item_call label="Optaget" name="Set Busy"/>
@@ -45,6 +51,7 @@
 			<menu_item_check label="Grundejere" name="Land Owners"/>
 			<menu_item_check label="Koordinater" name="Coordinates"/>
 			<menu_item_check label="Parcel egenskaber" name="Parcel Properties"/>
+			<menu_item_check label="Avanceret menu" name="Show Advanced Menu"/>
 		</menu>
 		<menu_item_call label="Teleport hjem" name="Teleport Home"/>
 		<menu_item_call label="Sæt dette sted som &apos;Hjem&apos;" name="Set Home to Here"/>
@@ -83,6 +90,7 @@
 			<menu_item_call label="Tag kopi" name="Take Copy"/>
 			<menu_item_call label="Opdatér ændringer til beholdning" name="Save Object Back to My Inventory"/>
 			<menu_item_call label="Opdater ændringer i indhold til objekt" name="Save Object Back to Object Contents"/>
+			<menu_item_call label="Returnér objekt" name="Return Object back to Owner"/>
 		</menu>
 		<menu label="Scripts" name="Scripts">
 			<menu_item_call label="Genoversæt scripts (Mono)" name="Mono"/>
@@ -96,6 +104,7 @@
 			<menu_item_check label="Vælg kun egne objekter" name="Select Only My Objects"/>
 			<menu_item_check label="Vis kun flytbare objekter" name="Select Only Movable Objects"/>
 			<menu_item_check label="Vælg ved at omkrandse" name="Select By Surrounding"/>
+			<menu_item_check label="Vis selektions afgrænsning" name="Show Selection Outlines"/>
 			<menu_item_check label="Vis skjulte objekter" name="Show Hidden Selection"/>
 			<menu_item_check label="Vis lys-radius for valgte" name="Show Light Radius for Selection"/>
 			<menu_item_check label="Vis pejlelys for valgte" name="Show Selection Beam"/>
@@ -116,9 +125,9 @@
 		<menu_item_call label="Rapporter misbrug" name="Report Abuse"/>
 		<menu_item_call label="Rapportér fejl" name="Report Bug"/>
 		<menu_item_call label="Om [APP_NAME]" name="About Second Life"/>
+		<menu_item_check label="Aktiver tips" name="Enable Hints"/>
 	</menu>
 	<menu label="Avanceret" name="Advanced">
-		<menu_item_call label="Stop animering af min avatar" name="Stop Animating My Avatar"/>
 		<menu_item_call label="Gendan teksturer" name="Rebake Texture"/>
 		<menu_item_call label="Sæt UI størrelse til standard" name="Set UI Size to Default"/>
 		<menu_item_call label="Vælg vinduesstørrelse..." name="Set Window Size..."/>
@@ -172,8 +181,7 @@
 			<menu_item_check label="Søg" name="Search"/>
 			<menu_item_call label="Frigør taster" name="Release Keys"/>
 			<menu_item_call label="Sæt UI størrelse til standard" name="Set UI Size to Default"/>
-			<menu_item_check label="Løb altid" name="Always Run"/>
-			<menu_item_check label="Flyv" name="Fly"/>
+			<menu_item_check label="Vis avanceret menu (gammel genvej)" name="Show Advanced Menu - legacy shortcut"/>
 			<menu_item_call label="Luk vindue" name="Close Window"/>
 			<menu_item_call label="Luk alle vinduer" name="Close All Windows"/>
 			<menu_item_call label="Foto til disk" name="Snapshot to Disk"/>
@@ -191,7 +199,6 @@
 			<menu_item_call label="Zoom ind" name="Zoom In"/>
 			<menu_item_call label="Zoom standard" name="Zoom Default"/>
 			<menu_item_call label="Zoom ud" name="Zoom Out"/>
-			<menu_item_check label="Vis avanceret menu" name="Show Advanced Menu"/>
 		</menu>
 		<menu_item_call label="Vis debug valg" name="Debug Settings"/>
 		<menu_item_check label="Vis udviklingsmenu" name="Debug Mode"/>
@@ -262,18 +269,16 @@
 			<menu_item_call label="Test web browser" name="Web Browser Test"/>
 			<menu_item_call label="Print info om valgt objekt" name="Print Selected Object Info"/>
 			<menu_item_call label="Hukommelse statistik" name="Memory Stats"/>
-			<menu_item_check label="Dobbeltklik for auto-pilot" name="Double-Click Auto-Pilot"/>
-			<menu_item_check label="Dobeltklik for at teleportere" name="DoubleClick Teleport"/>
+			<menu_item_check label="Debug konsol for region" name="Region Debug Console"/>
 			<menu_item_check label="Debug klik" name="Debug Clicks"/>
 			<menu_item_check label="Debug muse-hændelser" name="Debug Mouse Events"/>
 		</menu>
 		<menu label="XUI" name="XUI">
 			<menu_item_call label="Genindlæs farveopsætning" name="Reload Color Settings"/>
 			<menu_item_call label="Vis font test" name="Show Font Test"/>
-			<menu_item_call label="Hent fra XML" name="Load from XML"/>
-			<menu_item_call label="Gem til XML" name="Save to XML"/>
 			<menu_item_check label="Vis XUI navne" name="Show XUI Names"/>
 			<menu_item_call label="Send testbeskeder (IM)" name="Send Test IMs"/>
+			<menu_item_call label="Skriv navne-cache til disk" name="Flush Names Caches"/>
 		</menu>
 		<menu label="Avatar" name="Character">
 			<menu label="Grab Baked Texture" name="Grab Baked Texture">
@@ -297,9 +302,9 @@
 		</menu>
 		<menu_item_check label="HTTP teksturer" name="HTTP Textures"/>
 		<menu_item_check label="Benyt consol vindue ved næste opstart" name="Console Window"/>
-		<menu_item_check label="Vis administrationsmenu" name="View Admin Options"/>
 		<menu_item_call label="Anmod om administrator status" name="Request Admin Options"/>
 		<menu_item_call label="Forlad administrationsstatus" name="Leave Admin Options"/>
+		<menu_item_check label="Vis administrationsmenu" name="View Admin Options"/>
 	</menu>
 	<menu label="Administrér" name="Admin">
 		<menu label="Object">
diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml
index 917b7cc21e34541f94aef41509b512c96312b8f6..70299c61b4e8506ecc0bc07506a46179d6be2535 100644
--- a/indra/newview/skins/default/xui/da/notifications.xml
+++ b/indra/newview/skins/default/xui/da/notifications.xml
@@ -110,8 +110,8 @@ Vælg kun en genstand, og prøv igen.
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
 	<notification name="GrantModifyRights">
-		At give redigerings rettigheder til en anden beboer, giver dem mulighed for at ændre, slette eller tage ALLE genstande, du måtte have i verden. Vær MEGET forsigtig når uddeler denne tilladelse.
-Ønsker du at ændre rettigheder for [FIRST_NAME] [LAST_NAME]?
+		Tildeling af ændre-rettigheder til andre beboere, tillader dem at ændre, slette eller tage ETHVERT objekt du måtte have. Vær MEGET forsigtig ved tildeling af denne rettighed.
+Ønsker du at give ændre-rettgheder til [NAME]?
 		<usetemplate name="okcancelbuttons" notext="Nej" yestext="Ja"/>
 	</notification>
 	<notification name="GrantModifyRightsMultiple">
@@ -120,7 +120,7 @@ Vælg kun en genstand, og prøv igen.
 		<usetemplate name="okcancelbuttons" notext="Nej" yestext="Ja"/>
 	</notification>
 	<notification name="RevokeModifyRights">
-		Vil du tilbagekalde rettighederne for [FIRST_NAME] [LAST_NAME]?
+		Ønsker du at tilbagekalder ændre-rettigheder for [NAME]?
 		<usetemplate name="okcancelbuttons" notext="Nej" yestext="Ja"/>
 	</notification>
 	<notification name="RevokeModifyRightsMultiple">
@@ -202,14 +202,14 @@ Hvis media kun skal vises på en overflade, vælg &apos;Vælg overflade&apos; og
 Overskrider vedhæftnings begrænsning på [MAX_ATTACHMENTS] objekter. Tag venligst en anden vedhæftning af først.
 	</notification>
 	<notification name="MustHaveAccountToLogIn">
-		Ups! Noget var tomt.
-Du skal skrive både fornavn og efternavn på din figur.
+		Ups. Noget mangler at blive udfyldt.
+Du skal indtaste brugernavnet for din avatar.
 
-Du har brug for en konto for at logge ind i [SECOND_LIFE]. Vil du oprette en nu?
+Du skal bruge en konto for at benytte [SECOND_LIFE]. Ønsker du at oprette en konto nu?
 		<usetemplate name="okcancelbuttons" notext="Prøv igen" yestext="Lav ny konto"/>
 	</notification>
 	<notification name="InvalidCredentialFormat">
-		Du skal indtaste både fornavn og efternavn i din avatars brugernavn felt og derefter logge på igen.
+		Du skal indtaste enten dit brugernavn eller både dit fornavn og efternavn for din avatar i brugernavn feltet, derefter log på igen.
 	</notification>
 	<notification name="AddClassified">
 		Annoncer vil vises i &apos;Annoncer&apos; sektionen i søge biblioteket og på [http://secondlife.com/community/classifieds secondlife.com] i en uge.
@@ -247,6 +247,9 @@ Note: This will clear the cache.
 	<notification name="ChangeSkin">
 		Den nye hud vil blive vist ved næste genstart af [APP_NAME].
 	</notification>
+	<notification name="ChangeLanguage">
+		Ændring af sprog vil først have effekt efter genstart af [APP_NAME].
+	</notification>
 	<notification name="StartRegionEmpty">
 		Ups, din start region er ikke angivet.
 Indtast venligst navn på region i Start lokation feltet eller vælg &quot;Min sidste lokation&quot; eller &quot;Hjem&quot;.
@@ -287,6 +290,10 @@ og du vil miste dem fra din beholdning hvis du forærer dem væk. Er du sikker p
 		[EXTRA]
 
 Gå til [_URL] for information om køb af L$?
+	</notification>
+	<notification name="SoundFileInvalidChunkSize">
+		Fejl i WAV fil (chunk size):
+[FILE]
 	</notification>
 	<notification name="CannotEncodeFile">
 		Kunne ikke &apos;forstå&apos; filen: [FILE]
@@ -390,13 +397,6 @@ Dette er typisk en midlertidig fejl. Venligst rediger og gem igen om et par minu
             [MESSAGE]
 		<usetemplate name="okcancelbuttons" notext="Afslut" yestext="Se PB &amp; Chat"/>
 	</notification>
-	<notification label="Tilføj ven" name="AddFriend">
-		Venner kan give tilladelse til at følge hinanden
-på Verdenskortet eller modtage status opdateringer.
-
-Tilbyd venskab til [NAME]?
-		<usetemplate name="okcancelbuttons" notext="Annullér" yestext="OK"/>
-	</notification>
 	<notification label="Tilføj ven" name="AddFriendWithMessage">
 		Venner kan give tilladelse til at følge hinanden
 på Verdenskortet eller modtage status opdateringer.
@@ -440,12 +440,22 @@ Tilbyd venskab til [NAME]?
 			<button name="Cancel" text="Annullér"/>
 		</form>
 	</notification>
+	<notification name="RemoveFromFriends">
+		Ønsker du at fjerne [NAME] fra din venneliste?
+	</notification>
 	<notification name="ConfirmItemDeleteHasLinks">
 		Mindst en af genstandene har lænkede genstande der peger på den. Hvis du sletter denne genstand, vil lænkninger ikke virke mere.  Det anbefales kraftigt at fjerne lænkninger først.
 
 Er du sikker på at du vil slette disse genstande?
 		<usetemplate name="okcancelbuttons" notext="Annullér" yestext="OK"/>
 	</notification>
+	<notification name="DeedLandToGroupWithContribution">
+		Ved at dedikere denne parcel, vil gruppen skulle have og vedblive med at have nok kreditter til brug af land.
+Dedikeringen vil inkludere samtidige bidrag til gruppen fra &apos;[NAME]&apos;.
+Købsprisen for dette land er ikke refunderet til ejeren. Hvis en dedikeret parvel sælges, vil salgsprisen blive delt ligeligt mellem gruppe medlemmerne.
+
+Dediker disse [AREA] m² land til gruppen &apos;[GROUP_NAME]&apos;?
+	</notification>
 	<notification name="ErrorMessage">
 		<usetemplate name="okbutton" yestext="OK"/>
 	</notification>
@@ -581,6 +591,16 @@ Download til dit Program bibliotek?
 Denne opdatering er ikke påkrævet, men det anbefales at installere den for at opnå øget hastighed og forbedret stabilitet.
 
 Download til dit Program bibliotek?
+	</notification>
+	<notification name="FailedUpdateInstall">
+		Der opstod en fejl ved installation af opdatering.
+Hent og installér venligst den nyeste version fra
+http://secondlife.com/download.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="DownloadBackground">
+		En opdateret version af [APP_NAME] er hentet.
+Den vil blive anvendt næste gang du genstarter [APP_NAME]
 	</notification>
 	<notification name="DeedObjectToGroup">
 		<usetemplate ignoretext="Bekræft før jeg dedikerer et objekt til en gruppe" name="okcancelignore" notext="Cancel" yestext="Deed"/>
@@ -651,6 +671,46 @@ Chat og personlige beskeder vil blive skjult. Personlige beskeder vil få din &a
 	<notification name="UnFreezeUser">
 		Fjern frysning af beboeren med hvilken besked?
 	</notification>
+	<notification name="SetDisplayNameSuccess">
+		Hej [DISPLAY_NAME]!
+
+Præcist som i virkeligheden tager det et stykke tid at vænne sig til et nyt navn. Det kan tage flere dage for [http://wiki.secondlife.com/wiki/Setting_your_display_name your name to update] i objekter, scripts, søgninger m.v.
+	</notification>
+	<notification name="SetDisplayNameBlocked">
+		Beklager, du kan ikke ændre dit visningsnavn. Hvis du mener dette skyldes en fejl, kontakt venligst support.
+	</notification>
+	<notification name="SetDisplayNameFailedLength">
+		Beklager, mavnet er for langt. Visningsnavne kan ikke indholde mere end [LENGTH] karakterer.
+
+Prøv venligst med et kortere navn.
+	</notification>
+	<notification name="SetDisplayNameFailedGeneric">
+		Beklager, vi kunne ikke sætte dit visningsnavn.  Prøv venligst igen senere.
+	</notification>
+	<notification name="SetDisplayNameMismatch">
+		Visningsnavnene du angav matcher ikke. Prøv at taste ind igen.
+	</notification>
+	<notification name="AgentDisplayNameUpdateThresholdExceeded">
+		Beklager, du er nødt til at vente længere, inden du kan ændre visningsnavn.
+
+Se mere under http://wiki.secondlife.com/wiki/Setting_your_display_name
+
+Prøv venligst igen senere.
+	</notification>
+	<notification name="AgentDisplayNameSetBlocked">
+		Beklager, vi kunne ikke sætte dit valgte navn da det indholder et ikke tilladt ord.
+
+ Prøv med et andet navn.
+	</notification>
+	<notification name="AgentDisplayNameSetInvalidUnicode">
+		Visningsnavnet du prøver at angive indeholder ugyldige karakterer.
+	</notification>
+	<notification name="AgentDisplayNameSetOnlyPunctuation">
+		Dit vinsningsnavn skal indeholde andre bogstaver end tegnsætningstegn.
+	</notification>
+	<notification name="DisplayNameUpdate">
+		[OLD_NAME] ([SLID]) er nu kendt som [NEW_NAME].
+	</notification>
 	<notification name="OfferTeleport">
 		<form name="form">
 			<input name="message">
@@ -806,6 +866,7 @@ For at få adgang til voksen regioner, skal beboere være alders-checket, enten
 		<usetemplate ignoretext="Start min browser for at se min konto historik" name="okcancelignore" notext="Cancel" yestext="Go to page"/>
 	</notification>
 	<notification name="ConfirmQuit">
+		Er du sikker på at du vil afslutte?
 		<usetemplate ignoretext="Bekræft før jeg afslutter" name="okcancelignore" notext="Afslut ikke" yestext="Quit"/>
 	</notification>
 	<notification name="DeleteItems">
@@ -931,10 +992,10 @@ Henvis til dette fra en hjemmeside for at give andre nem adgang til denne lokati
 		Erstattet manglende tøj/kropsdele med standard.
 	</notification>
 	<notification name="FriendOnline">
-		[FIRST] [LAST] er Online
+		[NAME] er logget på
 	</notification>
 	<notification name="FriendOffline">
-		[FIRST] [LAST] er Offline
+		[NAME] er logget af
 	</notification>
 	<notification name="AddSelfFriend">
 		Selvom du nok er meget sød, kan du ikke tilføje dig selv som ven.
@@ -1002,9 +1063,6 @@ Prøv venligst igen.
 	<notification name="CannotRemoveProtectedCategories">
 		Du kan ikke fjerne beskyttede kategorier.
 	</notification>
-	<notification name="OfferedCard">
-		Du har tilbudt et visitkort til [FIRST] [LAST]
-	</notification>
 	<notification name="UnableToBuyWhileDownloading">
 		Ikke muligt at købe, imens genstandens data hentes.
 Prøv venligst igen.
@@ -1076,7 +1134,10 @@ Prøv at vælge mindre stykker land.
 	<notification name="SystemMessage">
 		[MESSAGE]
 	</notification>
-	<notification name="PaymentRecived">
+	<notification name="PaymentReceived">
+		[MESSAGE]
+	</notification>
+	<notification name="PaymentSent">
 		[MESSAGE]
 	</notification>
 	<notification name="EventNotification">
@@ -1085,7 +1146,7 @@ Prøv at vælge mindre stykker land.
 [NAME]
 [DATE]
 		<form name="form">
-			<button name="Details" text="Beskrivelse"/>
+			<button name="Details" text="Detaljer"/>
 			<button name="Cancel" text="Annullér"/>
 		</form>
 	</notification>
@@ -1120,7 +1181,7 @@ Prøv venligst at geninstallere plugin eller kontakt leverandøren hvis probleme
 		De genstande du ejer på det valgte stykke land er blevet returneret til din beholdning.
 	</notification>
 	<notification name="OtherObjectsReturned">
-		Genstandene på det valgte stykke land der er ejet af [FIRST] [LAST] er blevet returneret til hans eller hendes beholdning.
+		Objekterne på den valgte parcel, ejet af [NAME], er blevet returneret til vedkommendes beholdning.
 	</notification>
 	<notification name="OtherObjectsReturned2">
 		Objekterne i den valgte parcel, ejet af beboeren &apos;[NAME]&apos;, er blevet returneret til deres ejer.
@@ -1244,7 +1305,7 @@ Prøv igen om lidt.
 		No valid parcel could be found.
 	</notification>
 	<notification name="ObjectGiveItem">
-		Et objekt med navnet [OBJECTFROMNAME] ejet af [NAME_SLURL] har givet dig denne/dette [OBJECTTYPE]:
+		Et object med navnet &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; ejet af [NAME_SLURL] har givet dig denne [OBJECTTYPE]:
 [ITEM_SLURL]
 		<form name="form">
 			<button name="Keep" text="Behold"/>
@@ -1308,6 +1369,11 @@ Prøv igen om lidt.
 	<notification name="FriendshipOffered">
 		Du har tilbudt venskab til [TO_NAME]
 	</notification>
+	<notification name="OfferFriendshipNoMessage">
+		[NAME_SLURL] tilbyder venskab.
+
+(Som udgangspunkt, vil du være i stand til at se den andens online status)
+	</notification>
 	<notification name="FriendshipAccepted">
 		[NAME] accepterede dit tilbud om venskab.
 	</notification>
@@ -1321,8 +1387,8 @@ Prøv igen om lidt.
 		Tilbud om venskab afvist.
 	</notification>
 	<notification name="OfferCallingCard">
-		[FIRST] [LAST] tilbyder dig et visitkort.
-Dette vil lave et bogmørke i din beholding, så du hurtigt kan sende en IM til denne beboer.
+		[NAME] tilbyder sit visitkort.
+Dette vil tilføje et bogmærke i din beholdning, så du hurtigt kan sende en personlig besked til denne beboer.
 		<form name="form">
 			<button name="Accept" text="Acceptér"/>
 			<button name="Decline" text="Afvis"/>
@@ -1337,11 +1403,11 @@ Hvis du ikke forlader regionen, vil du blive logget af.
 Hvis du ikke forlader regionen, vil du blive logget af.
 	</notification>
 	<notification name="LoadWebPage">
-		Indlæs internetside [URL]?
+		Indlæas websiden [URL]?
 
 [MESSAGE]
 
-Fra genstand: [OBJECTNAME], ejer: [NAME]?
+Fra objekt: &lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;, ejer: [NAME]?
 		<form name="form">
 			<button name="Gotopage" text="GÃ¥ til side"/>
 			<button name="Cancel" text="Afbryd"/>
@@ -1357,9 +1423,10 @@ Fra genstand: [OBJECTNAME], ejer: [NAME]?
 		Den genstand du prøver at tage på benytter en funktion din klient ikke kan forstå. Upgradér venligst din version af [APP_NAME] for at kunne tage denne genstand på.
 	</notification>
 	<notification name="ScriptQuestion">
-		&apos;[OBJECTNAME]&apos;, en genstand, ejet af &apos;[NAME]&apos;, vil gerne:
- [QUESTIONS]
-Er det iorden?
+		&apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, et objekt ved ejet af &apos;[NAME]&apos;, ønsker at:
+
+[QUESTIONS]
+Er dette OK?
 		<form name="form">
 			<button name="Yes" text="Ja"/>
 			<button name="No" text="Nej"/>
@@ -1367,12 +1434,12 @@ Er det iorden?
 		</form>
 	</notification>
 	<notification name="ScriptQuestionCaution">
-		Et objekt med navnet &apos;[OBJECTNAME]&apos;, ejet af &apos;[NAME]&apos;, ønsker at:
+		Et objeckt med navn &apos;&lt;nolink&gt;[OBJECTNAME]&lt;/nolink&gt;&apos;, ejet af  &apos;[NAME]&apos; ønsker at:
 
 [QUESTIONS]
-Hvis du ikke stoler på dette objekt og dets skaber, bør du afvise denne forespørgsel.
+Hvis du ikke stoler på dette objekt og dets skaber, bør du afvise dette ønske.
 
-Tillad denne anmodning?
+Opfyld dette ønske?
 		<form name="form">
 			<button name="Grant" text="Imødekom"/>
 			<button name="Deny" text="Afvis"/>
@@ -1380,14 +1447,14 @@ Tillad denne anmodning?
 		</form>
 	</notification>
 	<notification name="ScriptDialog">
-		[FIRST] [LAST]&apos;s &apos;[TITLE]&apos;
+		[NAME]&apos;s &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
 [MESSAGE]
 		<form name="form">
 			<button name="Ignore" text="Ignorér"/>
 		</form>
 	</notification>
 	<notification name="ScriptDialogGroup">
-		[GROUPNAME]&apos;s &apos;[TITLE]&apos;
+		[GROUPNAME]&apos;s &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
 [MESSAGE]
 		<form name="form">
 			<button name="Ignore" text="Ignorér"/>
@@ -1424,13 +1491,13 @@ Klik på Acceptér for at deltage eller Afvis for at afvise invitationen. Klik p
 		</form>
 	</notification>
 	<notification name="AutoUnmuteByIM">
-		[FIRST] [LAST] fik tilsendt en personlig besked og er dermed automatisk ikke mere blokeret.
+		[NAME] har fået sendt en besked og blokering er derfor automatisk blevet fjernet.
 	</notification>
 	<notification name="AutoUnmuteByMoney">
-		[FIRST] [LAST] blev givet penge og er dermed automatisk ikke mere blokeret.
+		[NAME] har fået givet penge og blokering er derfor automatisk blevet fjernet.
 	</notification>
 	<notification name="AutoUnmuteByInventory">
-		[FIRST] [LAST] blev tilbudt en genstand og er dermed automatisk ikke mere blokeret.
+		[NAME] er blevet tilbud noget fra beholdning og blokering er derfor automatisk blevet fjernet.
 	</notification>
 	<notification name="VoiceInviteGroup">
 		[NAME] har has sluttet sig til stemme-chaten i gruppen [GROUP].
@@ -1658,6 +1725,37 @@ vil have lyden slukket - selv efter de har forladt kaldet.
 Sluk for alles lyd?
 		<usetemplate ignoretext="Bekræft før jeg slukker for alle deltageres lyd i gruppe-kald" name="okcancelignore" notext="Annullér" yestext="Ok"/>
 	</notification>
+	<notification label="Chat" name="HintChat">
+		For at deltage i samtalen tast tekst ind i chat feltet nedenfor.
+	</notification>
+	<notification label="Stå op" name="HintSit">
+		For at rejse dig op og forlad siddeposition, tryk på &quot;Stå op&quot; knappen.
+	</notification>
+	<notification label="Undersøg verden" name="HintDestinationGuide">
+		Destinationsguiden indeholder tusinder af nye steder der kan opleves. Vælg venligst et sted og vælg Teleport for at komme derhen.
+	</notification>
+	<notification label="Side panel" name="HintSidePanel">
+		Få hurtig tilgang til din beholdning, sæt, profiler og andet i dette side panel.
+	</notification>
+	<notification label="Flyt" name="HintMove">
+		For at gå eller løbe, åben Flyt panelet for neden og brug pilene til at navigere. Du kan også bruge pile-tasterne på dit tastatur.
+	</notification>
+	<notification label="Visningsnavn" name="HintDisplayName">
+		Angiv dit konfigurérbare visningsnavn her. Dette er i tillæg til dit unikke brugernavn, som ikke kan ændres. Du kan ændre hvordan du ser andre beboeres navne i dine indstillinger.
+	</notification>
+	<notification label="Beholdning" name="HintInventory">
+		Undersøg din beholdning for at finde ting. Nyeste genstand findes lettes under fanen &quot;Nye ting&quot;
+	</notification>
+	<notification label="Der er kommet Linden Dollars" name="HintLindenDollar">
+		Her er din nuværende balance af L$. Klik på Køb L$ for at købe flere Linden dollars.
+	</notification>
+	<notification name="PopupAttempt">
+		En pop-up blev hindret i at blive vist.
+		<form name="form">
+			<ignore name="ignore" text="Tillad alle pop-ups"/>
+			<button name="open" text="Ã…ben pop-up vindue"/>
+		</form>
+	</notification>
 	<global name="UnsupportedGLRequirements">
 		Det ser ikke ud til at din hardware opfylder minimumskravene til [APP_NAME]. [APP_NAME] kræver et OpenGL grafikkort som understøter &apos;multitexture&apos;. Check eventuelt om du har de nyeste drivere for grafikkortet, og de nyeste service-packs og patches til dit operativsystem.
 
diff --git a/indra/newview/skins/default/xui/da/panel_edit_gloves.xml b/indra/newview/skins/default/xui/da/panel_edit_gloves.xml
index 837abdac800d443b1bbef99bbcb03dea2f715fc3..36f58428a67532c84f19c7851e5485dc2a9574e7 100644
--- a/indra/newview/skins/default/xui/da/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_gloves.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_gloves_panel">
 	<panel name="avatar_gloves_color_panel">
-		<texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge bilede"/>
+		<texture_picker label="Tekstur" name="Fabric" tool_tip="Klik for at vælge bilede"/>
 		<color_swatch label="Farve/nuance" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/da/panel_edit_jacket.xml b/indra/newview/skins/default/xui/da/panel_edit_jacket.xml
index 62934e96c88670dba6c2a831bf742f42142e3340..4e7336747dc5a437195076c2f858d85de2cd7eb0 100644
--- a/indra/newview/skins/default/xui/da/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_jacket.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_jacket_panel">
 	<panel name="avatar_jacket_color_panel">
-		<texture_picker label="Stof foroven" name="Upper Fabric" tool_tip="Klik for at vælge et billede"/>
-		<texture_picker label="Stof forneden" name="Lower Fabric" tool_tip="Klik for at vælge et billede"/>
+		<texture_picker label="Øvre tekstur" name="Upper Fabric" tool_tip="Klik for at vælge et billede"/>
+		<texture_picker label="Nedre tekstur" name="Lower Fabric" tool_tip="Klik for at vælge et billede"/>
 		<color_swatch label="Farve/nuance" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/da/panel_edit_pants.xml b/indra/newview/skins/default/xui/da/panel_edit_pants.xml
index 36a9bc60a989c10652b1fbd2ce2d14262730fbda..61056e9e6c65be342cff80ad14c1b0d9904fac69 100644
--- a/indra/newview/skins/default/xui/da/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_pants.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_pants_panel">
 	<panel name="avatar_pants_color_panel">
-		<texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et bilede"/>
+		<texture_picker label="Tekstur" name="Fabric" tool_tip="Klik for at vælge et bilede"/>
 		<color_swatch label="Farve/Nuance" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/da/panel_edit_profile.xml b/indra/newview/skins/default/xui/da/panel_edit_profile.xml
index 27a60004191ee83ad7bece0e4e6ea0f1d4d2de2a..80b20f15e97c92eb9acb78da4f5ec444c607dac1 100644
--- a/indra/newview/skins/default/xui/da/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_profile.xml
@@ -23,6 +23,14 @@
 	<scroll_container name="profile_scroll">
 		<panel name="scroll_content_panel">
 			<panel name="data_panel">
+				<text name="display_name_label" value="Visningsnavn:"/>
+				<text name="solo_username_label" value="Bugernavn:"/>
+				<button name="set_name" tool_tip="Sæt visningsnavn"/>
+				<text name="solo_user_name" value="Hamilton Hitchings"/>
+				<text name="user_name" value="Hamilton Hitchings"/>
+				<text name="user_name_small" value="Hamilton Hitchings"/>
+				<text name="user_label" value="Brugernavn:"/>
+				<text name="user_slid" value="hamilton.linden"/>
 				<panel name="lifes_images_panel">
 					<icon label="" name="2nd_life_edit_icon" tool_tip="Klik for at vælge et billede"/>
 				</panel>
@@ -39,7 +47,7 @@
 				<text name="my_account_link" value="[[URL] Go to My Dashboard]"/>
 				<text name="title_partner_text" value="Min partner:"/>
 				<panel name="partner_data_panel">
-					<name_box initial_value="(henter)" name="partner_text"/>
+					<text initial_value="(henter)" name="partner_text"/>
 				</panel>
 				<text name="partner_edit_link" value="[[URL] Edit]"/>
 			</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_edit_shirt.xml b/indra/newview/skins/default/xui/da/panel_edit_shirt.xml
index e49667dc8f739de82a24f570e7800c55492167af..4dfb47aab2ac1b8b6b3ede6a90b32155791b816a 100644
--- a/indra/newview/skins/default/xui/da/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_shirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_shirt_panel">
 	<panel name="avatar_shirt_color_panel">
-		<texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/>
+		<texture_picker label="Tekstur" name="Fabric" tool_tip="Klik for at vælge et billede"/>
 		<color_swatch label="Farve/Nuance" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/da/panel_edit_shoes.xml b/indra/newview/skins/default/xui/da/panel_edit_shoes.xml
index 00d31da95a517191e165b12ba9c94eb4f97eb8b6..653ea421b58baf79b0c1f84d2430f68cc2e43bc0 100644
--- a/indra/newview/skins/default/xui/da/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_shoes.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_shoes_panel">
 	<panel name="avatar_shoes_color_panel">
-		<texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/>
+		<texture_picker label="Tekstur" name="Fabric" tool_tip="Klik for at vælge et billede"/>
 		<color_swatch label="Farve/nuance" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/da/panel_edit_skirt.xml b/indra/newview/skins/default/xui/da/panel_edit_skirt.xml
index 44a5beca456f42b782902f99bafc51c47ef7333d..e80e60efd81d1dae1ad2c511d040d836d095625a 100644
--- a/indra/newview/skins/default/xui/da/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_skirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_skirt_panel">
 	<panel name="avatar_skirt_color_panel">
-		<texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/>
+		<texture_picker label="Tekstur" name="Fabric" tool_tip="Klik for at vælge et billede"/>
 		<color_swatch label="Farve/Nuance" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/da/panel_edit_socks.xml b/indra/newview/skins/default/xui/da/panel_edit_socks.xml
index b7abd9d1a0625a55a8bd5762fbce29b6391fc3bf..82a7341317ec60f2076375e26b6a0614873b02b7 100644
--- a/indra/newview/skins/default/xui/da/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_socks.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_socks_panel">
 	<panel name="avatar_socks_color_panel">
-		<texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge et billede"/>
+		<texture_picker label="Tekstur" name="Fabric" tool_tip="Klik for at vælge et billede"/>
 		<color_swatch label="Farve/Nuance" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/da/panel_edit_underpants.xml b/indra/newview/skins/default/xui/da/panel_edit_underpants.xml
index 32596be57b5cda2f02d7463d0653dbb0aadf969d..aacfae79e1635cdb128d61e2a2b9a654e0f2722c 100644
--- a/indra/newview/skins/default/xui/da/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_underpants.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_underpants_panel">
 	<panel name="avatar_underpants_color_panel">
-		<texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge bilede"/>
+		<texture_picker label="Tekstur" name="Fabric" tool_tip="Klik for at vælge bilede"/>
 		<color_swatch label="Farve/nuance" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/da/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/da/panel_edit_undershirt.xml
index 14cf79b97f84802333acf9c9fc46d4a7c11a6194..a9db5d2ab0f8742b72775d63f0e5c3fa0d4a70b7 100644
--- a/indra/newview/skins/default/xui/da/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/da/panel_edit_undershirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_undershirt_panel">
 	<panel name="avatar_undershirt_color_panel">
-		<texture_picker label="Stof" name="Fabric" tool_tip="Klik for at vælge bilede"/>
+		<texture_picker label="Tekstur" name="Fabric" tool_tip="Klik for at vælge bilede"/>
 		<color_swatch label="Farve/nuance" name="Color/Tint" tool_tip="Klik for at åbne farvevælger"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/da/panel_group_land_money.xml b/indra/newview/skins/default/xui/da/panel_group_land_money.xml
index efad4d0c34ae6f4ec4ab93b036e7cbe9572eacff..49d415e515653e98363d320c1ac8bb8fbef4af09 100644
--- a/indra/newview/skins/default/xui/da/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/da/panel_group_land_money.xml
@@ -24,6 +24,7 @@
 			<scroll_list.columns label="Region" name="location"/>
 			<scroll_list.columns label="Type" name="type"/>
 			<scroll_list.columns label="Areal" name="area"/>
+			<scroll_list.columns label="Skjult" name="hidden"/>
 		</scroll_list>
 		<text name="total_contributed_land_label">
 			Totalt bidrag:
diff --git a/indra/newview/skins/default/xui/da/panel_login.xml b/indra/newview/skins/default/xui/da/panel_login.xml
index d4bf9a7d78f4cc9c916247e9f2bd3a0cd3cf38ad..268f138185f5f9c83b43d44697c9003aaf333b54 100644
--- a/indra/newview/skins/default/xui/da/panel_login.xml
+++ b/indra/newview/skins/default/xui/da/panel_login.xml
@@ -14,7 +14,7 @@
 			<text name="username_text">
 				Brugernavn:
 			</text>
-			<line_editor label="Brugernavn" name="username_edit" tool_tip="[SECOND_LIFE] Brugernavn"/>
+			<line_editor label="bobsmith12 eller Steller Sunshine" name="username_edit" tool_tip="Det brugernavn du valgte da du registrerede, som f.eks. bobsmith12 eller Steller Sunshine"/>
 			<text name="password_text">
 				Password:
 			</text>
@@ -34,7 +34,7 @@
 				Opret bruger
 			</text>
 			<text name="forgot_password_text">
-				Glemt navn eller password?
+				Har du glemt brugernavn eller password?
 			</text>
 			<text name="login_help">
 				Hjælp til login
diff --git a/indra/newview/skins/default/xui/da/panel_notify_textbox.xml b/indra/newview/skins/default/xui/da/panel_notify_textbox.xml
new file mode 100644
index 0000000000000000000000000000000000000000..949ff1a0585505fee0c2b64f87ce0819fe96bee5
--- /dev/null
+++ b/indra/newview/skins/default/xui/da/panel_notify_textbox.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="instant_message" name="panel_notify_textbox">
+	<string name="message_max_lines_count" value="7"/>
+	<panel label="info_panel" name="info_panel">
+		<text_editor name="message" value="besked"/>
+		parse_urls=&quot;false&quot;
+		<button label="Send" name="btn_submit"/>
+	</panel>
+	<panel label="control_panel" name="control_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_people.xml b/indra/newview/skins/default/xui/da/panel_people.xml
index 6c910cc3b2fa650bb1e4f1bbbc7718ff68915fc6..599686d36007a2e1dc0bdea8d932b8e7c168f0fc 100644
--- a/indra/newview/skins/default/xui/da/panel_people.xml
+++ b/indra/newview/skins/default/xui/da/panel_people.xml
@@ -22,7 +22,7 @@ Leder du efter nogen at være sammen med? Prøv [secondlife:///app/worldmap Worl
 	<tab_container name="tabs">
 		<panel label="TÆT PÅ" name="nearby_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="nearby_view_sort_btn" tool_tip="Valg"/>
+				<menu_button name="nearby_view_sort_btn" tool_tip="Valg"/>
 				<button name="add_friend_btn" tool_tip="Tilføj valgte beboer til din venneliste"/>
 			</panel>
 		</panel>
@@ -34,27 +34,27 @@ Leder du efter nogen at være sammen med? Prøv [secondlife:///app/worldmap Worl
 			<panel label="bottom_panel" name="bottom_panel">
 				<layout_stack name="bottom_panel">
 					<layout_panel name="options_gear_btn_panel">
-						<button name="friends_viewsort_btn" tool_tip="Vis flere valg"/>
+						<menu_button name="friends_viewsort_btn" tool_tip="Vis flere valg"/>
 					</layout_panel>
 					<layout_panel name="add_btn_panel">
 						<button name="add_btn" tool_tip="Tilbyd venskab til en beboer"/>
 					</layout_panel>
 					<layout_panel name="trash_btn_panel">
-						<dnd_button name="trash_btn" tool_tip="Fjern valgte personer fra venneliste"/>
+						<dnd_button name="del_btn" tool_tip="Fjern valgte person fra din venneliste"/>
 					</layout_panel>
 				</layout_stack>
 			</panel>
 		</panel>
 		<panel label="MINE GRUPPER" name="groups_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="groups_viewsort_btn" tool_tip="Valg"/>
+				<menu_button name="groups_viewsort_btn" tool_tip="Valg"/>
 				<button name="plus_btn" tool_tip="Bliv medlem af gruppe/Opret ny gruppe"/>
 				<button name="activate_btn" tool_tip="Activér valgte gruppe"/>
 			</panel>
 		</panel>
 		<panel label="NYLIGE" name="recent_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="recent_viewsort_btn" tool_tip="Valg"/>
+				<menu_button name="recent_viewsort_btn" tool_tip="Valg"/>
 				<button name="add_friend_btn" tool_tip="Tilføj valgte beboer til din venneliste"/>
 			</panel>
 		</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_place_profile.xml b/indra/newview/skins/default/xui/da/panel_place_profile.xml
index 05ef22328f49a213e25bc7cb2669f6aa837fe33a..8dd0fb2d2124b89c13604283a37f456a9066bc0f 100644
--- a/indra/newview/skins/default/xui/da/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/da/panel_place_profile.xml
@@ -76,7 +76,7 @@
 						<text name="region_rating_label" value="Rating:"/>
 						<text name="region_rating" value="Voksent"/>
 						<text name="region_owner_label" value="Ejer:"/>
-						<text name="region_owner" value="moose Van Moose"/>
+						<text name="region_owner" value="moose Van Moose extra long name moose"/>
 						<text name="region_group_label" value="Gruppe:"/>
 						<text name="region_group">
 							The Mighty Moose of mooseville soundvillemoose
@@ -89,6 +89,7 @@
 						<text name="estate_name_label" value="Estate:"/>
 						<text name="estate_rating_label" value="Rating:"/>
 						<text name="estate_owner_label" value="Ejer:"/>
+						<text name="estate_owner" value="Tester brugernavn længde med langt navn"/>
 						<text name="covenant_label" value="Regler:"/>
 					</panel>
 				</accordion_tab>
diff --git a/indra/newview/skins/default/xui/da/panel_places.xml b/indra/newview/skins/default/xui/da/panel_places.xml
index ca3d7c71bbc107fdde0440d653683c595294920a..fe8ca69f344d2f384c2691f3f01a2592448de23f 100644
--- a/indra/newview/skins/default/xui/da/panel_places.xml
+++ b/indra/newview/skins/default/xui/da/panel_places.xml
@@ -21,7 +21,7 @@
 						<button label="Redigér" name="edit_btn" tool_tip="Redigér landemærke information"/>
 					</layout_panel>
 					<layout_panel name="overflow_btn_lp">
-						<button label="â–¼" name="overflow_btn" tool_tip="Vis flere valg"/>
+						<menu_button label="â–¼" name="overflow_btn" tool_tip="Vis flere valg"/>
 					</layout_panel>
 				</layout_stack>
 				<layout_stack name="bottom_bar_ls3">
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml
index b267c75673a2c49aace3c7321234df1ca4e7206c..48106c7dfef2c5d41e0cf9638eb93d5fa3637b34 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_advanced.xml
@@ -3,35 +3,16 @@
 	<panel.string name="aspect_ratio_text">
 		[NUM]:[DEN]
 	</panel.string>
-	<panel.string name="middle_mouse">
-		Midterste mus
-	</panel.string>
-	<slider label="Synsvinkel" name="camera_fov"/>
-	<slider label="Distance" name="camera_offset_scale"/>
-	<text name="heading2">
-		Automatisk positionering for:
-	</text>
-	<check_box label="Byg/Redigér" name="edit_camera_movement" tool_tip="Benyt automatisk kamera positionering ved start og slut af editerings modus"/>
-	<check_box label="Udseende" name="appearance_camera_movement" tool_tip="Benyt automatisk kamera positionering ved redigering"/>
-	<check_box initial_value="sand" label="Sidepanel" name="appearance_sidebar_positioning" tool_tip="Benyt automatisk positionering af kamera"/>
-	<check_box label="Vis avatar i førsteperson" name="first_person_avatar_visible"/>
-	<check_box label="Piletaster bruges altid til bevægelse" name="arrow_keys_move_avatar_check"/>
-	<check_box label="Tast-tast-hold for at løbe" name="tap_tap_hold_to_run"/>
-	<check_box label="Bevæg avatarlæber når der tales" name="enable_lip_sync"/>
-	<check_box label="Talebobler" name="bubble_text_chat"/>
-	<slider label="Synlighed" name="bubble_chat_opacity"/>
-	<color_swatch name="background" tool_tip="Vælg farve for talebobler"/>
 	<text name="UI Size:">
-		Brugerflade størrelse
+		UI størrelse:
 	</text>
 	<check_box label="Vis script fejl i:" name="show_script_errors"/>
 	<radio_group name="show_location">
 		<radio_item label="Chat" name="0"/>
 		<radio_item label="Separat vindue" name="1"/>
 	</radio_group>
-	<check_box label="Knap til aktiverering af mikrofon:" name="push_to_talk_toggle_check" tool_tip="I walkie-talkie-modus sendes stemme kun når knappen er trykket ned, ellers vil tryk på knap tænde og slukke mikrofon."/>
-	<line_editor label="Brug walkie-talkie modus" name="modifier_combo"/>
-	<button label="Angiv taste" name="set_voice_hotkey_button"/>
-	<button label="Midterste museknap" name="set_voice_middlemouse_button" tool_tip="Nulstil til midterste musetaste"/>
-	<button label="Andre enheder" name="joystick_setup_button"/>
+	<check_box label="Tillad flere åbne klienter" name="allow_multiple_viewer_check"/>
+	<check_box label="Vælg netværk ved login" name="show_grid_selection_check"/>
+	<check_box label="Vælg avanceret menu" name="show_advanced_menu_check"/>
+	<check_box label="Vis udvikler menu" name="show_develop_menu_check"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_chat.xml b/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
index 72f8476094c4af17c43d84b3ae31b01442a4427a..3705a5902a0380320ba6170211b1c39d6170c5fd 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_chat.xml
@@ -8,44 +8,10 @@
 		<radio_item label="Mellem" name="radio2" value="1"/>
 		<radio_item label="Stor" name="radio3" value="2"/>
 	</radio_group>
-	<text name="font_colors">
-		Skriftfarve:
-	</text>
-	<color_swatch label="Dig" name="user"/>
-	<text name="text_box1">
-		Dig
-	</text>
-	<color_swatch label="Andre" name="agent"/>
-	<text name="text_box2">
-		Andre
-	</text>
-	<color_swatch label="IM" name="im"/>
-	<text name="text_box3">
-		IM
-	</text>
-	<color_swatch label="System" name="system"/>
-	<text name="text_box4">
-		System
-	</text>
-	<color_swatch label="Fejl" name="script_error"/>
-	<text name="text_box5">
-		Fejl
-	</text>
-	<color_swatch label="Objekter" name="objects"/>
-	<text name="text_box6">
-		Objekter
-	</text>
-	<color_swatch label="Ejer" name="owner"/>
-	<text name="text_box7">
-		Ejer
-	</text>
-	<color_swatch label="URL&apos;er" name="links"/>
-	<text name="text_box9">
-		URL&apos;er
-	</text>
 	<check_box initial_value="true" label="Afspil skrive animation ved chat" name="play_typing_animation"/>
 	<check_box label="Send e-mail til mig når jeg modtager IM og er offline" name="send_im_to_email"/>
 	<check_box label="Ã…ben for almindelig tekst i IM og chat historik" name="plain_text_chat_history"/>
+	<check_box label="Boble chat" name="bubble_text_chat"/>
 	<text name="show_ims_in_label">
 		Vis IM&apos;er i:
 	</text>
@@ -56,6 +22,13 @@
 		<radio_item label="Separate vinduer" name="radio" value="0"/>
 		<radio_item label="Faner" name="radio2" value="1"/>
 	</radio_group>
+	<text name="disable_toast_label">
+		Tillad ingående chat popup vinduer:
+	</text>
+	<check_box label="Gruppe chats" name="EnableGroupChatPopups" tool_tip="Vælg for at se popup vindue når gruppe chat beskeder modtages"/>
+	<check_box label="IM chats" name="EnableIMChatPopups" tool_tip="Vælg for at se popup vindue når personlige beskeder (IM) modtages"/>
+	<spinner label="Tid før chatvisning forsvinder:" name="nearby_toasts_lifetime"/>
+	<spinner label="Tid før chatvisning forsvinder:" name="nearby_toasts_fadingtime"/>
 	<check_box label="Benyt maskin-oversættelse ved chat (håndteret af Google)" name="translate_chat_checkbox"/>
 	<text name="translate_language_text" width="110">
 		Oversæt chat til :
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_colors.xml b/indra/newview/skins/default/xui/da/panel_preferences_colors.xml
new file mode 100644
index 0000000000000000000000000000000000000000..604a00e0b4671fde40766a5b3800dce043c3bad5
--- /dev/null
+++ b/indra/newview/skins/default/xui/da/panel_preferences_colors.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Farver" name="colors_panel">
+	<text name="effects_color_textbox">
+		Mine effekter (selektions-stråle):
+	</text>
+	<color_swatch name="effect_color_swatch" tool_tip="Klik for at åbne farve-vælger"/>
+	<text name="font_colors">
+		Chat bogstavsfarver:
+	</text>
+	<text name="text_box1">
+		Mig
+	</text>
+	<text name="text_box2">
+		Andre
+	</text>
+	<text name="text_box3">
+		Objekter
+	</text>
+	<text name="text_box4">
+		System
+	</text>
+	<text name="text_box5">
+		Fejl
+	</text>
+	<text name="text_box7">
+		Ejer
+	</text>
+	<text name="text_box9">
+		URL&apos;er
+	</text>
+	<text name="bubble_chat">
+		Chat-boble baggrund:
+	</text>
+	<color_swatch name="background" tool_tip="Vælg farve til chat-boble"/>
+	<slider label="Uigennemsigtighed:" name="bubble_chat_opacity"/>
+	<text name="floater_opacity">
+		Vindue uigennemsigtighed:
+	</text>
+	<slider label="Aktiv:" name="active"/>
+	<slider label="Inaktiv:" name="inactive"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_general.xml b/indra/newview/skins/default/xui/da/panel_preferences_general.xml
index 6a85cf4aae41c6f85f3e01e24bf3f3a32c0aebf7..5702d48e979712abd76c24771c280b23cb300704 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_general.xml
@@ -42,16 +42,22 @@
 		<radio_item label="Vis" name="radio2" value="1"/>
 		<radio_item label="Vis et øjeblik" name="radio3" value="2"/>
 	</radio_group>
-	<check_box label="Vis mit navn" name="show_my_name_checkbox1"/>
-	<check_box initial_value="true" label="Små avatar navne" name="small_avatar_names_checkbox"/>
-	<check_box label="Gruppetitler" name="show_all_title_checkbox1"/>
-	<text name="effects_color_textbox">
-		Farve til mine effekter:
+	<check_box label="Mit navn" name="show_my_name_checkbox1"/>
+	<check_box label="Brugernavne" name="show_slids" tool_tip="Vis brugernavne, som bobsmith123"/>
+	<check_box label="Gruppe titler" name="show_all_title_checkbox1" tool_tip="Vis hgruppetitler, som f.eks. administrator eller medlem"/>
+	<check_box label="Fremhæv venner" name="show_friends" tool_tip="Fremhæv navne-tags for dine venner"/>
+	<check_box label="Vis visningsnavne" name="display_names_check" tool_tip="Vælg for at bruge visningsnavne i chat, IM, navne-tags m.v."/>
+	<check_box label="Aktivér UI tips i klient" name="viewer_hints_check"/>
+	<text name="inworld_typing_rg_label">
+		Trykker bogstav taster:
 	</text>
+	<radio_group name="inworld_typing_preference">
+		<radio_item label="Starter lokal chat" name="radio_start_chat" value="1"/>
+		<radio_item label="Påvirker bevægelse (f.eks. WASD)" name="radio_move" value="0"/>
+	</radio_group>
 	<text name="title_afk_text">
 		Tid inden &quot;væk&quot;:
 	</text>
-	<color_swatch label="" name="effect_color_swatch" tool_tip="Klik for at åbne farvevælger"/>
 	<combo_box label="Timeout før &apos;væk&apos;:" name="afk">
 		<combo_box.item label="2 minutter" name="item0"/>
 		<combo_box.item label="5 minutter" name="item1"/>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
index 5bc5025ff19fb422dec85714f7e54a008e54fea5..15da1f9ec5819f13792bb1cc015c1bf679b65815 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_graphics1.xml
@@ -26,6 +26,7 @@
 		<text name="ShadersText">
 			Overflader:
 		</text>
+		<check_box initial_value="sand" label="Gennemsigtig vand" name="TransparentWater"/>
 		<check_box initial_value="true" label="Glatte flader og skin" name="BumpShiny"/>
 		<check_box initial_value="true" label="Basale flader" name="BasicShaders" tool_tip="Ved at slå dette valg fra, kan det forhindres at visse grafikkort drivere crasher."/>
 		<check_box initial_value="true" label="Atmosfæriske flader" name="WindLightUseAtmosShaders"/>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_move.xml b/indra/newview/skins/default/xui/da/panel_preferences_move.xml
new file mode 100644
index 0000000000000000000000000000000000000000..98dfed92c1643567a9b153b8252b24f357c3b2f2
--- /dev/null
+++ b/indra/newview/skins/default/xui/da/panel_preferences_move.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Flyv" name="move_panel">
+	<slider label="Se vinkel" name="camera_fov"/>
+	<slider label="Distance" name="camera_offset_scale"/>
+	<text name="heading2">
+		Automatisk position for:
+	</text>
+	<check_box label="Byg/Redigér" name="edit_camera_movement" tool_tip="Benyt automatisk kamera positionering når edit modus aktiveres og forlades"/>
+	<check_box label="Udseende" name="appearance_camera_movement" tool_tip="Benyt automatisk kamera positionering i edit modus"/>
+	<check_box initial_value="sand" label="Sidepanel" name="appearance_sidebar_positioning" tool_tip="Benyt automatisk kamera positionering ved sidepanel"/>
+	<check_box label="Vis avatar i første-person" name="first_person_avatar_visible"/>
+	<text name=" Mouse Sensitivity">
+		Muse-følsomhed i første-person:
+	</text>
+	<check_box label="Omvend" name="invert_mouse"/>
+	<check_box label="Piletaster bevæger altid avatar" name="arrow_keys_move_avatar_check"/>
+	<check_box label="Tryk to gange for at løbe" name="tap_tap_hold_to_run"/>
+	<check_box label="Dobbelt-klik for at:" name="double_click_chkbox"/>
+	<radio_group name="double_click_action">
+		<radio_item label="Teleportere" name="radio_teleport"/>
+		<radio_item label="Auto-pilot" name="radio_autopilot"/>
+	</radio_group>
+	<button label="Andre enheder" name="joystick_setup_button"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/da/panel_preferences_privacy.xml
index cdb407dbad6f3740c4b3f6bf12d1e130cc660102..2843f0d339f1c765be04ad21905736eab115d237 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_privacy.xml
@@ -10,16 +10,19 @@
 	<check_box label="Kun venner og grupper ved jeg er online" name="online_visibility"/>
 	<check_box label="Kun venner og grupper kan sende besked til mig" name="voice_call_friends_only_check"/>
 	<check_box label="Slå mikrofon fra når opkald slutter" name="auto_disengage_mic_check"/>
-	<check_box label="Acceptér cookies" name="cookies_enabled"/>
 	<text name="Logs:">
-		Logs:
+		Chat Logs:
 	</text>
 	<check_box label="Gem en log med lokal chat på min computer" name="log_nearby_chat"/>
 	<check_box label="Gem en log med private beskeder (IM) på min computer" name="log_instant_messages"/>
-	<check_box label="Tilføj tidsstempel" name="show_timestamps_check_im"/>
+	<check_box label="Tilføj klokkeslæt til hver linie i chat log" name="show_timestamps_check_im"/>
+	<check_box label="Tilføj datostempel til log filnavn." name="logfile_name_datestamp"/>
 	<text name="log_path_desc">
 		Placering af logfiler:
 	</text>
 	<button label="Ændre sti" label_selected="Ændre sti" left="150" name="log_path_button"/>
 	<button label="Liste med blokeringer" name="block_list"/>
+	<text name="block_list_label">
+		(Personer og/eller objekter du har blokeret)
+	</text>
 </panel>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_setup.xml b/indra/newview/skins/default/xui/da/panel_preferences_setup.xml
index 38bc9c0a2a705b2426e430c2e358e744e756ecf6..332b5ed1c4b0271a8b18921529af030723507598 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_setup.xml
@@ -1,13 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Opsætning" name="Input panel">
-	<button label="Andre enheder" name="joystick_setup_button"/>
-	<text name="Mouselook:">
-		Første person:
-	</text>
-	<text name=" Mouse Sensitivity">
-		Mus - følsomhed
-	</text>
-	<check_box label="Omvendt" name="invert_mouse"/>
 	<text name="Network:">
 		Netværk:
 	</text>
@@ -37,13 +29,15 @@
 		<radio_item label="Benyt min browser(IE, Firefox, Safari)" name="external" tool_tip="Brug systemets standard web browser til hjælp, web links, m.v. Ikke anbefalet hvis du kører i fuld-skærm." value="1"/>
 		<radio_item label="Benyt den indbyggede browser" name="internal" tool_tip="Brug den indbyggede web browser til hjælp, web links m.v. Denne browser åbner et nyt vindue i [APP_NAME]." value=""/>
 	</radio_group>
-	<check_box label="Aktivér plugins" name="browser_plugins_enabled"/>
-	<check_box label="Acceptér cookies" name="cookies_enabled"/>
-	<check_box label="Aktivér Javascript" name="browser_javascript_enabled"/>
-	<check_box label="Aktivér web proxy" name="web_proxy_enabled"/>
+	<check_box initial_value="true" label="Aktivér plugins" name="browser_plugins_enabled"/>
+	<check_box initial_value="true" label="Acceptér cookies" name="cookies_enabled"/>
+	<check_box initial_value="true" label="Aktivér Javascript" name="browser_javascript_enabled"/>
+	<check_box initial_value="fra" label="Tilad media browser pop-ups" name="media_popup_enabled"/>
+	<check_box initial_value="false" label="Aktivér web proxy" name="web_proxy_enabled"/>
 	<text name="Proxy location">
 		Proxy placering:
 	</text>
 	<line_editor name="web_proxy_editor" tool_tip="Angiv navn eller IP addresse på den proxy du ønsker at anvende"/>
 	<spinner label="Port nummer:" name="web_proxy_port"/>
+	<check_box initial_value="sand" label="Hent og installer automatisk [APP_NAME] opdateringer" name="updater_service_active"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/da/panel_preferences_sound.xml b/indra/newview/skins/default/xui/da/panel_preferences_sound.xml
index 18cb0e47b9261c0def658bfbd404fc934cedf0f7..75600a93f64bd32f2247483bb707b58596c40607 100644
--- a/indra/newview/skins/default/xui/da/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/da/panel_preferences_sound.xml
@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Lyde" name="Preference Media panel">
+	<panel.string name="middle_mouse">
+		Midterste museknap
+	</panel.string>
 	<slider label="Generel" name="System Volume"/>
 	<check_box initial_value="true" label="Sluk lyd når minimeret" name="mute_when_minimized"/>
 	<slider label="Knapper" name="UI Volume"/>
@@ -23,6 +26,11 @@
 		<radio_item label="Kamera position" name="0"/>
 		<radio_item label="Avatar position" name="1"/>
 	</radio_group>
+	<check_box label="Bevæg avatar-læber når der snakkes" name="enable_lip_sync"/>
+	<check_box label="Skift tale tænd/sluk når jeg trykker:" name="push_to_talk_toggle_check" tool_tip="Når du er i skift-modus, vil hvert tryk tænde eller slukke din mikrofon. Når du ikke er i skift-modus, vil din mikrofon kun være tændt når knappen/tasten holdes nede (som en Walkie Talkie)"/>
+	<line_editor label="Tryk-for-tale udløser" name="modifier_combo"/>
+	<button label="Angiv taste" name="set_voice_hotkey_button"/>
+	<button name="set_voice_middlemouse_button" tool_tip="Nulstil til midterste muse-knap"/>
 	<button label="Input/Output enheder" name="device_settings_btn"/>
 	<panel label="Enhedsopsætning" name="device_settings_panel">
 		<panel.string name="default_text">
diff --git a/indra/newview/skins/default/xui/da/panel_profile.xml b/indra/newview/skins/default/xui/da/panel_profile.xml
index b2d1e9791ab666bd1d88bc743c1ff6ec5919667f..b8b99a9c21a17a0b9704c01e7c4e72633f0f90d1 100644
--- a/indra/newview/skins/default/xui/da/panel_profile.xml
+++ b/indra/newview/skins/default/xui/da/panel_profile.xml
@@ -42,7 +42,7 @@
 					<button label="Teleportér" name="teleport" tool_tip="Tilbyd teleport"/>
 				</layout_panel>
 				<layout_panel name="overflow_btn_lp">
-					<button label="â–¼" name="overflow_btn" tool_tip="Betal eller del beholdning med denne beboer"/>
+					<menu_button label="â–¼" name="overflow_btn" tool_tip="Betal eller del beholdning med denne beboer"/>
 				</layout_panel>
 			</layout_stack>
 		</layout_panel>
diff --git a/indra/newview/skins/default/xui/da/panel_profile_view.xml b/indra/newview/skins/default/xui/da/panel_profile_view.xml
index 23b9d3ba83e0563516bbc82d0d7bca4529be8e21..5e0a51eb28d1a398a67a94aedf0b9c85c82e284c 100644
--- a/indra/newview/skins/default/xui/da/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/da/panel_profile_view.xml
@@ -6,8 +6,14 @@
 	<string name="status_offline">
 		Offline
 	</string>
-	<text_editor name="user_name" value="(Henter...)"/>
+	<text name="display_name_label" value="Visningsnavn:"/>
+	<text name="solo_username_label" value="Brugernavn:"/>
 	<text name="status" value="Online"/>
+	<text name="user_name_small" value="Se på mig med dette enormt ekstremt super lange navn"/>
+	<text name="user_name" value="Jack Linden"/>
+	<button name="copy_to_clipboard" tool_tip="Kopiér til udskriftsholder"/>
+	<text name="user_label" value="Brugernavn:"/>
+	<text name="user_slid" value="jack.linden"/>
 	<tab_container name="tabs">
 		<panel label="PROFIL" name="panel_profile"/>
 		<panel label="FAVORITTER" name="panel_picks"/>
diff --git a/indra/newview/skins/default/xui/da/panel_script_ed.xml b/indra/newview/skins/default/xui/da/panel_script_ed.xml
index 0bdfa89d3b7a894b4d2647077b57e0882628cc03..8997cab30ca98593f32c2b8aab265f03c8b6fc89 100644
--- a/indra/newview/skins/default/xui/da/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/da/panel_script_ed.xml
@@ -15,11 +15,6 @@
 	<panel.string name="Title">
 		Script: [NAME]
 	</panel.string>
-	<text_editor name="Script Editor">
-		Henter...
-	</text_editor>
-	<button label="Gem" label_selected="Gem" name="Save_btn"/>
-	<combo_box label="Indsæt..." name="Insert..."/>
 	<menu_bar name="script_menu">
 		<menu label="Filer" name="File">
 			<menu_item_call label="Gem" name="Save"/>
@@ -40,4 +35,10 @@
 			<menu_item_call label="Hjælp med keywords..." name="Keyword Help..."/>
 		</menu>
 	</menu_bar>
+	<text_editor name="Script Editor">
+		Henter...
+	</text_editor>
+	<combo_box label="Indsæt..." name="Insert..."/>
+	<button label="Gem" label_selected="Gem" name="Save_btn"/>
+	<button label="Redigér..." name="Edit_btn"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/da/role_actions.xml b/indra/newview/skins/default/xui/da/role_actions.xml
index 5ec90a759aacaee2967c5b38e5174a6970c3ff92..7e581200a58aff529258b71c020e4d90ee4f4f5e 100644
--- a/indra/newview/skins/default/xui/da/role_actions.xml
+++ b/indra/newview/skins/default/xui/da/role_actions.xml
@@ -1,76 +1,73 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <role_actions>
 	<action_set description="Disse rettigheder inkluderer adgang til at tilføje og fjerne gruppe medlemmer og tillade nye medlemmer at melde sig ind uden invitation" name="Membership">
-		<action description="Invitér personer til denne gruppe" longdescription="Invitér personer til denne gruppe via &apos;Invitér ny person...&apos; knappen i fanen: medlemmer &amp; roller &gt; underfanen: medlemmer" name="member invite"/>
-		<action description="Fjern medlemmer fra denne gruppe" longdescription="Fjern medlemmer i denne gruppe via &apos;Fjern fra gruppe&apos; knappen i fanen: medlemmer &amp; roller &gt; underfanen: medlemmer. En ejer kan fjerne alle undtagen en anden ejer. Hvis du ikke er en ejer, kan et medlem kun fjernes fra gruppen hvis, og kun hvis, medlemmet kun findes i Alle rollen, og ikke i andre roller. for at fjerne medlemmer fra roller, skal du have rettigheden &apos;Fjern medlemmer fra roller" name="member eject"/>
-		<action description="Åben eller luk for &apos;fri tilmelding&apos; og ændre &apos;tilmeldingsgebyr&apos;" longdescription="Åben for &apos;fri tilmelding&apos; så alle kan blive medlem af gruppen, eller luk for &apos;fri tilmelding&apos; så kun inveterede kan blive medlem. ændre &apos;tilmeldingsgebyr&apos; i gruppe opsætningsbilledet sektionen i Generelt fanen" name="member options"/>
+		<action description="Invitér personer til denne gruppe" longdescription="Invitér personer til denne gruppe via &apos;Invitér ny person...&apos; knappen i fanen: medlemmer &amp; roller &gt; underfanen: medlemmer" name="member invite" value="1"/>
+		<action description="Fjern medlemmer fra denne gruppe" longdescription="Fjern medlemmer i denne gruppe via &apos;Fjern fra gruppe&apos; knappen i fanen: medlemmer &amp; roller &gt; underfanen: medlemmer. En ejer kan fjerne alle undtagen en anden ejer. Hvis du ikke er en ejer, kan et medlem kun fjernes fra gruppen hvis, og kun hvis, medlemmet kun findes i Alle rollen, og ikke i andre roller. for at fjerne medlemmer fra roller, skal du have rettigheden &apos;Fjern medlemmer fra roller" name="member eject" value="2"/>
+		<action description="Åben eller luk for &apos;fri tilmelding&apos; og ændre &apos;tilmeldingsgebyr&apos;" longdescription="Åben for &apos;fri tilmelding&apos; så alle kan blive medlem af gruppen, eller luk for &apos;fri tilmelding&apos; så kun inveterede kan blive medlem. ændre &apos;tilmeldingsgebyr&apos; i gruppe opsætningsbilledet sektionen i Generelt fanen" name="member options" value="3"/>
 	</action_set>
 	<action_set description="Disse rettigheder inkluderer adgang til at tilføje, fjerne og ændre gruppe-roller, tilføje og fjerne medlemmer i roller, og give rettigheder til roller" name="Roles">
-		<action description="Opret nye roller" longdescription="Opret nye roller i fanen: Medlemmer &amp; roller &gt; under-fanen: Roller." name="role create"/>
-		<action description="Slet roller" longdescription="Slet roller i roller i fanen: Medlemmer &amp; roller &gt; under-fanen: Roller." name="role delete"/>
-		<action description="Ændre rolle navne, titler, beskrivelser og angivelse af om rollemedlemmer kan ses af andre udenfor gruppen" longdescription="Ændre rolle navne, titler, beskrivelser og angivelse af om rollemedlemmer kan ses af andre udenfor gruppen. Dette håndteres i bunden af fanen:: Medlemmer &amp; roller &gt; under-fanen: Roller efter at have valgt en rolle." name="role properties"/>
-		<action description="Tildel andre samme roller som dig selv" longdescription="Tildel andre medlemmer til roller i Tildelte roller sektionen på fanen: Medlemmer &amp; roller &gt; under-fanen: Medlemmer. Et medlem med denne rettighed kan kun tildele andre medlemmer en rolle som tildeleren allerede selv har." name="role assign member limited"/>
-		<action description="Tildele medlemmer enhver rolle" longdescription="Tildel andre medlemmer til en hvilken som helst rolle i Tildelte roller sektionen på fanen: Medlemmer &amp; roller &gt; under-fanen: Medlemmer. *ADVARSEL* Ethvert medlem i en rolle med denne rettighed kan tildele sig selv - og enhver anden - roller som giver dem flere rettigheder end de havde tidligere, og dermed potentielt få næsten samme magt som ejer. Vær sikker på at vide hvad du ør inden du tildeler denne rettighed." name="role assign member"/>
-		<action description="Fjern medlemmer fra roller" longdescription="Fjern medlemmer fra roller i in Tildelte roller sektionen på fanen: Medlemmer &amp; roller &gt; under-fanen: Medlemmer. Ejere kan ikke fjernes." name="role remove member"/>
-		<action description="Tildel og fjern rettigheder for roller" longdescription="Tildel og fjern rettigheder for roller i tilladte rettigheder sektionen på fanen: Medlemmer &amp; roller &gt; under-fanen: Roller. *ADVARSEL* Ethvert medlem i en rolle med denne rettighed kan tildele sig selv - og enhver anden - rettigheder som giver dem flere rettigheder end de havde tidligere, og dermed potentielt få næsten samme magt som ejer. Vær sikker på at vide hvad du gør inden du tildeler denne rettighed." name="role change actions"/>
+		<action description="Opret nye roller" longdescription="Opret nye roller i fanen: Medlemmer &amp; roller &gt; under-fanen: Roller." name="role create" value="4"/>
+		<action description="Slet roller" longdescription="Slet roller i roller i fanen: Medlemmer &amp; roller &gt; under-fanen: Roller." name="role delete" value="5"/>
+		<action description="Ændre rolle navne, titler, beskrivelser og angivelse af om rollemedlemmer kan ses af andre udenfor gruppen" longdescription="Ændre rolle navne, titler, beskrivelser og angivelse af om rollemedlemmer kan ses af andre udenfor gruppen. Dette håndteres i bunden af fanen:: Medlemmer &amp; roller &gt; under-fanen: Roller efter at have valgt en rolle." name="role properties" value="6"/>
+		<action description="Tildel andre samme roller som dig selv" longdescription="Tildel andre medlemmer til roller i Tildelte roller sektionen på fanen: Medlemmer &amp; roller &gt; under-fanen: Medlemmer. Et medlem med denne rettighed kan kun tildele andre medlemmer en rolle som tildeleren allerede selv har." name="role assign member limited" value="7"/>
+		<action description="Tildele medlemmer enhver rolle" longdescription="Tildel andre medlemmer til en hvilken som helst rolle i Tildelte roller sektionen på fanen: Medlemmer &amp; roller &gt; under-fanen: Medlemmer. *ADVARSEL* Ethvert medlem i en rolle med denne rettighed kan tildele sig selv - og enhver anden - roller som giver dem flere rettigheder end de havde tidligere, og dermed potentielt få næsten samme magt som ejer. Vær sikker på at vide hvad du ør inden du tildeler denne rettighed." name="role assign member" value="8"/>
+		<action description="Fjern medlemmer fra roller" longdescription="Fjern medlemmer fra roller i in Tildelte roller sektionen på fanen: Medlemmer &amp; roller &gt; under-fanen: Medlemmer. Ejere kan ikke fjernes." name="role remove member" value="9"/>
+		<action description="Tildel og fjern rettigheder for roller" longdescription="Tildel og fjern rettigheder for roller i tilladte rettigheder sektionen på fanen: Medlemmer &amp; roller &gt; under-fanen: Roller. *ADVARSEL* Ethvert medlem i en rolle med denne rettighed kan tildele sig selv - og enhver anden - rettigheder som giver dem flere rettigheder end de havde tidligere, og dermed potentielt få næsten samme magt som ejer. Vær sikker på at vide hvad du gør inden du tildeler denne rettighed." name="role change actions" value="10"/>
 	</action_set>
 	<action_set description="Disse rettigheder inkluderer adgang til at ændre denne gruppes identitetsoplysninger, som f.eks. om gruppen kan ses af andre, gruppens fundats og billede." name="Group Identity">
-		<action description="Ændre fundats, billede og &apos;Vis i søgning&apos;" longdescription="Ændre fundats og &apos;Vis i søgning&apos;. Dette gøres under fanen Generelt." name="group change identity"/>
+		<action description="Ændre fundats, billede og &apos;Vis i søgning&apos;" longdescription="Ændre fundats og &apos;Vis i søgning&apos;. Dette gøres under fanen Generelt." name="group change identity" value="11"/>
 	</action_set>
 	<action_set description="Disse rettigheder inkluderer adgang til dedikere, ændre og sælge land fra denne gruppes besiddelser. For at åbne &apos;Om land...&apos; vinduet, højre-klik på jorden og vælg &apos;Om land...&apos;, eller klik på &apos;Om land...&apos; i &apos;Verden&apos; menuen." name="Parcel Management">
-		<action description="Dedikér eller køb land til gruppen" longdescription="Dedikér eller køb land til gruppen. Dette gøres i fanen Generelt i &apos;Om land...&apos;." name="land deed"/>
-		<action description="Forlad land og overgiv det til guvernør Linden" longdescription="Forlad land og overgiv det til guvernør Linden. *ADVARSEL* Ethvert medlem med en rolle med denne rettighed kan overdrage gruppe-ejet land via fanen Generelt i &apos;Om land...&apos; til Lindens ejerskab uden salg! Vær sikker på at vide hvad du ør inden du tildeler denne rettighed." name="land release"/>
-		<action description="Sæt land til salg" longdescription="Sæt land til salg. *ADVARSEL* Ethvert medlem med en rolle med denne rettighed kan sælge gruppe-ejet land via fanen Generelt i &apos;Om land...&apos;! Vær sikker på at vide hvad du ør inden du tildeler denne rettighed." name="land set sale info"/>
-		<action description="Opdel og saml parceller" longdescription="Opdel og saml parceller. Dette gøres ved at højreklikke på jorden og vælge &apos;Redigér terræn&apos;" name="land divide join"/>
+		<action description="Dedikér eller køb land til gruppen" longdescription="Dedikér eller køb land til gruppen. Dette gøres i fanen Generelt i &apos;Om land...&apos;." name="land deed" value="12"/>
+		<action description="Forlad land og overgiv det til guvernør Linden" longdescription="Forlad land og overgiv det til guvernør Linden. *ADVARSEL* Ethvert medlem med en rolle med denne rettighed kan overdrage gruppe-ejet land via fanen Generelt i &apos;Om land...&apos; til Lindens ejerskab uden salg! Vær sikker på at vide hvad du ør inden du tildeler denne rettighed." name="land release" value="13"/>
+		<action description="Sæt land til salg" longdescription="Sæt land til salg. *ADVARSEL* Ethvert medlem med en rolle med denne rettighed kan sælge gruppe-ejet land via fanen Generelt i &apos;Om land...&apos;! Vær sikker på at vide hvad du ør inden du tildeler denne rettighed." name="land set sale info" value="14"/>
+		<action description="Opdel og saml parceller" longdescription="Opdel og saml parceller. Dette gøres ved at højreklikke på jorden og vælge &apos;Redigér terræn&apos;" name="land divide join" value="15"/>
 	</action_set>
 	<action_set description="Disse rettigheder inkluderer adgang til at ændre parcel navn og en række parametre om f.eks. landingspunkt, teleports m.v.." name="Parcel Identity">
-		<action description="Angive om sted skal vises i &apos;vis i Søg steder&apos; og angivelse af kategori" longdescription="Angive om sted skal vises i &apos;vis i Søg steder&apos; og angivelse af kategori i &apos;Om land...&apos; &gt; Indstillinger fanen." name="land find places"/>
-		<action description="Ændre parcel navn, beskrivelse, og &apos;Vis i Søg&apos; opsætning" longdescription="Ændre parcel navn, beskrivelse, og &apos;Vis i Søg&apos; opsætning. Dette håndteres i &apos;Om land...&apos;&gt; Opsætning fanen." name="land change identity"/>
-		<action description="Sæt landingspunkt og teleport muligheder" longdescription="På en gruppe-ejet parcel kan medlemmer, med en rolle med denne rettighed, sætte landingspunktet og dermed angive hvor indkommende teleporte skal ankomme og desuden angive dealjer om teleporte. Dette håndteres i &apos;Om land...&apos;&gt; Opsætning fanen." name="land set landing point"/>
+		<action description="Angive om sted skal vises i &apos;vis i Søg steder&apos; og angivelse af kategori" longdescription="Angive om sted skal vises i &apos;vis i Søg steder&apos; og angivelse af kategori i &apos;Om land...&apos; &gt; Indstillinger fanen." name="land find places" value="17"/>
+		<action description="Ændre parcel navn, beskrivelse, og &apos;Vis i Søg&apos; opsætning" longdescription="Ændre parcel navn, beskrivelse, og &apos;Vis i Søg&apos; opsætning. Dette håndteres i &apos;Om land...&apos;&gt; Opsætning fanen." name="land change identity" value="18"/>
+		<action description="Sæt landingspunkt og teleport muligheder" longdescription="På en gruppe-ejet parcel kan medlemmer, med en rolle med denne rettighed, sætte landingspunktet og dermed angive hvor indkommende teleporte skal ankomme og desuden angive dealjer om teleporte. Dette håndteres i &apos;Om land...&apos;&gt; Opsætning fanen." name="land set landing point" value="19"/>
 	</action_set>
 	<action_set description="Disse rettigheder inkluderer adgang til at opsætte parcel indstillinger som f.eks. &apos;Lave objekter&apos;, &apos;Redigere terræn&apos;, samt musik og media indstillinger." name="Parcel Settings">
-		<action description="Ændre musik og media indstillinger" longdescription="Ændre oplysninger om streaming musik og film i &apos;Om land...&apos; &gt; Media fanen." name="land change media"/>
-		<action description="Ændre rettighed til &apos;Redigere terræn&apos;" longdescription="Ændre rettighed til &apos;Redigere terræn&apos;. *ADVARSEL*: Redigere terræn&apos; kan give alle og enhver ret til at ændre terræn og opsætte og flytte Linden planter. Vær sikker på at vide hvad du ør inden du tildeler denne rettighed." name="land edit"/>
-		<action description="Ændre diverse andre indstillinger i &apos;Om land...&apos;&gt; indstillinger fanen" longdescription="Giv adgang til at ændre &apos;Sikker (ingen skade)&apos;, &apos;Flyve&apos;, og tillad andre beboere at: &apos;Lave objekter&apos;, &apos;Redigere terræn&apos;, &apos;Lave landemærker&apos;, og &apos;Køre scripts&apos; på gruppe-ejet land via About Land &gt; Indstillinger fanen." name="land options"/>
+		<action description="Ændre musik og media indstillinger" longdescription="Ændre oplysninger om streaming musik og film i &apos;Om land...&apos; &gt; Media fanen." name="land change media" value="20"/>
+		<action description="Ændre rettighed til &apos;Redigere terræn&apos;" longdescription="Ændre rettighed til &apos;Redigere terræn&apos;. *ADVARSEL*: Redigere terræn&apos; kan give alle og enhver ret til at ændre terræn og opsætte og flytte Linden planter. Vær sikker på at vide hvad du ør inden du tildeler denne rettighed." name="land edit" value="21"/>
+		<action description="Ændre diverse andre indstillinger i &apos;Om land...&apos;&gt; indstillinger fanen" longdescription="Giv adgang til at ændre &apos;Sikker (ingen skade)&apos;, &apos;Flyve&apos;, og tillad andre beboere at: &apos;Lave objekter&apos;, &apos;Redigere terræn&apos;, &apos;Lave landemærker&apos;, og &apos;Køre scripts&apos; på gruppe-ejet land via About Land &gt; Indstillinger fanen." name="land options" value="22"/>
 	</action_set>
 	<action_set description="Disse rettigheder inkluderer adgang til at medlemmer kan omgå restriktioner på gruppe-ejede parceller." name="Parcel Powers">
-		<action description="Tillad altid &apos;Rediger Terræn&apos;" longdescription="Medlemmer med denne rolle har adgang til at redigere terræn på gruppe-ejede parceller, også selvom denne mulighed ikke er aktiveret på &apos;Om land...&apos; &gt; Indstillinger fanen." name="land allow edit land"/>
-		<action description="Tillad altid at &apos;Flyve&apos;" longdescription="Medlemmer med denne rolle har adgang til at flyve på gruppe-ejede parceller, også selvom denne mulighed ikke er aktiveret på &apos;Om land...&apos; &gt; Indstillinger fanen." name="land allow fly"/>
-		<action description="Tillad altid &apos;Lave objekter&apos;" longdescription="Medlemmer med denne rolle har adgang til at lave nye objekter på gruppe-ejede parceller, også selvom denne mulighed ikke er aktiveret på &apos;Om land...&apos; &gt; Indstillinger fanen." name="land allow create"/>
-		<action description="Tillad altid at &apos;Lave landemærker&apos;" longdescription="Medlemmer med denne rolle har adgang til at lave landemærker på gruppe-ejede parceller, også selvom denne mulighed ikke er aktiveret på &apos;Om land...&apos; &gt; Indstillinger fanen." name="land allow landmark"/>
-		<action description="Tillad altid &apos;sæt til hjem&apos; på gruppe-ejet land" longdescription="Medlemmer med denne rolle har adgang til at benytte &apos;Verden&apos; menuen og vælge &apos;sæt til hjem&apos; på en parcel der er dedikeret til gruppen." name="land allow set home"/>
+		<action description="Tillad altid &apos;Rediger Terræn&apos;" longdescription="Medlemmer med denne rolle har adgang til at redigere terræn på gruppe-ejede parceller, også selvom denne mulighed ikke er aktiveret på &apos;Om land...&apos; &gt; Indstillinger fanen." name="land allow edit land" value="23"/>
+		<action description="Tillad altid at &apos;Flyve&apos;" longdescription="Medlemmer med denne rolle har adgang til at flyve på gruppe-ejede parceller, også selvom denne mulighed ikke er aktiveret på &apos;Om land...&apos; &gt; Indstillinger fanen." name="land allow fly" value="24"/>
+		<action description="Tillad altid &apos;Lave objekter&apos;" longdescription="Medlemmer med denne rolle har adgang til at lave nye objekter på gruppe-ejede parceller, også selvom denne mulighed ikke er aktiveret på &apos;Om land...&apos; &gt; Indstillinger fanen." name="land allow create" value="25"/>
+		<action description="Tillad altid at &apos;Lave landemærker&apos;" longdescription="Medlemmer med denne rolle har adgang til at lave landemærker på gruppe-ejede parceller, også selvom denne mulighed ikke er aktiveret på &apos;Om land...&apos; &gt; Indstillinger fanen." name="land allow landmark" value="26"/>
+		<action description="Tillad altid &apos;sæt til hjem&apos; på gruppe-ejet land" longdescription="Medlemmer med denne rolle har adgang til at benytte &apos;Verden&apos; menuen og vælge &apos;sæt til hjem&apos; på en parcel der er dedikeret til gruppen." name="land allow set home" value="28"/>
+		<action description="Tillad &apos;Event Hosting&apos; på gruppe ejet land" longdescription="Medlemmer med denne rolle kan vælge gruppe ejede parceller som sted når der afholdes et event." name="land allow host event" value="41"/>
 	</action_set>
 	<action_set description="Disse rettigheder inkluderer adgang til at medlemmer kan tillade eller forbyde adgang til gruppe-ejede parceller, inkluderende at &apos;fryse&apos; og udsmide beboere." name="Parcel Access">
-		<action description="Administrér adgangsregler for parceller" longdescription="Administrér adgangsregler for parceller i &apos;Om land&apos; &gt; &apos;Adgang&apos; fanen." name="land manage allowed"/>
-		<action description="Administrér liste med blokerede beboere på parceller" longdescription="Administrér liste med blokerede beboere på parceller i &apos;Om land&apos; &gt; &apos;Adgang&apos; fanen." name="land manage banned"/>
-		<action description="Ændre indstillinger for at &apos;Sælge adgang til&apos; parceller" longdescription="Ændre indstillinger for at &apos;Sælge adgang til&apos; parceller i &apos;Om land&apos; &gt; &apos;Adgang&apos; fanen." name="land manage passes"/>
-		<action description="Adgang til at smide beboere ud og &apos;fryse&apos; beboere på parceller" longdescription="Medlemmer med denne rolle kan håndtere beboere som ikke er velkomne på gruppe-ejet parceller ved at højreklikke på dem, vælge Mere&gt;, og vælge &apos;Smid ud...&apos; eller &apos;Frys...&apos;." name="land admin"/>
+		<action description="Administrér adgangsregler for parceller" longdescription="Administrér adgangsregler for parceller i &apos;Om land&apos; &gt; &apos;Adgang&apos; fanen." name="land manage allowed" value="29"/>
+		<action description="Administrér liste med blokerede beboere på parceller" longdescription="Administrér liste med blokerede beboere på parceller i &apos;Om land&apos; &gt; &apos;Adgang&apos; fanen." name="land manage banned" value="30"/>
+		<action description="Ændre indstillinger for at &apos;Sælge adgang til&apos; parceller" longdescription="Ændre indstillinger for at &apos;Sælge adgang til&apos; parceller i &apos;Om land&apos; &gt; &apos;Adgang&apos; fanen." name="land manage passes" value="31"/>
+		<action description="Adgang til at smide beboere ud og &apos;fryse&apos; beboere på parceller" longdescription="Medlemmer med denne rolle kan håndtere beboere som ikke er velkomne på gruppe-ejet parceller ved at højreklikke på dem, vælge Mere&gt;, og vælge &apos;Smid ud...&apos; eller &apos;Frys...&apos;." name="land admin" value="32"/>
 	</action_set>
 	<action_set description="Disse rettigheder inkluderer mulighed til at tillade beboere at returnere objekter og placere og flytte Linden planter. Dette er brugbart for at medlemmer kan holde orden og tilpasse landskabet. Denne mulighed skal benyttes med varsomhed, da der ikke er mulighed for at fortryde returnering af objekter og ændringer i landskabet." name="Parcel Content">
-		<action description="Returnere objekter ejet af gruppen" longdescription="Returne objekter på gruppe-ejede parceller der er ejet af gruppen. Dette håndteres i &apos;Om land...&apos;&gt; &apos;Objekter&apos; fanen." name="land return group owned"/>
-		<action description="Returnere objekter der er sat til &apos;gruppe&apos;" longdescription="Returnere objekter på gruppe-ejede parceller, der er &apos;sat til gruppe&apos; i &apos;Om land...&apos;&gt; &apos;Objekter&apos; fanen." name="land return group set"/>
-		<action description="Returnere objekter der ikke er ejet af andre" longdescription="Returnere objekter på gruppe-ejede parceller, der er &apos;Ejet af andre&apos; i &apos;Om land...&apos;&gt; &apos;Objekter&apos; fanen." name="land return non group"/>
-		<action description="Ændre landskab med Linden planter" longdescription="Disse rettigheder inkluderer mulighed til at tillade beboere at returnere objekter og placere og flytte Linden planter. Dette er brugbart for at medlemmer kan holde orden og tilpasse landskabet. Denne mulighed skal benyttes med varsomhed, da der ikke er mulighed for at fortryde returnering af objekter og ændringer i landskabet." name="land gardening"/>
+		<action description="Returnere objekter ejet af gruppen" longdescription="Returne objekter på gruppe-ejede parceller der er ejet af gruppen. Dette håndteres i &apos;Om land...&apos;&gt; &apos;Objekter&apos; fanen." name="land return group owned" value="48"/>
+		<action description="Returnere objekter der er sat til &apos;gruppe&apos;" longdescription="Returnere objekter på gruppe-ejede parceller, der er &apos;sat til gruppe&apos; i &apos;Om land...&apos;&gt; &apos;Objekter&apos; fanen." name="land return group set" value="33"/>
+		<action description="Returnere objekter der ikke er ejet af andre" longdescription="Returnere objekter på gruppe-ejede parceller, der er &apos;Ejet af andre&apos; i &apos;Om land...&apos;&gt; &apos;Objekter&apos; fanen." name="land return non group" value="34"/>
+		<action description="Ændre landskab med Linden planter" longdescription="Disse rettigheder inkluderer mulighed til at tillade beboere at returnere objekter og placere og flytte Linden planter. Dette er brugbart for at medlemmer kan holde orden og tilpasse landskabet. Denne mulighed skal benyttes med varsomhed, da der ikke er mulighed for at fortryde returnering af objekter og ændringer i landskabet." name="land gardening" value="35"/>
 	</action_set>
 	<action_set description="Disse rettigheder inkluderer mulighed til at dedikere, ændre og sælge gruppe-ejede objekter. Disse ændringer sker i &apos;Rediger&apos;&gt; &apos;Generelt&apos; fanen." name="Object Management">
-		<action description="Dediker objekter til gruppe" longdescription="Dediker objekter til gruppe i &apos;Rediger&apos;&gt; &apos;Generelt&apos; fanen." name="object deed"/>
-		<action description="Manipulér (flyt, kopiér, ændre) gruppe-ejede objekter" longdescription="Manipulér (flyt, kopiér, ændre) gruppe-ejede objekter i &apos;Rediger&apos;&gt; &apos;Generelt&apos; fanen." name="object manipulate"/>
-		<action description="Sæt gruppe-ejede objekter til salg" longdescription="Sæt gruppe-ejede objekter til salg i &apos;Rediger&apos;&gt; &apos;Generelt&apos; fanen." name="object set sale"/>
+		<action description="Dediker objekter til gruppe" longdescription="Dediker objekter til gruppe i &apos;Rediger&apos;&gt; &apos;Generelt&apos; fanen." name="object deed" value="36"/>
+		<action description="Manipulér (flyt, kopiér, ændre) gruppe-ejede objekter" longdescription="Manipulér (flyt, kopiér, ændre) gruppe-ejede objekter i &apos;Rediger&apos;&gt; &apos;Generelt&apos; fanen." name="object manipulate" value="38"/>
+		<action description="Sæt gruppe-ejede objekter til salg" longdescription="Sæt gruppe-ejede objekter til salg i &apos;Rediger&apos;&gt; &apos;Generelt&apos; fanen." name="object set sale" value="39"/>
 	</action_set>
 	<action_set description="Disse rettigheder inkluderer mulighed til at håndtere betalinger for gruppen og styre adgang til gruppens kontobevægelser." name="Accounting">
-		<action description="Betale gruppe regninger og modtage gruppe udbytte" longdescription="Medlemmer med denne rolle vil automatisk betale gruppe regninger og modtage gruppe udbytte. Det betyder at de vil modtager en andel af indtægter fra salg af gruppe-ejet land og bidrage til betaling af gruppe-relaterede betalinger, som f.eks. betaling for at paceller vises i lister. " name="accounting accountable"/>
+		<action description="Betale gruppe regninger og modtage gruppe udbytte" longdescription="Medlemmer med denne rolle vil automatisk betale gruppe regninger og modtage gruppe udbytte. Det betyder at de vil modtager en andel af indtægter fra salg af gruppe-ejet land og bidrage til betaling af gruppe-relaterede betalinger, som f.eks. betaling for at paceller vises i lister. " name="accounting accountable" value="40"/>
 	</action_set>
 	<action_set description="Disse rettigheder inkluderer adgang til at kunne sende, modtage og se gruppe beskeder." name="Notices">
-		<action description="Send beskeder" longdescription="Medlemmer med denne rolle kan sende beskeder i &apos;Beskeder&apos; fanen." name="notices send"/>
-		<action description="Modtage og se tidligere beskeder" longdescription="Medlemmer med denne rolle kan modtage og se tidligere beskeder i &apos;Beskeder&apos; fanen." name="notices receive"/>
-	</action_set>
-	<action_set description="Disse rettigheder inkluderer adgang til at kunne oprette forslag, stemme på forslag og se historik med forslag." name="Proposals">
-		<action description="Opret forslag" longdescription="Medlemmer med denne rolle kan oprette forslag som der kan stemmes om i &apos;Forslag&apos; fanen." name="proposal start"/>
-		<action description="Stem på forslag" longdescription="Medlemmer med denne rolle kan stemme på forslag i &apos;Forslag&apos; fanen." name="proposal vote"/>
+		<action description="Send beskeder" longdescription="Medlemmer med denne rolle kan sende beskeder i &apos;Beskeder&apos; fanen." name="notices send" value="42"/>
+		<action description="Modtage og se tidligere beskeder" longdescription="Medlemmer med denne rolle kan modtage og se tidligere beskeder i &apos;Beskeder&apos; fanen." name="notices receive" value="43"/>
 	</action_set>
 	<action_set description="Disse rettigheder styrer hvem der kan deltage i gruppe-chat og gruppe stemme-chat." name="Chat">
-		<action description="Deltage i gruppe-chat" longdescription="Medlemmer med denne rolle kan deltage i gruppe-chat sessioner" name="join group chat"/>
-		<action description="Deltag i gruppe stemme-chat" longdescription="Medlemmer med denne rolle kan deltage i gruppe stemme-chat sessioner.  BEMÆRK: Medlemmet skal også have rollen &apos;Deltage i gruppe-chat&apos; for at denne rolle har effekt." name="join voice chat"/>
-		<action description="Styr gruppe-chat" longdescription="Medlemmer med denne rolle kan kontrollere adgang og deltagelse i gruppe-chat og gruppe stemme-chat sessioner." name="moderate group chat"/>
+		<action description="Deltage i gruppe-chat" longdescription="Medlemmer med denne rolle kan deltage i gruppe-chat sessioner" name="join group chat" value="16"/>
+		<action description="Deltag i gruppe stemme-chat" longdescription="Medlemmer med denne rolle kan deltage i gruppe stemme-chat sessioner.  BEMÆRK: Medlemmet skal også have rollen &apos;Deltage i gruppe-chat&apos; for at denne rolle har effekt." name="join voice chat" value="27"/>
+		<action description="Styr gruppe-chat" longdescription="Medlemmer med denne rolle kan kontrollere adgang og deltagelse i gruppe-chat og gruppe stemme-chat sessioner." name="moderate group chat" value="37"/>
 	</action_set>
 </role_actions>
diff --git a/indra/newview/skins/default/xui/da/strings.xml b/indra/newview/skins/default/xui/da/strings.xml
index afd933c7fab406de4f9dd7bf671a1e372513990c..6f891b8d1b18552ef7a110991f27b992a58bf20a 100644
--- a/indra/newview/skins/default/xui/da/strings.xml
+++ b/indra/newview/skins/default/xui/da/strings.xml
@@ -191,6 +191,9 @@
 	<string name="TooltipAgentUrl">
 		Klik for at se beboers profil
 	</string>
+	<string name="TooltipAgentInspect">
+		Lær mere om denne beboer
+	</string>
 	<string name="TooltipAgentMute">
 		Klik for at slukke for denne beboer
 	</string>
@@ -738,6 +741,12 @@
 	<string name="Estate / Full Region">
 		Estate / Hel region
 	</string>
+	<string name="Estate / Homestead">
+		Estate / Homestead
+	</string>
+	<string name="Mainland / Homestead">
+		Mainland / Homestead
+	</string>
 	<string name="Mainland / Full Region">
 		Mainland / Hel region
 	</string>
@@ -775,7 +784,7 @@
 		XML Fil
 	</string>
 	<string name="raw_file">
-		RAW Fil
+		RAW fil
 	</string>
 	<string name="compressed_image_files">
 		Komprimerede billeder
@@ -1728,11 +1737,8 @@
 	<string name="InvOfferGaveYou">
 		gav dig
 	</string>
-	<string name="InvOfferYouDecline">
-		Du afslår
-	</string>
-	<string name="InvOfferFrom">
-		fra
+	<string name="InvOfferDecline">
+		Du afslår [DESC] fra &lt;nolink&gt;[NAME]&lt;/nolink&gt;.
 	</string>
 	<string name="GroupMoneyTotal">
 		Total
@@ -3469,7 +3475,7 @@ Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE].
 		Du er den eneste deltager i denne samtale
 	</string>
 	<string name="offline_message">
-		[FIRST] [LAST] er ikke logget på.
+		[NAME] er logget af.
 	</string>
 	<string name="invite_message">
 		Tryk på [BUTTON NAME] knappen for at acceptére/tilslutte til denne stemme chat.
@@ -3538,7 +3544,10 @@ Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE].
 		http://secondlife.com/landing/voicemorphing
 	</string>
 	<string name="paid_you_ldollars">
-		[NAME] betalte dig L$[AMOUNT]
+		[NAME] betalte dig L$[AMOUNT] [REASON].
+	</string>
+	<string name="paid_you_ldollars_no_reason">
+		[NAME] betalte dig L$[AMOUNT].
 	</string>
 	<string name="you_paid_ldollars">
 		Du betalte [NAME] L$[AMOUNT] [REASON].
@@ -3552,6 +3561,9 @@ Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE].
 	<string name="you_paid_ldollars_no_name">
 		Du betalte L$[AMOUNT] [REASON].
 	</string>
+	<string name="for item">
+		til [ITEM]
+	</string>
 	<string name="for a parcel of land">
 		for en parcel land
 	</string>
@@ -3570,6 +3582,9 @@ Hvis du bliver ved med at modtage denne besked, kontakt venligst [SUPPORT_SITE].
 	<string name="to upload">
 		for at uploade
 	</string>
+	<string name="to publish a classified ad">
+		til offentliggørelse af annonce
+	</string>
 	<string name="giving">
 		Giver L$ [AMOUNT]
 	</string>
diff --git a/indra/newview/skins/default/xui/de/floater_hardware_settings.xml b/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
index d931596efe6bea4d22c2c09df416899409fb73b8..9644bbbaea307524faf16aef7d51d8d696b556f8 100644
--- a/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/de/floater_hardware_settings.xml
@@ -14,6 +14,9 @@
 		<combo_box.item label="8x" name="8x"/>
 		<combo_box.item label="16x" name="16x"/>
 	</combo_box>
+	<text name="antialiasing restart">
+		(Neustart des Viewers erforderlich)
+	</text>
 	<spinner label="Gamma:" name="gamma"/>
 	<text name="(brightness, lower is brighter)">
 		(0 = Standard-Helligkeit, weniger = heller)
diff --git a/indra/newview/skins/default/xui/de/floater_preferences.xml b/indra/newview/skins/default/xui/de/floater_preferences.xml
index a2712c437be6369cd2e98d05c75d63bc7a960f08..3624c4c9689f8a0709e5ca23870c9f3ccfa2c871 100644
--- a/indra/newview/skins/default/xui/de/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/de/floater_preferences.xml
@@ -5,10 +5,12 @@
 	<tab_container name="pref core">
 		<panel label="Allgemein" name="general"/>
 		<panel label="Grafik" name="display"/>
-		<panel label="Privatsphäre" name="im"/>
 		<panel label="Sound &amp; Medien" name="audio"/>
 		<panel label="Chat" name="chat"/>
+		<panel label="Bewegen und anzeigen" name="move"/>
 		<panel label="Meldungen" name="msgs"/>
+		<panel label="Farben" name="colors"/>
+		<panel label="Privatsphäre" name="im"/>
 		<panel label="Konfiguration" name="input"/>
 		<panel label="Erweitert" name="advanced1"/>
 	</tab_container>
diff --git a/indra/newview/skins/default/xui/de/floater_region_debug_console.xml b/indra/newview/skins/default/xui/de/floater_region_debug_console.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b8a1a89c30f8f99b75193edeb8727ba5263fc317
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/floater_region_debug_console.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="region_debug_console" title="Regions-Debug"/>
diff --git a/indra/newview/skins/default/xui/de/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/de/menu_inventory_gear_default.xml
index 3fa68a27bdd1c6e4dad4a03eb04a0b6f596c8a78..df86a5cf71c13ec4c1461fd839996793ce168c1c 100644
--- a/indra/newview/skins/default/xui/de/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/de/menu_inventory_gear_default.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="menu_gear_default">
+<toggleable_menu name="menu_gear_default">
 	<menu_item_call label="Neues Inventar-Fenster" name="new_window"/>
-	<menu_item_call label="Nach Name sortieren" name="sort_by_name"/>
-	<menu_item_call label="Nach aktuellesten Objekten sortieren" name="sort_by_recent"/>
+	<menu_item_check label="Nach Name sortieren" name="sort_by_name"/>
+	<menu_item_check label="Nach aktuellesten Objekten sortieren" name="sort_by_recent"/>
+	<menu_item_check label="Systemordner nach oben" name="sort_system_folders_to_top"/>
 	<menu_item_call label="Filter anzeigen" name="show_filters"/>
 	<menu_item_call label="Filter zurücksetzen" name="reset_filters"/>
 	<menu_item_call label="Alle Ordner schließen" name="close_folders"/>
@@ -12,4 +13,4 @@
 	<menu_item_call label="Original suchen" name="Find Original"/>
 	<menu_item_call label="Alle Links suchen" name="Find All Links"/>
 	<menu_item_call label="Papierkorb ausleeren" name="empty_trash"/>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/de/menu_viewer.xml b/indra/newview/skins/default/xui/de/menu_viewer.xml
index 489990608ff1df7d270183437baf412895ddd799..9eeeaccdea417d298dca89217e56c728bab57d82 100644
--- a/indra/newview/skins/default/xui/de/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/de/menu_viewer.xml
@@ -12,6 +12,12 @@
 		<menu_item_check label="Mein Inventar" name="ShowSidetrayInventory"/>
 		<menu_item_check label="Meine Gesten" name="Gestures"/>
 		<menu_item_check label="Meine Stimme" name="ShowVoice"/>
+		<menu label="Bewegung" name="Movement">
+			<menu_item_call label="Hinsetzen" name="Sit Down Here"/>
+			<menu_item_check label="Fliegen" name="Fly"/>
+			<menu_item_check label="Immer rennen" name="Always Run"/>
+			<menu_item_call label="Animation meines Avatars stoppen" name="Stop Animating My Avatar"/>
+		</menu>
 		<menu label="Mein Status" name="Status">
 			<menu_item_call label="Abwesend" name="Set Away"/>
 			<menu_item_call label="Beschäftigt" name="Set Busy"/>
@@ -47,6 +53,7 @@
 			<menu_item_check label="Landeigentümer" name="Land Owners"/>
 			<menu_item_check label="Koordinaten" name="Coordinates"/>
 			<menu_item_check label="Parzelleneigenschaften" name="Parcel Properties"/>
+			<menu_item_check label="Menü „Erweitert“" name="Show Advanced Menu"/>
 		</menu>
 		<menu_item_call label="Teleport nach Hause" name="Teleport Home"/>
 		<menu_item_call label="Hier als Zuhause wählen" name="Set Home to Here"/>
@@ -123,7 +130,6 @@
 		<menu_item_check label="Hinweise aktivieren" name="Enable Hints"/>
 	</menu>
 	<menu label="Erweitert" name="Advanced">
-		<menu_item_call label="Animation meines Avatars stoppen" name="Stop Animating My Avatar"/>
 		<menu_item_call label="Textur neu laden" name="Rebake Texture"/>
 		<menu_item_call label="UI-Größe auf Standard setzen" name="Set UI Size to Default"/>
 		<menu_item_call label="Fenstergröße einstellen..." name="Set Window Size..."/>
@@ -178,8 +184,7 @@
 			<menu_item_check label="Suchen" name="Search"/>
 			<menu_item_call label="Tasten freigeben" name="Release Keys"/>
 			<menu_item_call label="UI-Größe auf Standard setzen" name="Set UI Size to Default"/>
-			<menu_item_check label="Immer rennen" name="Always Run"/>
-			<menu_item_check label="Fliegen" name="Fly"/>
+			<menu_item_check label="Erweitert-Menü anzeigen - veraltetet" name="Show Advanced Menu - legacy shortcut"/>
 			<menu_item_call label="Fenster schließen" name="Close Window"/>
 			<menu_item_call label="Alle Fenster schließen" name="Close All Windows"/>
 			<menu_item_call label="Foto auf Datenträger" name="Snapshot to Disk"/>
@@ -197,7 +202,6 @@
 			<menu_item_call label="Hineinzoomen" name="Zoom In"/>
 			<menu_item_call label="Zoom-Standard" name="Zoom Default"/>
 			<menu_item_call label="Wegzoomen" name="Zoom Out"/>
-			<menu_item_check label="Menü „Erweitert“ anzeigen" name="Show Advanced Menu"/>
 		</menu>
 		<menu_item_call label="Debug-Einstellungen anzeigen" name="Debug Settings"/>
 		<menu_item_check label="Menü „Entwickler“ anzeigen" name="Debug Mode"/>
@@ -312,8 +316,7 @@
 			<menu_item_call label="Ausgewählte Objektinfo drucken" name="Print Selected Object Info"/>
 			<menu_item_call label="Agent-Info drucken" name="Print Agent Info"/>
 			<menu_item_call label="Speicher-Stats" name="Memory Stats"/>
-			<menu_item_check label="Doppelklicken: Auto-Pilot" name="Double-ClickAuto-Pilot"/>
-			<menu_item_check label="Doppelklicken: Teleport" name="DoubleClick Teleport"/>
+			<menu_item_check label="Regions-Debug-Konsole" name="Region Debug Console"/>
 			<menu_item_check label="Fehler in SelectMgr beseitigen" name="Debug SelectMgr"/>
 			<menu_item_check label="Fehler in Klicks beseitigen" name="Debug Clicks"/>
 			<menu_item_check label="Debug-Ansichten" name="Debug Views"/>
@@ -325,8 +328,6 @@
 		<menu label="XUI" name="XUI">
 			<menu_item_call label="Farbeinstellungen neu laden" name="Reload Color Settings"/>
 			<menu_item_call label="Schriftarttest anzeigen" name="Show Font Test"/>
-			<menu_item_call label="Von XML laden" name="Load from XML"/>
-			<menu_item_call label="Als XML speichern" name="Save to XML"/>
 			<menu_item_check label="XUI-Namen anzeigen" name="Show XUI Names"/>
 			<menu_item_call label="Test-IMs senden" name="Send Test IMs"/>
 			<menu_item_call label="Namen-Cache leeren" name="Flush Names Caches"/>
@@ -366,9 +367,9 @@
 		<menu_item_call label="Bilder komprimieren" name="Compress Images"/>
 		<menu_item_check label="Ausgabe Fehlerbeseitigung ausgeben" name="Output Debug Minidump"/>
 		<menu_item_check label="Bei nächster Ausführung Fenster öffnen" name="Console Window"/>
-		<menu_item_check label="Admin-Menü anzeigen" name="View Admin Options"/>
 		<menu_item_call label="Admin-Status anfordern" name="Request Admin Options"/>
 		<menu_item_call label="Admin-Status verlassen" name="Leave Admin Options"/>
+		<menu_item_check label="Admin-Menü anzeigen" name="View Admin Options"/>
 	</menu>
 	<menu label="Admin" name="Admin">
 		<menu label="Object">
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index c2ca0c2fb032a1c2d7fca38c81cfafda561f856a..06cc02cd847a5181d9ec94da8d9bbffe6b9310b7 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -395,6 +395,9 @@ Hinweis: Der Cache wird dabei gelöscht/geleert.
 	<notification name="ChangeSkin">
 		Die neue Benutzeroberfläche wird nach einem Neustart von [APP_NAME] angezeigt.
 	</notification>
+	<notification name="ChangeLanguage">
+		Die Sprachänderung tritt nach Neustart von [APP_NAME] in Kraft.
+	</notification>
 	<notification name="GoToAuctionPage">
 		Zur [SECOND_LIFE]-Webseite, um Auktionen anzuzeigen oder ein Gebot abzugeben?
 		<url name="url">
@@ -605,6 +608,10 @@ Erwartet wurde [VALIDS]
 	</notification>
 	<notification name="SoundFileInvalidHeader">
 		„Daten“-Chunk in WAV-Header nicht gefunden:
+[FILE]
+	</notification>
+	<notification name="SoundFileInvalidChunkSize">
+		Falsche Chunk-Größe in WAV-Datei:
 [FILE]
 	</notification>
 	<notification name="SoundFileInvalidTooLong">
@@ -1343,6 +1350,15 @@ Dieses Update ist nicht erforderlich, für bessere Leistung und Stabilität soll
 In Ihren Anwendungsordner herunterladen?
 		<usetemplate name="okcancelbuttons" notext="Weiter" yestext="Herunterladen"/>
 	</notification>
+	<notification name="FailedUpdateInstall">
+		Beim Installieren des Viewer-Updates ist ein Fehler aufgetreten.
+Laden Sie den neuesten Viewer von http://secondlife.com/download herunter und installieren Sie ihn.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="DownloadBackground">
+		Eine aktualisierte Version von [APP_NAME] wurde heruntergeladen.
+Sie wird beim nächsten Neustart von [APP_NAME] verwendet.
+	</notification>
 	<notification name="DeedObjectToGroup">
 		Bei Übertragung dieses Objekts erhält die Gruppe:
 * An das Objekt bezahlte L$
@@ -2481,8 +2497,8 @@ Versuchen Sie es in einigen Minuten erneut.
 		Ihr Freundschaftsangebot wurde abgelehnt.
 	</notification>
 	<notification name="OfferCallingCard">
-		[FIRST] [LAST] bietet Ihnen ihre/seine Visitenkarte an.
-Ihrem Inventar wird ein Lesezeichen erstellt, damit Sie diesem Einwohner einfach eine IM schicken können.
+		[NAME] bietet Ihnen eine Visitenkarte an.
+In Ihrem Inventar wird ein Lesezeichen erstellt, damit Sie diesem Einwohner schnell IMs senden können.
 		<form name="form">
 			<button name="Accept" text="Akzeptieren"/>
 			<button name="Decline" text="Ablehnen"/>
diff --git a/indra/newview/skins/default/xui/de/panel_edit_gloves.xml b/indra/newview/skins/default/xui/de/panel_edit_gloves.xml
index ad87e432d6b6bd0f6d411f889c523f882ead8ade..fb7d18f66cfb79e8247387dad7d3a1348236f0fa 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_gloves.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_gloves_panel">
 	<panel name="avatar_gloves_color_panel">
-		<texture_picker label="Stoff" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+		<texture_picker label="Textur" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
 		<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_edit_jacket.xml b/indra/newview/skins/default/xui/de/panel_edit_jacket.xml
index 8fe76f6225e161a8bc1e044854a9492279a4c767..1b7c1d79a56d2869c3be7f8e010441ce4670ff9e 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_jacket.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_jacket_panel">
 	<panel name="avatar_jacket_color_panel">
-		<texture_picker label="Stoff: oben" name="Upper Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
-		<texture_picker label="Stoff: unten" name="Lower Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+		<texture_picker label="Obere Textur" name="Upper Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+		<texture_picker label="Untere Textur" name="Lower Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
 		<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_edit_pants.xml b/indra/newview/skins/default/xui/de/panel_edit_pants.xml
index d40a27c5fd1e3a4234c6123b29e7b38550219a66..533cf20412e3177dcff8b03a1197a257f6778455 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_pants.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_pants_panel">
 	<panel name="avatar_pants_color_panel">
-		<texture_picker label="Stoff" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+		<texture_picker label="Textur" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
 		<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_edit_profile.xml b/indra/newview/skins/default/xui/de/panel_edit_profile.xml
index 7f6054dd608e3d5d564f34f0dc423f1f46d85b1a..be124050e89dbe79dd5f456611582b434314569f 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_profile.xml
@@ -54,7 +54,7 @@
 				<text name="my_account_link" value="[[URL] Meine Startseite aufrufen]"/>
 				<text name="title_partner_text" value="Mein Partner:"/>
 				<panel name="partner_data_panel">
-					<text initial_value="(wird in Datenbank gesucht)" name="partner_text" value="[FIRST] [LAST]"/>
+					<text initial_value="(wird in Datenbank gesucht)" name="partner_text"/>
 				</panel>
 				<text name="partner_edit_link" value="[[URL] bearbeiten]"/>
 			</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_edit_shirt.xml b/indra/newview/skins/default/xui/de/panel_edit_shirt.xml
index 344b0b412a1a7dbaacad5f646dee4fce2e2d9ae3..4f140a2b018befa477388d3731135600c409042b 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_shirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_shirt_panel">
 	<panel name="avatar_shirt_color_panel">
-		<texture_picker label="Stoff" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+		<texture_picker label="Textur" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
 		<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_edit_shoes.xml b/indra/newview/skins/default/xui/de/panel_edit_shoes.xml
index 56aee5d0fed3e68bae3c7d4041338f697ec6cc13..abedb8d89e12b080a42b3d73d30c96f155d639e7 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_shoes.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_shoes_panel">
 	<panel name="avatar_shoes_color_panel">
-		<texture_picker label="Stoff" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+		<texture_picker label="Textur" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
 		<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_edit_skirt.xml b/indra/newview/skins/default/xui/de/panel_edit_skirt.xml
index c8931bc9472e05ce9224a47445ee049f2e7fe2d5..07ce8a7436a14c3705f1c980cbba52630b119cde 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_skirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_skirt_panel">
 	<panel name="avatar_skirt_color_panel">
-		<texture_picker label="Stoff" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+		<texture_picker label="Textur" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
 		<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_edit_socks.xml b/indra/newview/skins/default/xui/de/panel_edit_socks.xml
index abbeefa44efb1de5844c3d8dcff0f219a7c8b3d7..4e72b63f49124116ed8fecc77c900c57e505bedd 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_socks.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_socks_panel">
 	<panel name="avatar_socks_color_panel">
-		<texture_picker label="Stoff" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+		<texture_picker label="Textur" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
 		<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_edit_underpants.xml b/indra/newview/skins/default/xui/de/panel_edit_underpants.xml
index 03c61a495ddc5a9a04b8d533b5331f2b5770f94b..1fad0ccedb1fcbee0ba003404c62aef6da5f42fe 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_underpants.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_underpants_panel">
 	<panel name="avatar_underpants_color_panel">
-		<texture_picker label="Stoff" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+		<texture_picker label="Textur" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
 		<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/de/panel_edit_undershirt.xml
index 39919393e1ee794eb196debd7afe3734c3dfc4b4..9d193ffedb0e442949e624df602175b0eb3c45cc 100644
--- a/indra/newview/skins/default/xui/de/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/de/panel_edit_undershirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_undershirt_panel">
 	<panel name="avatar_undershirt_color_panel">
-		<texture_picker label="Stoff" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
+		<texture_picker label="Textur" name="Fabric" tool_tip="Zum Auswählen eines Bildes hier klicken"/>
 		<color_swatch label="Farbe/Ton" name="Color/Tint" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/de/panel_notify_textbox.xml b/indra/newview/skins/default/xui/de/panel_notify_textbox.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7187be570ce0e2cc3b503be99a56d28bda08b433
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_notify_textbox.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="instant_message" name="panel_notify_textbox">
+	<string name="message_max_lines_count" value="7"/>
+	<panel label="info_panel" name="info_panel">
+		<text_editor name="message" value="message"/>
+		parse_urls=&quot;false&quot;
+		<button label="Senden" name="btn_submit"/>
+	</panel>
+	<panel label="control_panel" name="control_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_people.xml b/indra/newview/skins/default/xui/de/panel_people.xml
index 6c859da4d6b86f4691748dbb96cdb4d1775690b0..99e0b933b8648dbbbc9197979c56dfa7aaec3ccc 100644
--- a/indra/newview/skins/default/xui/de/panel_people.xml
+++ b/indra/newview/skins/default/xui/de/panel_people.xml
@@ -22,7 +22,7 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].
 	<tab_container name="tabs">
 		<panel label="IN DER NÄHE" name="nearby_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="nearby_view_sort_btn" tool_tip="Optionen"/>
+				<menu_button name="nearby_view_sort_btn" tool_tip="Optionen"/>
 				<button name="add_friend_btn" tool_tip="Ausgewählten Einwohner zur Freundeliste hinzufügen"/>
 			</panel>
 		</panel>
@@ -34,27 +34,27 @@ Sie suchen nach Leuten? Verwenden Sie die [secondlife:///app/worldmap Karte].
 			<panel label="bottom_panel" name="bottom_panel">
 				<layout_stack name="bottom_panel">
 					<layout_panel name="options_gear_btn_panel">
-						<button name="friends_viewsort_btn" tool_tip="Zusätzliche Optionen anzeigen"/>
+						<menu_button name="friends_viewsort_btn" tool_tip="Zusätzliche Optionen anzeigen"/>
 					</layout_panel>
 					<layout_panel name="add_btn_panel">
 						<button name="add_btn" tool_tip="Bieten Sie einem Einwohner die Freundschaft an"/>
 					</layout_panel>
 					<layout_panel name="trash_btn_panel">
-						<dnd_button name="trash_btn" tool_tip="Ausgewählte Person von Ihrer Freundesliste entfernen"/>
+						<dnd_button name="del_btn" tool_tip="Ausgewählte Person aus Ihrer Freundesliste entfernen"/>
 					</layout_panel>
 				</layout_stack>
 			</panel>
 		</panel>
 		<panel label="MEINE GRUPPEN" name="groups_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="groups_viewsort_btn" tool_tip="Optionen"/>
+				<menu_button name="groups_viewsort_btn" tool_tip="Optionen"/>
 				<button name="plus_btn" tool_tip="Gruppe beitreten/Neue Gruppe erstellen"/>
 				<button name="activate_btn" tool_tip="Ausgewählte Gruppe aktivieren"/>
 			</panel>
 		</panel>
 		<panel label="AKTUELL" name="recent_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="recent_viewsort_btn" tool_tip="Optionen"/>
+				<menu_button name="recent_viewsort_btn" tool_tip="Optionen"/>
 				<button name="add_friend_btn" tool_tip="Ausgewählten Einwohner zur Freundeliste hinzufügen"/>
 			</panel>
 		</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_places.xml b/indra/newview/skins/default/xui/de/panel_places.xml
index 0e85829a0b263fef043feb247e5cb97a5ce96b62..36c77d4fe1023747b71a4136b805927e48709187 100644
--- a/indra/newview/skins/default/xui/de/panel_places.xml
+++ b/indra/newview/skins/default/xui/de/panel_places.xml
@@ -21,7 +21,7 @@
 						<button label="Bearbeiten" name="edit_btn" tool_tip="Landmarken-Info bearbeiten"/>
 					</layout_panel>
 					<layout_panel name="overflow_btn_lp">
-						<button label="▼" name="overflow_btn" tool_tip="Zusätzliche Optionen anzeigen"/>
+						<menu_button label="▼" name="overflow_btn" tool_tip="Zusätzliche Optionen anzeigen"/>
 					</layout_panel>
 				</layout_stack>
 				<layout_stack name="bottom_bar_ls3">
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml
index 7b6918ae24432b792d3548b76d640d4dcfad01db..0a596f2b2536b22b4abc47c109f9d31c3a2572b0 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_advanced.xml
@@ -3,35 +3,16 @@
 	<panel.string name="aspect_ratio_text">
 		[NUM]:[DEN]
 	</panel.string>
-	<panel.string name="middle_mouse">
-		Mittlere Maustaste
-	</panel.string>
-	<slider label="Sichtwinkel" name="camera_fov"/>
-	<slider label="Abstand" name="camera_offset_scale"/>
-	<text name="heading2">
-		Automatische Position für:
-	</text>
-	<check_box label="Bauen/Bearbeiten" name="edit_camera_movement" tool_tip="Automatische Kamerapositionierung bei Wechsel in und aus dem Bearbeitungsmodus verwenden"/>
-	<check_box label="Aussehen" name="appearance_camera_movement" tool_tip="Automatische Kamerapositionierung im Bearbeitenmodus verwenden"/>
-	<check_box initial_value="true" label="Seitenleiste" name="appearance_sidebar_positioning" tool_tip="Automatische Kameraposition für Seitenleiste verwenden"/>
-	<check_box label="Mich im Mouselook anzeigen" name="first_person_avatar_visible"/>
-	<check_box label="Mit Pfeiltasten bewegen" name="arrow_keys_move_avatar_check"/>
-	<check_box label="2-mal-drücken-halten, um zu rennen" name="tap_tap_hold_to_run"/>
-	<check_box label="Avatarlippen beim Sprechen bewegen" name="enable_lip_sync"/>
-	<check_box label="Blasen-Chat" name="bubble_text_chat"/>
-	<slider label="Deckkraft" label_width="66" name="bubble_chat_opacity"/>
-	<color_swatch left_pad="35" name="background" tool_tip="Farbe für Blasen-Chat auswählen"/>
 	<text name="UI Size:">
-		UI-Größe
+		UI-Größe:
 	</text>
 	<check_box label="Skript-Fehler anzeigen:" name="show_script_errors"/>
 	<radio_group name="show_location">
 		<radio_item label="Chat in der Nähe" name="0"/>
 		<radio_item label="Getrenntes Fenster" name="1"/>
 	</radio_group>
-	<check_box label="Sprachfunktion ein-/ausschalten, wenn gedrückt wird:" name="push_to_talk_toggle_check" tool_tip="Wenn der Umschaltmodus aktiviert ist, drücken Sie die Auslöse-Taste EINMAL, um Ihr Mikrofon an oder aus zu stellen. Wenn der Umschaltmodus nicht motiviert ist, ist das Mikro nur dann eingeschaltet, wenn Sie die Auslösetaste gedrückt halten."/>
-	<line_editor label="Auslöser für Zum-Sprechen-drücken:" name="modifier_combo"/>
-	<button label="Taste festlegen" name="set_voice_hotkey_button"/>
-	<button label="Mittlere Maustaste" name="set_voice_middlemouse_button" tool_tip="Auf mittlere Maustaste zurücksetzen"/>
-	<button label="Andere Geräte" name="joystick_setup_button"/>
+	<check_box label="Mehrere Viewer zulassen" name="allow_multiple_viewer_check"/>
+	<check_box label="Bei Anmeldung Rasterauswahl anzeigen" name="show_grid_selection_check"/>
+	<check_box label="Menü „Erweitert“ anzeigen" name="show_advanced_menu_check"/>
+	<check_box label="Menü „Entwickler“ anzeigen" name="show_develop_menu_check"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
index aa314a1a579d2686ff7b4e30d7c8da922e34b8c1..8086128dd75d71335ac1145abc91ea72de96c48f 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_chat.xml
@@ -8,44 +8,10 @@
 		<radio_item label="Mittel" name="radio2" value="1"/>
 		<radio_item label="Groß" name="radio3" value="2"/>
 	</radio_group>
-	<text name="font_colors">
-		Schriftfarben:
-	</text>
-	<color_swatch label="Sie" name="user"/>
-	<text name="text_box1">
-		Ich
-	</text>
-	<color_swatch label="Andere" name="agent"/>
-	<text name="text_box2">
-		Andere
-	</text>
-	<color_swatch label="IM" name="im"/>
-	<text name="text_box3">
-		IM
-	</text>
-	<color_swatch label="System" name="system"/>
-	<text name="text_box4">
-		System
-	</text>
-	<color_swatch label="Skriptfehler" name="script_error"/>
-	<text name="text_box5">
-		Skriptfehler
-	</text>
-	<color_swatch label="Objekte" name="objects"/>
-	<text name="text_box6">
-		Objekte
-	</text>
-	<color_swatch label="Eigentümer" name="owner"/>
-	<text name="text_box7">
-		Eigentümer
-	</text>
-	<color_swatch label="URLs" name="links"/>
-	<text name="text_box9">
-		URLs
-	</text>
 	<check_box initial_value="true" label="Beim Chatten Tippanimation abspielen" name="play_typing_animation"/>
 	<check_box label="IMs per Email zuschicken, wenn ich offline bin" name="send_im_to_email"/>
 	<check_box label="Kompakten IM- und Text-Chatverlauf aktivieren" name="plain_text_chat_history"/>
+	<check_box label="Blasen-Chat" name="bubble_text_chat"/>
 	<text name="show_ims_in_label">
 		IMs anzeigen in:
 	</text>
@@ -56,6 +22,13 @@
 		<radio_item label="Getrennte Fenster" name="radio" value="0"/>
 		<radio_item label="Registerkarten" name="radio2" value="1"/>
 	</radio_group>
+	<text name="disable_toast_label">
+		Popups für eingehende Chats aktivieren:
+	</text>
+	<check_box label="Gruppen-Chats" name="EnableGroupChatPopups" tool_tip="Markieren, um Popups zu sehen, wenn Gruppen-Chat-Message eintrifft"/>
+	<check_box label="IM-Chats" name="EnableIMChatPopups" tool_tip="Markieren, um Popups zu sehen, wenn Instant Message eintrifft"/>
+	<spinner label="Lebenszeit von Toasts für Chat in der Nähe:" name="nearby_toasts_lifetime"/>
+	<spinner label="Ein-/Ausblenddauer von Toasts für Chat in der Nähe:" name="nearby_toasts_fadingtime"/>
 	<check_box label="Bei Chat Maschinenübersetzung verwenden (Service von Google)" name="translate_chat_checkbox"/>
 	<text name="translate_language_text">
 		Chat übersetzen in:
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_colors.xml b/indra/newview/skins/default/xui/de/panel_preferences_colors.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d9e5c7f2b56d1cad67231cd496d2e2ca782c8fb1
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_preferences_colors.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Farben" name="colors_panel">
+	<text name="effects_color_textbox">
+		Meine Effekte (Auswahlstrahl):
+	</text>
+	<color_swatch name="effect_color_swatch" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
+	<text name="font_colors">
+		Schriftfarben für Chat:
+	</text>
+	<text name="text_box1">
+		Ich
+	</text>
+	<text name="text_box2">
+		Andere
+	</text>
+	<text name="text_box3">
+		Objekte
+	</text>
+	<text name="text_box4">
+		System
+	</text>
+	<text name="text_box5">
+		Fehler
+	</text>
+	<text name="text_box7">
+		Eigentümer
+	</text>
+	<text name="text_box9">
+		URLs
+	</text>
+	<text name="bubble_chat">
+		Hintergrund für Blasen-Chat:
+	</text>
+	<color_swatch name="background" tool_tip="Farbe für Blasen-Chat auswählen"/>
+	<slider label="Deckkraft:" name="bubble_chat_opacity"/>
+	<text name="floater_opacity">
+		Floater-Deckkraft:
+	</text>
+	<slider label="Aktiv:" name="active"/>
+	<slider label="Inaktiv:" name="inactive"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_general.xml b/indra/newview/skins/default/xui/de/panel_preferences_general.xml
index 8492d36bc7a0b77a4105efeef9d4553227f78502..79b2a544f95fd5bb04cb77c0fa223103ce3bcd29 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_general.xml
@@ -48,13 +48,18 @@
 	<check_box label="Benutzernamen" name="show_slids" tool_tip="Benutzernamen wie berndschmidt123 anzeigen"/>
 	<check_box label="Gruppentitel" name="show_all_title_checkbox1" tool_tip="Gruppentitel wie „Vorstand“ oder „Mitglied“"/>
 	<check_box label="Freunde hervorheben" name="show_friends" tool_tip="Avatarnamen Ihrer Freunde hervorheben"/>
-	<text name="effects_color_textbox">
-		Meine Effekte:
+	<check_box label="Anzeigenamen anzeigen" name="display_names_check" tool_tip="Aktivieren Sie diese Option, um Anzeigenamen in Chat, IM, Avatarnamen usw. zu verwenden."/>
+	<check_box label="Viewer-UI-Tipps aktivieren" name="viewer_hints_check"/>
+	<text name="inworld_typing_rg_label">
+		Drücken von Buchstabentasten:
 	</text>
+	<radio_group name="inworld_typing_preference">
+		<radio_item label="Startet lokalen Chat" name="radio_start_chat" value="1"/>
+		<radio_item label="Beeinflusst Bewegung (z. B. WASD)" name="radio_move" value="0"/>
+	</radio_group>
 	<text name="title_afk_text">
 		Zeit bis zur Abwesenheit:
 	</text>
-	<color_swatch label="" name="effect_color_swatch" tool_tip="Klicken Sie hier, um die Farbauswahl zu öffnen"/>
 	<combo_box label="Timeout für Abwesenheit:" name="afk">
 		<combo_box.item label="2 Minuten" name="item0"/>
 		<combo_box.item label="5 Minuten" name="item1"/>
@@ -62,7 +67,6 @@
 		<combo_box.item label="30 Minuten" name="item3"/>
 		<combo_box.item label="nie" name="item4"/>
 	</combo_box>
-	<check_box label="Anzeigenamen anzeigen" name="display_names_check" tool_tip="Aktivieren Sie diese Option, um Anzeigenamen in Chat, IM, Avatarnamen usw. zu verwenden."/>
 	<text name="text_box3">
 		Antwort, wenn im „Beschäftigt“-Modus:
 	</text>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
index ae3c791ab90c30eb2332ecd45c690280af76fc65..63161c954eaf4c71d5b8e8a90efceba8cf915f2b 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_graphics1.xml
@@ -25,6 +25,7 @@
 		<text name="ShadersText">
 			Shader:
 		</text>
+		<check_box initial_value="true" label="Transparentes Wasser" name="TransparentWater"/>
 		<check_box initial_value="true" label="Bumpmapping und Glanz" name="BumpShiny"/>
 		<check_box initial_value="true" label="Einfache Shader" name="BasicShaders" tool_tip="Deaktivieren Sie diese Option, wenn der Grafikkartentreiber Abstürze verursacht"/>
 		<check_box initial_value="true" label="Atmosphären-Shader" name="WindLightUseAtmosShaders"/>
@@ -46,7 +47,7 @@
 		<slider label="Max. Anzahl an voll dargestellten Avataren:" name="MaxNumberAvatarDrawn"/>
 		<slider label="Post-Processing-Qualität:" name="RenderPostProcess"/>
 		<text name="MeshDetailText">
-			Gitterdetails:
+			Darstellungsgrad:
 		</text>
 		<slider label="   Objekte:" name="ObjectMeshDetail"/>
 		<slider label="   Flexiprimitiva:" name="FlexibleMeshDetail"/>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_move.xml b/indra/newview/skins/default/xui/de/panel_preferences_move.xml
new file mode 100644
index 0000000000000000000000000000000000000000..fb749a16d7da8fef9f225128ab8a088f7f4c5a46
--- /dev/null
+++ b/indra/newview/skins/default/xui/de/panel_preferences_move.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Bewegen" name="move_panel">
+	<slider label="Sichtwinkel" name="camera_fov"/>
+	<slider label="Abstand" name="camera_offset_scale"/>
+	<text name="heading2">
+		Automatische Position für:
+	</text>
+	<check_box label="Bauen/Bearbeiten" name="edit_camera_movement" tool_tip="Automatische Kamerapositionierung bei Wechsel in und aus dem Bearbeitungsmodus verwenden"/>
+	<check_box label="Aussehen" name="appearance_camera_movement" tool_tip="Automatische Kamerapositionierung im Bearbeitenmodus verwenden"/>
+	<check_box initial_value="true" label="Seitenleiste" name="appearance_sidebar_positioning" tool_tip="Automatische Kameraposition für Seitenleiste verwenden"/>
+	<check_box label="Mich im Mouselook anzeigen" name="first_person_avatar_visible"/>
+	<text name=" Mouse Sensitivity">
+		Mausempfindlichkeit für Mouselook:
+	</text>
+	<check_box label="Umkehren" name="invert_mouse"/>
+	<check_box label="Mit Pfeiltasten bewegen" name="arrow_keys_move_avatar_check"/>
+	<check_box label="Drücken-drücken-halten, um zu rennen" name="tap_tap_hold_to_run"/>
+	<check_box label="Doppelklicken:" name="double_click_chkbox"/>
+	<radio_group name="double_click_action">
+		<radio_item label="Teleportieren" name="radio_teleport"/>
+		<radio_item label="Autopilot" name="radio_autopilot"/>
+	</radio_group>
+	<button label="Andere Geräte" name="joystick_setup_button"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml
index 42a625fbf61d1c9b18c8ad85a5bf4e906e482a70..d78064833b7a207b3de7715f74ed01fb2a54279a 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_privacy.xml
@@ -10,16 +10,19 @@
 	<check_box label="Nur Freunde und Gruppen wissen, dass ich online bin" name="online_visibility"/>
 	<check_box label="Nur Freunde und Gruppen können mich anrufen oder mir eine IM schicken" name="voice_call_friends_only_check"/>
 	<check_box label="Mikrofon ausschalten, wenn Anrufe beendet werden" name="auto_disengage_mic_check"/>
-	<check_box label="Cookies annehmen" name="cookies_enabled"/>
 	<text name="Logs:">
-		Protokolle:
+		Chatprotokolle:
 	</text>
 	<check_box label="Protokolle von Gesprächen in der Nähe auf meinem Computer speichern" name="log_nearby_chat"/>
 	<check_box label="IM Protokolle auf meinem Computer speichern" name="log_instant_messages"/>
-	<check_box label="Zeitstempel hinzufügen" name="show_timestamps_check_im"/>
+	<check_box label="Zeitstempel zu jeder Zeile im Chatprotokoll hinzufügen" name="show_timestamps_check_im"/>
+	<check_box label="Datumsstempel zu Protokolldateinamen hinzufügen" name="logfile_name_datestamp"/>
 	<text name="log_path_desc">
 		Protokolle speichern in:
 	</text>
 	<button label="Durchsuchen" label_selected="Durchsuchen" name="log_path_button"/>
 	<button label="Ignorierte Einwohner/Objekte" name="block_list" width="180"/>
+	<text name="block_list_label">
+		(Personen und/oder Objekte, die Sie blockiert haben)
+	</text>
 </panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
index 140b1ce7a4ac66360af5dea1ff8e8a66f494d577..c4d095dde5f683ef4271106c80f00a085f6db1d2 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_setup.xml
@@ -1,12 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Hardware/Internet" name="Input panel">
-	<text name="Mouselook:">
-		Mouselook:
-	</text>
-	<text name=" Mouse Sensitivity">
-		Mausempfindlichkeit:
-	</text>
-	<check_box label="Umkehren" name="invert_mouse"/>
 	<text name="Network:">
 		Netzwerk:
 	</text>
@@ -46,4 +39,5 @@
 	</text>
 	<line_editor name="web_proxy_editor" tool_tip="Name oder IP Adresse des Proxyservers, den Sie benutzen möchten"/>
 	<spinner label="Portnummer:" name="web_proxy_port"/>
+	<check_box initial_value="true" label="Updates für [APP_NAME] automatisch herunterladen und installieren" name="updater_service_active"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/de/panel_preferences_sound.xml b/indra/newview/skins/default/xui/de/panel_preferences_sound.xml
index 5c71b20fb02b79c2d67f1be649c48c3d3758674e..26674ea5948839c3dd27685a4a3b418969fbad77 100644
--- a/indra/newview/skins/default/xui/de/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/de/panel_preferences_sound.xml
@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Sounds" name="Preference Media panel">
+	<panel.string name="middle_mouse">
+		Mittlere Maustaste
+	</panel.string>
 	<slider label="Master-Lautstärke" name="System Volume"/>
 	<check_box initial_value="true" label="Stummschalten, wenn minimiert" name="mute_when_minimized"/>
 	<slider label="Schaltflächen" name="UI Volume"/>
@@ -23,6 +26,11 @@
 		<radio_item label="Kameraposition" name="0"/>
 		<radio_item label="Avatarposition" name="1"/>
 	</radio_group>
+	<check_box label="Avatarlippen beim Sprechen bewegen" name="enable_lip_sync"/>
+	<check_box label="Sprachfunktion beim Drücken folgender Taste(n) ein-/ausschalten:" name="push_to_talk_toggle_check" tool_tip="Wenn der Umschaltmodus aktiviert ist, drücken Sie die Auslöse-Taste EINMAL, um Ihr Mikrofon ein- oder auszuschalten. Wenn der Umschaltmodus nicht aktiviert ist, ist das Mikrofon nur dann eingeschaltet, wenn Sie die Auslösetaste gedrückt halten."/>
+	<line_editor label="Auslöser für Zum-Sprechen-drücken:" name="modifier_combo"/>
+	<button label="Taste festlegen" name="set_voice_hotkey_button"/>
+	<button name="set_voice_middlemouse_button" tool_tip="Auf mittlere Maustaste zurücksetzen"/>
 	<button label="Eingabe-/Ausgabegeräte" name="device_settings_btn"/>
 	<panel label="Geräte-Einstellungen" name="device_settings_panel">
 		<panel.string name="default_text">
diff --git a/indra/newview/skins/default/xui/de/panel_profile.xml b/indra/newview/skins/default/xui/de/panel_profile.xml
index 40fa2f922a13ab2f0a3c04a28933391e05de2d33..938631f65d398e115556259551a709010b66f3a9 100644
--- a/indra/newview/skins/default/xui/de/panel_profile.xml
+++ b/indra/newview/skins/default/xui/de/panel_profile.xml
@@ -57,7 +57,7 @@
 					<button label="Teleportieren" name="teleport" tool_tip="Teleport anbieten"/>
 				</layout_panel>
 				<layout_panel name="overflow_btn_lp">
-					<button label="â–¼" name="overflow_btn" tool_tip="Dem Einwohner Geld geben oder Inventar an den Einwohner schicken"/>
+					<menu_button label="â–¼" name="overflow_btn" tool_tip="Dem Einwohner Geld geben oder Inventar an den Einwohner schicken"/>
 				</layout_panel>
 			</layout_stack>
 		</layout_panel>
diff --git a/indra/newview/skins/default/xui/de/panel_script_ed.xml b/indra/newview/skins/default/xui/de/panel_script_ed.xml
index 17970cf2613b23eb23d49f84589ca251e17fe70d..73789f06d808fd186967dd5cff3ad7cf712ba9bd 100644
--- a/indra/newview/skins/default/xui/de/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/de/panel_script_ed.xml
@@ -15,11 +15,6 @@
 	<panel.string name="Title">
 		Skript: [NAME]
 	</panel.string>
-	<text_editor name="Script Editor">
-		Wird geladen...
-	</text_editor>
-	<button label="Speichern" label_selected="Speichern" name="Save_btn"/>
-	<combo_box label="Einfügen..." name="Insert..."/>
 	<menu_bar name="script_menu">
 		<menu label="Datei" name="File">
 			<menu_item_call label="Speichern" name="Save"/>
@@ -40,4 +35,10 @@
 			<menu_item_call label="Schlüsselwort-Hilfe" name="Keyword Help..."/>
 		</menu>
 	</menu_bar>
+	<text_editor name="Script Editor">
+		Wird geladen...
+	</text_editor>
+	<combo_box label="Einfügen..." name="Insert..."/>
+	<button label="Speichern" label_selected="Speichern" name="Save_btn"/>
+	<button label="Bearbeiten..." name="Edit_btn"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/de/strings.xml b/indra/newview/skins/default/xui/de/strings.xml
index f890506a5dd814247edb1599235cf16a24a55d54..e4676194aa8b0112e6b0ddc0f21c35af5643f868 100644
--- a/indra/newview/skins/default/xui/de/strings.xml
+++ b/indra/newview/skins/default/xui/de/strings.xml
@@ -1773,11 +1773,8 @@
 	<string name="InvOfferGaveYou">
 		hat Ihnen folgendes übergeben
 	</string>
-	<string name="InvOfferYouDecline">
-		Sie lehnen folgendes ab:
-	</string>
-	<string name="InvOfferFrom">
-		von
+	<string name="InvOfferDecline">
+		Sie lehnen [DESC] von &lt;nolink&gt;[NAME]&lt;/nolink&gt; ab.
 	</string>
 	<string name="GroupMoneyTotal">
 		Gesamtbetrag
diff --git a/indra/newview/skins/default/xui/en/floater_buy_currency.xml b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
index cd5922a9a29a4bbd1d96d8f1df1f6ee3931853ee..49deb9b025d4b08dd0735023d46658759e617730 100644
--- a/indra/newview/skins/default/xui/en/floater_buy_currency.xml
+++ b/indra/newview/skins/default/xui/en/floater_buy_currency.xml
@@ -20,6 +20,7 @@
      left="0"
      name="normal_background"
      top="17"
+     use_draw_context_alpha="false"
      width="350" />
    <text
      type="string"
@@ -292,6 +293,7 @@ Re-enter amount to see the latest exchange rate.
      left="0"
      name="error_background"
      top="15"
+     use_draw_context_alpha="false"
      width="350"/>
     <text
      type="string"
diff --git a/indra/newview/skins/default/xui/en/floater_env_settings.xml b/indra/newview/skins/default/xui/en/floater_env_settings.xml
index 14f9e2db95e439fbd8e2af0dd76b23761459ab32..8df5e232d91b6d69ce305747334cf039452885cd 100644
--- a/indra/newview/skins/default/xui/en/floater_env_settings.xml
+++ b/indra/newview/skins/default/xui/en/floater_env_settings.xml
@@ -44,6 +44,7 @@
      left="85"
      name="EnvDayCycle"
      top="30"
+     use_draw_context_alpha="false"
      width="200" />
     <slider
      control_name="EnvTimeSlider"
diff --git a/indra/newview/skins/default/xui/en/floater_help_browser.xml b/indra/newview/skins/default/xui/en/floater_help_browser.xml
index 837923bcf606c48dce7a36eb858eda8d2e36e324..02e50ee5844931593ad4894d0777b9f2ceff68c8 100644
--- a/indra/newview/skins/default/xui/en/floater_help_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_help_browser.xml
@@ -36,7 +36,8 @@
          user_resize="false"
          width="620">
             <web_browser
-              trusted_content="true" 
+             trusted_content="true" 
+             initial_mime_type="text/html" 
              bottom="-25"
              follows="left|right|top|bottom"
              layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/floater_media_browser.xml b/indra/newview/skins/default/xui/en/floater_media_browser.xml
index 49e835cce4d8cb1b79b7dcc3331ee8f19d8fddad..43729d7c9fd0da284a6a19b7e50fb6932f270cc9 100644
--- a/indra/newview/skins/default/xui/en/floater_media_browser.xml
+++ b/indra/newview/skins/default/xui/en/floater_media_browser.xml
@@ -101,7 +101,7 @@
              left_pad="5"
              name="go"
              top_delta="0"
-             width="55">
+             width="50">
 				<button.commit_callback
 				function="MediaBrowser.Go" />
 			</button>
diff --git a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
index 4c5113aa5515147144e34a6dbf6b7e7347259b13..ab966dbb0e028b2afa41f02072e883939522edb9 100644
--- a/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/floater_nearby_chat.xml
@@ -2,9 +2,6 @@
 <floater
  border_visible="false"
  border="false"
- bg_opaque_image="Window_Foreground" 
- bg_alpha_image="Window_Background" 
- bg_alpha_image_overlay="DkGray_66" 
  legacy_header_height="18"
  can_minimize="true"
  can_tear_off="false"
diff --git a/indra/newview/skins/default/xui/en/floater_preferences.xml b/indra/newview/skins/default/xui/en/floater_preferences.xml
index 50d0011338b35a9aa22ffd40e5d94058fdc1e6e0..8eee8f44b57dc2be4b019650193a29640791b517 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences.xml
@@ -63,13 +63,6 @@
          layout="topleft"
          help_topic="preferences_display_tab"
          name="display" />
-        <panel
-		 class="panel_preference"
-         filename="panel_preferences_privacy.xml"
-         label="Privacy"
-         layout="topleft"
-         help_topic="preferences_im_tab"
-         name="im" />
         <panel
 		 class="panel_preference"
          filename="panel_preferences_sound.xml"
@@ -84,6 +77,13 @@
          layout="topleft"
          help_topic="preferences_chat_tab"
          name="chat" />
+        <panel
+		 class="panel_preference"
+         filename="panel_preferences_move.xml"
+         label="Move &amp; View"
+         layout="topleft"
+         help_topic="preferences_move_tab"
+         name="move" />
         <panel
 		 class="panel_preference"
          filename="panel_preferences_alerts.xml"
@@ -91,6 +91,20 @@
          layout="topleft"
          help_topic="preferences_msgs_tab"
          name="msgs" />
+        <panel
+		 class="panel_preference"
+         filename="panel_preferences_colors.xml"
+         label="Colors"
+         layout="topleft"
+         help_topic="preferences_im_tab"
+         name="colors" />
+        <panel
+		 class="panel_preference"
+         filename="panel_preferences_privacy.xml"
+         label="Privacy"
+         layout="topleft"
+         help_topic="preferences_im_tab"
+         name="im" />
         <panel
 		 class="panel_preference"
          filename="panel_preferences_setup.xml"
diff --git a/indra/newview/skins/default/xui/en/floater_region_debug_console.xml b/indra/newview/skins/default/xui/en/floater_region_debug_console.xml
new file mode 100644
index 0000000000000000000000000000000000000000..cf95257b0a508d9d5a1e937f4c6ff4a7894cc68e
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_region_debug_console.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+  name="region_debug_console"
+  title="Region Debug"
+  layout="topleft"
+  min_height="300"
+  min_width="300"
+  height="400"
+  width="600"
+  default_tab_group="1">
+  <text_editor
+  left="10"
+   type="string"
+   length="1"
+   follows="left|top|right|bottom"
+   font="Monospace"
+   height="366"
+   width="576"
+   ignore_tab="false"
+   layout="topleft"
+   max_length="65536"
+   name="region_debug_console_output"
+   show_line_numbers="false" 
+   word_wrap="true"
+   track_end="true"
+   read_only="true">
+  </text_editor>
+  <line_editor
+   border_style="line"
+   border_thickness="1"
+   tab_group="1" 
+   follows="left|top|right"
+   font="SansSerif"
+   height="19"
+   layout="topleft"
+   bottom_delta="20"
+   max_length="127"
+   name="region_debug_console_input"
+   top_delta="0"
+   width="576" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml
index f361cb7f8e26639226fa6678826981fdaca3ab45..e70e1eb61b3a05db9c45570b418838b72f10e048 100644
--- a/indra/newview/skins/default/xui/en/floater_tools.xml
+++ b/indra/newview/skins/default/xui/en/floater_tools.xml
@@ -160,7 +160,7 @@
      layout="topleft"
      left="10"
       height="70"
-      top="54"
+      top="59"
      name="focus_radio_group">
         <radio_item
          top_pad="6"
@@ -197,7 +197,7 @@
    <radio_group
       left="10"
       height="70"
-      top="54"
+      top="59"
      layout="topleft"
      name="move_radio_group">
         <radio_item
@@ -931,7 +931,7 @@
 			 height="23"
 			 image_overlay="Edit_Wrench"
 			 layout="topleft"
-			 left_pad="3"
+			 left_pad="13"
 			 name="button set group"
 			 tab_stop="false"
 			 tool_tip="Choose a group to share this object's permissions"
@@ -944,7 +944,7 @@
              name="checkbox share with group"
              tool_tip="Allow all members of the set group to share your modify permissions for this object. You must Deed to enable role restrictions."
              top_pad="10"
-             left="106"
+             left="100"
              width="87" />
             <button
              follows="top|left"
@@ -953,7 +953,7 @@
              label_selected="Deed"
              layout="topleft"
              name="button deed"
-             left_pad="3"
+             left_pad="19"
              tool_tip="Deeding gives this item away with next owner permissions. Group shared objects can be deeded by a group officer."
              width="80" />
             <text
@@ -974,7 +974,7 @@
              layout="topleft"
              name="clickaction"
              width="148"
-             left_pad="0">
+             left_pad="10">
                 <combo_box.item
                  label="Touch  (default)"
                  name="Touch/grab(default)"
@@ -1009,7 +1009,7 @@
              width="100" />
 <!-- NEW SALE TYPE COMBO BOX -->
       <combo_box
-            left_pad="0"
+            left_pad="10"
             layout="topleft"
             follows="left|top"
             allow_text_entry="false"
@@ -1041,7 +1041,7 @@ even though the user gets a free copy.
         decimal_digits="0"
         increment="1"
         top_pad="8"
-        left="108"
+        left="118"
         control_name="Edit Cost"
         name="Edit Cost"
         label="Price: L$"
diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2ad46824c25def60bfef10ca725e16947a4184c4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_web_content.xml
@@ -0,0 +1,190 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+  legacy_header_height="18"
+  can_resize="true"
+  height="440"
+  layout="topleft"
+  min_height="140"
+  min_width="467"
+  name="floater_web_content"
+  help_topic="floater_web_content"
+  save_rect="true"
+  auto_tile="true"
+  title=""
+  initial_mime_type="text/html"
+  width="820">
+  <layout_stack
+    bottom="440"
+    follows="left|right|top|bottom"
+    layout="topleft"
+    left="5"
+    name="stack1"
+    orientation="vertical"
+    top="20"
+    width="810">
+    <layout_panel
+      auto_resize="false"
+      default_tab_group="1"
+      height="22"
+      layout="topleft"
+      left="0"
+      min_height="20"
+      name="nav_controls"
+      top="400"
+      user_resize="false"
+      width="800">
+      <button
+        image_overlay="Arrow_Left_Off"
+		    image_disabled="PushButton_Disabled"
+		    image_disabled_selected="PushButton_Disabled"
+		    image_selected="PushButton_Selected"
+		    image_unselected="PushButton_Off"
+		    hover_glow_amount="0.15"
+        tool_tip="Navigate back"
+        follows="left|top"
+        height="22"
+        layout="topleft"
+        left="1"
+        name="back"
+        top="0"
+        width="22">
+        <button.commit_callback
+          function="WebContent.Back" />
+      </button>
+      <button
+        image_overlay="Arrow_Right_Off"
+		    image_disabled="PushButton_Disabled"
+		    image_disabled_selected="PushButton_Disabled"
+		    image_selected="PushButton_Selected"
+		    image_unselected="PushButton_Off"
+        tool_tip="Navigate forward"
+        follows="left|top"
+        height="22"
+        layout="topleft"
+        left="27"
+        name="forward"
+        top_delta="0"
+        width="22">
+        <button.commit_callback
+          function="WebContent.Forward" />
+      </button>
+      <button
+        image_overlay="Stop_Off"
+		    image_disabled="PushButton_Disabled"
+		    image_disabled_selected="PushButton_Disabled"
+		    image_selected="PushButton_Selected"
+		    image_unselected="PushButton_Off"
+        tool_tip="Stop navigation"
+        enabled="true"
+        follows="left|top"
+        height="22"
+        layout="topleft"
+        left="51"
+        name="stop"
+        top_delta="0"
+        width="22">
+        <button.commit_callback
+          function="WebContent.Stop" />
+      </button>
+      <button
+        image_overlay="Refresh_Off"
+		    image_disabled="PushButton_Disabled"
+		    image_disabled_selected="PushButton_Disabled"
+		    image_selected="PushButton_Selected"
+		    image_unselected="PushButton_Off"
+        tool_tip="Reload page"
+        follows="left|top"
+        height="22"
+        layout="topleft"
+        left="51"
+        name="reload"
+        top_delta="0"
+        width="22">
+        <button.commit_callback
+          function="WebContent.Reload" />
+      </button>
+      <combo_box
+        allow_text_entry="true"
+        follows="left|top|right"
+        tab_group="1"
+        height="22"
+        layout="topleft"
+        left_pad="4"
+        max_chars="1024"
+        name="address"
+        combo_editor.select_on_focus="true"
+        tool_tip="Enter URL here"
+        top_delta="0"
+        width="702">
+        <combo_box.commit_callback
+          function="WebContent.EnterAddress" />
+      </combo_box>
+      <icon
+        name="media_secure_lock_flag"
+        height="16"
+        follows="top|right"
+        image_name="Lock2"
+        layout="topleft"
+        left_delta="656"
+        top_delta="2"
+        visible="false" 
+        tool_tip="Secured Browsing"
+        width="16" />
+      <button
+        image_overlay="ExternalBrowser_Off"
+		    image_disabled="PushButton_Disabled"
+		    image_disabled_selected="PushButton_Disabled"
+		    image_selected="PushButton_Selected"
+		    image_unselected="PushButton_Off"
+        tool_tip="Open current URL in your desktop browser"
+        follows="right|top"
+        enabled="true" 
+        height="22"
+        layout="topleft"
+        name="popexternal"
+        right="800"
+        top_delta="-2"
+        width="22">
+        <button.commit_callback
+          function="WebContent.PopExternal" />
+      </button>
+    </layout_panel>
+    <layout_panel
+      height="40"
+      layout="topleft"
+      left_delta="0"
+      name="external_controls"
+      top_delta="0"
+      user_resize="false"
+      width="540">
+      <web_browser
+        bottom="-22"
+        follows="all"
+        layout="topleft"
+        left="0"
+        name="webbrowser"
+        top="0"/>
+      <text
+        type="string"
+        length="100"
+        follows="bottom|left"
+        height="20"
+        layout="topleft"
+        left_delta="0"
+        name="statusbartext"
+        parse_urls="false"
+        text_color="0.4 0.4 0.4 1" 
+        top_pad="5"
+        width="452"/>
+      <progress_bar
+        color_bar="0.3 1.0 0.3 1"
+        follows="bottom|right"
+        height="16"
+        top_delta="-1"
+        left_pad="24"
+        layout="topleft"
+        name="statusbarprogress"
+        width="64"/>
+    </layout_panel>
+  </layout_stack>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_windlight_options.xml b/indra/newview/skins/default/xui/en/floater_windlight_options.xml
index 85a5be369c45b0d5aac1657bf4dfb42dc663ec2f..249ad95c41d1fc97630427f85315aae98999cdfc 100644
--- a/indra/newview/skins/default/xui/en/floater_windlight_options.xml
+++ b/indra/newview/skins/default/xui/en/floater_windlight_options.xml
@@ -594,6 +594,7 @@
              left_delta="14"
              top_pad="10"
              name="SkyDayCycle"
+             use_draw_context_alpha="false"
              width="148" />
             <slider
              control_name="WLSunAngle"
diff --git a/indra/newview/skins/default/xui/en/main_view.xml b/indra/newview/skins/default/xui/en/main_view.xml
index 520a604bdef47979a2f3f5de46ca4d36c480863d..d9991fcae96339fc9d65d74d10dd65fb678e0950 100644
--- a/indra/newview/skins/default/xui/en/main_view.xml
+++ b/indra/newview/skins/default/xui/en/main_view.xml
@@ -8,6 +8,12 @@
  tab_stop="false" 
  name="main_view"
  width="1024">
+  <panel top="0"
+     follows="all"
+     height="768"
+     mouse_opaque="false"
+     name="login_panel_holder"
+     width="1024"/>
   <layout_stack border_size="0"
                 follows="all"
                 mouse_opaque="false"
@@ -120,7 +126,7 @@
                       user_resize="false"
                       visible="false"
                       width="333"/>
-      </layout_stack>
+      </layout_stack>      
       <panel follows="all"
                     height="500"
                     left="0"
diff --git a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
index 679d5bc82e4582d588fef5630463de6ff410aea4..7fa4cd840a6b0ad30475b078757e23a530786756 100644
--- a/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/en/menu_inventory_gear_default.xml
@@ -16,22 +16,39 @@
     </menu_item_call>
     <menu_item_separator
      layout="topleft" />
-    <menu_item_call
+    <menu_item_check
      label="Sort by Name"
      layout="topleft"
      name="sort_by_name">
         <on_click
          function="Inventory.GearDefault.Custom.Action"
          parameter="sort_by_name" />
-    </menu_item_call>
-    <menu_item_call
+        <on_check
+         function="Inventory.GearDefault.Check"
+         parameter="sort_by_name" />
+    </menu_item_check>
+    <menu_item_check
      label="Sort by Most Recent"
      layout="topleft"
      name="sort_by_recent">
         <on_click
          function="Inventory.GearDefault.Custom.Action"
          parameter="sort_by_recent" />
-    </menu_item_call>
+        <on_check
+         function="Inventory.GearDefault.Check"
+         parameter="sort_by_recent" />         
+    </menu_item_check>
+    <menu_item_check
+     label="Sort System Folders to Top"
+     layout="topleft"
+     name="sort_system_folders_to_top">
+        <on_click
+         function="Inventory.GearDefault.Custom.Action"
+         parameter="sort_system_folders_to_top" />
+        <on_check
+         function="Inventory.GearDefault.Check"
+         parameter="sort_system_folders_to_top" />
+    </menu_item_check>
     <menu_item_separator
      layout="topleft" />
     <menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 4f982cc8e9a6c69993754e6fc333b5a3d61d105f..0d4a095e14d4cb0c1ebf4241d7ac8ed1b33ffb00 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -176,13 +176,19 @@
              parameter="message_critical" />
         </menu_item_call>
         <menu_item_call
-         label="Web Browser Test"
+         label="Media Browser Test"
          name="Web Browser Test">
           <menu_item_call.on_click
            function="Advanced.WebBrowserTest"
            parameter="http://join.secondlife.com/"/>
         </menu_item_call>
-      <menu_item_separator/>
+      <menu_item_call
+       label="Web Content Floater Test"
+       name="Web Content Floater Test">
+        <menu_item_call.on_click
+         function="Advanced.WebContentTest"
+         parameter="http://www.google.com"/>
+      </menu_item_call>
       <menu_item_check
         label="Show Grid Picker"
         name="Show Grid Picker"
diff --git a/indra/newview/skins/default/xui/en/menu_place.xml b/indra/newview/skins/default/xui/en/menu_place.xml
index 1b96eb51f0ca2c6811bbafba0998a23e15274fbf..288811d2f6b020f3e1ee8aa5bf5d10748ad2b918 100644
--- a/indra/newview/skins/default/xui/en/menu_place.xml
+++ b/indra/newview/skins/default/xui/en/menu_place.xml
@@ -24,26 +24,4 @@
          function="Places.OverflowMenu.Enable"
          parameter="can_create_pick" />
     </menu_item_call>
-    <menu_item_separator
-     layout="topleft"/>
-    <menu_item_call
-     enabled="false"
-     label="Buy Pass"
-     layout="topleft"
-     name="pass">
-        <menu_item_call.on_click
-         function="Places.OverflowMenu.Action"
-         parameter="pass" />
-    </menu_item_call>
-    <menu_item_separator
-     layout="topleft"/>
-    <menu_item_call
-     enabled="false"
-     label="Edit"
-     layout="topleft"
-     name="edit">
-        <menu_item_call.on_click
-         function="Places.OverflowMenu.Action"
-         parameter="edit" />
-    </menu_item_call>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index b36cf13f1bb194c8d36fd583a539694781663911..d997a262a820dae84ff8332bbf921cf10661a09a 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -94,6 +94,49 @@
              function="Floater.Toggle"
              parameter="voice_effect" />
         </menu_item_check>
+		<menu
+		 create_jump_keys="true"
+		 label="Movement"
+		 name="Movement"
+		 tear_off="true">
+            <menu_item_call
+             label="Sit Down"
+             layout="topleft"
+		     shortcut="alt|shift|S"
+             name="Sit Down Here">
+                <menu_item_call.on_click
+                 function="Self.SitDown"
+                 parameter="" />
+                <menu_item_call.on_enable
+                 function="Self.EnableSitDown" />
+            </menu_item_call>
+            <menu_item_check
+             label="Fly"
+             name="Fly"
+             shortcut="Home">
+                <menu_item_check.on_check
+                 function="Agent.getFlying" />
+                <menu_item_check.on_click
+                 function="Agent.toggleFlying" />
+                <menu_item_check.on_enable
+                 function="Agent.enableFlying" />
+            </menu_item_check>
+            <menu_item_check
+             label="Always Run"
+             name="Always Run"
+             shortcut="control|R">
+                <menu_item_check.on_check
+                 function="World.CheckAlwaysRun" />
+                <menu_item_check.on_click
+                 function="World.AlwaysRun" />
+            </menu_item_check>
+            <menu_item_call
+             label="Stop Animating Me"
+             name="Stop Animating My Avatar">
+                 <menu_item_call.on_click
+                  function="Tools.StopAllAnimations" />
+            </menu_item_call>
+		</menu>
         <menu
          create_jump_keys="true"
          label="My Status"
@@ -359,6 +402,18 @@
             <menu_item_check.on_check
                control="NavBarShowParcelProperties" />
           </menu_item_check>
+          <menu_item_separator />
+          <menu_item_check
+             label="Advanced Menu"
+             name="Show Advanced Menu"
+             shortcut="control|alt|shift|D">
+            <on_check
+               function="CheckControl"
+               parameter="UseDebugMenus" />
+            <on_click
+               function="ToggleControl"
+               parameter="UseDebugMenus" />
+          </menu_item_check>
         </menu>
 
         <menu_item_separator/>
@@ -921,6 +976,29 @@
                  parameter="perm_prefs" />
             </menu_item_call>
         </menu>
+        <menu_item_separator/>
+        <menu_item_call
+         enabled="false"
+         label="Undo"
+         name="Undo"
+         shortcut="control|Z">
+            <on_click
+             function="Edit.Undo"
+             userdata="" />
+            <on_enable
+             function="Edit.EnableUndo" />
+        </menu_item_call>
+        <menu_item_call
+         enabled="false"
+         label="Redo"
+         name="Redo"
+         shortcut="control|Y">
+            <on_click
+             function="Edit.Redo"
+             userdata="" />
+            <on_enable
+             function="Edit.EnableRedo" />
+        </menu_item_call>        
     </menu>
     <menu
      create_jump_keys="true"
@@ -935,6 +1013,14 @@
              function="ShowHelp"
              parameter="f1_help" />
         </menu_item_call>
+        <menu_item_check
+         label="Enable Hints"
+         name="Enable Hints">
+          <on_check
+            control="EnableUIHints"/>
+          <on_click
+            function="ToggleUIHints"/>
+        </menu_item_check>
 <!--        <menu_item_call
          label="Tutorial"
          name="Tutorial">
@@ -968,14 +1054,6 @@
              function="Floater.Show"
              parameter="sl_about" />
         </menu_item_call>
-        <menu_item_check
-         label="Enable Hints"
-         name="Enable Hints">
-          <on_check
-            control="EnableUIHints"/>
-          <on_click
-            function="ToggleUIHints"/>
-        </menu_item_check>
     </menu>
     <menu
      create_jump_keys="true"
@@ -983,12 +1061,6 @@
      name="Advanced"
      tear_off="true"
      visible="false">
-        <menu_item_call
-         label="Stop Animating Me"
-         name="Stop Animating My Avatar">
-            <menu_item_call.on_click
-             function="Tools.StopAllAnimations" />
-        </menu_item_call>
         <menu_item_call
          label="Rebake Textures"
          name="Rebake Texture"
@@ -1526,28 +1598,17 @@
                 <menu_item_call.on_click
                  function="View.DefaultUISize" />
             </menu_item_call>
-
-            <menu_item_separator/>
-
+            <!-- This second, alternative shortcut for Show Advanced Menu is for backward compatibility.  The main shortcut has been changed so it's Linux-friendly, where the old shortcut is typically eaten by the window manager. -->
             <menu_item_check
-             label="Always Run"
-             name="Always Run"
-             shortcut="control|R">
-                <menu_item_check.on_check
-                 function="World.CheckAlwaysRun" />
-                <menu_item_check.on_click
-                 function="World.AlwaysRun" />
-            </menu_item_check>
-            <menu_item_check
-             label="Fly"
-             name="Fly"
-             shortcut="Home">
-                <menu_item_check.on_check
-                 function="Agent.getFlying" />
-                <menu_item_check.on_click
-                 function="Agent.toggleFlying" />
-                <menu_item_check.on_enable
-                 function="Agent.enableFlying" />
+               label="Show Advanced Menu - legacy shortcut"
+               name="Show Advanced Menu - legacy shortcut"
+               shortcut="control|alt|D">
+              <on_check
+                 function="CheckControl"
+                 parameter="UseDebugMenus" />
+              <on_click
+                 function="ToggleControl"
+                 parameter="UseDebugMenus" />
             </menu_item_check>
 
             <menu_item_separator/>
@@ -1693,23 +1754,6 @@
                 <menu_item_call.on_click
                  function="View.ZoomOut" />
             </menu_item_call>
-            <menu_item_separator
-             visible="false"/>
-            <!-- Made invisible to avoid a dissonance: menu item toggles the menu where it is located. EXT-8069.
-              Can't be removed, to keep shortcut workable.
-            -->
-            <menu_item_check
-             label="Show Advanced Menu"
-             name="Show Advanced Menu"
-             shortcut="control|alt|D"
-             visible="false">
-                <on_check
-                 function="CheckControl"
-                 parameter="UseDebugMenus" />
-                <on_click
-                 function="ToggleControl"
-                 parameter="UseDebugMenus" />
-        </menu_item_check>
         </menu> <!--Shortcuts-->
 
         <menu_item_separator/>
@@ -1732,7 +1776,6 @@
              function="ToggleControl"
              parameter="QAMode" />
         </menu_item_check>
-    
     </menu>
     <menu
      create_jump_keys="true"
@@ -2603,13 +2646,21 @@
                  parameter="BottomPanelNew" />
             </menu_item_check>-->
             <menu_item_call
-             label="Web Browser Test"
+             label="Media Browser Test"
              name="Web Browser Test">
                 <menu_item_call.on_click
                  function="Advanced.WebBrowserTest"
                  parameter="http://secondlife.com/app/search/slurls.html"/>
             </menu_item_call>
-            <menu_item_call
+          <menu_item_call
+           label="Web Content Browser"
+           name="Web Content Browser"
+           shortcut="control|alt|W">
+            <menu_item_call.on_click
+             function="Advanced.WebContentTest"
+             parameter="http://google.com"/>
+          </menu_item_call>
+          <menu_item_call
              label="Dump SelectMgr"
              name="Dump SelectMgr">
                 <menu_item_call.on_click
@@ -2655,24 +2706,16 @@
                  function="Advanced.PrintTextureMemoryStats" />
             </menu_item_call>
             <menu_item_check
-             label="Double-ClickAuto-Pilot"
-             name="Double-ClickAuto-Pilot">
-                <menu_item_check.on_check
-                 function="CheckControl"
-                 parameter="DoubleClickAutoPilot" />
-                <menu_item_check.on_click
-                 function="ToggleControl"
-                 parameter="DoubleClickAutoPilot" />
-            </menu_item_check>
-            <menu_item_check
-             label="Double-Click Teleport"
-             name="DoubleClick Teleport">
+             label="Region Debug Console"
+             name="Region Debug Console"
+             shortcut="control|shift|`"
+             use_mac_ctrl="true">
                 <menu_item_check.on_check
-                 function="CheckControl"
-                 parameter="DoubleClickTeleport" />
+                 function="Floater.Visible"
+                 parameter="region_debug_console" />
                 <menu_item_check.on_click
-                 function="ToggleControl"
-                 parameter="DoubleClickTeleport" />
+                 function="Floater.Toggle"
+                 parameter="region_debug_console" />
             </menu_item_check>
 
             <menu_item_separator />
diff --git a/indra/newview/skins/default/xui/en/notification_visibility.xml b/indra/newview/skins/default/xui/en/notification_visibility.xml
new file mode 100644
index 0000000000000000000000000000000000000000..db292100d7b19e89a595945c95d0279e96cb9283
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/notification_visibility.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" ?>
+<notification_visibility>
+  <hide tag="custom_skin"/>
+	<show/> 
+</notification_visibility>
+
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index a0fd0a13ccea2a0e24b830aaba974e6f3353e785..63c030b0687cd85f33fdadfe9b4f57ab400e77f7 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -441,6 +441,7 @@ Please invite members within 48 hours.
    icon="alertmodal.tga"
    name="LandBuyPass"
    type="alertmodal">
+   <tag>fail</tag>
 For L$[COST] you can enter this land (&apos;[PARCEL_NAME]&apos;) for [TIME] hours.  Buy a pass?
     <usetemplate
      name="okcancelbuttons"
@@ -907,6 +908,13 @@ Port settings take effect after you restart [APP_NAME].
 The new skin will appear after you restart [APP_NAME].
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="ChangeLanguage"
+   type="alertmodal">
+Changing language will take effect after you restart [APP_NAME].
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="GoToAuctionPage"
@@ -1597,6 +1605,7 @@ If you continue to get this message, please check the [SUPPORT_SITE].
    icon="alertmodal.tga"
    name="blocked_tport"
    type="alertmodal">
+   <tag>fail</tag>
 Sorry, teleport is currently blocked. Try again in a moment.  If you still cannot teleport, please log out and log back in to resolve the problem.
   </notification>
   <notification
@@ -1609,42 +1618,49 @@ Sorry, but system was unable to locate landmark destination.
    icon="alertmodal.tga"
    name="timeout_tport"
    type="alertmodal">
+   <tag>fail</tag>
 Sorry, but system was unable to complete the teleport connection.  Try again in a moment.
   </notification>
   <notification
    icon="alertmodal.tga"
    name="noaccess_tport"
    type="alertmodal">
+   <tag>fail</tag>
 Sorry, you do not have access to that teleport destination.
   </notification>
   <notification
    icon="alertmodal.tga"
    name="missing_attach_tport"
    type="alertmodal">
+   <tag>fail</tag>
 Your attachments have not arrived yet. Try waiting for a few more seconds or log out and back in again before attempting to teleport.
   </notification>
   <notification
    icon="alertmodal.tga"
    name="too_many_uploads_tport"
    type="alertmodal">
+   <tag>fail</tag>
 The asset queue in this region is currently clogged so your teleport request will not be able to succeed in a timely manner. Please try again in a few minutes or go to a less busy area.
   </notification>
   <notification
    icon="alertmodal.tga"
    name="expired_tport"
    type="alertmodal">
+   <tag>fail</tag>
 Sorry, but the system was unable to complete your teleport request in a timely fashion. Please try again in a few minutes.
   </notification>
   <notification
    icon="alertmodal.tga"
    name="expired_region_handoff"
    type="alertmodal">
+   <tag>fail</tag>
 Sorry, but the system was unable to complete your region crossing in a timely fashion. Please try again in a few minutes.
   </notification>
   <notification
    icon="alertmodal.tga"
    name="no_host"
    type="alertmodal">
+   <tag>fail</tag>
 Unable to find teleport destination. The destination may be temporarily unavailable or no longer exists. Please try again in a few minutes.
   </notification>
   <notification
@@ -2063,7 +2079,7 @@ Would you be my friend?
       <button
        default="true"
        index="0"
-       name="Offer"
+       name="OK"
        text="OK"/>
       <button
        index="1"
@@ -2085,7 +2101,7 @@ Would you be my friend?
       <button
        default="true"
        index="0"
-       name="Offer"
+       name="OK"
        text="OK"/>
       <button
        index="1"
@@ -2108,7 +2124,7 @@ Would you be my friend?
       <button
        default="true"
        index="0"
-       name="Offer"
+       name="OK"
        text="OK"/>
       <button
        index="1"
@@ -2412,6 +2428,7 @@ Display settings have been set to recommended levels based on your system config
    icon="alertmodal.tga"
    name="AvatarMovedDesired"
    type="alertmodal">
+   <tag>fail</tag>
 Your desired location is not currently available.
 You have been moved into a nearby region.
   </notification>
@@ -2420,6 +2437,7 @@ You have been moved into a nearby region.
    icon="alertmodal.tga"
    name="AvatarMovedLast"
    type="alertmodal">
+   <tag>fail</tag>
 Your last location is not currently available.
 You have been moved into a nearby region.
   </notification>
@@ -2428,6 +2446,7 @@ You have been moved into a nearby region.
    icon="alertmodal.tga"
    name="AvatarMovedHome"
    type="alertmodal">
+   <tag>fail</tag>
 Your home location is not currently available.
 You have been moved into a nearby region.
 You may want to set a new home location.
@@ -2437,6 +2456,7 @@ You may want to set a new home location.
    icon="alertmodal.tga"
    name="ClothingLoading"
    type="alertmodal">
+   <tag>fail</tag>
 Your clothing is still downloading.
 You can use [SECOND_LIFE] normally and other people will see you correctly.
     <form name="form">
@@ -2464,6 +2484,7 @@ Return to [http://join.secondlife.com secondlife.com] to create a new account?
    icon="alertmodal.tga"
    name="LoginPacketNeverReceived"
    type="alertmodal">
+   <tag>fail</tag>
 We&apos;re having trouble connecting. There may be a problem with your Internet connection or the [SECOND_LIFE_GRID].
 
 You can either check your Internet connection and try again in a few minutes, click Help to view the [SUPPORT_SITE], or click Teleport to attempt to teleport home.
@@ -2869,6 +2890,93 @@ Download to your Applications folder?
      yestext="Download"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="FailedUpdateInstall"
+   type="alertmodal">
+An error occurred installing the viewer update.
+Please download and install the latest viewer from
+http://secondlife.com/download.
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="FailedRequiredUpdateInstall"
+   type="alertmodal">
+We were unable to install a required update. 
+You will be unable to log in until [APP_NAME] has been updated.
+
+Please download and install the latest viewer from
+http://secondlife.com/download.
+    <usetemplate
+     name="okbutton"
+     yestext="Quit"/>
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="UpdaterServiceNotRunning"
+   type="alertmodal">
+There is a required update for your Second Life Installation.
+
+You may download this update from http://www.secondlife.com/downloads
+or you can install it now.
+    <usetemplate
+     name="okcancelbuttons"
+     notext="Quit Second Life"
+     yestext="Download and install now"/>
+  </notification>
+
+  <notification
+   icon="notify.tga"
+   name="DownloadBackgroundTip"
+   type="notify">
+We have downloaded an update to your [APP_NAME] installation.
+Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]
+    <usetemplate
+     name="okcancelbuttons"
+     notext="Later..."
+     yestext="Install now and restart [APP_NAME]"/>
+  </notification>
+
+  <notification
+ icon="alertmodal.tga"
+ name="DownloadBackgroundDialog"
+ type="alertmodal">
+We have downloaded an update to your [APP_NAME] installation.
+Version [VERSION] [[RELEASE_NOTES_FULL_URL] Information about this update]
+    <usetemplate
+     name="okcancelbuttons"
+     notext="Later..."
+     yestext="Install now and restart [APP_NAME]"/>
+  </notification>
+  
+  <notification
+ icon="alertmodal.tga"
+ name="RequiredUpdateDownloadedVerboseDialog"
+ type="alertmodal">
+We have downloaded a required software update.
+Version [VERSION]
+
+We must restart [APP_NAME] to install the update.
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+  
+  <notification
+ icon="alertmodal.tga"
+ name="RequiredUpdateDownloadedDialog"
+ type="alertmodal">
+We must restart [APP_NAME] to install the update.
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="DeedObjectToGroup"
@@ -3112,6 +3220,7 @@ You have reached your maximum number of groups. Please leave some group before j
    icon="alert.tga"
    name="KickUser"
    type="alert">
+   <tag>win</tag>
 Kick this Resident with what message?
     <form name="form">
       <input name="message" type="text">
@@ -3133,6 +3242,7 @@ An administrator has logged you off.
    icon="alert.tga"
    name="KickAllUsers"
    type="alert">
+   <tag>win</tag>
 Kick everyone currently on the grid with what message?
     <form name="form">
       <input name="message" type="text">
@@ -3154,6 +3264,7 @@ An administrator has logged you off.
    icon="alert.tga"
    name="FreezeUser"
    type="alert">
+   <tag>win</tag>
 Freeze this Resident with what message?
     <form name="form">
       <input name="message" type="text">
@@ -3175,6 +3286,7 @@ You have been frozen. You cannot move or chat. An administrator will contact you
    icon="alert.tga"
    name="UnFreezeUser"
    type="alert">
+   <tag>win</tag>
 Unfreeze this Resident with what message?
     <form name="form">
       <input name="message" type="text">
@@ -3546,6 +3658,7 @@ Are you sure you want to change the Estate Covenant?
    icon="alertmodal.tga"
    name="RegionEntryAccessBlocked"
    type="alertmodal">
+   <tag>fail</tag>
 You are not allowed in that Region due to your maturity Rating. This may be a result of a lack of information validating your age.
 
 Please verify you have the latest Viewer installed, and go to the Knowledge Base for details on accessing areas with this maturity rating.
@@ -3558,6 +3671,7 @@ Please verify you have the latest Viewer installed, and go to the Knowledge Base
    icon="alertmodal.tga"
    name="RegionEntryAccessBlocked_KB"
    type="alertmodal">
+   <tag>fail</tag>
 You are not allowed in that region due to your maturity Rating.
 
 Go to the Knowledge Base for more information about maturity Ratings?
@@ -3575,6 +3689,7 @@ Go to the Knowledge Base for more information about maturity Ratings?
    icon="notifytip.tga"
    name="RegionEntryAccessBlocked_Notify"
    type="notifytip">
+   <tag>fail</tag>
 You are not allowed in that region due to your maturity Rating.
   </notification>
 
@@ -3582,6 +3697,7 @@ You are not allowed in that region due to your maturity Rating.
    icon="alertmodal.tga"
    name="RegionEntryAccessBlocked_Change"
    type="alertmodal">
+   <tag>fail</tag>
 You are not allowed in that Region due to your maturity Rating preference.
 
 To enter the desired region, please change your maturity Rating preference. This will allow you to search for and access [REGIONMATURITY] content. To undo any changes, go to Me &gt; Preferences &gt; General.
@@ -4498,6 +4614,7 @@ Would you like to automatically wear the clothing you are about to create?
    icon="alertmodal.tga"
    name="NotAgeVerified"
    type="alertmodal">
+   <tag>fail</tag>
 You must be age-verified to visit this area.  Do you want to go to the [SECOND_LIFE] website and verify your age?
 
 [_URL]
@@ -4879,24 +4996,6 @@ Some terms in your search query were excluded due to content restrictions as cla
 Please select at least one type of content to search (General, Moderate, or Adult).
   </notification>
 
-  <notification
-   icon="notify.tga"
-   name="GroupVote"
-   type="notify">
-[NAME] has proposed to vote on:
-[MESSAGE]
-    <form name="form">
-      <button
-       index="0"
-       name="VoteNow"
-       text="Vote Now"/>
-      <button
-       index="1"
-       name="Later"
-       text="Later"/>
-    </form>
-  </notification>
-
   <notification
    icon="notify.tga"
    name="SystemMessage"
@@ -4983,7 +5082,7 @@ If you want to view streaming media on parcels that support it you should go to
    type="notify">
 No Media Plugin was found to handle the "[MIME_TYPE]" mime type.  Media of this type will be unavailable.
     <unique>
-      <context key="[MIME_TYPE]"/>
+      <context>MIME_TYPE</context>
     </unique>
 
   </notification>
@@ -5067,6 +5166,7 @@ You can be hurt here. If you die, you will be teleported to your home location.
    persist="true"
    type="notify"
    unique="true">
+   <tag>fail</tag>
 This area has flying disabled.
 You can&apos;t fly here.
   </notification>
@@ -5119,6 +5219,7 @@ This region is not running any scripts.
    name="NoOutsideScripts"
    persist="true"
    type="notify">
+   <tag>fail</tag>
 This land has outside scripts disabled.
 
 No scripts will work here except those belonging to the land owner.
@@ -5137,6 +5238,7 @@ You can only claim public land in the Region you&apos;re in.
    name="RegionTPAccessBlocked"
    persist="true"
    type="notify">
+   <tag>fail</tag>
 You aren&apos;t allowed in that Region due to your maturity Rating. You may need to validate your age and/or install the latest Viewer.
 
 Please go to the Knowledge Base for details on accessing areas with this maturity Rating.
@@ -5147,6 +5249,7 @@ Please go to the Knowledge Base for details on accessing areas with this maturit
 	name="URBannedFromRegion"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 You are banned from the region.
   </notification>
 
@@ -5155,6 +5258,7 @@ You are banned from the region.
 	name="NoTeenGridAccess"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 Your account cannot connect to this teen grid region.
   </notification>
 
@@ -5163,6 +5267,7 @@ Your account cannot connect to this teen grid region.
 	name="ImproperPaymentStatus"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 You do not have proper payment status to enter this region.
   </notification>
 
@@ -5171,6 +5276,7 @@ You do not have proper payment status to enter this region.
 	name="MustGetAgeRgion"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 You must be age-verified to enter this region.
   </notification>
 
@@ -5179,6 +5285,7 @@ You must be age-verified to enter this region.
 	name="MustGetAgeParcel"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 You must be age-verified to enter this parcel.
   </notification>
 
@@ -5187,6 +5294,7 @@ You must be age-verified to enter this parcel.
 	name="NoDestRegion"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 No destination region found.
   </notification>
 
@@ -5195,6 +5303,7 @@ No destination region found.
 	name="NotAllowedInDest"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 You are not allowed into the destination.
   </notification>
 
@@ -5203,6 +5312,7 @@ You are not allowed into the destination.
 	name="RegionParcelBan"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 Cannot region cross into banned parcel. Try another way.
   </notification>
 
@@ -5211,6 +5321,7 @@ Cannot region cross into banned parcel. Try another way.
 	name="TelehubRedirect"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 You have been redirected to a telehub.
   </notification>
 
@@ -5219,6 +5330,7 @@ You have been redirected to a telehub.
 	name="CouldntTPCloser"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 Could not teleport closer to destination.
   </notification>
 
@@ -5235,6 +5347,7 @@ Teleport cancelled.
 	name="FullRegionTryAgain"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 The region you are attempting to enter is currently full.
 Please try again in a few moments.
   </notification>
@@ -5244,6 +5357,7 @@ Please try again in a few moments.
 	name="GeneralFailure"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 General failure.
   </notification>
 
@@ -5252,6 +5366,7 @@ General failure.
 	name="RoutedWrongRegion"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 Routed to wrong region. Please try again.
   </notification>
 
@@ -5260,6 +5375,7 @@ Routed to wrong region. Please try again.
 	name="NoValidAgentID"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 No valid agent id.
   </notification>
 
@@ -5268,6 +5384,7 @@ No valid agent id.
 	name="NoValidSession"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 No valid session id.
   </notification>
 
@@ -5276,6 +5393,7 @@ No valid session id.
 	name="NoValidCircuit"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 No valid circuit code.
   </notification>
 
@@ -5284,6 +5402,7 @@ No valid circuit code.
 	name="NoValidTimestamp"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 No valid timestamp.
   </notification>
 
@@ -5292,6 +5411,7 @@ No valid timestamp.
 	name="NoPendingConnection"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 Unable to create pending connection.
   </notification>
 
@@ -5300,6 +5420,7 @@ Unable to create pending connection.
 	name="InternalUsherError"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 Internal error attempting to connect agent usher.
   </notification>
 
@@ -5308,6 +5429,7 @@ Internal error attempting to connect agent usher.
 	name="NoGoodTPDestination"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 Unable to find a good teleport destination in this region.
   </notification>
 
@@ -5316,6 +5438,7 @@ Unable to find a good teleport destination in this region.
 	name="InternalErrorRegionResolver"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 Internal error attempting to activate region resolver.
   </notification>
 
@@ -5324,6 +5447,7 @@ Internal error attempting to activate region resolver.
 	name="NoValidLanding"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 A valid landing point could not be found.
   </notification>
 
@@ -5332,6 +5456,7 @@ A valid landing point could not be found.
 	name="NoValidParcel"
    persist="true"
 	type="notify">
+   <tag>fail</tag>
 No valid parcel could be found.
   </notification>
 
@@ -5539,7 +5664,7 @@ Friendship offer declined.
    name="OfferCallingCard"
    persist="true"
    type="notify">
-[FIRST] [LAST] is offering their calling card.
+[NAME] is offering their calling card.
 This will add a bookmark in your inventory so you can quickly IM this Resident.
     <form name="form">
       <button
@@ -5708,6 +5833,7 @@ Grant this request?
    name="FirstBalanceIncrease"
    persist="true"
    type="notify">
+   <tag>win</tag>
 You just received L$[AMOUNT].
 Your L$ balance is shown in the upper-right.
   </notification>
@@ -5885,7 +6011,7 @@ You may only select up to [MAX_SELECT] items from this list.
 [NAME] is inviting you to a Voice Chat call.
 Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.
     <unique>
-      <context key="NAME"/>
+      <context>NAME</context>
     </unique>
     <form name="form">
       <button
@@ -5934,8 +6060,8 @@ Click Accept to join the call or Decline to decline the invitation. Click Block
 [NAME] has joined a Voice Chat call with the group [GROUP].
 Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.
     <unique>
-      <context key="NAME"/>
-      <context key="GROUP"/>
+      <context>NAME</context>
+      <context>GROUP</context>
     </unique>
     <form name="form">
       <button
@@ -5960,7 +6086,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block
 [NAME] has joined a voice chat call with a conference chat.
 Click Accept to join the call or Decline to decline the invitation. Click Block to block this caller.
     <unique>
-      <context key="NAME"/>
+      <context>NAME</context>
     </unique>
     <form name="form">
       <button
@@ -5985,7 +6111,7 @@ Click Accept to join the call or Decline to decline the invitation. Click Block
 [NAME] is inviting you to a conference chat.
 Click Accept to join the chat or Decline to decline the invitation. Click Block to block this caller.
     <unique>
-      <context key="NAME"/>
+      <context>NAME</context>
     </unique>
     <form name="form">
       <button
@@ -6009,7 +6135,7 @@ Click Accept to join the chat or Decline to decline the invitation. Click Block
    type="notifytip">
 The voice call you are trying to join, [VOICE_CHANNEL_NAME], has reached maximum capacity. Please try again later.
     <unique>
-      <context key="VOICE_CHANNEL_NAME"/>
+      <context>VOICE_CHANNEL_NAME</context>
     </unique>
   </notification>
 
@@ -6027,7 +6153,7 @@ We&apos;re sorry.  This area has reached maximum capacity for voice conversation
    type="notifytip">
 You have been disconnected from [VOICE_CHANNEL_NAME].  You will now be reconnected to Nearby Voice Chat.
     <unique>
-      <context key="VOICE_CHANNEL_NAME"/>
+      <context>VOICE_CHANNEL_NAME</context>
     </unique>
   </notification>
 
@@ -6037,7 +6163,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME].  You will now be reconnect
    type="notifytip">
 [VOICE_CHANNEL_NAME] has ended the call.  You will now be reconnected to Nearby Voice Chat.
     <unique>
-      <context key="VOICE_CHANNEL_NAME"/>
+      <context>VOICE_CHANNEL_NAME</context>
     </unique>
   </notification>
 
@@ -6047,7 +6173,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME].  You will now be reconnect
    type="notifytip">
 [VOICE_CHANNEL_NAME] has declined your call.  You will now be reconnected to Nearby Voice Chat.
     <unique>
-      <context key="VOICE_CHANNEL_NAME"/>
+      <context>VOICE_CHANNEL_NAME</context>
     </unique>
   </notification>
 
@@ -6057,7 +6183,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME].  You will now be reconnect
    type="notifytip">
 [VOICE_CHANNEL_NAME] is not available to take your call.  You will now be reconnected to Nearby Voice Chat.
     <unique>
-      <context key="VOICE_CHANNEL_NAME"/>
+      <context>VOICE_CHANNEL_NAME</context>
     </unique>
   </notification>
 
@@ -6067,7 +6193,7 @@ You have been disconnected from [VOICE_CHANNEL_NAME].  You will now be reconnect
    type="notifytip">
 Failed to connect to [VOICE_CHANNEL_NAME], please try again later.  You will now be reconnected to Nearby Voice Chat.
     <unique>
-      <context key="VOICE_CHANNEL_NAME"/>
+      <context>VOICE_CHANNEL_NAME</context>
     </unique>
   </notification>
 
@@ -6127,6 +6253,7 @@ New Voice Morphs are available!
    icon="notifytip.tga"
    name="Cannot enter parcel: not a group member"
    type="notifytip">
+   <tag>fail</tag>
 Only members of a certain group can visit this area.
   </notification>
 
@@ -6134,6 +6261,7 @@ Only members of a certain group can visit this area.
    icon="notifytip.tga"
    name="Cannot enter parcel: banned"
    type="notifytip">
+   <tag>fail</tag>
 Cannot enter parcel, you have been banned.
   </notification>
 
@@ -6141,6 +6269,7 @@ Cannot enter parcel, you have been banned.
    icon="notifytip.tga"
    name="Cannot enter parcel: not on access list"
    type="notifytip">
+   <tag>fail</tag>
 Cannot enter parcel, you are not on the access list.
   </notification>
 
@@ -6150,7 +6279,7 @@ Cannot enter parcel, you are not on the access list.
    type="notifytip">
 You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME].
     <unique>
-      <context key="VOICE_CHANNEL_NAME"/>
+      <context>VOICE_CHANNEL_NAME</context>
     </unique>
   </notification>
 
@@ -6160,7 +6289,7 @@ You do not have permission to connect to voice chat for [VOICE_CHANNEL_NAME].
    type="notifytip">
 An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_NAME].  Please try again later.
     <unique>
-      <context key="VOICE_CHANNEL_NAME"/>
+      <context>VOICE_CHANNEL_NAME</context>
     </unique>
   </notification>
 
@@ -6186,6 +6315,7 @@ The SLurl you clicked on is not supported.
    name="BlockedSLURL"
    priority="high"
    type="notifytip">
+   <tag>win</tag>
 A SLurl was received from an untrusted browser and has been blocked for your security.
   </notification>
 
@@ -6385,13 +6515,9 @@ Avatar '[NAME]' left appearance mode.
    type="alertmodal">
 We're having trouble connecting using [PROTOCOL] [HOSTID].
 Please check your network and firewall setup.
-    <form name="form">
-      <button
-       default="true"
-       index="0"
-       name="OK"
-       text="OK"/>
-    </form>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
   </notification>
 
   <notification
@@ -6404,13 +6530,9 @@ We're having trouble connecting to your voice server:
 
 Voice communications will not be available.
 Please check your network and firewall setup.
-    <form name="form">
-      <button
-       default="true"
-       index="0"
-       name="OK"
-       text="OK"/>
-    </form>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
   </notification>
 
   <notification
@@ -6491,6 +6613,14 @@ Mute everyone?
     The Destination Guide contains thousands of new places to discover. Select a location and choose Teleport to start exploring.
   </notification>
 
+  <notification
+  name="HintAvatarPicker"
+  label="Change your Look"
+  type="hint"
+  unique="true">
+    Would you like to try a new look? Click the button below to see more Avatars.
+  </notification>
+
   <notification
     name="HintSidePanel"
     label="Side Panel"
@@ -6515,6 +6645,24 @@ Mute everyone?
     Set your customizable display name here. This is in addition to your unique username, which can't be changed. You can change how you see other people's names in your preferences.
   </notification>
 
+  <notification
+  name="HintMoveArrows"
+  label="Move"
+  type="hint"
+  unique="true">
+    To walk, use the directional keys on your keyboard. You can run by pressing the Up arrow twice.
+    <tag>custom_skin</tag>
+  </notification>
+
+  <notification
+  name="HintView"
+  label="View"
+  type="hint"
+  unique="true">
+    To change your camera view, use the Orbit and Pan controls. Reset your view by pressing Escape or walking.
+    <tag>custom_skin</tag>
+  </notification>
+
   <notification
   name="HintInventory"
   label="Inventory"
@@ -6548,6 +6696,23 @@ Mute everyone?
     </form>
   </notification>
 
+  <notification
+  name="AuthRequest"
+  type="browser">
+The site at &apos;&lt;nolink&gt;[HOST_NAME]&lt;/nolink&gt;&apos; in realm &apos;[REALM]&apos; requires a user name and password.
+    <form name="form">
+      <input name="username" type="text" text="User Name"/>
+      <input name="password" type="password" text="Password    "/>
+      <button default="true"
+              index="0"
+              name="ok"
+              text="Submit"/>
+      <button index="1"
+              name="cancel"
+              text="Cancel"/>
+    </form>
+  </notification>
+
   
   <global name="UnsupportedCPU">
 - Your CPU speed does not meet the minimum requirements.
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index 6f3629cc8fc2a7521847597c8dfdb2fc3d8410fc..4b21ffa1f915238ed2dede4cf5b3a1d4b0eea971 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -62,7 +62,7 @@
      name="avatar_name"
      top="6"
      use_ellipses="true"
-     value="Unknown"
+     value="(loading)"
      width="180" />
     <text
      follows="right"
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray.xml b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
index 63068a069f4b608c2d01056067ac3faae7de76c0..013a8090f7a1170ab2dc2bf6f1d12b4d511b23c1 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray.xml
@@ -5,6 +5,7 @@
  bg_opaque_color="DkGray"
  chrome="true"
  follows="left|bottom|right"
+ focus_root="true" 
  height="33"
  layout="topleft"
  left="0"
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
index efb1da4c05b57805d885d60ebb43c00c02fb9eff..b5e1a5f16df15c9faa438f8e992c0d25e688581e 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
@@ -10,6 +10,7 @@
  layout="topleft"
  left="0"
  name="bottom_tray_lite"
+ focus_root="true" 
  tab_stop="true"
  top="28"
  chrome="true"
diff --git a/indra/newview/skins/default/xui/en/panel_classified_info.xml b/indra/newview/skins/default/xui/en/panel_classified_info.xml
index 0fb7691ee7ba221c88be2e4847182ac65c58c14c..6c8d994bc6324238b0d8ff284398b03cbfddc2bb 100644
--- a/indra/newview/skins/default/xui/en/panel_classified_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_classified_info.xml
@@ -49,7 +49,8 @@
      left="10"
      tab_stop="false"
      top="2"
-     width="30" />
+     width="30"
+     use_draw_context_alpha="false" />
     <text
      follows="top|left|right"
      font="SansSerifHugeBold"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_alpha.xml b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml
index 7bcd4962d2e81f5a502bf4a23151b3e35f1df6e5..813aa5d7a93dfa69ad9a2a07d865007b37404c1b 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_alpha.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_alpha.xml
@@ -8,6 +8,17 @@
 	 name="edit_alpha_panel"
 	 top_pad="10"
 	 width="333" >
+   <scroll_container
+    color="DkGray2"
+    follows="all"
+    height="400"
+    layout="topleft"
+    left="10"
+    top_pad="0"
+    name="avatar_alpha_color_panel_scroll"
+    reserve_scroll_corner="false"
+    opaque="true"
+    width="313">
    <panel
       border="false"
       bg_alpha_color="DkGray2"
@@ -16,14 +27,14 @@
       background_opaque="true"
       follows="top|left|right"
       height="400" 
-      left="10" 
+      left="0" 
       layout="topleft" 
       name="avatar_alpha_color_panel"
       top="0"
       width="313" >
        <check_box
         control_name="LowerAlphaTextureInvisible"
-        follows="left"
+        follows="left|top"
         height="16"
         layout="topleft"
         left="5"
@@ -48,7 +59,7 @@
 
        <check_box
         control_name="UpperAlphaTextureInvisible"
-        follows="left"
+        follows="left|top"
         height="16"
         layout="topleft"
         left_pad="20"
@@ -73,7 +84,7 @@
 
        <check_box
         control_name="HeadAlphaTextureInvisible"
-        follows="left"
+        follows="left|top"
         height="16"
         layout="topleft"
         left="5"
@@ -98,7 +109,7 @@
 
        <check_box
         control_name="Eye AlphaTextureInvisible"
-        follows="left"
+        follows="left|top"
         height="16"
         layout="topleft"
         left_pad="20"
@@ -123,7 +134,7 @@
 
        <check_box
         control_name="HairAlphaTextureInvisible"
-        follows="left"
+        follows="left|top"
         height="16"
         layout="topleft"
         left="5"
@@ -147,5 +158,6 @@
        </texture_picker>
 
 	 </panel>
+	 </scroll_container>
 </panel>
 
diff --git a/indra/newview/skins/default/xui/en/panel_edit_classified.xml b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
index f60c1e62acfd418a4c0913ccd9f67a527cd84901..e512d63f9e2ebd48f8809332e93cbd60705157f5 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_classified.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_classified.xml
@@ -33,7 +33,8 @@
      left="10"
      tab_stop="false"
      top="2"
-     width="30" />
+     width="30"
+     use_draw_context_alpha="false" />
    <text
      type="string"
      length="1"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_pick.xml b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
index a284d3ccc029c846290f6fc567514aa6d4b92c41..a028e3ab9f6f11bca6d7cb893e9611b5b218952f 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_pick.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_pick.xml
@@ -27,7 +27,8 @@
      left="10"
      tab_stop="false"
      top="2"
-     width="30" />
+     width="30"
+     use_draw_context_alpha="false" />
    <text
      type="string"
      length="1"
diff --git a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml
index 23a08344eab5f056367b7d453ba85218f957a5e3..97f1a1a6589bbd8b5de6e3a56f254ea92a617095 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_tattoo.xml
@@ -14,7 +14,7 @@
       bg_opaque_color="DkGray2"
       background_visible="true"
       background_opaque="true"
-	  follows="top|left|right"
+	  follows="all"
 	  height="400" 
 	  left="10" 
 	  layout="topleft" 
diff --git a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
index b3e9586ee9347ce30347082e409c33cba3c1dd4b..ac8917d272d9364d12563200e33c52a1cd0777eb 100644
--- a/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
+++ b/indra/newview/skins/default/xui/en/panel_edit_wearable.xml
@@ -147,7 +147,8 @@
      pad_left="24"
      tool_tip="Return to Edit Outfit"
      top="3"
-     width="30" />
+     width="30"
+     use_draw_context_alpha="false" />
     <text
      follows="top|left|right"
      font="SansSerifHugeBold"
diff --git a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
index 0347d2feec5e540a038751245893cf536325cacf..ec3f3b48bcb72b6bc29b8f77bfac72b397da8be6 100644
--- a/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_info_sidetray.xml
@@ -45,7 +45,8 @@ background_visible="true"
      left="7"
      tab_stop="false"
      top="2"
-     width="30" />
+     width="30"
+     use_draw_context_alpha="false" />
     <text_editor
      allow_scroll="false"
      bg_visible="false"
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
index 0b84ac03c542f2333a28a0c0da460b7b08992d3b..7d0b0890f0250a97183bce3d5f06ca545de209e8 100644
--- a/indra/newview/skins/default/xui/en/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
@@ -34,6 +34,7 @@
      mouse_opaque="true"
      left="5"
      top="2"
+     use_draw_context_alpha="false"
      width="20" />
    <text
      parse_urls="false"
diff --git a/indra/newview/skins/default/xui/en/panel_hint_image.xml b/indra/newview/skins/default/xui/en/panel_hint_image.xml
new file mode 100644
index 0000000000000000000000000000000000000000..00b6e4249716ccda54a56278f75fb3cecc096c5f
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_hint_image.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ width="205"
+ height="140"
+ layout="topleft">
+  <text name="hint_title"
+        font="SansSerifMedium" 
+        left="8"
+        right="180"
+        top="8"
+        bottom="20"
+        follows="left|right|top"
+        text_color="Black"
+        wrap="false"/>
+  <icon name="hint_image"
+        left="42"
+        top="25"
+        width="115"
+        height="86"
+        image_name="arrow_keys.png"
+        />
+  <text name="hint_text"
+        left="8"
+        right="197"
+        top_pad="5"
+        bottom="120"
+        follows="all" 
+        text_color="Black"
+        wrap="true"/>
+  <button right="197" 
+          top="8"
+          width="16" 
+          height="16"
+          name="close" 
+          follows="right|top" 
+          image_color="DkGray" 
+          image_unselected="Icon_Close_Foreground"
+          image_selected="Icon_Close_Press"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_landmark_info.xml b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
index 6ee2abc70fe233329979d1809f99dca8e33c345d..d2088594dd91148667ce12312e97f700a61ea2b2 100644
--- a/indra/newview/skins/default/xui/en/panel_landmark_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmark_info.xml
@@ -68,7 +68,8 @@
      tool_tip="Back"
      tab_stop="false"
      top="4"
-     width="30" />
+     width="30"
+     use_draw_context_alpha="false" />
     <text
      follows="top|left|right"
      font="SansSerifHugeBold"
diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index 2a5933e3e93bbc9f5ebe13b07809b2d47beb17a5..23d8cb11cac136fbf4cd7e33455639c478f1cb63 100644
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -114,6 +114,7 @@
 		       height="25"
 		       layout="topleft"
 		       name="options_gear_btn_panel"
+		       user_resize="false"
 		       width="32">
 		          <menu_button
 		           follows="bottom|left"
@@ -134,6 +135,7 @@
 		       height="25"
 		       layout="topleft"
 		       name="add_btn_panel"
+		       user_resize="false"
 		       width="32">
 		          <button
 		           follows="bottom|left"
@@ -154,6 +156,7 @@
 		       height="25"
 		       layout="topleft"
 		       name="dummy_panel"
+		       user_resize="false"
 		       width="212">
 		          <icon
 		           follows="bottom|left|right"
@@ -170,6 +173,7 @@
 		       height="25"
 		       layout="topleft"
 		       name="trash_btn_panel"
+		       user_resize="false"
 		       width="31">
 		          <dnd_button
 		           follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/panel_login.xml b/indra/newview/skins/default/xui/en/panel_login.xml
index b181ca3bbad8db1defeb8ea60aceacf2e4d1ac28..257ed799da3e32f8971dc89f35c01b92e3c5a5a2 100644
--- a/indra/newview/skins/default/xui/en/panel_login.xml
+++ b/indra/newview/skins/default/xui/en/panel_login.xml
@@ -5,17 +5,14 @@ height="600"
 layout="topleft"
 left="0"
 name="panel_login"
+focus_root="true" 
 top="600"
  width="996">
 <panel.string
      name="create_account_url">
        http://join.secondlife.com/
 </panel.string>
-<panel.string
-     name="real_url" translate="false">
-       http://secondlife.com/app/login/
-</panel.string>
-    <string name="reg_in_client_url" translate="false">
+<string name="reg_in_client_url" translate="false">
      http://secondlife.eniac15.lindenlab.com/reg-in-client/
 </string>
 <panel.string
@@ -91,6 +88,7 @@ follows="left|bottom"
   height="22"
   max_length_bytes="16"
 name="password_edit"
+is_password="true" 
 select_on_focus="true"
   top_pad="0"
   width="135" />
@@ -127,7 +125,7 @@ top="20"
  </text>
 <combo_box
 allow_text_entry="true"
-control_name="LoginLocation"
+control_name="NextLoginLocation"
   follows="left|bottom"
   height="23"
 max_chars="128"
diff --git a/indra/newview/skins/default/xui/en/panel_main_inventory.xml b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
index 2b6e082542aedf2cdd56fa7b37e56eba58e2140b..96633cb5b4c020103d201525983963812f5bc486 100644
--- a/indra/newview/skins/default/xui/en/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_main_inventory.xml
@@ -118,6 +118,7 @@
        height="25"
        layout="topleft"
        name="options_gear_btn_panel"
+       user_resize="false"
        width="32">
           <menu_button
            follows="bottom|left"
@@ -138,6 +139,7 @@
        height="25"
        layout="topleft"
        name="add_btn_panel"
+       user_resize="false"
        width="32">
           <button
            follows="bottom|left"
@@ -158,6 +160,7 @@
        height="25"
        layout="topleft"
        name="dummy_panel"
+       user_resize="false"
        width="212">
           <icon
            follows="bottom|left|right"
@@ -174,6 +177,7 @@
        height="25"
        layout="topleft"
        name="trash_btn_panel"
+       user_resize="false"
        width="31">
           <dnd_button
            follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/panel_my_profile.xml b/indra/newview/skins/default/xui/en/panel_my_profile.xml
index 1b41f602cd59e3a2bee32dd4742308efab218c1b..5b8abaca6f1b7467f72603bf44805969da26f482 100644
--- a/indra/newview/skins/default/xui/en/panel_my_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_my_profile.xml
@@ -185,7 +185,7 @@
               </expandable_text>
             </panel>
             <text
-             follows="left|top"
+             follows="left|top|right"
              height="15"
        font.style="BOLD"
        font="SansSerifMedium"
@@ -200,7 +200,7 @@
              use_ellipses="true"
          />
             <text
-             follows="left|top"
+             follows="left|top|right"
            font.style="BOLD"
              height="10"
              layout="topleft"
@@ -213,7 +213,7 @@
             <text_editor
              allow_scroll="false"
              bg_visible="false"
-             follows="left|top"
+             follows="left|top|right"
              h_pad="0"
              height="15"
              layout="topleft"
@@ -226,7 +226,7 @@
              width="300"
              word_wrap="true" />
             <text
-             follows="left|top"
+             follows="left|top|right"
        font.style="BOLD"
              height="15"
              layout="topleft"
@@ -250,7 +250,7 @@
             <text_editor
             allow_scroll="false"
             bg_visible="false"
-            follows="left|top"
+            follows="left|top|right"
             h_pad="0"
             height="28"
             layout="topleft"
@@ -266,7 +266,7 @@
               Linden.
             </text_editor>
             <text
-             follows="left|top"
+             follows="left|top|right"
        font.style="BOLD"
              height="15"
              layout="topleft"
@@ -277,7 +277,7 @@
              value="Partner:"
              width="300" />
             <panel
-             follows="left|top"
+             follows="left|top|right"
              height="15"
              layout="topleft"
              left="10"
@@ -285,7 +285,7 @@
              top_pad="0"
              width="300">
               <text
-               follows="left|top"
+               follows="left|top|right"
                height="10"
                initial_value="(retrieving)"
                layout="topleft"
@@ -297,7 +297,7 @@
            width="300" />
             </panel>
             <text
-             follows="left|top"
+             follows="left|top|right"
        font.style="BOLD"
              height="13"
              layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
index 082d51ed3ccdebf911034fe66eea8ce3af64c1c3..8a7bd53054b60293cb4ae0a5c094d27ea651e56b 100644
--- a/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_navigation_bar.xml
@@ -4,6 +4,7 @@
  background_visible="true"
  bg_opaque_color="MouseGray"
  follows="left|top|right"
+ focus_root="true" 
  height="60"
  layout="topleft"
  name="navigation_bar"
diff --git a/indra/newview/skins/default/xui/en/panel_notify_textbox.xml b/indra/newview/skins/default/xui/en/panel_notify_textbox.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d5b6057233086b3289d54b5e68ebc8830547974d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_notify_textbox.xml
@@ -0,0 +1,94 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+   background_visible="true"
+   height="220"
+   label="instant_message"
+   layout="topleft"
+   left="0"
+   name="panel_notify_textbox"
+   top="0"
+   width="305">
+  <string
+     name="message_max_lines_count"
+     value="7" />
+  <panel
+   bevel_style="none"
+   follows="left|right|top"
+   height="185"
+   label="info_panel"
+   layout="topleft"
+   left="0"
+   name="info_panel"
+   top="0"
+   width="305">    
+    <text_editor
+     bg_readonly_color="0.0 0.0 0.0 0"
+     enabled="false"
+     follows="left|right|top|bottom"
+     font="SansSerif"
+     height="110" 
+     layout="topleft"
+     left="10"
+     mouse_opaque="false"
+     name="text_editor_box"
+     read_only="true"
+     text_color="white"
+     text_readonly_color="white"
+     top="10"
+     width="285"
+     wrap="true"
+     parse_highlights="true"
+     parse_urls="true"/>
+    <text_editor
+     parse_urls="true"
+     enabled="true"
+     follows="all"
+     height="50"
+     layout="topleft"
+     left="10"
+     max_length="250"
+     name="message"
+     parse_highlights="true"
+     read_only="false"
+     top_pad="10"
+     type="string"
+     use_ellipses="true"
+     value="message"
+     width="285"
+     word_wrap="true"
+     parse_url="false" >
+    </text_editor>
+  </panel>
+  <panel
+     background_visible="false"
+     follows="left|right|bottom"
+     height="25" 
+     width="290"
+     label="control_panel"
+     layout="topleft"
+     left="10"
+     name="control_panel"
+     top_pad="0">
+    <!-- 
+	 Notes:
+	 This panel holds the Ignore button and possibly other buttons of notification.
+      -->
+    <button
+     top="0"
+     follows="top|left"
+     height="20"
+     label="Submit"
+     layout="topleft"
+     name="btn_submit"
+     width="70" />
+    <button
+     follows="top|right"
+     height="20"
+     label="Ignore"
+     layout="topleft"
+     left="215"
+     name="ignore_btn"
+     top="0"
+     width="70" />
+  </panel>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
index f4dee9cd55f30c69e17d600b3fb855ac4703f79a..e1cd78bad8abb23b67ed936a71354b8e02fe461e 100644
--- a/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfit_edit.xml
@@ -70,7 +70,8 @@
      left="5"
      tab_stop="false"
      top="1"
-     width="30" />
+     width="30"
+     use_draw_context_alpha="false" />
     <text
      follows="top|left|right"
      font="SansSerifHugeBold"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 68c423d7dd65cfcf26c4f915c9c339c1050ccc93..6a8bf87bc56ad85a31cce7bdf72327d35b04f9cf 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -241,6 +241,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 				       height="25"
 				       layout="topleft"
 				       name="options_gear_btn_panel"
+				       user_resize="false"
 				       width="32">
 				          <menu_button
 				           follows="bottom|left"
@@ -261,6 +262,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 				       height="25"
 				       layout="topleft"
 				       name="add_btn_panel"
+				       user_resize="false"
 				       width="32">
 				          <button
 				           follows="bottom|left"
@@ -281,6 +283,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 				       height="25"
 				       layout="topleft"
 				       name="dummy_panel"
+				       user_resize="false"
 				       width="212">
 				          <icon
 				           follows="bottom|left|right"
@@ -297,6 +300,7 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 				       height="25"
 				       layout="topleft"
 				       name="trash_btn_panel"
+				       user_resize="false"
 				       width="31">
 				          <dnd_button
 				           follows="bottom|left"
diff --git a/indra/newview/skins/default/xui/en/panel_pick_info.xml b/indra/newview/skins/default/xui/en/panel_pick_info.xml
index 0496c862156c336d1bcbc61f7f838855e0a5bba0..7daa52b2d980c984bb2165846e1cafee1647a87e 100644
--- a/indra/newview/skins/default/xui/en/panel_pick_info.xml
+++ b/indra/newview/skins/default/xui/en/panel_pick_info.xml
@@ -21,7 +21,8 @@
      left="10"
      tab_stop="false"
      top="2"
-     width="30" />
+     width="30"
+     use_draw_context_alpha="false" />
     <text
      follows="top|left|right"
      font="SansSerifHugeBold"
diff --git a/indra/newview/skins/default/xui/en/panel_place_profile.xml b/indra/newview/skins/default/xui/en/panel_place_profile.xml
index 8036411d2bf628f7906b0aea37bbf6319f439b04..7e89860c608a7918b288b8750444a255c2d623a9 100644
--- a/indra/newview/skins/default/xui/en/panel_place_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_place_profile.xml
@@ -165,7 +165,8 @@
      tool_tip="Back"
      tab_stop="false"
      top="4"
-     width="30" />
+     width="30"
+     use_draw_context_alpha="false" />
     <text
      follows="top|left|right"
      font="SansSerifHugeBold"
diff --git a/indra/newview/skins/default/xui/en/panel_places.xml b/indra/newview/skins/default/xui/en/panel_places.xml
index 21314703b0aa0c96ce49eb6048daee29e95b7c86..d9c357f27769e9c40182327644b76c3c46079718 100644
--- a/indra/newview/skins/default/xui/en/panel_places.xml
+++ b/indra/newview/skins/default/xui/en/panel_places.xml
@@ -211,7 +211,7 @@ background_visible="true"
 				    user_resize="false" 
 				    auto_resize="true"
 					width="24">
-						<button
+						<menu_button
 				         follows="bottom|left|right"
 				         height="23"
 				         label="â–¼"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 006d7895b22ee03bfb6f3bab0e624010ba31fba5..37aab059a93b2cb85a603c40189b39384be8740a 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -13,238 +13,17 @@
      name="aspect_ratio_text">
         [NUM]:[DEN]
     </panel.string>
-    <panel.string
-     name="middle_mouse">
-        Middle Mouse
-    </panel.string>
-    <slider
-     can_edit_text="false"
-     control_name="ActiveFloaterTransparency"
-     decimal_digits="2"
-     follows="left|top"
-     height="16"
-     increment="0.01"
-     initial_value="0.8"
-     layout="topleft"
-     label_width="120"
-     label="Active floater opacity:"
-     left="240"
-     max_val="1.00"
-     min_val="0.00"
-     name="active"
-     show_text="true"
-     top="75"
-     width="290" />
-    <slider
-     can_edit_text="false"
-     control_name="InactiveFloaterTransparency"
-     decimal_digits="2"
-     follows="left|top"
-     height="16"
-     increment="0.01"
-     initial_value="0.5"
-     layout="topleft"
-     label_width="120"
-     label="Inctive floater opacity:"
-     left="240"
-     max_val="1.00"
-     min_val="0.00"
-     name="active"
-     show_text="true"
-     top_pad="15"
-     width="290" />
-         <icon
-	 follows="left|top"
-	 height="18"
-	 image_name="Cam_FreeCam_Off"
-         layout="topleft"
-	 name="camera_icon"
-	 mouse_opaque="false"
-	 visible="true"
-	 width="18"
-         left="30"
-         top="10"/>
-    <slider
-     can_edit_text="true"
-     control_name="CameraAngle"
-     decimal_digits="2"
-     follows="left|top"
-     height="16"
-     increment="0.025"
-     initial_value="1.57"
-     layout="topleft"
-     label_width="100"
-     label="View angle"
-     left_pad="30"
-     max_val="2.97"
-     min_val="0.17"
-     name="camera_fov"
-     show_text="false"
-     width="240" />
-    <slider
-     can_edit_text="true"
-     control_name="CameraOffsetScale"
-     decimal_digits="2"
-     follows="left|top"
-     height="16"
-     increment="0.025"
-     initial_value="1"
-     layout="topleft"
-     label="Distance"
-     left_delta="0"
-     label_width="100"
-     max_val="3"
-     min_val="0.5"
-     name="camera_offset_scale"
-     show_text="false"
-     width="240"
-     top_pad="5"/>
-     <text
-     follows="left|top"
-     type="string"
-     length="1"
-     height="10"
-     left="80"
-     name="heading2"
-     width="240"
-     top_pad="5">
-Automatic position for:
-	</text>
-        <check_box
-     control_name="EditCameraMovement"
-     height="20"
-     follows="left|top"
-     label="Build/Edit"
-     layout="topleft"
-     left_delta="30"
-     name="edit_camera_movement"
-     tool_tip="Use automatic camera positioning when entering and exiting edit mode"
-     width="280"
-     top_pad="5" />
-    <check_box
-     control_name="AppearanceCameraMovement"
-     follows="left|top"
-     height="16"
-     label="Appearance"
-     layout="topleft"
-     name="appearance_camera_movement"
-     tool_tip="Use automatic camera positioning while in edit mode"
-     width="242" />
-    <check_box
-     control_name="SidebarCameraMovement"
-     follows="left|top"
-     height="16"
-     initial_value="true"
-     label="Sidebar"
-     layout="topleft"
-     name="appearance_sidebar_positioning"
-     tool_tip="Use automatic camera positioning for sidebar"
-     width="242" />
-     	<icon
-	 follows="left|top"
-	 height="18"
-	 image_name="Move_Walk_Off"
-         layout="topleft"
-	 name="avatar_icon"
-	 mouse_opaque="false"
-	 visible="true"
-	 width="18"
-         top_pad="2"
-         left="30"
-         />
-    <check_box
-     control_name="FirstPersonAvatarVisible"
-     follows="left|top"
-     height="20"
-     label="Show me in Mouselook"
-     layout="topleft"
-     left_pad="30"
-     name="first_person_avatar_visible"
-     width="256" />
-   
-    <check_box
-     control_name="ArrowKeysAlwaysMove"
-     follows="left|top"
-     height="20"
-     label="Arrow keys always move me"
-     layout="topleft"
-     left_delta="0"
-     name="arrow_keys_move_avatar_check"
-     width="237"
-     top_pad="0"/>
-    <check_box
-     control_name="AllowTapTapHoldRun"
-     follows="left|top"
-     height="20"
-     label="Tap-tap-hold to run"
-     layout="topleft"
-     left_delta="0"
-     name="tap_tap_hold_to_run"
-     width="237"
-     top_pad="0"/>
-    <check_box
-     control_name="LipSyncEnabled"
-     follows="left|top"
-     height="20"
-     label="Move avatar lips when speaking"
-     layout="topleft"
-     left_delta="0"
-     name="enable_lip_sync"
-     width="237"
-     top_pad="0" />
-        <check_box
-     control_name="UseChatBubbles"
-     follows="left|top"
-     height="16"
-     label="Bubble chat"
-     layout="topleft"
-     left="78"
-     top_pad="6"
-     name="bubble_text_chat"
-     width="150" />
-    <slider
-     control_name="ChatBubbleOpacity"
-     follows="left|top"
-     height="16"
-     increment="0.05"
-     initial_value="1"
-     label="Opacity"
-     layout="topleft"
-     left="80"
-     label_width="156"
-     name="bubble_chat_opacity"
-     top_pad = "10"
-     width="347" />
-    <color_swatch
-     can_apply_immediately="true"
-     color="0 0 0 1"
-     control_name="BackgroundChatColor"
-     follows="left|top"
-     height="50"
-     layout="topleft"
-     left_pad="30"
-     top="190"
-     name="background"
-     tool_tip="Choose color for bubble chat"
-     width="38">
-        <color_swatch.init_callback
-		     function="Pref.getUIColor"
-		     parameter="BackgroundChatColor" />
-		    <color_swatch.commit_callback
-		     function="Pref.applyUIColor"
-		     parameter="BackgroundChatColor" />
-    </color_swatch>
   <text
    type="string"
    length="1"
    follows="left|top"
    height="12"
    layout="topleft"
-   left="80"
+   left="33"
    name="UI Size:"
    top_pad="25"
-   width="160">
-    UI size
+   width="100">
+    UI size:
   </text>
   <slider
    control_name="UIScaleFactor"
@@ -259,7 +38,7 @@ Automatic position for:
    min_val="0.75"
    name="ui_scale_slider"
    top_pad="-14"
-   width="180" />
+   width="250" />
     <check_box
      control_name="ShowScriptErrors"
      follows="left|top"
@@ -298,65 +77,45 @@ Automatic position for:
          top_delta="0"
          width="315" />
     </radio_group>
-     <check_box
+
+    <check_box
+     control_name="AllowMultipleViewers"
      follows="top|left"
-     enabled_control="EnableVoiceChat"
-     control_name="PushToTalkToggle"
      height="15"
-     label="Toggle speak on/off when I press:"
+     label="Allow Multiple Viewers"
      layout="topleft"
      left="30"
-     name="push_to_talk_toggle_check"
-     width="237"
-     tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."/>
-    <line_editor
+     name="allow_multiple_viewer_check"
+     top_pad="20"
+     width="237"/>
+    <check_box
+     control_name="ForceShowGrid"
      follows="top|left"
-     control_name="PushToTalkButton"
-     enabled="false"
-     enabled_control="EnableVoiceChat"
-     height="23"
-     left="80"
-     max_length_bytes="200"
-     name="modifier_combo"
-     label="Push-to-Speak trigger"
+     height="15"
+     label="Show Grid Selection at login"
+     layout="topleft"
+     left="30"
+     name="show_grid_selection_check"
      top_pad="5"
-     width="200" />
-    <button
-     layout="topleft" 
+     width="237"/>
+    <check_box
+     control_name="UseDebugMenus"
      follows="top|left"
-     enabled_control="EnableVoiceChat"
-     height="23"
-     label="Set Key"
-     left_pad="5"
-     name="set_voice_hotkey_button"
-     width="100">
-          <button.commit_callback
-          function="Pref.VoiceSetKey" />
-    </button>
-  <button
-   enabled_control="EnableVoiceChat"
+     height="15"
+     label="Show Advanced Menu"
+     layout="topleft"
+     left="30"
+     name="show_advanced_menu_check"
+     top_pad="5"
+     width="237"/>
+    <check_box
+     control_name="QAMode"
      follows="top|left"
-     halign="center"
-     height="23"
-     image_overlay="Refresh_Off"
-   layout="topleft" 
-     tool_tip="Reset to Middle Mouse Button"
-     mouse_opaque="true"
-     name="set_voice_middlemouse_button"
-     left_pad="5"
-     width="25">
-          <button.commit_callback
-          function="Pref.VoiceSetMiddleMouse" />
-    </button>
-  <button
- height="23"
- label="Other Devices"
- left="30"
- name="joystick_setup_button"
- top_pad="27"
- width="155">
-    <button.commit_callback
-     function="Floater.Show"
-     parameter="pref_joystick" />
-  </button>
+     height="15"
+     label="Show Developer Menu"
+     layout="topleft"
+     left="30"
+     name="show_develop_menu_check"
+     top_pad="5"
+     width="237"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
index 85824c2576d49d70d2fee7330648d74bb779fd75..a1082d9c329685785de7c981a12787bae706e1f3 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -23,7 +23,7 @@
      height="30"
      layout="topleft"
      left="40"
-	   control_name="ChatFontSize"
+	 control_name="ChatFontSize"
      name="chat_font_size"
      top_pad="0"
      width="440">
@@ -55,291 +55,7 @@
          top_delta="0"
          width="125" />
     </radio_group>
-
-    <text
-      follows="left|top"
-      layout="topleft"
-      left="30"
-      height="12"
-      name="font_colors" 
-      top_pad="10" 
-      width="120"
-      >
-    Font colors:
-    </text>  
-  
-    <color_swatch
-     can_apply_immediately="true"
-     follows="left|top"
-     height="47"
-     layout="topleft"
-     left="40"
-     name="user"
-     top_pad="10"
-     width="44" >
-		<color_swatch.init_callback
-		 function="Pref.getUIColor"
-		 parameter="UserChatColor" />
-		<color_swatch.commit_callback
-		 function="Pref.applyUIColor"
-		 parameter="UserChatColor" />
-	</color_swatch>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_pad="5"
-     mouse_opaque="false"
-     name="text_box1"
-     top_delta="5"
-     width="95">
-        Me
-    </text>
-    <color_swatch
-     can_apply_immediately="true"
-     follows="left|top"
-     height="47"
-     layout="topleft"
-     left="190"
-     name="agent"
-     top_pad="-15"
-     width="44" >
-		<color_swatch.init_callback
-		 function="Pref.getUIColor"
-		 parameter="AgentChatColor" />
-		<color_swatch.commit_callback
-		 function="Pref.applyUIColor"
-		 parameter="AgentChatColor" />
-	</color_swatch>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_pad="5"
-     mouse_opaque="false"
-     name="text_box2"
-     top_delta="5"
-     width="95">
-        Others
-    </text>
-    <color_swatch
-     can_apply_immediately="true"
-     color="LtGray"
-     follows="left|top"
-     height="47"
-     label_width="60"
-     layout="topleft"
-     left="360"
-     name="im"
-     top_pad="-15"
-     width="44">
-		<color_swatch.init_callback
-		 function="Pref.getUIColor"
-		 parameter="IMChatColor" />
-		<color_swatch.commit_callback
-		 function="Pref.applyUIColor"
-		 parameter="IMChatColor" />
-	</color_swatch>
-	<text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_pad="5"
-     mouse_opaque="false"
-     name="text_box3"
-     top_delta="5"
-     width="95">
-        IM
-    </text>
-    <color_swatch
-     can_apply_immediately="true"
-     color="LtGray"
-     follows="left|top"
-     height="47"
-     label_width="44"
-     layout="topleft"
-     left="40"
-     name="system"
-     top_pad="22"
-     width="44" >
-		<color_swatch.init_callback
-		 function="Pref.getUIColor"
-		 parameter="SystemChatColor" />
-		<color_swatch.commit_callback
-		 function="Pref.applyUIColor"
-		 parameter="SystemChatColor" />
-	</color_swatch>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_pad="5"
-     mouse_opaque="false"
-     name="text_box4"
-     top_delta="5"
-     width="95">
-        System
-    </text>
-    <color_swatch
-     can_apply_immediately="true"
-     color="Red"
-     follows="left|top"
-     height="47"
-     layout="topleft"
-     left="190"
-     name="script_error"
-     top_pad="-15"
-     width="44">
-		<color_swatch.init_callback
-		 function="Pref.getUIColor"
-		 parameter="ScriptErrorColor" />
-		<color_swatch.commit_callback
-		 function="Pref.applyUIColor"
-		 parameter="ScriptErrorColor" />
-	</color_swatch>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_pad="5"
-     mouse_opaque="false"
-     name="text_box5"
-     top_delta="5"
-     width="95">
-        Errors
-    </text>
-    <color_swatch
-     can_apply_immediately="true"
-     color="EmphasisColor_35"
-     follows="left|top"
-     height="47"
-     layout="topleft"
-     left="360"
-     name="objects"
-     top_pad="-15"
-     width="44" >
-		<color_swatch.init_callback
-		 function="Pref.getUIColor"
-		 parameter="ObjectChatColor" />
-		<color_swatch.commit_callback
-		 function="Pref.applyUIColor"
-		 parameter="ObjectChatColor" />
-	</color_swatch>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_pad="5"
-     mouse_opaque="false"
-     name="text_box6"
-     top_delta="5"
-     width="95">
-        Objects
-    </text>
-    <color_swatch
-     can_apply_immediately="true"
-     color="LtYellow"
-     follows="left|top"
-     height="47"
-     layout="topleft"
-     left="40"
-     name="owner"
-     top_pad="22"
-     width="44" >
-		<color_swatch.init_callback
-		 function="Pref.getUIColor"
-		 parameter="llOwnerSayChatColor" />
-		<color_swatch.commit_callback
-		 function="Pref.applyUIColor"
-		 parameter="llOwnerSayChatColor" />
-	</color_swatch>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_pad="5"
-     mouse_opaque="false"
-     name="text_box7"
-     top_delta="5"
-     width="95">
-        Owner
-    </text>
-    <color_swatch
-     can_apply_immediately="true"
-     color="EmphasisColor"
-     follows="left|top"
-     height="47"
-     layout="topleft"
-     left="190"
-     name="links"
-     top_pad="-15"
-     width="44" >
-		<color_swatch.init_callback
-		 function="Pref.getUIColor"
-		 parameter="HTMLLinkColor" />
-		<color_swatch.commit_callback
-		 function="Pref.applyUIColor"
-		 parameter="HTMLLinkColor" />
-	</color_swatch>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_pad="5"
-     mouse_opaque="false"
-     name="text_box9"
-     top_delta="5"
-     width="95">
-        URLs
-    </text>
-    <spinner
-     control_name="NearbyToastLifeTime"
-     decimal_digits="0"
-     follows="left|top"
-     height="23"
-     increment="1"
-     initial_value="23"
-     label="Nearby chat toasts life time:"
-     label_width="190"
-     layout="topleft"
-     left="290"
-     max_val="60"
-     min_val="1"
-     name="nearby_toasts_lifetime"
-     top_pad="33"
-     width="210" />
-    <spinner
-     control_name="NearbyToastFadingTime"
-     decimal_digits="0"
-     follows="left|top"
-     height="23"
-     increment="1"
-     initial_value="3"
-     label="Nearby chat toasts fading time:"
-     label_width="190"
-     layout="topleft"
-     left_delta="00"
-     max_val="60"
-     min_val="0"
-     name="nearby_toasts_fadingtime"
-     top_pad="15"
-     width="210" />
+    
     <check_box
      control_name="PlayTypingAnim"
      height="16"
@@ -348,7 +64,7 @@
      layout="topleft"
      left="30"
      name="play_typing_animation"
-     top="205"
+     top_pad="10"
      width="400" />
     <check_box
      enabled="false"
@@ -368,6 +84,16 @@
      name="plain_text_chat_history"
      top_pad="5"
      width="400" />
+    <check_box
+     control_name="UseChatBubbles"
+     follows="left|top"
+     height="16"
+     label="Bubble Chat"
+     layout="topleft"
+     left_delta="0"
+     top_pad="5"
+     name="bubble_text_chat"
+     width="150" />     
     <text
      name="show_ims_in_label"
      follows="left|top"
@@ -375,7 +101,7 @@
      left="30"
      height="20"
      width="170"
-     top_pad="7">
+     top_pad="15">
      Show IMs in:
     </text>
     <text
@@ -385,9 +111,8 @@
      top_delta="0" 
      left="170" 
   	 height="20"
-	   width="130"
-     text_color="White_25"
-	  >
+	 width="130"
+     text_color="White_25">
       (requires restart)
       </text>
     <radio_group
@@ -401,7 +126,7 @@
      width="150">
      <radio_item
       height="16"
-      label="Separate windows"
+      label="Separate Windows"
       layout="topleft"
       left="0"
       name="radio"
@@ -422,19 +147,19 @@
      name="disable_toast_label"
      follows="left|top"
      layout="topleft"
-     top_delta="-22" 
-     left="280" 
+     top_pad="20" 
+     left="30" 
      height="10"
      width="180">
-      Enable Incoming Chat popups:
+      Enable incoming chat popups:
       </text>
     <check_box
      control_name="EnableGroupChatPopups"
      name="EnableGroupChatPopups"
      label="Group Chats" 
      layout="topleft"
-     top_delta="18" 
-     left="295" 
+     top_pad="5" 
+     left_delta="10" 
      height="20"
      tool_tip="Check to see popups when a Group Chat message arrives"
      width="400" />
@@ -443,11 +168,43 @@
      name="EnableIMChatPopups"
      label="IM Chats" 
      layout="topleft"
-     top_delta="22" 
-     left="295" 
-     height="20"
+     top_pad="5"
+     height="16"
      tool_tip="Check to see popups when an instant message arrives"
      width="400" />
+    <spinner
+     control_name="NearbyToastLifeTime"
+     decimal_digits="0"
+     follows="left|top"
+     height="23"
+     increment="1"
+     initial_value="23"
+     label="Nearby chat toasts life time:"
+     label_width="190"
+     layout="topleft"
+     left="45"
+     max_val="60"
+     min_val="1"
+     name="nearby_toasts_lifetime"
+     top_pad="10"
+     width="230" />
+    <spinner
+     control_name="NearbyToastFadingTime"
+     decimal_digits="0"
+     follows="left|top"
+     height="23"
+     increment="1"
+     initial_value="3"
+     label="Nearby chat toasts fading time:"
+     label_width="190"
+     layout="topleft"
+     left_delta="0"
+     max_val="60"
+     min_val="0"
+     name="nearby_toasts_fadingtime"
+     top_pad="3"
+     width="230" />
+    
     <check_box
      control_name="TranslateChat"
      enabled="true"
@@ -456,7 +213,7 @@
      layout="topleft"
      left="30"
      name="translate_chat_checkbox"
-     bottom_delta="40"
+     bottom_delta="30"
      width="400" />
     <text
      bottom_delta="30"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8a37822413f23e3dc5c01d16108cd6056886b539
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml
@@ -0,0 +1,363 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="408"
+ label="Colors"
+ layout="topleft"
+ left="102"
+ name="colors_panel"
+ top="1"
+ width="517">
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="15"
+   layout="topleft"
+   left="30"
+   name="effects_color_textbox"
+   top_pad="10"
+   width="200">
+    My effects (selection beam):
+  </text>
+  <color_swatch
+	 can_apply_immediately="true"
+     follows="left|top"
+     height="24"
+     label_height="0"
+     layout="topleft"
+     left="40"
+     name="effect_color_swatch"
+     tool_tip="Click to open Color Picker"
+     width="44">
+    <color_swatch.init_callback
+		 function="Pref.getUIColor"
+		 parameter="EffectColor" />
+    <color_swatch.commit_callback
+		 function="Pref.applyUIColor"
+		 parameter="EffectColor" />
+    <color_swatch.caption_text
+    height="0" />
+  </color_swatch>
+  <text
+   follows="left|top"
+   layout="topleft"
+   left="30"
+   height="12"
+   name="font_colors"
+   top_pad="20"
+   width="120"
+   >
+    Chat font colors:
+  </text>
+  <color_swatch
+   can_apply_immediately="true"
+   follows="left|top"
+   height="24"
+   label_height="0"
+   layout="topleft"
+   left="40"
+   name="user"
+   top_pad="10"
+   width="44" >
+    <color_swatch.init_callback
+		 function="Pref.getUIColor"
+		 parameter="UserChatColor" />
+    <color_swatch.commit_callback
+		 function="Pref.applyUIColor"
+		 parameter="UserChatColor" />
+  </color_swatch>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="10"
+   layout="topleft"
+   left_pad="5"
+   mouse_opaque="false"
+   name="text_box1"
+   top_delta="5"
+   width="95">
+    Me
+  </text>
+  <color_swatch
+   can_apply_immediately="true"
+   follows="left|top"
+   height="24"
+   label_height="0"
+   layout="topleft"
+   left="190"
+   name="agent"
+   top_pad="-15"
+   width="44" >
+    <color_swatch.init_callback
+		 function="Pref.getUIColor"
+		 parameter="AgentChatColor" />
+    <color_swatch.commit_callback
+		 function="Pref.applyUIColor"
+		 parameter="AgentChatColor" />
+  </color_swatch>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="10"
+   layout="topleft"
+   left_pad="5"
+   mouse_opaque="false"
+   name="text_box2"
+   top_delta="5"
+   width="95">
+    Others
+  </text>
+  <color_swatch
+   can_apply_immediately="true"
+   color="EmphasisColor_35"
+   follows="left|top"
+   height="24"
+   label_height="0"
+   label_width="60"
+   layout="topleft"
+   left="360"
+   name="objects"
+   top_pad="-15"
+   width="44">
+    <color_swatch.init_callback
+		 function="Pref.getUIColor"
+		 parameter="ObjectChatColor" />
+    <color_swatch.commit_callback
+		 function="Pref.applyUIColor"
+		 parameter="ObjectChatColor" />
+  </color_swatch>
+  <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="false"
+     name="text_box3"
+     top_delta="5"
+     width="95">
+    Objects
+  </text>
+  <color_swatch
+   can_apply_immediately="true"
+   color="LtGray"
+   follows="left|top"
+   height="24"
+   label_height="0"
+   label_width="44"
+   layout="topleft"
+   left="40"
+   name="system"
+   top_pad="22"
+   width="44" >
+    <color_swatch.init_callback
+		 function="Pref.getUIColor"
+		 parameter="SystemChatColor" />
+    <color_swatch.commit_callback
+		 function="Pref.applyUIColor"
+		 parameter="SystemChatColor" />
+  </color_swatch>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="10"
+   layout="topleft"
+   left_pad="5"
+   mouse_opaque="false"
+   name="text_box4"
+   top_delta="5"
+   width="95">
+    System
+  </text>
+  <color_swatch
+   can_apply_immediately="true"
+   color="Red"
+   follows="left|top"
+   height="24"
+   label_height="0"
+   layout="topleft"
+   left="190"
+   name="script_error"
+   top_pad="-15"
+   width="44">
+    <color_swatch.init_callback
+		 function="Pref.getUIColor"
+		 parameter="ScriptErrorColor" />
+    <color_swatch.commit_callback
+		 function="Pref.applyUIColor"
+		 parameter="ScriptErrorColor" />
+  </color_swatch>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="10"
+   layout="topleft"
+   left_pad="5"
+   mouse_opaque="false"
+   name="text_box5"
+   top_delta="5"
+   width="95">
+    Errors
+  </text>
+  <color_swatch
+   can_apply_immediately="true"
+   color="LtYellow"
+   follows="left|top"
+   height="24"
+   label_height="0"
+   layout="topleft"
+   left="40"
+   name="owner"
+   top_pad="22"
+   width="44" >
+    <color_swatch.init_callback
+		 function="Pref.getUIColor"
+		 parameter="llOwnerSayChatColor" />
+    <color_swatch.commit_callback
+		 function="Pref.applyUIColor"
+		 parameter="llOwnerSayChatColor" />
+  </color_swatch>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="10"
+   layout="topleft"
+   left_pad="5"
+   mouse_opaque="false"
+   name="text_box7"
+   top_delta="5"
+   width="95">
+    Owner
+  </text>
+  <color_swatch
+   can_apply_immediately="true"
+   color="EmphasisColor"
+   follows="left|top"
+   height="24"
+   label_height="0"
+   layout="topleft"
+   left="190"
+   name="links"
+   top_pad="-15"
+   width="44" >
+    <color_swatch.init_callback
+		 function="Pref.getUIColor"
+		 parameter="HTMLLinkColor" />
+    <color_swatch.commit_callback
+		 function="Pref.applyUIColor"
+		 parameter="HTMLLinkColor" />
+  </color_swatch>
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="10"
+   layout="topleft"
+   left_pad="5"
+   mouse_opaque="false"
+   name="text_box9"
+   top_delta="5"
+   width="95">
+    URLs
+  </text>
+  <text
+   follows="left|top"
+   layout="topleft"
+   left="30"
+   height="12"
+   name="bubble_chat"
+   top_pad="20"
+   width="450"
+   >
+    Name tag background color (also affects Bubble Chat):
+  </text>
+  <color_swatch
+   can_apply_immediately="true"
+   color="0 0 0 1"
+   control_name="NameTagBackground"
+   follows="left|top"
+   height="24"
+   label_height="0"
+   layout="topleft"
+   left_delta="10"
+   top_pad="5"
+   name="background"
+   tool_tip="Choose name tag color"
+   width="44">
+   <color_swatch.init_callback
+    function="Pref.getUIColor"
+    parameter="NameTagBackground" />
+   <color_swatch.commit_callback
+    function="Pref.applyUIColor"
+    parameter="NameTagBackground" />
+  </color_swatch>
+  <slider
+   control_name="ChatBubbleOpacity"
+   follows="left|top"
+   height="16"
+   increment="0.05"
+   initial_value="1"
+   label="Opacity:"
+   layout="topleft"
+   left_pad="10"
+   label_width="70"
+   name="bubble_chat_opacity"
+   tool_tip="Choose name tag opacity"
+   top_delta = "6"
+   width="378" />
+  <text
+   follows="left|top"
+   layout="topleft"
+   left="30"
+   height="12"
+   name="floater_opacity"
+   top_pad="15"
+   width="120"
+   >
+    Floater Opacity:
+  </text>
+ <slider
+   can_edit_text="false"
+   control_name="ActiveFloaterTransparency"
+   decimal_digits="2"
+   follows="left|top"
+   height="16"
+   increment="0.01"
+   initial_value="0.8"
+   layout="topleft"
+   label_width="115"
+   label="Active:"
+   left="50"
+   max_val="1.00"
+   min_val="0.00"
+   name="active"
+   show_text="true"
+   top_pad="5"
+   width="415" />
+  <slider
+   can_edit_text="false"
+   control_name="InactiveFloaterTransparency"
+   decimal_digits="2"
+   follows="left|top"
+   height="16"
+   increment="0.01"
+   initial_value="0.5"
+   layout="topleft"
+   label_width="115"
+   label="Inactive:"
+   left="50"
+   max_val="1.00"
+   min_val="0.00"
+   name="inactive"
+   show_text="true"
+   top_pad="5"
+   width="415" />
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index 392d50fc4248fac22aad18e47305a440bebf1458..36f8f991789402b79939992a6e57177bc499235b 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -106,7 +106,7 @@
      height="15"
      layout="topleft"
      left="30"
-     top_pad="14"
+     top_pad="8"
      name="maturity_desired_prompt"
      width="200">
         I want to access content rated:
@@ -177,7 +177,7 @@
      layout="topleft"
      left="30"
      name="start_location_textbox"
-     top_pad="15"
+     top_pad="8"
      width="394">
         Start location:
     </text>
@@ -216,7 +216,7 @@
     layout="topleft"
     left="30"
     name="name_tags_textbox"
-    top_pad="14"
+    top_pad="10"
     width="400">
        Name tags:
    </text>
@@ -224,8 +224,8 @@
      control_name="AvatarNameTagMode"
      height="20"
      layout="topleft"
-     left="50"
-     top_pad="5" 
+     left="35"
+     top_pad="0" 
      name="Name_Tag_Preference">
         <radio_item
          label="Off"
@@ -261,9 +261,9 @@
      height="16"
      label="My name"
      layout="topleft"
-     left="70"
+     left="35"
      name="show_my_name_checkbox1"
-	 top_pad="0"
+	 top_pad="2"
      width="100" />
    <check_box
      control_name="NameTagShowUsernames"
@@ -271,7 +271,7 @@
      height="16"
      label="Usernames"
      layout="topleft"
-     left_pad="70"
+     left_pad="50"
      name="show_slids"
      tool_tip="Show username, like bobsmith123"
      top_delta="0" />
@@ -281,72 +281,103 @@
      height="16"
      label="Group titles"
      layout="topleft"
-     left="70"
+     left="35"
      width="100" 
      name="show_all_title_checkbox1"
 	 tool_tip="Show group titles, like Officer or Member"
-     top_pad="5" />
-
-   <check_box
-    control_name="NameTagShowFriends"
+     top_pad="3" />
+    <check_box
+     control_name="NameTagShowFriends"
 	 enabled_control="AvatarNameTagMode"
      height="16"
-    label="Highlight friends"
+     label="Highlight friends"
      layout="topleft"
-    left_pad="70"
-    name="show_friends"
-    tool_tip="Highlight the name tags of your friends"
-    top_delta="0" />
-
+     left_pad="50"
+     name="show_friends"
+     tool_tip="Highlight the name tags of your friends"/>     
+    <check_box
+	 control_name="UseDisplayNames"
+	 follows="top|left"
+	 height="16"
+	 label="View Display Names"
+	 layout="topleft"
+	 left="35"
+	 name="display_names_check"
+	 width="237"
+	 tool_tip="Check to use display names in chat, IM, name tags, etc."
+	 top_pad="3"/>
+	 
+	<check_box
+	 control_name="EnableUIHints"
+	 follows="top|left"
+	 height="16"
+	 label="Enable Viewer UI Hints"
+	 layout="topleft"
+	 left="27"
+	 name="viewer_hints_check"
+	 top_pad="5"
+	 width="237"/>
+	 
+	<text
+	 type="string"
+	 length="1"
+	 follows="left|top"
+	 height="15"
+	 layout="topleft"
+	 left="30"
+	 name="inworld_typing_rg_label"
+	 top_pad="6"
+	 width="400">
+       Pressing letter keys:
+   </text>
+   <radio_group
+     control_name="LetterKeysFocusChatBar" 
+     height="20"
+     layout="topleft"
+     left="35"
+     top_pad="0" 
+     name="inworld_typing_preference">
+        <radio_item
+         label="Starts local chat"
+         name="radio_start_chat"
+         top_delta="20" 
+         layout="topleft"
+         height="16" 
+         left="0" 
+         value="1"
+         width="150" />
+        <radio_item
+         label="Affects movement (i.e. WASD)"
+         left_pad="0"
+         layout="topleft"
+         top_delta="0" 
+         height="16" 
+         name="radio_move"
+         value="0"
+         width="75" />
+    </radio_group>
+    
     <text
      type="string"
      length="1"
      follows="left|top"
-     height="15"
+     height="13"
      layout="topleft"
      left="30"
-     name="effects_color_textbox"
-     top_pad="9"
-     width="200">
-        My effects:
-    </text>
-    <text
-      type="string"
-      length="1"
-      follows="left|top"
-      height="13"
-      layout="topleft"
-      left_pad="5"
-      name="title_afk_text"
-      top_delta="0" 
-      width="190">
-    Away timeout:
+     name="title_afk_text"
+     top_pad="4" 
+     width="190">
+    	Away timeout:
     </text>
-    <color_swatch
-	 can_apply_immediately="true"
-     follows="left|top"
-     height="50"
-     layout="topleft"
-     left="50"
-     name="effect_color_swatch"
-     tool_tip="Click to open Color Picker"
-     width="38">
-		<color_swatch.init_callback
-		 function="Pref.getUIColor"
-		 parameter="EffectColor" />
-		<color_swatch.commit_callback
-		 function="Pref.applyUIColor"
-		 parameter="EffectColor" />
-	</color_swatch>
   <combo_box
-            height="23"
-            layout="topleft"
-            control_name="AFKTimeout"
-            left_pad="160"
-            label="Away timeout:"
-            top_delta="0"
-            name="afk"
-            width="130">
+     height="23"
+     layout="topleft"
+     control_name="AFKTimeout"
+     left="30"
+     label="Away timeout:"
+     top_pad="2"
+     name="afk"
+     width="130">
     <combo_box.item
      label="2 minutes"
      name="item0"
@@ -368,17 +399,6 @@
      name="item4"
      value="0" />
   </combo_box>
-  <check_box
-control_name="UseDisplayNames"
-follows="top|left"
-height="14"
-label="View Display Names"
-layout="topleft"
-left="30"
-name="display_names_check"
-width="237"
-tool_tip="Check to use display names in chat, IM, name tags, etc."
-top_pad="20"/>
     <text
      type="string"
      length="1"
@@ -388,7 +408,7 @@ top_pad="20"/>
      left="30"
      mouse_opaque="false"
      name="text_box3"
-     top_pad="10"
+     top_pad="5"
      width="240">
        Busy mode response:
     </text>
@@ -399,11 +419,11 @@ top_pad="20"/>
       use_ellipses="false"
      commit_on_focus_lost = "true"
      follows="left|top"
-     height="42"
+     height="29"
      layout="topleft"
      left="50"
      name="busy_response"
-     width="450"
+     width="470"
      word_wrap="true">
        log_in_to_change
     </text_editor>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 7d49a671e66d258865730cc6635a8ca2edd07039..6573822d1a1b493a5da26081806d590e2b4eab78 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -163,536 +163,546 @@
      top="76"
      width="485">
 		<text
-		type="string"
-		length="1"
-		follows="left|top"
-		height="12"
-		layout="topleft"
-		left_delta="5"
-		name="ShadersText"
-		top="3"
-		width="128">
+		 type="string"
+		 length="1"
+		 follows="left|top"
+		 height="12"
+		 layout="topleft"
+		 left_delta="5"
+		 name="ShadersText"
+		 top="3"
+		 width="128">
 			Shaders:
 		</text>
 		<check_box
-		control_name="RenderObjectBump"
-		height="16"
-		initial_value="true"
-		label="Bump mapping and shiny"
-		layout="topleft"
-		left_delta="0"
-		name="BumpShiny"
-		top_pad="7"
-		width="256" />
+		 control_name="RenderTransparentWater"
+		 height="16"
+		 initial_value="true"
+		 label="Transparent Water"
+		 layout="topleft"
+		 left_delta="0"
+		 name="TransparentWater"
+		 top_pad="7"
+		 width="256" />
 		<check_box
-		control_name="VertexShaderEnable"
-		height="16"
-		initial_value="true"
-		label="Basic shaders"
-		layout="topleft"
-		left_delta="0"
-		name="BasicShaders"
-		tool_tip="Disabling this option may prevent some graphics card drivers from crashing"
-		top_pad="1"
-		width="315">
+		 control_name="RenderObjectBump"
+		 height="16"
+		 initial_value="true"
+		 label="Bump mapping and shiny"
+		 layout="topleft"
+		 left_delta="0"
+		 name="BumpShiny"
+		 top_pad="1"
+		 width="256" />
+		<check_box
+		 control_name="VertexShaderEnable"
+		 height="16"
+		 initial_value="true"
+		 label="Basic shaders"
+		 layout="topleft"
+		 left_delta="0"
+		 name="BasicShaders"
+		 tool_tip="Disabling this option may prevent some graphics card drivers from crashing"
+		 top_pad="1"
+		 width="315">
 			<check_box.commit_callback
-			function="Pref.VertexShaderEnable" />
+		     function="Pref.VertexShaderEnable" />
 		</check_box>
 		<check_box
-		control_name="WindLightUseAtmosShaders"
-		height="16"
-		initial_value="true"
-		label="Atmospheric shaders"
-		layout="topleft"
-		left_delta="0"
-		name="WindLightUseAtmosShaders"
-		top_pad="1"
-		width="256">
+		 control_name="WindLightUseAtmosShaders"
+		 height="16"
+		 initial_value="true"
+		 label="Atmospheric shaders"
+		 layout="topleft"
+		 left_delta="0"
+		 name="WindLightUseAtmosShaders"
+		 top_pad="1"
+		 width="256">
 			<check_box.commit_callback
-			function="Pref.VertexShaderEnable" />
+			 function="Pref.VertexShaderEnable" />
 		</check_box>
 <!-- DISABLED UNTIL WE REALLY WANT TO SUPPORT THIS
-    <check_box
-		control_name="RenderDeferred"
-		height="16"
-		initial_value="true"
-		label="Lighting and Shadows"
-		layout="topleft"
-		left_delta="0"
-		name="UseLightShaders"
-		top_pad="1"
-		width="256">
-      <check_box.commit_callback
-			function="Pref.VertexShaderEnable" />
-    </check_box>
-    <check_box
-		control_name="RenderDeferredSSAO"
-		height="16"
-		initial_value="true"
-		label="Ambient Occlusion"
-		layout="topleft"
-		left_delta="0"
-		name="UseSSAO"
-		top_pad="1"
-		width="256">
-      <check_box.commit_callback
-			function="Pref.VertexShaderEnable" />
-    </check_box>
+    	<check_box
+		 control_name="RenderDeferred"
+		 height="16"
+		 initial_value="true"
+		 label="Lighting and Shadows"
+		 layout="topleft"
+		 left_delta="0"
+		 name="UseLightShaders"
+		 top_pad="1"
+		 width="256">
+         	<check_box.commit_callback
+			 function="Pref.VertexShaderEnable" />
+    	</check_box>
+    	<check_box
+		 control_name="RenderDeferredSSAO"
+		 height="16"
+		 initial_value="true"
+		 label="Ambient Occlusion"
+		 layout="topleft"
+		 left_delta="0"
+		 name="UseSSAO"
+		 top_pad="1"
+		 width="256">
+         	<check_box.commit_callback
+			 function="Pref.VertexShaderEnable" />
+    	</check_box>
 
-     <text
-    type="string"
-    length="1"
-    top_pad="8"
-    follows="top|left"
-    height="23"
-    width="110"
-    word_wrap="true"
-    layout="topleft"
-    left="10"
-    name="shadows_label">
-        Shadows:
-      </text>
-      <combo_box
-      control_name="RenderShadowDetail"
-      height="23"
-      layout="topleft"
-      left="10"
-      top_pad="0" 
-      name="ShadowDetail"
-      width="150">
-        <combo_box.item
-        label="None"
-        name="0"
-        value="0"/>
-        <combo_box.item
-        label="Sun/Moon"
-        name="1"
-        value="1"/>
-        <combo_box.item
-        label="Sun/Moon + Projectors"
-        name="2"
-        value="2"/>
-      </combo_box>
+        <text
+         type="string"
+         length="1"
+         top_pad="8"
+         follows="top|left"
+         height="23"
+         width="110"
+         word_wrap="true"
+         layout="topleft"
+         left="10"
+         name="shadows_label">
+         	Shadows:
+        </text>
+        <combo_box
+         control_name="RenderShadowDetail"
+         height="23"
+         layout="topleft"
+         left="10"
+         top_pad="0" 
+         name="ShadowDetail"
+         width="150">
+           <combo_box.item
+            label="None"
+            name="0"
+            value="0"/>
+           <combo_box.item
+            label="Sun/Moon"
+            name="1"
+            value="1"/>
+           <combo_box.item
+            label="Sun/Moon + Projectors"
+            name="2"
+            value="2"/>
+        </combo_box>
 -->
-      <text
-  type="string"
-  length="1"
-  top_pad="8"
-  follows="top|left"
-  height="23"
-  width="110"
-  word_wrap="true"
-  layout="topleft"
-  left="10"
-  name="reflection_label">
-        Water Reflections:
-      </text>
-      <combo_box
-      control_name="RenderReflectionDetail"
-      height="23"
-      layout="topleft"
-      left_delta="10"
-      top_pad ="0"
-      name="Reflections"
-      width="150">
-        <combo_box.item
-        label="Minimal"
-        name="0"
-        value="0"/>
-        <combo_box.item
-        label="Terrain and trees"
-        name="1"
-        value="1"/>
-        <combo_box.item
-        label="All static objects"
-        name="2"
-        value="2"/>
-        <combo_box.item
-        label="All avatars and objects"
-        name="3"
-        value="3"/>
-        <combo_box.item
-        label="Everything"
-        name="4"
-        value="4"/>
-      </combo_box>
+        <text
+         type="string"
+         length="1"
+         top_pad="8"
+         follows="top|left"
+         height="12"
+         width="110"
+         word_wrap="true"
+         layout="topleft"
+         left="05"
+         name="reflection_label">
+            Water Reflections:
+        </text>
+        <combo_box
+         control_name="RenderReflectionDetail"
+         height="18"
+         layout="topleft"
+         left_delta="10"
+         top_pad ="3"
+         name="Reflections"
+         width="150">
+            <combo_box.item
+             label="Minimal"
+             name="0"
+             value="0"/>
+            <combo_box.item
+             label="Terrain and trees"
+             name="1"
+             value="1"/>
+            <combo_box.item
+             label="All static objects"
+             name="2"
+             value="2"/>
+            <combo_box.item
+             label="All avatars and objects"
+             name="3"
+             value="3"/>
+            <combo_box.item
+             label="Everything"
+             name="4"
+             value="4"/>
+        </combo_box>
     
 		<slider
-		control_name="RenderFarClip"
-		decimal_digits="0"
-		follows="left|top"
-		height="16"
-		increment="8"
-		initial_value="160"
-		label="Draw distance:"
-		label_width="185"
-		layout="topleft"
-		left="200"
-		max_val="512"
-		min_val="64"
-		name="DrawDistance"
-		top="3"
-		width="296" />
+		 control_name="RenderFarClip"
+		 decimal_digits="0"
+		 follows="left|top"
+		 height="16"
+		 increment="8"
+		 initial_value="160"
+		 label="Draw distance:"
+		 label_width="185"
+		 layout="topleft"
+		 left="200"
+		 max_val="512"
+		 min_val="64"
+		 name="DrawDistance"
+		 top="3"
+		 width="296" />
 		<text
-		type="string"
-		length="1"
-		follows="left|top"
-		height="12"
-		layout="topleft"
-		left_delta="291"
-		name="DrawDistanceMeterText2"
-		top_delta="0"
-		width="128">
+		 type="string"
+		 length="1"
+		 follows="left|top"
+		 height="12"
+		 layout="topleft"
+		 left_delta="291"
+		 name="DrawDistanceMeterText2"
+		 top_delta="0"
+		 width="128">
 			m
 		</text>    
 		<slider
-		control_name="RenderMaxPartCount"
-		decimal_digits="0"
-		follows="left|top"
-		height="16"
-		increment="256"
-		initial_value="4096"
-		label="Max. particle count:"
-		label_width="185"
-		layout="topleft"
-		left="200"
-		max_val="8192"
-		name="MaxParticleCount"
-		top_pad="7"
-		width="303" />
-    <slider
-    control_name="RenderAvatarMaxVisible"
-    decimal_digits="0"
-    follows="left|top"
-    height="16"
-    increment="1"
-    initial_value="12"
-    label="Max. # of non-impostor avatars:"
-    label_width="185"
-    layout="topleft"
-    left_delta="0"
-    max_val="65"
-    min_val="1"
-    name="MaxNumberAvatarDrawn"
-    top_pad="4"
-    width="290" />
+		 control_name="RenderMaxPartCount"
+		 decimal_digits="0"
+		 follows="left|top"
+		 height="16"
+		 increment="256"
+		 initial_value="4096"
+		 label="Max. particle count:"
+		 label_width="185"
+		 layout="topleft"
+		 left="200"
+		 max_val="8192"
+		 name="MaxParticleCount"
+		 top_pad="7"
+		 width="303" />
+        <slider
+         control_name="RenderAvatarMaxVisible"
+         decimal_digits="0"
+         follows="left|top"
+         height="16"
+         increment="1"
+         initial_value="12"
+         label="Max. # of non-impostor avatars:"
+         label_width="185"
+         layout="topleft"
+         left_delta="0"
+         max_val="65"
+         min_val="1"
+         name="MaxNumberAvatarDrawn"
+         top_pad="4"
+         width="290" />
 		<slider
-		control_name="RenderGlowResolutionPow"
-		decimal_digits="0"
-		follows="left|top"
-		height="16"
-		increment="1"
-		initial_value="8"
-		label="Post process quality:"
-		label_width="185"
-		layout="topleft"
-		left="200"
-		max_val="9"
-		min_val="8"
-		name="RenderPostProcess"
-		show_text="false"
-		top_pad="4"
-		width="264">
+ 		 control_name="RenderGlowResolutionPow"
+		 decimal_digits="0"
+		 follows="left|top"
+		 height="16"
+		 increment="1"
+		 initial_value="8"
+		 label="Post process quality:"
+		 label_width="185"
+		 layout="topleft"
+		 left="200"
+		 max_val="9"
+		 min_val="8"
+		 name="RenderPostProcess"
+		 show_text="false"
+		 top_pad="4"
+		 width="264">
 			<slider.commit_callback
-			function="Pref.UpdateSliderText"
-			parameter="PostProcessText" />
+			 function="Pref.UpdateSliderText"
+			 parameter="PostProcessText" />
 		</slider>
 		<text
-		type="string"
-		length="1"
-		follows="left|top"
-		height="12"
-		layout="topleft"
-		left_delta="0"
-		name="MeshDetailText"
-		top_pad="5"
-		width="128">
+		 type="string"
+		 length="1"
+		 follows="left|top"
+		 height="12"
+		 layout="topleft"
+		 left_delta="0"
+		 name="MeshDetailText"
+		 top_pad="5"
+		 width="128">
 			Mesh detail:
 		</text>
 		<slider
-		control_name="RenderVolumeLODFactor"
-		follows="left|top"
-		height="16"
-		increment="0.125"
-		initial_value="160"
-		label="  Objects:"
-		label_width="185"
-		layout="topleft"
-		left_delta="0"
-		max_val="2"
-		name="ObjectMeshDetail"
-		show_text="false"
-		top_pad="6"
-		width="264">
+		 control_name="RenderVolumeLODFactor"
+		 follows="left|top"
+		 height="16"
+		 increment="0.125"
+		 initial_value="160"
+		 label="  Objects:"
+		 label_width="185"
+		 layout="topleft"
+		 left_delta="0"
+		 max_val="2"
+		 name="ObjectMeshDetail"
+		 show_text="false"
+		 top_pad="6"
+		 width="264">
 			<slider.commit_callback
-			function="Pref.UpdateSliderText"
-			parameter="ObjectMeshDetailText" />
+			 function="Pref.UpdateSliderText"
+			 parameter="ObjectMeshDetailText" />
 		</slider>
 		<slider
-		control_name="RenderFlexTimeFactor"
-		follows="left|top"
-		height="16"
-		initial_value="160"
-		label="  Flexiprims:"
-		label_width="185"
-		layout="topleft"
-		left_delta="0"
-		name="FlexibleMeshDetail"
-		show_text="false"
-		top_pad="4"
-		width="264">
+		 control_name="RenderFlexTimeFactor"
+		 follows="left|top"
+		 height="16"
+		 initial_value="160"
+		 label="  Flexiprims:"
+		 label_width="185"
+		 layout="topleft"
+		 left_delta="0"
+		 name="FlexibleMeshDetail"
+		 show_text="false"
+		 top_pad="4"
+		 width="264">
 			<slider.commit_callback
-			function="Pref.UpdateSliderText"
-			parameter="FlexibleMeshDetailText" />
+			 function="Pref.UpdateSliderText"
+			 parameter="FlexibleMeshDetailText" />
 		</slider>
         <slider
-        control_name="RenderTreeLODFactor"
-        follows="left|top"
-        height="16"
-        increment="0.125"
-        initial_value="160"
-        label="  Trees:"
-        label_width="185"
-        layout="topleft"
-        left_delta="0"
-        name="TreeMeshDetail"
-        show_text="false"
-        top_pad="4"
-        width="264">
-           <slider.commit_callback
-            function="Pref.UpdateSliderText"
-            parameter="TreeMeshDetailText" />
-        </slider>
+         control_name="RenderTreeLODFactor"
+         follows="left|top"
+         height="16"
+         increment="0.125"
+         initial_value="160"
+         label="  Trees:"
+         label_width="185"
+         layout="topleft"
+         left_delta="0"
+         name="TreeMeshDetail"
+         show_text="false"
+         top_pad="4"
+         width="264">
+            <slider.commit_callback
+             function="Pref.UpdateSliderText"
+             parameter="TreeMeshDetailText" />
+            </slider>
         <slider
-        control_name="RenderAvatarLODFactor"
-        follows="left|top"
-        height="16"
-        increment="0.125"
-        initial_value="160"
-        label="  Avatars:"
-        label_width="185"
-        layout="topleft"
-        left_delta="0"
-        name="AvatarMeshDetail"
-        show_text="false"
-        top_pad="4"
-        width="264">
-           <slider.commit_callback
-            function="Pref.UpdateSliderText"
-            parameter="AvatarMeshDetailText" />
+         control_name="RenderAvatarLODFactor"
+         follows="left|top"
+         height="16"
+         increment="0.125"
+         initial_value="160"
+         label="  Avatars:"
+         label_width="185"
+         layout="topleft"
+         left_delta="0"
+         name="AvatarMeshDetail"
+         show_text="false"
+         top_pad="4"
+         width="264">
+            <slider.commit_callback
+             function="Pref.UpdateSliderText"
+             parameter="AvatarMeshDetailText" />
         </slider>
         <slider
-        control_name="RenderTerrainLODFactor"
-        follows="left|top"
-        height="16"
-        increment="0.125"
-        initial_value="160"
-        label="  Terrain:"
-        label_width="185"
-        layout="topleft"
-        left_delta="0"
-        max_val="2"
-        min_val="1"
-        name="TerrainMeshDetail"
-        show_text="false"
-        top_pad="4"
-        width="264">
-           <slider.commit_callback
-            function="Pref.UpdateSliderText"
-            parameter="TerrainMeshDetailText" />
+         control_name="RenderTerrainLODFactor"
+         follows="left|top"
+         height="16"
+         increment="0.125"
+         initial_value="160"
+         label="  Terrain:"
+         label_width="185"
+         layout="topleft"
+         left_delta="0"
+         max_val="2"
+         min_val="1"
+         name="TerrainMeshDetail"
+         show_text="false"
+         top_pad="4"
+         width="264">
+            <slider.commit_callback
+             function="Pref.UpdateSliderText"
+             parameter="TerrainMeshDetailText" />
         </slider>
         <slider
-        control_name="WLSkyDetail"
-		enabled_control="WindLightUseAtmosShaders"
-        decimal_digits="0"
-        follows="left|top"
-        height="16"
-        increment="8"
-        initial_value="160"
-        label="  Sky:"
-        label_width="185"
-        layout="topleft"
-        left_delta="0"
-        max_val="128"
-        min_val="16"
-        name="SkyMeshDetail"
-        show_text="false"
-        top_pad="4"
-        width="264">
-           <slider.commit_callback
-            function="Pref.UpdateSliderText"
-            parameter="SkyMeshDetailText" />
+         control_name="WLSkyDetail"
+		 enabled_control="WindLightUseAtmosShaders"
+         decimal_digits="0"
+         follows="left|top"
+         height="16"
+         increment="8"
+         initial_value="160"
+         label="  Sky:"
+         label_width="185"
+         layout="topleft"
+         left_delta="0"
+         max_val="128"
+         min_val="16"
+         name="SkyMeshDetail"
+         show_text="false"
+         top_pad="4"
+         width="264">
+            <slider.commit_callback
+             function="Pref.UpdateSliderText"
+             parameter="SkyMeshDetailText" />
         </slider>
         <text
-        type="string"
-        length="1"
-        follows="left|top"
-        height="12"
-        layout="topleft"
-        left="469"
-        name="PostProcessText"
-        top="60"
-        width="128">
-           Low
+         type="string"
+         length="1"
+         follows="left|top"
+         height="12"
+         layout="topleft"
+         left="469"
+         name="PostProcessText"
+         top="60"
+         width="128">
+            Low
         </text>
         <text
-        type="string"
-        length="1"
-        follows="left|top"
-        height="12"
-        layout="topleft"
-        left_delta="0"
-        name="ObjectMeshDetailText"
-        top_pad="26"
-        width="128">
-           Low
+         type="string"
+         length="1"
+         follows="left|top"
+         height="12"
+         layout="topleft"
+         left_delta="0"
+         name="ObjectMeshDetailText"
+         top_pad="26"
+         width="128">
+            Low
         </text>
         <text
-        type="string"
-        length="1"
-        follows="left|top"
-        height="12"
-        layout="topleft"
-        left_delta="0"
-        name="FlexibleMeshDetailText"
-        top_pad="8"
-        width="128">
-           Low
+         type="string"
+         length="1"
+         follows="left|top"
+         height="12"
+         layout="topleft"
+         left_delta="0"
+         name="FlexibleMeshDetailText"
+         top_pad="8"
+         width="128">
+            Low
         </text>
         <text
-        type="string"
-        length="1"
-        follows="left|top"
-        height="12"
-        layout="topleft"
-        left_delta="0"
-        name="TreeMeshDetailText"
-        top_pad="8"
-        width="128">
-           Low
+         type="string"
+         length="1"
+         follows="left|top"
+         height="12"
+         layout="topleft"
+         left_delta="0"
+         name="TreeMeshDetailText"
+         top_pad="8"
+         width="128">
+            Low
         </text>
         <text
-        type="string"
-        length="1"
-        follows="left|top"
-        height="12"
-        layout="topleft"
-        left_delta="0"
-        name="AvatarMeshDetailText"
-        top_pad="8"
-        width="128">
-           Low
+         type="string"
+         length="1"
+         follows="left|top"
+         height="12"
+         layout="topleft"
+         left_delta="0"
+         name="AvatarMeshDetailText"
+         top_pad="8"
+         width="128">
+            Low
         </text>
         <text
-        type="string"
-        length="1"
-        follows="left|top"
-        height="12"
-        layout="topleft"
-        left_delta="0"
-        name="TerrainMeshDetailText"
-        top_pad="8"
-        width="128">
-           Low
+         type="string"
+         length="1"
+         follows="left|top"
+         height="12"
+         layout="topleft"
+         left_delta="0"
+         name="TerrainMeshDetailText"
+         top_pad="8"
+         width="128">
+            Low
         </text>
         <text
-		enabled_control="WindLightUseAtmosShaders"
-        type="string"
-        length="1"
-        follows="left|top"
-        height="12"
-        layout="topleft"
-        left_delta="0"
-        name="SkyMeshDetailText"
-        top_pad="8"
-        width="128">
-           Low
+		 enabled_control="WindLightUseAtmosShaders"
+         type="string"
+         length="1"
+         follows="left|top"
+         height="12"
+         layout="topleft"
+         left_delta="0"
+         name="SkyMeshDetailText"
+         top_pad="8"
+         width="128">
+            Low
         </text>
-      <text
-      type="string"
-      length="1"
-      follows="left|top"
-      height="12"
-      layout="topleft"
-      left_delta="-260"
-      name="AvatarRenderingText"
-        top_pad="18"
-      width="128">
-        Avatar rendering:
+        <text
+         type="string"
+         length="1"
+         follows="left|top"
+         height="12"
+         layout="topleft"
+         left_delta="-260"
+         name="AvatarRenderingText"
+         top_pad="18"
+         width="128">
+            Avatar rendering:
       </text>
       <check_box
-      control_name="RenderUseImpostors"
-      height="16"
-      initial_value="true"
-      label="Avatar impostors"
-      layout="topleft"
-      left_delta="0"
-      name="AvatarImpostors"
-      top_pad="7"
-      width="256" />
+       control_name="RenderUseImpostors"
+       height="16"
+       initial_value="true"
+       label="Avatar impostors"
+       layout="topleft"
+       left_delta="0"
+       name="AvatarImpostors"
+       top_pad="7"
+       width="256" />
       <check_box
-      control_name="RenderAvatarVP"
-      height="16"
-      initial_value="true"
-      label="Hardware skinning"
-      layout="topleft"
-      left_delta="0"
-      name="AvatarVertexProgram"
-      top_pad="1"
-      width="256">
-        <check_box.commit_callback
-        function="Pref.VertexShaderEnable" />
+       control_name="RenderAvatarVP"
+       height="16"
+       initial_value="true"
+       label="Hardware skinning"
+       layout="topleft"
+       left_delta="0"
+       name="AvatarVertexProgram"
+       top_pad="1"
+       width="256">
+          <check_box.commit_callback
+           function="Pref.VertexShaderEnable" />
       </check_box>
       <check_box
-      control_name="RenderAvatarCloth"
-      height="16"
-      initial_value="true"
-      label="Avatar cloth"
-      layout="topleft"
-      left_delta="0"
-      name="AvatarCloth"
-      top_pad="1"
-      width="256" />
-        <text
-        type="string"
-        length="1"
-        follows="left|top"
-        height="12"
-        layout="topleft"
-        left="358"
-        left_pad="-30"
-        name="TerrainDetailText"
-        top="226"
-        width="155">
-           Terrain detail:
-        </text>
-        <radio_group
-        control_name="RenderTerrainDetail"
-        draw_border="false"
-        height="38"
-        layout="topleft"
-        left_delta="0"
-        name="TerrainDetailRadio"
-        top_pad="5"
-        width="70">
-           <radio_item
-            height="16"
-            label="Low"
-            layout="topleft"
-            name="0"
-            top="3"
-            width="50" />
-           <radio_item
-            height="16"
-            label="High"
-            layout="topleft"
-            name="2"
-            top_delta="16"
-            width="50" />
-        </radio_group> -->
+       control_name="RenderAvatarCloth"
+       height="16"
+       initial_value="true"
+       label="Avatar cloth"
+       layout="topleft"
+       left_delta="0"
+       name="AvatarCloth"
+       top_pad="1"
+       width="256" />
+      <text
+       type="string"
+       length="1"
+       follows="left|top"
+       height="12"
+       layout="topleft"
+       left="358"
+       left_pad="-30"
+       name="TerrainDetailText"
+       top="226"
+       width="155">
+          Terrain detail:
+      </text>
+      <radio_group
+       control_name="RenderTerrainDetail"
+       draw_border="false"
+       height="38"
+       layout="topleft"
+       left_delta="0"
+       name="TerrainDetailRadio"
+       top_pad="5"
+       width="70">
+          <radio_item
+           height="16"
+           label="Low"
+           layout="topleft"
+           name="0"
+           top="3"
+           width="50" />
+          <radio_item
+           height="16"
+           label="High"
+           layout="topleft"
+           name="2"
+           top_delta="16"
+           width="50" />
+      </radio_group> -->
 	</panel>
 	
-        <button
+    <button
      follows="left|bottom"
      height="23"
      label="Apply"
@@ -701,8 +711,7 @@
      left="10"
      name="Apply"
      top="383"
-     width="115"
-      >
+     width="115">
         <button.commit_callback
          function="Pref.Apply" />
     </button>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_move.xml b/indra/newview/skins/default/xui/en/panel_preferences_move.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d2fc6ea09a3ae2a575e11abab399166c9b4e05cc
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_preferences_move.xml
@@ -0,0 +1,220 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ border="true"
+ follows="left|top|right|bottom"
+ height="408"
+ label="Move"
+ layout="topleft"
+ left="102"
+ name="move_panel"
+ top="1"
+ width="517">
+  <icon
+     follows="left|top"
+     height="18"
+     image_name="Cam_FreeCam_Off"
+     layout="topleft"
+     name="camera_icon"
+     mouse_opaque="false"
+     visible="true"
+     width="18"
+     left="30"
+     top="10"/>
+  <slider
+   can_edit_text="true"
+   control_name="CameraAngle"
+   decimal_digits="2"
+   follows="left|top"
+   height="16"
+   increment="0.025"
+   initial_value="1.57"
+   layout="topleft"
+   label_width="100"
+   label="View angle"
+   left_pad="30"
+   max_val="2.97"
+   min_val="0.17"
+   name="camera_fov"
+   show_text="false"
+   width="240" />
+  <slider
+   can_edit_text="true"
+   control_name="CameraOffsetScale"
+   decimal_digits="2"
+   follows="left|top"
+   height="16"
+   increment="0.025"
+   initial_value="1"
+   layout="topleft"
+   label="Distance"
+   left_delta="0"
+   label_width="100"
+   max_val="3"
+   min_val="0.5"
+   name="camera_offset_scale"
+   show_text="false"
+   width="240"
+   top_pad="5"/>
+  <text
+  follows="left|top"
+  type="string"
+  length="1"
+  height="10"
+  left="80"
+  name="heading2"
+  width="270"
+  top_pad="5">
+    Automatic position for:
+  </text>
+  <check_box
+     control_name="EditCameraMovement"
+     height="20"
+     follows="left|top"
+     label="Build/Edit"
+     layout="topleft"
+     left_delta="30"
+     name="edit_camera_movement"
+     tool_tip="Use automatic camera positioning when entering and exiting edit mode"
+     width="280"
+     top_pad="5" />
+  <check_box
+   control_name="AppearanceCameraMovement"
+   follows="left|top"
+   height="16"
+   label="Appearance"
+   layout="topleft"
+   name="appearance_camera_movement"
+   tool_tip="Use automatic camera positioning while in edit mode"
+   width="242" />
+  <check_box
+   control_name="SidebarCameraMovement"
+   follows="left|top"
+   height="16"
+   initial_value="true"
+   label="Sidebar"
+   layout="topleft"
+   name="appearance_sidebar_positioning"
+   tool_tip="Use automatic camera positioning for sidebar"
+   width="242" />
+  <icon
+	 follows="left|top"
+	 height="18"
+	 image_name="Move_Walk_Off"
+   layout="topleft"
+	 name="avatar_icon"
+	 mouse_opaque="false"
+	 visible="true"
+	 width="18"
+   top_pad="2"
+   left="30" />
+  <check_box
+   control_name="FirstPersonAvatarVisible"
+   follows="left|top"
+   height="20"
+   label="Show me in Mouselook"
+   layout="topleft"
+   left_pad="30"
+   name="first_person_avatar_visible"
+   width="256" />
+  <text
+   type="string"
+   length="1"
+   follows="left|top"
+   height="10"
+   layout="topleft"
+   left_delta="3"
+   name=" Mouse Sensitivity"
+   top_pad="10"
+   width="160">
+    Mouselook mouse sensitivity:
+  </text>
+  <slider
+   control_name="MouseSensitivity"
+   follows="left|top"
+   height="15"
+   initial_value="2"
+   layout="topleft"
+   show_text="false"
+   left_pad="5"
+   max_val="15"
+   name="mouse_sensitivity"
+   top_delta="-1"
+   width="145" />
+  <check_box
+   control_name="InvertMouse"
+   height="16"
+   label="Invert"
+   layout="topleft"
+   left_pad="2"
+   name="invert_mouse"
+   top_delta="0"
+   width="128" />
+  <check_box
+   control_name="ArrowKeysAlwaysMove"
+   follows="left|top"
+   height="20"
+   label="Arrow keys always move me"
+   layout="topleft"
+   left="78"
+   name="arrow_keys_move_avatar_check"
+   width="237"
+   top_pad="1"/>
+  <check_box
+   control_name="AllowTapTapHoldRun"
+   follows="left|top"
+   height="20"
+   label="Tap-tap-hold to run"
+   layout="topleft"
+   left_delta="0"
+   name="tap_tap_hold_to_run"
+   width="237"
+   top_pad="0"/>
+  <check_box
+   follows="left|top"
+   height="20"
+   label="Double-Click to:"
+   layout="topleft"
+   left_delta="0"
+   name="double_click_chkbox"
+   width="237"
+   top_pad="0">
+   <check_box.commit_callback
+    function="Pref.CommitDoubleClickChekbox"/>
+  </check_box>
+  <radio_group
+     height="20"
+     layout="topleft"
+     left_delta="17"
+     top_pad="2"
+     name="double_click_action">
+    <radio_item
+     height="16"
+     label="Teleport"
+     layout="topleft"
+     left="0"
+     name="radio_teleport"
+     top_delta="20"
+     width="100" />
+    <radio_item
+     height="16"
+     label="Auto-pilot"
+     left_pad="0"
+     layout="topleft"
+     name="radio_autopilot"
+     top_delta="0"
+     width="75" />
+    <radio_group.commit_callback
+	     function="Pref.CommitRadioDoubleClick"/>
+  </radio_group>
+  <button
+   height="23"
+   label="Other Devices"
+   left="30"
+   name="joystick_setup_button"
+   top="30"
+   width="155">
+    <button.commit_callback
+     function="Floater.Show"
+     parameter="pref_joystick" />
+  </button>
+</panel>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index 4ebd4c76f897c4bac86d4708af6cd57257028a19..626122c0b054774cb4213586b676117d8f0b3032 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -47,7 +47,7 @@
      layout="topleft"
      left="30"
      name="online_visibility"
-     top_pad="20"
+     top_pad="30"
      width="350" />
     <check_box
      enabled_control="EnableVoiceChat"
@@ -78,9 +78,9 @@
      left="30"
      mouse_opaque="false"
      name="Logs:"
-     top_pad="10"
+     top_pad="30"
      width="350">
-        Logs:
+        Chat Logs:
     </text>
     <check_box
 	 enabled="false"
@@ -108,13 +108,23 @@
      control_name="LogTimestamp"
 	 enabled="false"
      height="16"
-     label="Add timestamp"
+     label="Add timestamp to each line in chat log"
      layout="topleft"
      left_delta="0"
      name="show_timestamps_check_im"
      top_pad="10"
      width="237" />
-    <text
+	<check_box
+     control_name="LogFileNamewithDate"
+     enabled="false"
+     height="16"
+     label="Add datestamp to log file name."
+     layout="topleft"
+     left_detla="5"
+     name="logfile_name_datestamp"
+     top_pad="10"
+     width="350"/>
+	<text
      type="string"
      length="1"
      follows="left|top"
@@ -123,7 +133,7 @@
      left_delta="0"
      mouse_opaque="false"
      name="log_path_desc"
-     top_pad="5"
+     top_pad="30"
      width="128">
         Location of logs:
     </text>    
@@ -160,11 +170,25 @@
      layout="topleft"
      left="30"
      name="block_list"
-     top_pad="20"
+     top_pad="35"
      width="145">
         <!--<button.commit_callback
          function="SideTray.ShowPanel"-->
       <button.commit_callback
          function="Pref.BlockList"/>
     </button>
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left_pad="10"
+     mouse_opaque="false"
+     name="block_list_label"
+     top_delta="3"
+     text_color="LtGray_50"
+     width="300">
+       (People and/or Objects you have blocked)
+    </text>
     </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 140d16e37f6603c2d4055aa1d366b25169beb683..901a1257e08104ddb80dfc182ccb6d17666ef796 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -9,51 +9,6 @@
  name="Input panel"
  top="1"
  width="517">
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="10"
-   layout="topleft"
-   left="30"
-   name="Mouselook:"
-   top="10"
-   width="300">
-    Mouselook:
-  </text>
-  <text
-   type="string"
-   length="1"
-   follows="left|top"
-   height="10"
-   layout="topleft"
-   left_delta="50"
-   name=" Mouse Sensitivity"
-   top_pad="10"
-   width="150">
-    Mouse sensitivity
-  </text>
-  <slider
-   control_name="MouseSensitivity"
-   follows="left|top"
-   height="15"
-   initial_value="2"
-   layout="topleft"
-   show_text="false"
-   left_delta="150"
-   max_val="15"
-   name="mouse_sensitivity"
-   top_delta="0"
-   width="145" />
-  <check_box
-   control_name="InvertMouse"
-   height="16"
-   label="Invert"
-   layout="topleft"
-   left_pad="2"
-   name="invert_mouse"
-   top_delta="0"
-   width="128" />
   <text
      type="string"
      length="1"
@@ -63,7 +18,7 @@
      left="30"
      name="Network:"
      mouse_opaque="false"
-     top_pad="4"
+     top="10"
      width="300">
     Network:
   </text>
@@ -386,4 +341,41 @@
    name="web_proxy_port"
    top_delta="0"
    width="145" />
+  <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="10"
+     layout="topleft"
+     left="30"
+     name="Software updates:"
+     mouse_opaque="false"
+     top_pad="5"
+     width="300">
+    Software updates:
+  </text>
+  <combo_box
+     control_name="UpdaterServiceSetting"
+     follows="left|top"
+     height="23"
+     layout="topleft"
+     left_delta="50"
+	 top_pad="5"
+     name="updater_service_combobox"
+     width="300">
+        <combo_box.item
+         label="Install automatically"
+         name="Install_automatically"
+         value="3" />
+      <!--
+        <combo_box.item
+         label="Ask before installing"
+         name="Install_ask"
+         value="1" />
+      -->
+        <combo_box.item
+         label="Download and install updates manually"
+         name="Install_manual"
+         value="0" />
+  </combo_box>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
index aa760edad344d9c65df46bc45af2002c90893038..da366f30aef79687850b22b734d8e380f433e25b 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_sound.xml
@@ -9,6 +9,10 @@
  name="Preference Media panel"
  top="1"
  width="517">
+    <panel.string
+     name="middle_mouse">
+     Middle Mouse
+    </panel.string>
     <slider
      control_name="AudioLevelMaster"
      follows="left|top"
@@ -66,7 +70,7 @@
 		name="UI Volume"
 		show_text="false"
 		slider_label.halign="right"
-		top_pad="7"
+		top_pad="4"
 		volume="true"
 		width="300">
 	  <slider.commit_callback
@@ -100,7 +104,7 @@
      name="Wind Volume"
      show_text="false"
      slider_label.halign="right"
-     top_pad="7"
+     top_pad="4"
      volume="true"
      width="300">
         <slider.commit_callback
@@ -134,7 +138,7 @@
      left="0"
      name="SFX Volume"
      show_text="false"
-     top_pad="7"
+     top_pad="4"
      volume="true"
      width="300">
         <slider.commit_callback
@@ -168,7 +172,7 @@
      name="Music Volume"
      slider_label.halign="right"
      show_text="false"
-     top_pad="7"
+     top_pad="4"
      volume="true"
      width="300">
         <slider.commit_callback
@@ -211,7 +215,7 @@
 		name="Media Volume"
 		show_text="false"
 		slider_label.halign="right"
-		top_pad="7"
+		top_pad="4"
 		volume="true"
 		width="300">
 	  <slider.commit_callback
@@ -253,7 +257,7 @@
 		label_width="120"
 		layout="topleft"
 		left="0"
-		top_delta="20"
+		top_pad="4"
 		name="Voice Volume"
 		show_text="false"
 		slider_label.halign="right"
@@ -297,9 +301,9 @@
 		height="15"
 		tool_tip="Check this to let media auto-play if it wants"
 		label="Allow Media to auto-play"
-		top_pad="5"
+		top_pad="1"
 		left="25"/>
-	<check_box
+ 	<check_box
 		name="media_show_on_others_btn"
 		control_name="MediaShowOnOthers"
 		value="true"
@@ -307,7 +311,8 @@
 		height="15"
 		tool_tip="Uncheck this to hide media attached to other avatars nearby"
 		label="Play media attached to other avatars"
-		left="25"/>
+		left="25"
+    width="230"/>
 
     <text
      type="string"
@@ -317,8 +322,8 @@
      layout="topleft"
      left="25"
      name="voice_chat_settings"
-     width="200"
-     top="210">
+     width="180"
+     top_pad="7">
 	  Voice Chat Settings
     </text>
     <text
@@ -326,10 +331,10 @@
      length="1"
      follows="left|top"
      layout="topleft"
-	   left="80"
+	   left="46"
 	   top_delta="16"
      name="Listen from"
-     width="142">
+     width="112">
         Listen from:
     </text>
 	<icon
@@ -341,43 +346,107 @@
 		mouse_opaque="false"
 		visible="true"
 		width="18"
-		left_pad="0"
+		left_pad="-4"
 		top_delta="-5"/>
 	<icon
 		follows="left|top"
 		height="18"
 		image_name="Move_Walk_Off"
 		layout="topleft"
+    left_pad="170" 
 		name="avatar_icon"
 		mouse_opaque="false"
 		visible="true"
 		width="18"
-		top_delta="20" />
+		top_delta="0" />
    <radio_group
      enabled_control="EnableVoiceChat"
      control_name="VoiceEarLocation"
      draw_border="false"
      follows="left|top"
      layout="topleft"
-     left_pad="2"
+     left_delta="-168"
      width="221"
-     height="38"
+     height="20"
      name="ear_location">
     <radio_item
-     height="16"
+     height="19"
      label="Camera position"
      follows="left|top"
      layout="topleft"
      name="0"
      width="200"/>
     <radio_item
-     height="16"
+     height="19"
      follows="left|top"
      label="Avatar position"
      layout="topleft"
+     left_pad="-16"
      name="1"
+     top_delta ="0" 
      width="200" />
    </radio_group>
+  <check_box
+   control_name="LipSyncEnabled"
+   follows="left|top"
+   height="15"
+   label="Move avatar lips when speaking"
+   layout="topleft"
+   left="44"
+   name="enable_lip_sync"
+   top_pad="5" 
+   width="237"/>
+ <check_box
+  follows="top|left"
+  enabled_control="EnableVoiceChat"
+  control_name="PushToTalkToggle"
+  height="15"
+  label="Toggle speak on/off when I press:"
+  layout="topleft"
+  left="44"
+  name="push_to_talk_toggle_check"
+  width="237"
+  tool_tip="When in toggle mode, press and release the trigger key ONCE to switch your microphone on or off. When not in toggle mode, the microphone broadcasts your voice only while the trigger is being held down."
+  top_pad="3"/>
+  <line_editor
+   follows="top|left"
+   control_name="PushToTalkButton"
+   enabled="false"
+   enabled_control="EnableVoiceChat"
+   height="23"
+   left="80"
+   max_length_bytes="200"
+   name="modifier_combo"
+   label="Push-to-Speak trigger"
+   top_pad="3"
+   width="200" />
+  <button
+   layout="topleft"
+   follows="top|left"
+   enabled_control="EnableVoiceChat"
+   height="23"
+   label="Set Key"
+   left_pad="5"
+   name="set_voice_hotkey_button"
+   width="100">
+    <button.commit_callback
+    function="Pref.VoiceSetKey" />
+  </button>
+  <button
+     enabled_control="EnableVoiceChat"
+     follows="top|left"
+     halign="center"
+     height="23"
+     image_overlay="Refresh_Off"
+     layout="topleft"
+     tool_tip="Reset to Middle Mouse Button"
+     mouse_opaque="true"
+     name="set_voice_middlemouse_button"
+     left_pad="5"
+     width="25">
+    <button.commit_callback
+    function="Pref.VoiceSetMiddleMouse" />
+  </button>
   <button
    control_name="ShowDeviceSettings"
    follows="left|top"
@@ -385,8 +454,8 @@
    is_toggle="true"
    label="Input/Output devices"
    layout="topleft"
-   left="80"
-   top_pad="5"
+   left="20"
+   top_pad="6"
    name="device_settings_btn"
    width="190">
   </button>
@@ -396,14 +465,14 @@
      visiblity_control="ShowDeviceSettings"
      border="false"
      follows="top|left"
-     height="120"
+     height="100"
      label="Device Settings"
      layout="topleft"
-     left="0"
+     left_delta="-2"
      name="device_settings_panel"
      class="panel_voice_device_settings"
-     width="501"
-     top="285">
+     width="470"
+     top_pad="0">
       <panel.string
         name="default_text">
         Default
@@ -419,7 +488,7 @@
       <icon
              height="18"
              image_name="Microphone_On"
-             left="80"
+             left_delta="4"
              name="microphone_icon"
              mouse_opaque="false"
              top="7"
@@ -434,17 +503,17 @@
      layout="topleft"
      left_pad="3"
      name="Input"
-     width="200">
+     width="70">
         Input
     </text>
     <combo_box
      height="23"
      control_name="VoiceInputAudioDevice"
      layout="topleft"
-     left="165"
+     left_pad="0"
      max_chars="128"
      name="voice_input_device"
-     top_pad="-2"
+     top_delta="-5"
      width="200" />
    <text
      type="string"
@@ -452,9 +521,9 @@
      follows="left|top"
      height="16"
      layout="topleft"
-     left="165"
+     left_delta="-70"
      name="My volume label"
-     top_pad="5"
+     top_pad="4"
      width="200">
         My volume:
     </text>
@@ -465,11 +534,11 @@
      increment="0.025"
      initial_value="1.0"
      layout="topleft"
-     left="160"
+     left_delta="-6"
      max_val="2"
      name="mic_volume_slider"
      tool_tip="Change the volume using this slider"
-     top_pad="-2"
+     top_pad="-1"
      width="220" />
     <text
      type="string"
@@ -480,7 +549,7 @@
      layout="topleft"
      left_pad="5"
      name="wait_text"
-     top_delta="0"
+     top_delta="-1"
      width="110">
         Please wait
     </text>
@@ -489,7 +558,7 @@
      layout="topleft"
      left_delta="0"
      name="bar0"
-     top_delta="0"
+     top_delta="-2"
      width="20" />
     <locate
      height="20"
@@ -522,10 +591,10 @@
           <icon
              height="18"
              image_name="Parcel_Voice_Light"
-             left="80"
+             left="5"
              name="speaker_icon"
              mouse_opaque="false"
-             top_pad="-8"
+             top_pad="3"
              visible="true"
              width="22" />
     <text
@@ -537,17 +606,17 @@
      layout="topleft"
      left_pad="0"
      name="Output"
-     width="200">
+     width="70">
         Output
     </text>
     <combo_box
      control_name="VoiceOutputAudioDevice"
      height="23"
      layout="topleft"
-     left="165"
+     left_pad="0"
      max_chars="128"
      name="voice_output_device"
-     top_pad="-2"
+     top_delta="-3"
      width="200" />
     </panel>
     </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_profile.xml b/indra/newview/skins/default/xui/en/panel_profile.xml
index efc37c2127e7bb141e0ddd1f2b43798f44b01b03..61e3bb354f492c8af9e0abcb99c9b86fbfa8a169 100644
--- a/indra/newview/skins/default/xui/en/panel_profile.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile.xml
@@ -59,7 +59,7 @@
          left="0"
          name="profile_scroll"
          opaque="true"
-         height="527"
+         height="400"
          width="317"
          top="0">
           <panel
@@ -432,7 +432,7 @@
 			    user_resize="false" 
 			    auto_resize="false"
 				width="24">
-					<button
+					<menu_button
 			         follows="bottom|left|right"
 			         height="23"
 			         label="â–¼"
diff --git a/indra/newview/skins/default/xui/en/panel_profile_view.xml b/indra/newview/skins/default/xui/en/panel_profile_view.xml
index 97229c413c3808cb63823409de0060b09378a417..c553a3aba01948914015d69fe15955f095001153 100644
--- a/indra/newview/skins/default/xui/en/panel_profile_view.xml
+++ b/indra/newview/skins/default/xui/en/panel_profile_view.xml
@@ -27,7 +27,8 @@
    left="10"
    tab_stop="false"
    top="2"
-   width="30" />
+   width="30"
+   use_draw_context_alpha="false" />
   <text
    top="10"
    follows="top|left"
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index 1e332a40c2ef6101a38df83a021dcd51edc594e0..a041c9b2293ffd777af8f2ae999622c6e9171b04 100644
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -179,4 +179,13 @@
      right="487"
      name="Save_btn"
      width="81" />
+    <button
+     follows="right|bottom"
+     height="23"
+     label="Edit..."
+     layout="topleft"
+     top_pad="-23"
+     right="400"
+     name="Edit_btn"
+     width="81" />
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_status_bar.xml b/indra/newview/skins/default/xui/en/panel_status_bar.xml
index 2f52ca660b833608d09f63c95d5c62e59d66484e..d756dfb7de6d53b13bdaabb3f059651fa0973fa0 100644
--- a/indra/newview/skins/default/xui/en/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_status_bar.xml
@@ -51,7 +51,7 @@
      height="18"
      left="0" 
      name="balance"
-     tool_tip="My Balance"
+     tool_tip="Click to refresh your L$ balance"
      v_pad="4"
      top="0"
      wrap="false" 
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 6940d1549ba249b9ccdb397810dc3312ceb5fc9d..54a312bd59247e66d0ba34dc0170f4f2b7dae06f 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_item_info.xml
@@ -56,7 +56,8 @@
      name="back_btn"
      tab_stop="false"
      top="2"
-     width="30" />
+     width="30"
+     use_draw_context_alpha="false" />
     <text
      follows="top|left|right"
      font="SansSerifHugeBold"
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 ca63d2df3962f8fe89ac06b57d2d497c7ea92cc5..afaf41d0733087f584462b52718854f4a09d3e0a 100644
--- a/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
+++ b/indra/newview/skins/default/xui/en/sidepanel_task_info.xml
@@ -65,7 +65,8 @@
      name="back_btn"
      tab_stop="false"
      top="0"
-     width="30" />
+     width="30"
+     use_draw_context_alpha="false" />
         <text
      follows="top|left|right"
      font="SansSerifHuge"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 1ec0d34d9a6cfa2e6153fb8ad8dbe7e292ce6a05..752bb6ed3a03724cd290966def01c5a62eca4807 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -1716,8 +1716,8 @@ integer llGetRegionAgentCount()
 Returns the number of avatars in the region
 	</string>
 	<string name="LSLTipText_llTextBox" translate="false">
-llTextBox(key avatar, string message, integer chat_channel
-Shows a dialog box on the avatar&apos;s screen with the message.
+llTextBox(key avatar, string message, integer chat_channel)
+Shows a window on the avatar&apos;s screen with the message.
 It contains a text box for input, and if entered that text is chatted on chat_channel.
 	</string>
 	<string name="LSLTipText_llGetAgentLanguage" translate="false">
@@ -1823,8 +1823,8 @@ key llRequestUsername(key id)
 Requests single-word username of an avatar.  When data is available the dataserver event will be raised.
 </string>
 <string name="LSLTipText_llGetDisplayName" translate="false">
-string llGetDisplayName(key id)
-Returns the name of an avatar, iff the avatar is in the current simulator, otherwise the empty string.
+  string llGetDisplayName(key id)
+  Returns the name of an avatar, iff the avatar is in the current simulator, and the name has been cached, otherwise the same as llGetUsername.  Use llRequestDisplayName if you absolutely must have the display name.
 </string>
 <string name="LSLTipText_llRequestDisplayName" translate="false">
 key llRequestDisplayName(key id)
diff --git a/indra/newview/skins/default/xui/en/widgets/avatar_icon.xml b/indra/newview/skins/default/xui/en/widgets/avatar_icon.xml
index a35e2c3663c4f68377411d93e4978d161f7c9ee0..a1e32e44de6deaf02472939d0b6843685466c1f2 100644
--- a/indra/newview/skins/default/xui/en/widgets/avatar_icon.xml
+++ b/indra/newview/skins/default/xui/en/widgets/avatar_icon.xml
@@ -1,4 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 
-<avatar_icon default_icon_name="Generic_Person_Large">
+<avatar_icon
+    default_icon_name="Generic_Person_Large"
+    use_draw_context_alpha="false">
 </avatar_icon>
diff --git a/indra/newview/skins/default/xui/en/widgets/button.xml b/indra/newview/skins/default/xui/en/widgets/button.xml
index 2d0a1728d58e768d2366d6f9201e961ac14e310a..16241ed84ec5a8f9e9fbb5966cb14cc686014b5d 100644
--- a/indra/newview/skins/default/xui/en/widgets/button.xml
+++ b/indra/newview/skins/default/xui/en/widgets/button.xml
@@ -19,10 +19,11 @@
         image_color="ButtonImageColor"
         image_color_disabled="ButtonImageColor"
         flash_color="ButtonFlashBgColor"
-	font="SansSerifSmall"
+        font="SansSerifSmall"
         hover_glow_amount="0.15"
         halign="center"
         pad_bottom="3" 
         height="23"
-        scale_image="true">
+        scale_image="true"
+        use_draw_context_alpha="true">
 </button>
diff --git a/indra/newview/skins/default/xui/en/widgets/check_box.xml b/indra/newview/skins/default/xui/en/widgets/check_box.xml
index 7a60bee338f3d8927f346214ce965f33b2595c40..cca64fad2a735a33c82163f2f6d967d451b7801e 100644
--- a/indra/newview/skins/default/xui/en/widgets/check_box.xml
+++ b/indra/newview/skins/default/xui/en/widgets/check_box.xml
@@ -2,9 +2,17 @@
 <check_box font="SansSerifSmall"
            follows="left|top">
   <check_box.label_text name="checkbox label"
+                        left="20"
+                        bottom="3" 
+                        width="0"
+                        height="0"
                         text_color="LabelTextColor"
                         text_readonly_color="LabelDisabledColor"/>
   <check_box.check_button name="CheckboxCtrl Button"
+                          left="2"
+                          bottom="2"
+                          width="13"
+                          height="13" 
                           commit_on_return="false"
                           label=""
                           is_toggle="true"
diff --git a/indra/newview/skins/default/xui/en/widgets/group_icon.xml b/indra/newview/skins/default/xui/en/widgets/group_icon.xml
index 58d5e19fcc20ab5c813ef2b5656fee18306fbd23..36ee6dd7ebcef7a463b3cee5466c6aa3dd2fbddb 100644
--- a/indra/newview/skins/default/xui/en/widgets/group_icon.xml
+++ b/indra/newview/skins/default/xui/en/widgets/group_icon.xml
@@ -2,4 +2,5 @@
 <group_icon
  default_icon_name="Generic_Group"
  image_name="Generic_Group"
- name="group_icon" />
+ name="group_icon"
+ use_draw_context_alpha="false" />
diff --git a/indra/newview/skins/default/xui/en/widgets/icon.xml b/indra/newview/skins/default/xui/en/widgets/icon.xml
index adb743a628c63def6227e2f8a0307e3db63d30c4..cf8edfcedb65d884c5f14b07f33d1eba27a7d9b2 100644
--- a/indra/newview/skins/default/xui/en/widgets/icon.xml
+++ b/indra/newview/skins/default/xui/en/widgets/icon.xml
@@ -3,5 +3,6 @@
       tab_stop="false"
       mouse_opaque="false"
       name="icon"
+      use_draw_context_alpha="true"
       follows="left|top">
 </icon>
diff --git a/indra/newview/skins/default/xui/en/widgets/sidetray_tab.xml b/indra/newview/skins/default/xui/en/widgets/sidetray_tab.xml
new file mode 100644
index 0000000000000000000000000000000000000000..aa8461d367be46395ae227cf044757850bf5a3d4
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/sidetray_tab.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<sidetray_tab 
+  focus_root="true"
+  />
diff --git a/indra/newview/skins/default/xui/es/floater_hardware_settings.xml b/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
index f967d697c5025507c5c6aa0ee68015d651087fbb..0150241d9a91791a20ca2fd523debaba84ba083e 100644
--- a/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/es/floater_hardware_settings.xml
@@ -14,6 +14,9 @@
 		<combo_box.item label="8x" name="8x"/>
 		<combo_box.item label="16x" name="16x"/>
 	</combo_box>
+	<text name="antialiasing restart">
+		(requiere reiniciar el visor)
+	</text>
 	<spinner label="Gamma:" name="gamma"/>
 	<text name="(brightness, lower is brighter)">
 		(0 = brillo por defecto, más bajo = más brillo)
diff --git a/indra/newview/skins/default/xui/es/floater_im.xml b/indra/newview/skins/default/xui/es/floater_im.xml
deleted file mode 100644
index 3850b94fd67fd4ad678c88caa565b49148ef99fe..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/es/floater_im.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<multi_floater name="im_floater" title="Mensaje Instantáneo">
-	<string name="only_user_message">
-		Eres el único Residente en esta sesión.
-	</string>
-	<string name="offline_message">
-		[FIRST] [LAST] no está conectado.
-	</string>
-	<string name="invite_message">
-		Pulse el botón [BUTTON NAME] para aceptar/conectar este chat de voz.
-	</string>
-	<string name="muted_message">
-		Has ignorado a este Residente. Enviándole un mensaje, automáticamente dejarás de ignorarle.
-	</string>
-	<string name="generic_request_error">
-		Error al hacer lo solicitado; por favor, inténtelo más tarde.
-	</string>
-	<string name="insufficient_perms_error">
-		Usted no tiene permisos suficientes.
-	</string>
-	<string name="session_does_not_exist_error">
-		La sesión ya acabó
-	</string>
-	<string name="no_ability_error">
-		Usted no tiene esa capacidad.
-	</string>
-	<string name="not_a_mod_error">
-		Usted no es un moderador de la sesión.
-	</string>
-	<string name="muted_error">
-		Un moderador del grupo le ha desactivado el chat de texto.
-	</string>
-	<string name="add_session_event">
-		No es posible añadir Residentes a la sesión de chat con [RECIPIENT].
-	</string>
-	<string name="message_session_event">
-		No se ha podido enviar su mensaje a la sesión de chat con [RECIPIENT].
-	</string>
-	<string name="removed_from_group">
-		Ha sido eliminado del grupo.
-	</string>
-	<string name="close_on_no_ability">
-		Usted ya no tendrá más la capacidad de estar en la sesión de chat.
-	</string>
-</multi_floater>
diff --git a/indra/newview/skins/default/xui/es/floater_preferences.xml b/indra/newview/skins/default/xui/es/floater_preferences.xml
index 61f12fc0d75e9095dc5b5dc31e49ecd2d365e893..372680f55df90f15040c35d104274524a573caed 100644
--- a/indra/newview/skins/default/xui/es/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/es/floater_preferences.xml
@@ -5,10 +5,12 @@
 	<tab_container name="pref core">
 		<panel label="General" name="general"/>
 		<panel label="Gráficos" name="display"/>
-		<panel label="Privacidad" name="im"/>
 		<panel label="Sonido y Media" name="audio"/>
 		<panel label="Chat" name="chat"/>
+		<panel label="Mover y ver" name="move"/>
 		<panel label="Notificaciones" name="msgs"/>
+		<panel label="Colores" name="colors"/>
+		<panel label="Privacidad" name="im"/>
 		<panel label="Configurar" name="input"/>
 		<panel label="Avanzado" name="advanced1"/>
 	</tab_container>
diff --git a/indra/newview/skins/default/xui/es/floater_region_debug_console.xml b/indra/newview/skins/default/xui/es/floater_region_debug_console.xml
new file mode 100644
index 0000000000000000000000000000000000000000..40851f897ecd8ed8be6a330cfa06855831d59423
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/floater_region_debug_console.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="region_debug_console" title="Depuración de región"/>
diff --git a/indra/newview/skins/default/xui/es/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/es/menu_inventory_gear_default.xml
index 8c4488a285e6910d66709a485f703b1bad3e9f15..8e498fefba1434807b3cf337a30e2b8326994d4c 100644
--- a/indra/newview/skins/default/xui/es/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/es/menu_inventory_gear_default.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="menu_gear_default">
+<toggleable_menu name="menu_gear_default">
 	<menu_item_call label="Nueva ventana del inventario" name="new_window"/>
-	<menu_item_call label="Ordenar alfabéticamente" name="sort_by_name"/>
-	<menu_item_call label="Ordenar por los más recientes" name="sort_by_recent"/>
+	<menu_item_check label="Ordenar alfabéticamente" name="sort_by_name"/>
+	<menu_item_check label="Ordenar por los más recientes" name="sort_by_recent"/>
+	<menu_item_check label="Las carpetas del sistema, arriba" name="sort_system_folders_to_top"/>
 	<menu_item_call label="Ver los filtros" name="show_filters"/>
 	<menu_item_call label="Restablecer los filtros" name="reset_filters"/>
 	<menu_item_call label="Cerrar todas las carpetas" name="close_folders"/>
@@ -12,4 +13,4 @@
 	<menu_item_call label="Encontrar el original" name="Find Original"/>
 	<menu_item_call label="Encontrar todos los enlazados" name="Find All Links"/>
 	<menu_item_call label="Vaciar la Papelera" name="empty_trash"/>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/es/menu_viewer.xml b/indra/newview/skins/default/xui/es/menu_viewer.xml
index 649c0c20437151c5b9559e6e20a1580289c2e6ac..3dd940c331f78359af4048cdb43398bc2f2ef4c0 100644
--- a/indra/newview/skins/default/xui/es/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/es/menu_viewer.xml
@@ -12,6 +12,12 @@
 		<menu_item_check label="Mi Inventario" name="ShowSidetrayInventory"/>
 		<menu_item_check label="Mis gestos" name="Gestures"/>
 		<menu_item_check label="Mi voz" name="ShowVoice"/>
+		<menu label="Movimiento" name="Movement">
+			<menu_item_call label="Sentarte" name="Sit Down Here"/>
+			<menu_item_check label="Volar" name="Fly"/>
+			<menu_item_check label="Correr siempre" name="Always Run"/>
+			<menu_item_call label="Parar mis animaciones" name="Stop Animating My Avatar"/>
+		</menu>
 		<menu label="Mi estado" name="Status">
 			<menu_item_call label="Ausente" name="Set Away"/>
 			<menu_item_call label="Ocupado" name="Set Busy"/>
@@ -47,6 +53,7 @@
 			<menu_item_check label="Propietarios del terreno" name="Land Owners"/>
 			<menu_item_check label="Coordenadas" name="Coordinates"/>
 			<menu_item_check label="Propiedades de la parcela" name="Parcel Properties"/>
+			<menu_item_check label="Menú Avanzado" name="Show Advanced Menu"/>
 		</menu>
 		<menu_item_call label="Teleportar a la Base" name="Teleport Home"/>
 		<menu_item_call label="Fijar mi Base aquí" name="Set Home to Here"/>
@@ -123,7 +130,6 @@
 		<menu_item_check label="Permitir consejos" name="Enable Hints"/>
 	</menu>
 	<menu label="Avanzado" name="Advanced">
-		<menu_item_call label="Parar mis animaciones" name="Stop Animating My Avatar"/>
 		<menu_item_call label="Recargar las texturas" name="Rebake Texture"/>
 		<menu_item_call label="Interfaz en el tamaño predeterminado" name="Set UI Size to Default"/>
 		<menu_item_call label="Definir el tamaño de la ventana..." name="Set Window Size..."/>
@@ -177,8 +183,7 @@
 			<menu_item_check label="Buscar" name="Search"/>
 			<menu_item_call label="Recuperar las teclas" name="Release Keys"/>
 			<menu_item_call label="Interfaz en el tamaño predeterminado" name="Set UI Size to Default"/>
-			<menu_item_check label="Correr siempre" name="Always Run"/>
-			<menu_item_check label="Volar" name="Fly"/>
+			<menu_item_check label="Mostrar el menú Avanzado - acceso directo antiguo" name="Show Advanced Menu - legacy shortcut"/>
 			<menu_item_call label="Cerrar la ventana" name="Close Window"/>
 			<menu_item_call label="Cerrar todas las ventanas" name="Close All Windows"/>
 			<menu_item_call label="Guardar una foto" name="Snapshot to Disk"/>
@@ -196,7 +201,6 @@
 			<menu_item_call label="Acercar el zoom" name="Zoom In"/>
 			<menu_item_call label="Zoom por defecto" name="Zoom Default"/>
 			<menu_item_call label="Alejar el zoom" name="Zoom Out"/>
-			<menu_item_check label="Mostrar el menú Avanzado" name="Show Advanced Menu"/>
 		</menu>
 		<menu_item_call label="Mostrar las configuraciones del depurador" name="Debug Settings"/>
 		<menu_item_check label="Mostrar el menú &apos;Develop&apos;" name="Debug Mode"/>
@@ -267,16 +271,13 @@
 			<menu_item_call label="Web Browser Test" name="Web Browser Test"/>
 			<menu_item_call label="Print Selected Object Info" name="Print Selected Object Info"/>
 			<menu_item_call label="Memory Stats" name="Memory Stats"/>
-			<menu_item_check label="Haz doble clic en Piloto automático" name="Double-ClickAuto-Pilot"/>
-			<menu_item_check label="Teleportar mediante doble clic" name="DoubleClick Teleport"/>
+			<menu_item_check label="Consola de depuración de región" name="Region Debug Console"/>
 			<menu_item_check label="Debug Clicks" name="Debug Clicks"/>
 			<menu_item_check label="Debug Mouse Events" name="Debug Mouse Events"/>
 		</menu>
 		<menu label="XUI" name="XUI">
 			<menu_item_call label="Reload Color Settings" name="Reload Color Settings"/>
 			<menu_item_call label="Show Font Test" name="Show Font Test"/>
-			<menu_item_call label="Load from XML" name="Load from XML"/>
-			<menu_item_call label="Save to XML" name="Save to XML"/>
 			<menu_item_check label="Show XUI Names" name="Show XUI Names"/>
 			<menu_item_call label="Send Test IMs" name="Send Test IMs"/>
 			<menu_item_call label="Eliminar registros de nombres en caché" name="Flush Names Caches"/>
@@ -303,9 +304,9 @@
 		</menu>
 		<menu_item_check label="HTTP Textures" name="HTTP Textures"/>
 		<menu_item_check label="Console Window on next Run" name="Console Window"/>
-		<menu_item_check label="Show Admin Menu" name="View Admin Options"/>
 		<menu_item_call label="Request Admin Status" name="Request Admin Options"/>
 		<menu_item_call label="Leave Admin Status" name="Leave Admin Options"/>
+		<menu_item_check label="Show Admin Menu" name="View Admin Options"/>
 	</menu>
 	<menu label="Admin" name="Admin">
 		<menu label="Object">
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 286af718e39d8e5732b74849b1f1255803bf3316..2dd7a6b0f549de273aa8a827b7a1342fcefa2483 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -385,6 +385,9 @@ Nota: esto vaciará la caché.
 	<notification name="ChangeSkin">
 		Verás la nueva apariencia cuando reinicies [APP_NAME].
 	</notification>
+	<notification name="ChangeLanguage">
+		El cambio de idioma tendrá efecto cuando reinicies [APP_NAME].
+	</notification>
 	<notification name="GoToAuctionPage">
 		¿Ir a la página web de [SECOND_LIFE] para ver los detalles de la subasta
 o hacer una puja?
@@ -597,6 +600,10 @@ Podría ser [VALIDS]
 	</notification>
 	<notification name="SoundFileInvalidHeader">
 		No se encontró el fragmento &apos;data&apos; en la cabecera del WAV:
+[FILE]
+	</notification>
+	<notification name="SoundFileInvalidChunkSize">
+		Tamaño de lote erróneo en el archivo WAV:
 [FILE]
 	</notification>
 	<notification name="SoundFileInvalidTooLong">
@@ -1334,6 +1341,16 @@ Esta actualización no es obligatoria, pero te sugerimos instalarla para mejorar
 ¿Descargarla a tu carpeta de Programas?
 		<usetemplate name="okcancelbuttons" notext="Continuar" yestext="Descargarla"/>
 	</notification>
+	<notification name="FailedUpdateInstall">
+		Se ha producido un error al instalar la actualización del visor.
+Descarga e instala el último visor a través de
+http://secondlife.com/download.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="DownloadBackground">
+		Se ha descargado una versión actualizada de [APP_NAME].
+Se aplicará la próxima vez que reinicies [APP_NAME]
+	</notification>
 	<notification name="DeedObjectToGroup">
 		Transferir este objeto al grupo hará que:
 * Reciba los L$ pagados en el objeto
@@ -2469,7 +2486,7 @@ Por favor, vuelve a intentarlo en unos momentos.
 		Rehusado el ofrecimiento de amistad.
 	</notification>
 	<notification name="OfferCallingCard">
-		[FIRST] [LAST] te está ofreciendo su tarjeta de visita.
+		[NAME] te está ofreciendo su tarjeta de visita.
 Esto añadirá un marcador en tu inventario para que puedas enviarle rápidamente un MI.
 		<form name="form">
 			<button name="Accept" text="Aceptar"/>
diff --git a/indra/newview/skins/default/xui/es/panel_edit_gloves.xml b/indra/newview/skins/default/xui/es/panel_edit_gloves.xml
index 684a35a830426f0627f7a790614a00c52bfd4891..d536a862f562b8df3c82783f8e2f8340da48e722 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_gloves.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_gloves_panel">
 	<panel name="avatar_gloves_color_panel">
-		<texture_picker label="Tela" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
 		<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_edit_jacket.xml b/indra/newview/skins/default/xui/es/panel_edit_jacket.xml
index 347107d746a5763a7284b0635150d5e3c4bd0a0b..22a46a2f753a8e0687986b7976e5a0d0f1dfe3e9 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_jacket.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_jacket_panel">
 	<panel name="avatar_jacket_color_panel">
-		<texture_picker label="Tejido superior" name="Upper Fabric" tool_tip="Pulsa para elegir una imagen"/>
-		<texture_picker label="Tejido inferior" name="Lower Fabric" tool_tip="Pulsa para elegir una imagen"/>
+		<texture_picker label="Textura superior" name="Upper Fabric" tool_tip="Pulsa para elegir una imagen"/>
+		<texture_picker label="Textura inferior" name="Lower Fabric" tool_tip="Pulsa para elegir una imagen"/>
 		<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_edit_pants.xml b/indra/newview/skins/default/xui/es/panel_edit_pants.xml
index e765702343524f651b9c6bf3f5cdd43aa0b23e8c..fb35e0953bf4b377b9c01116babbed8790c57e6d 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_pants.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_pants_panel">
 	<panel name="avatar_pants_color_panel">
-		<texture_picker label="Tela" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
 		<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_edit_shirt.xml b/indra/newview/skins/default/xui/es/panel_edit_shirt.xml
index f763e1b18d1e23bc335df579593bf7240a705a2d..73b712374e585f45b7978bef58a876749c3e2fe4 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_shirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_shirt_panel">
 	<panel name="avatar_shirt_color_panel">
-		<texture_picker label="Tela" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
 		<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_edit_shoes.xml b/indra/newview/skins/default/xui/es/panel_edit_shoes.xml
index 70f20273987b36ec3188128cf775fa3421ffbb93..5e457612d5a93e1213c522c57f384a38116cb999 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_shoes.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_shoes_panel">
 	<panel name="avatar_shoes_color_panel">
-		<texture_picker label="Tela" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
 		<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_edit_skirt.xml b/indra/newview/skins/default/xui/es/panel_edit_skirt.xml
index 2c7196642cda132fe09fb376261bd6e3bbb33fcd..416d174298ab2ea9fcc635a400d8bf294246b5e0 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_skirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_skirt_panel">
 	<panel name="avatar_skirt_color_panel">
-		<texture_picker label="Tela" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
 		<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_edit_socks.xml b/indra/newview/skins/default/xui/es/panel_edit_socks.xml
index 28423eaf617c573b1faf5fd610c501c727fb5418..ac9b2a773e324cd4273153d7c59f75a6d898de26 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_socks.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_socks_panel">
 	<panel name="avatar_socks_color_panel">
-		<texture_picker label="Tela" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
 		<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_edit_underpants.xml b/indra/newview/skins/default/xui/es/panel_edit_underpants.xml
index 6c82bcfedf9a3feac50090daf7c2ce3b40678f61..aac8af44b958b1283c132aee3c60287867c9f83a 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_underpants.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_underpants_panel">
 	<panel name="avatar_underpants_color_panel">
-		<texture_picker label="Tela" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
 		<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/es/panel_edit_undershirt.xml
index 412bdceddfc176d22342997afd04af3f7d628664..c26c554c1ab9059ba2ae4c5257db1990a69a0161 100644
--- a/indra/newview/skins/default/xui/es/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/es/panel_edit_undershirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_undershirt_panel">
 	<panel name="avatar_undershirt_color_panel">
-		<texture_picker label="Tela" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Pulsa para elegir una imagen"/>
 		<color_swatch label="Color/Tinte" name="Color/Tint" tool_tip="Pulsa para abrir el selector de color"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/es/panel_notify_textbox.xml b/indra/newview/skins/default/xui/es/panel_notify_textbox.xml
new file mode 100644
index 0000000000000000000000000000000000000000..10aaa288d7db99e3e767b5e017d2f18096e94b25
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_notify_textbox.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="instant_message" name="panel_notify_textbox">
+	<string name="message_max_lines_count" value="7"/>
+	<panel label="info_panel" name="info_panel">
+		<text_editor name="message" value="message"/>
+		parse_urls=&quot;false&quot;
+		<button label="Enviar" name="btn_submit"/>
+	</panel>
+	<panel label="control_panel" name="control_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_people.xml b/indra/newview/skins/default/xui/es/panel_people.xml
index 177373559882711f337afcac69ab267b512f021e..d0c80ebae531a9b56a4f283883b4ccbfca3d7cf2 100644
--- a/indra/newview/skins/default/xui/es/panel_people.xml
+++ b/indra/newview/skins/default/xui/es/panel_people.xml
@@ -22,7 +22,7 @@
 	<tab_container name="tabs">
 		<panel label="CERCANA" name="nearby_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="nearby_view_sort_btn" tool_tip="Opciones"/>
+				<menu_button name="nearby_view_sort_btn" tool_tip="Opciones"/>
 				<button name="add_friend_btn" tool_tip="Añadir al Residente seleccionado a la lista de tus amigos"/>
 			</panel>
 		</panel>
@@ -34,27 +34,27 @@
 			<panel label="bottom_panel" name="bottom_panel">
 				<layout_stack name="bottom_panel">
 					<layout_panel name="options_gear_btn_panel">
-						<button name="friends_viewsort_btn" tool_tip="Ver más opciones"/>
+						<menu_button name="friends_viewsort_btn" tool_tip="Ver más opciones"/>
 					</layout_panel>
 					<layout_panel name="add_btn_panel">
 						<button name="add_btn" tool_tip="Ofrecer amistad a un Residente"/>
 					</layout_panel>
 					<layout_panel name="trash_btn_panel">
-						<dnd_button name="trash_btn" tool_tip="Quitar a la persona seleccionada de tu lista de amigos"/>
+						<dnd_button name="del_btn" tool_tip="Quitar a la persona seleccionada de tu lista de amigos"/>
 					</layout_panel>
 				</layout_stack>
 			</panel>
 		</panel>
 		<panel label="MIS GRUPOS" name="groups_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="groups_viewsort_btn" tool_tip="Opciones"/>
+				<menu_button name="groups_viewsort_btn" tool_tip="Opciones"/>
 				<button name="plus_btn" tool_tip="Entrar en un grupo o crear uno"/>
 				<button name="activate_btn" tool_tip="Activar el grupo seleccionado"/>
 			</panel>
 		</panel>
 		<panel label="RECIENTE" name="recent_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="recent_viewsort_btn" tool_tip="Opciones"/>
+				<menu_button name="recent_viewsort_btn" tool_tip="Opciones"/>
 				<button name="add_friend_btn" tool_tip="Añadir al Residente seleccionado a la lista de tus amigos"/>
 			</panel>
 		</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_places.xml b/indra/newview/skins/default/xui/es/panel_places.xml
index 2e349c7fe256b90fbfdd66f2ddc5ebd27d06bccc..4c90a7e6b4636318e1022242dd986045aa28acf6 100644
--- a/indra/newview/skins/default/xui/es/panel_places.xml
+++ b/indra/newview/skins/default/xui/es/panel_places.xml
@@ -21,7 +21,7 @@
 						<button label="Editar" name="edit_btn" tool_tip="Editar la información del hito"/>
 					</layout_panel>
 					<layout_panel name="overflow_btn_lp">
-						<button label="▼" name="overflow_btn" tool_tip="Ver más opciones"/>
+						<menu_button label="▼" name="overflow_btn" tool_tip="Ver más opciones"/>
 					</layout_panel>
 				</layout_stack>
 				<layout_stack name="bottom_bar_ls3">
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
index d65868c0a8f03a2428fe99d2985f9583d64ef797..7c2c9f505e619ef9eb9a086a47937e58eef8ba97 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_advanced.xml
@@ -3,35 +3,16 @@
 	<panel.string name="aspect_ratio_text">
 		[NUM]:[DEN]
 	</panel.string>
-	<panel.string name="middle_mouse">
-		Botón medio del ratón
-	</panel.string>
-	<slider label="Ángulo de visión" name="camera_fov"/>
-	<slider label="Distancia" name="camera_offset_scale"/>
-	<text name="heading2">
-		Posición automática para:
-	</text>
-	<check_box label="Construir/Editar" name="edit_camera_movement" tool_tip="Usar el posicionamiento automático de la cámara al entrar en o salir del modo de edición"/>
-	<check_box label="Apariencia" name="appearance_camera_movement" tool_tip="Usar el posicionamiento automático de la cámara mientras se está editando"/>
-	<check_box initial_value="true" label="Barra lateral" name="appearance_sidebar_positioning" tool_tip="Usar el posicionamiento automático de la cámara para la barra lateral"/>
-	<check_box label="Verme en vista subjetiva" name="first_person_avatar_visible"/>
-	<check_box label="Las teclas del cursor siempre para moverme" name="arrow_keys_move_avatar_check"/>
-	<check_box label="Correr siempre: atajo de teclado" name="tap_tap_hold_to_run"/>
-	<check_box label="Al hablar, mover los labios del avatar" name="enable_lip_sync"/>
-	<check_box label="Chat en bocadillos" name="bubble_text_chat"/>
-	<slider label="Opacidad" name="bubble_chat_opacity"/>
-	<color_swatch name="background" tool_tip="Elegir el color de los bocadillos del chat"/>
 	<text name="UI Size:">
-		Tamaño de la UI
+		Tamaño de la UI:
 	</text>
 	<check_box label="Mostrar los errores de los scripts en:" name="show_script_errors"/>
 	<radio_group name="show_location">
 		<radio_item label="Chat" name="0"/>
 		<radio_item label="Ventanas distintas" name="1"/>
 	</radio_group>
-	<check_box label="Cambiar entre hablar on/off cuando pulse:" name="push_to_talk_toggle_check" tool_tip="En el modo &apos;un toque&apos;, pulsa y suelta el botón UNA VEZ para activar o desactivar el micrófono. Si no estás en el modo &apos;un toque&apos;, el micrófono sólo recogerá tu voz mientras mantengas pulsado el botón."/>
-	<line_editor label="Botón de Apretar para Hablar" name="modifier_combo"/>
-	<button label="Elegir la tecla" name="set_voice_hotkey_button"/>
-	<button label="Botón de en medio del ratón" name="set_voice_middlemouse_button" tool_tip="Reconfigurarlo al botón medio del ratón"/>
-	<button label="Otros dispositivos" name="joystick_setup_button"/>
+	<check_box label="Permitir el acceso de varios usuarios" name="allow_multiple_viewer_check"/>
+	<check_box label="Mostrar la selección de cuadrícula al iniciar sesión" name="show_grid_selection_check"/>
+	<check_box label="Mostrar el menú Avanzado" name="show_advanced_menu_check"/>
+	<check_box label="Mostrar el menú Desarrollador" name="show_develop_menu_check"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
index 05aea82d824860f67bd7ef4c5774e8cf16383a52..67f9a929f68c2b58076977788ed8511386d86fb5 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_chat.xml
@@ -8,44 +8,10 @@
 		<radio_item label="Medio" name="radio2" value="1"/>
 		<radio_item label="Aumentar" name="radio3" value="2"/>
 	</radio_group>
-	<text name="font_colors">
-		Colores de la fuente:
-	</text>
-	<color_swatch label="Usted" name="user"/>
-	<text name="text_box1">
-		Yo
-	</text>
-	<color_swatch label="Otros" name="agent"/>
-	<text name="text_box2">
-		Otros
-	</text>
-	<color_swatch label="MI" name="im"/>
-	<text name="text_box3">
-		MI
-	</text>
-	<color_swatch label="Sistema" name="system"/>
-	<text name="text_box4">
-		Sistema
-	</text>
-	<color_swatch label="Errores de script" name="script_error"/>
-	<text name="text_box5">
-		Errores de script
-	</text>
-	<color_swatch label="Objetos" name="objects"/>
-	<text name="text_box6">
-		Objetos
-	</text>
-	<color_swatch label="Propietario" name="owner"/>
-	<text name="text_box7">
-		Propietario
-	</text>
-	<color_swatch label="URL" name="links"/>
-	<text name="text_box9">
-		URL
-	</text>
 	<check_box initial_value="true" label="Ejecutar la animación de escribir al hacerlo en el chat" name="play_typing_animation"/>
 	<check_box label="Cuando estoy desconectado, enviarme los MI al correo-e" name="send_im_to_email"/>
 	<check_box label="Permitir el historial de MI y chat en texto sin formato" name="plain_text_chat_history"/>
+	<check_box label="Bocadillos del chat" name="bubble_text_chat"/>
 	<text name="show_ims_in_label">
 		Mostrar los MI en:
 	</text>
@@ -53,9 +19,16 @@
 		(requiere reiniciar)
 	</text>
 	<radio_group name="chat_window" tool_tip="Muestra tus mensajes instantáneos en varias ventanas flotantes o en una sola con varias pestañas (requiere que reinicies)">
-		<radio_item label="Varias ventanas" name="radio" value="0"/>
+		<radio_item label="Ventanas distintas" name="radio" value="0"/>
 		<radio_item label="Pestañas" name="radio2" value="1"/>
 	</radio_group>
+	<text name="disable_toast_label">
+		Permitir ventanas de chat emergentes:
+	</text>
+	<check_box label="Chats de grupo" name="EnableGroupChatPopups" tool_tip="Activa esta casilla para ver una ventana emergente cada vez que recibas un mensaje de un grupo de chat"/>
+	<check_box label="Chats de MI" name="EnableIMChatPopups" tool_tip="Activa esta casilla para ver una ventana emergente cada vez que recibas un mensaje instantáneo"/>
+	<spinner label="Duración de los interlocutores favoritos en los chats:" name="nearby_toasts_lifetime"/>
+	<spinner label="Tiempo restante de los interlocutores favoritos en los chats:" name="nearby_toasts_fadingtime"/>
 	<check_box label="Utiliza la herramienta de traducción automática mientras utilizas el chat (mediante Google)" name="translate_chat_checkbox"/>
 	<text name="translate_language_text">
 		Traducir el chat al:
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_colors.xml b/indra/newview/skins/default/xui/es/panel_preferences_colors.xml
new file mode 100644
index 0000000000000000000000000000000000000000..4fa5c4ce635d8f89327a7187e050ee32f97afd13
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_preferences_colors.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Colores" name="colors_panel">
+	<text name="effects_color_textbox">
+		Mis efectos (rayo indicador):
+	</text>
+	<color_swatch name="effect_color_swatch" tool_tip="Pulsa para abrir el selector de color"/>
+	<text name="font_colors">
+		Colores de fuente del chat:
+	</text>
+	<text name="text_box1">
+		Yo
+	</text>
+	<text name="text_box2">
+		Otros avatares
+	</text>
+	<text name="text_box3">
+		Objetos
+	</text>
+	<text name="text_box4">
+		Sistema
+	</text>
+	<text name="text_box5">
+		Errores
+	</text>
+	<text name="text_box7">
+		Propietario
+	</text>
+	<text name="text_box9">
+		URL
+	</text>
+	<text name="bubble_chat">
+		Fondo de los bocadillos del chat:
+	</text>
+	<color_swatch name="background" tool_tip="Elegir el color de los bocadillos del chat"/>
+	<slider label="Opacidad:" name="bubble_chat_opacity"/>
+	<text name="floater_opacity">
+		Opacidad de la ventana:
+	</text>
+	<slider label="Activo:" name="active"/>
+	<slider label="Inactivo:" name="inactive"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_general.xml b/indra/newview/skins/default/xui/es/panel_preferences_general.xml
index 5b8cb77173873a5b7279bbd311224ab714a6e3a2..91cf9524a3639b459044c78c5090320aa8fbd545 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_general.xml
@@ -48,13 +48,18 @@
 	<check_box label="Nombre de usuario" name="show_slids" tool_tip="Mostrar el nombre de usuario, como bobsmith123"/>
 	<check_box label="Títulos de grupos" name="show_all_title_checkbox1" tool_tip="Mostrar títulos de grupos, como Jefe o Miembro"/>
 	<check_box label="Realzar amigos" name="show_friends" tool_tip="Realzar las etiquetas de los nombres de tus amigos"/>
-	<text name="effects_color_textbox">
-		Mis efectos:
+	<check_box label="Ver nombres mostrados" name="display_names_check" tool_tip="Comprobar para utilizar nombres mostrados en chat, MI, etiquetas de nombres, etc."/>
+	<check_box label="Permitir los consejos de la IU del visor" name="viewer_hints_check"/>
+	<text name="inworld_typing_rg_label">
+		Si pulsas las teclas de letras:
 	</text>
+	<radio_group name="inworld_typing_preference">
+		<radio_item label="Inicia el chat local" name="radio_start_chat" value="1"/>
+		<radio_item label="Se verá afectado el movimiento (por ejemplo, mediante las teclas WASD)" name="radio_move" value="0"/>
+	</radio_group>
 	<text name="title_afk_text">
 		Ausente tras:
 	</text>
-	<color_swatch label="" name="effect_color_swatch" tool_tip="Pulse para abrir el selector de color"/>
 	<combo_box label="Ausente tras:" name="afk">
 		<combo_box.item label="2 minutos" name="item0"/>
 		<combo_box.item label="5 minutos" name="item1"/>
@@ -62,7 +67,6 @@
 		<combo_box.item label="30 minutos" name="item3"/>
 		<combo_box.item label="nunca" name="item4"/>
 	</combo_box>
-	<check_box label="Ver nombres mostrados" name="display_names_check" tool_tip="Comprobar para utilizar nombres mostrados en chat, MI, etiquetas de nombres, etc."/>
 	<text name="text_box3">
 		Respuesta cuando estoy en modo ocupado:
 	</text>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
index 36b64930041748be836a56a4366b5e5568a43e68..c569db33762c20a79cfdfe936485abdf6ebbc2be 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_graphics1.xml
@@ -25,6 +25,7 @@
 		<text name="ShadersText">
 			Shaders:
 		</text>
+		<check_box initial_value="verdadero" label="Agua transparente" name="TransparentWater"/>
 		<check_box initial_value="true" label="Efecto de relieve y brillo" name="BumpShiny"/>
 		<check_box initial_value="true" label="Shaders básicos" name="BasicShaders" tool_tip="Desactivando esta opción puede prevenir fallos en algunos controladores de la tarjeta gráfica."/>
 		<check_box initial_value="true" label="Shaders de la atmósfera" name="WindLightUseAtmosShaders"/>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_move.xml b/indra/newview/skins/default/xui/es/panel_preferences_move.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d95e1673612d60c55037570fe35aa21325e2c154
--- /dev/null
+++ b/indra/newview/skins/default/xui/es/panel_preferences_move.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Mover" name="move_panel">
+	<slider label="Ángulo de visión" name="camera_fov"/>
+	<slider label="Distancia" name="camera_offset_scale"/>
+	<text name="heading2">
+		Posición automática para:
+	</text>
+	<check_box label="Construir/Editar" name="edit_camera_movement" tool_tip="Usar el posicionamiento automático de la cámara al entrar en o salir del modo de edición"/>
+	<check_box label="Apariencia" name="appearance_camera_movement" tool_tip="Usar el posicionamiento automático de la cámara mientras se está editando"/>
+	<check_box initial_value="verdadero" label="Barra lateral" name="appearance_sidebar_positioning" tool_tip="Usar el posicionamiento automático de la cámara para la barra lateral"/>
+	<check_box label="Verme en vista subjetiva" name="first_person_avatar_visible"/>
+	<text name=" Mouse Sensitivity">
+		Sensibilidad del ratón en la Vista subjetiva:
+	</text>
+	<check_box label="Invertir" name="invert_mouse"/>
+	<check_box label="Las teclas del cursor siempre para moverme" name="arrow_keys_move_avatar_check"/>
+	<check_box label="Correr siempre: atajo de teclado" name="tap_tap_hold_to_run"/>
+	<check_box label="Haz doble clic para:" name="double_click_chkbox"/>
+	<radio_group name="double_click_action">
+		<radio_item label="Teleportarte" name="radio_teleport"/>
+		<radio_item label="Piloto automático" name="radio_autopilot"/>
+	</radio_group>
+	<button label="Otros dispositivos" name="joystick_setup_button"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml
index bf2c6b7aa61250bf066643ebf542ccdc9cc5cd84..abff72c346c1c516bda3aa2e63f7dfe635da7f2f 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_privacy.xml
@@ -10,17 +10,20 @@
 	<check_box label="Sólo saben si estoy conectado mis amigos y grupos" name="online_visibility"/>
 	<check_box label="Sólo pueden llamarme o mandarme un MI mis amigos y grupos" name="voice_call_friends_only_check"/>
 	<check_box label="Desconectar el micrófono cuando finalicen las llamadas" name="auto_disengage_mic_check"/>
-	<check_box label="Aceptar las &apos;cookies&apos;" name="cookies_enabled"/>
 	<text name="Logs:">
-		Registros:
+		Registros de chat:
 	</text>
 	<check_box label="Guardar en mi ordenador registros del chat" name="log_nearby_chat"/>
 	<check_box label="Guardar en mi ordenador registros de los MI" name="log_instant_messages"/>
-	<check_box label="Añadir fecha y hora" name="show_timestamps_check_im"/>
+	<check_box label="Añadir fecha y hora a todas las líneas del registro de chat" name="show_timestamps_check_im"/>
+	<check_box label="Añadir la fecha al nombre del archivo del registro." name="logfile_name_datestamp"/>
 	<text name="log_path_desc">
 		Ruta de los registros:
 	</text>
 	<line_editor left="278" name="log_path_string" right="-20"/>
 	<button label="Elegir" label_selected="Elegir" name="log_path_button" width="120"/>
 	<button label="Lista de ignorados" name="block_list"/>
+	<text name="block_list_label">
+		(Gente u objetos que has bloqueado)
+	</text>
 </panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
index 100951a51ebb4a509e1a58c5389d580742e31251..f968f489100c38a954d48ac6755257a0bf68db0b 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_setup.xml
@@ -1,12 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Configurar" name="Input panel">
-	<text name="Mouselook:">
-		Vista subjetiva:
-	</text>
-	<text name=" Mouse Sensitivity">
-		Sensibilidad del ratón
-	</text>
-	<check_box label="Invertir" name="invert_mouse"/>
 	<text name="Network:">
 		Red:
 	</text>
@@ -46,4 +39,5 @@
 	</text>
 	<line_editor name="web_proxy_editor" tool_tip="Nombre o dirección IP del proxy que quieres usar"/>
 	<spinner label="Nº del puerto:" name="web_proxy_port"/>
+	<check_box initial_value="verdadero" label="Descargar e instalar automáticamente actualizaciones de [APP_NAME]" name="updater_service_active"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/es/panel_preferences_sound.xml b/indra/newview/skins/default/xui/es/panel_preferences_sound.xml
index b0088ee1a2d3a2254f64bd087251ed25bc2596ae..7989100c09ecf2a04c6d9da197e7e6c337647a62 100644
--- a/indra/newview/skins/default/xui/es/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/es/panel_preferences_sound.xml
@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Sonidos" name="Preference Media panel">
+	<panel.string name="middle_mouse">
+		Botón medio del ratón
+	</panel.string>
 	<slider label="Volumen general" name="System Volume"/>
 	<check_box initial_value="true" label="Silenciar cuando minimice" name="mute_when_minimized"/>
 	<slider label="Botones" name="UI Volume"/>
@@ -23,6 +26,11 @@
 		<radio_item label="La posición de la cámara" name="0"/>
 		<radio_item label="La posición del avatar" name="1"/>
 	</radio_group>
+	<check_box label="Al hablar, mover los labios del avatar" name="enable_lip_sync"/>
+	<check_box label="Cambiar entre hablar on/off cuando pulse:" name="push_to_talk_toggle_check" tool_tip="En el modo &apos;un toque&apos;, pulsa y suelta el botón UNA VEZ para activar o desactivar el micrófono. Si no estás en el modo &apos;un toque&apos;, el micrófono sólo recogerá tu voz mientras mantengas pulsado el botón."/>
+	<line_editor label="Botón de Apretar para Hablar" name="modifier_combo"/>
+	<button label="Elegir la tecla" name="set_voice_hotkey_button"/>
+	<button name="set_voice_middlemouse_button" tool_tip="Reconfigurarlo al botón medio del ratón"/>
 	<button label="Dispositivos de entrada y salida" name="device_settings_btn" width="210"/>
 	<panel label="Configuración de dispositivos" name="device_settings_panel">
 		<panel.string name="default_text">
diff --git a/indra/newview/skins/default/xui/es/panel_profile.xml b/indra/newview/skins/default/xui/es/panel_profile.xml
index 5cfe83cd612f3af446d044352496c26fe1c309db..339a1f236bab167d78a4697812926f14dcd8ccae 100644
--- a/indra/newview/skins/default/xui/es/panel_profile.xml
+++ b/indra/newview/skins/default/xui/es/panel_profile.xml
@@ -53,7 +53,7 @@
 					<button label="Teleporte" name="teleport" tool_tip="Ofrecer teleporte"/>
 				</layout_panel>
 				<layout_panel name="overflow_btn_lp">
-					<button label="▼" name="overflow_btn" tool_tip="Pagar dinero al Residente o compartir algo del inventario con él"/>
+					<menu_button label="▼" name="overflow_btn" tool_tip="Pagar dinero al Residente o compartir algo del inventario con él"/>
 				</layout_panel>
 			</layout_stack>
 		</layout_panel>
diff --git a/indra/newview/skins/default/xui/es/panel_script_ed.xml b/indra/newview/skins/default/xui/es/panel_script_ed.xml
index c73db729fe5d502114b4c1257e1327dd66d6e2c2..5be25a286da070675bce79ead284e3773f5ce1ff 100644
--- a/indra/newview/skins/default/xui/es/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/es/panel_script_ed.xml
@@ -15,11 +15,6 @@
 	<panel.string name="Title">
 		Script: [NAME]
 	</panel.string>
-	<text_editor name="Script Editor">
-		Cargando...
-	</text_editor>
-	<button label="Guardar" label_selected="Guardar" name="Save_btn"/>
-	<combo_box label="Insertar..." name="Insert..."/>
 	<menu_bar name="script_menu">
 		<menu label="Archivo" name="File">
 			<menu_item_call label="Guardar" name="Save"/>
@@ -40,4 +35,10 @@
 			<menu_item_call label="Ayuda de palabras clave..." name="Keyword Help..."/>
 		</menu>
 	</menu_bar>
+	<text_editor name="Script Editor">
+		Cargando...
+	</text_editor>
+	<combo_box label="Insertar..." name="Insert..."/>
+	<button label="Guardar" label_selected="Guardar" name="Save_btn"/>
+	<button label="Editar..." name="Edit_btn"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/es/strings.xml b/indra/newview/skins/default/xui/es/strings.xml
index 0be827f5f7323f7978fc05addc61fd5345110a6f..810b1630dda07482c8ce7e9e3a6de791f1ff02a5 100644
--- a/indra/newview/skins/default/xui/es/strings.xml
+++ b/indra/newview/skins/default/xui/es/strings.xml
@@ -1740,11 +1740,8 @@
 	<string name="InvOfferGaveYou">
 		te ha dado
 	</string>
-	<string name="InvOfferYouDecline">
-		Has rehusado
-	</string>
-	<string name="InvOfferFrom">
-		de
+	<string name="InvOfferDecline">
+		Rechazas [DESC] de &lt;nolink&gt;[NAME]&lt;/nolink&gt;.
 	</string>
 	<string name="GroupMoneyTotal">
 		Total
diff --git a/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml b/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
index e3d604477cf9d564ab0c329b2496cd6bfc42f979..8ad301823bf2ea8f8888d6267d608edf6f50aa61 100644
--- a/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/fr/floater_hardware_settings.xml
@@ -14,6 +14,9 @@
 		<combo_box.item label="8x" name="8x"/>
 		<combo_box.item label="16x" name="16x"/>
 	</combo_box>
+	<text name="antialiasing restart">
+		(redémarrage du client requis)
+	</text>
 	<spinner label="Gamma :" name="gamma"/>
 	<text left="217" name="(brightness, lower is brighter)">
 		(0 = défaut, valeur faible = plus lumineux)
diff --git a/indra/newview/skins/default/xui/fr/floater_preferences.xml b/indra/newview/skins/default/xui/fr/floater_preferences.xml
index 052e43388b03c26b21d62e0faad207df6b37d757..0f9fb1334b58879ffbfbb95572b71cf3d0d033e7 100644
--- a/indra/newview/skins/default/xui/fr/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/fr/floater_preferences.xml
@@ -5,10 +5,12 @@
 	<tab_container name="pref core">
 		<panel label="Général" name="general"/>
 		<panel label="Graphiques" name="display"/>
-		<panel label="Confidentialité" name="im"/>
 		<panel label="Son et Média" name="audio"/>
 		<panel label="Chat" name="chat"/>
+		<panel label="Affichage/Déplacement" name="move"/>
 		<panel label="Notifications" name="msgs"/>
+		<panel label="Couleurs" name="colors"/>
+		<panel label="Confidentialité" name="im"/>
 		<panel label="Configuration" name="input"/>
 		<panel label="Avancées" name="advanced1"/>
 	</tab_container>
diff --git a/indra/newview/skins/default/xui/fr/floater_region_debug_console.xml b/indra/newview/skins/default/xui/fr/floater_region_debug_console.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1747155b6099d99cc3510162f0b936ba9a083208
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/floater_region_debug_console.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="region_debug_console" title="Débogage de région"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/fr/menu_inspect_avatar_gear.xml
index 8bda133a0b469002b24fdfe1343b541dd48dbac4..17254ff325f1802100a79d37524276917b93acb5 100644
--- a/indra/newview/skins/default/xui/fr/menu_inspect_avatar_gear.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inspect_avatar_gear.xml
@@ -3,7 +3,7 @@
 	<menu_item_call label="Voir le profil" name="view_profile"/>
 	<menu_item_call label="Devenir amis" name="add_friend"/>
 	<menu_item_call label="IM" name="im"/>
-	<menu_item_call label="Appeler" name="call"/>
+	<menu_item_call label="Appel" name="call"/>
 	<menu_item_call label="Téléporter" name="teleport"/>
 	<menu_item_call label="Inviter dans le groupe" name="invite_to_group"/>
 	<menu_item_call label="Ignorer" name="block"/>
diff --git a/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml
index 73770dce5f73553600eaa4c43b3d6727b9cd53ec..f28918ae1421eebbac64771c05266973a8ed74f3 100644
--- a/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/fr/menu_inventory_gear_default.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="menu_gear_default">
+<toggleable_menu name="menu_gear_default">
 	<menu_item_call label="Nouvelle fenêtre d&apos;inventaire" name="new_window"/>
-	<menu_item_call label="Trier par nom" name="sort_by_name"/>
-	<menu_item_call label="Trier en commençant par le plus récent" name="sort_by_recent"/>
+	<menu_item_check label="Trier par nom" name="sort_by_name"/>
+	<menu_item_check label="Trier en commençant par le plus récent" name="sort_by_recent"/>
+	<menu_item_check label="Dossiers système en premier" name="sort_system_folders_to_top"/>
 	<menu_item_call label="Afficher les filtres" name="show_filters"/>
 	<menu_item_call label="Réinitialiser les filtres" name="reset_filters"/>
 	<menu_item_call label="Fermer tous les dossiers" name="close_folders"/>
@@ -12,4 +13,4 @@
 	<menu_item_call label="Trouver l&apos;original" name="Find Original"/>
 	<menu_item_call label="Trouver tous les liens" name="Find All Links"/>
 	<menu_item_call label="Vider la corbeille" name="empty_trash"/>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/fr/menu_viewer.xml b/indra/newview/skins/default/xui/fr/menu_viewer.xml
index 4e09a9bec30a019140a126c1ef01698b530a3ff5..fb4ab314afed3a025b01fb7dbe076b02d75e84f3 100644
--- a/indra/newview/skins/default/xui/fr/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/fr/menu_viewer.xml
@@ -12,6 +12,12 @@
 		<menu_item_check label="Mon inventaire" name="ShowSidetrayInventory"/>
 		<menu_item_check label="Mes gestes" name="Gestures"/>
 		<menu_item_check label="Ma voix" name="ShowVoice"/>
+		<menu label="Déplacement" name="Movement">
+			<menu_item_call label="M&apos;asseoir" name="Sit Down Here"/>
+			<menu_item_check label="Voler" name="Fly"/>
+			<menu_item_check label="Toujours courir" name="Always Run"/>
+			<menu_item_call label="Arrêter mon animation" name="Stop Animating My Avatar"/>
+		</menu>
 		<menu label="Mon statut" name="Status">
 			<menu_item_call label="Absent" name="Set Away"/>
 			<menu_item_call label="Occupé" name="Set Busy"/>
@@ -47,6 +53,7 @@
 			<menu_item_check label="Propriétaires de terrains" name="Land Owners"/>
 			<menu_item_check label="Coordonnées" name="Coordinates"/>
 			<menu_item_check label="Propriétés de la parcelle" name="Parcel Properties"/>
+			<menu_item_check label="Menu Avancé" name="Show Advanced Menu"/>
 		</menu>
 		<menu_item_call label="Me téléporter chez moi" name="Teleport Home"/>
 		<menu_item_call label="Définir le domicile ici" name="Set Home to Here"/>
@@ -123,7 +130,6 @@
 		<menu_item_check label="Activer les astuces" name="Enable Hints"/>
 	</menu>
 	<menu label="Avancé" name="Advanced">
-		<menu_item_call label="Arrêter mon animation" name="Stop Animating My Avatar"/>
 		<menu_item_call label="Refixer les textures" name="Rebake Texture"/>
 		<menu_item_call label="Taille de l&apos;interface par défaut" name="Set UI Size to Default"/>
 		<menu_item_call label="Définir la taille de la fenêtre…" name="Set Window Size..."/>
@@ -177,8 +183,7 @@
 			<menu_item_check label="Rechercher" name="Search"/>
 			<menu_item_call label="Relâcher les touches" name="Release Keys"/>
 			<menu_item_call label="Taille de l&apos;interface par défaut" name="Set UI Size to Default"/>
-			<menu_item_check label="Toujours courir" name="Always Run"/>
-			<menu_item_check label="Voler" name="Fly"/>
+			<menu_item_check label="Afficher le menu Avancé - raccourci existant" name="Show Advanced Menu - legacy shortcut"/>
 			<menu_item_call label="Fermer la fenêtre" name="Close Window"/>
 			<menu_item_call label="Fermer toutes les fenêtres" name="Close All Windows"/>
 			<menu_item_call label="Photo sur disque" name="Snapshot to Disk"/>
@@ -196,7 +201,6 @@
 			<menu_item_call label="Zoomer en avant" name="Zoom In"/>
 			<menu_item_call label="Zoom par défaut" name="Zoom Default"/>
 			<menu_item_call label="Zoomer en arrière" name="Zoom Out"/>
-			<menu_item_check label="Afficher le menu Avancé" name="Show Advanced Menu"/>
 		</menu>
 		<menu_item_call label="Afficher les paramètres de débogage" name="Debug Settings"/>
 		<menu_item_check label="Afficher le menu Développeurs" name="Debug Mode"/>
@@ -311,8 +315,7 @@
 			<menu_item_call label="Imprimer les infos sur l&apos;objet sélectionné" name="Print Selected Object Info"/>
 			<menu_item_call label="Imprimer les infos sur l&apos;avatar" name="Print Agent Info"/>
 			<menu_item_call label="Statistiques de mémoire" name="Memory Stats"/>
-			<menu_item_check label="Pilotage auto par double-clic" name="Double-ClickAuto-Pilot"/>
-			<menu_item_check label="Téléportation par double-clic" name="DoubleClick Teleport"/>
+			<menu_item_check label="Console de débogage de région" name="Region Debug Console"/>
 			<menu_item_check label="Débogage SelectMgr" name="Debug SelectMgr"/>
 			<menu_item_check label="Débogage clics" name="Debug Clicks"/>
 			<menu_item_check label="Débogage des vues" name="Debug Views"/>
@@ -324,8 +327,6 @@
 		<menu label="XUI" name="XUI">
 			<menu_item_call label="Recharger les paramètres de couleurs" name="Reload Color Settings"/>
 			<menu_item_call label="Afficher le test de police" name="Show Font Test"/>
-			<menu_item_call label="Charger à partir de XML" name="Load from XML"/>
-			<menu_item_call label="Enregistrer en XML" name="Save to XML"/>
 			<menu_item_check label="Afficher les noms XUI" name="Show XUI Names"/>
 			<menu_item_call label="Envoyer des IM tests" name="Send Test IMs"/>
 			<menu_item_call label="Vider les caches de noms" name="Flush Names Caches"/>
@@ -365,9 +366,9 @@
 		<menu_item_call label="Compresser les images" name="Compress Images"/>
 		<menu_item_check label="Output Debug Minidump" name="Output Debug Minidump"/>
 		<menu_item_check label="Console Window on next Run" name="Console Window"/>
-		<menu_item_check label="Afficher le menu Admin" name="View Admin Options"/>
 		<menu_item_call label="Demander le statut Admin" name="Request Admin Options"/>
 		<menu_item_call label="Quitter le statut Admin" name="Leave Admin Options"/>
+		<menu_item_check label="Afficher le menu Admin" name="View Admin Options"/>
 	</menu>
 	<menu label="Admin" name="Admin">
 		<menu label="Object">
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index 89fd9c6fdcaadaa715ccd9746d7042bd0346cb3f..ec362d7f22f73a87e66df815fe5463757c9d098e 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -387,6 +387,9 @@ Remarque : cela videra le cache.
 	<notification name="ChangeSkin">
 		Le nouveau thème apparaîtra après le redémarrage de [APP_NAME].
 	</notification>
+	<notification name="ChangeLanguage">
+		Le changement de langue sera effectué au redémarrage de [APP_NAME].
+	</notification>
 	<notification name="GoToAuctionPage">
 		Aller à la page web de [SECOND_LIFE] pour voir le détail des enchères ou enchérir ?
 		<url name="url">
@@ -597,6 +600,10 @@ Assurez-vous que le fichier a l&apos;extension correcte.
 	</notification>
 	<notification name="SoundFileInvalidHeader">
 		Impossible de trouver les données dans l&apos;en-tête WAV :
+[FILE]
+	</notification>
+	<notification name="SoundFileInvalidChunkSize">
+		Taille de fragment incorrecte dans le fichier WAV :
 [FILE]
 	</notification>
 	<notification name="SoundFileInvalidTooLong">
@@ -1325,6 +1332,16 @@ Cette mise à jour n&apos;est pas requise mais si vous voulez une meilleure perf
 Télécharger vers le dossier Applications ?
 		<usetemplate name="okcancelbuttons" notext="Continuer" yestext="Télécharger"/>
 	</notification>
+	<notification name="FailedUpdateInstall">
+		Une erreur est survenue lors de l&apos;installation de la mise à jour du client.
+Veuillez télécharger et installer la dernière version du client à la page Web
+http://secondlife.com/download.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="DownloadBackground">
+		Une mise à jour de [APP_NAME] a été téléchargée.
+Elle sera appliquée au prochain redémarrage de [APP_NAME].
+	</notification>
 	<notification name="DeedObjectToGroup">
 		Si vous cédez cet objet, le groupe :
 * recevra les L$ versés pour l&apos;objet ;
@@ -2464,8 +2481,8 @@ Veuillez réessayer dans quelques minutes.
 		Amitié refusée.
 	</notification>
 	<notification name="OfferCallingCard">
-		[FIRST] [LAST] vous offre sa carte de visite.
-Cela ajoute un marque-page dans votre inventaire, ce qui vous permet d&apos;envoyer rapidement un IM à ce résident.
+		[NAME] vous offre sa carte de visite.
+Un signet sera ajouté dans votre inventaire afin que vous puissiez envoyer rapidement un IM à ce résident.
 		<form name="form">
 			<button name="Accept" text="Accepter"/>
 			<button name="Decline" text="Refuser"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_gloves.xml b/indra/newview/skins/default/xui/fr/panel_edit_gloves.xml
index 7f02222bef2412ebfce4f1b3e4a613f47de2fe94..68a7ac54e2c6144a58a06699e571eb1dcf75e353 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_gloves.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_gloves_panel">
 	<panel name="avatar_gloves_color_panel">
-		<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Texture" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
 		<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="80"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_jacket.xml b/indra/newview/skins/default/xui/fr/panel_edit_jacket.xml
index 0a87471db882dd8946f4e8ae543a138e1cdacd90..7e467b130cf071c52935726b887f913ece4e8f39 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_jacket.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_jacket_panel">
 	<panel name="avatar_jacket_color_panel">
-		<texture_picker label="Tissu (haut)" name="Upper Fabric" tool_tip="Cliquez pour sélectionner une image"/>
-		<texture_picker label="Tissu (bas)" name="Lower Fabric" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Texture (haut)" name="Upper Fabric" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Texture (bas)" name="Lower Fabric" tool_tip="Cliquez pour sélectionner une image"/>
 		<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="80"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_pants.xml b/indra/newview/skins/default/xui/fr/panel_edit_pants.xml
index b9f81278e22e6f57743ce4d0cfbbee1adb06a817..60d8e947f82c594068a1eedf403ff3d66f3309f5 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_pants.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_pants_panel">
 	<panel name="avatar_pants_color_panel">
-		<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Texture" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
 		<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="80"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_profile.xml b/indra/newview/skins/default/xui/fr/panel_edit_profile.xml
index 30799caf1f57f5e0ceb2b65b9410f5a6bf9a4693..ef65d2fe242fd3c0a82a0fa6abdcca976c6901f7 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_profile.xml
@@ -54,7 +54,7 @@
 				<text name="my_account_link" value="[[URL] Accéder à ma Page d&apos;accueil]"/>
 				<text name="title_partner_text" value="Mon partenaire :"/>
 				<panel name="partner_data_panel">
-					<text initial_value="(récupération en cours)" name="partner_text" value="[FIRST] [LAST]"/>
+					<text initial_value="(récupération en cours)" name="partner_text"/>
 				</panel>
 				<text name="partner_edit_link" value="[[URL] Modifier]"/>
 			</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_shirt.xml b/indra/newview/skins/default/xui/fr/panel_edit_shirt.xml
index e4e66db2edd103308308e2789b52dfde48098ef2..9a263f6148ce2cfaaf01cb57505ad9feec10b0ae 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_shirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_shirt_panel">
 	<panel name="avatar_shirt_color_panel">
-		<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Texture" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
 		<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="80"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_shoes.xml b/indra/newview/skins/default/xui/fr/panel_edit_shoes.xml
index 6fca0fe1217a1992a5de3498d2c9b54d05c68c6b..3eb70923ef246a678a2c8308a4efa340113aca95 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_shoes.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_shoes_panel">
 	<panel name="avatar_shoes_color_panel">
-		<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Texture" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
 		<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="80"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_skirt.xml b/indra/newview/skins/default/xui/fr/panel_edit_skirt.xml
index 65fed2fbf49a46c1150aa151394cab0686e61a1c..f562d679373befb47b34b0a10358c03d5638c2c2 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_skirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_skirt_panel">
 	<panel name="avatar_skirt_color_panel">
-		<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Texture" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
 		<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="80"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_socks.xml b/indra/newview/skins/default/xui/fr/panel_edit_socks.xml
index b9e9a07b8ce6543e11e2f4609f1d8555a98928d8..f97047ae28a60db8a6be4b1027525eea2714b5db 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_socks.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_socks_panel">
 	<panel name="avatar_socks_color_panel">
-		<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Texture" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
 		<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="80"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_underpants.xml b/indra/newview/skins/default/xui/fr/panel_edit_underpants.xml
index 7eddbd93f6a001f929ea49e830bdee2a8fb5e72d..c83ce048851ad2269b9f6a4a6731f5d52cdb3ad7 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_underpants.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_underpants_panel">
 	<panel name="avatar_underpants_color_panel">
-		<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Texture" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
 		<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="80"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/fr/panel_edit_undershirt.xml
index e6bac22c231bff19e7fec9fd4fd0bcd7dc5aebe0..689b7b81f4572cea7634c3b9745d9cdebd99edeb 100644
--- a/indra/newview/skins/default/xui/fr/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/fr/panel_edit_undershirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_undershirt_panel">
 	<panel name="avatar_undershirt_color_panel">
-		<texture_picker label="Tissu" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
+		<texture_picker label="Texture" name="Fabric" tool_tip="Cliquez pour sélectionner une image"/>
 		<color_swatch label="Coul./Teinte" name="Color/Tint" tool_tip="Cliquez pour ouvrir le sélecteur de couleurs" width="80"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
index e4c35d60fe400d7a5ac6ae1979f2a7b12a97c08d..db7d254b7ace284232642702f7da94e1899e4ec8 100644
--- a/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
+++ b/indra/newview/skins/default/xui/fr/panel_main_inventory.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Choses" name="main inventory panel">
 	<panel.string name="ItemcountFetching">
-		Récupération de [ITEM_COUNT] articles... [FILTER]
+		[ITEM_COUNT] articles récupérés... [FILTER]
 	</panel.string>
 	<panel.string name="ItemcountCompleted">
 		[ITEM_COUNT] articles [FILTER]
diff --git a/indra/newview/skins/default/xui/fr/panel_notify_textbox.xml b/indra/newview/skins/default/xui/fr/panel_notify_textbox.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a37770e184e4977da4d3da24c428b689b8554dcb
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_notify_textbox.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="instant_message" name="panel_notify_textbox">
+	<string name="message_max_lines_count" value="7"/>
+	<panel label="info_panel" name="info_panel">
+		<text_editor name="message" value="message"/>
+		parse_urls=&quot;false&quot;
+		<button label="Soumettre" name="btn_submit"/>
+	</panel>
+	<panel label="control_panel" name="control_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_people.xml b/indra/newview/skins/default/xui/fr/panel_people.xml
index 0ca4208282440d3a75df909b77d58e6c4c17ecb7..eecbabae2b3071eb3ca32cc230bc72ee9d57a63b 100644
--- a/indra/newview/skins/default/xui/fr/panel_people.xml
+++ b/indra/newview/skins/default/xui/fr/panel_people.xml
@@ -2,9 +2,9 @@
 <!-- Side tray panel -->
 <panel label="Résidents" name="people_panel">
 	<string name="no_recent_people" value="Personne de récent. Pour rechercher des résidents avec qui passer du temps, voir [secondlife:///app/search/people Rechercher] ou [secondlife:///app/worldmap Carte du monde]."/>
-	<string name="no_filtered_recent_people" value="Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/people/Rechercher [SEARCH_TERM]]."/>
+	<string name="no_filtered_recent_people" value="Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/people/[SEARCH_TERM] Rechercher]."/>
 	<string name="no_one_near" value="Personne près de vous. Pour rechercher des résidents avec qui passer du temps, voir [secondlife:///app/search/people Rechercher] ou [secondlife:///app/worldmap Carte du monde]."/>
-	<string name="no_one_filtered_near" value="Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/people/Rechercher [SEARCH_TERM]]."/>
+	<string name="no_one_filtered_near" value="Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/people/[SEARCH_TERM] Rechercher]."/>
 	<string name="no_friends_online" value="Pas d&apos;amis connectés"/>
 	<string name="no_friends" value="Pas d&apos;amis"/>
 	<string name="no_friends_msg">
@@ -12,17 +12,17 @@
 Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife:///app/worldmap Carte du monde].
 	</string>
 	<string name="no_filtered_friends_msg">
-		Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/people/Rechercher [SEARCH_TERM]].
+		Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/people/[SEARCH_TERM] Rechercher].
 	</string>
 	<string name="people_filter_label" value="Filtrer les personnes"/>
 	<string name="groups_filter_label" value="Filtrer les groupes"/>
-	<string name="no_filtered_groups_msg" value="Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/groups/Rechercher [SEARCH_TERM]]."/>
+	<string name="no_filtered_groups_msg" value="Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/groups/[SEARCH_TERM] Rechercher]."/>
 	<string name="no_groups_msg" value="Vous souhaitez trouver des groupes à rejoindre ? Utilisez [secondlife:///app/search/groups Rechercher]."/>
 	<filter_editor label="Filtre" name="filter_input"/>
 	<tab_container name="tabs">
 		<panel label="PRÈS DE VOUS" name="nearby_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="nearby_view_sort_btn" tool_tip="Options"/>
+				<menu_button name="nearby_view_sort_btn" tool_tip="Options"/>
 				<button name="add_friend_btn" tool_tip="Ajouter le résident sélectionné à votre liste d&apos;amis"/>
 			</panel>
 		</panel>
@@ -34,27 +34,27 @@ Pour rechercher des résidents avec qui passer du temps, utilisez [secondlife://
 			<panel label="bottom_panel" name="bottom_panel">
 				<layout_stack name="bottom_panel">
 					<layout_panel name="options_gear_btn_panel">
-						<button name="friends_viewsort_btn" tool_tip="Afficher d&apos;autres options"/>
+						<menu_button name="friends_viewsort_btn" tool_tip="Afficher d&apos;autres options"/>
 					</layout_panel>
 					<layout_panel name="add_btn_panel">
 						<button name="add_btn" tool_tip="Proposer à un résident de devenir votre ami"/>
 					</layout_panel>
 					<layout_panel name="trash_btn_panel">
-						<dnd_button name="trash_btn" tool_tip="Supprimer le résident sélectionné de votre liste d&apos;amis"/>
+						<dnd_button name="del_btn" tool_tip="Supprimer le résident sélectionné de votre liste d&apos;amis."/>
 					</layout_panel>
 				</layout_stack>
 			</panel>
 		</panel>
 		<panel label="MES GROUPES" name="groups_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="groups_viewsort_btn" tool_tip="Options"/>
+				<menu_button name="groups_viewsort_btn" tool_tip="Options"/>
 				<button name="plus_btn" tool_tip="Rejoindre/créer un nouveau groupe"/>
 				<button name="activate_btn" tool_tip="Activer le groupe sélectionné"/>
 			</panel>
 		</panel>
 		<panel label="RÉCENT" name="recent_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="recent_viewsort_btn" tool_tip="Options"/>
+				<menu_button name="recent_viewsort_btn" tool_tip="Options"/>
 				<button name="add_friend_btn" tool_tip="Ajouter le résident sélectionné à votre liste d&apos;amis"/>
 			</panel>
 		</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_places.xml b/indra/newview/skins/default/xui/fr/panel_places.xml
index 7f3601b90dbb7d905ea3bd6664eb48cac441c3c9..e252c224f83a1308ddc85d9419a13be8d5b4fce6 100644
--- a/indra/newview/skins/default/xui/fr/panel_places.xml
+++ b/indra/newview/skins/default/xui/fr/panel_places.xml
@@ -21,7 +21,7 @@
 						<button label="Modifier" name="edit_btn" tool_tip="Modifier les informations du repère"/>
 					</layout_panel>
 					<layout_panel name="overflow_btn_lp">
-						<button label="â–¼" name="overflow_btn" tool_tip="Afficher d&apos;autres options"/>
+						<menu_button label="â–¼" name="overflow_btn" tool_tip="Afficher d&apos;autres options"/>
 					</layout_panel>
 				</layout_stack>
 				<layout_stack name="bottom_bar_ls3">
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml
index 9af3a8a5d80f032679b2c737e0e4be60ece3e6c5..3468afbafe1a6bab46bbd8a3279e3441178b1c97 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_advanced.xml
@@ -3,35 +3,16 @@
 	<panel.string name="aspect_ratio_text">
 		[NUM]:[DEN]
 	</panel.string>
-	<panel.string name="middle_mouse">
-		Bouton central de la souris
-	</panel.string>
-	<slider label="Angle de vue" name="camera_fov"/>
-	<slider label="Distance" name="camera_offset_scale"/>
-	<text name="heading2">
-		Positionnement automatique pour :
-	</text>
-	<check_box label="Construire/Modifier" name="edit_camera_movement" tool_tip="Utilisez le positionnement automatique de la caméra quand vous accédez au mode de modification et quand vous le quittez"/>
-	<check_box label="Apparence" name="appearance_camera_movement" tool_tip="Utiliser le positionnement automatique de la caméra quand je suis en mode Édition"/>
-	<check_box initial_value="true" label="Panneau latéral" name="appearance_sidebar_positioning" tool_tip="Positionnement auto de la caméra pour le panneau latéral"/>
-	<check_box label="Afficher en vue subjective" name="first_person_avatar_visible"/>
-	<check_box label="Les touches de direction me font toujours me déplacer" name="arrow_keys_move_avatar_check"/>
-	<check_box label="Appuyer deux fois et maintenir enfoncé pour courir" name="tap_tap_hold_to_run"/>
-	<check_box label="Faire bouger les lèvres de l&apos;avatar quand il parle" name="enable_lip_sync"/>
-	<check_box label="Bulles de chat" name="bubble_text_chat"/>
-	<slider label="Opacité" name="bubble_chat_opacity"/>
-	<color_swatch name="background" tool_tip="Choisir la couleur des bulles de chat"/>
 	<text name="UI Size:">
-		Taille de l&apos;interface
+		Taille d&apos;interface :
 	</text>
 	<check_box label="Afficher les erreurs de script dans :" name="show_script_errors"/>
 	<radio_group name="show_location">
 		<radio_item label="Chat près de moi" name="0"/>
 		<radio_item label="Autre fenêtre" name="1"/>
 	</radio_group>
-	<check_box label="Activer/désactiver la fonction Parler quand j&apos;appuie sur :" name="push_to_talk_toggle_check" tool_tip="En mode bascule, appuyez une fois sur la touche de contrôle de la fonction, puis relâchez-la pour activer/désactiver votre micro. Si vous n&apos;êtes pas en mode bascule, le micro ne diffuse votre voix que quand vous maintenez la touche de contrôle de la fonction enfoncée."/>
-	<line_editor label="Touche de contrôle de la fonction Appuyer pour parler" name="modifier_combo"/>
-	<button label="Définir la touche" name="set_voice_hotkey_button"/>
-	<button label="Bouton central de la souris" name="set_voice_middlemouse_button" tool_tip="Réinitialiser sur le bouton central de la souris"/>
-	<button label="Autres accessoires" name="joystick_setup_button"/>
+	<check_box label="Clients multiples autorisés" name="allow_multiple_viewer_check"/>
+	<check_box label="Liste de sélection de grille affichée à la connexion" name="show_grid_selection_check"/>
+	<check_box label="Menu Avancé affiché" name="show_advanced_menu_check"/>
+	<check_box label="Menu Développeurs affiché" name="show_develop_menu_check"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
index a482fa99d033e19e4400b36e53c6f0b9389c2954..4b3fc35150ded5bfac72ee11f5798d5500f97040 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_chat.xml
@@ -8,44 +8,10 @@
 		<radio_item label="Moyenne" name="radio2" value="1"/>
 		<radio_item label="Grande" name="radio3" value="2"/>
 	</radio_group>
-	<text name="font_colors">
-		Couleurs de police :
-	</text>
-	<color_swatch label="Vous" name="user"/>
-	<text name="text_box1">
-		Moi
-	</text>
-	<color_swatch label="Avatars" name="agent"/>
-	<text name="text_box2">
-		Avatars
-	</text>
-	<color_swatch label="IM" name="im"/>
-	<text name="text_box3">
-		IM
-	</text>
-	<color_swatch label="Système" name="system"/>
-	<text name="text_box4">
-		Système
-	</text>
-	<color_swatch label="Erreurs de script" name="script_error"/>
-	<text name="text_box5">
-		Erreurs de script
-	</text>
-	<color_swatch label="Objets" name="objects"/>
-	<text name="text_box6">
-		Objets
-	</text>
-	<color_swatch label="Propriétaire" name="owner"/>
-	<text name="text_box7">
-		Propriétaire
-	</text>
-	<color_swatch label="URL" name="links"/>
-	<text name="text_box9">
-		URL
-	</text>
 	<check_box initial_value="true" label="Jouer l&apos;animation clavier quand vous écrivez" name="play_typing_animation"/>
 	<check_box label="M&apos;envoyer les IM par e-mail une fois déconnecté" name="send_im_to_email"/>
 	<check_box label="Activer l&apos;historique des chats et des IM en texte brut" name="plain_text_chat_history"/>
+	<check_box label="Bulles de chat" name="bubble_text_chat"/>
 	<text name="show_ims_in_label">
 		Afficher les IM dans :
 	</text>
@@ -56,6 +22,13 @@
 		<radio_item label="Plusieurs fenêtres" name="radio" value="0"/>
 		<radio_item label="Onglets" name="radio2" value="1"/>
 	</radio_group>
+	<text name="disable_toast_label">
+		Activer les popups de chat entrant :
+	</text>
+	<check_box label="Chats de groupe" name="EnableGroupChatPopups" tool_tip="Cocher cette case pour qu&apos;un popup s&apos;affiche à réception d&apos;un message de chat de groupe."/>
+	<check_box label="Chats IM" name="EnableIMChatPopups" tool_tip="Cocher cette case pour qu&apos;un popup s&apos;affiche à réception d&apos;un message instantané."/>
+	<spinner label="Durée de vie du popup Chat près de moi :" name="nearby_toasts_lifetime"/>
+	<spinner label="Disparition progressive du popup Chat près de moi :" name="nearby_toasts_fadingtime"/>
 	<check_box label="Utiliser la traduction automatique lors des chats (fournie par Google)" name="translate_chat_checkbox"/>
 	<text name="translate_language_text">
 		Traduire le chat en :
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_colors.xml b/indra/newview/skins/default/xui/fr/panel_preferences_colors.xml
new file mode 100644
index 0000000000000000000000000000000000000000..e94bb08c9c9ed3009a5994c7fcf73cfffdad5623
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_colors.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Couleurs" name="colors_panel">
+	<text name="effects_color_textbox">
+		Mes effets (faisceau de sélection lumineux) :
+	</text>
+	<color_swatch name="effect_color_swatch" tool_tip="Cliquer pour ouvrir le sélecteur de couleurs."/>
+	<text name="font_colors">
+		Couleurs de la police du chat :
+	</text>
+	<text name="text_box1">
+		Moi
+	</text>
+	<text name="text_box2">
+		Autres résidents
+	</text>
+	<text name="text_box3">
+		Objets
+	</text>
+	<text name="text_box4">
+		Système
+	</text>
+	<text name="text_box5">
+		Erreurs
+	</text>
+	<text name="text_box7">
+		Propriétaire
+	</text>
+	<text name="text_box9">
+		URL
+	</text>
+	<text name="bubble_chat">
+		Arrière-plan des bulles de chat :
+	</text>
+	<color_swatch name="background" tool_tip="Choisir la couleur des bulles de chat."/>
+	<slider label="Opacité :" name="bubble_chat_opacity"/>
+	<text name="floater_opacity">
+		Opacité des fenêtres flottantes :
+	</text>
+	<slider label="Actives :" name="active"/>
+	<slider label="Inactives :" name="inactive"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
index 30389a0ef95fc69184bccec74cffbf3f55d7f87b..2786798173134cb29bc14f785b047de8108624e3 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_general.xml
@@ -48,13 +48,18 @@
 	<check_box label="Noms d&apos;utilisateur" name="show_slids" tool_tip="Afficher le nom d&apos;utilisateur, comme bobsmith123."/>
 	<check_box label="Titres de groupe" name="show_all_title_checkbox1" tool_tip="Afficher les titres de groupe, comme Officier ou Membre."/>
 	<check_box label="Mettre mes amis en surbrillance" name="show_friends" tool_tip="Mettre en surbrillance l&apos;affichage des noms de vos amis."/>
-	<text name="effects_color_textbox">
-		Mes effets :
+	<check_box label="Voir les noms d&apos;affichage" name="display_names_check" tool_tip="Cocher pour utiliser les noms d&apos;affichage dans les chats, les IM, l&apos;affichage des noms, etc."/>
+	<check_box label="Activer les astuces de l&apos;interface" name="viewer_hints_check"/>
+	<text name="inworld_typing_rg_label">
+		Appuyer sur les touches lettre :
 	</text>
+	<radio_group name="inworld_typing_preference">
+		<radio_item label="Lance le chat local" name="radio_start_chat" value="1"/>
+		<radio_item label="Affecte le déplacement (ZQSD/WASD)" name="radio_move" value="0"/>
+	</radio_group>
 	<text name="title_afk_text">
 		Me montrer absent après :
 	</text>
-	<color_swatch label="" name="effect_color_swatch" tool_tip="Cliquer pour ouvrir le sélecteur de couleurs"/>
 	<combo_box label="Me montrer absent après :" name="afk">
 		<combo_box.item label="2 minutes" name="item0"/>
 		<combo_box.item label="5 minutes" name="item1"/>
@@ -62,7 +67,6 @@
 		<combo_box.item label="30 minutes" name="item3"/>
 		<combo_box.item label="Jamais" name="item4"/>
 	</combo_box>
-	<check_box label="Voir les noms d&apos;affichage" name="display_names_check" tool_tip="Cocher pour utiliser les noms d&apos;affichage dans les chats, les IM, l&apos;affichage des noms, etc."/>
 	<text name="text_box3">
 		Réponse si occupé(e) :
 	</text>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
index 0c8d957f5b49d2365b5a87045ad92c505e89ac4e..c90edd443e6def6f434ac83c6c433bc27e734c3f 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_graphics1.xml
@@ -25,6 +25,7 @@
 		<text name="ShadersText">
 			Effets :
 		</text>
+		<check_box initial_value="true" label="Eau transparente" name="TransparentWater"/>
 		<check_box initial_value="true" label="Placage de relief et brillance" name="BumpShiny"/>
 		<check_box initial_value="true" label="Effets de base" name="BasicShaders" tool_tip="La désactivation de cette option peut éviter le plantage de certains pilotes de cartes graphiques"/>
 		<check_box initial_value="true" label="Effets atmosphériques" name="WindLightUseAtmosShaders"/>
@@ -42,8 +43,8 @@
 		<text name="DrawDistanceMeterText2">
 			m
 		</text>
-		<slider label="Nombre de particules max. :" label_width="147" name="MaxParticleCount"/>
-		<slider label="Nb max d&apos;avatars non éloignés en 2D :" name="MaxNumberAvatarDrawn"/>
+		<slider label="Nb max. de particules :" label_width="147" name="MaxParticleCount"/>
+		<slider label="Avatars max. non éloignés en 2D :" name="MaxNumberAvatarDrawn"/>
 		<slider label="Qualité post-traitement :" name="RenderPostProcess"/>
 		<text name="MeshDetailText">
 			Détails des rendus :
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_move.xml b/indra/newview/skins/default/xui/fr/panel_preferences_move.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5f1b206a39719f47b5d65712f69eb6f0f59097c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_move.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Déplacement" name="move_panel">
+	<slider label="Angle de vue" name="camera_fov"/>
+	<slider label="Distance" name="camera_offset_scale"/>
+	<text name="heading2">
+		Positionnement automatique pour :
+	</text>
+	<check_box label="Construire/Modifier" name="edit_camera_movement" tool_tip="Utiliser le positionnement automatique de la caméra lorsque vous entrez en mode de modification et le quittez."/>
+	<check_box label="Apparence" name="appearance_camera_movement" tool_tip="Utiliser le positionnement automatique de la caméra en mode de modification."/>
+	<check_box initial_value="true" label="Panneau latéral" name="appearance_sidebar_positioning" tool_tip="Utiliser le positionnement automatique de la caméra pour le panneau latéral."/>
+	<check_box label="Afficher en vue subjective" name="first_person_avatar_visible"/>
+	<text name=" Mouse Sensitivity">
+		Sensibilité de la souris en vue subjective :
+	</text>
+	<check_box label="Inverser" name="invert_mouse"/>
+	<check_box label="Les touches de direction me font toujours me déplacer" name="arrow_keys_move_avatar_check"/>
+	<check_box label="Appuyer deux fois et maintenir enfoncé pour courir" name="tap_tap_hold_to_run"/>
+	<check_box label="Double-cliquer pour :" name="double_click_chkbox"/>
+	<radio_group name="double_click_action">
+		<radio_item label="Téléportation" name="radio_teleport"/>
+		<radio_item label="Pilotage auto" name="radio_autopilot"/>
+	</radio_group>
+	<button label="Autres accessoires" name="joystick_setup_button"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
index f14ccc3a8e88de4f8f88a321f92df0732fd0094b..6a4c77a10e6c21bd8fdae1182ce381d4293f377d 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_privacy.xml
@@ -10,17 +10,20 @@
 	<check_box label="Seuls mes amis et groupes voient quand je suis en ligne" name="online_visibility"/>
 	<check_box label="Seuls mes amis et groupes peuvent m&apos;appeler ou m&apos;envoyer un IM" name="voice_call_friends_only_check"/>
 	<check_box label="Fermer le micro à la fin d&apos;un appel" name="auto_disengage_mic_check"/>
-	<check_box label="Accepter les cookies" name="cookies_enabled"/>
 	<text name="Logs:">
-		Journaux :
+		Journaux de chat :
 	</text>
 	<check_box label="Sauvegarder les chats près de moi sur mon ordinateur" name="log_nearby_chat"/>
 	<check_box label="Sauvegarder les IM sur mon ordinateur" name="log_instant_messages"/>
-	<check_box label="Inclure les dates et heures" name="show_timestamps_check_im"/>
+	<check_box label="Inclure la date et l&apos;heure pour chaque ligne du journal de chat" name="show_timestamps_check_im"/>
+	<check_box label="Inclure la date dans le nom du fichier journal" name="logfile_name_datestamp"/>
 	<text name="log_path_desc">
 		Emplacement :
 	</text>
 	<line_editor left="308" name="log_path_string" right="-20"/>
 	<button label="Parcourir" label_selected="Parcourir" name="log_path_button" width="150"/>
 	<button label="Liste des ignorés" name="block_list"/>
+	<text name="block_list_label">
+		(personnes et/ou objets que vous avez ignorés)
+	</text>
 </panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml b/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml
index c1cec7537eabb05778c1f59f9abde0df552404d8..8fa499d14aab04315a9f6fb9e1c1294a03af8e5a 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_setup.xml
@@ -1,12 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Configuration" name="Input panel">
-	<text name="Mouselook:">
-		Vue subjective :
-	</text>
-	<text name=" Mouse Sensitivity">
-		Sensibilité de la souris
-	</text>
-	<check_box label="Inverser" name="invert_mouse"/>
 	<text name="Network:">
 		Réseau :
 	</text>
@@ -46,4 +39,5 @@
 	</text>
 	<line_editor name="web_proxy_editor" tool_tip="Le nom ou adresse IP du proxy que vous souhaitez utiliser"/>
 	<spinner label="Numéro de port :" label_width="95" name="web_proxy_port" width="170"/>
+	<check_box initial_value="true" label="Télécharger et installer automatiquement les mises à jour [APP_NAME]" name="updater_service_active"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml b/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml
index b82d8bcd18b53127c9792491f2e771352c50d55e..654d40e2f950478fb5483b3aafae31ca51b55bf7 100644
--- a/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/fr/panel_preferences_sound.xml
@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Sons" name="Preference Media panel">
+	<panel.string name="middle_mouse">
+		Bouton central de la souris
+	</panel.string>
 	<slider label="Volume principal" name="System Volume"/>
 	<check_box initial_value="true" label="Couper quand minimisé" name="mute_when_minimized"/>
 	<slider label="Boutons" name="UI Volume"/>
@@ -23,6 +26,11 @@
 		<radio_item label="Position de la caméra" name="0"/>
 		<radio_item label="Position de l&apos;avatar" name="1"/>
 	</radio_group>
+	<check_box label="Faire bouger les lèvres de l&apos;avatar lorsqu&apos;il parle" name="enable_lip_sync"/>
+	<check_box label="Activer/désactiver la fonction Parler quand j&apos;appuie sur :" name="push_to_talk_toggle_check" tool_tip="En mode bascule, appuyez une fois sur la touche de contrôle de la fonction, puis relâchez-la pour activer/désactiver votre micro. Si vous n&apos;êtes pas en mode bascule, le micro ne diffuse votre voix que lorsque vous maintenez la touche de contrôle de la fonction enfoncée."/>
+	<line_editor label="Touche de contrôle de la fonction Appuyer pour parler" name="modifier_combo"/>
+	<button label="Définir la touche" name="set_voice_hotkey_button"/>
+	<button name="set_voice_middlemouse_button" tool_tip="Réinitialiser sur le bouton central de la souris"/>
 	<button label="Périphériques d&apos;entrée/de sortie" name="device_settings_btn"/>
 	<panel label="Paramètres du matériel" name="device_settings_panel">
 		<panel.string name="default_text">
diff --git a/indra/newview/skins/default/xui/fr/panel_profile.xml b/indra/newview/skins/default/xui/fr/panel_profile.xml
index 4606f5a0c60f3323bb7779b44c9608ad3357a561..6b611923af1f7d9f6d1aa81bd72a1689a422e054 100644
--- a/indra/newview/skins/default/xui/fr/panel_profile.xml
+++ b/indra/newview/skins/default/xui/fr/panel_profile.xml
@@ -57,7 +57,7 @@
 					<button label="Téléporter" name="teleport" tool_tip="Proposer une téléportation"/>
 				</layout_panel>
 				<layout_panel name="overflow_btn_lp">
-					<button label="▼" name="overflow_btn" tool_tip="Payer le résident ou partager l&apos;inventaire avec lui"/>
+					<menu_button label="▼" name="overflow_btn" tool_tip="Payer le résident ou partager l&apos;inventaire avec lui"/>
 				</layout_panel>
 			</layout_stack>
 		</layout_panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_script_ed.xml b/indra/newview/skins/default/xui/fr/panel_script_ed.xml
index 3b3b676aa15ac7e5cff98c3f8220413105c2b5db..2c86dd72b65cc049f79df8950f7685fd471c0df3 100644
--- a/indra/newview/skins/default/xui/fr/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/fr/panel_script_ed.xml
@@ -15,11 +15,6 @@
 	<panel.string name="Title">
 		Script : [NAME]
 	</panel.string>
-	<text_editor name="Script Editor">
-		Chargement...
-	</text_editor>
-	<button label="Enregistrer" label_selected="Enregistrer" name="Save_btn"/>
-	<combo_box label="Insérer..." name="Insert..."/>
 	<menu_bar name="script_menu">
 		<menu label="Fichier" name="File">
 			<menu_item_call label="Enregistrer" name="Save"/>
@@ -40,4 +35,10 @@
 			<menu_item_call label="Aide par mots-clés..." name="Keyword Help..."/>
 		</menu>
 	</menu_bar>
+	<text_editor name="Script Editor">
+		Chargement...
+	</text_editor>
+	<combo_box label="Insérer..." name="Insert..."/>
+	<button label="Enregistrer" label_selected="Enregistrer" name="Save_btn"/>
+	<button label="Modifier..." name="Edit_btn"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/fr/panel_teleport_history.xml b/indra/newview/skins/default/xui/fr/panel_teleport_history.xml
index 1586c201dafb265925b89e49d2acea798a2750be..cf1266a4606976fe467db20be8b7d3812cc6278e 100644
--- a/indra/newview/skins/default/xui/fr/panel_teleport_history.xml
+++ b/indra/newview/skins/default/xui/fr/panel_teleport_history.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="Teleport History">
 	<accordion name="history_accordion">
-		<no_matched_tabs_text name="no_matched_teleports_msg" value="Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/places/Rechercher [SEARCH_TERM]]."/>
+		<no_matched_tabs_text name="no_matched_teleports_msg" value="Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/places/[SEARCH_TERM] Rechercher]."/>
 		<no_visible_tabs_text name="no_teleports_msg" value="L&apos;historique des téléportations est vide. Essayez [secondlife:///app/search/places/ Rechercher]."/>
 		<accordion_tab name="today" title="Aujourd&apos;hui"/>
 		<accordion_tab name="yesterday" title="Hier"/>
diff --git a/indra/newview/skins/default/xui/fr/strings.xml b/indra/newview/skins/default/xui/fr/strings.xml
index d6c701dc904a7c84f270387f976607f75fe62c8e..d75f6c731de2e853373bd742ba2cdf4f15f18993 100644
--- a/indra/newview/skins/default/xui/fr/strings.xml
+++ b/indra/newview/skins/default/xui/fr/strings.xml
@@ -1036,10 +1036,10 @@
 		Appuyez sur ESC pour quitter la vue subjective
 	</string>
 	<string name="InventoryNoMatchingItems">
-		Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/all/ Rechercher [SEARCH_TERM]].
+		Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/all/[SEARCH_TERM] Rechercher].
 	</string>
 	<string name="PlacesNoMatchingItems">
-		Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/places/ Rechercher [SEARCH_TERM]].
+		Vous n&apos;avez pas trouvé ce que vous cherchiez ? Essayez [secondlife:///app/search/places/[SEARCH_TERM] Rechercher].
 	</string>
 	<string name="FavoritesNoMatchingItems">
 		Faites glisser un repère ici pour l&apos;ajouter à vos Favoris.
@@ -1089,7 +1089,7 @@
 	<string name="Textures" value=" Textures,"/>
 	<string name="Snapshots" value=" Photos,"/>
 	<string name="No Filters" value="Non "/>
-	<string name="Since Logoff" value=" - Depuis la déconnexion"/>
+	<string name="Since Logoff" value="depuis la déconnexion"/>
 	<string name="InvFolder My Inventory">
 		Mon inventaire
 	</string>
@@ -1773,11 +1773,8 @@
 	<string name="InvOfferGaveYou">
 		vous a donné
 	</string>
-	<string name="InvOfferYouDecline">
-		Vous avez refusé
-	</string>
-	<string name="InvOfferFrom">
-		de la part de
+	<string name="InvOfferDecline">
+		Vous refusez l&apos;offre [DESC] de &lt;nolink&gt;[NAME]&lt;/nolink&gt;.
 	</string>
 	<string name="GroupMoneyTotal">
 		Total
diff --git a/indra/newview/skins/default/xui/it/floater_bumps.xml b/indra/newview/skins/default/xui/it/floater_bumps.xml
index d9dd3f26d722946375722b46e575614661b5e100..6de2fea67f98947063350c48867a4485b6f95899 100644
--- a/indra/newview/skins/default/xui/it/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/it/floater_bumps.xml
@@ -4,19 +4,19 @@
 		Nessuno rilevato
 	</floater.string>
 	<floater.string name="bump">
-		[TIME]  [FIRST] [LAST] ti ha urtato
+		[TIME]  [NAME] ti ha urtato
 	</floater.string>
 	<floater.string name="llpushobject">
-		[TIME]  [FIRST] [LAST] ti ha spinto per mezzo di uno script
+		[TIME]  [NAME] ti ha spinto per mezzo di uno script
 	</floater.string>
 	<floater.string name="selected_object_collide">
-		[TIME]  [FIRST] [LAST] ti ha colpito con un oggetto
+		[TIME]  [NAME] ti ha colpito con un oggetto
 	</floater.string>
 	<floater.string name="scripted_object_collide">
-		[TIME]  [FIRST] [LAST] ti ha colpito con un oggetto scriptato
+		[TIME]  [NAME] ti ha colpito con un oggetto scriptato
 	</floater.string>
 	<floater.string name="physical_object_collide">
-		[TIME]  [FIRST] [LAST] ti ha colpito con un oggetto fisico
+		[TIME]  [NAME] ti ha colpito con un oggetto fisico
 	</floater.string>
 	<floater.string name="timeStr">
 		[[hour,datetime,slt]:[min,datetime,slt]]
diff --git a/indra/newview/skins/default/xui/it/floater_pay.xml b/indra/newview/skins/default/xui/it/floater_pay.xml
index c1ea8ec9c8e243e7cdef68b2b7d98eaf2a843d04..6389cbfbf7bc9ffd4e12b82ee8e8104cb74fb68f 100644
--- a/indra/newview/skins/default/xui/it/floater_pay.xml
+++ b/indra/newview/skins/default/xui/it/floater_pay.xml
@@ -11,7 +11,7 @@
 	</text>
 	<icon name="icon_person" tool_tip="Persona"/>
 	<text left="115" name="payee_name">
-		[FIRST] [LAST]
+		Test Name That Is Extremely Long To Check Clipping
 	</text>
 	<button label="1 L$" label_selected="1 L$" left="118" name="fastpay 1" width="80"/>
 	<button label="5 L$" label_selected="5 L$" left="210" name="fastpay 5"/>
diff --git a/indra/newview/skins/default/xui/it/floater_pay_object.xml b/indra/newview/skins/default/xui/it/floater_pay_object.xml
index 37f549b5da077bafd80205a9fe27d2993bd490a6..8805f3208e726c88dbae5c5867e6738a9e4a350d 100644
--- a/indra/newview/skins/default/xui/it/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/it/floater_pay_object.xml
@@ -8,7 +8,7 @@
 	</string>
 	<icon name="icon_person" tool_tip="Persona"/>
 	<text left="120" name="payee_name">
-		[FIRST] [LAST]
+		Ericacita Moostopolison
 	</text>
 	<text halign="left" left="5" name="object_name_label" width="110">
 		Mediante l&apos;oggetto:
diff --git a/indra/newview/skins/default/xui/it/floater_tools.xml b/indra/newview/skins/default/xui/it/floater_tools.xml
index fbe611407eecd23200f3d66e898e056e8a6fe010..a8c985cb124fa412d9341b5cfb82ce3a80e2efa5 100644
--- a/indra/newview/skins/default/xui/it/floater_tools.xml
+++ b/indra/newview/skins/default/xui/it/floater_tools.xml
@@ -283,7 +283,7 @@
 				<combo_box.item label="Plastica" name="Plastic"/>
 				<combo_box.item label="Gomma" name="Rubber"/>
 			</combo_box>
-			<text name="text cut">
+			<text name="text cut" left_delta="-10" width="170">
 				Riduci una sezione (inizio/fine)
 			</text>
 			<spinner label="I" name="cut begin"/>
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index ffd27d55e8895c5d68013bf37088d93f88ebf5a5..32483881b2b6d07aa2a5f62210bf4ab6df776145 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -2035,10 +2035,10 @@ Inseriscilo in una pagina web per dare ad altri un accesso facile a questa ubica
 		Oggetto: [SUBJECT], Messaggio: [MESSAGE]
 	</notification>
 	<notification name="FriendOnline">
-		[FIRST] [LAST] è Online
+		[NAME] è Online
 	</notification>
 	<notification name="FriendOffline">
-		[FIRST] [LAST] è Offline
+		[NAME] è Offline
 	</notification>
 	<notification name="AddSelfFriend">
 		Anche se sei molto simpatico, non puoi aggiungere te stesso all&apos;elenco degli amici.
@@ -2105,9 +2105,6 @@ Questo potrebbe incidere sulla tua password.
 	<notification name="CannotRemoveProtectedCategories">
 		Non è possibile rimuovere le categorie protette.
 	</notification>
-	<notification name="OfferedCard">
-		Hai offerto un biglietto da visita a [FIRST] [LAST]
-	</notification>
 	<notification name="UnableToBuyWhileDownloading">
 		Impossibile acquistare l&apos;oggetto durante il download dei dati.
 Riprova.
@@ -2223,7 +2220,7 @@ Reinstalla il plugin o contatta il venditore se continui ad avere questi problem
 		Gli oggetti che possiedi sul terreno selezionato ti sono stati restituiti nell&apos;inventario.
 	</notification>
 	<notification name="OtherObjectsReturned">
-		Gli oggetti selezionati sul terreno che è di proprietà di [FIRST] [LAST] sono stati restituiti nel suo inventario.
+		Gli oggetti selezionati sul terreno che è di proprietà di [NAME] sono stati restituiti nel suo inventario.
 	</notification>
 	<notification name="OtherObjectsReturned2">
 		Sono stati restituiti al proprietario gli oggetti selezionati sul lotto nella terra di proprietà del residente &apos;[NAME]&apos;.
@@ -2433,7 +2430,7 @@ Riprova tra qualche istante.
 		Offerta di amicizia rifiutata.
 	</notification>
 	<notification name="OfferCallingCard">
-		[FIRST] [LAST] ti offre il suo biglietto da visita.
+		[NAME] ti offre il suo biglietto da visita.
 Questo sarà aggiunto nel tuo inventario come segnalibro per consentirti di inviare rapidamente messaggi IM a questo residente.
 		<form name="form">
 			<button name="Accept" text="Accetta"/>
@@ -2493,7 +2490,7 @@ Concedi questa richiesta?
 		</form>
 	</notification>
 	<notification name="ScriptDialog">
-		[FIRST] [LAST] &apos;[TITLE]&apos;
+		[NAME] &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
 [MESSAGE]
 		<form name="form">
 			<button name="Ignore" text="Ignora"/>
@@ -2537,13 +2534,13 @@ Clicca su Accetta per unirti alla chiamata oppure su Declina to declinare l&apos
 		</form>
 	</notification>
 	<notification name="AutoUnmuteByIM">
-		[FIRST] [LAST] ha ricevuto un IM ed è stato automaticamente sbloccato.
+		[NAME] ha ricevuto un IM ed è stato automaticamente sbloccato.
 	</notification>
 	<notification name="AutoUnmuteByMoney">
-		[FIRST] [LAST] ha ricevuto del denaro e pertanto è stato automaticamente sbloccato.
+		[NAME] ha ricevuto del denaro e pertanto è stato automaticamente sbloccato.
 	</notification>
 	<notification name="AutoUnmuteByInventory">
-		A [FIRST] [LAST] è stato offerto un elemento dell&apos;Inventario e pertanto è stato automaticamente sbloccato.
+		A [NAME] è stato offerto un elemento dell&apos;Inventario e pertanto è stato automaticamente sbloccato.
 	</notification>
 	<notification name="VoiceInviteGroup">
 		[NAME] si è aggiunto alla chiamata in chat vocale con il gruppo [GROUP].
diff --git a/indra/newview/skins/default/xui/it/panel_places.xml b/indra/newview/skins/default/xui/it/panel_places.xml
index e33f8190eb01f61b08d94d79b1f7b3ba0a196e50..61830f186f0cd5ae01849984963e8c713c726cf3 100644
--- a/indra/newview/skins/default/xui/it/panel_places.xml
+++ b/indra/newview/skins/default/xui/it/panel_places.xml
@@ -21,7 +21,7 @@
 						<button label="Modifica" name="edit_btn" tool_tip="Modifica le informazioni del punto di riferimento"/>
 					</layout_panel>
 					<layout_panel name="overflow_btn_lp">
-						<button label="â–¼" name="overflow_btn" tool_tip="Mostra ulteriori opzioni"/>
+						<menu_button label="â–¼" name="overflow_btn" tool_tip="Mostra ulteriori opzioni"/>
 					</layout_panel>
 				</layout_stack>
 				<layout_stack name="bottom_bar_ls3">
diff --git a/indra/newview/skins/default/xui/it/panel_profile.xml b/indra/newview/skins/default/xui/it/panel_profile.xml
index 8a8d8f58461ce4faa92cf2cade297ee7ae29d672..c11adeda3db51693b252777ed6928af9bf5c7264 100644
--- a/indra/newview/skins/default/xui/it/panel_profile.xml
+++ b/indra/newview/skins/default/xui/it/panel_profile.xml
@@ -53,7 +53,7 @@
 					<button label="Teleport" name="teleport" tool_tip="Offri teleport"/>
 				</layout_panel>
 				<layout_panel name="overflow_btn_lp">
-					<button label="â–¼" name="overflow_btn" tool_tip="Paga del denaro o condividi qualcosa dall&apos;inventario con il residente"/>
+					<menu_button label="â–¼" name="overflow_btn" tool_tip="Paga del denaro o condividi qualcosa dall&apos;inventario con il residente"/>
 				</layout_panel>
 			</layout_stack>
 		</layout_panel>
diff --git a/indra/newview/skins/default/xui/it/strings.xml b/indra/newview/skins/default/xui/it/strings.xml
index 9dbfc2b79c9851acc3fe9d559ad8819c6a9d5744..dfe635182e60ccf3090e6ab955fc30000213e574 100644
--- a/indra/newview/skins/default/xui/it/strings.xml
+++ b/indra/newview/skins/default/xui/it/strings.xml
@@ -3478,7 +3478,7 @@ Se il messaggio persiste, contatta [SUPPORT_SITE].
 		Sei l&apos;unico utente di questa sessione.
 	</string>
 	<string name="offline_message">
-		[FIRST] [LAST] è offline.
+		[NAME] è offline.
 	</string>
 	<string name="invite_message">
 		Clicca il tasto [BUTTON NAME] per accettare/connetterti a questa voice chat.
diff --git a/indra/newview/skins/default/xui/ja/floater_bumps.xml b/indra/newview/skins/default/xui/ja/floater_bumps.xml
index 8a1e19b852928ca35ee1cde81f29fdef59dad3a4..c7e4dd348fb704665b65572f9b6fd530aa5eb459 100644
--- a/indra/newview/skins/default/xui/ja/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/ja/floater_bumps.xml
@@ -4,19 +4,19 @@
 		検出なし
 	</floater.string>
 	<floater.string name="bump">
-		[TIME]  [FIRST] [LAST]が、あなたにぶつかりました。
+		[TIME]  [NAME]が、あなたにぶつかりました。
 	</floater.string>
 	<floater.string name="llpushobject">
-		[TIME]  [FIRST] [LAST]が、スクリプトであなたをプッシュしました。
+		[TIME]  [NAME]が、スクリプトであなたをプッシュしました。
 	</floater.string>
 	<floater.string name="selected_object_collide">
-		[TIME]  [FIRST] [LAST]が、オブジェクトをあなたに当てました。
+		[TIME]  [NAME]が、オブジェクトをあなたに当てました。
 	</floater.string>
 	<floater.string name="scripted_object_collide">
-		[TIME]  [FIRST] [LAST]が、スクリプト・オブジェクトをあなたに当てました。
+		[TIME]  [NAME]が、スクリプト・オブジェクトをあなたに当てました。
 	</floater.string>
 	<floater.string name="physical_object_collide">
-		[TIME]  [FIRST] [LAST]が、物理オブジェクトをあなたに当てました。
+		[TIME]  [NAME]が、物理オブジェクトをあなたに当てました。
 	</floater.string>
 	<floater.string name="timeStr">
 		[[hour,datetime,slt]:[min,datetime,slt]]
diff --git a/indra/newview/skins/default/xui/ja/floater_pay.xml b/indra/newview/skins/default/xui/ja/floater_pay.xml
index 39bc37bc6c2e9beac84be7e3718750eecfb7dc4e..83a3c641f9a75b58c99c7f63dae0726b1d56f74a 100644
--- a/indra/newview/skins/default/xui/ja/floater_pay.xml
+++ b/indra/newview/skins/default/xui/ja/floater_pay.xml
@@ -11,7 +11,7 @@
 	</text>
 	<icon name="icon_person" tool_tip="住人"/>
 	<text name="payee_name">
-		[FIRST] [LAST]
+		Test Name That Is Extremely Long To Check Clipping
 	</text>
 	<button label="L$1" label_selected="L$1" name="fastpay 1"/>
 	<button label="L$5" label_selected="L$5" name="fastpay 5"/>
diff --git a/indra/newview/skins/default/xui/ja/floater_pay_object.xml b/indra/newview/skins/default/xui/ja/floater_pay_object.xml
index ffd57ab67b5f53a1abf38f5d0f0e169f7e1e2ff5..637ad496efab8d712e9a32e44caea39e3853dd5c 100644
--- a/indra/newview/skins/default/xui/ja/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/ja/floater_pay_object.xml
@@ -8,7 +8,7 @@
 	</string>
 	<icon name="icon_person" tool_tip="住人"/>
 	<text name="payee_name">
-		[FIRST] [LAST]
+		Ericacita Moostopolison
 	</text>
 	<text name="object_name_label">
 		オブジェクトを介して:
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index 93d664490203c28541d3447a1ded8d3d046d2ca8..c0af0e03ff2edfddb4ddeb85b97272b97703b3fe 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -2082,10 +2082,10 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
 		件名: [SUBJECT]、メッセージ: [MESSAGE]
 	</notification>
 	<notification name="FriendOnline">
-		[FIRST] [LAST] はオンラインです
+		[NAME] はオンラインです
 	</notification>
 	<notification name="FriendOffline">
-		[FIRST] [LAST] はオフラインです
+		[NAME] はオフラインです
 	</notification>
 	<notification name="AddSelfFriend">
 		残念ながら自分自身をフレンド登録することはできません。
@@ -2153,9 +2153,6 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
 	<notification name="CannotRemoveProtectedCategories">
 		保護されたカテゴリは削除できません。
 	</notification>
-	<notification name="OfferedCard">
-		[FIRST] [LAST] にコーリングカードを送りました。
-	</notification>
 	<notification name="UnableToBuyWhileDownloading">
 		オブジェクトデータのダウンロード中は購入できません。
 もう一度お試しください。
@@ -2273,7 +2270,7 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
 	</notification>
 	<notification name="OtherObjectsReturned">
 		選択した土地の区画上にあった
- [FIRST] [LAST]
+ [NAME]
  が所有するオブジェクトは、すべて所有者の「持ち物」に返却されました。
 	</notification>
 	<notification name="OtherObjectsReturned2">
@@ -2488,7 +2485,7 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
 		フレンドの登録依頼が拒否されました。
 	</notification>
 	<notification name="OfferCallingCard">
-		[FIRST] [LAST] がコーリングカードを渡そうとしています。
+		[NAME] がコーリングカードを渡そうとしています。
 あなたの「持ち物」にブックマークが追加され、この住人に素早く IM を送ることができます。
 		<form name="form">
 			<button name="Accept" text="受け入れる"/>
@@ -2548,7 +2545,7 @@ Web ページにリンクすると、他人がこの場所に簡単にアクセ
 		</form>
 	</notification>
 	<notification name="ScriptDialog">
-		[FIRST] [LAST] の「 [TITLE] 」
+		[NAME] の「 &lt;nolink&gt;[TITLE]&lt;/nolink&gt; 」
 [MESSAGE]
 		<form name="form">
 			<button name="Ignore" text="無視する"/>
@@ -2592,13 +2589,13 @@ M キーを押して変更します。
 		</form>
 	</notification>
 	<notification name="AutoUnmuteByIM">
-		[FIRST] [LAST] はインスタントメッセージを受け取り、自動的にブロックが解除されました。
+		[NAME] はインスタントメッセージを受け取り、自動的にブロックが解除されました。
 	</notification>
 	<notification name="AutoUnmuteByMoney">
-		[FIRST] [LAST] はお金を受け取り、自動的にブロックが解除されました。
+		[NAME] はお金を受け取り、自動的にブロックが解除されました。
 	</notification>
 	<notification name="AutoUnmuteByInventory">
-		[FIRST] [LAST] はアイテムを受け取り、自動的にブロックが解除されました。
+		[NAME] はアイテムを受け取り、自動的にブロックが解除されました。
 	</notification>
 	<notification name="VoiceInviteGroup">
 		[NAME] は [GROUP] のボイスチャットコールに参加しました。
diff --git a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml
index 2aba4edc0d6c9afae404350d5dd1585834ee288d..334cf54a4dd24f58e3c55b23c91df9782fc09e63 100644
--- a/indra/newview/skins/default/xui/ja/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/ja/panel_edit_profile.xml
@@ -46,7 +46,7 @@
 				<text name="my_account_link" value="[[URL] マイアカウントに移動]"/>
 				<text name="title_partner_text" value="マイパートナー:"/>
 				<panel name="partner_data_panel">
-					<name_box initial_value="(取得中)" name="partner_text" value="[FIRST] [LAST]"/>
+					<name_box initial_value="(取得中)" name="partner_text"/>
 				</panel>
 				<text name="partner_edit_link" value="[[URL] 編集]" width="100"/>
 			</panel>
diff --git a/indra/newview/skins/default/xui/ja/panel_places.xml b/indra/newview/skins/default/xui/ja/panel_places.xml
index 3e364c9b3a28696cfa171c0f1a85377653323000..e19b86e55231ed6e898b227af5d6fd7cd90e8176 100644
--- a/indra/newview/skins/default/xui/ja/panel_places.xml
+++ b/indra/newview/skins/default/xui/ja/panel_places.xml
@@ -21,7 +21,7 @@
 						<button label="編集" name="edit_btn" tool_tip="ランドマークの情報を編集します"/>
 					</layout_panel>
 					<layout_panel name="overflow_btn_lp">
-						<button label="▼" name="overflow_btn" tool_tip="オプションを表示します"/>
+						<menu_button label="▼" name="overflow_btn" tool_tip="オプションを表示します"/>
 					</layout_panel>
 				</layout_stack>
 				<layout_stack name="bottom_bar_ls3">
diff --git a/indra/newview/skins/default/xui/ja/panel_profile.xml b/indra/newview/skins/default/xui/ja/panel_profile.xml
index 860020c87c25b5428b6e8f9222fc5784507b3f2c..c2ffd74ec04a1b8d7ce1f7a719564f084a658cfb 100644
--- a/indra/newview/skins/default/xui/ja/panel_profile.xml
+++ b/indra/newview/skins/default/xui/ja/panel_profile.xml
@@ -57,7 +57,7 @@
 					<button label="テレポート" name="teleport" tool_tip="テレポートを送ります"/>
 				</layout_panel>
 				<layout_panel name="overflow_btn_lp">
-					<button label="▼" name="overflow_btn" tool_tip="住人にお金を渡すか持ち物を共有します"/>
+					<menu_button label="▼" name="overflow_btn" tool_tip="住人にお金を渡すか持ち物を共有します"/>
 				</layout_panel>
 			</layout_stack>
 		</layout_panel>
diff --git a/indra/newview/skins/default/xui/ja/strings.xml b/indra/newview/skins/default/xui/ja/strings.xml
index 92bbedaee52e06dea5bbe63088ba4cf8c2cb54ee..187f21257a33755e89a8f57faae26f910ea36dc8 100644
--- a/indra/newview/skins/default/xui/ja/strings.xml
+++ b/indra/newview/skins/default/xui/ja/strings.xml
@@ -3574,7 +3574,7 @@ www.secondlife.com から最新バージョンをダウンロードしてくだ
 		このセッションにいるユーザーはあなただけです。
 	</string>
 	<string name="offline_message">
-		[FIRST] [LAST] はオフラインです。
+		[NAME] はオフラインです。
 	</string>
 	<string name="invite_message">
 		このボイスチャットに応答・接続する場合は、[BUTTON NAME] をクリックしてください。
diff --git a/indra/newview/skins/default/xui/nl/floater_bumps.xml b/indra/newview/skins/default/xui/nl/floater_bumps.xml
index df9a99d62ef8bfb81cbdb4bdfc50622e3713529b..516b59658d9d421dae23a6c55262c98999558382 100644
--- a/indra/newview/skins/default/xui/nl/floater_bumps.xml
+++ b/indra/newview/skins/default/xui/nl/floater_bumps.xml
@@ -4,18 +4,18 @@
 		Geen gedetecteerd
 	</string>
 	<string name="bump">
-		[TIME]  [FIRST] [LAST] botste tegen u aan
+		[TIME]  [NAME] botste tegen u aan
 	</string>
 	<string name="llpushobject">
-		[TIME]  [FIRST] [LAST] duwde u met een script
+		[TIME]  [NAME] duwde u met een script
 	</string>
 	<string name="selected_object_collide">
-		[TIME]  [FIRST] [LAST] raakte u met een object
+		[TIME]  [NAME] raakte u met een object
 	</string>
 	<string name="scripted_object_collide">
-		[TIME]  [FIRST] [LAST] raakte u met een gescript object
+		[TIME]  [NAME] raakte u met een gescript object
 	</string>
 	<string name="physical_object_collide">
-		[TIME]  [FIRST] [LAST] raakte u met een fysiek object
+		[TIME]  [NAME] raakte u met een fysiek object
 	</string>
 </floater>
diff --git a/indra/newview/skins/default/xui/nl/floater_pay.xml b/indra/newview/skins/default/xui/nl/floater_pay.xml
index 4018ebdc93b0f977083a569260f446ff33c4099e..f2b34d78d727e15fadfad7c7e8be6c6578c93799 100644
--- a/indra/newview/skins/default/xui/nl/floater_pay.xml
+++ b/indra/newview/skins/default/xui/nl/floater_pay.xml
@@ -10,7 +10,7 @@
 		Betaal inwoner:
 	</text>
 	<text name="payee_name" left="110">
-		[FIRST] [LAST]
+		Test Name That Is Extremely Long To Check Clipping
 	</text>
 	<text name="fastpay text">
 		Snel betalen:
diff --git a/indra/newview/skins/default/xui/nl/floater_pay_object.xml b/indra/newview/skins/default/xui/nl/floater_pay_object.xml
index d3826648f23a37acc8d3219f9345aa200340740b..11fa6d4a44d6c90e4ecff95a7092e6a37d875461 100644
--- a/indra/newview/skins/default/xui/nl/floater_pay_object.xml
+++ b/indra/newview/skins/default/xui/nl/floater_pay_object.xml
@@ -7,7 +7,7 @@
 		Betaal inwoner:
 	</text>
 	<text name="payee_name" left="100" width="200">
-		[FIRST] [LAST]
+		Ericacita Moostopolison
 	</text>
 	<text name="object_name_label" left="5" width="90" halign="left">
 		Via object:
diff --git a/indra/newview/skins/default/xui/nl/floater_tools.xml b/indra/newview/skins/default/xui/nl/floater_tools.xml
index d49ffc2f51225369b1385b6bd5c40ccaa7b3c81a..4ffe675831579ddd98bfd2299914a398b9cc6b4d 100644
--- a/indra/newview/skins/default/xui/nl/floater_tools.xml
+++ b/indra/newview/skins/default/xui/nl/floater_tools.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="toolbox floater" title="" short_title="BOUWEN" height="587">
+<floater name="toolbox floater" title="" short_title="BOUWEN" height="592">
 	<button label="" label_selected="" name="button focus" tool_tip="Focus"/>
 	<button label="" label_selected="" name="button move" tool_tip="Verplaats"/>
 	<button label="" label_selected="" name="button edit" tool_tip="Bewerk"/>
@@ -81,13 +81,13 @@
 	<text name="Strength:">
 		Sterkte
 	</text>
-	<text name="obj_count" top_pad="15">
+	<text name="obj_count" top_pad="20">
 		Geselecteerde objecten: [COUNT]
 	</text>
 	<text name="prim_count">
 		primitieven: [COUNT]
 	</text>
-	<tab_container name="Object Info Tabs" tab_max_width="62" tab_min_width="30" top="180">
+	<tab_container name="Object Info Tabs" tab_max_width="62" tab_min_width="30" top="185">
 		<panel label="Algemeen" name="General">
 			<text name="Name:">
 				Naam:
@@ -115,19 +115,19 @@
 			<text name="Group Name Proxy">
 				De Lindens
 			</text>
-			<button label="Instellen..." label_selected="Instellen..." name="button set group" left_pad="13"/>
+			<button label="Instellen..." label_selected="Instellen..." name="button set group"/>
 			<text name="Permissions:">
 				Permissies:
 			</text>
 
-			<check_box label="Deel met groep" name="checkbox share with group" tool_tip="Alle leden van de ingestelde groep toestaan om te delen en uw permissies voor dit object te gebruiken. U moet &apos;Overdragen&apos; om rolbeperkingen in te schakelen." left="100"/>
+			<check_box label="Deel met groep" name="checkbox share with group" tool_tip="Alle leden van de ingestelde groep toestaan om te delen en uw permissies voor dit object te gebruiken. U moet &apos;Overdragen&apos; om rolbeperkingen in te schakelen."/>
 			<string name="text deed continued">
 				Overdragen...
 			</string>
 			<string name="text deed">
 				Overdragen
 			</string>
-			<button label="Overdragen..." label_selected="Overdragen..." name="button deed" tool_tip="Groepgedeelde objecten kunnen door een groepofficier worden overgedragen" left_pad="19"/>
+			<button label="Overdragen..." label_selected="Overdragen..." name="button deed" tool_tip="Groepgedeelde objecten kunnen door een groepofficier worden overgedragen"/>
 			<check_box label="Iedereen mag verplaatsen" name="checkbox allow everyone move"/>
 			<check_box label="Iedereen mag kopiëren" name="checkbox allow everyone copy"/>
 			<check_box label="Toon in zoeken" name="search_check" tool_tip="Laat mensen dit object zien in zoekresultaten"/>
diff --git a/indra/newview/skins/default/xui/nl/notifications.xml b/indra/newview/skins/default/xui/nl/notifications.xml
index b4b56a035ff55204ce95f82819382f57d08f8a3b..be0c17d2ff8a7145f51aca577a62311a38bbe875 100644
--- a/indra/newview/skins/default/xui/nl/notifications.xml
+++ b/indra/newview/skins/default/xui/nl/notifications.xml
@@ -2478,9 +2478,6 @@ Wilt u de [SECOND_LIFE] website bezoeken om dit in te stellen?
 	<notification name="CannotRemoveProtectedCategories">
 		U kunt geen beschermde categorieën verwijderen.
 	</notification>
-	<notification name="OfferedCard">
-		U heeft een visitekaartje aangeboden aan [FIRST] [LAST]
-	</notification>
 	<notification name="UnableToBuyWhileDownloading">
 		Niet mogelijk te kopen terwijl objectdata wordt gedownload. Probeer het alstublieft opnieuw.
 	</notification>
@@ -2780,7 +2777,7 @@ Probeer het alstublieft opnieuw over enkele ogenblikken.
 		[NAME] heeft uw vriendschapsaanbod afgewezen.
 	</notification>
 	<notification name="OfferCallingCard">
-		[FIRST] [LAST] biedt zijn/haar visitekaartje aan.
+		[NAME] biedt zijn/haar visitekaartje aan.
 Dit zal een bladwijzer in uw inventaris toevoegen zodat u deze inwoner snel kunt een IM kunt sturen.
 		<form name="form">
 			<button name="Accept" text="Accepteren"/>
diff --git a/indra/newview/skins/default/xui/nl/panel_edit_profile.xml b/indra/newview/skins/default/xui/nl/panel_edit_profile.xml
index 172395e20a27b6ca938f09d58240b33ee8ac636e..fffdb9e8dfd9b71e656aff5a575ea7f874fb3c1d 100644
--- a/indra/newview/skins/default/xui/nl/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/nl/panel_edit_profile.xml
@@ -35,7 +35,7 @@
       </panel>
         <text name="title_partner_text" value="Partner:"/>
         <panel name="partner_data_panel">
-            <text name="partner_text" value="[FIRST] [LAST]"/>
+            <text name="partner_text"/>
          </panel>
       <text name="text_box3">
 	Antwoord bij Niet Storen:
diff --git a/indra/newview/skins/default/xui/nl/strings.xml b/indra/newview/skins/default/xui/nl/strings.xml
index 844945913fb31a86cd49de3a36f5585b8f95f6cb..07265d27162a5d65edc62c7ae49144a6b1f9c557 100644
--- a/indra/newview/skins/default/xui/nl/strings.xml
+++ b/indra/newview/skins/default/xui/nl/strings.xml
@@ -3211,7 +3211,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
 		U bent de enige gebruiker in deze sessie.
 	</string>
 	<string name="offline_message">
-		[FIRST] [LAST] is offline.
+		[NAME] is offline.
 	</string>
 	<string name="invite_message">
 		Klik de [BUTTON NAME] knop om deze voicechat te accepteren/verbinden.
diff --git a/indra/newview/skins/default/xui/pl/floater_tools.xml b/indra/newview/skins/default/xui/pl/floater_tools.xml
index 8c77df92487610984fab5c30186d21841ebdd481..7c1ced0eaee7349f6de61cef899a7760a383da45 100644
--- a/indra/newview/skins/default/xui/pl/floater_tools.xml
+++ b/indra/newview/skins/default/xui/pl/floater_tools.xml
@@ -307,7 +307,7 @@
 				<combo_box.item label="Kwadrat" name="Square"/>
 				<combo_box.item label="Trójkąt" name="Triangle"/>
 			</combo_box>
-			<text name="text twist">
+			<text name="text twist" left_delta="-5" width="160">
 				Skręcenie (początek/koniec)
 			</text>
 			<spinner label="P" name="Twist Begin"/>
diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml
index 7e5ed4347553c1b58c99c15db92bc64c17f22b90..8151c7eb938304846d51f890b8b1d769879b4d9f 100644
--- a/indra/newview/skins/default/xui/pl/notifications.xml
+++ b/indra/newview/skins/default/xui/pl/notifications.xml
@@ -2440,7 +2440,7 @@ Spróbuj ponowanie za kilka minut.
 		Propozycja znajomości została odrzucona.
 	</notification>
 	<notification name="OfferCallingCard">
-		[FIRST] [LAST] daje Tobie swoją wizytówkę.
+		[NAME] daje Tobie swoją wizytówkę.
 Wizytówka będzie znajdowała się w Szafie i umożliwi szybkie wysłanie IM do tego Rezydenta.
 		<form name="form">
 			<button name="Accept" text="Zaakceptuj"/>
diff --git a/indra/newview/skins/default/xui/pl/panel_edit_profile.xml b/indra/newview/skins/default/xui/pl/panel_edit_profile.xml
index dad8bca1830342d98d6f31b44d7a22a4c16e032a..c409666ec92b307772d1a1673ffd95064197e0c9 100644
--- a/indra/newview/skins/default/xui/pl/panel_edit_profile.xml
+++ b/indra/newview/skins/default/xui/pl/panel_edit_profile.xml
@@ -46,7 +46,7 @@
 				<text name="my_account_link" value="[[URL] idź do dashboard]"/>
 				<text name="title_partner_text" value="Partner:"/>
 				<panel name="partner_data_panel">
-					<text initial_value="(wyszukiwanie)" name="partner_text" value="[FIRST] [LAST]"/>
+					<text initial_value="(wyszukiwanie)" name="partner_text"/>
 				</panel>
 				<text name="partner_edit_link" value="[[URL] Edytuj]"/>
 			</panel>
diff --git a/indra/newview/skins/default/xui/pl/panel_places.xml b/indra/newview/skins/default/xui/pl/panel_places.xml
index e0a0cfd96a35c8861ba9712948ce582b273bc30c..34c105225d0774463d7ccc26782337d1099c44bd 100644
--- a/indra/newview/skins/default/xui/pl/panel_places.xml
+++ b/indra/newview/skins/default/xui/pl/panel_places.xml
@@ -21,7 +21,7 @@
 						<button label="Edytuj" name="edit_btn" tool_tip="Edytuj informacje landmarka"/>
 					</layout_panel>
 					<layout_panel name="overflow_btn_lp">
-						<button label="▼" name="overflow_btn" tool_tip="Pokaż opcje dodatkowe"/>
+						<menu_button label="▼" name="overflow_btn" tool_tip="Pokaż opcje dodatkowe"/>
 					</layout_panel>
 				</layout_stack>
 				<layout_stack name="bottom_bar_ls3">
diff --git a/indra/newview/skins/default/xui/pl/panel_profile.xml b/indra/newview/skins/default/xui/pl/panel_profile.xml
index f4a5699f8d54268a4d9a699ce06afa23f95d2e78..4152c003860debab7eee0dd81fda66ebc4981f34 100644
--- a/indra/newview/skins/default/xui/pl/panel_profile.xml
+++ b/indra/newview/skins/default/xui/pl/panel_profile.xml
@@ -42,7 +42,7 @@
 					<button label="Teleportuj" name="teleport" tool_tip="Teleportuj"/>
 				</layout_panel>
 				<layout_panel name="overflow_btn_lp">
-					<button label="▼" name="overflow_btn" tool_tip="Zapłać lub udostępnij obiekt Rezydentowi"/>
+					<menu_button label="▼" name="overflow_btn" tool_tip="Zapłać lub udostępnij obiekt Rezydentowi"/>
 				</layout_panel>
 			</layout_stack>
 		</layout_panel>
diff --git a/indra/newview/skins/default/xui/pl/strings.xml b/indra/newview/skins/default/xui/pl/strings.xml
index 59daa26bf0eba63b646d0604d13eea89142bb98f..ea8bdd75b9fa53b0fd733949e301894f8bf60977 100644
--- a/indra/newview/skins/default/xui/pl/strings.xml
+++ b/indra/newview/skins/default/xui/pl/strings.xml
@@ -3469,7 +3469,7 @@ Jeżeli nadal otrzymujesz ten komunikat, skontaktuj się z [SUPPORT_SITE].
 		Rozmowa głosowa zakończona
 	</string>
 	<string name="conference-title-incoming">
-		Konferencja z  [AGENT_NAME]
+		Konferencja z [AGENT_NAME]
 	</string>
 	<string name="no_session_message">
 		(Sesja IM wygasła)
diff --git a/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml b/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
index c666a941feaf8e6905f585a04d5d850510ec6b94..8c95a3b5482e6302a2000dea0a26f9951a5c81de 100644
--- a/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
+++ b/indra/newview/skins/default/xui/pt/floater_hardware_settings.xml
@@ -14,6 +14,9 @@
 		<combo_box.item label="8x" name="8x"/>
 		<combo_box.item label="16x" name="16x"/>
 	</combo_box>
+	<text name="antialiasing restart">
+		(Reinicie para ativar)
+	</text>
 	<spinner label="Gama:" name="gamma"/>
 	<text name="(brightness, lower is brighter)">
 		(0 = brilho padrão, menor = mais brilho)
diff --git a/indra/newview/skins/default/xui/pt/floater_im.xml b/indra/newview/skins/default/xui/pt/floater_im.xml
deleted file mode 100644
index c81d0dd7ef37d079c0641a4044a9cc20a11d28a0..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/pt/floater_im.xml
+++ /dev/null
@@ -1,45 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<multi_floater name="im_floater" title="Mensagem Instantânea">
-	<string name="only_user_message">
-		Você é o único residente nesta sessão
-	</string>
-	<string name="offline_message">
-		[FIRST] [LAST] está offline.
-	</string>
-	<string name="invite_message">
-		Clique no botão [BUTTON NAME] para aceitar/ conectar a este bate-papo em voz.
-	</string>
-	<string name="muted_message">
-		Você bloqueou este residente.  Se quiser retirar o bloqueio, basta enviar uma mensagem.
-	</string>
-	<string name="generic_request_error">
-		Erro na requisição, por favor, tente novamente.
-	</string>
-	<string name="insufficient_perms_error">
-		Você não tem permissões suficientes.
-	</string>
-	<string name="session_does_not_exist_error">
-		A sessão deixou de existir
-	</string>
-	<string name="no_ability_error">
-		Você não possui esta habilidade.
-	</string>
-	<string name="not_a_mod_error">
-		Você não é um moderador de sessão.
-	</string>
-	<string name="muted_error">
-		Um moderador do grupo desabilitou seu bate-papo em texto.
-	</string>
-	<string name="add_session_event">
-		Não foi possível adicionar residentes ao bate-papo com [RECIPIENT].
-	</string>
-	<string name="message_session_event">
-		Não foi possível enviar sua mensagem na sessão de bate- papo com [RECIPIENT].
-	</string>
-	<string name="removed_from_group">
-		Você foi removido do grupo.
-	</string>
-	<string name="close_on_no_ability">
-		Você não possui mais a habilidade de estar na sessão de bate-papo.
-	</string>
-</multi_floater>
diff --git a/indra/newview/skins/default/xui/pt/floater_preferences.xml b/indra/newview/skins/default/xui/pt/floater_preferences.xml
index 2c76a72ca869f4196a98dab25b7bb628691ea322..c89a61d9b1592666cce2fb3f0f4f53439dc672af 100644
--- a/indra/newview/skins/default/xui/pt/floater_preferences.xml
+++ b/indra/newview/skins/default/xui/pt/floater_preferences.xml
@@ -5,10 +5,12 @@
 	<tab_container name="pref core">
 		<panel label="Geral" name="general"/>
 		<panel label="Vídeo" name="display"/>
-		<panel label="Privacidade" name="im"/>
 		<panel label="Som e mídia" name="audio"/>
 		<panel label="Bate-papo" name="chat"/>
+		<panel label="Mover e ver" name="move"/>
 		<panel label="Notificações" name="msgs"/>
+		<panel label="Cores" name="colors"/>
+		<panel label="Privacidade" name="im"/>
 		<panel label="Configurações" name="input"/>
 		<panel label="Avançado" name="advanced1"/>
 	</tab_container>
diff --git a/indra/newview/skins/default/xui/pt/floater_region_debug_console.xml b/indra/newview/skins/default/xui/pt/floater_region_debug_console.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d3b5df2d74b386043a972b456bcf1d2951426ebd
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/floater_region_debug_console.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<floater name="region_debug_console" title="Depuração de região"/>
diff --git a/indra/newview/skins/default/xui/pt/floater_tools.xml b/indra/newview/skins/default/xui/pt/floater_tools.xml
index 2925e286edf255d9db2317538d7a82279445212f..bd5fbf80d13ece103f164ebab873ac30e2188147 100644
--- a/indra/newview/skins/default/xui/pt/floater_tools.xml
+++ b/indra/newview/skins/default/xui/pt/floater_tools.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="toolbox floater" short_title="BUILD TOOLS" title="" width="288">
+<floater name="toolbox floater" short_title="BUILD TOOLS" title="">
 	<floater.string name="status_rotate">
 		Arrastar as faixas coloridas para girar o objeto
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/pt/menu_inventory_gear_default.xml b/indra/newview/skins/default/xui/pt/menu_inventory_gear_default.xml
index a3e62924ecc147d0ee9c2598e206fb2374f88aaa..3400578d9a939ce359d83ee7d1cbe115c1e5d966 100644
--- a/indra/newview/skins/default/xui/pt/menu_inventory_gear_default.xml
+++ b/indra/newview/skins/default/xui/pt/menu_inventory_gear_default.xml
@@ -1,8 +1,9 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<menu name="menu_gear_default">
+<toggleable_menu name="menu_gear_default">
 	<menu_item_call label="Nova janela de inventário" name="new_window"/>
-	<menu_item_call label="Ordenar por nome" name="sort_by_name"/>
-	<menu_item_call label="Ordenar por mais recente" name="sort_by_recent"/>
+	<menu_item_check label="Ordenar por nome" name="sort_by_name"/>
+	<menu_item_check label="Ordenar por mais recente" name="sort_by_recent"/>
+	<menu_item_check label="Pastas do sistema no topo" name="sort_system_folders_to_top"/>
 	<menu_item_call label="Mostrar filtros" name="show_filters"/>
 	<menu_item_call label="Restabelecer filtros" name="reset_filters"/>
 	<menu_item_call label="Fechar todas as pastas" name="close_folders"/>
@@ -12,4 +13,4 @@
 	<menu_item_call label="Encontrar original" name="Find Original"/>
 	<menu_item_call label="Encontrar todos os links" name="Find All Links"/>
 	<menu_item_call label="Esvaziar lixeira" name="empty_trash"/>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/pt/menu_viewer.xml b/indra/newview/skins/default/xui/pt/menu_viewer.xml
index dc0e2ffb64db3383826edd9632d0886e55ff7515..95c37c53ca48eb6c358b596e0a9ff1d41b5b22e7 100644
--- a/indra/newview/skins/default/xui/pt/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/pt/menu_viewer.xml
@@ -12,6 +12,12 @@
 		<menu_item_check label="Meu inventário" name="ShowSidetrayInventory"/>
 		<menu_item_check label="Meus gestos" name="Gestures"/>
 		<menu_item_check label="Minha voz" name="ShowVoice"/>
+		<menu label="Movimentos" name="Movement">
+			<menu_item_call label="Sentar" name="Sit Down Here"/>
+			<menu_item_check label="Voar" name="Fly"/>
+			<menu_item_check label="Correr sempre" name="Always Run"/>
+			<menu_item_call label="Parar minha animação" name="Stop Animating My Avatar"/>
+		</menu>
 		<menu label="Meu status" name="Status">
 			<menu_item_call label="Ausente" name="Set Away"/>
 			<menu_item_call label="Ocupado" name="Set Busy"/>
@@ -47,6 +53,7 @@
 			<menu_item_check label="Proprietários" name="Land Owners"/>
 			<menu_item_check label="Coordenadas" name="Coordinates"/>
 			<menu_item_check label="Propriedades do lote" name="Parcel Properties"/>
+			<menu_item_check label="Menu avançado" name="Show Advanced Menu"/>
 		</menu>
 		<menu_item_call label="Teletransportar para meu início" name="Teleport Home"/>
 		<menu_item_call label="Definir como Início" name="Set Home to Here"/>
@@ -123,7 +130,6 @@
 		<menu_item_check label="Ativar dicas" name="Enable Hints"/>
 	</menu>
 	<menu label="Avançado" name="Advanced">
-		<menu_item_call label="Parar minha animação" name="Stop Animating My Avatar"/>
 		<menu_item_call label="Recarregar texturas" name="Rebake Texture"/>
 		<menu_item_call label="Interface tamanho padrão" name="Set UI Size to Default"/>
 		<menu_item_call label="Definir tamanho da janela:" name="Set Window Size..."/>
@@ -177,8 +183,7 @@
 			<menu_item_check label="Busca" name="Search"/>
 			<menu_item_call label="Soltar objeto" name="Release Keys"/>
 			<menu_item_call label="Interface tamanho padrão" name="Set UI Size to Default"/>
-			<menu_item_check label="Correr sempre" name="Always Run"/>
-			<menu_item_check label="Voar" name="Fly"/>
+			<menu_item_check label="Mostrar menu avançado - atalho antigo" name="Show Advanced Menu - legacy shortcut"/>
 			<menu_item_call label="Fechar janela" name="Close Window"/>
 			<menu_item_call label="Fechar todas as janelas" name="Close All Windows"/>
 			<menu_item_call label="Gravar fotos no HD" name="Snapshot to Disk"/>
@@ -196,7 +201,6 @@
 			<menu_item_call label="Mais zoom" name="Zoom In"/>
 			<menu_item_call label="Zoom padrão" name="Zoom Default"/>
 			<menu_item_call label="Menos zoom" name="Zoom Out"/>
-			<menu_item_check label="Exibir menu avançado" name="Show Advanced Menu"/>
 		</menu>
 		<menu_item_call label="Mostrar configurações de depuração" name="Debug Settings"/>
 		<menu_item_check label="Show Develop Menu" name="Debug Mode"/>
@@ -267,16 +271,13 @@
 			<menu_item_call label="Teste de navegador web" name="Web Browser Test"/>
 			<menu_item_call label="Print Selected Object Info" name="Print Selected Object Info"/>
 			<menu_item_call label="Dados de memória" name="Memory Stats"/>
-			<menu_item_check label="Trajeto c/ dois cliques" name="Double-ClickAuto-Pilot"/>
-			<menu_item_check label="Teletransportar c/ dois cliques" name="DoubleClick Teleport"/>
+			<menu_item_check label="Console de depuração de região" name="Region Debug Console"/>
 			<menu_item_check label="Debug Clicks" name="Debug Clicks"/>
 			<menu_item_check label="Debug Mouse Events" name="Debug Mouse Events"/>
 		</menu>
 		<menu label="XUI" name="XUI">
 			<menu_item_call label="Recarregar cores" name="Reload Color Settings"/>
 			<menu_item_call label="Teste de fonte" name="Show Font Test"/>
-			<menu_item_call label="Carregar de XML" name="Load from XML"/>
-			<menu_item_call label="Salvar para XML" name="Save to XML"/>
 			<menu_item_check label="Mostrar nomes XUI" name="Show XUI Names"/>
 			<menu_item_call label="Enviar MIs de teste" name="Send Test IMs"/>
 			<menu_item_call label="Limpar cache de nomes" name="Flush Names Caches"/>
@@ -303,9 +304,9 @@
 		</menu>
 		<menu_item_check label="Texturas HTTP" name="HTTP Textures"/>
 		<menu_item_check label="Console Window on next Run" name="Console Window"/>
-		<menu_item_check label="Mostrar menu admin" name="View Admin Options"/>
 		<menu_item_call label="Request Admin Status" name="Request Admin Options"/>
 		<menu_item_call label="Sair do modo admin" name="Leave Admin Options"/>
+		<menu_item_check label="Mostrar menu admin" name="View Admin Options"/>
 	</menu>
 	<menu label="Admin" name="Admin">
 		<menu label="Object">
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index 466a24742d0f2ad20de56c234fae1c2b6d373307..dc38b740aaf54053ecb2bc2e575919a6937a26f0 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -385,6 +385,9 @@ Nota: Este procedimento limpa o cache.
 	<notification name="ChangeSkin">
 		Reinicie o [APP_NAME] para ativar a pele nova.
 	</notification>
+	<notification name="ChangeLanguage">
+		Reinicie o [APP_NAME] para exibir o idioma selecionado.
+	</notification>
 	<notification name="GoToAuctionPage">
 		Ir para a página do [SECOND_LIFE] para ver os detalhes do leilão ou fazer um lance?
 		<usetemplate name="okcancelbuttons" notext="Cancelar" yestext="Ir para a página"/>
@@ -592,6 +595,10 @@ Esperada [VALIDS]
 	</notification>
 	<notification name="SoundFileInvalidHeader">
 		Não pode ser encontrado bloco de dados no cabeçalho WAV:
+[FILE]
+	</notification>
+	<notification name="SoundFileInvalidChunkSize">
+		Pedaço de arquivo WAV de tamanho errado:
 [FILE]
 	</notification>
 	<notification name="SoundFileInvalidTooLong">
@@ -1316,6 +1323,16 @@ Não é preciso passar para a nova versão, mas ela pode melhorar o desempenho e
 Salvar na pasta Aplicativos?
 		<usetemplate name="okcancelbuttons" notext="Continuar" yestext="Atualizar"/>
 	</notification>
+	<notification name="FailedUpdateInstall">
+		Ocorreu um erro de atualização do visualizador. 
+Baixe e instale a versão mais recente do visualizador em 
+http://secondlife.com/download.
+		<usetemplate name="okbutton" yestext="OK"/>
+	</notification>
+	<notification name="DownloadBackground">
+		Foi baixada uma nova versão do [APP_NAME]
+A nova versão será exibida quando o [APP_NAME] for reiniciado.
+	</notification>
 	<notification name="DeedObjectToGroup">
 		Delegar este objeto causará ao grupo:
 * Receber os L$ pagos ao objeto
@@ -2448,8 +2465,8 @@ Cada um pode ver o status do outro (definição padrão).
 		Oferta de amizada aceita.
 	</notification>
 	<notification name="OfferCallingCard">
-		[FIRST] [LAST] estão te oferecendo um cartão de visita.
-Ele colocará um item de inventário, para você possa contatá-lo facilmente.
+		[NOME] está te oferecendo um cartão de visita.
+Ele será um item no seu inventário, para você possa contatá-lo facilmente.
 		<form name="form">
 			<button name="Accept" text="Aceitar"/>
 			<button name="Decline" text="Recusar"/>
@@ -2552,13 +2569,13 @@ Clique em Aceitar para atender ou em Recusar para recusar este convite.  Clique
 		</form>
 	</notification>
 	<notification name="AutoUnmuteByIM">
-		[FIRST] recebeu uma MI e foi desbloqueado(a) automaticamente.
+		[NAME] recebeu uma MI e foi desbloqueado(a) automaticamente.
 	</notification>
 	<notification name="AutoUnmuteByMoney">
-		[FIRST] recebeu dinheiro e foi desbloqueado(a) automaticamente.
+		[NAME] recebeu dinheiro e foi desbloqueado(a) automaticamente.
 	</notification>
 	<notification name="AutoUnmuteByInventory">
-		[FIRST] recebeu dinheiro e foi desbloqueado(a) automaticamente.
+		[NAME] recebeu dinheiro e foi desbloqueado(a) automaticamente.
 	</notification>
 	<notification name="VoiceInviteGroup">
 		[NAME] atendeu uma ligação de bate-papo de voz com o grupo [GROUP].  
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_gloves.xml b/indra/newview/skins/default/xui/pt/panel_edit_gloves.xml
index a94716e659ee4257ecb103c5ee31333272b0fc85..281823d6412084106c19a3bf3555d430ee97e5f5 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_gloves.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_gloves.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_gloves_panel">
 	<panel name="avatar_gloves_color_panel">
-		<texture_picker label="Tecido" name="Fabric" tool_tip="Selecionar imagem"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Selecionar imagem"/>
 		<color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_jacket.xml b/indra/newview/skins/default/xui/pt/panel_edit_jacket.xml
index f555bd9ac78b374460c08546973460709940ae34..5798325bd734d64f66a6c72d46a691501a6e1d24 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_jacket.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_jacket.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_jacket_panel">
 	<panel name="avatar_jacket_color_panel">
-		<texture_picker label="Tecido de cima" name="Upper Fabric" tool_tip="Selecionar imagem"/>
-		<texture_picker label="Tecido de baixo" name="Lower Fabric" tool_tip="Selecionar imagem"/>
+		<texture_picker label="Textura superior" name="Upper Fabric" tool_tip="Selecionar imagem"/>
+		<texture_picker label="Textura inferior" name="Lower Fabric" tool_tip="Selecionar imagem"/>
 		<color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_pants.xml b/indra/newview/skins/default/xui/pt/panel_edit_pants.xml
index 67c300cc8dd77090d41532a8bef26a22bca6b93d..18568a81a897f6e893d1aa058e19fde0ebec4b7a 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_pants.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_pants.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_pants_panel">
 	<panel name="avatar_pants_color_panel">
-		<texture_picker label="Tecido" name="Fabric" tool_tip="Selecionar imagem"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Selecionar imagem"/>
 		<color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_shirt.xml b/indra/newview/skins/default/xui/pt/panel_edit_shirt.xml
index fb7c4c080c38cf229020db4bc7a0ac9cfb51b31a..c7e2b1e64cc80b75e0f2e215024c6115c29ed0b0 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_shirt.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_shirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_shirt_panel">
 	<panel name="avatar_shirt_color_panel">
-		<texture_picker label="tecido" name="Fabric" tool_tip="Clique para escolher uma foto"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Clique para escolher uma foto"/>
 		<color_swatch label="Cor/Matiz" name="Color/Tint" tool_tip="Clique para abrir o selecionador de cor"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_shoes.xml b/indra/newview/skins/default/xui/pt/panel_edit_shoes.xml
index d1d30cf46ea73a1c276f3b4ccd398d34a5b5fa54..08465d09e7555b54eaf2addd496099cd2d5b0aee 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_shoes.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_shoes.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_shoes_panel">
 	<panel name="avatar_shoes_color_panel">
-		<texture_picker label="Tecido" name="Fabric" tool_tip="Selecionar imagem"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Selecionar imagem"/>
 		<color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_skirt.xml b/indra/newview/skins/default/xui/pt/panel_edit_skirt.xml
index b67cd53a8316cb6d8a42b5f8621af2d3d578ded5..275efba6e68b8a5e3d9f3b9a366d36c8c69ef2d9 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_skirt.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_skirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_skirt_panel">
 	<panel name="avatar_skirt_color_panel">
-		<texture_picker label="Tecido" name="Fabric" tool_tip="Selecionar imagem"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Selecionar imagem"/>
 		<color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_socks.xml b/indra/newview/skins/default/xui/pt/panel_edit_socks.xml
index 405568abeba2ec7bf52ee2d7a79d69d17ac15193..6f4779d85525f3eb0adc6bfcbe3099dec343a667 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_socks.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_socks.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_socks_panel">
 	<panel name="avatar_socks_color_panel">
-		<texture_picker label="Tecido" name="Fabric" tool_tip="Selecionar imagem"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Selecionar imagem"/>
 		<color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_underpants.xml b/indra/newview/skins/default/xui/pt/panel_edit_underpants.xml
index f858dc04951548617ae9b532457594686cc4209f..c383471851c0c2408f520d37483ce0c6f7e7b7a6 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_underpants.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_underpants.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_underpants_panel">
 	<panel name="avatar_underpants_color_panel">
-		<texture_picker label="Tecido" name="Fabric" tool_tip="Selecionar imagem"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Selecionar imagem"/>
 		<color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_edit_undershirt.xml b/indra/newview/skins/default/xui/pt/panel_edit_undershirt.xml
index 9c18fc1d6c56a1946ed5a557dd277c647018a2bb..0bf510c67f3dc1481d0172e309523f8946b717db 100644
--- a/indra/newview/skins/default/xui/pt/panel_edit_undershirt.xml
+++ b/indra/newview/skins/default/xui/pt/panel_edit_undershirt.xml
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel name="edit_undershirt_panel">
 	<panel name="avatar_undershirt_color_panel">
-		<texture_picker label="Tecido" name="Fabric" tool_tip="Selecionar imagem"/>
+		<texture_picker label="Textura" name="Fabric" tool_tip="Selecionar imagem"/>
 		<color_swatch label="Cor/Tonalidade" name="Color/Tint" tool_tip="Selecionar a cor"/>
 	</panel>
 	<panel name="accordion_panel">
diff --git a/indra/newview/skins/default/xui/pt/panel_notify_textbox.xml b/indra/newview/skins/default/xui/pt/panel_notify_textbox.xml
new file mode 100644
index 0000000000000000000000000000000000000000..d9614fe76bdf076787ea9c1f3ae8441ae65ed656
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_notify_textbox.xml
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="instant_message" name="panel_notify_textbox">
+	<string name="message_max_lines_count" value="7"/>
+	<panel label="info_panel" name="info_panel">
+		<text_editor name="message" value="mensagem"/>
+		parse_urls=&quot;false&quot;
+		<button label="Enviar" name="btn_submit"/>
+	</panel>
+	<panel label="control_panel" name="control_panel"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_people.xml b/indra/newview/skins/default/xui/pt/panel_people.xml
index e02e3998eb01c54a8a190a0e11630ed83d5bf72d..f1632729a91d50f4fe9855a051f55b6f03db0846 100644
--- a/indra/newview/skins/default/xui/pt/panel_people.xml
+++ b/indra/newview/skins/default/xui/pt/panel_people.xml
@@ -22,7 +22,7 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-
 	<tab_container name="tabs">
 		<panel label="PROXIMIDADE" name="nearby_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="nearby_view_sort_btn" tool_tip="Opções"/>
+				<menu_button name="nearby_view_sort_btn" tool_tip="Opções"/>
 				<button name="add_friend_btn" tool_tip="Adicionar o residente selecionado para sua lista de amigos"/>
 			</panel>
 		</panel>
@@ -34,27 +34,27 @@ Em busca de alguém para conversar? Procure no [secondlife:///app/worldmap Mapa-
 			<panel label="bottom_panel" name="bottom_panel">
 				<layout_stack name="bottom_panel">
 					<layout_panel name="options_gear_btn_panel">
-						<button name="friends_viewsort_btn" tool_tip="Mostrar opções adicionais"/>
+						<menu_button name="friends_viewsort_btn" tool_tip="Mostrar opções adicionais"/>
 					</layout_panel>
 					<layout_panel name="add_btn_panel">
 						<button name="add_btn" tool_tip="Oferecer amizade para um residente"/>
 					</layout_panel>
 					<layout_panel name="trash_btn_panel">
-						<dnd_button name="trash_btn" tool_tip="Remover a pessoa selecionada da sua lista de amigos"/>
+						<dnd_button name="del_btn" tool_tip="Remover a pessoa selecionada da sua lista de amigos"/>
 					</layout_panel>
 				</layout_stack>
 			</panel>
 		</panel>
 		<panel label="MEUS GRUPOS" name="groups_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="groups_viewsort_btn" tool_tip="Opções"/>
+				<menu_button name="groups_viewsort_btn" tool_tip="Opções"/>
 				<button name="plus_btn" tool_tip="Ingressar em um grupo/Criar novo grupo"/>
 				<button name="activate_btn" tool_tip="Ativar o grupo selecionado"/>
 			</panel>
 		</panel>
 		<panel label="RECENTE" name="recent_panel">
 			<panel label="bottom_panel" name="bottom_panel">
-				<button name="recent_viewsort_btn" tool_tip="Opções"/>
+				<menu_button name="recent_viewsort_btn" tool_tip="Opções"/>
 				<button name="add_friend_btn" tool_tip="Adicionar o residente selecionado para sua lista de amigos"/>
 			</panel>
 		</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_places.xml b/indra/newview/skins/default/xui/pt/panel_places.xml
index 2e443bc0572255d8bee3e0f94bd126c2c4bcd792..828ef3e4693dff10adadde315f919478c1cf55ff 100644
--- a/indra/newview/skins/default/xui/pt/panel_places.xml
+++ b/indra/newview/skins/default/xui/pt/panel_places.xml
@@ -21,7 +21,7 @@
 						<button label="Editar" name="edit_btn" tool_tip="Editar dados do marco"/>
 					</layout_panel>
 					<layout_panel name="overflow_btn_lp">
-						<button label="▼" name="overflow_btn" tool_tip="Mostrar opções adicionais"/>
+						<menu_button label="▼" name="overflow_btn" tool_tip="Mostrar opções adicionais"/>
 					</layout_panel>
 				</layout_stack>
 				<layout_stack name="bottom_bar_ls3">
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml
index 13cb8a444ede63caa2e3a44f0fced7994280129d..bbe7e15ba2edcff4ba33da1f4ce0c91be3da40a3 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_advanced.xml
@@ -3,35 +3,16 @@
 	<panel.string name="aspect_ratio_text">
 		[NUM]:[DEN]
 	</panel.string>
-	<panel.string name="middle_mouse">
-		Botão do meio do mouse
-	</panel.string>
-	<slider label="Ângulo de visão" name="camera_fov"/>
-	<slider label="Distância" name="camera_offset_scale"/>
-	<text name="heading2">
-		Posicionamento automático da:
-	</text>
-	<check_box label="Construção/Edição" name="edit_camera_movement" tool_tip="Use o posicionamento automático da câmera quando entrar e sair do modo de edição"/>
-	<check_box label="Aparência" name="appearance_camera_movement" tool_tip="Use o posicionamento automático da câmera quando em modo de edição"/>
-	<check_box initial_value="verdadeiro" label="Barra lateral" name="appearance_sidebar_positioning" tool_tip="Usar posicionamento automático da câmera na barra lateral"/>
-	<check_box label="Mostre-me em visão de mouse" name="first_person_avatar_visible"/>
-	<check_box label="Teclas de seta sempre me movem" name="arrow_keys_move_avatar_check"/>
-	<check_box label="Dê dois toques e pressione para correr" name="tap_tap_hold_to_run"/>
-	<check_box label="Mover os lábios do avatar ao falar" name="enable_lip_sync"/>
-	<check_box label="Balão de bate-papo" name="bubble_text_chat"/>
-	<slider label="Opacidade" name="bubble_chat_opacity"/>
-	<color_swatch name="background" tool_tip="Cor do balão de bate-papo"/>
 	<text name="UI Size:">
-		Interface
+		Interface:
 	</text>
 	<check_box label="Mostrar erros de script" name="show_script_errors"/>
 	<radio_group name="show_location">
 		<radio_item label="Bate-papo local" name="0"/>
 		<radio_item label="Janelas separadas" name="1"/>
 	</radio_group>
-	<check_box label="Tecla liga/desliga da minha voz:" name="push_to_talk_toggle_check" tool_tip="Quando em modo de alternância, pressione e solte o botão UMA vez para ligar e desligar o microfone. Quando em modo de alternância, o microfone só transmite sua voz quando o botão estiver pressionado."/>
-	<line_editor label="Botão apertar e falar" name="modifier_combo"/>
-	<button label="Definir tecla" name="set_voice_hotkey_button"/>
-	<button label="Botão do meio do mouse" name="set_voice_middlemouse_button" tool_tip="Redefinir como botão do meio do mouse"/>
-	<button label="Outros dispositivos" name="joystick_setup_button"/>
+	<check_box label="Permitir vários visualizadores" name="allow_multiple_viewer_check"/>
+	<check_box label="Mostrar grade selecionada ao entrar" name="show_grid_selection_check"/>
+	<check_box label="Exibir menu avançado" name="show_advanced_menu_check"/>
+	<check_box label="Exibir menu desenvolvedor" name="show_develop_menu_check"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
index ea15b906282df5c96378ec6af3535b24da5d055b..368c474ee9d132b38599f9e6a5aa26d29d89067a 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_chat.xml
@@ -8,44 +8,10 @@
 		<radio_item label="Médio" name="radio2" value="1"/>
 		<radio_item label="Grande" name="radio3" value="2"/>
 	</radio_group>
-	<text name="font_colors">
-		Cor da fonte:
-	</text>
-	<color_swatch label="Você" name="user"/>
-	<text name="text_box1">
-		Eu
-	</text>
-	<color_swatch label="Outros" name="agent"/>
-	<text name="text_box2">
-		Outros
-	</text>
-	<color_swatch label="MI" name="im"/>
-	<text name="text_box3">
-		MI
-	</text>
-	<color_swatch label="Sistema" name="system"/>
-	<text name="text_box4">
-		Sistema
-	</text>
-	<color_swatch label="Erros" name="script_error"/>
-	<text name="text_box5">
-		Erros
-	</text>
-	<color_swatch label="Objetos" name="objects"/>
-	<text name="text_box6">
-		Objetos
-	</text>
-	<color_swatch label="Dono" name="owner"/>
-	<text name="text_box7">
-		Dono
-	</text>
-	<color_swatch label="URLs" name="links"/>
-	<text name="text_box9">
-		URLs
-	</text>
 	<check_box initial_value="true" label="Executar animação digitada quando estiver conversando" name="play_typing_animation"/>
 	<check_box label="Enviar MIs por email se estiver desconectado" name="send_im_to_email"/>
 	<check_box label="Ativar MIs e bate-papos de texto simples" name="plain_text_chat_history"/>
+	<check_box label="Balão de bate-papo" name="bubble_text_chat"/>
 	<text name="show_ims_in_label">
 		Mostrar MIs em:
 	</text>
@@ -56,6 +22,13 @@
 		<radio_item label="Janelas separadas" name="radio" value="0"/>
 		<radio_item label="Guias" name="radio2" value="1"/>
 	</radio_group>
+	<text name="disable_toast_label">
+		Ativar pop-ups de novos bate-papos:
+	</text>
+	<check_box label="Bate-papo de grupo" name="EnableGroupChatPopups" tool_tip="Exibir pop-up de bate-papos novos de grupos"/>
+	<check_box label="Bate-papos de MI" name="EnableIMChatPopups" tool_tip="Exibir pop-up de mensagens instantâneas novas"/>
+	<spinner label="Transição de avisos de bate-papos por perto:" name="nearby_toasts_lifetime"/>
+	<spinner label="Transição de avisos de bate-papos por perto:" name="nearby_toasts_fadingtime"/>
 	<check_box label="Traduzir bate-papo automaticamente (via Google)" name="translate_chat_checkbox"/>
 	<text name="translate_language_text">
 		Traduzir bate-papo para:
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_colors.xml b/indra/newview/skins/default/xui/pt/panel_preferences_colors.xml
new file mode 100644
index 0000000000000000000000000000000000000000..3ca9da06c9cd0ef3169ca215bef57a36e6f35beb
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_colors.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Cores" name="colors_panel">
+	<text name="effects_color_textbox">
+		Meus efeitos (raio de seleção):
+	</text>
+	<color_swatch name="effect_color_swatch" tool_tip="Selecionar a cor"/>
+	<text name="font_colors">
+		Cores no bate-papo:
+	</text>
+	<text name="text_box1">
+		Eu
+	</text>
+	<text name="text_box2">
+		Outros
+	</text>
+	<text name="text_box3">
+		Objetos
+	</text>
+	<text name="text_box4">
+		Sistema
+	</text>
+	<text name="text_box5">
+		Erros
+	</text>
+	<text name="text_box7">
+		Proprietário
+	</text>
+	<text name="text_box9">
+		URLs
+	</text>
+	<text name="bubble_chat">
+		Fundo do balão:
+	</text>
+	<color_swatch name="background" tool_tip="Escolha a cor do balão de bate-papo"/>
+	<slider label="Opacidade:" name="bubble_chat_opacity"/>
+	<text name="floater_opacity">
+		Opacidade:
+	</text>
+	<slider label="Ativo:" name="active"/>
+	<slider label="Inativo:" name="inactive"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
index ea618d097d6ffb79659f8c4bc84e16c241a83577..deeb917e82d248f951a111d7a21c7ae4e914fabf 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_general.xml
@@ -48,13 +48,18 @@
 	<check_box label="Nomes de usuário" name="show_slids" tool_tip="Mostrar nome de usuário, como zecazc123"/>
 	<check_box label="Cargos do grupo" name="show_all_title_checkbox1" tool_tip="Mostrar os títulos de cargos, como membro ou diretor"/>
 	<check_box label="Realçar amigos" name="show_friends" tool_tip="Realçar nomes de tela de amigos"/>
-	<text name="effects_color_textbox">
-		Meus efeitos:
+	<check_box label="Ver nomes de tela" name="display_names_check" tool_tip="Usar nome de tela no bate-papo, MI, etc."/>
+	<check_box label="Exibir dicas da interface" name="viewer_hints_check"/>
+	<text name="inworld_typing_rg_label">
+		Teclas de letras:
 	</text>
+	<radio_group name="inworld_typing_preference">
+		<radio_item label="Inicia o bate-papo local" name="radio_start_chat" value="1"/>
+		<radio_item label="Afeta o movimento (ex.: WASD)" name="radio_move" value="0"/>
+	</radio_group>
 	<text name="title_afk_text">
 		Entrar no modo ausente em:
 	</text>
-	<color_swatch label="" name="effect_color_swatch" tool_tip="Clique para abrir o seletor de cores"/>
 	<combo_box label="Entrar no modo ausente em:" name="afk">
 		<combo_box.item label="2 minutos" name="item0"/>
 		<combo_box.item label="5 minutos" name="item1"/>
@@ -62,7 +67,6 @@
 		<combo_box.item label="30 minutos" name="item3"/>
 		<combo_box.item label="(nunca)" name="item4"/>
 	</combo_box>
-	<check_box label="Ver nomes de tela" name="display_names_check" tool_tip="Usar nome de tela no bate-papo, MI, etc."/>
 	<text name="text_box3">
 		Mensagem do modo ocupado:
 	</text>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
index 912eea13b8a183cd1039a4d073e70de89d9bf606..c2efbf03003fe3ca556e2b5b98cfe90d080c9063 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_graphics1.xml
@@ -26,6 +26,7 @@ rápido
 		<text name="ShadersText">
 			Sombreadores:
 		</text>
+		<check_box initial_value="verdadeiro" label="Água transparente" name="TransparentWater"/>
 		<check_box initial_value="true" label="Bump de Mapeamento e Brilho" name="BumpShiny"/>
 		<check_box initial_value="true" label="Sombreadores básicos" name="BasicShaders" tool_tip="Desabilitar esta opção poderá impedir que alguns drivers de placa de vídeo a travem."/>
 		<check_box initial_value="true" label="Sombreadores Atmosféricos" name="WindLightUseAtmosShaders"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_move.xml b/indra/newview/skins/default/xui/pt/panel_preferences_move.xml
new file mode 100644
index 0000000000000000000000000000000000000000..1a4c27182736133a919f2d14ca71d85430d24f0e
--- /dev/null
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_move.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes"?>
+<panel label="Movimentar" name="move_panel">
+	<slider label="Ângulo de visão" name="camera_fov"/>
+	<slider label="Distância" name="camera_offset_scale"/>
+	<text name="heading2">
+		Posicionamento automático:
+	</text>
+	<check_box label="Construir/Editar" name="edit_camera_movement" tool_tip="Use o posicionamento automático da câmera quando entrar e sair do modo de edição"/>
+	<check_box label="Aparência" name="appearance_camera_movement" tool_tip="Use o posicionamento automático da câmera quando em modo de edição"/>
+	<check_box initial_value="verdadeiro" label="Barra lateral" name="appearance_sidebar_positioning" tool_tip="Usar posicionamento automático da câmera na barra lateral"/>
+	<check_box label="Mostre-me em visão de mouse" name="first_person_avatar_visible"/>
+	<text name=" Mouse Sensitivity">
+		Sensibilidade do mouse:
+	</text>
+	<check_box label="Inverter" name="invert_mouse"/>
+	<check_box label="Teclas de seta sempre me movem" name="arrow_keys_move_avatar_check"/>
+	<check_box label="Dê dois toques e pressione para correr" name="tap_tap_hold_to_run"/>
+	<check_box label="Dar dois cliques para:" name="double_click_chkbox"/>
+	<radio_group name="double_click_action">
+		<radio_item label="Teletransportar" name="radio_teleport"/>
+		<radio_item label="Piloto automático" name="radio_autopilot"/>
+	</radio_group>
+	<button label="Outros dispositivos" name="joystick_setup_button"/>
+</panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/pt/panel_preferences_privacy.xml
index ba4ebdb9bffe70c1d3a3af1882150713e65b27f3..5545dcda388bbd18cdd04091d531c2ec8f5a7220 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_privacy.xml
@@ -10,17 +10,20 @@
 	<check_box label="Apenas amigos e grupos sabem que estou online" name="online_visibility"/>
 	<check_box label="Apenas amigos e grupos podem me chamar ou enviar MI" name="voice_call_friends_only_check"/>
 	<check_box label="Desligar o microfone quando terminar chamadas" name="auto_disengage_mic_check"/>
-	<check_box label="Aceitar  cookies" name="cookies_enabled"/>
 	<text name="Logs:">
-		Logs:
+		Registro de bate-papos:
 	</text>
 	<check_box label="Salvar logs de bate- papo das proximidades no meu computador" name="log_nearby_chat"/>
 	<check_box label="Salvar logs de MI no meu computador" name="log_instant_messages"/>
-	<check_box label="Adicionar timestamp" name="show_timestamps_check_im"/>
+	<check_box label="Anotar horas de cada linha de bate-papo" name="show_timestamps_check_im"/>
+	<check_box label="Anotar a data ao arquivo." name="logfile_name_datestamp"/>
 	<text name="log_path_desc">
 		Localização dos logs:
 	</text>
 	<line_editor left="278" name="log_path_string" right="-20"/>
 	<button label="Procurar" label_selected="Procurar" name="log_path_button" width="120"/>
 	<button label="Lista de bloqueados" name="block_list"/>
+	<text name="block_list_label">
+		(Pessoas ou objetos que você bloqueou)
+	</text>
 </panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
index deb8573ba3fb7c32a94dbff88bf93a816b2fe862..0c6fb68140b0e6a81a196ff58d4513d437f553e5 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_setup.xml
@@ -1,12 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Configurações" name="Input panel">
-	<text name="Mouselook:">
-		Visão subjetiva:
-	</text>
-	<text name=" Mouse Sensitivity">
-		Sensibilidade do mouse
-	</text>
-	<check_box label="Inverter" name="invert_mouse"/>
 	<text name="Network:">
 		Rede:
 	</text>
@@ -46,4 +39,5 @@
 	</text>
 	<line_editor name="web_proxy_editor" tool_tip="O nome ou endereço IP do proxy da sua preferência"/>
 	<spinner label="Porta:" name="web_proxy_port"/>
+	<check_box initial_value="verdadeiro" label="Baixar e instalar atualizações [APP_NAME] automaticamente" name="updater_service_active"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml b/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml
index 5be07f4d1f9abe710b2fcffa3234470a92f59b35..60f51c33e5c8f5cc2106b4a6f77456672d60f736 100644
--- a/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml
+++ b/indra/newview/skins/default/xui/pt/panel_preferences_sound.xml
@@ -1,5 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel label="Sons" name="Preference Media panel">
+	<panel.string name="middle_mouse">
+		Botão do meio do mouse
+	</panel.string>
 	<slider label="Volume principal" name="System Volume"/>
 	<check_box initial_value="true" label="Silenciar ao minimizar" name="mute_when_minimized"/>
 	<slider label="Botões" name="UI Volume"/>
@@ -23,6 +26,11 @@
 		<radio_item label="Posição de câmera" name="0"/>
 		<radio_item label="Posição do avatar" name="1"/>
 	</radio_group>
+	<check_box label="Mover os lábios do avatar quando estiver falando" name="enable_lip_sync"/>
+	<check_box label="Tecla liga/desliga da minha voz:" name="push_to_talk_toggle_check" tool_tip="Quando em modo de alternância, pressione e solte o botão UMA vez para ligar e desligar o microfone. Fora do modo de alternância, o microfone só transmite sua voz enquanto o botão estiver pressionado."/>
+	<line_editor label="Botão apertar e falar" name="modifier_combo"/>
+	<button label="Definir chave" name="set_voice_hotkey_button"/>
+	<button name="set_voice_middlemouse_button" tool_tip="Redefinir como botão do meio do mouse"/>
 	<button label="Controles de entrada/saída" name="device_settings_btn" width="180"/>
 	<panel label="Configuração dos dispositivo" name="device_settings_panel">
 		<panel.string name="default_text">
diff --git a/indra/newview/skins/default/xui/pt/panel_profile.xml b/indra/newview/skins/default/xui/pt/panel_profile.xml
index e4200ae5dacac964b1fd2e3ad3f688f751b37a01..f984ed6a7be3268213d8930a5fc7c0927691543e 100644
--- a/indra/newview/skins/default/xui/pt/panel_profile.xml
+++ b/indra/newview/skins/default/xui/pt/panel_profile.xml
@@ -53,7 +53,7 @@
 					<button label="Teletransportar" name="teleport" tool_tip="Oferecer teletransporte"/>
 				</layout_panel>
 				<layout_panel name="overflow_btn_lp">
-					<button label="▼" name="overflow_btn" tool_tip="Pagar ou compartilhar inventário com o residente"/>
+					<menu_button label="▼" name="overflow_btn" tool_tip="Pagar ou compartilhar inventário com o residente"/>
 				</layout_panel>
 			</layout_stack>
 		</layout_panel>
diff --git a/indra/newview/skins/default/xui/pt/panel_script_ed.xml b/indra/newview/skins/default/xui/pt/panel_script_ed.xml
index 6f022945c2fafde43310d94fd8d664cf8d24ac20..563f4fe054c81d5d1fffc48c6fddafa9bf7ecae6 100644
--- a/indra/newview/skins/default/xui/pt/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/pt/panel_script_ed.xml
@@ -15,11 +15,6 @@
 	<panel.string name="Title">
 		Script: [NOME]
 	</panel.string>
-	<text_editor name="Script Editor">
-		Carregando...
-	</text_editor>
-	<button label="Salvar" label_selected="Salvar" name="Save_btn"/>
-	<combo_box label="Inserir..." name="Insert..."/>
 	<menu_bar name="script_menu">
 		<menu label="Arquivo" name="File">
 			<menu_item_call label="Salvar" name="Save"/>
@@ -40,4 +35,10 @@
 			<menu_item_call label="ajuda palavra- chave..." name="Keyword Help..."/>
 		</menu>
 	</menu_bar>
+	<text_editor name="Script Editor">
+		Carregando...
+	</text_editor>
+	<combo_box label="Inserir..." name="Insert..."/>
+	<button label="Salvar" label_selected="Salvar" name="Save_btn"/>
+	<button label="Editar..." name="Edit_btn"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/pt/strings.xml b/indra/newview/skins/default/xui/pt/strings.xml
index 59c6c8f080f918092f6868849413beeac59c48eb..ce2c2ddaa13f09cc3a604e17ca7931c4fea8394f 100644
--- a/indra/newview/skins/default/xui/pt/strings.xml
+++ b/indra/newview/skins/default/xui/pt/strings.xml
@@ -1740,11 +1740,8 @@
 	<string name="InvOfferGaveYou">
 		deu a você
 	</string>
-	<string name="InvOfferYouDecline">
-		Você recusa
-	</string>
-	<string name="InvOfferFrom">
-		de
+	<string name="InvOfferDecline">
+		Você recusou um(a) [DESC] de &lt;nolink&gt;[NAME]&lt;/nolink&gt;.
 	</string>
 	<string name="GroupMoneyTotal">
 		Total
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index db50b896204988faff21ca5d606e97d086bcc715..9e321db889941a0054cf133c03c2ba66ac8e582a 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -40,6 +40,7 @@
 
 #if defined(LL_WINDOWS)
 #pragma warning(disable: 4355)      // using 'this' in base-class ctor initializer expr
+#pragma warning(disable: 4702)      // disable 'unreachable code' so we can safely use skip().
 #endif
 
 // Constants
@@ -48,6 +49,9 @@ const std::string VIEWERLOGIN_GRIDLABEL("viewerlogin_grid");
 
 const std::string APPVIEWER_SERIALNUMBER("appviewer_serialno");
 
+const std::string VIEWERLOGIN_CHANNEL("invalid_channel");
+const std::string VIEWERLOGIN_VERSION_CHANNEL("invalid_version");
+
 // Link seams.
 
 //-----------------------------------------------------------------------------
@@ -65,6 +69,7 @@ static bool gDisconnectCalled = false;
 
 #include "../llviewerwindow.h"
 void LLViewerWindow::setShowProgress(BOOL show) {}
+LLProgressView * LLViewerWindow::getProgressView(void) const { return 0; }
 
 LLViewerWindow* gViewerWindow;
 
@@ -160,7 +165,6 @@ std::string LLGridManager::getAppSLURLBase(const std::string& grid_name)
 //-----------------------------------------------------------------------------
 #include "../llviewercontrol.h"
 LLControlGroup gSavedSettings("Global");
-std::string gCurrentVersion = "invalid_version";
 
 LLControlGroup::LLControlGroup(const std::string& name) :
 	LLInstanceTracker<LLControlGroup, std::string>(name){}
@@ -177,6 +181,45 @@ BOOL LLControlGroup::declareString(const std::string& name, const std::string &i
 #include "lluicolortable.h"
 void LLUIColorTable::saveUserSettings(void)const {}
 
+//-----------------------------------------------------------------------------
+#include "../llversioninfo.h"
+const std::string &LLVersionInfo::getChannelAndVersion() { return VIEWERLOGIN_VERSION_CHANNEL; }
+const std::string &LLVersionInfo::getChannel() { return VIEWERLOGIN_CHANNEL; }
+
+//-----------------------------------------------------------------------------
+#include "../llappviewer.h"
+void LLAppViewer::forceQuit(void) {}
+LLAppViewer * LLAppViewer::sInstance = 0;
+
+//-----------------------------------------------------------------------------
+#include "llnotificationsutil.h"
+LLNotificationPtr LLNotificationsUtil::add(const std::string& name, 
+					  const LLSD& substitutions, 
+					  const LLSD& payload, 
+					  boost::function<void (const LLSD&, const LLSD&)> functor) { return LLNotificationPtr((LLNotification*)0); }
+
+
+//-----------------------------------------------------------------------------
+#include "llupdaterservice.h"
+
+std::string const & LLUpdaterService::pumpName(void)
+{
+	static std::string wakka = "wakka wakka wakka";
+	return wakka;
+}
+bool LLUpdaterService::updateReadyToInstall(void) { return false; }
+void LLUpdaterService::initialize(const std::string& protocol_version,
+				const std::string& url, 
+				const std::string& path,
+				const std::string& channel,
+								  const std::string& version) {}
+
+void LLUpdaterService::setCheckPeriod(unsigned int seconds) {}
+void LLUpdaterService::startChecking(bool install_if_ready) {}
+void LLUpdaterService::stopChecking() {}
+bool LLUpdaterService::isChecking() { return false; }
+LLUpdaterService::eUpdaterState LLUpdaterService::getState() { return INITIAL; }
+std::string LLUpdaterService::updatedVersion() { return ""; }
 
 //-----------------------------------------------------------------------------
 #include "llnotifications.h"
@@ -192,6 +235,12 @@ LLFloater* LLFloaterReg::showInstance(const std::string& name, const LLSD& key,
 	return NULL;
 }
 
+//----------------------------------------------------------------------------
+#include "../llprogressview.h"
+void LLProgressView::setText(std::string const &){}
+void LLProgressView::setPercent(float){}
+void LLProgressView::setMessage(std::string const &){}
+
 //-----------------------------------------------------------------------------
 // LLNotifications
 class MockNotifications : public LLNotificationsInterface
@@ -290,7 +339,6 @@ namespace tut
 			gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE);
 			gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE);
 			gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE);
-			gSavedSettings.declareString("VersionChannelName", "test_version_string", "", FALSE);
 			gSavedSettings.declareString("NextLoginLocation", "", "", FALSE);
 			gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE);
 
@@ -430,6 +478,8 @@ namespace tut
     template<> template<>
     void lllogininstance_object::test<3>()
     {
+		skip();
+		
 		set_test_name("Test Mandatory Update User Accepts");
 
 		// Part 1 - Mandatory Update, with User accepts response.
@@ -457,6 +507,8 @@ namespace tut
 	template<> template<>
     void lllogininstance_object::test<4>()
     {
+		skip();
+		
 		set_test_name("Test Mandatory Update User Decline");
 
 		// Test connect with update needed.
diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a6c1f69c82a4784958da65c248613f320117ae61
--- /dev/null
+++ b/indra/newview/tests/llremoteparcelrequest_test.cpp
@@ -0,0 +1,134 @@
+/** 
+ * @file llremoteparcelrequest_test.cpp
+ * @author Brad Kittenbrink <brad@lindenlab.com>
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "../test/lltut.h"
+
+#include "../llremoteparcelrequest.h"
+
+#include "../llagent.h"
+#include "message.h"
+
+namespace {
+	LLControlGroup s_saved_settings("dummy_settings");
+	const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111");
+}
+
+LLCurl::Responder::Responder() { }
+LLCurl::Responder::~Responder() { }
+void LLCurl::Responder::error(U32,std::string const &) { }
+void LLCurl::Responder::result(LLSD const &) { }
+void LLCurl::Responder::errorWithContent(U32 status,std::string const &,LLSD const &) { }
+void LLCurl::Responder::completedRaw(U32 status, std::string const &, LLChannelDescriptors const &,boost::shared_ptr<LLBufferArray> const &) { }
+void LLCurl::Responder::completed(U32 status, std::string const &, LLSD const &) { }
+void LLCurl::Responder::completedHeader(U32 status, std::string const &, LLSD const &) { }
+void LLMessageSystem::getF32(char const *,char const *,F32 &,S32) { }
+void LLMessageSystem::getU8(char const *,char const *,U8 &,S32) { }
+void LLMessageSystem::getS32(char const *,char const *,S32 &,S32) { }
+void LLMessageSystem::getString(char const *,char const *, std::string &,S32) { }
+void LLMessageSystem::getUUID(char const *,char const *, LLUUID & out_id,S32)
+{
+	out_id = TEST_PARCEL_ID;
+}
+void LLMessageSystem::nextBlock(char const *) { }
+void LLMessageSystem::addUUID(char const *,LLUUID const &) { }
+void LLMessageSystem::addUUIDFast(char const *,LLUUID const &) { }
+void LLMessageSystem::nextBlockFast(char const *) { }
+void LLMessageSystem::newMessage(char const *) { }
+LLMessageSystem * gMessageSystem;
+char * _PREHASH_AgentID;
+char * _PREHASH_AgentData;
+LLAgent gAgent;
+LLAgent::LLAgent() : mAgentAccess(s_saved_settings) { }
+LLAgent::~LLAgent() { }
+void LLAgent::sendReliableMessage(void) { }
+LLUUID gAgentSessionID;
+LLUUID gAgentID;
+LLUIColor::LLUIColor(void) { }
+LLAgentAccess::LLAgentAccess(LLControlGroup & settings) : mSavedSettings(settings) { }
+LLControlGroup::LLControlGroup(std::string const & name) : LLInstanceTracker<LLControlGroup, std::string>(name) { }
+LLControlGroup::~LLControlGroup(void) { }
+
+namespace tut
+{
+	struct TestObserver : public LLRemoteParcelInfoObserver {
+		TestObserver() : mProcessed(false) { }
+
+		virtual void processParcelInfo(const LLParcelData& parcel_data)
+		{
+			mProcessed = true;
+		}
+
+		virtual void setParcelID(const LLUUID& parcel_id) { }
+
+		virtual void setErrorStatus(U32 status, const std::string& reason) { }
+
+		bool mProcessed;
+	};
+
+    struct RemoteParcelRequestData
+    {
+		RemoteParcelRequestData()
+		{
+		}
+    };
+    
+	typedef test_group<RemoteParcelRequestData> remoteparcelrequest_t;
+	typedef remoteparcelrequest_t::object remoteparcelrequest_object_t;
+	tut::remoteparcelrequest_t tut_remoteparcelrequest("LLRemoteParcelRequest");
+
+	template<> template<>
+	void remoteparcelrequest_object_t::test<1>()
+	{
+		set_test_name("observer pointer");
+
+		boost::scoped_ptr<TestObserver> observer(new TestObserver());
+
+		LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance();
+		processor.addObserver(LLUUID(TEST_PARCEL_ID), observer.get());
+
+		processor.processParcelInfoReply(gMessageSystem, NULL);
+
+		ensure(observer->mProcessed);
+	}
+
+	template<> template<>
+	void remoteparcelrequest_object_t::test<2>()
+	{
+		set_test_name("CHOP-220: dangling observer pointer");
+
+		LLRemoteParcelInfoObserver * observer = new TestObserver();
+
+		LLRemoteParcelInfoProcessor & processor = LLRemoteParcelInfoProcessor::instance();
+		processor.addObserver(LLUUID(TEST_PARCEL_ID), observer);
+
+		delete observer;
+		observer = NULL;
+
+		processor.processParcelInfoReply(gMessageSystem, NULL);
+	}
+}
diff --git a/indra/newview/tests/llsimplestat_test.cpp b/indra/newview/tests/llsimplestat_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..60a8cac995ba1ad1f280c21406a45f44b50f73d1
--- /dev/null
+++ b/indra/newview/tests/llsimplestat_test.cpp
@@ -0,0 +1,586 @@
+/** 
+ * @file llsimplestats_test.cpp
+ * @date 2010-10-22
+ * @brief Test cases for some of llsimplestat.h
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include <tut/tut.hpp>
+
+#include "lltut.h"
+#include "../llsimplestat.h"
+#include "llsd.h"
+#include "llmath.h"
+
+// @brief Used as a pointer cast type to get access to LLSimpleStatCounter
+class TutStatCounter: public LLSimpleStatCounter
+{
+public:
+	TutStatCounter();							// Not defined
+	~TutStatCounter();							// Not defined
+	void operator=(const TutStatCounter &);		// Not defined
+	
+	void setRawCount(U32 c)				{ mCount = c; }
+	U32 getRawCount() const				{ return mCount; }
+};
+
+
+namespace tut
+{
+	struct stat_counter_index
+	{};
+	typedef test_group<stat_counter_index> stat_counter_index_t;
+	typedef stat_counter_index_t::object stat_counter_index_object_t;
+	tut::stat_counter_index_t tut_stat_counter_index("stat_counter_test");
+
+	// Testing LLSimpleStatCounter's external interface
+	template<> template<>
+	void stat_counter_index_object_t::test<1>()
+	{
+		LLSimpleStatCounter c1;
+		ensure("Initialized counter is zero", (0 == c1.getCount()));
+
+		ensure("Counter increment return is 1", (1 == ++c1));
+		ensure("Counter increment return is 2", (2 == ++c1));
+
+		ensure("Current counter is 2", (2 == c1.getCount()));
+
+		c1.reset();
+		ensure("Counter is 0 after reset", (0 == c1.getCount()));
+		
+		ensure("Counter increment return is 1", (1 == ++c1));
+	}
+
+	// Testing LLSimpleStatCounter's internal state
+	template<> template<>
+	void stat_counter_index_object_t::test<2>()
+	{
+		LLSimpleStatCounter c1;
+		TutStatCounter * tc1 = (TutStatCounter *) &c1;
+		
+		ensure("Initialized private counter is zero", (0 == tc1->getRawCount()));
+
+		++c1;
+		++c1;
+		
+		ensure("Current private counter is 2", (2 == tc1->getRawCount()));
+
+		c1.reset();
+		ensure("Raw counter is 0 after reset", (0 == tc1->getRawCount()));
+	}
+
+	// Testing LLSimpleStatCounter's wrapping behavior
+	template<> template<>
+	void stat_counter_index_object_t::test<3>()
+	{
+		LLSimpleStatCounter c1;
+		TutStatCounter * tc1 = (TutStatCounter *) &c1;
+
+		tc1->setRawCount(U32_MAX);
+		ensure("Initialized private counter is zero", (U32_MAX == c1.getCount()));
+
+		ensure("Increment of max value wraps to 0", (0 == ++c1));
+	}
+
+	// Testing LLSimpleStatMMM's external behavior
+	template<> template<>
+	void stat_counter_index_object_t::test<4>()
+	{
+		LLSimpleStatMMM<> m1;
+		typedef LLSimpleStatMMM<>::Value lcl_float;
+		lcl_float zero(0);
+
+		// Freshly-constructed
+		ensure("Constructed MMM<> has 0 count", (0 == m1.getCount()));
+		ensure("Constructed MMM<> has 0 min", (zero == m1.getMin()));
+		ensure("Constructed MMM<> has 0 max", (zero == m1.getMax()));
+		ensure("Constructed MMM<> has 0 mean no div-by-zero", (zero == m1.getMean()));
+
+		// Single insert
+		m1.record(1.0);
+		ensure("Single insert MMM<> has 1 count", (1 == m1.getCount()));
+		ensure("Single insert MMM<> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("Single insert MMM<> has 1.0 max", (1.0 == m1.getMax()));
+		ensure("Single insert MMM<> has 1.0 mean", (1.0 == m1.getMean()));
+		
+		// Second insert
+		m1.record(3.0);
+		ensure("2nd insert MMM<> has 2 count", (2 == m1.getCount()));
+		ensure("2nd insert MMM<> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("2nd insert MMM<> has 3.0 max", (3.0 == m1.getMax()));
+		ensure_approximately_equals("2nd insert MMM<> has 2.0 mean", m1.getMean(), lcl_float(2.0), 1);
+
+		// Third insert
+		m1.record(5.0);
+		ensure("3rd insert MMM<> has 3 count", (3 == m1.getCount()));
+		ensure("3rd insert MMM<> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("3rd insert MMM<> has 5.0 max", (5.0 == m1.getMax()));
+		ensure_approximately_equals("3rd insert MMM<> has 3.0 mean", m1.getMean(), lcl_float(3.0), 1);
+
+		// Fourth insert
+		m1.record(1000000.0);
+		ensure("4th insert MMM<> has 4 count", (4 == m1.getCount()));
+		ensure("4th insert MMM<> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("4th insert MMM<> has 100000.0 max", (1000000.0 == m1.getMax()));
+		ensure_approximately_equals("4th insert MMM<> has 250002.0 mean", m1.getMean(), lcl_float(250002.0), 1);
+
+		// Reset
+		m1.reset();
+		ensure("Reset MMM<> has 0 count", (0 == m1.getCount()));
+		ensure("Reset MMM<> has 0 min", (zero == m1.getMin()));
+		ensure("Reset MMM<> has 0 max", (zero == m1.getMax()));
+		ensure("Reset MMM<> has 0 mean no div-by-zero", (zero == m1.getMean()));
+	}
+
+	// Testing LLSimpleStatMMM's response to large values
+	template<> template<>
+	void stat_counter_index_object_t::test<5>()
+	{
+		LLSimpleStatMMM<> m1;
+		typedef LLSimpleStatMMM<>::Value lcl_float;
+		lcl_float zero(0);
+
+		// Insert overflowing values
+		const lcl_float bignum(F32_MAX / 2);
+
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(zero);
+
+		ensure("Overflowed MMM<> has 8 count", (8 == m1.getCount()));
+		ensure("Overflowed MMM<> has 0 min", (zero == m1.getMin()));
+		ensure("Overflowed MMM<> has huge max", (bignum == m1.getMax()));
+		ensure("Overflowed MMM<> has fetchable mean", (1.0 == m1.getMean() || true));
+		// We should be infinte but not interested in proving the IEEE standard here.
+		LLSD sd1(m1.getMean());
+		// std::cout << "Thingy:  " << m1.getMean() << " and as LLSD:  " << sd1 << std::endl;
+		ensure("Overflowed MMM<> produces LLSDable Real", (sd1.isReal()));
+	}
+
+	// Testing LLSimpleStatMMM<F32>'s external behavior
+	template<> template<>
+	void stat_counter_index_object_t::test<6>()
+	{
+		LLSimpleStatMMM<F32> m1;
+		typedef LLSimpleStatMMM<F32>::Value lcl_float;
+		lcl_float zero(0);
+
+		// Freshly-constructed
+		ensure("Constructed MMM<F32> has 0 count", (0 == m1.getCount()));
+		ensure("Constructed MMM<F32> has 0 min", (zero == m1.getMin()));
+		ensure("Constructed MMM<F32> has 0 max", (zero == m1.getMax()));
+		ensure("Constructed MMM<F32> has 0 mean no div-by-zero", (zero == m1.getMean()));
+
+		// Single insert
+		m1.record(1.0);
+		ensure("Single insert MMM<F32> has 1 count", (1 == m1.getCount()));
+		ensure("Single insert MMM<F32> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("Single insert MMM<F32> has 1.0 max", (1.0 == m1.getMax()));
+		ensure("Single insert MMM<F32> has 1.0 mean", (1.0 == m1.getMean()));
+		
+		// Second insert
+		m1.record(3.0);
+		ensure("2nd insert MMM<F32> has 2 count", (2 == m1.getCount()));
+		ensure("2nd insert MMM<F32> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("2nd insert MMM<F32> has 3.0 max", (3.0 == m1.getMax()));
+		ensure_approximately_equals("2nd insert MMM<F32> has 2.0 mean", m1.getMean(), lcl_float(2.0), 1);
+
+		// Third insert
+		m1.record(5.0);
+		ensure("3rd insert MMM<F32> has 3 count", (3 == m1.getCount()));
+		ensure("3rd insert MMM<F32> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("3rd insert MMM<F32> has 5.0 max", (5.0 == m1.getMax()));
+		ensure_approximately_equals("3rd insert MMM<F32> has 3.0 mean", m1.getMean(), lcl_float(3.0), 1);
+
+		// Fourth insert
+		m1.record(1000000.0);
+		ensure("4th insert MMM<F32> has 4 count", (4 == m1.getCount()));
+		ensure("4th insert MMM<F32> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("4th insert MMM<F32> has 1000000.0 max", (1000000.0 == m1.getMax()));
+		ensure_approximately_equals("4th insert MMM<F32> has 250002.0 mean", m1.getMean(), lcl_float(250002.0), 1);
+
+		// Reset
+		m1.reset();
+		ensure("Reset MMM<F32> has 0 count", (0 == m1.getCount()));
+		ensure("Reset MMM<F32> has 0 min", (zero == m1.getMin()));
+		ensure("Reset MMM<F32> has 0 max", (zero == m1.getMax()));
+		ensure("Reset MMM<F32> has 0 mean no div-by-zero", (zero == m1.getMean()));
+	}
+
+	// Testing LLSimpleStatMMM's response to large values
+	template<> template<>
+	void stat_counter_index_object_t::test<7>()
+	{
+		LLSimpleStatMMM<F32> m1;
+		typedef LLSimpleStatMMM<F32>::Value lcl_float;
+		lcl_float zero(0);
+
+		// Insert overflowing values
+		const lcl_float bignum(F32_MAX / 2);
+
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(zero);
+
+		ensure("Overflowed MMM<F32> has 8 count", (8 == m1.getCount()));
+		ensure("Overflowed MMM<F32> has 0 min", (zero == m1.getMin()));
+		ensure("Overflowed MMM<F32> has huge max", (bignum == m1.getMax()));
+		ensure("Overflowed MMM<F32> has fetchable mean", (1.0 == m1.getMean() || true));
+		// We should be infinte but not interested in proving the IEEE standard here.
+		LLSD sd1(m1.getMean());
+		// std::cout << "Thingy:  " << m1.getMean() << " and as LLSD:  " << sd1 << std::endl;
+		ensure("Overflowed MMM<F32> produces LLSDable Real", (sd1.isReal()));
+	}
+
+	// Testing LLSimpleStatMMM<F64>'s external behavior
+	template<> template<>
+	void stat_counter_index_object_t::test<8>()
+	{
+		LLSimpleStatMMM<F64> m1;
+		typedef LLSimpleStatMMM<F64>::Value lcl_float;
+		lcl_float zero(0);
+
+		// Freshly-constructed
+		ensure("Constructed MMM<F64> has 0 count", (0 == m1.getCount()));
+		ensure("Constructed MMM<F64> has 0 min", (zero == m1.getMin()));
+		ensure("Constructed MMM<F64> has 0 max", (zero == m1.getMax()));
+		ensure("Constructed MMM<F64> has 0 mean no div-by-zero", (zero == m1.getMean()));
+
+		// Single insert
+		m1.record(1.0);
+		ensure("Single insert MMM<F64> has 1 count", (1 == m1.getCount()));
+		ensure("Single insert MMM<F64> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("Single insert MMM<F64> has 1.0 max", (1.0 == m1.getMax()));
+		ensure("Single insert MMM<F64> has 1.0 mean", (1.0 == m1.getMean()));
+		
+		// Second insert
+		m1.record(3.0);
+		ensure("2nd insert MMM<F64> has 2 count", (2 == m1.getCount()));
+		ensure("2nd insert MMM<F64> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("2nd insert MMM<F64> has 3.0 max", (3.0 == m1.getMax()));
+		ensure_approximately_equals("2nd insert MMM<F64> has 2.0 mean", m1.getMean(), lcl_float(2.0), 1);
+
+		// Third insert
+		m1.record(5.0);
+		ensure("3rd insert MMM<F64> has 3 count", (3 == m1.getCount()));
+		ensure("3rd insert MMM<F64> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("3rd insert MMM<F64> has 5.0 max", (5.0 == m1.getMax()));
+		ensure_approximately_equals("3rd insert MMM<F64> has 3.0 mean", m1.getMean(), lcl_float(3.0), 1);
+
+		// Fourth insert
+		m1.record(1000000.0);
+		ensure("4th insert MMM<F64> has 4 count", (4 == m1.getCount()));
+		ensure("4th insert MMM<F64> has 1.0 min", (1.0 == m1.getMin()));
+		ensure("4th insert MMM<F64> has 1000000.0 max", (1000000.0 == m1.getMax()));
+		ensure_approximately_equals("4th insert MMM<F64> has 250002.0 mean", m1.getMean(), lcl_float(250002.0), 1);
+
+		// Reset
+		m1.reset();
+		ensure("Reset MMM<F64> has 0 count", (0 == m1.getCount()));
+		ensure("Reset MMM<F64> has 0 min", (zero == m1.getMin()));
+		ensure("Reset MMM<F64> has 0 max", (zero == m1.getMax()));
+		ensure("Reset MMM<F64> has 0 mean no div-by-zero", (zero == m1.getMean()));
+	}
+
+	// Testing LLSimpleStatMMM's response to large values
+	template<> template<>
+	void stat_counter_index_object_t::test<9>()
+	{
+		LLSimpleStatMMM<F64> m1;
+		typedef LLSimpleStatMMM<F64>::Value lcl_float;
+		lcl_float zero(0);
+
+		// Insert overflowing values
+		const lcl_float bignum(F64_MAX / 2);
+
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(zero);
+
+		ensure("Overflowed MMM<F64> has 8 count", (8 == m1.getCount()));
+		ensure("Overflowed MMM<F64> has 0 min", (zero == m1.getMin()));
+		ensure("Overflowed MMM<F64> has huge max", (bignum == m1.getMax()));
+		ensure("Overflowed MMM<F64> has fetchable mean", (1.0 == m1.getMean() || true));
+		// We should be infinte but not interested in proving the IEEE standard here.
+		LLSD sd1(m1.getMean());
+		// std::cout << "Thingy:  " << m1.getMean() << " and as LLSD:  " << sd1 << std::endl;
+		ensure("Overflowed MMM<F64> produces LLSDable Real", (sd1.isReal()));
+	}
+
+	// Testing LLSimpleStatMMM<U64>'s external behavior
+	template<> template<>
+	void stat_counter_index_object_t::test<10>()
+	{
+		LLSimpleStatMMM<U64> m1;
+		typedef LLSimpleStatMMM<U64>::Value lcl_int;
+		lcl_int zero(0);
+
+		// Freshly-constructed
+		ensure("Constructed MMM<U64> has 0 count", (0 == m1.getCount()));
+		ensure("Constructed MMM<U64> has 0 min", (zero == m1.getMin()));
+		ensure("Constructed MMM<U64> has 0 max", (zero == m1.getMax()));
+		ensure("Constructed MMM<U64> has 0 mean no div-by-zero", (zero == m1.getMean()));
+
+		// Single insert
+		m1.record(1);
+		ensure("Single insert MMM<U64> has 1 count", (1 == m1.getCount()));
+		ensure("Single insert MMM<U64> has 1 min", (1 == m1.getMin()));
+		ensure("Single insert MMM<U64> has 1 max", (1 == m1.getMax()));
+		ensure("Single insert MMM<U64> has 1 mean", (1 == m1.getMean()));
+		
+		// Second insert
+		m1.record(3);
+		ensure("2nd insert MMM<U64> has 2 count", (2 == m1.getCount()));
+		ensure("2nd insert MMM<U64> has 1 min", (1 == m1.getMin()));
+		ensure("2nd insert MMM<U64> has 3 max", (3 == m1.getMax()));
+		ensure("2nd insert MMM<U64> has 2 mean", (2 == m1.getMean()));
+
+		// Third insert
+		m1.record(5);
+		ensure("3rd insert MMM<U64> has 3 count", (3 == m1.getCount()));
+		ensure("3rd insert MMM<U64> has 1 min", (1 == m1.getMin()));
+		ensure("3rd insert MMM<U64> has 5 max", (5 == m1.getMax()));
+		ensure("3rd insert MMM<U64> has 3 mean", (3 == m1.getMean()));
+
+		// Fourth insert
+		m1.record(U64L(1000000000000));
+		ensure("4th insert MMM<U64> has 4 count", (4 == m1.getCount()));
+		ensure("4th insert MMM<U64> has 1 min", (1 == m1.getMin()));
+		ensure("4th insert MMM<U64> has 1000000000000ULL max", (U64L(1000000000000) == m1.getMax()));
+		ensure("4th insert MMM<U64> has 250000000002ULL mean", (U64L( 250000000002) == m1.getMean()));
+
+		// Reset
+		m1.reset();
+		ensure("Reset MMM<U64> has 0 count", (0 == m1.getCount()));
+		ensure("Reset MMM<U64> has 0 min", (zero == m1.getMin()));
+		ensure("Reset MMM<U64> has 0 max", (zero == m1.getMax()));
+		ensure("Reset MMM<U64> has 0 mean no div-by-zero", (zero == m1.getMean()));
+	}
+
+	// Testing LLSimpleStatMMM's response to large values
+	template<> template<>
+	void stat_counter_index_object_t::test<11>()
+	{
+		LLSimpleStatMMM<U64> m1;
+		typedef LLSimpleStatMMM<U64>::Value lcl_int;
+		lcl_int zero(0);
+
+		// Insert overflowing values
+		const lcl_int bignum(U64L(0xffffffffffffffff) / 2);
+
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(bignum);
+		m1.record(zero);
+
+		ensure("Overflowed MMM<U64> has 8 count", (8 == m1.getCount()));
+		ensure("Overflowed MMM<U64> has 0 min", (zero == m1.getMin()));
+		ensure("Overflowed MMM<U64> has huge max", (bignum == m1.getMax()));
+		ensure("Overflowed MMM<U64> has fetchable mean", (zero == m1.getMean() || true));
+	}
+
+    // Testing LLSimpleStatCounter's merge() method
+	template<> template<>
+	void stat_counter_index_object_t::test<12>()
+	{
+		LLSimpleStatCounter c1;
+		LLSimpleStatCounter c2;
+
+		++c1;
+		++c1;
+		++c1;
+		++c1;
+
+		++c2;
+		++c2;
+		c2.merge(c1);
+		
+		ensure_equals("4 merged into 2 results in 6", 6, c2.getCount());
+
+		ensure_equals("Source of merge is undamaged", 4, c1.getCount());
+	}
+
+    // Testing LLSimpleStatMMM's merge() method
+	template<> template<>
+	void stat_counter_index_object_t::test<13>()
+	{
+		LLSimpleStatMMM<> m1;
+		LLSimpleStatMMM<> m2;
+
+		m1.record(3.5);
+		m1.record(4.5);
+		m1.record(5.5);
+		m1.record(6.5);
+
+		m2.record(5.0);
+		m2.record(7.0);
+		m2.record(9.0);
+		
+		m2.merge(m1);
+
+		ensure_equals("Count after merge (p1)", 7, m2.getCount());
+		ensure_approximately_equals("Min after merge (p1)", F32(3.5), m2.getMin(), 22);
+		ensure_approximately_equals("Max after merge (p1)", F32(9.0), m2.getMax(), 22);
+		ensure_approximately_equals("Mean after merge (p1)", F32(41.000/7.000), m2.getMean(), 22);
+		
+
+		ensure_equals("Source count of merge is undamaged (p1)", 4, m1.getCount());
+		ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(3.5), m1.getMin(), 22);
+		ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(6.5), m1.getMax(), 22);
+		ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(5.0), m1.getMean(), 22);
+
+		m2.reset();
+
+		m2.record(-22.0);
+		m2.record(-1.0);
+		m2.record(30.0);
+		
+		m2.merge(m1);
+
+		ensure_equals("Count after merge (p2)", 7, m2.getCount());
+		ensure_approximately_equals("Min after merge (p2)", F32(-22.0), m2.getMin(), 22);
+		ensure_approximately_equals("Max after merge (p2)", F32(30.0), m2.getMax(), 22);
+		ensure_approximately_equals("Mean after merge (p2)", F32(27.000/7.000), m2.getMean(), 22);
+
+	}
+
+    // Testing LLSimpleStatMMM's merge() method when src contributes nothing
+	template<> template<>
+	void stat_counter_index_object_t::test<14>()
+	{
+		LLSimpleStatMMM<> m1;
+		LLSimpleStatMMM<> m2;
+
+		m2.record(5.0);
+		m2.record(7.0);
+		m2.record(9.0);
+		
+		m2.merge(m1);
+
+		ensure_equals("Count after merge (p1)", 3, m2.getCount());
+		ensure_approximately_equals("Min after merge (p1)", F32(5.0), m2.getMin(), 22);
+		ensure_approximately_equals("Max after merge (p1)", F32(9.0), m2.getMax(), 22);
+		ensure_approximately_equals("Mean after merge (p1)", F32(7.000), m2.getMean(), 22);
+
+		ensure_equals("Source count of merge is undamaged (p1)", 0, m1.getCount());
+		ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(0), m1.getMin(), 22);
+		ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(0), m1.getMax(), 22);
+		ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(0), m1.getMean(), 22);
+
+		m2.reset();
+
+		m2.record(-22.0);
+		m2.record(-1.0);
+		
+		m2.merge(m1);
+
+		ensure_equals("Count after merge (p2)", 2, m2.getCount());
+		ensure_approximately_equals("Min after merge (p2)", F32(-22.0), m2.getMin(), 22);
+		ensure_approximately_equals("Max after merge (p2)", F32(-1.0), m2.getMax(), 22);
+		ensure_approximately_equals("Mean after merge (p2)", F32(-11.5), m2.getMean(), 22);
+	}
+
+    // Testing LLSimpleStatMMM's merge() method when dst contributes nothing
+	template<> template<>
+	void stat_counter_index_object_t::test<15>()
+	{
+		LLSimpleStatMMM<> m1;
+		LLSimpleStatMMM<> m2;
+
+		m1.record(5.0);
+		m1.record(7.0);
+		m1.record(9.0);
+		
+		m2.merge(m1);
+
+		ensure_equals("Count after merge (p1)", 3, m2.getCount());
+		ensure_approximately_equals("Min after merge (p1)", F32(5.0), m2.getMin(), 22);
+		ensure_approximately_equals("Max after merge (p1)", F32(9.0), m2.getMax(), 22);
+		ensure_approximately_equals("Mean after merge (p1)", F32(7.000), m2.getMean(), 22);
+
+		ensure_equals("Source count of merge is undamaged (p1)", 3, m1.getCount());
+		ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(5.0), m1.getMin(), 22);
+		ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(9.0), m1.getMax(), 22);
+		ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(7.0), m1.getMean(), 22);
+
+		m1.reset();
+		m2.reset();
+		
+		m1.record(-22.0);
+		m1.record(-1.0);
+		
+		m2.merge(m1);
+
+		ensure_equals("Count after merge (p2)", 2, m2.getCount());
+		ensure_approximately_equals("Min after merge (p2)", F32(-22.0), m2.getMin(), 22);
+		ensure_approximately_equals("Max after merge (p2)", F32(-1.0), m2.getMax(), 22);
+		ensure_approximately_equals("Mean after merge (p2)", F32(-11.5), m2.getMean(), 22);
+	}
+
+    // Testing LLSimpleStatMMM's merge() method when neither dst nor src contributes
+	template<> template<>
+	void stat_counter_index_object_t::test<16>()
+	{
+		LLSimpleStatMMM<> m1;
+		LLSimpleStatMMM<> m2;
+
+		m2.merge(m1);
+
+		ensure_equals("Count after merge (p1)", 0, m2.getCount());
+		ensure_approximately_equals("Min after merge (p1)", F32(0), m2.getMin(), 22);
+		ensure_approximately_equals("Max after merge (p1)", F32(0), m2.getMax(), 22);
+		ensure_approximately_equals("Mean after merge (p1)", F32(0), m2.getMean(), 22);
+
+		ensure_equals("Source count of merge is undamaged (p1)", 0, m1.getCount());
+		ensure_approximately_equals("Source min of merge is undamaged (p1)", F32(0), m1.getMin(), 22);
+		ensure_approximately_equals("Source max of merge is undamaged (p1)", F32(0), m1.getMax(), 22);
+		ensure_approximately_equals("Source mean of merge is undamaged (p1)", F32(0), m1.getMean(), 22);
+	}
+}
diff --git a/indra/newview/tests/llversioninfo_test.cpp b/indra/newview/tests/llversioninfo_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..398d8f16ed4c2a75991d1e6db310ba0072d45cb2
--- /dev/null
+++ b/indra/newview/tests/llversioninfo_test.cpp
@@ -0,0 +1,114 @@
+/** 
+ * @file llversioninfo_test.cpp
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "../test/lltut.h"
+
+#include "../llversioninfo.h"
+#include "llversionviewer.h"
+
+namespace tut
+{
+    struct versioninfo
+    {
+		versioninfo()
+			: mResetChannel("Reset Channel")
+		{
+			std::ostringstream stream;
+			stream << LL_VERSION_MAJOR << "."
+				   << LL_VERSION_MINOR << "."
+				   << LL_VERSION_PATCH << "."
+				   << LL_VERSION_BUILD;
+			mVersion = stream.str();
+			stream.str("");
+
+			stream << LL_VERSION_MAJOR << "."
+				   << LL_VERSION_MINOR << "."
+				   << LL_VERSION_PATCH;
+			mShortVersion = stream.str();
+			stream.str("");
+
+			stream << LL_CHANNEL
+				   << " "
+				   << mVersion;
+			mVersionAndChannel = stream.str();
+			stream.str("");
+
+			stream << mResetChannel
+				   << " "
+				   << mVersion;
+			mResetVersionAndChannel = stream.str();
+		}
+		std::string mResetChannel;
+		std::string mVersion;
+		std::string mShortVersion;
+		std::string mVersionAndChannel;
+		std::string mResetVersionAndChannel;
+    };
+    
+	typedef test_group<versioninfo> versioninfo_t;
+	typedef versioninfo_t::object versioninfo_object_t;
+	tut::versioninfo_t tut_versioninfo("LLVersionInfo");
+
+	template<> template<>
+	void versioninfo_object_t::test<1>()
+	{
+		ensure_equals("Major version", 
+					  LLVersionInfo::getMajor(), 
+					  LL_VERSION_MAJOR);
+		ensure_equals("Minor version", 
+					  LLVersionInfo::getMinor(), 
+					  LL_VERSION_MINOR);
+		ensure_equals("Patch version", 
+					  LLVersionInfo::getPatch(), 
+					  LL_VERSION_PATCH);
+		ensure_equals("Build version", 
+					  LLVersionInfo::getBuild(), 
+					  LL_VERSION_BUILD);
+		ensure_equals("Channel version", 
+					  LLVersionInfo::getChannel(), 
+					  LL_CHANNEL);
+
+		ensure_equals("Version String", 
+					  LLVersionInfo::getVersion(), 
+					  mVersion);
+		ensure_equals("Short Version String", 
+					  LLVersionInfo::getShortVersion(), 
+					  mShortVersion);
+		ensure_equals("Version and channel String", 
+					  LLVersionInfo::getChannelAndVersion(), 
+					  mVersionAndChannel);
+
+		LLVersionInfo::resetChannel(mResetChannel);
+		ensure_equals("Reset channel version", 
+					  LLVersionInfo::getChannel(), 
+					  mResetChannel);
+
+		ensure_equals("Reset Version and channel String", 
+					  LLVersionInfo::getChannelAndVersion(), 
+					  mResetVersionAndChannel);
+	}
+}
diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..1bb4fb7c0cf1b64080674751bd34b6d46693c862
--- /dev/null
+++ b/indra/newview/tests/llviewerassetstats_test.cpp
@@ -0,0 +1,990 @@
+/** 
+ * @file llviewerassetstats_tut.cpp
+ * @date 2010-10-28
+ * @brief Test cases for some of newview/llviewerassetstats.cpp
+ *
+ * $LicenseInfo:firstyear=2010&license=viewergpl$
+ * 
+ * Copyright (c) 2010, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at
+ * http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include <tut/tut.hpp>
+#include <iostream>
+
+#include "lltut.h"
+#include "../llviewerassetstats.h"
+#include "lluuid.h"
+#include "llsdutil.h"
+#include "llregionhandle.h"
+
+static const char * all_keys[] = 
+{
+	"duration",
+	"fps",
+	"get_other",
+	"get_texture_temp_http",
+	"get_texture_temp_udp",
+	"get_texture_non_temp_http",
+	"get_texture_non_temp_udp",
+	"get_wearable_udp",
+	"get_sound_udp",
+	"get_gesture_udp"
+};
+
+static const char * resp_keys[] = 
+{
+	"get_other",
+	"get_texture_temp_http",
+	"get_texture_temp_udp",
+	"get_texture_non_temp_http",
+	"get_texture_non_temp_udp",
+	"get_wearable_udp",
+	"get_sound_udp",
+	"get_gesture_udp"
+};
+
+static const char * sub_keys[] =
+{
+	"dequeued",
+	"enqueued",
+	"resp_count",
+	"resp_max",
+	"resp_min",
+	"resp_mean"
+};
+
+static const char * mmm_resp_keys[] = 
+{
+	"fps"
+};
+
+static const char * mmm_sub_keys[] =
+{
+	"count",
+	"max",
+	"min",
+	"mean"
+};
+
+static const LLUUID region1("4e2d81a3-6263-6ffe-ad5c-8ce04bee07e8");
+static const LLUUID region2("68762cc8-b68b-4e45-854b-e830734f2d4a");
+static const U64 region1_handle(0x0000040000003f00ULL);
+static const U64 region2_handle(0x0000030000004200ULL);
+static const std::string region1_handle_str("0000040000003f00");
+static const std::string region2_handle_str("0000030000004200");
+
+#if 0
+static bool
+is_empty_map(const LLSD & sd)
+{
+	return sd.isMap() && 0 == sd.size();
+}
+
+static bool
+is_single_key_map(const LLSD & sd, const std::string & key)
+{
+	return sd.isMap() && 1 == sd.size() && sd.has(key);
+}
+#endif
+
+static bool
+is_double_key_map(const LLSD & sd, const std::string & key1, const std::string & key2)
+{
+	return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2);
+}
+
+static bool
+is_no_stats_map(const LLSD & sd)
+{
+	return is_double_key_map(sd, "duration", "regions");
+}
+
+static bool
+is_single_slot_array(const LLSD & sd, U64 region_handle)
+{
+	U32 grid_x(0), grid_y(0);
+	grid_from_region_handle(region_handle, &grid_x, &grid_y);
+	
+	return (sd.isArray() &&
+			1 == sd.size() &&
+			sd[0].has("grid_x") &&
+			sd[0].has("grid_y") &&
+			sd[0]["grid_x"].isInteger() &&
+			sd[0]["grid_y"].isInteger() &&
+			grid_x == sd[0]["grid_x"].asInteger() &&
+			grid_y == sd[0]["grid_y"].asInteger());
+}
+
+static bool
+is_double_slot_array(const LLSD & sd, U64 region_handle1, U64 region_handle2)
+{
+	U32 grid_x1(0), grid_y1(0);
+	U32 grid_x2(0), grid_y2(0);
+	grid_from_region_handle(region_handle1, &grid_x1, &grid_y1);
+	grid_from_region_handle(region_handle2, &grid_x2, &grid_y2);
+	
+	return (sd.isArray() &&
+			2 == sd.size() &&
+			sd[0].has("grid_x") &&
+			sd[0].has("grid_y") &&
+			sd[0]["grid_x"].isInteger() &&
+			sd[0]["grid_y"].isInteger() &&
+			sd[1].has("grid_x") &&
+			sd[1].has("grid_y") &&
+			sd[1]["grid_x"].isInteger() &&
+			sd[1]["grid_y"].isInteger() &&
+			((grid_x1 == sd[0]["grid_x"].asInteger() &&
+			  grid_y1 == sd[0]["grid_y"].asInteger() &&
+			  grid_x2 == sd[1]["grid_x"].asInteger() &&
+			  grid_y2 == sd[1]["grid_y"].asInteger()) ||
+			 (grid_x1 == sd[1]["grid_x"].asInteger() &&
+			  grid_y1 == sd[1]["grid_y"].asInteger() &&
+			  grid_x2 == sd[0]["grid_x"].asInteger() &&
+			  grid_y2 == sd[0]["grid_y"].asInteger())));
+}
+
+static LLSD
+get_region(const LLSD & sd, U64 region_handle1)
+{
+	U32 grid_x(0), grid_y(0);
+	grid_from_region_handle(region_handle1, &grid_x, &grid_y);
+
+	for (LLSD::array_const_iterator it(sd["regions"].beginArray());
+		 sd["regions"].endArray() != it;
+		 ++it)
+	{
+		if ((*it).has("grid_x") &&
+			(*it).has("grid_y") &&
+			(*it)["grid_x"].isInteger() &&
+			(*it)["grid_y"].isInteger() &&
+			(*it)["grid_x"].asInteger() == grid_x &&
+			(*it)["grid_y"].asInteger() == grid_y)
+		{
+			return *it;
+		}
+	}
+	return LLSD();
+}
+
+namespace tut
+{
+	struct tst_viewerassetstats_index
+	{};
+	typedef test_group<tst_viewerassetstats_index> tst_viewerassetstats_index_t;
+	typedef tst_viewerassetstats_index_t::object tst_viewerassetstats_index_object_t;
+	tut::tst_viewerassetstats_index_t tut_tst_viewerassetstats_index("tst_viewerassetstats_test");
+
+	// Testing free functions without global stats allocated
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<1>()
+	{
+		// Check that helpers aren't bothered by missing global stats
+		ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain));
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+
+		LLViewerAssetStatsFF::record_response_main(LLViewerAssetType::AT_GESTURE, false, false, 12300000ULL);
+	}
+
+	// Create a non-global instance and check the structure
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<2>()
+	{
+		ensure("Global gViewerAssetStatsMain should be NULL", (NULL == gViewerAssetStatsMain));
+
+		LLViewerAssetStats * it = new LLViewerAssetStats();
+
+		ensure("Global gViewerAssetStatsMain should still be NULL", (NULL == gViewerAssetStatsMain));
+
+		LLSD sd_full = it->asLLSD(false);
+
+		// Default (NULL) region ID doesn't produce LLSD results so should
+		// get an empty map back from output
+		ensure("Stat-less LLSD initially", is_no_stats_map(sd_full));
+
+		// Once the region is set, we will get a response even with no data collection
+		it->setRegion(region1_handle);
+		sd_full = it->asLLSD(false);
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd_full, "duration", "regions"));
+		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd_full["regions"], region1_handle));
+		
+		LLSD sd = sd_full["regions"][0];
+
+		delete it;
+			
+		// Check the structure of the LLSD
+		for (int i = 0; i < LL_ARRAY_SIZE(all_keys); ++i)
+		{
+			std::string line = llformat("Has '%s' key", all_keys[i]);
+			ensure(line, sd.has(all_keys[i]));
+		}
+
+		for (int i = 0; i < LL_ARRAY_SIZE(resp_keys); ++i)
+		{
+			for (int j = 0; j < LL_ARRAY_SIZE(sub_keys); ++j)
+			{
+				std::string line = llformat("Key '%s' has '%s' key", resp_keys[i], sub_keys[j]);
+				ensure(line, sd[resp_keys[i]].has(sub_keys[j]));
+			}
+		}
+
+		for (int i = 0; i < LL_ARRAY_SIZE(mmm_resp_keys); ++i)
+		{
+			for (int j = 0; j < LL_ARRAY_SIZE(mmm_sub_keys); ++j)
+			{
+				std::string line = llformat("Key '%s' has '%s' key", mmm_resp_keys[i], mmm_sub_keys[j]);
+				ensure(line, sd[mmm_resp_keys[i]].has(mmm_sub_keys[j]));
+			}
+		}
+	}
+
+	// Create a non-global instance and check some content
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<3>()
+	{
+		LLViewerAssetStats * it = new LLViewerAssetStats();
+		it->setRegion(region1_handle);
+		
+		LLSD sd = it->asLLSD(false);
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
+		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
+		sd = sd[0];
+		
+		delete it;
+
+		// Check a few points on the tree for content
+		ensure("sd[get_texture_temp_http][dequeued] is 0", (0 == sd["get_texture_temp_http"]["dequeued"].asInteger()));
+		ensure("sd[get_sound_udp][resp_min] is 0", (0.0 == sd["get_sound_udp"]["resp_min"].asReal()));
+	}
+
+	// Create a global instance and verify free functions do something useful
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<4>()
+	{
+		gViewerAssetStatsMain = new LLViewerAssetStats();
+		LLViewerAssetStatsFF::set_region_main(region1_handle);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
+
+		LLSD sd = gViewerAssetStatsMain->asLLSD(false);
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
+		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
+		sd = sd["regions"][0];
+		
+		// Check a few points on the tree for content
+		ensure("sd[get_texture_non_temp_udp][enqueued] is 1", (1 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
+		ensure("sd[get_texture_temp_udp][enqueued] is 0", (0 == sd["get_texture_temp_udp"]["enqueued"].asInteger()));
+		ensure("sd[get_texture_non_temp_http][enqueued] is 0", (0 == sd["get_texture_non_temp_http"]["enqueued"].asInteger()));
+		ensure("sd[get_texture_temp_http][enqueued] is 0", (0 == sd["get_texture_temp_http"]["enqueued"].asInteger()));
+		ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
+
+		// Reset and check zeros...
+		// Reset leaves current region in place
+		gViewerAssetStatsMain->reset();
+		sd = gViewerAssetStatsMain->asLLSD(false)["regions"][region1_handle_str];
+		
+		delete gViewerAssetStatsMain;
+		gViewerAssetStatsMain = NULL;
+
+		ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
+		ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
+	}
+
+	// Create two global instances and verify no interactions
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<5>()
+	{
+		gViewerAssetStatsThread1 = new LLViewerAssetStats();
+		gViewerAssetStatsMain = new LLViewerAssetStats();
+		LLViewerAssetStatsFF::set_region_main(region1_handle);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
+
+		LLSD sd = gViewerAssetStatsThread1->asLLSD(false);
+		ensure("Other collector is empty", is_no_stats_map(sd));
+		sd = gViewerAssetStatsMain->asLLSD(false);
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
+		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
+		sd = sd["regions"][0];
+		
+		// Check a few points on the tree for content
+		ensure("sd[get_texture_non_temp_udp][enqueued] is 1", (1 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
+		ensure("sd[get_texture_temp_udp][enqueued] is 0", (0 == sd["get_texture_temp_udp"]["enqueued"].asInteger()));
+		ensure("sd[get_texture_non_temp_http][enqueued] is 0", (0 == sd["get_texture_non_temp_http"]["enqueued"].asInteger()));
+		ensure("sd[get_texture_temp_http][enqueued] is 0", (0 == sd["get_texture_temp_http"]["enqueued"].asInteger()));
+		ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
+
+		// Reset and check zeros...
+		// Reset leaves current region in place
+		gViewerAssetStatsMain->reset();
+		sd = gViewerAssetStatsMain->asLLSD(false)["regions"][0];
+		
+		delete gViewerAssetStatsMain;
+		gViewerAssetStatsMain = NULL;
+		delete gViewerAssetStatsThread1;
+		gViewerAssetStatsThread1 = NULL;
+
+		ensure("sd[get_texture_non_temp_udp][enqueued] is reset", (0 == sd["get_texture_non_temp_udp"]["enqueued"].asInteger()));
+		ensure("sd[get_gesture_udp][dequeued] is reset", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
+	}
+
+    // Check multiple region collection
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<6>()
+	{
+		gViewerAssetStatsMain = new LLViewerAssetStats();
+
+		LLViewerAssetStatsFF::set_region_main(region1_handle);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
+
+		LLViewerAssetStatsFF::set_region_main(region2_handle);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+
+		LLSD sd = gViewerAssetStatsMain->asLLSD(false);
+
+		// std::cout << sd << std::endl;
+		
+		ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
+		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));
+		LLSD sd1 = get_region(sd, region1_handle);
+		LLSD sd2 = get_region(sd, region2_handle);
+		ensure("Region1 is present in results", sd1.isMap());
+		ensure("Region2 is present in results", sd2.isMap());
+		
+		// Check a few points on the tree for content
+		ensure_equals("sd1[get_texture_non_temp_udp][enqueued] is 1", sd1["get_texture_non_temp_udp"]["enqueued"].asInteger(), 1);
+		ensure_equals("sd1[get_texture_temp_udp][enqueued] is 0", sd1["get_texture_temp_udp"]["enqueued"].asInteger(), 0);
+		ensure_equals("sd1[get_texture_non_temp_http][enqueued] is 0", sd1["get_texture_non_temp_http"]["enqueued"].asInteger(), 0);
+		ensure_equals("sd1[get_texture_temp_http][enqueued] is 0", sd1["get_texture_temp_http"]["enqueued"].asInteger(), 0);
+		ensure_equals("sd1[get_gesture_udp][dequeued] is 0", sd1["get_gesture_udp"]["dequeued"].asInteger(), 0);
+
+		// Check a few points on the tree for content
+		ensure("sd2[get_gesture_udp][enqueued] is 4", (4 == sd2["get_gesture_udp"]["enqueued"].asInteger()));
+		ensure("sd2[get_gesture_udp][dequeued] is 0", (0 == sd2["get_gesture_udp"]["dequeued"].asInteger()));
+		ensure("sd2[get_texture_non_temp_udp][enqueued] is 0", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger()));
+
+		// Reset and check zeros...
+		// Reset leaves current region in place
+		gViewerAssetStatsMain->reset();
+		sd = gViewerAssetStatsMain->asLLSD(false);
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
+		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
+		sd2 = sd["regions"][0];
+		
+		delete gViewerAssetStatsMain;
+		gViewerAssetStatsMain = NULL;
+
+		ensure("sd2[get_texture_non_temp_udp][enqueued] is reset", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger()));
+		ensure("sd2[get_gesture_udp][enqueued] is reset", (0 == sd2["get_gesture_udp"]["enqueued"].asInteger()));
+	}
+
+    // Check multiple region collection jumping back-and-forth between regions
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<7>()
+	{
+		gViewerAssetStatsMain = new LLViewerAssetStats();
+
+		LLViewerAssetStatsFF::set_region_main(region1_handle);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
+
+		LLViewerAssetStatsFF::set_region_main(region2_handle);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+
+		LLViewerAssetStatsFF::set_region_main(region1_handle);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, true, true);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, true, true);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
+
+		LLViewerAssetStatsFF::set_region_main(region2_handle);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_GESTURE, false, false);
+
+		LLSD sd = gViewerAssetStatsMain->asLLSD(false);
+
+		ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
+		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));
+		LLSD sd1 = get_region(sd, region1_handle);
+		LLSD sd2 = get_region(sd, region2_handle);
+		ensure("Region1 is present in results", sd1.isMap());
+		ensure("Region2 is present in results", sd2.isMap());
+		
+		// Check a few points on the tree for content
+		ensure("sd1[get_texture_non_temp_udp][enqueued] is 1", (1 == sd1["get_texture_non_temp_udp"]["enqueued"].asInteger()));
+		ensure("sd1[get_texture_temp_udp][enqueued] is 0", (0 == sd1["get_texture_temp_udp"]["enqueued"].asInteger()));
+		ensure("sd1[get_texture_non_temp_http][enqueued] is 0", (0 == sd1["get_texture_non_temp_http"]["enqueued"].asInteger()));
+		ensure("sd1[get_texture_temp_http][enqueued] is 1", (1 == sd1["get_texture_temp_http"]["enqueued"].asInteger()));
+		ensure("sd1[get_gesture_udp][dequeued] is 0", (0 == sd1["get_gesture_udp"]["dequeued"].asInteger()));
+
+		// Check a few points on the tree for content
+		ensure("sd2[get_gesture_udp][enqueued] is 8", (8 == sd2["get_gesture_udp"]["enqueued"].asInteger()));
+		ensure("sd2[get_gesture_udp][dequeued] is 0", (0 == sd2["get_gesture_udp"]["dequeued"].asInteger()));
+		ensure("sd2[get_texture_non_temp_udp][enqueued] is 0", (0 == sd2["get_texture_non_temp_udp"]["enqueued"].asInteger()));
+
+		// Reset and check zeros...
+		// Reset leaves current region in place
+		gViewerAssetStatsMain->reset();
+		sd = gViewerAssetStatsMain->asLLSD(false);
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
+		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
+		sd2 = get_region(sd, region2_handle);
+		ensure("Region2 is present in results", sd2.isMap());
+		
+		delete gViewerAssetStatsMain;
+		gViewerAssetStatsMain = NULL;
+
+		ensure_equals("sd2[get_texture_non_temp_udp][enqueued] is reset", sd2["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0);
+		ensure_equals("sd2[get_gesture_udp][enqueued] is reset", sd2["get_gesture_udp"]["enqueued"].asInteger(), 0);
+	}
+
+	// Non-texture assets ignore transport and persistence flags
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<8>()
+	{
+		gViewerAssetStatsThread1 = new LLViewerAssetStats();
+		gViewerAssetStatsMain = new LLViewerAssetStats();
+		LLViewerAssetStatsFF::set_region_main(region1_handle);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_TEXTURE, false, false);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, false, true);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, true);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, false);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, false);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_BODYPART, true, true);
+		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, true, true);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, false);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, false, true);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, false);
+
+		LLViewerAssetStatsFF::record_enqueue_main(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		LLSD sd = gViewerAssetStatsThread1->asLLSD(false);
+		ensure("Other collector is empty", is_no_stats_map(sd));
+		sd = gViewerAssetStatsMain->asLLSD(false);
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
+		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
+		sd = get_region(sd, region1_handle);
+		ensure("Region1 is present in results", sd.isMap());
+		
+		// Check a few points on the tree for content
+		ensure("sd[get_gesture_udp][enqueued] is 0", (0 == sd["get_gesture_udp"]["enqueued"].asInteger()));
+		ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
+
+		ensure("sd[get_wearable_udp][enqueued] is 4", (4 == sd["get_wearable_udp"]["enqueued"].asInteger()));
+		ensure("sd[get_wearable_udp][dequeued] is 4", (4 == sd["get_wearable_udp"]["dequeued"].asInteger()));
+
+		ensure("sd[get_other][enqueued] is 4", (4 == sd["get_other"]["enqueued"].asInteger()));
+		ensure("sd[get_other][dequeued] is 0", (0 == sd["get_other"]["dequeued"].asInteger()));
+
+		// Reset and check zeros...
+		// Reset leaves current region in place
+		gViewerAssetStatsMain->reset();
+		sd = get_region(gViewerAssetStatsMain->asLLSD(false), region1_handle);
+		ensure("Region1 is present in results", sd.isMap());
+		
+		delete gViewerAssetStatsMain;
+		gViewerAssetStatsMain = NULL;
+		delete gViewerAssetStatsThread1;
+		gViewerAssetStatsThread1 = NULL;
+
+		ensure_equals("sd[get_texture_non_temp_udp][enqueued] is reset", sd["get_texture_non_temp_udp"]["enqueued"].asInteger(), 0);
+		ensure_equals("sd[get_gesture_udp][dequeued] is reset", sd["get_gesture_udp"]["dequeued"].asInteger(), 0);
+	}
+
+
+	// LLViewerAssetStats::merge() basic functions work
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<9>()
+	{
+		LLViewerAssetStats s1;
+		LLViewerAssetStats s2;
+
+		s1.setRegion(region1_handle);
+		s2.setRegion(region1_handle);
+
+		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 5000000);
+		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 6000000);
+		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 8000000);
+		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 7000000);
+		s1.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 9000000);
+		
+		s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 2000000);
+		s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 3000000);
+		s2.recordGetServiced(LLViewerAssetType::AT_TEXTURE, true, true, 4000000);
+
+		s2.merge(s1);
+
+		LLSD s2_llsd = get_region(s2.asLLSD(false), region1_handle);
+		ensure("Region1 is present in results", s2_llsd.isMap());
+		
+		ensure_equals("count after merge", s2_llsd["get_texture_temp_http"]["resp_count"].asInteger(), 8);
+		ensure_approximately_equals("min after merge", s2_llsd["get_texture_temp_http"]["resp_min"].asReal(), 2.0, 22);
+		ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_max"].asReal(), 9.0, 22);
+		ensure_approximately_equals("max after merge", s2_llsd["get_texture_temp_http"]["resp_mean"].asReal(), 5.5, 22);
+	}
+
+	// LLViewerAssetStats::merge() basic functions work without corrupting source data
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<10>()
+	{
+		LLViewerAssetStats s1;
+		LLViewerAssetStats s2;
+
+		s1.setRegion(region1_handle);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200);
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900);
+
+		
+		s2.setRegion(region2_handle);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000);
+		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000);
+
+		{
+			s2.merge(s1);
+			
+			LLSD src = s1.asLLSD(false);
+			LLSD dst = s2.asLLSD(false);
+
+			ensure_equals("merge src has single region", src["regions"].size(), 1);
+			ensure_equals("merge dst has dual regions", dst["regions"].size(), 2);
+			
+			// Remove time stamps, they're a problem
+			src.erase("duration");
+			src["regions"][0].erase("duration");
+			dst.erase("duration");
+			dst["regions"][0].erase("duration");
+			dst["regions"][1].erase("duration");
+
+			LLSD s1_llsd = get_region(src, region1_handle);
+			ensure("Region1 is present in src", s1_llsd.isMap());
+			LLSD s2_llsd = get_region(dst, region1_handle);
+			ensure("Region1 is present in dst", s2_llsd.isMap());
+
+			ensure("result from src is in dst", llsd_equals(s1_llsd, s2_llsd));
+		}
+
+		s1.setRegion(region1_handle);
+		s2.setRegion(region1_handle);
+		s1.reset();
+		s2.reset();
+		
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 23289200);
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 282900);
+
+		
+		s2.setRegion(region1_handle);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 6500000);
+		s2.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 10000);
+
+		{
+			s2.merge(s1);
+			
+			LLSD src = s1.asLLSD(false);
+			LLSD dst = s2.asLLSD(false);
+
+			ensure_equals("merge src has single region (p2)", src["regions"].size(), 1);
+			ensure_equals("merge dst has single region (p2)", dst["regions"].size(), 1);
+
+			// Remove time stamps, they're a problem
+			src.erase("duration");
+			src["regions"][0].erase("duration");
+			dst.erase("duration");
+			dst["regions"][0].erase("duration");
+			
+			LLSD s1_llsd = get_region(src, region1_handle);
+			ensure("Region1 is present in src", s1_llsd.isMap());
+			LLSD s2_llsd = get_region(dst, region1_handle);
+			ensure("Region1 is present in dst", s2_llsd.isMap());
+
+			ensure_equals("src counts okay (enq)", s1_llsd["get_other"]["enqueued"].asInteger(), 4);
+			ensure_equals("src counts okay (deq)", s1_llsd["get_other"]["dequeued"].asInteger(), 4);
+			ensure_equals("src resp counts okay", s1_llsd["get_other"]["resp_count"].asInteger(), 2);
+			ensure_approximately_equals("src respmin okay", s1_llsd["get_other"]["resp_min"].asReal(), 0.2829, 20);
+			ensure_approximately_equals("src respmax okay", s1_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20);
+			
+			ensure_equals("dst counts okay (enq)", s2_llsd["get_other"]["enqueued"].asInteger(), 12);
+			ensure_equals("src counts okay (deq)", s2_llsd["get_other"]["dequeued"].asInteger(), 11);
+			ensure_equals("dst resp counts okay", s2_llsd["get_other"]["resp_count"].asInteger(), 4);
+			ensure_approximately_equals("dst respmin okay", s2_llsd["get_other"]["resp_min"].asReal(), 0.010, 20);
+			ensure_approximately_equals("dst respmax okay", s2_llsd["get_other"]["resp_max"].asReal(), 23.2892, 20);
+		}
+	}
+
+
+    // Maximum merges are interesting when one side contributes nothing
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<11>()
+	{
+		LLViewerAssetStats s1;
+		LLViewerAssetStats s2;
+
+		s1.setRegion(region1_handle);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		// Want to test negative numbers here but have to work in U64
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
+
+		s2.setRegion(region1_handle);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		{
+			s2.merge(s1);
+			
+			LLSD src = s1.asLLSD(false);
+			LLSD dst = s2.asLLSD(false);
+
+			ensure_equals("merge src has single region", src["regions"].size(), 1);
+			ensure_equals("merge dst has single region", dst["regions"].size(), 1);
+			
+			// Remove time stamps, they're a problem
+			src.erase("duration");
+			src["regions"][0].erase("duration");
+			dst.erase("duration");
+			dst["regions"][0].erase("duration");
+
+			LLSD s2_llsd = get_region(dst, region1_handle);
+			ensure("Region1 is present in dst", s2_llsd.isMap());
+			
+			ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3);
+
+			ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum",
+										s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20);
+		}
+
+		// Other way around
+		s1.setRegion(region1_handle);
+		s2.setRegion(region1_handle);
+		s1.reset();
+		s2.reset();
+
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		// Want to test negative numbers here but have to work in U64
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 0);
+
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		{
+			s1.merge(s2);
+			
+			LLSD src = s2.asLLSD(false);
+			LLSD dst = s1.asLLSD(false);
+
+			ensure_equals("merge src has single region", src["regions"].size(), 1);
+			ensure_equals("merge dst has single region", dst["regions"].size(), 1);
+			
+			// Remove time stamps, they're a problem
+			src.erase("duration");
+			src["regions"][0].erase("duration");
+			dst.erase("duration");
+			dst["regions"][0].erase("duration");
+
+			LLSD s2_llsd = get_region(dst, region1_handle);
+			ensure("Region1 is present in dst", s2_llsd.isMap());
+
+			ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3);
+
+			ensure_approximately_equals("dst maximum with count 0 does not contribute to merged maximum (flipped)",
+										s2_llsd["get_other"]["resp_max"].asReal(), F64(0.0), 20);
+		}
+	}
+
+    // Minimum merges are interesting when one side contributes nothing
+	template<> template<>
+	void tst_viewerassetstats_index_object_t::test<12>()
+	{
+		LLViewerAssetStats s1;
+		LLViewerAssetStats s2;
+
+		s1.setRegion(region1_handle);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000);
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000);
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000);
+
+		s2.setRegion(region1_handle);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		{
+			s2.merge(s1);
+			
+			LLSD src = s1.asLLSD(false);
+			LLSD dst = s2.asLLSD(false);
+
+			ensure_equals("merge src has single region", src["regions"].size(), 1);
+			ensure_equals("merge dst has single region", dst["regions"].size(), 1);
+			
+			// Remove time stamps, they're a problem
+			src.erase("duration");
+			src["regions"][0].erase("duration");
+			dst.erase("duration");
+			dst["regions"][0].erase("duration");
+
+			LLSD s2_llsd = get_region(dst, region1_handle);
+			ensure("Region1 is present in dst", s2_llsd.isMap());
+
+			ensure_equals("dst counts come from src only", s2_llsd["get_other"]["resp_count"].asInteger(), 3);
+
+			ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum",
+										s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20);
+		}
+
+		// Other way around
+		s1.setRegion(region1_handle);
+		s2.setRegion(region1_handle);
+		s1.reset();
+		s2.reset();
+
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s1.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 3800000);
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2700000);
+		s1.recordGetServiced(LLViewerAssetType::AT_LSL_BYTECODE, true, true, 2900000);
+
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetEnqueued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+		s2.recordGetDequeued(LLViewerAssetType::AT_LSL_BYTECODE, true, true);
+
+		{
+			s1.merge(s2);
+			
+			LLSD src = s2.asLLSD(false);
+			LLSD dst = s1.asLLSD(false);
+
+			ensure_equals("merge src has single region", src["regions"].size(), 1);
+			ensure_equals("merge dst has single region", dst["regions"].size(), 1);
+			
+			// Remove time stamps, they're a problem
+			src.erase("duration");
+			src["regions"][0].erase("duration");
+			dst.erase("duration");
+			dst["regions"][0].erase("duration");
+
+			LLSD s2_llsd = get_region(dst, region1_handle);
+			ensure("Region1 is present in dst", s2_llsd.isMap());
+
+			ensure_equals("dst counts come from src only (flipped)", s2_llsd["get_other"]["resp_count"].asInteger(), 3);
+
+			ensure_approximately_equals("dst minimum with count 0 does not contribute to merged minimum (flipped)",
+										s2_llsd["get_other"]["resp_min"].asReal(), F64(2.7), 20);
+		}
+	}
+
+}
diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp
index a0f1d1c3c34499998e1cc6a0f1abd3679dd6fe67..b425b50c8bd36a2be38d959b586c880bdb867ceb 100644
--- a/indra/newview/tests/llviewerhelputil_test.cpp
+++ b/indra/newview/tests/llviewerhelputil_test.cpp
@@ -72,16 +72,13 @@ static void substitute_string(std::string &input, const std::string &search, con
 	}
 }
 
-class LLAgent
-{
-public:
-	LLAgent() {}
-	~LLAgent() {}
-#ifdef __GNUC__
-	__attribute__ ((noinline))
-#endif
-	bool isGodlike() const { return FALSE; }
-};
+#include "../llagent.h"
+LLAgent::LLAgent() : mAgentAccess(gSavedSettings) { }
+LLAgent::~LLAgent() { }
+bool LLAgent::isGodlike() const { return FALSE; }
+LLAgentAccess::LLAgentAccess(LLControlGroup& settings) : mSavedSettings(settings) { }
+LLUIColor::LLUIColor() {}
+
 LLAgent gAgent;
 
 std::string LLWeb::expandURLSubstitutions(const std::string &url,
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 370dc3af8a41e0255cdb1c2c979adde90a3f5aa7..338c62b9fb3a7193971a511872c108a16fd69be4 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -247,6 +247,8 @@ def construct(self):
         
         self.disable_manifest_check()
 
+        self.path(src="../viewer_components/updater/scripts/windows/update_install.bat", dst="update_install.bat")
+
         # Get shared libs from the shared libs staging directory
         if self.prefix(src=os.path.join(os.pardir, 'sharedlibs', self.args['configuration']),
                        dst=""):
@@ -566,6 +568,8 @@ def construct(self):
             # copy additional libs in <bundle>/Contents/MacOS/
             self.path("../../libraries/universal-darwin/lib_release/libndofdev.dylib", dst="MacOS/libndofdev.dylib")
 
+            self.path("../viewer_components/updater/scripts/darwin/update_install", "MacOS/update_install")
+
             # most everything goes in the Resources directory
             if self.prefix(src="", dst="Resources"):
                 super(DarwinManifest, self).construct()
@@ -701,6 +705,11 @@ def construct(self):
             self.run_command('strip -S %(viewer_binary)r' %
                              { 'viewer_binary' : self.dst_path_of('Contents/MacOS/Second Life')})
 
+    def copy_finish(self):
+        # Force executable permissions to be set for scripts
+        # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802
+        for script in 'Contents/MacOS/update_install',:
+            self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script))
 
     def package_finish(self):
         channel_standin = 'Second Life Viewer 2'  # hah, our default channel is not usable on its own
@@ -737,6 +746,11 @@ def package_finish(self):
             devfile = re.search("/dev/disk([0-9]+)[^s]", hdi_output).group(0).strip()
             volpath = re.search('HFS\s+(.+)', hdi_output).group(1).strip()
 
+            if devfile != '/dev/disk1':
+                # adding more debugging info based upon nat's hunches to the
+                # logs to help track down 'SetFile -a V' failures -brad
+                print "WARNING: 'SetFile -a V' command below is probably gonna fail"
+
             # Copy everything in to the mounted .dmg
 
             if self.default_channel() and not self.default_grid():
@@ -836,6 +850,8 @@ def construct(self):
             # recurse
             self.end_prefix("res-sdl")
 
+        self.path("../viewer_components/updater/scripts/linux/update_install", "bin/update_install")
+
         # plugins
         if self.prefix(src="", dst="bin/llplugin"):
             self.path("../media_plugins/webkit/libmedia_plugin_webkit.so", "libmedia_plugin_webkit.so")
@@ -849,6 +865,12 @@ def construct(self):
 
         self.path("featuretable_linux.txt")
 
+    def copy_finish(self):
+        # Force executable permissions to be set for scripts
+        # see CHOP-223 and http://mercurial.selenic.com/bts/issue1802
+        for script in 'secondlife', 'bin/update_install':
+            self.run_command("chmod +x %r" % os.path.join(self.get_dst_prefix(), script))
+
     def package_finish(self):
         if 'installer_name' in self.args:
             installer_name = self.args['installer_name']
@@ -864,7 +886,7 @@ def package_finish(self):
 
         if self.args['buildtype'].lower() == 'release' and self.is_packaging_viewer():
             print "* Going strip-crazy on the packaged binaries, since this is a RELEASE build"
-            self.run_command("find %(d)r/bin %(d)r/lib -type f | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure
+            self.run_command("find %(d)r/bin %(d)r/lib -type f \\! -name update_install | xargs --no-run-if-empty strip -S" % {'d': self.get_dst_prefix()} ) # makes some small assumptions about our packaged dir structure
 
         # Fix access permissions
         self.run_command("""
@@ -891,6 +913,9 @@ def package_finish(self):
                         'dir': self.get_build_prefix(),
                         'inst_name': installer_name,
                         'inst_path':self.build_path_of(installer_name)})
+            else:
+                print "Skipping %s.tar.bz2 for non-Release build (%s)" % \
+                      (installer_name, self.args['buildtype'])
         finally:
             self.run_command("mv %(inst)s %(dst)s" % {
                 'dst': self.get_dst_prefix(),
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index 66c78a86c4e8d3ba17e9c0ef952c4f24d4d44b8a..e9eb3c188447b73ed11313459a250a2d05bebada 100644
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -27,6 +27,7 @@ include_directories(
     ${LLXML_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}
     ${GOOGLEMOCK_INCLUDE_DIRS}
+    ${TUT_INCLUDE_DIR}
     )
 
 set(test_SOURCE_FILES
diff --git a/indra/test_apps/llplugintest/llmediaplugintest.cpp b/indra/test_apps/llplugintest/llmediaplugintest.cpp
index 873fa23db8675b55c8e5cfca4c3311a9411fafee..4a2272032b0a7fd2d1c85136da9822e8e5f805a7 100644
--- a/indra/test_apps/llplugintest/llmediaplugintest.cpp
+++ b/indra/test_apps/llplugintest/llmediaplugintest.cpp
@@ -2220,6 +2220,21 @@ void LLMediaPluginTest::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent e
 				<< ", height = " << self->getGeometryHeight() 
 				<< std::endl;
 		break;
+
+		case MEDIA_EVENT_AUTH_REQUEST:
+		{
+			//std::cerr <<  "Media event:  MEDIA_EVENT_AUTH_REQUEST, url " << self->getAuthURL() ", realm " << self->getAuthRealm() << std::endl;
+
+			// TODO: display an auth dialog
+			self->sendAuthResponse(false, "", "");
+		}
+		break;
+
+		case MEDIA_EVENT_LINK_HOVERED:
+		{
+			std::cerr <<  "Media event:  MEDIA_EVENT_LINK_HOVERED, hover text is: " << self->getHoverText() << std::endl;
+		};
+		break;
 	}
 }
 
diff --git a/indra/viewer_components/CMakeLists.txt b/indra/viewer_components/CMakeLists.txt
index 0993b64b14781415b4de7a1b20488a7182487231..74c9b4568d97b9d46cbef7a481b8c25e04632c43 100644
--- a/indra/viewer_components/CMakeLists.txt
+++ b/indra/viewer_components/CMakeLists.txt
@@ -1,4 +1,4 @@
 # -*- cmake -*-
 
 add_subdirectory(login)
-
+add_subdirectory(updater)
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0e288bb4963a52f91620cea48a01e7310659f92b
--- /dev/null
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -0,0 +1,82 @@
+# -*- cmake -*-
+
+project(updater_service)
+
+include(00-Common)
+if(LL_TESTS)
+  include(LLAddBuildTest)
+endif(LL_TESTS)
+include(CMakeCopyIfDifferent)
+include(CURL)
+include(LLCommon)
+include(LLMessage)
+include(LLPlugin)
+include(LLVFS)
+
+include_directories(
+    ${LLCOMMON_INCLUDE_DIRS}
+    ${LLMESSAGE_INCLUDE_DIRS}
+    ${LLPLUGIN_INCLUDE_DIRS}
+	${LLVFS_INCLUDE_DIRS}
+	${CURL_INCLUDE_DIRS}
+    )
+
+set(updater_service_SOURCE_FILES
+    llupdaterservice.cpp
+    llupdatechecker.cpp
+    llupdatedownloader.cpp
+    llupdateinstaller.cpp
+    )
+
+set(updater_service_HEADER_FILES
+    llupdaterservice.h
+    llupdatechecker.h
+    llupdatedownloader.h
+    llupdateinstaller.h
+    )
+
+set_source_files_properties(${updater_service_HEADER_FILES}
+                            PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND 
+    updater_service_SOURCE_FILES 
+    ${updater_service_HEADER_FILES} 
+    )
+
+add_library(llupdaterservice
+            ${updater_service_SOURCE_FILES}
+            )
+
+target_link_libraries(llupdaterservice
+    ${LLCOMMON_LIBRARIES}
+    ${LLMESSAGE_LIBRARIES}
+    ${LLPLUGIN_LIBRARIES}
+	${LLVFS_LIBRARIES}
+    )
+
+if(LL_TESTS)
+  SET(llupdater_service_TEST_SOURCE_FILES
+      llupdaterservice.cpp
+      )
+
+# *NOTE:Mani - I was trying to use the preprocessor seam to mock out
+#              llifstream (and other) llcommon classes. I didn't work
+#              because of the windows declspec(dllimport)attribute.
+#set_source_files_properties(
+#    llupdaterservice.cpp
+#    PROPERTIES
+#      LL_TEST_ADDITIONAL_CFLAGS "-Dllifstream=llus_mock_llifstream"
+#    )
+
+  LL_ADD_PROJECT_UNIT_TESTS(llupdaterservice "${llupdater_service_TEST_SOURCE_FILES}")
+endif(LL_TESTS)
+
+set(UPDATER_INCLUDE_DIRS 
+  ${LIBS_OPEN_DIR}/viewer_components/updater 
+  CACHE INTERNAL ""
+)
+
+set(UPDATER_LIBRARIES 
+  llupdaterservice
+  CACHE INTERNAL ""
+)
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c6aa9b0f110d1422e4c665c7e6532cc4bc91684d
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -0,0 +1,194 @@
+/** 
+ * @file llupdaterservice.cpp
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include <stdexcept>
+#include <boost/format.hpp>
+#include "llhttpclient.h"
+#include "llsd.h"
+#include "llupdatechecker.h"
+#include "lluri.h"
+
+
+#if LL_WINDOWS
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
+
+
+class LLUpdateChecker::CheckError:
+	public std::runtime_error
+{
+public:
+	CheckError(const char * message):
+		std::runtime_error(message)
+	{
+		; // No op.
+	}
+};
+
+
+class LLUpdateChecker::Implementation:
+	public LLHTTPClient::Responder
+{
+public:
+	Implementation(Client & client);
+	~Implementation();
+	void check(std::string const & protocolVersion, std::string const & hostUrl, 
+			   std::string const & servicePath, std::string channel, std::string version);
+	
+	// Responder:
+	virtual void completed(U32 status,
+						   const std::string & reason,
+						   const LLSD& content);
+	virtual void error(U32 status, const std::string & reason);
+	
+private:	
+	static const char * sProtocolVersion;
+	
+	Client & mClient;
+	LLHTTPClient mHttpClient;
+	bool mInProgress;
+	std::string mVersion;
+	
+	std::string buildUrl(std::string const & protocolVersion, std::string const & hostUrl, 
+						 std::string const & servicePath, std::string channel, std::string version);
+
+	LOG_CLASS(LLUpdateChecker::Implementation);
+};
+
+
+
+// LLUpdateChecker
+//-----------------------------------------------------------------------------
+
+
+LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):
+	mImplementation(new LLUpdateChecker::Implementation(client))
+{
+	; // No op.
+}
+
+
+void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl, 
+							std::string const & servicePath, std::string channel, std::string version)
+{
+	mImplementation->check(protocolVersion, hostUrl, servicePath, channel, version);
+}
+
+
+
+// LLUpdateChecker::Implementation
+//-----------------------------------------------------------------------------
+
+
+const char * LLUpdateChecker::Implementation::sProtocolVersion = "v1.0";
+
+
+LLUpdateChecker::Implementation::Implementation(LLUpdateChecker::Client & client):
+	mClient(client),
+	mInProgress(false)
+{
+	; // No op.
+}
+
+
+LLUpdateChecker::Implementation::~Implementation()
+{
+	; // No op.
+}
+
+
+void LLUpdateChecker::Implementation::check(std::string const & protocolVersion, std::string const & hostUrl, 
+											std::string const & servicePath, std::string channel, std::string version)
+{
+	llassert(!mInProgress);
+	
+	if(protocolVersion != sProtocolVersion) throw CheckError("unsupported protocol");
+		
+	mInProgress = true;
+	mVersion = version;
+	std::string checkUrl = buildUrl(protocolVersion, hostUrl, servicePath, channel, version);
+	LL_INFOS("UpdateCheck") << "checking for updates at " << checkUrl << llendl;
+	
+	// The HTTP client will wrap a raw pointer in a boost::intrusive_ptr causing the
+	// passed object to be silently and automatically deleted.  We pass a self-
+	// referential intrusive pointer to which we add a reference to keep the
+	// client from deleting the update checker implementation instance.
+	LLHTTPClient::ResponderPtr temporaryPtr(this);
+	boost::intrusive_ptr_add_ref(temporaryPtr.get());
+	mHttpClient.get(checkUrl, temporaryPtr);
+}
+
+void LLUpdateChecker::Implementation::completed(U32 status,
+							  const std::string & reason,
+							  const LLSD & content)
+{
+	mInProgress = false;	
+	
+	if(status != 200) {
+		LL_WARNS("UpdateCheck") << "html error " << status << " (" << reason << ")" << llendl;
+		mClient.error(reason);
+	} else if(!content.asBoolean()) {
+		LL_INFOS("UpdateCheck") << "up to date" << llendl;
+		mClient.upToDate();
+	} else if(content["required"].asBoolean()) {
+		LL_INFOS("UpdateCheck") << "version invalid" << llendl;
+		LLURI uri(content["url"].asString());
+		mClient.requiredUpdate(content["version"].asString(), uri, content["hash"].asString());
+	} else {
+		LL_INFOS("UpdateCheck") << "newer version " << content["version"].asString() << " available" << llendl;
+		LLURI uri(content["url"].asString());
+		mClient.optionalUpdate(content["version"].asString(), uri, content["hash"].asString());
+	}
+}
+
+
+void LLUpdateChecker::Implementation::error(U32 status, const std::string & reason)
+{
+	mInProgress = false;
+	LL_WARNS("UpdateCheck") << "update check failed; " << reason << llendl;
+	mClient.error(reason);
+}
+
+
+std::string LLUpdateChecker::Implementation::buildUrl(std::string const & protocolVersion, std::string const & hostUrl, 
+													  std::string const & servicePath, std::string channel, std::string version)
+{	
+#ifdef LL_WINDOWS
+	static const char * platform = "win";
+#elif LL_DARWIN
+	static const char * platform = "mac";
+#else
+	static const char * platform = "lnx";
+#endif
+	
+	LLSD path;
+	path.append(servicePath);
+	path.append(protocolVersion);
+	path.append(channel);
+	path.append(version);
+	path.append(platform);
+	return LLURI::buildHTTP(hostUrl, path).asString();
+}
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
new file mode 100644
index 0000000000000000000000000000000000000000..cea1f13647dc2275182691c6ac022ab89d075b7d
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -0,0 +1,82 @@
+/** 
+ * @file llupdatechecker.h
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_UPDATERCHECKER_H
+#define LL_UPDATERCHECKER_H
+
+
+#include <boost/shared_ptr.hpp>
+
+
+//
+// Implements asynchronous checking for updates.
+//
+class LLUpdateChecker {
+public:
+	class Client;
+	class Implementation;
+	
+	// An exception that may be raised on check errors.
+	class CheckError;
+	
+	LLUpdateChecker(Client & client);
+	
+	// Check status of current app on the given host for the channel and version provided.
+	void check(std::string const & protocolVersion, std::string const & hostUrl, 
+			   std::string const & servicePath, std::string channel, std::string version);
+	
+private:
+	boost::shared_ptr<Implementation> mImplementation;
+};
+
+
+class LLURI; // From lluri.h
+
+
+//
+// The client interface implemented by a requestor checking for an update.
+//
+class LLUpdateChecker::Client
+{
+public:
+	// An error occurred while checking for an update.
+	virtual void error(std::string const & message) = 0;
+	
+	// A newer version is available, but the current version may still be used.
+	virtual void optionalUpdate(std::string const & newVersion,
+								LLURI const & uri,
+								std::string const & hash) = 0;
+	
+	// A newer version is available, and the current version is no longer valid. 
+	virtual void requiredUpdate(std::string const & newVersion,
+								LLURI const & uri,
+								std::string const & hash) = 0;
+	
+	// The checked version is up to date; no newer version exists.
+	virtual void upToDate(void) = 0;
+};
+
+
+#endif
diff --git a/indra/viewer_components/updater/llupdatedownloader.cpp b/indra/viewer_components/updater/llupdatedownloader.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e88d1bf811d726056cf63c03ccb5a1910f20b3a4
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatedownloader.cpp
@@ -0,0 +1,517 @@
+/** 
+ * @file llupdatedownloader.cpp
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llupdatedownloader.h"
+
+#include <stdexcept>
+#include <boost/format.hpp>
+#include <boost/lexical_cast.hpp>
+#include <curl/curl.h>
+#include "lldir.h"
+#include "llevents.h"
+#include "llfile.h"
+#include "llmd5.h"
+#include "llsd.h"
+#include "llsdserialize.h"
+#include "llthread.h"
+#include "llupdaterservice.h"
+
+
+class LLUpdateDownloader::Implementation:
+	public LLThread
+{
+public:
+	Implementation(LLUpdateDownloader::Client & client);
+	~Implementation();
+	void cancel(void);
+	void download(LLURI const & uri,
+				  std::string const & hash,
+				  std::string const & updateVersion,
+				  bool required);
+	bool isDownloading(void);
+	size_t onHeader(void * header, size_t size);
+	size_t onBody(void * header, size_t size);
+	int onProgress(double downloadSize, double bytesDownloaded);
+	void resume(void);
+	void setBandwidthLimit(U64 bytesPerSecond);
+	
+private:
+	curl_off_t mBandwidthLimit;
+	bool mCancelled;
+	LLUpdateDownloader::Client & mClient;
+	CURL * mCurl;
+	LLSD mDownloadData;
+	llofstream mDownloadStream;
+	unsigned char mDownloadPercent;
+	std::string mDownloadRecordPath;
+	curl_slist * mHeaderList;
+	
+	void initializeCurlGet(std::string const & url, bool processHeader);
+	void resumeDownloading(size_t startByte);
+	void run(void);
+	void startDownloading(LLURI const & uri, std::string const & hash);
+	void throwOnCurlError(CURLcode code);
+	bool validateDownload(void);
+
+	LOG_CLASS(LLUpdateDownloader::Implementation);
+};
+
+
+namespace {
+	class DownloadError:
+		public std::runtime_error
+	{
+	public:
+		DownloadError(const char * message):
+			std::runtime_error(message)
+		{
+			; // No op.
+		}
+	};
+
+		
+	const char * gSecondLifeUpdateRecord = "SecondLifeUpdateDownload.xml";
+};
+
+
+
+// LLUpdateDownloader
+//-----------------------------------------------------------------------------
+
+
+
+std::string LLUpdateDownloader::downloadMarkerPath(void)
+{
+	return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, gSecondLifeUpdateRecord);
+}
+
+
+LLUpdateDownloader::LLUpdateDownloader(Client & client):
+	mImplementation(new LLUpdateDownloader::Implementation(client))
+{
+	; // No op.
+}
+
+
+void LLUpdateDownloader::cancel(void)
+{
+	mImplementation->cancel();
+}
+
+
+void LLUpdateDownloader::download(LLURI const & uri,
+								  std::string const & hash,
+								  std::string const & updateVersion,
+								  bool required)
+{
+	mImplementation->download(uri, hash, updateVersion, required);
+}
+
+
+bool LLUpdateDownloader::isDownloading(void)
+{
+	return mImplementation->isDownloading();
+}
+
+
+void LLUpdateDownloader::resume(void)
+{
+	mImplementation->resume();
+}
+
+
+void LLUpdateDownloader::setBandwidthLimit(U64 bytesPerSecond)
+{
+	mImplementation->setBandwidthLimit(bytesPerSecond);
+}
+
+
+
+// LLUpdateDownloader::Implementation
+//-----------------------------------------------------------------------------
+
+
+namespace {
+	size_t write_function(void * data, size_t blockSize, size_t blocks, void * downloader)
+	{
+		size_t bytes = blockSize * blocks;
+		return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onBody(data, bytes);
+	}
+
+
+	size_t header_function(void * data, size_t blockSize, size_t blocks, void * downloader)
+	{
+		size_t bytes = blockSize * blocks;
+		return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->onHeader(data, bytes);
+	}
+
+
+	int progress_callback(void * downloader,
+						  double dowloadTotal,
+						  double downloadNow,
+						  double uploadTotal,
+						  double uploadNow)
+	{
+		return reinterpret_cast<LLUpdateDownloader::Implementation *>(downloader)->
+			onProgress(dowloadTotal, downloadNow);
+	}
+}
+
+
+LLUpdateDownloader::Implementation::Implementation(LLUpdateDownloader::Client & client):
+	LLThread("LLUpdateDownloader"),
+	mBandwidthLimit(0),
+	mCancelled(false),
+	mClient(client),
+	mCurl(0),
+	mDownloadPercent(0),
+	mHeaderList(0)
+{
+	CURLcode code = curl_global_init(CURL_GLOBAL_ALL); // Just in case.
+	llverify(code == CURLE_OK); // TODO: real error handling here. 
+}
+
+
+LLUpdateDownloader::Implementation::~Implementation()
+{
+	if(isDownloading()) {
+		cancel();
+		shutdown();
+	} else {
+		; // No op.
+	}
+	if(mCurl) curl_easy_cleanup(mCurl);
+}
+
+
+void LLUpdateDownloader::Implementation::cancel(void)
+{
+	mCancelled = true;
+}
+	
+
+void LLUpdateDownloader::Implementation::download(LLURI const & uri,
+												  std::string const & hash,
+												  std::string const & updateVersion,
+												  bool required)
+{
+	if(isDownloading()) mClient.downloadError("download in progress");
+
+	mDownloadRecordPath = downloadMarkerPath();
+	mDownloadData = LLSD();
+	mDownloadData["required"] = required;
+	mDownloadData["update_version"] = updateVersion;
+	try {
+		startDownloading(uri, hash);
+	} catch(DownloadError const & e) {
+		mClient.downloadError(e.what());
+	}
+}
+
+
+bool LLUpdateDownloader::Implementation::isDownloading(void)
+{
+	return !isStopped();
+}
+
+
+void LLUpdateDownloader::Implementation::resume(void)
+{
+	mCancelled = false;
+
+	if(isDownloading()) {
+		mClient.downloadError("download in progress");
+	}
+
+	mDownloadRecordPath = downloadMarkerPath();
+	llifstream dataStream(mDownloadRecordPath);
+	if(!dataStream) {
+		mClient.downloadError("no download marker");
+		return;
+	}
+	
+	LLSDSerialize::fromXMLDocument(mDownloadData, dataStream);
+	
+	if(!mDownloadData.asBoolean()) {
+		mClient.downloadError("no download information in marker");
+		return;
+	}
+	
+	std::string filePath = mDownloadData["path"].asString();
+	try {
+		if(LLFile::isfile(filePath)) {		
+			llstat fileStatus;
+			LLFile::stat(filePath, &fileStatus);
+			if(fileStatus.st_size != mDownloadData["size"].asInteger()) {
+				resumeDownloading(fileStatus.st_size);
+			} else if(!validateDownload()) {
+				LLFile::remove(filePath);
+				download(LLURI(mDownloadData["url"].asString()), 
+						 mDownloadData["hash"].asString(),
+						 mDownloadData["update_version"].asString(),
+						 mDownloadData["required"].asBoolean());
+			} else {
+				mClient.downloadComplete(mDownloadData);
+			}
+		} else {
+			download(LLURI(mDownloadData["url"].asString()), 
+					 mDownloadData["hash"].asString(),
+					 mDownloadData["update_version"].asString(),
+					 mDownloadData["required"].asBoolean());
+		}
+	} catch(DownloadError & e) {
+		mClient.downloadError(e.what());
+	}
+}
+
+
+void LLUpdateDownloader::Implementation::setBandwidthLimit(U64 bytesPerSecond)
+{
+	if((mBandwidthLimit != bytesPerSecond) && isDownloading() && !mDownloadData["required"].asBoolean()) {
+		llassert(mCurl != 0);
+		mBandwidthLimit = bytesPerSecond;
+		CURLcode code = curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, &mBandwidthLimit);
+		if(code != CURLE_OK) LL_WARNS("UpdateDownload") << 
+			"unable to change dowload bandwidth" << LL_ENDL;
+	} else {
+		mBandwidthLimit = bytesPerSecond;
+	}
+}
+
+
+size_t LLUpdateDownloader::Implementation::onHeader(void * buffer, size_t size)
+{
+	char const * headerPtr = reinterpret_cast<const char *> (buffer);
+	std::string header(headerPtr, headerPtr + size);
+	size_t colonPosition = header.find(':');
+	if(colonPosition == std::string::npos) return size; // HTML response; ignore.
+	
+	if(header.substr(0, colonPosition) == "Content-Length") {
+		try {
+			size_t firstDigitPos = header.find_first_of("0123456789", colonPosition);
+			size_t lastDigitPos = header.find_last_of("0123456789");
+			std::string contentLength = header.substr(firstDigitPos, lastDigitPos - firstDigitPos + 1);
+			size_t size = boost::lexical_cast<size_t>(contentLength);
+			LL_INFOS("UpdateDownload") << "download size is " << size << LL_ENDL;
+			
+			mDownloadData["size"] = LLSD(LLSD::Integer(size));
+			llofstream odataStream(mDownloadRecordPath);
+			LLSDSerialize::toPrettyXML(mDownloadData, odataStream);
+		} catch (std::exception const & e) {
+			LL_WARNS("UpdateDownload") << "unable to read content length (" 
+				<< e.what() << ")" << LL_ENDL;
+		}
+	} else {
+		; // No op.
+	}
+	
+	return size;
+}
+
+
+size_t LLUpdateDownloader::Implementation::onBody(void * buffer, size_t size)
+{
+	if(mCancelled) return 0; // Forces a write error which will halt curl thread.
+	if((size == 0) || (buffer == 0)) return 0; 
+	
+	mDownloadStream.write(reinterpret_cast<const char *>(buffer), size);
+	if(mDownloadStream.bad()) {
+		return 0;
+	} else {
+		return size;
+	}
+}
+
+
+int LLUpdateDownloader::Implementation::onProgress(double downloadSize, double bytesDownloaded)
+{
+	int downloadPercent = static_cast<int>(100. * (bytesDownloaded / downloadSize));
+	if(downloadPercent > mDownloadPercent) {
+		mDownloadPercent = downloadPercent;
+		
+		LLSD event;
+		event["pump"] = LLUpdaterService::pumpName();
+		LLSD payload;
+		payload["type"] = LLSD(LLUpdaterService::PROGRESS);
+		payload["download_size"] = downloadSize;
+		payload["bytes_downloaded"] = bytesDownloaded;
+		event["payload"] = payload;
+		LLEventPumps::instance().obtain("mainlooprepeater").post(event);
+		
+		LL_INFOS("UpdateDownload") << "progress event " << payload << LL_ENDL;
+	} else {
+		; // Keep events to a reasonalbe number.
+	}
+	
+	return 0;
+}
+
+
+void LLUpdateDownloader::Implementation::run(void)
+{
+	CURLcode code = curl_easy_perform(mCurl);
+	mDownloadStream.close();
+	if(code == CURLE_OK) {
+		LLFile::remove(mDownloadRecordPath);
+		if(validateDownload()) {
+			LL_INFOS("UpdateDownload") << "download successful" << LL_ENDL;
+			mClient.downloadComplete(mDownloadData);
+		} else {
+			LL_INFOS("UpdateDownload") << "download failed hash check" << LL_ENDL;
+			std::string filePath = mDownloadData["path"].asString();
+			if(filePath.size() != 0) LLFile::remove(filePath);
+			mClient.downloadError("failed hash check");
+		}
+	} else if(mCancelled && (code == CURLE_WRITE_ERROR)) {
+		LL_INFOS("UpdateDownload") << "download canceled by user" << LL_ENDL;
+		// Do not call back client.
+	} else {
+		LL_WARNS("UpdateDownload") << "download failed with error '" << 
+			curl_easy_strerror(code) << "'" << LL_ENDL;
+		LLFile::remove(mDownloadRecordPath);
+		if(mDownloadData.has("path")) LLFile::remove(mDownloadData["path"].asString());
+		mClient.downloadError("curl error");
+	}
+	
+	if(mHeaderList) {
+		curl_slist_free_all(mHeaderList);
+		mHeaderList = 0;
+	}
+}
+
+
+void LLUpdateDownloader::Implementation::initializeCurlGet(std::string const & url, bool processHeader)
+{
+	if(mCurl == 0) {
+		mCurl = curl_easy_init();
+	} else {
+		curl_easy_reset(mCurl);
+	}
+	
+	if(mCurl == 0) throw DownloadError("failed to initialize curl");
+	
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOSIGNAL, true));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_FOLLOWLOCATION, true));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEFUNCTION, &write_function));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_WRITEDATA, this));
+	if(processHeader) {
+	   throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERFUNCTION, &header_function));
+	   throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HEADERDATA, this));
+	}
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPGET, true));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_URL, url.c_str()));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_PROGRESSFUNCTION, &progress_callback));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_PROGRESSDATA, this));
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_NOPROGRESS, false));
+	// if it's a required update set the bandwidth limit to 0 (unlimited)
+	curl_off_t limit = mDownloadData["required"].asBoolean() ? 0 : mBandwidthLimit;
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_MAX_RECV_SPEED_LARGE, limit));
+	
+	mDownloadPercent = 0;
+}
+
+
+void LLUpdateDownloader::Implementation::resumeDownloading(size_t startByte)
+{
+	LL_INFOS("UpdateDownload") << "resuming download from " << mDownloadData["url"].asString()
+		<< " at byte " << startByte << LL_ENDL;
+
+	initializeCurlGet(mDownloadData["url"].asString(), false);
+	
+	// The header 'Range: bytes n-' will request the bytes remaining in the
+	// source begining with byte n and ending with the last byte.
+	boost::format rangeHeaderFormat("Range: bytes=%u-");
+	rangeHeaderFormat % startByte;
+	mHeaderList = curl_slist_append(mHeaderList, rangeHeaderFormat.str().c_str());
+	if(mHeaderList == 0) throw DownloadError("cannot add Range header");
+	throwOnCurlError(curl_easy_setopt(mCurl, CURLOPT_HTTPHEADER, mHeaderList));
+	
+	mDownloadStream.open(mDownloadData["path"].asString(),
+						 std::ios_base::out | std::ios_base::binary | std::ios_base::app);
+	start();
+}
+
+
+void LLUpdateDownloader::Implementation::startDownloading(LLURI const & uri, std::string const & hash)
+{
+	mDownloadData["url"] = uri.asString();
+	mDownloadData["hash"] = hash;
+	mDownloadData["current_version"] = ll_get_version();
+	LLSD path = uri.pathArray();
+	if(path.size() == 0) throw DownloadError("no file path");
+	std::string fileName = path[path.size() - 1].asString();
+	std::string filePath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, fileName);
+	mDownloadData["path"] = filePath;
+
+	LL_INFOS("UpdateDownload") << "downloading " << filePath
+		<< " from " << uri.asString() << LL_ENDL;
+	LL_INFOS("UpdateDownload") << "hash of file is " << hash << LL_ENDL;
+		
+	llofstream dataStream(mDownloadRecordPath);
+	LLSDSerialize::toPrettyXML(mDownloadData, dataStream);
+	
+	mDownloadStream.open(filePath, std::ios_base::out | std::ios_base::binary);
+	initializeCurlGet(uri.asString(), true);
+	start();
+}
+
+
+void LLUpdateDownloader::Implementation::throwOnCurlError(CURLcode code)
+{
+	if(code != CURLE_OK) {
+		const char * errorString = curl_easy_strerror(code);
+		if(errorString != 0) {
+			throw DownloadError(curl_easy_strerror(code));
+		} else {
+			throw DownloadError("unknown curl error");
+		}
+	} else {
+		; // No op.
+	}
+}
+
+
+bool LLUpdateDownloader::Implementation::validateDownload(void)
+{
+	std::string filePath = mDownloadData["path"].asString();
+	llifstream fileStream(filePath, std::ios_base::in | std::ios_base::binary);
+	if(!fileStream) return false;
+
+	std::string hash = mDownloadData["hash"].asString();
+	if(hash.size() != 0) {
+		LL_INFOS("UpdateDownload") << "checking hash..." << LL_ENDL;
+		char digest[33];
+		LLMD5(fileStream).hex_digest(digest);
+		if(hash != digest) {
+			LL_WARNS("UpdateDownload") << "download hash mismatch; expeted " << hash <<
+				" but download is " << digest << LL_ENDL;
+		}
+		return hash == digest;
+	} else {
+		return true; // No hash check provided.
+	}
+}
diff --git a/indra/viewer_components/updater/llupdatedownloader.h b/indra/viewer_components/updater/llupdatedownloader.h
new file mode 100644
index 0000000000000000000000000000000000000000..0d635640cf2e1d6734f6745dbe51e5b132c94309
--- /dev/null
+++ b/indra/viewer_components/updater/llupdatedownloader.h
@@ -0,0 +1,94 @@
+/** 
+ * @file llupdatedownloader.h
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_UPDATE_DOWNLOADER_H
+#define LL_UPDATE_DOWNLOADER_H
+
+
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include "lluri.h"
+
+
+//
+// An asynchronous download service for fetching updates.
+//
+class LLUpdateDownloader
+{
+public:
+	class Client;
+	class Implementation;
+	
+	// Returns the path to the download marker file containing details of the
+	// latest download.
+	static std::string downloadMarkerPath(void);
+	
+	LLUpdateDownloader(Client & client);
+	
+	// Cancel any in progress download; a no op if none is in progress.  The
+	// client will not receive a complete or error callback.
+	void cancel(void);
+	
+	// Start a new download.
+	void download(LLURI const & uri,
+				  std::string const & hash, 
+				  std::string const & updateVersion,
+				  bool required=false);
+	
+	// Returns true if a download is in progress.
+	bool isDownloading(void);
+	
+	// Resume a partial download.
+	void resume(void);
+	
+	// Set a limit on the dowload rate.
+	void setBandwidthLimit(U64 bytesPerSecond);
+	
+private:
+	boost::shared_ptr<Implementation> mImplementation;
+};
+
+
+//
+// An interface to be implemented by clients initiating a update download.
+//
+class LLUpdateDownloader::Client {
+public:
+	
+	// The download has completed successfully.
+	// data is a map containing the following items:
+	// url - source (remote) location
+	// hash - the md5 sum that should match the installer file.
+	// path - destination (local) location
+	// required - boolean indicating if this is a required update.
+	// size - the size of the installer in bytes
+	virtual void downloadComplete(LLSD const & data) = 0;
+	
+	// The download failed.
+	virtual void downloadError(std::string const & message) = 0;
+};
+
+
+#endif
diff --git a/indra/viewer_components/updater/llupdateinstaller.cpp b/indra/viewer_components/updater/llupdateinstaller.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d450c068ade8b4bc0c481505a8057a379ec83701
--- /dev/null
+++ b/indra/viewer_components/updater/llupdateinstaller.cpp
@@ -0,0 +1,100 @@
+/** 
+ * @file llupdateinstaller.cpp
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include <apr_file_io.h>
+#include "llapr.h"
+#include "llprocesslauncher.h"
+#include "llupdateinstaller.h"
+#include "lldir.h"
+
+
+#if defined(LL_WINDOWS)
+#pragma warning(disable: 4702)      // disable 'unreachable code' so we can use lexical_cast (really!).
+#endif
+#include <boost/lexical_cast.hpp>
+
+
+namespace {
+	class RelocateError {};
+	
+	
+	std::string copy_to_temp(std::string const & path)
+	{
+		std::string scriptFile = gDirUtilp->getBaseFileName(path);
+		std::string newPath = gDirUtilp->getExpandedFilename(LL_PATH_TEMP, scriptFile);
+		apr_status_t status = apr_file_copy(path.c_str(), newPath.c_str(), APR_FILE_SOURCE_PERMS, gAPRPoolp);
+		if(status != APR_SUCCESS) throw RelocateError();
+		
+		return newPath;
+	}
+}
+
+
+int ll_install_update(std::string const & script,
+					  std::string const & updatePath,
+					  bool required,
+					  LLInstallScriptMode mode)
+{
+	std::string actualScriptPath;
+	switch(mode) {
+		case LL_COPY_INSTALL_SCRIPT_TO_TEMP:
+			try {
+				actualScriptPath = copy_to_temp(script);
+			}
+			catch (RelocateError &) {
+				return -1;
+			}
+			break;
+		case LL_RUN_INSTALL_SCRIPT_IN_PLACE:
+			actualScriptPath = script;
+			break;
+		default:
+			llassert(!"unpossible copy mode");
+	}
+	
+	llinfos << "UpdateInstaller: installing " << updatePath << " using " <<
+		actualScriptPath << LL_ENDL;
+	
+	LLProcessLauncher launcher;
+	launcher.setExecutable(actualScriptPath);
+	launcher.addArgument(updatePath);
+	launcher.addArgument(ll_install_failed_marker_path().c_str());
+	launcher.addArgument(boost::lexical_cast<std::string>(required));
+	int result = launcher.launch();
+	launcher.orphan();
+	
+	return result;
+}
+
+
+std::string const & ll_install_failed_marker_path(void)
+{
+	static std::string path;
+	if(path.empty()) {
+		path = gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "SecondLifeInstallFailed.marker");
+	}
+	return path;
+}
diff --git a/indra/viewer_components/updater/llupdateinstaller.h b/indra/viewer_components/updater/llupdateinstaller.h
new file mode 100644
index 0000000000000000000000000000000000000000..fe5b1d19b52f2fb7b0651f5ec21acd21efac4ebb
--- /dev/null
+++ b/indra/viewer_components/updater/llupdateinstaller.h
@@ -0,0 +1,58 @@
+/** 
+ * @file llupdateinstaller.h
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_UPDATE_INSTALLER_H
+#define LL_UPDATE_INSTALLER_H
+
+
+#include <string>
+
+
+enum LLInstallScriptMode {
+	LL_RUN_INSTALL_SCRIPT_IN_PLACE,
+	LL_COPY_INSTALL_SCRIPT_TO_TEMP
+};
+
+//
+// Launch the installation script.
+// 
+// The updater will overwrite the current installation, so it is highly recommended
+// that the current application terminate once this function is called.
+//
+int ll_install_update(
+					  std::string const & script, // Script to execute.
+					  std::string const & updatePath, // Path to update file.
+					  bool required, // Is the update required.
+					  LLInstallScriptMode mode=LL_COPY_INSTALL_SCRIPT_TO_TEMP); // Run in place or copy to temp?
+
+
+//
+// Returns the path which points to the failed install marker file, should it
+// exist.
+//
+std::string const & ll_install_failed_marker_path(void);
+
+
+#endif
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aa4983a3b6634984df873f706787e7a4a1c128d9
--- /dev/null
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -0,0 +1,622 @@
+/** 
+ * @file llupdaterservice.cpp
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llupdaterservice.h"
+
+#include "llupdatedownloader.h"
+#include "llevents.h"
+#include "lltimer.h"
+#include "llupdatechecker.h"
+#include "llupdateinstaller.h"
+#include "llversionviewer.h"
+
+#include <boost/scoped_ptr.hpp>
+#include <boost/weak_ptr.hpp>
+#include "lldir.h"
+#include "llsdserialize.h"
+#include "llfile.h"
+
+#if LL_WINDOWS
+#pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
+#endif
+
+
+namespace 
+{
+	boost::weak_ptr<LLUpdaterServiceImpl> gUpdater;
+
+	const std::string UPDATE_MARKER_FILENAME("SecondLifeUpdateReady.xml");
+	std::string update_marker_path()
+	{
+		return gDirUtilp->getExpandedFilename(LL_PATH_LOGS, 
+											  UPDATE_MARKER_FILENAME);
+	}
+	
+	std::string install_script_path(void)
+	{
+#ifdef LL_WINDOWS
+		std::string scriptFile = "update_install.bat";
+#else
+		std::string scriptFile = "update_install";
+#endif
+		return gDirUtilp->getExpandedFilename(LL_PATH_EXECUTABLE, scriptFile);
+	}
+	
+	LLInstallScriptMode install_script_mode(void) 
+	{
+#ifdef LL_WINDOWS
+		return LL_COPY_INSTALL_SCRIPT_TO_TEMP;
+#else
+		return LL_RUN_INSTALL_SCRIPT_IN_PLACE;
+#endif
+	};
+	
+}
+
+class LLUpdaterServiceImpl : 
+	public LLUpdateChecker::Client,
+	public LLUpdateDownloader::Client
+{
+	static const std::string sListenerName;
+	
+	std::string mProtocolVersion;
+	std::string mUrl;
+	std::string mPath;
+	std::string mChannel;
+	std::string mVersion;
+	
+	unsigned int mCheckPeriod;
+	bool mIsChecking;
+	bool mIsDownloading;
+	
+	LLUpdateChecker mUpdateChecker;
+	LLUpdateDownloader mUpdateDownloader;
+	LLTimer mTimer;
+
+	LLUpdaterService::app_exit_callback_t mAppExitCallback;
+	
+	LLUpdaterService::eUpdaterState mState;
+	
+	LOG_CLASS(LLUpdaterServiceImpl);
+	
+public:
+	LLUpdaterServiceImpl();
+	virtual ~LLUpdaterServiceImpl();
+
+	void initialize(const std::string& protocol_version,
+				   const std::string& url, 
+				   const std::string& path,
+				   const std::string& channel,
+				   const std::string& version);
+	
+	void setCheckPeriod(unsigned int seconds);
+	void setBandwidthLimit(U64 bytesPerSecond);
+
+	void startChecking(bool install_if_ready);
+	void stopChecking();
+	bool isChecking();
+	LLUpdaterService::eUpdaterState getState();
+	
+	void setAppExitCallback(LLUpdaterService::app_exit_callback_t aecb) { mAppExitCallback = aecb;}
+	std::string updatedVersion(void);
+
+	bool checkForInstall(bool launchInstaller); // Test if a local install is ready.
+	bool checkForResume(); // Test for resumeable d/l.
+
+	// LLUpdateChecker::Client:
+	virtual void error(std::string const & message);
+	virtual void optionalUpdate(std::string const & newVersion,
+								LLURI const & uri,
+								std::string const & hash);
+	virtual void requiredUpdate(std::string const & newVersion,
+								LLURI const & uri,
+								std::string const & hash);
+	virtual void upToDate(void);
+	
+	// LLUpdateDownloader::Client
+	void downloadComplete(LLSD const & data);
+	void downloadError(std::string const & message);
+
+	bool onMainLoop(LLSD const & event);
+
+private:
+	std::string mNewVersion;
+	
+	void restartTimer(unsigned int seconds);
+	void setState(LLUpdaterService::eUpdaterState state);
+	void stopTimer();
+};
+
+const std::string LLUpdaterServiceImpl::sListenerName = "LLUpdaterServiceImpl";
+
+LLUpdaterServiceImpl::LLUpdaterServiceImpl() :
+	mIsChecking(false),
+	mIsDownloading(false),
+	mCheckPeriod(0),
+	mUpdateChecker(*this),
+	mUpdateDownloader(*this),
+	mState(LLUpdaterService::INITIAL)
+{
+}
+
+LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
+{
+	LL_INFOS("UpdaterService") << "shutting down updater service" << LL_ENDL;
+	LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
+}
+
+void LLUpdaterServiceImpl::initialize(const std::string& protocol_version,
+									  const std::string& url, 
+									  const std::string& path,
+									  const std::string& channel,
+									  const std::string& version)
+{
+	if(mIsChecking || mIsDownloading)
+	{
+		throw LLUpdaterService::UsageError("LLUpdaterService::initialize call "
+										   "while updater is running.");
+	}
+		
+	mProtocolVersion = protocol_version;
+	mUrl = url;
+	mPath = path;
+	mChannel = channel;
+	mVersion = version;
+}
+
+void LLUpdaterServiceImpl::setCheckPeriod(unsigned int seconds)
+{
+	mCheckPeriod = seconds;
+}
+
+void LLUpdaterServiceImpl::setBandwidthLimit(U64 bytesPerSecond)
+{
+	mUpdateDownloader.setBandwidthLimit(bytesPerSecond);
+}
+
+void LLUpdaterServiceImpl::startChecking(bool install_if_ready)
+{
+	if(mUrl.empty() || mChannel.empty() || mVersion.empty())
+	{
+		throw LLUpdaterService::UsageError("Set params before call to "
+			"LLUpdaterService::startCheck().");
+	}
+
+	mIsChecking = true;
+
+    // Check to see if an install is ready.
+	bool has_install = checkForInstall(install_if_ready);
+	if(!has_install)
+	{
+		checkForResume(); // will set mIsDownloading to true if resuming
+
+		if(!mIsDownloading)
+		{
+			setState(LLUpdaterService::CHECKING_FOR_UPDATE);
+			
+			// Checking can only occur during the mainloop.
+			// reset the timer to 0 so that the next mainloop event 
+			// triggers a check;
+			restartTimer(0); 
+		} 
+		else
+		{
+			setState(LLUpdaterService::DOWNLOADING);
+		}
+	}
+}
+
+void LLUpdaterServiceImpl::stopChecking()
+{
+	if(mIsChecking)
+	{
+		mIsChecking = false;
+		stopTimer();
+	}
+
+    if(mIsDownloading)
+    {
+        mUpdateDownloader.cancel();
+		mIsDownloading = false;
+    }
+	
+	setState(LLUpdaterService::TERMINAL);
+}
+
+bool LLUpdaterServiceImpl::isChecking()
+{
+	return mIsChecking;
+}
+
+LLUpdaterService::eUpdaterState LLUpdaterServiceImpl::getState()
+{
+	return mState;
+}
+
+std::string LLUpdaterServiceImpl::updatedVersion(void)
+{
+	return mNewVersion;
+}
+
+bool LLUpdaterServiceImpl::checkForInstall(bool launchInstaller)
+{
+	bool foundInstall = false; // return true if install is found.
+
+	llifstream update_marker(update_marker_path(), 
+							 std::ios::in | std::ios::binary);
+
+	if(update_marker.is_open())
+	{
+		// Found an update info - now lets see if its valid.
+		LLSD update_info;
+		LLSDSerialize::fromXMLDocument(update_info, update_marker);
+		update_marker.close();
+
+		// Get the path to the installer file.
+		LLSD path = update_info.get("path");
+		if(update_info["current_version"].asString() != ll_get_version())
+		{
+			// This viewer is not the same version as the one that downloaded
+			// the update.  Do not install this update.
+			if(!path.asString().empty())
+			{
+				llinfos << "ignoring update dowloaded by different client version" << llendl;
+				LLFile::remove(path.asString());
+				LLFile::remove(update_marker_path());
+			}
+			else
+			{
+				; // Nothing to clean up.
+			}
+			
+			foundInstall = false;
+		} 
+		else if(path.isDefined() && !path.asString().empty())
+		{
+			if(launchInstaller)
+			{
+				setState(LLUpdaterService::INSTALLING);
+				
+				LLFile::remove(update_marker_path());
+
+				int result = ll_install_update(install_script_path(),
+											   update_info["path"].asString(),
+											   update_info["required"].asBoolean(),
+											   install_script_mode());	
+				
+				if((result == 0) && mAppExitCallback)
+				{
+					mAppExitCallback();
+				} else if(result != 0) {
+					llwarns << "failed to run update install script" << LL_ENDL;
+				} else {
+					; // No op.
+				}
+			}
+			
+			foundInstall = true;
+		}
+	}
+	return foundInstall;
+}
+
+bool LLUpdaterServiceImpl::checkForResume()
+{
+	bool result = false;
+	std::string download_marker_path = mUpdateDownloader.downloadMarkerPath();
+	if(LLFile::isfile(download_marker_path))
+	{
+		llifstream download_marker_stream(download_marker_path, 
+								 std::ios::in | std::ios::binary);
+		if(download_marker_stream.is_open())
+		{
+			LLSD download_info;
+			LLSDSerialize::fromXMLDocument(download_info, download_marker_stream);
+			download_marker_stream.close();
+			if(download_info["current_version"].asString() == ll_get_version())
+			{
+				mIsDownloading = true;
+				mNewVersion = download_info["update_version"].asString();
+				mUpdateDownloader.resume();
+				result = true;
+			}
+			else 
+			{
+				// The viewer that started this download is not the same as this viewer; ignore.
+				llinfos << "ignoring partial download from different viewer version" << llendl;
+				std::string path = download_info["path"].asString();
+				if(!path.empty()) LLFile::remove(path);
+				LLFile::remove(download_marker_path);
+			}
+		} 
+	}
+	return result;
+}
+
+void LLUpdaterServiceImpl::error(std::string const & message)
+{
+	if(mIsChecking)
+	{
+		restartTimer(mCheckPeriod);
+	}
+}
+
+void LLUpdaterServiceImpl::optionalUpdate(std::string const & newVersion,
+										  LLURI const & uri,
+										  std::string const & hash)
+{
+	stopTimer();
+	mNewVersion = newVersion;
+	mIsDownloading = true;
+	mUpdateDownloader.download(uri, hash, newVersion, false);
+	
+	setState(LLUpdaterService::DOWNLOADING);
+}
+
+void LLUpdaterServiceImpl::requiredUpdate(std::string const & newVersion,
+										  LLURI const & uri,
+										  std::string const & hash)
+{
+	stopTimer();
+	mNewVersion = newVersion;
+	mIsDownloading = true;
+	mUpdateDownloader.download(uri, hash, newVersion, true);
+	
+	setState(LLUpdaterService::DOWNLOADING);
+}
+
+void LLUpdaterServiceImpl::upToDate(void)
+{
+	if(mIsChecking)
+	{
+		restartTimer(mCheckPeriod);
+	}
+	
+	setState(LLUpdaterService::UP_TO_DATE);
+}
+
+void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) 
+{ 
+	mIsDownloading = false;
+
+	// Save out the download data to the SecondLifeUpdateReady
+	// marker file. 
+	llofstream update_marker(update_marker_path());
+	LLSDSerialize::toPrettyXML(data, update_marker);
+	
+	LLSD event;
+	event["pump"] = LLUpdaterService::pumpName();
+	LLSD payload;
+	payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_COMPLETE);
+	payload["required"] = data["required"];
+	payload["version"] = mNewVersion;
+	event["payload"] = payload;
+	LLEventPumps::instance().obtain("mainlooprepeater").post(event);
+	
+	setState(LLUpdaterService::TERMINAL);
+}
+
+void LLUpdaterServiceImpl::downloadError(std::string const & message) 
+{ 
+	LL_INFOS("UpdaterService") << "Error downloading: " << message << LL_ENDL;
+
+	mIsDownloading = false;
+
+	// Restart the timer on error
+	if(mIsChecking)
+	{
+		restartTimer(mCheckPeriod); 
+	}
+
+	LLSD event;
+	event["pump"] = LLUpdaterService::pumpName();
+	LLSD payload;
+	payload["type"] = LLSD(LLUpdaterService::DOWNLOAD_ERROR);
+	payload["message"] = message;
+	event["payload"] = payload;
+	LLEventPumps::instance().obtain("mainlooprepeater").post(event);
+
+	setState(LLUpdaterService::FAILURE);
+}
+
+void LLUpdaterServiceImpl::restartTimer(unsigned int seconds)
+{
+	LL_INFOS("UpdaterService") << "will check for update again in " << 
+	seconds << " seconds" << LL_ENDL; 
+	mTimer.start();
+	mTimer.setTimerExpirySec(seconds);
+	LLEventPumps::instance().obtain("mainloop").listen(
+		sListenerName, boost::bind(&LLUpdaterServiceImpl::onMainLoop, this, _1));
+}
+
+void LLUpdaterServiceImpl::setState(LLUpdaterService::eUpdaterState state)
+{
+	if(state != mState)
+	{
+		mState = state;
+		
+		LLSD event;
+		event["pump"] = LLUpdaterService::pumpName();
+		LLSD payload;
+		payload["type"] = LLSD(LLUpdaterService::STATE_CHANGE);
+		payload["state"] = state;
+		event["payload"] = payload;
+		LLEventPumps::instance().obtain("mainlooprepeater").post(event);
+		
+		LL_INFOS("UpdaterService") << "setting state to " << state << LL_ENDL;
+	}
+	else 
+	{
+		; // State unchanged; noop.
+	}
+}
+
+void LLUpdaterServiceImpl::stopTimer()
+{
+	mTimer.stop();
+	LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
+}
+
+bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
+{
+	if(mTimer.getStarted() && mTimer.hasExpired())
+	{
+		stopTimer();
+
+		// Check for failed install.
+		if(LLFile::isfile(ll_install_failed_marker_path()))
+		{
+			int requiredValue = 0; 
+			{
+				llifstream stream(ll_install_failed_marker_path());
+				stream >> requiredValue;
+				if(stream.fail()) requiredValue = 0;
+			}
+			// TODO: notify the user.
+			llinfos << "found marker " << ll_install_failed_marker_path() << llendl;
+			llinfos << "last install attempt failed" << llendl;
+			LLFile::remove(ll_install_failed_marker_path());
+			
+			LLSD event;
+			event["type"] = LLSD(LLUpdaterService::INSTALL_ERROR);
+			event["required"] = LLSD(requiredValue);
+			LLEventPumps::instance().obtain(LLUpdaterService::pumpName()).post(event);
+			
+			setState(LLUpdaterService::TERMINAL);
+		}
+		else
+		{
+			mUpdateChecker.check(mProtocolVersion, mUrl, mPath, mChannel, mVersion);
+			setState(LLUpdaterService::CHECKING_FOR_UPDATE);
+		}
+	} 
+	else 
+	{
+		// Keep on waiting...
+	}
+	
+	return false;
+}
+
+
+//-----------------------------------------------------------------------
+// Facade interface
+
+std::string const & LLUpdaterService::pumpName(void)
+{
+	static std::string name("updater_service");
+	return name;
+}
+
+bool LLUpdaterService::updateReadyToInstall(void)
+{
+	return LLFile::isfile(update_marker_path());
+}
+
+LLUpdaterService::LLUpdaterService()
+{
+	if(gUpdater.expired())
+	{
+		mImpl = 
+			boost::shared_ptr<LLUpdaterServiceImpl>(new LLUpdaterServiceImpl());
+		gUpdater = mImpl;
+	}
+	else
+	{
+		mImpl = gUpdater.lock();
+	}
+}
+
+LLUpdaterService::~LLUpdaterService()
+{
+}
+
+void LLUpdaterService::initialize(const std::string& protocol_version,
+								 const std::string& url, 
+								 const std::string& path,
+								 const std::string& channel,
+								 const std::string& version)
+{
+	mImpl->initialize(protocol_version, url, path, channel, version);
+}
+
+void LLUpdaterService::setCheckPeriod(unsigned int seconds)
+{
+	mImpl->setCheckPeriod(seconds);
+}
+
+void LLUpdaterService::setBandwidthLimit(U64 bytesPerSecond)
+{
+	mImpl->setBandwidthLimit(bytesPerSecond);
+}
+	
+void LLUpdaterService::startChecking(bool install_if_ready)
+{
+	mImpl->startChecking(install_if_ready);
+}
+
+void LLUpdaterService::stopChecking()
+{
+	mImpl->stopChecking();
+}
+
+bool LLUpdaterService::isChecking()
+{
+	return mImpl->isChecking();
+}
+
+LLUpdaterService::eUpdaterState LLUpdaterService::getState()
+{
+	return mImpl->getState();
+}
+
+void LLUpdaterService::setImplAppExitCallback(LLUpdaterService::app_exit_callback_t aecb)
+{
+	return mImpl->setAppExitCallback(aecb);
+}
+
+std::string LLUpdaterService::updatedVersion(void)
+{
+	return mImpl->updatedVersion();
+}
+
+
+std::string const & ll_get_version(void) {
+	static std::string version("");
+	
+	if (version.empty()) {
+		std::ostringstream stream;
+		stream << LL_VERSION_MAJOR << "."
+		<< LL_VERSION_MINOR << "."
+		<< LL_VERSION_PATCH << "."
+		<< LL_VERSION_BUILD;
+		version = stream.str();
+	}
+	
+	return version;
+}
+
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
new file mode 100644
index 0000000000000000000000000000000000000000..421481bc43d0adfe44ad6d6bb12dbd8bc22e2d93
--- /dev/null
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -0,0 +1,107 @@
+/** 
+ * @file llupdaterservice.h
+ *
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_UPDATERSERVICE_H
+#define LL_UPDATERSERVICE_H
+
+#include <boost/shared_ptr.hpp>
+#include <boost/function.hpp>
+
+class LLUpdaterServiceImpl;
+
+class LLUpdaterService
+{
+public:
+	class UsageError: public std::runtime_error
+	{
+	public:
+		UsageError(const std::string& msg) : std::runtime_error(msg) {}
+	};
+	
+	// Name of the event pump through which update events will be delivered.
+	static std::string const & pumpName(void);
+	
+	// Returns true if an update has been completely downloaded and is now ready to install.
+	static bool updateReadyToInstall(void);
+	
+	// Type codes for events posted by this service.  Stored the event's 'type' element.
+	enum eUpdaterEvent {
+		INVALID,
+		DOWNLOAD_COMPLETE,
+		DOWNLOAD_ERROR,
+		INSTALL_ERROR,
+		PROGRESS,
+		STATE_CHANGE
+	};
+	
+	enum eUpdaterState {
+		INITIAL,
+		CHECKING_FOR_UPDATE,
+		DOWNLOADING,
+		INSTALLING,
+		UP_TO_DATE,
+		TERMINAL,
+		FAILURE
+	};
+
+	LLUpdaterService();
+	~LLUpdaterService();
+
+	void initialize(const std::string& protocol_version,
+				    const std::string& url, 
+				    const std::string& path,
+				    const std::string& channel,
+				    const std::string& version);
+
+	void setCheckPeriod(unsigned int seconds);
+	void setBandwidthLimit(U64 bytesPerSecond);
+	
+	void startChecking(bool install_if_ready = false);
+	void stopChecking();
+	bool isChecking();
+	eUpdaterState getState();
+
+	typedef boost::function<void (void)> app_exit_callback_t;
+	template <typename F>
+	void setAppExitCallback(F const &callable) 
+	{ 
+		app_exit_callback_t aecb = callable;
+		setImplAppExitCallback(aecb);
+	}
+	
+	// If an update is or has been downloaded, this method will return the
+	// version string for that update.  An empty string will be returned
+	// otherwise.
+	std::string updatedVersion(void);
+
+private:
+	boost::shared_ptr<LLUpdaterServiceImpl> mImpl;
+	void setImplAppExitCallback(app_exit_callback_t aecb);
+};
+
+// Returns the full version as a string.
+std::string const & ll_get_version(void);
+
+#endif // LL_UPDATERSERVICE_H
diff --git a/indra/viewer_components/updater/scripts/darwin/update_install b/indra/viewer_components/updater/scripts/darwin/update_install
new file mode 100644
index 0000000000000000000000000000000000000000..6a95f96d86f520e5543ac3925544d55b7204716a
--- /dev/null
+++ b/indra/viewer_components/updater/scripts/darwin/update_install
@@ -0,0 +1,10 @@
+#! /bin/bash
+
+#
+# The first argument contains the path to the installer app.  The second a path
+# to a marker file which should be created if the installer fails.q
+#
+
+cd "$(dirname "$0")"
+(../Resources/mac-updater.app/Contents/MacOS/mac-updater -dmg "$1" -name "Second Life Viewer 2"; if [ $? -ne 0 ]; then echo $3 >> "$2"; fi;) &
+exit 0
diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install
new file mode 100644
index 0000000000000000000000000000000000000000..88451340eca36ace15d01f845bba765b9933a7aa
--- /dev/null
+++ b/indra/viewer_components/updater/scripts/linux/update_install
@@ -0,0 +1,10 @@
+#! /bin/bash
+INSTALL_DIR=$(cd "$(dirname "$0")/.." ; pwd)
+export LD_LIBRARY_PATH="$INSTALL_DIR/lib"
+bin/linux-updater.bin --file "$1" --dest "$INSTALL_DIR" --name "Second Life Viewer 2" --stringsdir "$INSTALL_DIR/skins/default/xui/en" --stringsfile "strings.xml"
+
+if [ $? -ne 0 ]
+   then echo $3 >> "$2"
+fi
+
+rm -f "$1"
diff --git a/indra/viewer_components/updater/scripts/windows/update_install.bat b/indra/viewer_components/updater/scripts/windows/update_install.bat
new file mode 100644
index 0000000000000000000000000000000000000000..96687226a8d3d243cdb268707a4eecefbb1d33e1
--- /dev/null
+++ b/indra/viewer_components/updater/scripts/windows/update_install.bat
@@ -0,0 +1,3 @@
+start /WAIT %1 /SKIP_DIALOGS
+IF ERRORLEVEL 1 ECHO %3 > %2
+DEL %1
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5f8cd28f2976501f23f6eef2360ce4c228f6d215
--- /dev/null
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -0,0 +1,200 @@
+/**
+ * @file   llupdaterservice_test.cpp
+ * @brief  Tests of llupdaterservice.cpp.
+ * 
+ * $LicenseInfo:firstyear=2010&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "../llupdaterservice.h"
+#include "../llupdatechecker.h"
+#include "../llupdatedownloader.h"
+#include "../llupdateinstaller.h"
+
+#include "../../../test/lltut.h"
+//#define DEBUG_ON
+#include "../../../test/debug.h"
+
+#include "llevents.h"
+#include "lldir.h"
+
+/*****************************************************************************
+*   MOCK'd
+*****************************************************************************/
+LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
+{}
+void LLUpdateChecker::check(std::string const & protocolVersion, std::string const & hostUrl, 
+								  std::string const & servicePath, std::string channel, std::string version)
+{}
+LLUpdateDownloader::LLUpdateDownloader(Client & ) {}
+void LLUpdateDownloader::download(LLURI const & , std::string const &, std::string const &, bool){}
+
+class LLDir_Mock : public LLDir
+{
+	void initAppDirs(const std::string &app_name, 
+		   			 const std::string& app_read_only_data_dir = "") {}
+	U32 countFilesInDir(const std::string &dirname, const std::string &mask) 
+	{
+		return 0;
+	}
+
+	BOOL getNextFileInDir(const std::string &dirname, 
+						  const std::string &mask, 
+						  std::string &fname) 
+	{
+		return false;
+	}
+	void getRandomFileInDir(const std::string &dirname, 
+							const std::string &mask, 
+							std::string &fname) {}
+	std::string getCurPath() { return ""; }
+	BOOL fileExists(const std::string &filename) const { return false; }
+	std::string getLLPluginLauncher() { return ""; }
+	std::string getLLPluginFilename(std::string base_name) { return ""; }
+
+} gDirUtil;
+LLDir* gDirUtilp = &gDirUtil;
+LLDir::LLDir() {}
+LLDir::~LLDir() {}
+S32 LLDir::deleteFilesInDir(const std::string &dirname, 
+							const std::string &mask)
+{ return 0; }
+
+void LLDir::setChatLogsDir(const std::string &path){}		
+void LLDir::setPerAccountChatLogsDir(const std::string &username){}
+void LLDir::setLindenUserDir(const std::string &username){}		
+void LLDir::setSkinFolder(const std::string &skin_folder){}
+bool LLDir::setCacheDir(const std::string &path){ return true; }
+void LLDir::dumpCurrentDirectories() {}
+
+std::string LLDir::getExpandedFilename(ELLPath location, 
+									   const std::string &filename) const 
+{
+	return "";
+}
+
+std::string LLUpdateDownloader::downloadMarkerPath(void)
+{
+	return "";
+}
+
+void LLUpdateDownloader::resume(void) {}
+void LLUpdateDownloader::cancel(void) {}
+void LLUpdateDownloader::setBandwidthLimit(U64 bytesPerSecond) {}
+
+int ll_install_update(std::string const &, std::string const &, bool, LLInstallScriptMode)
+{
+	return 0;
+}
+
+std::string const & ll_install_failed_marker_path()
+{
+	static std::string wubba;
+	return wubba;
+}
+
+/*
+#pragma warning(disable: 4273)
+llus_mock_llifstream::llus_mock_llifstream(const std::string& _Filename,
+										   ios_base::openmode _Mode,
+										   int _Prot) :
+	std::basic_istream<char,std::char_traits< char > >(NULL,true)
+{}
+
+llus_mock_llifstream::~llus_mock_llifstream() {}
+bool llus_mock_llifstream::is_open() const {return true;}
+void llus_mock_llifstream::close() {}
+*/
+
+/*****************************************************************************
+*   TUT
+*****************************************************************************/
+namespace tut
+{
+    struct llupdaterservice_data
+    {
+		llupdaterservice_data() :
+            pumps(LLEventPumps::instance()),
+			test_url("dummy_url"),
+			test_channel("dummy_channel"),
+			test_version("dummy_version")
+		{}
+		LLEventPumps& pumps;
+		std::string test_url;
+		std::string test_channel;
+		std::string test_version;
+	};
+
+    typedef test_group<llupdaterservice_data> llupdaterservice_group;
+    typedef llupdaterservice_group::object llupdaterservice_object;
+    llupdaterservice_group llupdaterservicegrp("LLUpdaterService");
+
+    template<> template<>
+    void llupdaterservice_object::test<1>()
+    {
+        DEBUG;
+		LLUpdaterService updater;
+		bool got_usage_error = false;
+		try
+		{
+			updater.startChecking();
+		}
+		catch(LLUpdaterService::UsageError)
+		{
+			got_usage_error = true;
+		}
+		ensure("Caught start before params", got_usage_error);
+	}
+
+    template<> template<>
+    void llupdaterservice_object::test<2>()
+    {
+        DEBUG;
+		LLUpdaterService updater;
+		bool got_usage_error = false;
+		try
+		{
+			updater.initialize("1.0",test_url, "update" ,test_channel, test_version);
+			updater.startChecking();
+			updater.initialize("1.0", "other_url", "update", test_channel, test_version);
+		}
+		catch(LLUpdaterService::UsageError)
+		{
+			got_usage_error = true;
+		}
+		ensure("Caught params while running", got_usage_error);
+	}
+
+    template<> template<>
+    void llupdaterservice_object::test<3>()
+    {
+        DEBUG;
+		LLUpdaterService updater;
+		updater.initialize("1.0", test_url, "update", test_channel, test_version);
+		updater.startChecking();
+		ensure(updater.isChecking());
+		updater.stopChecking();
+		ensure(!updater.isChecking());
+	}
+}
diff --git a/install.xml b/install.xml
index ad2472bfdf58e53a959b9acff5e222d9cc4b69a6..13abaac1c1ce5a6ae5c9eecb3e2c00b2c7e42ad4 100644
--- a/install.xml
+++ b/install.xml
@@ -233,16 +233,16 @@
           <key>darwin</key>
           <map>
             <key>md5sum</key>
-            <string>752e295ccb17f0dcb7c0167db3ad1e69</string>
+            <string>ca8f0134fa5ab6f34a6eeb8d0896c9b0</string>
             <key>url</key>
-            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/curl-7.20.1-darwin-20100606.tar.bz2</uri>
+            <uri>https://s3.amazonaws.com/automated-builds-secondlife-com/hg/repo/brad_curl-autobuild/rev/216961/arch/Darwin/installer/curl-7.21.1-darwin-20101214.tar.bz2</uri>
           </map>
           <key>linux</key>
           <map>
             <key>md5sum</key>
-            <string>a20e73f2e7d6a032ff25a5161b1b7394</string>
+            <string>9c9b629b62bf874d550c430ad678dc04</string>
             <key>url</key>
-            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/curl-7.20.1-linux-20100527.tar.bz2</uri>
+            <uri>https://s3.amazonaws.com/automated-builds-secondlife-com/hg/repo/brad_curl-autobuild/rev/216961/arch/Linux/installer/curl-7.21.1-linux-20101215.tar.bz2</uri>
           </map>
           <key>linux64</key>
           <map>
@@ -254,9 +254,9 @@
           <key>windows</key>
           <map>
             <key>md5sum</key>
-            <string>b28856d3d02ee680353ae440561a6579</string>
+            <string>48691883065a82d53691d73aae81d4c1</string>
             <key>url</key>
-            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/curl-7.20.1-windows-20100611.tar.bz2</uri>
+            <uri>https://s3.amazonaws.com/automated-builds-secondlife-com/hg/repo/brad_curl-autobuild/rev/216961/arch/CYGWIN/installer/curl-7.21.1-windows-20101214.tar.bz2</uri>
           </map>
         </map>
       </map>
@@ -981,9 +981,9 @@ anguage Infrstructure (CLI) international standard</string>
           <key>darwin</key>
           <map>
             <key>md5sum</key>
-            <string>34d9e4c93678a422cf80521bf0cd7628</string>
+            <string>66c46841825ab4969ec875b5c8f9b24c</string>
             <key>url</key>
-            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/llqtwebkit-4.6-darwin-20100914.tar.bz2</uri>
+            <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-darwin-qt4.7.1-20101221.tar.bz2</uri>
           </map>
           <key>linux</key>
           <map>
@@ -995,9 +995,9 @@ anguage Infrstructure (CLI) international standard</string>
           <key>windows</key>
           <map>
             <key>md5sum</key>
-            <string>4b8412833c00f8cdaba26808f0ddb404</string>
+            <string>b678c4d18ea8e4fab42b20f8d0b2629a</string>
             <key>url</key>
-            <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.6-20100916.tar.bz2</uri>
+            <uri>http://viewer-source-downloads.s3.amazonaws.com/install_pkgs/llqtwebkit-windows-qt4.7.1-20101221.tar.bz2</uri>
           </map>
         </map>
       </map>
@@ -1408,7 +1408,7 @@ anguage Infrstructure (CLI) international standard</string>
           </map>
         </map>
       </map>
-      <key>vivox</key>
+      <key>slvoice</key>
       <map>
         <key>copyright</key>
         <string> </string>
@@ -1419,23 +1419,23 @@ anguage Infrstructure (CLI) international standard</string>
           <key>darwin</key>
           <map>
             <key>md5sum</key>
-            <string>aa144917d0e33453d3c2cc2c05c6c47c</string>
+            <string>2f9b3528d4b5f858fb8dcee4b6dd5188</string>
             <key>url</key>
-            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.1.0001.8821-darwin-20100529.tar.bz2</uri>
+            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/slvoice-3.2.0002.9361-darwin-20101117a.tar.bz2</uri>
           </map>
           <key>linux</key>
           <map>
             <key>md5sum</key>
-            <string>98f7945755f3ee8e52f685a3eff4d7be</string>
+            <string>cde4728b8a75a76c72a8785815cb769f</string>
             <key>url</key>
-            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.1.0001.8821-linux-20100529.tar.bz2</uri>
+            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/slvoice-3.2.0002.9361-linux-20101117a.tar.bz2</uri>
           </map>
           <key>windows</key>
           <map>
             <key>md5sum</key>
-            <string>e8fdd46cb026c2ec72c4489eb3bf39c1</string>
+            <string>940ac55a6d0141c958bf2b14939d8474</string>
             <key>url</key>
-            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/vivox-3.1.0001.8821-windows-20100529.tar.bz2</uri>
+            <uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/slvoice-3.2.0002.9361-windows-20101117a.tar.bz2</uri>
           </map>
         </map>
       </map>
diff --git a/scripts/install.py b/scripts/install.py
index c2adf4d0a27ce79b9edfb4a28ea594141a13039b..d3bdf52283778899aab8476a71862f012389bb20 100755
--- a/scripts/install.py
+++ b/scripts/install.py
@@ -486,7 +486,7 @@ def _uninstall(self, installables):
         for filename in remove_file_list:
             print "rm",filename
             if not self._dryrun:
-                if os.path.exists(filename):
+                if os.path.lexists(filename):
                     remove_dir_set.add(os.path.dirname(filename))
                     try:
                         os.remove(filename)
diff --git a/scripts/md5check.py b/scripts/md5check.py
new file mode 100755
index 0000000000000000000000000000000000000000..951fe0105ca8a7106c0ac9649b6f4d050b016402
--- /dev/null
+++ b/scripts/md5check.py
@@ -0,0 +1,61 @@
+#!/usr/bin/python
+"""\
+@file md5check.py
+@brief Replacement for message template compatibility verifier.
+
+$LicenseInfo:firstyear=20i10&license=viewergpl$
+Copyright (c) 2010, Linden Research, Inc.
+
+Second Life Viewer Source Code
+The source code in this file ("Source Code") is provided by Linden Lab
+to you under the terms of the GNU General Public License, version 2.0
+("GPL"), unless you have obtained a separate licensing agreement
+("Other License"), formally executed by you and Linden Lab.  Terms of
+the GPL can be found in doc/GPL-license.txt in this distribution, or
+online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+
+There are special exceptions to the terms and conditions of the GPL as
+it is applied to this Source Code. View the full text of the exception
+in the file doc/FLOSS-exception.txt in this software distribution, or
+online at
+http://secondlifegrid.net/programs/open_source/licensing/flossexception
+
+By copying, modifying or distributing this software, you acknowledge
+that you have read and understood your obligations described above,
+and agree to abide by those obligations.
+
+ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+COMPLETENESS OR PERFORMANCE.
+$/LicenseInfo$
+"""
+
+import sys
+import hashlib
+
+if len(sys.argv) != 3:
+    print """Usage: %s --create|<hash-digest> <file>
+
+Creates an md5sum hash digest of the specified file content
+and compares it with the given hash digest.
+
+If --create is used instead of a hash digest, it will simply
+print out the hash digest of specified file content.
+""" % sys.argv[0]
+    sys.exit(1)
+
+if sys.argv[2] == '-':
+    fh = sys.stdin
+    filename = "<stdin>"
+else:
+    filename = sys.argv[2]
+    fh = open(filename)
+
+hexdigest = hashlib.md5(fh.read()).hexdigest()
+if sys.argv[1] == '--create':
+    print hexdigest
+elif hexdigest == sys.argv[1]:
+    print "md5sum check passed:", filename
+else:
+    print "md5sum check FAILED:", filename
+    sys.exit(1)