diff --git a/doc/contributions.txt b/doc/contributions.txt
index 3b14ce5125ffd0823a401a43c78fe869aaf8fdf8..f21354b4069d4d9516fa8761d39f4721a18e5014 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -219,6 +219,8 @@ Catherine Pfeffer
 Celierra Darling
 	VWR-1274
 	VWR-6975
+Coaldust Numbers
+    VWR-1095
 Cron Stardust
 	VWR-10579
 Cypren Christenson
@@ -364,15 +366,17 @@ JB Kraft
 Joghert LeSabre
 	VWR-64
 Jonathan Yap
-	STORM-596
 	STORM-523
+	STORM-596
+	STORM-615
 	STORM-616
 	STORM-679
-	STORM-737
+	STORM-723
 	STORM-726
+	STORM-737
+	STORM-785
 	STORM-812
 	VWR-17801
-	STORM-785
 Kage Pixel
 	VWR-11
 Ken March
diff --git a/indra/cmake/Boost.cmake b/indra/cmake/Boost.cmake
index 7ce57a5572336c4927a7f2b6e4e97d4e3aecb745..012d3c2ab204853214cdd09db8f79762c3d6806c 100644
--- a/indra/cmake/Boost.cmake
+++ b/indra/cmake/Boost.cmake
@@ -10,6 +10,8 @@ if (STANDALONE)
   set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-mt)
   set(BOOST_REGEX_LIBRARY boost_regex-mt)
   set(BOOST_SIGNALS_LIBRARY boost_signals-mt)
+  set(BOOST_SYSTEM_LIBRARY boost_system-mt)
+  set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-mt)
 else (STANDALONE)
   use_prebuilt_binary(boost)
   set(Boost_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include)
@@ -26,6 +28,12 @@ else (STANDALONE)
       set(BOOST_SIGNALS_LIBRARY 
           optimized libboost_signals-vc71-mt-s-${BOOST_VERSION}
           debug libboost_signals-vc71-mt-sgd-${BOOST_VERSION})
+      set(BOOST_SYSTEM_LIBRARY 
+          optimized libboost_system-vc71-mt-s-${BOOST_VERSION}
+          debug libboost_system-vc71-mt-sgd-${BOOST_VERSION})
+      set(BOOST_FILESYSTEM_LIBRARY 
+          optimized libboost_filesystem-vc71-mt-s-${BOOST_VERSION}
+          debug libboost_filesystem-vc71-mt-sgd-${BOOST_VERSION})
     else (MSVC71)
       set(BOOST_PROGRAM_OPTIONS_LIBRARY 
           optimized libboost_program_options-vc80-mt-${BOOST_VERSION}
@@ -36,14 +44,24 @@ else (STANDALONE)
       set(BOOST_SIGNALS_LIBRARY 
           optimized libboost_signals-vc80-mt-${BOOST_VERSION}
           debug libboost_signals-vc80-mt-gd-${BOOST_VERSION})
+      set(BOOST_SYSTEM_LIBRARY 
+          optimized libboost_system-vc80-mt-${BOOST_VERSION}
+          debug libboost_system-vc80-mt-gd-${BOOST_VERSION})
+      set(BOOST_FILESYSTEM_LIBRARY 
+          optimized libboost_filesystem-vc80-mt-${BOOST_VERSION}
+          debug libboost_filesystem-vc80-mt-gd-${BOOST_VERSION})
     endif (MSVC71)
   elseif (DARWIN)
     set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-xgcc40-mt)
     set(BOOST_REGEX_LIBRARY boost_regex-xgcc40-mt)
     set(BOOST_SIGNALS_LIBRARY boost_signals-xgcc40-mt)
+    set(BOOST_SYSTEM_LIBRARY boost_system-xgcc40-mt)
+    set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-xgcc40-mt)
   elseif (LINUX)
     set(BOOST_PROGRAM_OPTIONS_LIBRARY boost_program_options-gcc41-mt)
     set(BOOST_REGEX_LIBRARY boost_regex-gcc41-mt)
     set(BOOST_SIGNALS_LIBRARY boost_signals-gcc41-mt)
+    set(BOOST_SYSTEM_LIBRARY boost_system-gcc41-mt)
+    set(BOOST_FILESYSTEM_LIBRARY boost_filesystem-gcc41-mt)
   endif (WINDOWS)
 endif (STANDALONE)
diff --git a/indra/cmake/GetPrerequisites_2_8.cmake b/indra/cmake/GetPrerequisites_2_8.cmake
index 5a24842c896af36c13b8897a0285222dbffa2d12..05ec1539ba1bc5842565dbc419b65aef914e7319 100644
--- a/indra/cmake/GetPrerequisites_2_8.cmake
+++ b/indra/cmake/GetPrerequisites_2_8.cmake
@@ -1,786 +1,786 @@
-# GetPrerequisites.cmake
-#
-# This script provides functions to list the .dll, .dylib or .so files that an
-# executable or shared library file depends on. (Its prerequisites.)
-#
-# It uses various tools to obtain the list of required shared library files:
-#   dumpbin (Windows)
-#   ldd (Linux/Unix)
-#   otool (Mac OSX)
-#
-# The following functions are provided by this script:
-#   gp_append_unique
-#   is_file_executable
-#   gp_item_default_embedded_path
-#     (projects can override with gp_item_default_embedded_path_override)
-#   gp_resolve_item
-#     (projects can override with gp_resolve_item_override)
-#   gp_resolved_file_type
-#   gp_file_type
-#   get_prerequisites
-#   list_prerequisites
-#   list_prerequisites_by_glob
-#
-# Requires CMake 2.6 or greater because it uses function, break, return and
-# PARENT_SCOPE.
-
-#=============================================================================
-# Copyright 2008-2009 Kitware, Inc.
-#
-# Distributed under the OSI-approved BSD License (the "License");
-# see accompanying file Copyright.txt for details.
-#
-# This software is distributed WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-# See the License for more information.
-#=============================================================================
-# (To distributed this file outside of CMake, substitute the full
-#  License text for the above reference.)
-
-# gp_append_unique list_var value
-#
-# Append value to the list variable ${list_var} only if the value is not
-# already in the list.
-#
-function(gp_append_unique list_var value)
-  set(contains 0)
-
-  foreach(item ${${list_var}})
-    if("${item}" STREQUAL "${value}")
-      set(contains 1)
-      break()
-    endif("${item}" STREQUAL "${value}")
-  endforeach(item)
-
-  if(NOT contains)
-    set(${list_var} ${${list_var}} "${value}" PARENT_SCOPE)
-  endif(NOT contains)
-endfunction(gp_append_unique)
-
-
-# is_file_executable file result_var
-#
-# Return 1 in ${result_var} if ${file} is a binary executable.
-#
-# Return 0 in ${result_var} otherwise.
-#
-function(is_file_executable file result_var)
-  #
-  # A file is not executable until proven otherwise:
-  #
-  set(${result_var} 0 PARENT_SCOPE)
-
-  get_filename_component(file_full "${file}" ABSOLUTE)
-  string(TOLOWER "${file_full}" file_full_lower)
-
-  # If file name ends in .exe on Windows, *assume* executable:
-  #
-  if(WIN32)
-    if("${file_full_lower}" MATCHES "\\.exe$")
-      set(${result_var} 1 PARENT_SCOPE)
-      return()
-    endif("${file_full_lower}" MATCHES "\\.exe$")
-
-    # A clause could be added here that uses output or return value of dumpbin
-    # to determine ${result_var}. In 99%+? practical cases, the exe name
-    # match will be sufficient...
-    #
-  endif(WIN32)
-
-  # Use the information returned from the Unix shell command "file" to
-  # determine if ${file_full} should be considered an executable file...
-  #
-  # If the file command's output contains "executable" and does *not* contain
-  # "text" then it is likely an executable suitable for prerequisite analysis
-  # via the get_prerequisites macro.
-  #
-  if(UNIX)
-    if(NOT file_cmd)
-      find_program(file_cmd "file")
-    endif(NOT file_cmd)
-
-    if(file_cmd)
-      execute_process(COMMAND "${file_cmd}" "${file_full}"
-        OUTPUT_VARIABLE file_ov
-        OUTPUT_STRIP_TRAILING_WHITESPACE
-        )
-
-      # Replace the name of the file in the output with a placeholder token
-      # (the string " _file_full_ ") so that just in case the path name of
-      # the file contains the word "text" or "executable" we are not fooled
-      # into thinking "the wrong thing" because the file name matches the
-      # other 'file' command output we are looking for...
-      #
-      string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}")
-      string(TOLOWER "${file_ov}" file_ov)
-
-      #message(STATUS "file_ov='${file_ov}'")
-      if("${file_ov}" MATCHES "executable")
-        #message(STATUS "executable!")
-        if("${file_ov}" MATCHES "text")
-          #message(STATUS "but text, so *not* a binary executable!")
-        else("${file_ov}" MATCHES "text")
-          set(${result_var} 1 PARENT_SCOPE)
-          return()
-        endif("${file_ov}" MATCHES "text")
-      endif("${file_ov}" MATCHES "executable")
-    else(file_cmd)
-      message(STATUS "warning: No 'file' command, skipping execute_process...")
-    endif(file_cmd)
-  endif(UNIX)
-endfunction(is_file_executable)
-
-
-# gp_item_default_embedded_path item default_embedded_path_var
-#
-# Return the path that others should refer to the item by when the item
-# is embedded inside a bundle.
-#
-# Override on a per-project basis by providing a project-specific
-# gp_item_default_embedded_path_override function.
-#
-function(gp_item_default_embedded_path item default_embedded_path_var)
-
-  # On Windows and Linux, "embed" prerequisites in the same directory
-  # as the executable by default:
-  #
-  set(path "@executable_path")
-  set(overridden 0)
-
-  # On the Mac, relative to the executable depending on the type
-  # of the thing we are embedding:
-  #
-  if(APPLE)
-    #
-    # The assumption here is that all executables in the bundle will be
-    # in same-level-directories inside the bundle. The parent directory
-    # of an executable inside the bundle should be MacOS or a sibling of
-    # MacOS and all embedded paths returned from here will begin with
-    # "@executable_path/../" and will work from all executables in all
-    # such same-level-directories inside the bundle.
-    #
-
-    # By default, embed things right next to the main bundle executable:
-    #
-    set(path "@executable_path/../../Contents/MacOS")
-
-    # Embed .dylibs right next to the main bundle executable:
-    #
-    if(item MATCHES "\\.dylib$")
-      set(path "@executable_path/../MacOS")
-      set(overridden 1)
-    endif(item MATCHES "\\.dylib$")
-
-    # Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS):
-    #
-    if(NOT overridden)
-      if(item MATCHES "[^/]+\\.framework/")
-        set(path "@executable_path/../Frameworks")
-        set(overridden 1)
-      endif(item MATCHES "[^/]+\\.framework/")
-    endif(NOT overridden)
-  endif()
-
-  # Provide a hook so that projects can override the default embedded location
-  # of any given library by whatever logic they choose:
-  #
-  if(COMMAND gp_item_default_embedded_path_override)
-    gp_item_default_embedded_path_override("${item}" path)
-  endif(COMMAND gp_item_default_embedded_path_override)
-
-  set(${default_embedded_path_var} "${path}" PARENT_SCOPE)
-endfunction(gp_item_default_embedded_path)
-
-
-# gp_resolve_item context item exepath dirs resolved_item_var
-#
-# Resolve an item into an existing full path file.
-#
-# Override on a per-project basis by providing a project-specific
-# gp_resolve_item_override function.
-#
-function(gp_resolve_item context item exepath dirs resolved_item_var)
-  set(resolved 0)
-  set(resolved_item "${item}")
-
-  # Is it already resolved?
-  #
-  if(EXISTS "${resolved_item}")
-    set(resolved 1)
-  endif(EXISTS "${resolved_item}")
-
-  if(NOT resolved)
-    if(item MATCHES "@executable_path")
-      #
-      # @executable_path references are assumed relative to exepath
-      #
-      string(REPLACE "@executable_path" "${exepath}" ri "${item}")
-      get_filename_component(ri "${ri}" ABSOLUTE)
-
-      if(EXISTS "${ri}")
-        #message(STATUS "info: embedded item exists (${ri})")
-        set(resolved 1)
-        set(resolved_item "${ri}")
-      else(EXISTS "${ri}")
-        message(STATUS "warning: embedded item does not exist '${ri}'")
-      endif(EXISTS "${ri}")
-    endif(item MATCHES "@executable_path")
-  endif(NOT resolved)
-
-  if(NOT resolved)
-    if(item MATCHES "@loader_path")
-      #
-      # @loader_path references are assumed relative to the
-      # PATH of the given "context" (presumably another library)
-      #
-      get_filename_component(contextpath "${context}" PATH)
-      string(REPLACE "@loader_path" "${contextpath}" ri "${item}")
-      get_filename_component(ri "${ri}" ABSOLUTE)
-
-      if(EXISTS "${ri}")
-        #message(STATUS "info: embedded item exists (${ri})")
-        set(resolved 1)
-        set(resolved_item "${ri}")
-      else(EXISTS "${ri}")
-        message(STATUS "warning: embedded item does not exist '${ri}'")
-      endif(EXISTS "${ri}")
-    endif(item MATCHES "@loader_path")
-  endif(NOT resolved)
-
-  if(NOT resolved)
-    set(ri "ri-NOTFOUND")
-    find_file(ri "${item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
-    find_file(ri "${item}" ${exepath} ${dirs} /usr/lib)
-    if(ri)
-      #message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
-      set(resolved 1)
-      set(resolved_item "${ri}")
-      set(ri "ri-NOTFOUND")
-    endif(ri)
-  endif(NOT resolved)
-
-  if(NOT resolved)
-    if(item MATCHES "[^/]+\\.framework/")
-      set(fw "fw-NOTFOUND")
-      find_file(fw "${item}"
-        "~/Library/Frameworks"
-        "/Library/Frameworks"
-        "/System/Library/Frameworks"
-      )
-      if(fw)
-        #message(STATUS "info: 'find_file' found framework (${fw})")
-        set(resolved 1)
-        set(resolved_item "${fw}")
-        set(fw "fw-NOTFOUND")
-      endif(fw)
-    endif(item MATCHES "[^/]+\\.framework/")
-  endif(NOT resolved)
-
-  # Using find_program on Windows will find dll files that are in the PATH.
-  # (Converting simple file names into full path names if found.)
-  #
-  if(WIN32)
-  if(NOT resolved)
-    set(ri "ri-NOTFOUND")
-    find_program(ri "${item}" PATHS "${exepath};${dirs}" NO_DEFAULT_PATH)
-    find_program(ri "${item}" PATHS "${exepath};${dirs}")
-    if(ri)
-      #message(STATUS "info: 'find_program' in exepath/dirs (${ri})")
-      set(resolved 1)
-      set(resolved_item "${ri}")
-      set(ri "ri-NOTFOUND")
-    endif(ri)
-  endif(NOT resolved)
-  endif(WIN32)
-
-  # Provide a hook so that projects can override item resolution
-  # by whatever logic they choose:
-  #
-  if(COMMAND gp_resolve_item_override)
-    gp_resolve_item_override("${context}" "${item}" "${exepath}" "${dirs}" resolved_item resolved)
-  endif(COMMAND gp_resolve_item_override)
-
-  if(NOT resolved)
-    message(STATUS "
-warning: cannot resolve item '${item}'
-
-  possible problems:
-    need more directories?
-    need to use InstallRequiredSystemLibraries?
-    run in install tree instead of build tree?
-")
-#    message(STATUS "
-#******************************************************************************
-#warning: cannot resolve item '${item}'
-#
-#  possible problems:
-#    need more directories?
-#    need to use InstallRequiredSystemLibraries?
-#    run in install tree instead of build tree?
-#
-#    context='${context}'
-#    item='${item}'
-#    exepath='${exepath}'
-#    dirs='${dirs}'
-#    resolved_item_var='${resolved_item_var}'
-#******************************************************************************
-#")
-  endif(NOT resolved)
-
-  set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE)
-endfunction(gp_resolve_item)
-
-
-# gp_resolved_file_type original_file file exepath dirs type_var
-#
-# Return the type of ${file} with respect to ${original_file}. String
-# describing type of prerequisite is returned in variable named ${type_var}.
-#
-# Use ${exepath} and ${dirs} if necessary to resolve non-absolute ${file}
-# values -- but only for non-embedded items.
-#
-# Possible types are:
-#   system
-#   local
-#   embedded
-#   other
-#
-function(gp_resolved_file_type original_file file exepath dirs type_var)
-  #message(STATUS "**")
-
-  if(NOT IS_ABSOLUTE "${original_file}")
-    message(STATUS "warning: gp_resolved_file_type expects absolute full path for first arg original_file")
-  endif()
-
-  set(is_embedded 0)
-  set(is_local 0)
-  set(is_system 0)
-
-  set(resolved_file "${file}")
-
-  if("${file}" MATCHES "^@(executable|loader)_path")
-    set(is_embedded 1)
-  endif()
-
-  if(NOT is_embedded)
-    if(NOT IS_ABSOLUTE "${file}")
-      gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file)
-    endif()
-
-    string(TOLOWER "${original_file}" original_lower)
-    string(TOLOWER "${resolved_file}" lower)
-
-    if(UNIX)
-      if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/)")
-        set(is_system 1)
-      endif()
-    endif()
-
-    if(APPLE)
-      if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)")
-        set(is_system 1)
-      endif()
-    endif()
-
-    if(WIN32)
-      string(TOLOWER "$ENV{SystemRoot}" sysroot)
-      string(REGEX REPLACE "\\\\" "/" sysroot "${sysroot}")
-
-      string(TOLOWER "$ENV{windir}" windir)
-      string(REGEX REPLACE "\\\\" "/" windir "${windir}")
-
-      if(lower MATCHES "^(${sysroot}/system|${windir}/system|${sysroot}/syswow|${windir}/syswow|(.*/)*msvc[^/]+dll)")
-        set(is_system 1)
-      endif()
-    endif()
-
-    if(NOT is_system)
-      get_filename_component(original_path "${original_lower}" PATH)
-      get_filename_component(path "${lower}" PATH)
-      if("${original_path}" STREQUAL "${path}")
-        set(is_local 1)
-      endif()
-    endif()
-  endif()
-
-  # Return type string based on computed booleans:
-  #
-  set(type "other")
-
-  if(is_system)
-    set(type "system")
-  elseif(is_embedded)
-    set(type "embedded")
-  elseif(is_local)
-    set(type "local")
-  endif()
-
-  #message(STATUS "gp_resolved_file_type: '${file}' '${resolved_file}'")
-  #message(STATUS "                type: '${type}'")
-
-  if(NOT is_embedded)
-    if(NOT IS_ABSOLUTE "${resolved_file}")
-      if(lower MATCHES "^msvc[^/]+dll" AND is_system)
-        message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'")
-      else()
-        message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect")
-      endif()
-    endif()
-  endif()
-
-  set(${type_var} "${type}" PARENT_SCOPE)
-
-  #message(STATUS "**")
-endfunction()
-
-
-# gp_file_type original_file file type_var
-#
-# Return the type of ${file} with respect to ${original_file}. String
-# describing type of prerequisite is returned in variable named ${type_var}.
-#
-# Possible types are:
-#   system
-#   local
-#   embedded
-#   other
-#
-function(gp_file_type original_file file type_var)
-  if(NOT IS_ABSOLUTE "${original_file}")
-    message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file")
-  endif()
-
-  get_filename_component(exepath "${original_file}" PATH)
-
-  set(type "")
-  gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "" type)
-
-  set(${type_var} "${type}" PARENT_SCOPE)
-endfunction(gp_file_type)
-
-
-# get_prerequisites target prerequisites_var exclude_system recurse dirs
-#
-# Get the list of shared library files required by ${target}. The list in
-# the variable named ${prerequisites_var} should be empty on first entry to
-# this function. On exit, ${prerequisites_var} will contain the list of
-# required shared library files.
-#
-#  target is the full path to an executable file
-#
-#  prerequisites_var is the name of a CMake variable to contain the results
-#
-#  exclude_system is 0 or 1: 0 to include "system" prerequisites , 1 to
-#   exclude them
-#
-#  recurse is 0 or 1: 0 for direct prerequisites only, 1 for all prerequisites
-#   recursively
-#
-#  exepath is the path to the top level executable used for @executable_path
-#   replacment on the Mac
-#
-#  dirs is a list of paths where libraries might be found: these paths are
-#   searched first when a target without any path info is given. Then standard
-#   system locations are also searched: PATH, Framework locations, /usr/lib...
-#
-function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
-  set(verbose 0)
-  set(eol_char "E")
-
-  if(NOT IS_ABSOLUTE "${target}")
-    message("warning: target '${target}' is not absolute...")
-  endif(NOT IS_ABSOLUTE "${target}")
-
-  if(NOT EXISTS "${target}")
-    message("warning: target '${target}' does not exist...")
-  endif(NOT EXISTS "${target}")
-
-  # <setup-gp_tool-vars>
-  #
-  # Try to choose the right tool by default. Caller can set gp_tool prior to
-  # calling this function to force using a different tool.
-  #
-  if("${gp_tool}" STREQUAL "")
-    set(gp_tool "ldd")
-    if(APPLE)
-      set(gp_tool "otool")
-    endif(APPLE)
-    if(WIN32)
-      set(gp_tool "dumpbin")
-    endif(WIN32)
-  endif("${gp_tool}" STREQUAL "")
-
-  set(gp_tool_known 0)
-
-  if("${gp_tool}" STREQUAL "ldd")
-    set(gp_cmd_args "")
-    set(gp_regex "^[\t ]*[^\t ]+ => ([^\t ]+).*${eol_char}$")
-    set(gp_regex_cmp_count 1)
-    set(gp_tool_known 1)
-  endif("${gp_tool}" STREQUAL "ldd")
-
-  if("${gp_tool}" STREQUAL "otool")
-    set(gp_cmd_args "-L")
-    set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$")
-    set(gp_regex_cmp_count 3)
-    set(gp_tool_known 1)
-  endif("${gp_tool}" STREQUAL "otool")
-
-  if("${gp_tool}" STREQUAL "dumpbin")
-    set(gp_cmd_args "/dependents")
-    set(gp_regex "^    ([^ ].*[Dd][Ll][Ll])${eol_char}$")
-    set(gp_regex_cmp_count 1)
-    set(gp_tool_known 1)
-    set(ENV{VS_UNICODE_OUTPUT} "") # Block extra output from inside VS IDE.
-  endif("${gp_tool}" STREQUAL "dumpbin")
-
-  if(NOT gp_tool_known)
-    message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
-    message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
-    message(STATUS "Valid gp_tool values are dumpbin, ldd and otool.")
-    return()
-  endif(NOT gp_tool_known)
-
-  set(gp_cmd_paths ${gp_cmd_paths}
-    "C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"
-    "C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"
-    "C:/Program Files/Microsoft Visual Studio 8/VC/BIN"
-    "C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"
-    "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"
-    "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"
-    "/usr/local/bin"
-    "/usr/bin"
-    )
-
-  find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths})
-
-  if(NOT gp_cmd)
-    message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...")
-    return()
-  endif(NOT gp_cmd)
-
-  if("${gp_tool}" STREQUAL "dumpbin")
-    # When running dumpbin, it also needs the "Common7/IDE" directory in the
-    # PATH. It will already be in the PATH if being run from a Visual Studio
-    # command prompt. Add it to the PATH here in case we are running from a
-    # different command prompt.
-    #
-    get_filename_component(gp_cmd_dir "${gp_cmd}" PATH)
-    get_filename_component(gp_cmd_dlls_dir "${gp_cmd_dir}/../../Common7/IDE" ABSOLUTE)
-    if(EXISTS "${gp_cmd_dlls_dir}")
-      # only add to the path if it is not already in the path
-      if(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}")
-        set(ENV{PATH} "$ENV{PATH};${gp_cmd_dlls_dir}")
-      endif(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}")
-    endif(EXISTS "${gp_cmd_dlls_dir}")
-  endif("${gp_tool}" STREQUAL "dumpbin")
-  #
-  # </setup-gp_tool-vars>
-
-  if("${gp_tool}" STREQUAL "ldd")
-    set(old_ld_env "$ENV{LD_LIBRARY_PATH}")
-    foreach(dir ${exepath} ${dirs})
-      set(ENV{LD_LIBRARY_PATH} "${dir}:$ENV{LD_LIBRARY_PATH}")
-    endforeach(dir)
-  endif("${gp_tool}" STREQUAL "ldd")
-
-
-  # Track new prerequisites at each new level of recursion. Start with an
-  # empty list at each level:
-  #
-  set(unseen_prereqs)
-
-  # Run gp_cmd on the target:
-  #
-  execute_process(
-    COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
-    OUTPUT_VARIABLE gp_cmd_ov
-    )
-
-  if("${gp_tool}" STREQUAL "ldd")
-    set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
-  endif("${gp_tool}" STREQUAL "ldd")
-
-  if(verbose)
-    message(STATUS "<RawOutput cmd='${gp_cmd} ${gp_cmd_args} ${target}'>")
-    message(STATUS "gp_cmd_ov='${gp_cmd_ov}'")
-    message(STATUS "</RawOutput>")
-  endif(verbose)
-
-  get_filename_component(target_dir "${target}" PATH)
-
-  # Convert to a list of lines:
-  #
-  string(REGEX REPLACE ";" "\\\\;" candidates "${gp_cmd_ov}")
-  string(REGEX REPLACE "\n" "${eol_char};" candidates "${candidates}")
-
-  # Analyze each line for file names that match the regular expression:
-  #
-  foreach(candidate ${candidates})
-  if("${candidate}" MATCHES "${gp_regex}")
-    # Extract information from each candidate:
-    string(REGEX REPLACE "${gp_regex}" "\\1" raw_item "${candidate}")
-
-    if(gp_regex_cmp_count GREATER 1)
-      string(REGEX REPLACE "${gp_regex}" "\\2" raw_compat_version "${candidate}")
-      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" compat_major_version "${raw_compat_version}")
-      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" compat_minor_version "${raw_compat_version}")
-      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" compat_patch_version "${raw_compat_version}")
-    endif(gp_regex_cmp_count GREATER 1)
-
-    if(gp_regex_cmp_count GREATER 2)
-      string(REGEX REPLACE "${gp_regex}" "\\3" raw_current_version "${candidate}")
-      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" current_major_version "${raw_current_version}")
-      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" current_minor_version "${raw_current_version}")
-      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" current_patch_version "${raw_current_version}")
-    endif(gp_regex_cmp_count GREATER 2)
-
-    # Use the raw_item as the list entries returned by this function. Use the
-    # gp_resolve_item function to resolve it to an actual full path file if
-    # necessary.
-    #
-    set(item "${raw_item}")
-
-    # Add each item unless it is excluded:
-    #
-    set(add_item 1)
-
-    if(${exclude_system})
-      set(type "")
-      gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type)
-      if("${type}" STREQUAL "system")
-        set(add_item 0)
-      endif("${type}" STREQUAL "system")
-    endif(${exclude_system})
-
-    if(add_item)
-      list(LENGTH ${prerequisites_var} list_length_before_append)
-      gp_append_unique(${prerequisites_var} "${item}")
-      list(LENGTH ${prerequisites_var} list_length_after_append)
-
-      if(${recurse})
-        # If item was really added, this is the first time we have seen it.
-        # Add it to unseen_prereqs so that we can recursively add *its*
-        # prerequisites...
-        #
-        # But first: resolve its name to an absolute full path name such
-        # that the analysis tools can simply accept it as input.
-        #
-        if(NOT list_length_before_append EQUAL list_length_after_append)
-          gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item)
-          set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
-        endif(NOT list_length_before_append EQUAL list_length_after_append)
-      endif(${recurse})
-    endif(add_item)
-  else("${candidate}" MATCHES "${gp_regex}")
-    if(verbose)
-      message(STATUS "ignoring non-matching line: '${candidate}'")
-    endif(verbose)
-  endif("${candidate}" MATCHES "${gp_regex}")
-  endforeach(candidate)
-
-  list(LENGTH ${prerequisites_var} prerequisites_var_length)
-  if(prerequisites_var_length GREATER 0)
-    list(SORT ${prerequisites_var})
-  endif(prerequisites_var_length GREATER 0)
-  if(${recurse})
-    set(more_inputs ${unseen_prereqs})
-    foreach(input ${more_inputs})
-      get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}")
-    endforeach(input)
-  endif(${recurse})
-
-  set(${prerequisites_var} ${${prerequisites_var}} PARENT_SCOPE)
-endfunction(get_prerequisites)
-
-
-# list_prerequisites target all exclude_system verbose
-#
-#  ARGV0 (target) is the full path to an executable file
-#
-#  optional ARGV1 (all) is 0 or 1: 0 for direct prerequisites only,
-#   1 for all prerequisites recursively
-#
-#  optional ARGV2 (exclude_system) is 0 or 1: 0 to include "system"
-#   prerequisites , 1 to exclude them
-#
-#  optional ARGV3 (verbose) is 0 or 1: 0 to print only full path
-#   names of prerequisites, 1 to print extra information
-#
-function(list_prerequisites target)
-  if("${ARGV1}" STREQUAL "")
-    set(all 1)
-  else("${ARGV1}" STREQUAL "")
-    set(all "${ARGV1}")
-  endif("${ARGV1}" STREQUAL "")
-
-  if("${ARGV2}" STREQUAL "")
-    set(exclude_system 0)
-  else("${ARGV2}" STREQUAL "")
-    set(exclude_system "${ARGV2}")
-  endif("${ARGV2}" STREQUAL "")
-
-  if("${ARGV3}" STREQUAL "")
-    set(verbose 0)
-  else("${ARGV3}" STREQUAL "")
-    set(verbose "${ARGV3}")
-  endif("${ARGV3}" STREQUAL "")
-
-  set(count 0)
-  set(count_str "")
-  set(print_count "${verbose}")
-  set(print_prerequisite_type "${verbose}")
-  set(print_target "${verbose}")
-  set(type_str "")
-
-  get_filename_component(exepath "${target}" PATH)
-
-  set(prereqs "")
-  get_prerequisites("${target}" prereqs ${exclude_system} ${all} "${exepath}" "")
-
-  if(print_target)
-    message(STATUS "File '${target}' depends on:")
-  endif(print_target)
-
-  foreach(d ${prereqs})
-    math(EXPR count "${count} + 1")
-
-    if(print_count)
-      set(count_str "${count}. ")
-    endif(print_count)
-
-    if(print_prerequisite_type)
-      gp_file_type("${target}" "${d}" type)
-      set(type_str " (${type})")
-    endif(print_prerequisite_type)
-
-    message(STATUS "${count_str}${d}${type_str}")
-  endforeach(d)
-endfunction(list_prerequisites)
-
-
-# list_prerequisites_by_glob glob_arg glob_exp
-#
-#  glob_arg is GLOB or GLOB_RECURSE
-#
-#  glob_exp is a globbing expression used with "file(GLOB" to retrieve a list
-#   of matching files. If a matching file is executable, its prerequisites are
-#   listed.
-#
-# Any additional (optional) arguments provided are passed along as the
-# optional arguments to the list_prerequisites calls.
-#
-function(list_prerequisites_by_glob glob_arg glob_exp)
-  message(STATUS "=============================================================================")
-  message(STATUS "List prerequisites of executables matching ${glob_arg} '${glob_exp}'")
-  message(STATUS "")
-  file(${glob_arg} file_list ${glob_exp})
-  foreach(f ${file_list})
-    is_file_executable("${f}" is_f_executable)
-    if(is_f_executable)
-      message(STATUS "=============================================================================")
-      list_prerequisites("${f}" ${ARGN})
-      message(STATUS "")
-    endif(is_f_executable)
-  endforeach(f)
-endfunction(list_prerequisites_by_glob)
+# GetPrerequisites.cmake
+#
+# This script provides functions to list the .dll, .dylib or .so files that an
+# executable or shared library file depends on. (Its prerequisites.)
+#
+# It uses various tools to obtain the list of required shared library files:
+#   dumpbin (Windows)
+#   ldd (Linux/Unix)
+#   otool (Mac OSX)
+#
+# The following functions are provided by this script:
+#   gp_append_unique
+#   is_file_executable
+#   gp_item_default_embedded_path
+#     (projects can override with gp_item_default_embedded_path_override)
+#   gp_resolve_item
+#     (projects can override with gp_resolve_item_override)
+#   gp_resolved_file_type
+#   gp_file_type
+#   get_prerequisites
+#   list_prerequisites
+#   list_prerequisites_by_glob
+#
+# Requires CMake 2.6 or greater because it uses function, break, return and
+# PARENT_SCOPE.
+
+#=============================================================================
+# Copyright 2008-2009 Kitware, Inc.
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+# (To distributed this file outside of CMake, substitute the full
+#  License text for the above reference.)
+
+# gp_append_unique list_var value
+#
+# Append value to the list variable ${list_var} only if the value is not
+# already in the list.
+#
+function(gp_append_unique list_var value)
+  set(contains 0)
+
+  foreach(item ${${list_var}})
+    if("${item}" STREQUAL "${value}")
+      set(contains 1)
+      break()
+    endif("${item}" STREQUAL "${value}")
+  endforeach(item)
+
+  if(NOT contains)
+    set(${list_var} ${${list_var}} "${value}" PARENT_SCOPE)
+  endif(NOT contains)
+endfunction(gp_append_unique)
+
+
+# is_file_executable file result_var
+#
+# Return 1 in ${result_var} if ${file} is a binary executable.
+#
+# Return 0 in ${result_var} otherwise.
+#
+function(is_file_executable file result_var)
+  #
+  # A file is not executable until proven otherwise:
+  #
+  set(${result_var} 0 PARENT_SCOPE)
+
+  get_filename_component(file_full "${file}" ABSOLUTE)
+  string(TOLOWER "${file_full}" file_full_lower)
+
+  # If file name ends in .exe on Windows, *assume* executable:
+  #
+  if(WIN32)
+    if("${file_full_lower}" MATCHES "\\.exe$")
+      set(${result_var} 1 PARENT_SCOPE)
+      return()
+    endif("${file_full_lower}" MATCHES "\\.exe$")
+
+    # A clause could be added here that uses output or return value of dumpbin
+    # to determine ${result_var}. In 99%+? practical cases, the exe name
+    # match will be sufficient...
+    #
+  endif(WIN32)
+
+  # Use the information returned from the Unix shell command "file" to
+  # determine if ${file_full} should be considered an executable file...
+  #
+  # If the file command's output contains "executable" and does *not* contain
+  # "text" then it is likely an executable suitable for prerequisite analysis
+  # via the get_prerequisites macro.
+  #
+  if(UNIX)
+    if(NOT file_cmd)
+      find_program(file_cmd "file")
+    endif(NOT file_cmd)
+
+    if(file_cmd)
+      execute_process(COMMAND "${file_cmd}" "${file_full}"
+        OUTPUT_VARIABLE file_ov
+        OUTPUT_STRIP_TRAILING_WHITESPACE
+        )
+
+      # Replace the name of the file in the output with a placeholder token
+      # (the string " _file_full_ ") so that just in case the path name of
+      # the file contains the word "text" or "executable" we are not fooled
+      # into thinking "the wrong thing" because the file name matches the
+      # other 'file' command output we are looking for...
+      #
+      string(REPLACE "${file_full}" " _file_full_ " file_ov "${file_ov}")
+      string(TOLOWER "${file_ov}" file_ov)
+
+      #message(STATUS "file_ov='${file_ov}'")
+      if("${file_ov}" MATCHES "executable")
+        #message(STATUS "executable!")
+        if("${file_ov}" MATCHES "text")
+          #message(STATUS "but text, so *not* a binary executable!")
+        else("${file_ov}" MATCHES "text")
+          set(${result_var} 1 PARENT_SCOPE)
+          return()
+        endif("${file_ov}" MATCHES "text")
+      endif("${file_ov}" MATCHES "executable")
+    else(file_cmd)
+      message(STATUS "warning: No 'file' command, skipping execute_process...")
+    endif(file_cmd)
+  endif(UNIX)
+endfunction(is_file_executable)
+
+
+# gp_item_default_embedded_path item default_embedded_path_var
+#
+# Return the path that others should refer to the item by when the item
+# is embedded inside a bundle.
+#
+# Override on a per-project basis by providing a project-specific
+# gp_item_default_embedded_path_override function.
+#
+function(gp_item_default_embedded_path item default_embedded_path_var)
+
+  # On Windows and Linux, "embed" prerequisites in the same directory
+  # as the executable by default:
+  #
+  set(path "@executable_path")
+  set(overridden 0)
+
+  # On the Mac, relative to the executable depending on the type
+  # of the thing we are embedding:
+  #
+  if(APPLE)
+    #
+    # The assumption here is that all executables in the bundle will be
+    # in same-level-directories inside the bundle. The parent directory
+    # of an executable inside the bundle should be MacOS or a sibling of
+    # MacOS and all embedded paths returned from here will begin with
+    # "@executable_path/../" and will work from all executables in all
+    # such same-level-directories inside the bundle.
+    #
+
+    # By default, embed things right next to the main bundle executable:
+    #
+    set(path "@executable_path/../../Contents/MacOS")
+
+    # Embed .dylibs right next to the main bundle executable:
+    #
+    if(item MATCHES "\\.dylib$")
+      set(path "@executable_path/../MacOS")
+      set(overridden 1)
+    endif(item MATCHES "\\.dylib$")
+
+    # Embed frameworks in the embedded "Frameworks" directory (sibling of MacOS):
+    #
+    if(NOT overridden)
+      if(item MATCHES "[^/]+\\.framework/")
+        set(path "@executable_path/../Frameworks")
+        set(overridden 1)
+      endif(item MATCHES "[^/]+\\.framework/")
+    endif(NOT overridden)
+  endif()
+
+  # Provide a hook so that projects can override the default embedded location
+  # of any given library by whatever logic they choose:
+  #
+  if(COMMAND gp_item_default_embedded_path_override)
+    gp_item_default_embedded_path_override("${item}" path)
+  endif(COMMAND gp_item_default_embedded_path_override)
+
+  set(${default_embedded_path_var} "${path}" PARENT_SCOPE)
+endfunction(gp_item_default_embedded_path)
+
+
+# gp_resolve_item context item exepath dirs resolved_item_var
+#
+# Resolve an item into an existing full path file.
+#
+# Override on a per-project basis by providing a project-specific
+# gp_resolve_item_override function.
+#
+function(gp_resolve_item context item exepath dirs resolved_item_var)
+  set(resolved 0)
+  set(resolved_item "${item}")
+
+  # Is it already resolved?
+  #
+  if(EXISTS "${resolved_item}")
+    set(resolved 1)
+  endif(EXISTS "${resolved_item}")
+
+  if(NOT resolved)
+    if(item MATCHES "@executable_path")
+      #
+      # @executable_path references are assumed relative to exepath
+      #
+      string(REPLACE "@executable_path" "${exepath}" ri "${item}")
+      get_filename_component(ri "${ri}" ABSOLUTE)
+
+      if(EXISTS "${ri}")
+        #message(STATUS "info: embedded item exists (${ri})")
+        set(resolved 1)
+        set(resolved_item "${ri}")
+      else(EXISTS "${ri}")
+        message(STATUS "warning: embedded item does not exist '${ri}'")
+      endif(EXISTS "${ri}")
+    endif(item MATCHES "@executable_path")
+  endif(NOT resolved)
+
+  if(NOT resolved)
+    if(item MATCHES "@loader_path")
+      #
+      # @loader_path references are assumed relative to the
+      # PATH of the given "context" (presumably another library)
+      #
+      get_filename_component(contextpath "${context}" PATH)
+      string(REPLACE "@loader_path" "${contextpath}" ri "${item}")
+      get_filename_component(ri "${ri}" ABSOLUTE)
+
+      if(EXISTS "${ri}")
+        #message(STATUS "info: embedded item exists (${ri})")
+        set(resolved 1)
+        set(resolved_item "${ri}")
+      else(EXISTS "${ri}")
+        message(STATUS "warning: embedded item does not exist '${ri}'")
+      endif(EXISTS "${ri}")
+    endif(item MATCHES "@loader_path")
+  endif(NOT resolved)
+
+  if(NOT resolved)
+    set(ri "ri-NOTFOUND")
+    find_file(ri "${item}" ${exepath} ${dirs} NO_DEFAULT_PATH)
+    find_file(ri "${item}" ${exepath} ${dirs} /usr/lib)
+    if(ri)
+      #message(STATUS "info: 'find_file' in exepath/dirs (${ri})")
+      set(resolved 1)
+      set(resolved_item "${ri}")
+      set(ri "ri-NOTFOUND")
+    endif(ri)
+  endif(NOT resolved)
+
+  if(NOT resolved)
+    if(item MATCHES "[^/]+\\.framework/")
+      set(fw "fw-NOTFOUND")
+      find_file(fw "${item}"
+        "~/Library/Frameworks"
+        "/Library/Frameworks"
+        "/System/Library/Frameworks"
+      )
+      if(fw)
+        #message(STATUS "info: 'find_file' found framework (${fw})")
+        set(resolved 1)
+        set(resolved_item "${fw}")
+        set(fw "fw-NOTFOUND")
+      endif(fw)
+    endif(item MATCHES "[^/]+\\.framework/")
+  endif(NOT resolved)
+
+  # Using find_program on Windows will find dll files that are in the PATH.
+  # (Converting simple file names into full path names if found.)
+  #
+  if(WIN32)
+  if(NOT resolved)
+    set(ri "ri-NOTFOUND")
+    find_program(ri "${item}" PATHS "${exepath};${dirs}" NO_DEFAULT_PATH)
+    find_program(ri "${item}" PATHS "${exepath};${dirs}")
+    if(ri)
+      #message(STATUS "info: 'find_program' in exepath/dirs (${ri})")
+      set(resolved 1)
+      set(resolved_item "${ri}")
+      set(ri "ri-NOTFOUND")
+    endif(ri)
+  endif(NOT resolved)
+  endif(WIN32)
+
+  # Provide a hook so that projects can override item resolution
+  # by whatever logic they choose:
+  #
+  if(COMMAND gp_resolve_item_override)
+    gp_resolve_item_override("${context}" "${item}" "${exepath}" "${dirs}" resolved_item resolved)
+  endif(COMMAND gp_resolve_item_override)
+
+  if(NOT resolved)
+    message(STATUS "
+warning: cannot resolve item '${item}'
+
+  possible problems:
+    need more directories?
+    need to use InstallRequiredSystemLibraries?
+    run in install tree instead of build tree?
+")
+#    message(STATUS "
+#******************************************************************************
+#warning: cannot resolve item '${item}'
+#
+#  possible problems:
+#    need more directories?
+#    need to use InstallRequiredSystemLibraries?
+#    run in install tree instead of build tree?
+#
+#    context='${context}'
+#    item='${item}'
+#    exepath='${exepath}'
+#    dirs='${dirs}'
+#    resolved_item_var='${resolved_item_var}'
+#******************************************************************************
+#")
+  endif(NOT resolved)
+
+  set(${resolved_item_var} "${resolved_item}" PARENT_SCOPE)
+endfunction(gp_resolve_item)
+
+
+# gp_resolved_file_type original_file file exepath dirs type_var
+#
+# Return the type of ${file} with respect to ${original_file}. String
+# describing type of prerequisite is returned in variable named ${type_var}.
+#
+# Use ${exepath} and ${dirs} if necessary to resolve non-absolute ${file}
+# values -- but only for non-embedded items.
+#
+# Possible types are:
+#   system
+#   local
+#   embedded
+#   other
+#
+function(gp_resolved_file_type original_file file exepath dirs type_var)
+  #message(STATUS "**")
+
+  if(NOT IS_ABSOLUTE "${original_file}")
+    message(STATUS "warning: gp_resolved_file_type expects absolute full path for first arg original_file")
+  endif()
+
+  set(is_embedded 0)
+  set(is_local 0)
+  set(is_system 0)
+
+  set(resolved_file "${file}")
+
+  if("${file}" MATCHES "^@(executable|loader)_path")
+    set(is_embedded 1)
+  endif()
+
+  if(NOT is_embedded)
+    if(NOT IS_ABSOLUTE "${file}")
+      gp_resolve_item("${original_file}" "${file}" "${exepath}" "${dirs}" resolved_file)
+    endif()
+
+    string(TOLOWER "${original_file}" original_lower)
+    string(TOLOWER "${resolved_file}" lower)
+
+    if(UNIX)
+      if(resolved_file MATCHES "^(/lib/|/lib32/|/lib64/|/usr/lib/|/usr/lib32/|/usr/lib64/|/usr/X11R6/)")
+        set(is_system 1)
+      endif()
+    endif()
+
+    if(APPLE)
+      if(resolved_file MATCHES "^(/System/Library/|/usr/lib/)")
+        set(is_system 1)
+      endif()
+    endif()
+
+    if(WIN32)
+      string(TOLOWER "$ENV{SystemRoot}" sysroot)
+      string(REGEX REPLACE "\\\\" "/" sysroot "${sysroot}")
+
+      string(TOLOWER "$ENV{windir}" windir)
+      string(REGEX REPLACE "\\\\" "/" windir "${windir}")
+
+      if(lower MATCHES "^(${sysroot}/system|${windir}/system|${sysroot}/syswow|${windir}/syswow|(.*/)*msvc[^/]+dll)")
+        set(is_system 1)
+      endif()
+    endif()
+
+    if(NOT is_system)
+      get_filename_component(original_path "${original_lower}" PATH)
+      get_filename_component(path "${lower}" PATH)
+      if("${original_path}" STREQUAL "${path}")
+        set(is_local 1)
+      endif()
+    endif()
+  endif()
+
+  # Return type string based on computed booleans:
+  #
+  set(type "other")
+
+  if(is_system)
+    set(type "system")
+  elseif(is_embedded)
+    set(type "embedded")
+  elseif(is_local)
+    set(type "local")
+  endif()
+
+  #message(STATUS "gp_resolved_file_type: '${file}' '${resolved_file}'")
+  #message(STATUS "                type: '${type}'")
+
+  if(NOT is_embedded)
+    if(NOT IS_ABSOLUTE "${resolved_file}")
+      if(lower MATCHES "^msvc[^/]+dll" AND is_system)
+        message(STATUS "info: non-absolute msvc file '${file}' returning type '${type}'")
+      else()
+        message(STATUS "warning: gp_resolved_file_type non-absolute file '${file}' returning type '${type}' -- possibly incorrect")
+      endif()
+    endif()
+  endif()
+
+  set(${type_var} "${type}" PARENT_SCOPE)
+
+  #message(STATUS "**")
+endfunction()
+
+
+# gp_file_type original_file file type_var
+#
+# Return the type of ${file} with respect to ${original_file}. String
+# describing type of prerequisite is returned in variable named ${type_var}.
+#
+# Possible types are:
+#   system
+#   local
+#   embedded
+#   other
+#
+function(gp_file_type original_file file type_var)
+  if(NOT IS_ABSOLUTE "${original_file}")
+    message(STATUS "warning: gp_file_type expects absolute full path for first arg original_file")
+  endif()
+
+  get_filename_component(exepath "${original_file}" PATH)
+
+  set(type "")
+  gp_resolved_file_type("${original_file}" "${file}" "${exepath}" "" type)
+
+  set(${type_var} "${type}" PARENT_SCOPE)
+endfunction(gp_file_type)
+
+
+# get_prerequisites target prerequisites_var exclude_system recurse dirs
+#
+# Get the list of shared library files required by ${target}. The list in
+# the variable named ${prerequisites_var} should be empty on first entry to
+# this function. On exit, ${prerequisites_var} will contain the list of
+# required shared library files.
+#
+#  target is the full path to an executable file
+#
+#  prerequisites_var is the name of a CMake variable to contain the results
+#
+#  exclude_system is 0 or 1: 0 to include "system" prerequisites , 1 to
+#   exclude them
+#
+#  recurse is 0 or 1: 0 for direct prerequisites only, 1 for all prerequisites
+#   recursively
+#
+#  exepath is the path to the top level executable used for @executable_path
+#   replacment on the Mac
+#
+#  dirs is a list of paths where libraries might be found: these paths are
+#   searched first when a target without any path info is given. Then standard
+#   system locations are also searched: PATH, Framework locations, /usr/lib...
+#
+function(get_prerequisites target prerequisites_var exclude_system recurse exepath dirs)
+  set(verbose 0)
+  set(eol_char "E")
+
+  if(NOT IS_ABSOLUTE "${target}")
+    message("warning: target '${target}' is not absolute...")
+  endif(NOT IS_ABSOLUTE "${target}")
+
+  if(NOT EXISTS "${target}")
+    message("warning: target '${target}' does not exist...")
+  endif(NOT EXISTS "${target}")
+
+  # <setup-gp_tool-vars>
+  #
+  # Try to choose the right tool by default. Caller can set gp_tool prior to
+  # calling this function to force using a different tool.
+  #
+  if("${gp_tool}" STREQUAL "")
+    set(gp_tool "ldd")
+    if(APPLE)
+      set(gp_tool "otool")
+    endif(APPLE)
+    if(WIN32)
+      set(gp_tool "dumpbin")
+    endif(WIN32)
+  endif("${gp_tool}" STREQUAL "")
+
+  set(gp_tool_known 0)
+
+  if("${gp_tool}" STREQUAL "ldd")
+    set(gp_cmd_args "")
+    set(gp_regex "^[\t ]*[^\t ]+ => ([^\t ]+).*${eol_char}$")
+    set(gp_regex_cmp_count 1)
+    set(gp_tool_known 1)
+  endif("${gp_tool}" STREQUAL "ldd")
+
+  if("${gp_tool}" STREQUAL "otool")
+    set(gp_cmd_args "-L")
+    set(gp_regex "^\t([^\t]+) \\(compatibility version ([0-9]+.[0-9]+.[0-9]+), current version ([0-9]+.[0-9]+.[0-9]+)\\)${eol_char}$")
+    set(gp_regex_cmp_count 3)
+    set(gp_tool_known 1)
+  endif("${gp_tool}" STREQUAL "otool")
+
+  if("${gp_tool}" STREQUAL "dumpbin")
+    set(gp_cmd_args "/dependents")
+    set(gp_regex "^    ([^ ].*[Dd][Ll][Ll])${eol_char}$")
+    set(gp_regex_cmp_count 1)
+    set(gp_tool_known 1)
+    set(ENV{VS_UNICODE_OUTPUT} "") # Block extra output from inside VS IDE.
+  endif("${gp_tool}" STREQUAL "dumpbin")
+
+  if(NOT gp_tool_known)
+    message(STATUS "warning: gp_tool='${gp_tool}' is an unknown tool...")
+    message(STATUS "CMake function get_prerequisites needs more code to handle '${gp_tool}'")
+    message(STATUS "Valid gp_tool values are dumpbin, ldd and otool.")
+    return()
+  endif(NOT gp_tool_known)
+
+  set(gp_cmd_paths ${gp_cmd_paths}
+    "C:/Program Files/Microsoft Visual Studio 9.0/VC/bin"
+    "C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/bin"
+    "C:/Program Files/Microsoft Visual Studio 8/VC/BIN"
+    "C:/Program Files (x86)/Microsoft Visual Studio 8/VC/BIN"
+    "C:/Program Files/Microsoft Visual Studio .NET 2003/VC7/BIN"
+    "C:/Program Files (x86)/Microsoft Visual Studio .NET 2003/VC7/BIN"
+    "/usr/local/bin"
+    "/usr/bin"
+    )
+
+  find_program(gp_cmd ${gp_tool} PATHS ${gp_cmd_paths})
+
+  if(NOT gp_cmd)
+    message(STATUS "warning: could not find '${gp_tool}' - cannot analyze prerequisites...")
+    return()
+  endif(NOT gp_cmd)
+
+  if("${gp_tool}" STREQUAL "dumpbin")
+    # When running dumpbin, it also needs the "Common7/IDE" directory in the
+    # PATH. It will already be in the PATH if being run from a Visual Studio
+    # command prompt. Add it to the PATH here in case we are running from a
+    # different command prompt.
+    #
+    get_filename_component(gp_cmd_dir "${gp_cmd}" PATH)
+    get_filename_component(gp_cmd_dlls_dir "${gp_cmd_dir}/../../Common7/IDE" ABSOLUTE)
+    if(EXISTS "${gp_cmd_dlls_dir}")
+      # only add to the path if it is not already in the path
+      if(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}")
+        set(ENV{PATH} "$ENV{PATH};${gp_cmd_dlls_dir}")
+      endif(NOT "$ENV{PATH}" MATCHES "${gp_cmd_dlls_dir}")
+    endif(EXISTS "${gp_cmd_dlls_dir}")
+  endif("${gp_tool}" STREQUAL "dumpbin")
+  #
+  # </setup-gp_tool-vars>
+
+  if("${gp_tool}" STREQUAL "ldd")
+    set(old_ld_env "$ENV{LD_LIBRARY_PATH}")
+    foreach(dir ${exepath} ${dirs})
+      set(ENV{LD_LIBRARY_PATH} "${dir}:$ENV{LD_LIBRARY_PATH}")
+    endforeach(dir)
+  endif("${gp_tool}" STREQUAL "ldd")
+
+
+  # Track new prerequisites at each new level of recursion. Start with an
+  # empty list at each level:
+  #
+  set(unseen_prereqs)
+
+  # Run gp_cmd on the target:
+  #
+  execute_process(
+    COMMAND ${gp_cmd} ${gp_cmd_args} ${target}
+    OUTPUT_VARIABLE gp_cmd_ov
+    )
+
+  if("${gp_tool}" STREQUAL "ldd")
+    set(ENV{LD_LIBRARY_PATH} "${old_ld_env}")
+  endif("${gp_tool}" STREQUAL "ldd")
+
+  if(verbose)
+    message(STATUS "<RawOutput cmd='${gp_cmd} ${gp_cmd_args} ${target}'>")
+    message(STATUS "gp_cmd_ov='${gp_cmd_ov}'")
+    message(STATUS "</RawOutput>")
+  endif(verbose)
+
+  get_filename_component(target_dir "${target}" PATH)
+
+  # Convert to a list of lines:
+  #
+  string(REGEX REPLACE ";" "\\\\;" candidates "${gp_cmd_ov}")
+  string(REGEX REPLACE "\n" "${eol_char};" candidates "${candidates}")
+
+  # Analyze each line for file names that match the regular expression:
+  #
+  foreach(candidate ${candidates})
+  if("${candidate}" MATCHES "${gp_regex}")
+    # Extract information from each candidate:
+    string(REGEX REPLACE "${gp_regex}" "\\1" raw_item "${candidate}")
+
+    if(gp_regex_cmp_count GREATER 1)
+      string(REGEX REPLACE "${gp_regex}" "\\2" raw_compat_version "${candidate}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" compat_major_version "${raw_compat_version}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" compat_minor_version "${raw_compat_version}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" compat_patch_version "${raw_compat_version}")
+    endif(gp_regex_cmp_count GREATER 1)
+
+    if(gp_regex_cmp_count GREATER 2)
+      string(REGEX REPLACE "${gp_regex}" "\\3" raw_current_version "${candidate}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\1" current_major_version "${raw_current_version}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\2" current_minor_version "${raw_current_version}")
+      string(REGEX REPLACE "^([0-9]+)\\.([0-9]+)\\.([0-9]+)$" "\\3" current_patch_version "${raw_current_version}")
+    endif(gp_regex_cmp_count GREATER 2)
+
+    # Use the raw_item as the list entries returned by this function. Use the
+    # gp_resolve_item function to resolve it to an actual full path file if
+    # necessary.
+    #
+    set(item "${raw_item}")
+
+    # Add each item unless it is excluded:
+    #
+    set(add_item 1)
+
+    if(${exclude_system})
+      set(type "")
+      gp_resolved_file_type("${target}" "${item}" "${exepath}" "${dirs}" type)
+      if("${type}" STREQUAL "system")
+        set(add_item 0)
+      endif("${type}" STREQUAL "system")
+    endif(${exclude_system})
+
+    if(add_item)
+      list(LENGTH ${prerequisites_var} list_length_before_append)
+      gp_append_unique(${prerequisites_var} "${item}")
+      list(LENGTH ${prerequisites_var} list_length_after_append)
+
+      if(${recurse})
+        # If item was really added, this is the first time we have seen it.
+        # Add it to unseen_prereqs so that we can recursively add *its*
+        # prerequisites...
+        #
+        # But first: resolve its name to an absolute full path name such
+        # that the analysis tools can simply accept it as input.
+        #
+        if(NOT list_length_before_append EQUAL list_length_after_append)
+          gp_resolve_item("${target}" "${item}" "${exepath}" "${dirs}" resolved_item)
+          set(unseen_prereqs ${unseen_prereqs} "${resolved_item}")
+        endif(NOT list_length_before_append EQUAL list_length_after_append)
+      endif(${recurse})
+    endif(add_item)
+  else("${candidate}" MATCHES "${gp_regex}")
+    if(verbose)
+      message(STATUS "ignoring non-matching line: '${candidate}'")
+    endif(verbose)
+  endif("${candidate}" MATCHES "${gp_regex}")
+  endforeach(candidate)
+
+  list(LENGTH ${prerequisites_var} prerequisites_var_length)
+  if(prerequisites_var_length GREATER 0)
+    list(SORT ${prerequisites_var})
+  endif(prerequisites_var_length GREATER 0)
+  if(${recurse})
+    set(more_inputs ${unseen_prereqs})
+    foreach(input ${more_inputs})
+      get_prerequisites("${input}" ${prerequisites_var} ${exclude_system} ${recurse} "${exepath}" "${dirs}")
+    endforeach(input)
+  endif(${recurse})
+
+  set(${prerequisites_var} ${${prerequisites_var}} PARENT_SCOPE)
+endfunction(get_prerequisites)
+
+
+# list_prerequisites target all exclude_system verbose
+#
+#  ARGV0 (target) is the full path to an executable file
+#
+#  optional ARGV1 (all) is 0 or 1: 0 for direct prerequisites only,
+#   1 for all prerequisites recursively
+#
+#  optional ARGV2 (exclude_system) is 0 or 1: 0 to include "system"
+#   prerequisites , 1 to exclude them
+#
+#  optional ARGV3 (verbose) is 0 or 1: 0 to print only full path
+#   names of prerequisites, 1 to print extra information
+#
+function(list_prerequisites target)
+  if("${ARGV1}" STREQUAL "")
+    set(all 1)
+  else("${ARGV1}" STREQUAL "")
+    set(all "${ARGV1}")
+  endif("${ARGV1}" STREQUAL "")
+
+  if("${ARGV2}" STREQUAL "")
+    set(exclude_system 0)
+  else("${ARGV2}" STREQUAL "")
+    set(exclude_system "${ARGV2}")
+  endif("${ARGV2}" STREQUAL "")
+
+  if("${ARGV3}" STREQUAL "")
+    set(verbose 0)
+  else("${ARGV3}" STREQUAL "")
+    set(verbose "${ARGV3}")
+  endif("${ARGV3}" STREQUAL "")
+
+  set(count 0)
+  set(count_str "")
+  set(print_count "${verbose}")
+  set(print_prerequisite_type "${verbose}")
+  set(print_target "${verbose}")
+  set(type_str "")
+
+  get_filename_component(exepath "${target}" PATH)
+
+  set(prereqs "")
+  get_prerequisites("${target}" prereqs ${exclude_system} ${all} "${exepath}" "")
+
+  if(print_target)
+    message(STATUS "File '${target}' depends on:")
+  endif(print_target)
+
+  foreach(d ${prereqs})
+    math(EXPR count "${count} + 1")
+
+    if(print_count)
+      set(count_str "${count}. ")
+    endif(print_count)
+
+    if(print_prerequisite_type)
+      gp_file_type("${target}" "${d}" type)
+      set(type_str " (${type})")
+    endif(print_prerequisite_type)
+
+    message(STATUS "${count_str}${d}${type_str}")
+  endforeach(d)
+endfunction(list_prerequisites)
+
+
+# list_prerequisites_by_glob glob_arg glob_exp
+#
+#  glob_arg is GLOB or GLOB_RECURSE
+#
+#  glob_exp is a globbing expression used with "file(GLOB" to retrieve a list
+#   of matching files. If a matching file is executable, its prerequisites are
+#   listed.
+#
+# Any additional (optional) arguments provided are passed along as the
+# optional arguments to the list_prerequisites calls.
+#
+function(list_prerequisites_by_glob glob_arg glob_exp)
+  message(STATUS "=============================================================================")
+  message(STATUS "List prerequisites of executables matching ${glob_arg} '${glob_exp}'")
+  message(STATUS "")
+  file(${glob_arg} file_list ${glob_exp})
+  foreach(f ${file_list})
+    is_file_executable("${f}" is_f_executable)
+    if(is_f_executable)
+      message(STATUS "=============================================================================")
+      list_prerequisites("${f}" ${ARGN})
+      message(STATUS "")
+    endif(is_f_executable)
+  endforeach(f)
+endfunction(list_prerequisites_by_glob)
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
index 62b764bb307debcee404eb7bc355f8b361cabadb..05f0492234f059146f38ef586295707ef3456cff 100644
--- a/indra/cmake/LLAddBuildTest.cmake
+++ b/indra/cmake/LLAddBuildTest.cmake
@@ -1,276 +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} )
-    # 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)
+# -*- 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/integration_tests/llui_libtest/llui_libtest.cpp b/indra/integration_tests/llui_libtest/llui_libtest.cpp
index c34115ee8064a6d8a63b3ad03ad85e7d44b5dfed..217e26c3ca527380c91fd8bbc1e1d42d3debc83b 100644
--- a/indra/integration_tests/llui_libtest/llui_libtest.cpp
+++ b/indra/integration_tests/llui_libtest/llui_libtest.cpp
@@ -33,6 +33,7 @@
 // linden library includes
 #include "llcontrol.h"		// LLControlGroup
 #include "lldir.h"
+#include "lldiriterator.h"
 #include "llerrorcontrol.h"
 #include "llfloater.h"
 #include "llfontfreetype.h"
@@ -174,7 +175,9 @@ 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))
+
+	LLDirIterator iter(xui_dir, "floater_test_*.xml");
+	while (iter.next(filename))
 	{
 		if (filename.find("_new.xml") != std::string::npos)
 		{
diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
index d909516bf8fbce6872458eec049e0b4c836df6ae..808ab3f64f81ab2da3d945212f7a510a251018ef 100644
--- a/indra/linux_updater/linux_updater.cpp
+++ b/indra/linux_updater/linux_updater.cpp
@@ -33,6 +33,7 @@
 #include "llerrorcontrol.h"
 #include "llfile.h"
 #include "lldir.h"
+#include "lldiriterator.h"
 #include "llxmlnode.h"
 #include "lltrans.h"
 
@@ -55,6 +56,8 @@ typedef struct _updater_app_state {
 	std::string strings_dirs;
 	std::string strings_file;
 
+	LLDirIterator *image_dir_iter;
+
 	GtkWidget *window;
 	GtkWidget *progress_bar;
 	GtkWidget *image;
@@ -108,7 +111,7 @@ bool translate_init(std::string comma_delim_path_list,
 void updater_app_ui_init(void);
 void updater_app_quit(UpdaterAppState *app_state);
 void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state);
-std::string next_image_filename(std::string& image_path);
+std::string next_image_filename(std::string& image_path, LLDirIterator& iter);
 void display_error(GtkWidget *parent, std::string title, std::string message);
 BOOL install_package(std::string package_file, std::string destination);
 BOOL spawn_viewer(UpdaterAppState *app_state);
@@ -174,7 +177,7 @@ void updater_app_ui_init(UpdaterAppState *app_state)
 
 		// load the first image
 		app_state->image = gtk_image_new_from_file
-			(next_image_filename(app_state->image_dir).c_str());
+			(next_image_filename(app_state->image_dir, *app_state->image_dir_iter).c_str());
 		gtk_widget_set_size_request(app_state->image, 340, 310);
 		gtk_container_add(GTK_CONTAINER(frame), app_state->image);
 
@@ -205,7 +208,7 @@ gboolean rotate_image_cb(gpointer data)
 	llassert(data != NULL);
 	app_state = (UpdaterAppState *) data;
 
-	filename = next_image_filename(app_state->image_dir);
+	filename = next_image_filename(app_state->image_dir, *app_state->image_dir_iter);
 
 	gdk_threads_enter();
 	gtk_image_set_from_file(GTK_IMAGE(app_state->image), filename.c_str());
@@ -214,10 +217,10 @@ gboolean rotate_image_cb(gpointer data)
 	return TRUE;
 }
 
-std::string next_image_filename(std::string& image_path)
+std::string next_image_filename(std::string& image_path, LLDirIterator& iter)
 {
 	std::string image_filename;
-	gDirUtilp->getNextFileInDir(image_path, "/*.jpg", image_filename);
+	iter.next(image_filename);
 	return image_path + "/" + image_filename;
 }
 
@@ -741,6 +744,7 @@ void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
 		else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc))
 		{
 			app_state->image_dir = argv[i];
+			app_state->image_dir_iter = new LLDirIterator(argv[i], "/*.jpg");
 		}
 		else if ((!strcmp(argv[i], "--dest")) && (++i < argc))
 		{
@@ -825,6 +829,7 @@ int main(int argc, char **argv)
 	}
 
 	bool success = !app_state->failure;
+	delete app_state->image_dir_iter;
 	delete app_state;
 	return success ? 0 : 1;
 }
diff --git a/indra/llmath/llbbox.cpp b/indra/llmath/llbbox.cpp
index b46a6e03d2ed198ed9680e31b98bc711e9b172e1..3e2c05a6e6d4d861c6755213b88fb785e87ad0cb 100644
--- a/indra/llmath/llbbox.cpp
+++ b/indra/llmath/llbbox.cpp
@@ -89,6 +89,19 @@ void LLBBox::addBBoxAgent(const LLBBox& b)
 	}
 }
 
+LLBBox LLBBox::getAxisAligned() const
+{
+	// no rotation = axis aligned rotation
+	LLBBox aligned(mPosAgent, LLQuaternion(), LLVector3(), LLVector3());
+
+	// add the center point so that it's not empty
+	aligned.addPointAgent(mPosAgent);
+
+	// add our BBox
+	aligned.addBBoxAgent(*this);
+
+	return aligned;
+}
 
 void LLBBox::expand( F32 delta )
 {
@@ -147,6 +160,15 @@ BOOL LLBBox::containsPointAgent(const LLVector3& p) const
 	return containsPointLocal(point_local);
 }
 
+LLVector3 LLBBox::getMinAgent() const
+{
+	return localToAgent(mMinLocal);
+}
+
+LLVector3 LLBBox::getMaxAgent() const
+{
+	return localToAgent(mMaxLocal);
+}
 
 /*
 LLBBox operator*(const LLBBox &a, const LLMatrix4 &b)
diff --git a/indra/llmath/llbbox.h b/indra/llmath/llbbox.h
index 5b911793f0f4ae12289deff4e00540a8ea8a877a..28e69b75e122629aa680b83927463be3aefd52c9 100644
--- a/indra/llmath/llbbox.h
+++ b/indra/llmath/llbbox.h
@@ -51,9 +51,11 @@ class LLBBox
 	const LLVector3&	getPositionAgent() const			{ return mPosAgent; }
 	const LLQuaternion&	getRotation() const					{ return mRotation; }
 
+	LLVector3           getMinAgent() const;
 	const LLVector3&	getMinLocal() const					{ return mMinLocal; }
 	void				setMinLocal( const LLVector3& min )	{ mMinLocal = min; }
 
+	LLVector3           getMaxAgent() const;
 	const LLVector3&	getMaxLocal() const					{ return mMaxLocal; }
 	void				setMaxLocal( const LLVector3& max )	{ mMaxLocal = max; }
 
@@ -80,6 +82,8 @@ class LLBBox
 	LLVector3			localToAgentBasis(const LLVector3& v) const;
 	LLVector3			agentToLocalBasis(const LLVector3& v) const;
 
+	// Get the smallest possible axis aligned bbox that contains this bbox
+	LLBBox              getAxisAligned() const;
 
 //	friend LLBBox operator*(const LLBBox& a, const LLMatrix4& b);
 
diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h
index b9b974ec4f6a8109cbad4859b0c8f4671767654e..7b796a0fa875f92785ac0f0c376338c453188f97 100644
--- a/indra/llmessage/llregionflags.h
+++ b/indra/llmessage/llregionflags.h
@@ -42,9 +42,6 @@ const U32 REGION_FLAGS_RESET_HOME_ON_TELEPORT	= (1 << 3);
 // Does the sun move?
 const U32 REGION_FLAGS_SUN_FIXED				= (1 << 4);
 
-// Tax free zone (no taxes on objects, land, etc.)
-const U32 REGION_FLAGS_TAX_FREE					= (1 << 5);
-
 // Can't change the terrain heightfield, even on owned parcels,
 // but can plant trees and grass.
 const U32 REGION_FLAGS_BLOCK_TERRAFORM			= (1 << 6);
@@ -54,17 +51,12 @@ const U32 REGION_FLAGS_BLOCK_LAND_RESELL		= (1 << 7);
 
 // All content wiped once per night
 const U32 REGION_FLAGS_SANDBOX					= (1 << 8);
-const U32 REGION_FLAGS_NULL_LAYER				= (1 << 9);
-// const U32 REGION_FLAGS_SKIP_AGENT_ACTION		= (1 << 10);
-const U32 REGION_FLAGS_HARD_ALLOW_LAND_TRANSFER	= (1 << 10);	// Region allows land reselling
-// const U32 REGION_FLAGS_SKIP_UPDATE_INTEREST_LIST= (1 << 11);
-const U32 REGION_FLAGS_HARD_ALLOW_POST_CLASSIFIED	= (1 << 11);	// Region allows posting of classified ads
 const U32 REGION_FLAGS_SKIP_COLLISIONS			= (1 << 12); // Pin all non agent rigid bodies
 const U32 REGION_FLAGS_SKIP_SCRIPTS				= (1 << 13);
 const U32 REGION_FLAGS_SKIP_PHYSICS				= (1 << 14); // Skip all physics
 const U32 REGION_FLAGS_EXTERNALLY_VISIBLE		= (1 << 15);
-//const U32 REGION_FLAGS_MAINLAND_VISIBLE			= (1 << 16);
-const U32 REGION_FLAGS_PUBLIC_ALLOWED			= (1 << 17);
+const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16);
+const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17);
 const U32 REGION_FLAGS_BLOCK_DWELL				= (1 << 18);
 
 // Is flight allowed?
@@ -81,18 +73,13 @@ const U32 REGION_FLAGS_ESTATE_SKIP_SCRIPTS		= (1 << 21);
 const U32 REGION_FLAGS_RESTRICT_PUSHOBJECT		= (1 << 22);
 
 const U32 REGION_FLAGS_DENY_ANONYMOUS			= (1 << 23);
-// const U32 REGION_FLAGS_DENY_IDENTIFIED			= (1 << 24);
-// const U32 REGION_FLAGS_DENY_TRANSACTED			= (1 << 25);
 
 const U32 REGION_FLAGS_ALLOW_PARCEL_CHANGES		= (1 << 26);
 
-// const U32 REGION_FLAGS_ABUSE_EMAIL_TO_ESTATE_OWNER = (1 << 27); // We no longer support ELAR
-
 const U32 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
 
 const U32 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);
 const U32 REGION_FLAGS_DENY_AGEUNVERIFIED	= (1 << 30);
-const U32 REGION_FLAGS_SKIP_MONO_SCRIPTS	= (1 << 31);
 
 const U32 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |
 								 REGION_FLAGS_ALLOW_SET_HOME |
@@ -105,7 +92,6 @@ const U32 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK
 									   | REGION_FLAGS_ALLOW_SET_HOME;
 
 const U32 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE
-									 | REGION_FLAGS_PUBLIC_ALLOWED	
 									 | REGION_FLAGS_SUN_FIXED
 									 | REGION_FLAGS_DENY_ANONYMOUS
 									 | REGION_FLAGS_DENY_AGEUNVERIFIED;
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index d30697e1784487c2f9694dae189b3d3ac9e11bf3..c4257827152fab8bf99420a3d2cb02e871f2f00b 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -272,9 +272,6 @@ LLFloater::LLFloater(const LLSD& key, const LLFloater::Params& p)
 	
 	initFromParams(p);
 	
-	// chrome floaters don't take focus at all
-	setFocusRoot(!getIsChrome());
-
 	initFloater(p);
 }
 
@@ -2910,8 +2907,6 @@ bool LLFloater::initFloaterXML(LLXMLNodePtr node, LLView *parent, const std::str
 	params.from_xui = true;
 	applyXUILayout(params, parent);
  	initFromParams(params);
-	// chrome floaters don't take focus at all
-	setFocusRoot(!getIsChrome());
 
 	initFloater(params);
 	
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 6c0d47ef63d08ffc776cb5bf2cb3de240c93585d..32d7be377a3386a34f769fbb20876712b7b0ef3f 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -1637,6 +1637,10 @@ LLMenuScrollItem::LLMenuScrollItem(const Params& p)
 	}
 
 	LLButton::Params bparams;
+
+	// Disabled the Return key handling by LLMenuScrollItem instead of
+	// passing the key press to the currently selected menu item. See STORM-385.
+	bparams.commit_on_return(false);
 	bparams.mouse_opaque(true);
 	bparams.scale_image(false);
 	bparams.click_callback(p.scroll_callback);
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index 4f7b4be52609206899dee5e9934bdf6c9aa49d62..9db1feafd1b179c9bea839139188158b4b4de205 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -36,6 +36,7 @@
 #include "llcachename.h"
 #include "lltrans.h"
 #include "lluicolortable.h"
+#include "message.h"
 
 #define APP_HEADER_REGEX "((x-grid-location-info://[-\\w\\.]+/app)|(secondlife:///app))"
 
@@ -684,8 +685,8 @@ std::string LLUrlEntryGroup::getLabel(const std::string &url, const LLUrlLabelCa
 LLStyle::Params LLUrlEntryGroup::getStyle() const
 {
 	LLStyle::Params style_params = LLUrlEntryBase::getStyle();
-	style_params.color = LLUIColorTable::instance().getColor("GroupLinkColor");
-	style_params.readonly_color = LLUIColorTable::instance().getColor("GroupLinkColor");
+	style_params.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
+	style_params.readonly_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
 	return style_params;
 }
 
@@ -740,6 +741,13 @@ std::string LLUrlEntryObjectIM::getLocation(const std::string &url) const
 	return LLUrlEntryBase::getLocation(url);
 }
 
+// LLUrlEntryParcel statics.
+LLUUID	LLUrlEntryParcel::sAgentID(LLUUID::null);
+LLUUID	LLUrlEntryParcel::sSessionID(LLUUID::null);
+LLHost	LLUrlEntryParcel::sRegionHost(LLHost::invalid);
+bool	LLUrlEntryParcel::sDisconnected(false);
+std::set<LLUrlEntryParcel*> LLUrlEntryParcel::sParcelInfoObservers;
+
 ///
 /// LLUrlEntryParcel Describes a Second Life parcel Url, e.g.,
 /// secondlife:///app/parcel/0000060e-4b39-e00b-d0c3-d98b1934e3a8/about
@@ -751,13 +759,88 @@ LLUrlEntryParcel::LLUrlEntryParcel()
 							boost::regex::perl|boost::regex::icase);
 	mMenuName = "menu_url_parcel.xml";
 	mTooltip = LLTrans::getString("TooltipParcelUrl");
+
+	sParcelInfoObservers.insert(this);
+}
+
+LLUrlEntryParcel::~LLUrlEntryParcel()
+{
+	sParcelInfoObservers.erase(this);
 }
 
 std::string LLUrlEntryParcel::getLabel(const std::string &url, const LLUrlLabelCallback &cb)
 {
+	LLSD path_array = LLURI(url).pathArray();
+	S32 path_parts = path_array.size();
+
+	if (path_parts < 3) // no parcel id
+	{
+		llwarns << "Failed to parse url [" << url << "]" << llendl;
+		return url;
+	}
+
+	std::string parcel_id_string = unescapeUrl(path_array[2]); // parcel id
+
+	// Add an observer to call LLUrlLabelCallback when we have parcel name.
+	addObserver(parcel_id_string, url, cb);
+
+	LLUUID parcel_id(parcel_id_string);
+
+	sendParcelInfoRequest(parcel_id);
+
 	return unescapeUrl(url);
 }
 
+void LLUrlEntryParcel::sendParcelInfoRequest(const LLUUID& parcel_id)
+{
+	if (sRegionHost == LLHost::invalid || sDisconnected) return;
+
+	LLMessageSystem *msg = gMessageSystem;
+	msg->newMessage("ParcelInfoRequest");
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, sAgentID );
+	msg->addUUID("SessionID", sSessionID);
+	msg->nextBlock("Data");
+	msg->addUUID("ParcelID", parcel_id);
+	msg->sendReliable(sRegionHost);
+}
+
+void LLUrlEntryParcel::onParcelInfoReceived(const std::string &id, const std::string &label)
+{
+	callObservers(id, label.empty() ? LLTrans::getString("RegionInfoError") : label, mIcon);
+}
+
+// static
+void LLUrlEntryParcel::processParcelInfo(const LLParcelData& parcel_data)
+{
+	std::string label(LLStringUtil::null);
+	if (!parcel_data.name.empty())
+	{
+		label = parcel_data.name;
+	}
+	// If parcel name is empty use Sim_name (x, y, z) for parcel label.
+	else if (!parcel_data.sim_name.empty())
+	{
+		S32 region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
+		S32 region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
+		S32 region_z = llround(parcel_data.global_z);
+
+		label = llformat("%s (%d, %d, %d)",
+				parcel_data.sim_name.c_str(), region_x, region_y, region_z);
+	}
+
+	for (std::set<LLUrlEntryParcel*>::iterator iter = sParcelInfoObservers.begin();
+			iter != sParcelInfoObservers.end();
+			++iter)
+	{
+		LLUrlEntryParcel* url_entry = *iter;
+		if (url_entry)
+		{
+			url_entry->onParcelInfoReceived(parcel_data.parcel_id.asString(), label);
+		}
+	}
+}
+
 //
 // LLUrlEntryPlace Describes secondlife://<location> URLs
 //
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 1791739061cdae4c3cf3db6891984ef99d2eeb08..5f82721c0fdf9067383f1d974a052242c4c8a2a3 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -31,6 +31,9 @@
 #include "lluuid.h"
 #include "lluicolor.h"
 #include "llstyle.h"
+
+#include "llhost.h" // for resolving parcel name by parcel id
+
 #include <boost/signals2.hpp>
 #include <boost/regex.hpp>
 #include <string>
@@ -285,8 +288,44 @@ class LLUrlEntryObjectIM : public LLUrlEntryBase
 class LLUrlEntryParcel : public LLUrlEntryBase
 {
 public:
+	struct LLParcelData
+	{
+		LLUUID		parcel_id;
+		std::string	name;
+		std::string	sim_name;
+		F32			global_x;
+		F32			global_y;
+		F32			global_z;
+	};
+
 	LLUrlEntryParcel();
+	~LLUrlEntryParcel();
 	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
+
+	// Sends a parcel info request to sim.
+	void sendParcelInfoRequest(const LLUUID& parcel_id);
+
+	// Calls observers of certain parcel id providing them with parcel label.
+	void onParcelInfoReceived(const std::string &id, const std::string &label);
+
+	// Processes parcel label and triggers notifying observers.
+	static void processParcelInfo(const LLParcelData& parcel_data);
+
+	// Next 4 setters are used to update agent and viewer connection information
+	// upon events like user login, viewer disconnect and user changing region host.
+	// These setters are made public to be accessible from newview and should not be
+	// used in other cases.
+	static void setAgentID(const LLUUID& id) { sAgentID = id; }
+	static void setSessionID(const LLUUID& id) { sSessionID = id; }
+	static void setRegionHost(const LLHost& host) { sRegionHost = host; }
+	static void setDisconnected(bool disconnected) { sDisconnected = disconnected; }
+
+private:
+	static LLUUID						sAgentID;
+	static LLUUID						sSessionID;
+	static LLHost						sRegionHost;
+	static bool							sDisconnected;
+	static std::set<LLUrlEntryParcel*>	sParcelInfoObservers;
 };
 
 ///
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index f30704cb2269c8b40b9fd5b0f44fe51aa934e7db..96ebe83826c5137dd90cd0458620a15d2777a4c8 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -30,6 +30,7 @@
 #include "llavatarnamecache.h"
 #include "llcachename.h"
 #include "lluuid.h"
+#include "message.h"
 
 #include <string>
 
@@ -191,3 +192,20 @@ LLFontGL* LLFontGL::getFontDefault()
 {
 	return NULL; 
 }
+
+char* _PREHASH_AgentData = "AgentData";
+char* _PREHASH_AgentID = "AgentID";
+
+LLHost LLHost::invalid(INVALID_PORT,INVALID_HOST_IP_ADDRESS);
+
+LLMessageSystem* gMessageSystem = NULL;
+
+//
+// Stub implementation for LLMessageSystem
+//
+void LLMessageSystem::newMessage(const char *name) { }
+void LLMessageSystem::nextBlockFast(const char *blockname) { }
+void LLMessageSystem::nextBlock(const char *blockname) { }
+void LLMessageSystem::addUUIDFast( const char *varname, const LLUUID& uuid) { }
+void LLMessageSystem::addUUID( const char *varname, const LLUUID& uuid) { }
+S32 LLMessageSystem::sendReliable(const LLHost &host) { return 0; }
diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt
index 722f4e2bfdef9c6212c9edf06f2abee5f55ff996..a3782d824b4cbbcf0abe31ecb5d754238cf3c8a5 100644
--- a/indra/llvfs/CMakeLists.txt
+++ b/indra/llvfs/CMakeLists.txt
@@ -12,6 +12,7 @@ include_directories(
 
 set(llvfs_SOURCE_FILES
     lldir.cpp
+    lldiriterator.cpp
     lllfsthread.cpp
     llpidlock.cpp
     llvfile.cpp
@@ -24,6 +25,7 @@ set(llvfs_HEADER_FILES
 
     lldir.h
     lldirguard.h
+    lldiriterator.h
     lllfsthread.h
     llpidlock.h
     llvfile.h
@@ -60,6 +62,11 @@ list(APPEND llvfs_SOURCE_FILES ${llvfs_HEADER_FILES})
 
 add_library (llvfs ${llvfs_SOURCE_FILES})
 
+target_link_libraries(llvfs
+    ${BOOST_FILESYSTEM_LIBRARY}
+    ${BOOST_SYSTEM_LIBRARY}
+    )
+
 if (DARWIN)
   include(CMakeFindFrameworks)
   find_library(CARBON_LIBRARY Carbon)
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 64556bcb4c34dcacd2b48f391dbfebf0eb528421..ab7d15dfefdcbec79c3d894b19dee81f0352b0a3 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -40,6 +40,8 @@
 #include "lltimer.h"	// ms_sleep()
 #include "lluuid.h"
 
+#include "lldiriterator.h"
+
 #if LL_WINDOWS
 #include "lldir_win32.h"
 LLDir_Win32 gDirUtil;
@@ -83,7 +85,9 @@ S32 LLDir::deleteFilesInDir(const std::string &dirname, const std::string &mask)
 	std::string filename; 
 	std::string fullpath;
 	S32 result;
-	while (getNextFileInDir(dirname, mask, filename))
+
+	LLDirIterator iter(dirname, mask);
+	while (iter.next(filename))
 	{
 		fullpath = dirname;
 		fullpath += getDirDelimiter();
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 42996fd051b9f5cc8ed949645fa7fda5c4c58f74..5ee8bdb542da2ebc4ee3d10ce114a7df3c1e20b6 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -75,31 +75,6 @@ class LLDir
 // pure virtual functions
 	virtual U32 countFilesInDir(const std::string &dirname, const std::string &mask) = 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 73f2336f94fa70bf2d43bc6b924ed6262b7bd2e8..4ba2f519b0f8080d700dd4c672abeac8ce803962 100644
--- a/indra/llvfs/lldir_linux.cpp
+++ b/indra/llvfs/lldir_linux.cpp
@@ -242,68 +242,6 @@ U32 LLDir_Linux::countFilesInDir(const std::string &dirname, const std::string &
 	return (file_count);
 }
 
-// get the next file in the directory
-BOOL LLDir_Linux::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
-{
-	glob_t g;
-	BOOL result = FALSE;
-	fname = "";
-	
-	if(!(dirname == mCurrentDir))
-	{
-		// different dir specified, close old search
-		mCurrentDirIndex = -1;
-		mCurrentDirCount = -1;
-		mCurrentDir = dirname;
-	}
-	
-	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)
-		{
-			if((int)g.gl_pathc != mCurrentDirCount)
-			{
-				// Number of matches has changed since the last search, meaning a file has been added or deleted.
-				// Reset the index.
-				mCurrentDirIndex = -1;
-				mCurrentDirCount = g.gl_pathc;
-			}
-	
-			mCurrentDirIndex++;
-	
-			if(mCurrentDirIndex < (int)g.gl_pathc)
-			{
-//				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
-
-				// The API wants just the filename, not the full path.
-				//fname = g.gl_pathv[mCurrentDirIndex];
-
-				char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/');
-				
-				if(s == NULL)
-					s = g.gl_pathv[mCurrentDirIndex];
-				else if(s[0] == '/')
-					s++;
-					
-				fname = s;
-				
-				result = TRUE;
-			}
-		}
-		
-		globfree(&g);
-	}
-	
-	return(result);
-}
-
-
-
-
 std::string LLDir_Linux::getCurPath()
 {
 	char tmp_str[LL_MAX_PATH];	/* Flawfinder: ignore */ 
diff --git a/indra/llvfs/lldir_linux.h b/indra/llvfs/lldir_linux.h
index 451e81ae93c560114b83f556120f3fd42f6dbec9..ff4c48759a03327d6b04191d3b179451ad0fd3fd 100644
--- a/indra/llvfs/lldir_linux.h
+++ b/indra/llvfs/lldir_linux.h
@@ -43,7 +43,6 @@ 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);
 	/*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 445285aa43ac2c5dae2c11187e73280dc88614db..2d039527c06fa05286ddcbd04226a4425c0e85fb 100644
--- a/indra/llvfs/lldir_mac.cpp
+++ b/indra/llvfs/lldir_mac.cpp
@@ -258,67 +258,6 @@ U32 LLDir_Mac::countFilesInDir(const std::string &dirname, const std::string &ma
 	return (file_count);
 }
 
-// get the next file in the directory
-BOOL LLDir_Mac::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
-{
-	glob_t g;
-	BOOL result = FALSE;
-	fname = "";
-	
-	if(!(dirname == mCurrentDir))
-	{
-		// different dir specified, close old search
-		mCurrentDirIndex = -1;
-		mCurrentDirCount = -1;
-		mCurrentDir = dirname;
-	}
-	
-	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)
-		{
-			if(g.gl_pathc != mCurrentDirCount)
-			{
-				// Number of matches has changed since the last search, meaning a file has been added or deleted.
-				// Reset the index.
-				mCurrentDirIndex = -1;
-				mCurrentDirCount = g.gl_pathc;
-			}
-	
-			mCurrentDirIndex++;
-	
-			if(mCurrentDirIndex < g.gl_pathc)
-			{
-//				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
-
-				// The API wants just the filename, not the full path.
-				//fname = g.gl_pathv[mCurrentDirIndex];
-
-				char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/');
-				
-				if(s == NULL)
-					s = g.gl_pathv[mCurrentDirIndex];
-				else if(s[0] == '/')
-					s++;
-					
-				fname = s;
-				
-				result = TRUE;
-			}
-		}
-		
-		globfree(&g);
-	}
-	
-	return(result);
-}
-
-
-
 S32 LLDir_Mac::deleteFilesInDir(const std::string &dirname, const std::string &mask)
 {
 	glob_t g;
diff --git a/indra/llvfs/lldir_mac.h b/indra/llvfs/lldir_mac.h
index 4eac3c3ae6fce824624bc7c048b8922c6c86e517..e60d5e41c2deca2e9aaca01d8f34306fbb896c1a 100644
--- a/indra/llvfs/lldir_mac.h
+++ b/indra/llvfs/lldir_mac.h
@@ -43,7 +43,6 @@ 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);
 	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 515fd66b6e9a9f4d2aef1647ad78134a15419f0c..21f8c3acdbeefa56272bac597cf5b1d1858ba46c 100644
--- a/indra/llvfs/lldir_solaris.cpp
+++ b/indra/llvfs/lldir_solaris.cpp
@@ -260,68 +260,6 @@ U32 LLDir_Solaris::countFilesInDir(const std::string &dirname, const std::string
 	return (file_count);
 }
 
-// get the next file in the directory
-BOOL LLDir_Solaris::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
-{
-	glob_t g;
-	BOOL result = FALSE;
-	fname = "";
-	
-	if(!(dirname == mCurrentDir))
-	{
-		// different dir specified, close old search
-		mCurrentDirIndex = -1;
-		mCurrentDirCount = -1;
-		mCurrentDir = dirname;
-	}
-	
-	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)
-		{
-			if((int)g.gl_pathc != mCurrentDirCount)
-			{
-				// Number of matches has changed since the last search, meaning a file has been added or deleted.
-				// Reset the index.
-				mCurrentDirIndex = -1;
-				mCurrentDirCount = g.gl_pathc;
-			}
-	
-			mCurrentDirIndex++;
-	
-			if(mCurrentDirIndex < (int)g.gl_pathc)
-			{
-//				llinfos << "getNextFileInDir: returning number " << mCurrentDirIndex << ", path is " << g.gl_pathv[mCurrentDirIndex] << llendl;
-
-				// The API wants just the filename, not the full path.
-				//fname = g.gl_pathv[mCurrentDirIndex];
-
-				char *s = strrchr(g.gl_pathv[mCurrentDirIndex], '/');
-				
-				if(s == NULL)
-					s = g.gl_pathv[mCurrentDirIndex];
-				else if(s[0] == '/')
-					s++;
-					
-				fname = s;
-				
-				result = TRUE;
-			}
-		}
-		
-		globfree(&g);
-	}
-	
-	return(result);
-}
-
-
-
-
 std::string LLDir_Solaris::getCurPath()
 {
 	char tmp_str[LL_MAX_PATH];	/* Flawfinder: ignore */ 
diff --git a/indra/llvfs/lldir_solaris.h b/indra/llvfs/lldir_solaris.h
index 4a1794f53950dab8f147dae3c4bc9cfe4e3b1088..f7e1a6301dbdc19a713e568d44cb28812b048427 100644
--- a/indra/llvfs/lldir_solaris.h
+++ b/indra/llvfs/lldir_solaris.h
@@ -43,7 +43,6 @@ 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);
 	/*virtual*/ BOOL fileExists(const std::string &filename) const;
 
 private:
diff --git a/indra/llvfs/lldir_win32.cpp b/indra/llvfs/lldir_win32.cpp
index 33718e520d71b4c3e2595574187c22d0224c0ce7..2f96fbbbc10d2aeee4a78a3c29742aacad05c6e2 100644
--- a/indra/llvfs/lldir_win32.cpp
+++ b/indra/llvfs/lldir_win32.cpp
@@ -236,67 +236,6 @@ U32 LLDir_Win32::countFilesInDir(const std::string &dirname, const std::string &
 	return (file_count);
 }
 
-
-// get the next file in the directory
-BOOL LLDir_Win32::getNextFileInDir(const std::string &dirname, const std::string &mask, std::string &fname)
-{
-    BOOL fileFound = FALSE;
-	fname = "";
-
-	WIN32_FIND_DATAW FileData;
-    llutf16string pathname = utf8str_to_utf16str(dirname) + utf8str_to_utf16str(mask);
-
-	if (pathname != mCurrentDir)
-	{
-		// different dir specified, close old search
-		if (mCurrentDir[0])
-		{
-			FindClose(mDirSearch_h);
-		}
-		mCurrentDir = pathname;
-
-		// and open new one
-		// Check error opening Directory structure
-		if ((mDirSearch_h = FindFirstFile(pathname.c_str(), &FileData)) != INVALID_HANDLE_VALUE)   
-		{
-           fileFound = TRUE;
-		}
-	}
-
-    // 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 (fileFound)
-    {
-        // convert from TCHAR to char
-        fname = utf16str_to_utf8str(FileData.cFileName);
-	}
-    
-	return fileFound;
-}
-
 std::string LLDir_Win32::getCurPath()
 {
 	WCHAR w_str[MAX_PATH];
diff --git a/indra/llvfs/lldir_win32.h b/indra/llvfs/lldir_win32.h
index 4c932c932c8f06d6015c106f2b2cd8c9bd50e7f6..19c610eb8b2f6aeee28622a62568a7e14df7517d 100644
--- a/indra/llvfs/lldir_win32.h
+++ b/indra/llvfs/lldir_win32.h
@@ -40,15 +40,12 @@ 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);
 	/*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);
-	
 	void* mDirSearch_h;
 	llutf16string mCurrentDir;
 };
diff --git a/indra/llvfs/lldiriterator.cpp b/indra/llvfs/lldiriterator.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5536ed8f69a97c49721cf0242d8a97bf5d89ad1f
--- /dev/null
+++ b/indra/llvfs/lldiriterator.cpp
@@ -0,0 +1,203 @@
+/**
+ * @file lldiriterator.cpp
+ * @brief Iterator through directory entries matching the search pattern.
+ *
+ * $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 "lldiriterator.h"
+
+#include <boost/filesystem.hpp>
+#include <boost/regex.hpp>
+
+namespace fs = boost::filesystem;
+
+static std::string glob_to_regex(const std::string& glob);
+
+class LLDirIterator::Impl
+{
+public:
+	Impl(const std::string &dirname, const std::string &mask);
+	~Impl();
+
+	bool next(std::string &fname);
+
+private:
+	boost::regex			mFilterExp;
+	fs::directory_iterator	mIter;
+	bool					mIsValid;
+};
+
+LLDirIterator::Impl::Impl(const std::string &dirname, const std::string &mask)
+	: mIsValid(false)
+{
+	fs::path dir_path(dirname);
+
+	// Check if path exists.
+	if (!fs::exists(dir_path))
+	{
+		llerrs << "Invalid path: \"" << dir_path.string() << "\"" << llendl;
+		return;
+	}
+
+	// Initialize the directory iterator for the given path.
+	try
+	{
+		mIter = fs::directory_iterator(dir_path);
+	}
+	catch (fs::basic_filesystem_error<fs::path>& e)
+	{
+		llerrs << e.what() << llendl;
+		return;
+	}
+
+	// Convert the glob mask to a regular expression
+	std::string exp = glob_to_regex(mask);
+
+	// Initialize boost::regex with the expression converted from
+	// the glob mask.
+	// An exception is thrown if the expression is not valid.
+	try
+	{
+		mFilterExp.assign(exp);
+	}
+	catch (boost::regex_error& e)
+	{
+		llerrs << "\"" << exp << "\" is not a valid regular expression: "
+				<< e.what() << llendl;
+		return;
+	}
+
+	mIsValid = true;
+}
+
+LLDirIterator::Impl::~Impl()
+{
+}
+
+bool LLDirIterator::Impl::next(std::string &fname)
+{
+	fname = "";
+
+	if (!mIsValid)
+	{
+		llerrs << "The iterator is not correctly initialized." << llendl;
+		return false;
+	}
+
+	fs::directory_iterator end_itr; // default construction yields past-the-end
+	bool found = false;
+	while (mIter != end_itr && !found)
+	{
+		boost::smatch match;
+		std::string name = mIter->path().filename();
+		if (found = boost::regex_match(name, match, mFilterExp))
+		{
+			fname = name;
+		}
+
+		++mIter;
+	}
+
+	return found;
+}
+
+std::string glob_to_regex(const std::string& glob)
+{
+	std::string regex;
+	regex.reserve(glob.size()<<1);
+	S32 braces = 0;
+	bool escaped = false;
+	bool square_brace_open = false;
+
+	for (std::string::const_iterator i = glob.begin(); i != glob.end(); ++i)
+	{
+		char c = *i;
+
+		switch (c)
+		{
+			case '.':
+				regex+="\\.";
+				break;
+			case '*':
+				if (glob.begin() == i)
+				{
+					regex+="[^.].*";
+				}
+				else
+				{
+					regex+= escaped ? "*" : ".*";
+				}
+				break;
+			case '?':
+				regex+= escaped ? '?' : '.';
+				break;
+			case '{':
+				braces++;
+				regex+='(';
+				break;
+			case '}':
+				if (!braces)
+				{
+					llerrs << "glob_to_regex: Closing brace without an equivalent opening brace: " << glob << llendl;
+				}
+
+				regex+=')';
+				braces--;
+				break;
+			case ',':
+				regex+= braces ? '|' : c;
+				break;
+			case '!':
+				regex+= square_brace_open ? '^' : c;
+				break;
+			default:
+				regex+=c;
+				break;
+		}
+
+		escaped = ('\\' == c);
+		square_brace_open = ('[' == c);
+	}
+
+	if (braces)
+	{
+		llerrs << "glob_to_regex: Unterminated brace expression: " << glob << llendl;
+	}
+
+	return regex;
+}
+
+LLDirIterator::LLDirIterator(const std::string &dirname, const std::string &mask)
+{
+	mImpl = new Impl(dirname, mask);
+}
+
+LLDirIterator::~LLDirIterator()
+{
+	delete mImpl;
+}
+
+bool LLDirIterator::next(std::string &fname)
+{
+	return mImpl->next(fname);
+}
diff --git a/indra/llvfs/lldiriterator.h b/indra/llvfs/lldiriterator.h
new file mode 100644
index 0000000000000000000000000000000000000000..0b48be41b321c71935957773ea5a43494c9d5959
--- /dev/null
+++ b/indra/llvfs/lldiriterator.h
@@ -0,0 +1,87 @@
+/**
+ * @file lldiriterator.h
+ * @brief Iterator through directory entries matching the search pattern.
+ *
+ * $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_LLDIRITERATOR_H
+#define LL_LLDIRITERATOR_H
+
+#include "linden_common.h"
+
+/**
+ * Class LLDirIterator
+ *
+ * Iterates through directory entries matching the search pattern.
+ */
+class LLDirIterator
+{
+public:
+	/**
+	 * Constructs LLDirIterator object to search for glob pattern
+	 * matches in a directory.
+	 *
+	 * @param dirname - name of a directory to search in.
+	 * @param mask - search pattern, a glob expression
+	 *
+	 * Wildcards supported in glob expressions:
+	 * --------------------------------------------------------------
+	 * | Wildcard 	| Matches										|
+	 * --------------------------------------------------------------
+	 * | 	* 		|zero or more characters						|
+	 * | 	?		|exactly one character							|
+	 * | [abcde]	|exactly one character listed					|
+	 * | [a-e]		|exactly one character in the given range		|
+	 * | [!abcde]	|any character that is not listed				|
+	 * | [!a-e]		|any character that is not in the given range	|
+	 * | {abc,xyz}	|exactly one entire word in the options given	|
+	 * --------------------------------------------------------------
+	 */
+	LLDirIterator(const std::string &dirname, const std::string &mask);
+
+	~LLDirIterator();
+
+	/**
+	 * Searches for the next directory entry matching the glob mask
+	 * specified upon iterator construction.
+	 * Returns true if a match is found, sets fname
+	 * parameter to the name of the matched directory entry and
+	 * increments the iterator position.
+	 *
+	 * Typical usage:
+	 * <code>
+	 * LLDirIterator iter(directory, pattern);
+	 * if ( iter.next(scanResult) )
+	 * </code>
+	 *
+	 * @param fname - name of the matched directory entry.
+	 * @return true if a match is found, false otherwise.
+	 */
+	bool next(std::string &fname);
+
+protected:
+	class Impl;
+	Impl* mImpl;
+};
+
+#endif //LL_LLDIRITERATOR_H
diff --git a/indra/llvfs/tests/lldir_test.cpp b/indra/llvfs/tests/lldir_test.cpp
index 8788bd63e87d2b8030324ffcd0e0434057844151..ea321c5ae958829d739137eae3548f5cbf07c540 100644
--- a/indra/llvfs/tests/lldir_test.cpp
+++ b/indra/llvfs/tests/lldir_test.cpp
@@ -28,6 +28,7 @@
 #include "linden_common.h"
 
 #include "../lldir.h"
+#include "../lldiriterator.h"
 
 #include "../test/lltut.h"
 
@@ -259,13 +260,12 @@ namespace tut
 
    std::string makeTestFile( const std::string& dir, const std::string& file )
    {
-      std::string delim = gDirUtilp->getDirDelimiter();
-      std::string path = dir + delim + file;
+      std::string path = dir + 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);
+      ensure("failed to write to test file '"+path+"'", EOF != fputs("test file", handle) );
       fclose(handle);
       return path;
    }
@@ -290,7 +290,7 @@ namespace tut
    }
 
    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])
    {
 
@@ -300,7 +300,8 @@ namespace tut
       bool  filesFound[5] = { false, false, false, false, false };
       //std::cerr << "searching '"+directory+"' for '"+pattern+"'\n";
 
-      while ( found <= 5 && gDirUtilp->getNextFileInDir(directory, pattern, scanResult) )
+      LLDirIterator iter(directory, pattern);
+      while ( found <= 5 && iter.next(scanResult) )
       {
          found++;
          //std::cerr << "  found '"+scanResult+"'\n";
@@ -334,15 +335,15 @@ namespace tut
    
    template<> template<>
    void LLDirTest_object_t::test<5>()
-      // getNextFileInDir
+      // LLDirIterator::next
    {
       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 dir1 = makeTestDir(dirTemp + "LLDirIterator");
+      std::string dir2 = makeTestDir(dirTemp + "LLDirIterator");
       std::string dir1files[5];
       std::string dir2files[5];
       for (int i=0; i<5; i++)
@@ -380,19 +381,17 @@ namespace tut
       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);
+      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);
+      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 };
@@ -402,6 +401,15 @@ namespace tut
       bool  expected12[5] = { false, false, true, true, false };
       scanTest(dir1, "??l??.xyz", expected12);
 
+      bool expected13[5] = { true, false, true, false, false };
+      scanTest(dir1, "file1.{abc,xyz}", expected13);
+
+      bool expected14[5] = { true, true, false, false, false };
+      scanTest(dir1, "file[0-9].abc", expected14);
+
+      bool expected15[5] = { true, true, false, false, false };
+      scanTest(dir1, "file[!a-z].abc", expected15);
+
       // clean up all test files and directories
       for (int i=0; i<5; i++)
       {
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 77552663abd8d72458b8d9c86e6b7c0c8c00883c..7d908df5ceed5469064c52543e304114be028dc7 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -64,6 +64,7 @@
 #include "lltool.h"
 #include "lltoolmgr.h"
 #include "lltrans.h"
+#include "llurlentry.h"
 #include "llviewercontrol.h"
 #include "llviewerdisplay.h"
 #include "llviewerjoystick.h"
@@ -649,6 +650,10 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 	}
 	mRegionp = regionp;
 
+	// Pass the region host to LLUrlEntryParcel to resolve parcel name
+	// with a server request.
+	LLUrlEntryParcel::setRegionHost(getRegionHost());
+
 	// Must shift hole-covering water object locations because local
 	// coordinate frame changed.
 	LLWorld::getInstance()->updateWaterObjects();
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 80734b0d41ae5231d670a03cf50c2bb5ef8f5868..f40fed5ad3450010bbfbc964f2b0b0332592cb84 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1300,8 +1300,16 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
 		return false;
 	}
 
-	// Check whether the outfit contains the full set of body parts (shape+skin+hair+eyes).
-	return getCanMakeFolderIntoOutfit(outfit_cat_id);
+	// Check whether the outfit contains any wearables we aren't wearing already (STORM-702).
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true);
+	gInventory.collectDescendentsIf(outfit_cat_id,
+		cats,
+		items,
+		LLInventoryModel::EXCLUDE_TRASH,
+		is_worn);
+	return items.size() > 0;
 }
 
 void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 8a3f3a14edf91ade03b586112aabc7fcb003cda7..fab6343864a6394db71fd24a8336bf072a80af40 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -90,10 +90,12 @@
 
 // Linden library includes
 #include "llavatarnamecache.h"
+#include "lldiriterator.h"
 #include "llimagej2c.h"
 #include "llmemory.h"
 #include "llprimitive.h"
 #include "llurlaction.h"
+#include "llurlentry.h"
 #include "llvfile.h"
 #include "llvfsthread.h"
 #include "llvolumemgr.h"
@@ -3301,7 +3303,9 @@ void LLAppViewer::migrateCacheDirectory()
 			S32 file_count = 0;
 			std::string file_name;
 			std::string mask = delimiter + "*.*";
-			while (gDirUtilp->getNextFileInDir(old_cache_dir, mask, file_name))
+
+			LLDirIterator iter(old_cache_dir, mask);
+			while (iter.next(file_name))
 			{
 				if (file_name == "." || file_name == "..") continue;
 				std::string source_path = old_cache_dir + delimiter + file_name;
@@ -3520,7 +3524,8 @@ bool LLAppViewer::initCache()
 		dir = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,"");
 
 		std::string found_file;
-		if (gDirUtilp->getNextFileInDir(dir, mask, found_file))
+		LLDirIterator iter(dir, mask);
+		if (iter.next(found_file))
 		{
 			old_vfs_data_file = dir + gDirUtilp->getDirDelimiter() + found_file;
 
@@ -4578,6 +4583,10 @@ void LLAppViewer::disconnectViewer()
 
 	cleanup_xfer_manager();
 	gDisconnected = TRUE;
+
+	// Pass the connection state to LLUrlEntryParcel not to attempt
+	// parcel info requests while disconnected.
+	LLUrlEntryParcel::setDisconnected(gDisconnected);
 }
 
 void LLAppViewer::forceErrorLLError()
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 898cc1c0ba8686bc615b685e2d17353c5d51dbb9..fc7a27e5e04ec302e8d0ff161e2de215c888717f 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -30,6 +30,7 @@
 
 #include "llcommandlineparser.h"
 
+#include "lldiriterator.h"
 #include "llmemtype.h"
 #include "llurldispatcher.h"		// SLURL from other app instance
 #include "llviewernetwork.h"
@@ -504,7 +505,9 @@ std::string LLAppViewerLinux::generateSerialNumber()
 
 	// trawl /dev/disk/by-uuid looking for a good-looking UUID to grab
 	std::string this_name;
-	while (gDirUtilp->getNextFileInDir(uuiddir, "*", this_name))
+
+	LLDirIterator iter(uuiddir, "*");
+	while (iter.next(this_name))
 	{
 		if (this_name.length() > best.length() ||
 		    (this_name.length() == best.length() &&
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index f12bc16d4b958eff310c64053081e92f15f93ab3..dd5bc74b2a7a2154b09d838c90850a1d162e40c6 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -126,6 +126,7 @@ void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
 			break;
 	}
 	LLUploadDialog::modalUploadFinished();
+	LLFilePicker::instance().reset();  // unlock file picker when bulk upload fails
 }
 
 //virtual 
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 11b3379814a52d3de44e343675abd7196417e5e9..182d3d23f1a868355b19dfb6be4fe03959a2ade6 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -35,6 +35,7 @@
 #include "llfloateruipreview.h"			// Own header
 
 // Internal utility
+#include "lldiriterator.h"
 #include "lleventtimer.h"
 #include "llexternaleditor.h"
 #include "llrender.h"
@@ -481,9 +482,11 @@ BOOL LLFloaterUIPreview::postBuild()
 	std::string language_directory;
 	std::string xui_dir = get_xui_dir();	// directory containing localizations -- don't forget trailing delim
 	mLanguageSelection->removeall();																				// clear out anything temporarily in list from XML
+
+	LLDirIterator iter(xui_dir, "*");
 	while(found)																									// for every directory
 	{
-		if((found = gDirUtilp->getNextFileInDir(xui_dir, "*", language_directory)))							// get next directory
+		if((found = iter.next(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
@@ -635,42 +638,51 @@ void LLFloaterUIPreview::refreshList()
 	mFileList->clearRows();		// empty list
 	std::string name;
 	BOOL found = TRUE;
+
+	LLDirIterator floater_iter(getLocalizedDirectory(), "floater_*.xml");
 	while(found)				// for every floater file that matches the pattern
 	{
-		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "floater_*.xml", name)))	// get next file matching pattern
+		if((found = floater_iter.next(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)
 		}
 	}
 	found = TRUE;
+
+	LLDirIterator inspect_iter(getLocalizedDirectory(), "inspect_*.xml");
 	while(found)				// for every inspector file that matches the pattern
 	{
-		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "inspect_*.xml", name)))	// get next file matching pattern
+		if((found = inspect_iter.next(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)
 		}
 	}
 	found = TRUE;
+
+	LLDirIterator menu_iter(getLocalizedDirectory(), "menu_*.xml");
 	while(found)				// for every menu file that matches the pattern
 	{
-		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "menu_*.xml", name)))	// get next file matching pattern
+		if((found = menu_iter.next(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)
 		}
 	}
 	found = TRUE;
+
+	LLDirIterator panel_iter(getLocalizedDirectory(), "panel_*.xml");
 	while(found)				// for every panel file that matches the pattern
 	{
-		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "panel_*.xml", name)))	// get next file matching pattern
+		if((found = panel_iter.next(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)
 		}
 	}
-
 	found = TRUE;
+
+	LLDirIterator sidepanel_iter(getLocalizedDirectory(), "sidepanel_*.xml");
 	while(found)				// for every sidepanel file that matches the pattern
 	{
-		if((found = gDirUtilp->getNextFileInDir(getLocalizedDirectory(), "sidepanel_*.xml", name)))	// get next file matching pattern
+		if((found = sidepanel_iter.next(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)
 		}
diff --git a/indra/newview/llfloaterwebcontent.cpp b/indra/newview/llfloaterwebcontent.cpp
index 51726112a0fccb2c2081a701a8ddf16e9d2016bd..058567492be7ad57ee9a8a14cfd6b812b3827788 100644
--- a/indra/newview/llfloaterwebcontent.cpp
+++ b/indra/newview/llfloaterwebcontent.cpp
@@ -1,402 +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 );
-	};
-}
+/**
+ * @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
index 001d822ada48b918eb4b5e0b8243377984224c44..ecc7e970d865c5ac94f181abe08224e0962cdf7b 100644
--- a/indra/newview/llfloaterwebcontent.h
+++ b/indra/newview/llfloaterwebcontent.h
@@ -1,82 +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);
-
+/**
+ * @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
+
+	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/llimview.cpp b/indra/newview/llimview.cpp
index ce305dcd89741303bfc567e4f87732987d8d78fb..afd565bb26424a7882edbb444ece40a2bb2b6afe 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -280,19 +280,19 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 void LLIMModel::LLIMSession::onAdHocNameCache(const LLAvatarName& av_name)
 {
 	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);
-		}
+	{
+		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
 	{
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index e765a8da2fe69167dfd88eb8c8828cdfda28aae7..a15776c20791c4ab1aad7b9ead90491640203ae0 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -100,7 +100,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 
 		void onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name);
 
-		void onAdHocNameCache(const LLAvatarName& av_name);
+		void onAdHocNameCache(const LLAvatarName& av_name);
 
 		//*TODO make private
 		static std::string generateHash(const std::set<LLUUID>& sorted_uuids);
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index ef2086911401ccdcda96cdaf0d3196fdccdd1694..61d0a150b719603072987d96288f4fed97d4b559 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -686,6 +686,12 @@ bool LLFindWearablesEx::operator()(LLInventoryCategory* cat, LLInventoryItem* it
 		return false;
 	}
 
+	// Skip broken links.
+	if (vitem->getIsBrokenLink())
+	{
+		return false;
+	}
+
 	return (bool) get_is_item_worn(item->getUUID()) == mIsWorn;
 }
 
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 1527f8f4c9484ca1a36fb9aaad701922b40d4061..55164f609494e7e1214fb29cc1b50b2f6faa196c 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -547,6 +547,10 @@ void LLLocationInputCtrl::onFocusLost()
 {
 	LLUICtrl::onFocusLost();
 	refreshLocation();
+
+	// Setting cursor to 0  to show the left edge of the text. See STORM-370.
+	mTextEntry->setCursor(0);
+
 	if(mTextEntry->hasSelection()){
 		mTextEntry->deselect();
 	}
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 0121bbb1ed3dc88164c88cc39f66ee9c0aa1841c..b09cfbe90754f7db7186b2d637b6d9db01023f8e 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -32,6 +32,7 @@
 #include "lltrans.h"
 #include "llviewercontrol.h"
 
+#include "lldiriterator.h"
 #include "llinstantmessage.h"
 #include "llsingleton.h" // for LLSingleton
 
@@ -89,15 +90,15 @@ 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}");
+/**
+ * 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(": ");
@@ -601,7 +602,8 @@ std::string LLLogChat::oldLogFileName(std::string filename)
 	//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))
+	LLDirIterator iter(directory, pattern);
+	while (iter.next(scanResult))
     {
 		//LL_INFOS("") << "Found   :" << scanResult << LL_ENDL;
         allfiles.push_back(scanResult);
diff --git a/indra/newview/llpanelme.cpp b/indra/newview/llpanelme.cpp
index 5ea94e06116c5546a4baf9f7a801f629acb54530..d3c9c3e1314014e3309d8a1631b52092d6872aef 100644
--- a/indra/newview/llpanelme.cpp
+++ b/indra/newview/llpanelme.cpp
@@ -76,17 +76,19 @@ void LLPanelMe::onOpen(const LLSD& key)
 {
 	LLPanelProfile::onOpen(key);
 
-	// Force Edit My Profile if this is the first time when user is opening Me Panel (EXT-5068)
-	bool opened = gSavedSettings.getBOOL("MePanelOpened");
-	// In some cases Side Tray my call onOpen() twice, check getCollapsed() to be sure this
-	// is the last time onOpen() is called
-	if( !opened && !LLSideTray::getInstance()->getCollapsed() )
-	{
-		buildEditPanel();
-		openPanel(mEditPanel, getAvatarId());
-
-		gSavedSettings.setBOOL("MePanelOpened", true);
-	}
+	// Removed this action as per SOCIAL-431 The first time a new resident opens the profile tab 
+	//                                       in the sidebar, they see the old profile editing panel
+	//
+	//// Force Edit My Profile if this is the first time when user is opening Me Panel (EXT-5068)
+	//bool opened = gSavedSettings.getBOOL("MePanelOpened");
+	//// In some cases Side Tray my call onOpen() twice, check getCollapsed() to be sure this
+	//// is the last time onOpen() is called
+	//if( !opened && !LLSideTray::getInstance()->getCollapsed() )
+	//{
+	//	buildEditPanel();
+	//	openPanel(mEditPanel, getAvatarId());
+	//	gSavedSettings.setBOOL("MePanelOpened", true);
+	//}
 }
 
 bool LLPanelMe::notifyChildren(const LLSD& info)
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index e5ef51bdd18c6b54c1ac0e801fa3567f6f15ec87..3862dac340d0db44d3ed0411a56c7cbee3a4ac01 100644
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -33,6 +33,7 @@
 #include "llpanel.h"
 #include "llhttpclient.h"
 #include "llsdserialize.h"
+#include "llurlentry.h"
 #include "llviewerregion.h"
 #include "llview.h"
 
@@ -168,6 +169,18 @@ void LLRemoteParcelInfoProcessor::processParcelInfoReply(LLMessageSystem* msg, v
 	{
 		observers.erase(*i);
 	}
+
+	LLUrlEntryParcel::LLParcelData url_data;
+	url_data.parcel_id = parcel_data.parcel_id;
+	url_data.name = parcel_data.name;
+	url_data.sim_name = parcel_data.sim_name;
+	url_data.global_x = parcel_data.global_x;
+	url_data.global_y = parcel_data.global_y;
+	url_data.global_z = parcel_data.global_z;
+
+	// Pass the parcel data to LLUrlEntryParcel to render
+	// human readable parcel name.
+	LLUrlEntryParcel::processParcelInfo(url_data);
 }
 
 void LLRemoteParcelInfoProcessor::sendParcelInfoRequest(const LLUUID& parcel_id)
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index aef665a35cd4db8079689d71296109b8f8dc4c40..19d1bdee862b5bafd624cae04bb367724fd0eb2d 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -498,8 +498,8 @@ class LLSideTrayButton : public LLButton
 
 LLSideTray::Params::Params()
 :	collapsed("collapsed",false),
-	tab_btn_image_normal("tab_btn_image",LLUI::getUIImage("sidebar_tab_left.tga")),
-	tab_btn_image_selected("tab_btn_image_selected",LLUI::getUIImage("button_enabled_selected_32x128.tga")),
+	tab_btn_image_normal("tab_btn_image",LLUI::getUIImage("taskpanel/TaskPanel_Tab_Off.png")),
+	tab_btn_image_selected("tab_btn_image_selected",LLUI::getUIImage("taskpanel/TaskPanel_Tab_Selected.png")),
 	default_button_width("tab_btn_width",32),
 	default_button_height("tab_btn_height",32),
 	default_button_margin("tab_btn_margin",0)
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 611f9de2e6db8dcdb24f2edf9fe9789c0bcd6684..5617eea4c339a3763c1ad151c3ca47552307e488 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -139,6 +139,7 @@
 #include "lltrans.h"
 #include "llui.h"
 #include "llurldispatcher.h"
+#include "llurlentry.h"
 #include "llslurl.h"
 #include "llurlhistory.h"
 #include "llurlwhitelist.h"
@@ -2882,9 +2883,17 @@ bool process_login_success_response()
 	if(!text.empty()) gAgentID.set(text);
 	gDebugInfo["AgentID"] = text;
 	
+	// Agent id needed for parcel info request in LLUrlEntryParcel
+	// to resolve parcel name.
+	LLUrlEntryParcel::setAgentID(gAgentID);
+
 	text = response["session_id"].asString();
 	if(!text.empty()) gAgentSessionID.set(text);
 	gDebugInfo["SessionID"] = text;
+
+	// Session id needed for parcel info request in LLUrlEntryParcel
+	// to resolve parcel name.
+	LLUrlEntryParcel::setSessionID(gAgentSessionID);
 	
 	text = response["secure_session_id"].asString();
 	if(!text.empty()) gAgent.mSecureSessionID.set(text);
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index d3b6dcd86f2f937121d61890f9c997ae0869fd08..8a0d0a6623b8138b67227c8225781656979a17be 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -54,6 +54,7 @@
 #include "llfilepicker.h"
 #include "llnotifications.h"
 
+#include "lldiriterator.h"
 #include "llevent.h"		// LLSimpleListener
 #include "llnotificationsutil.h"
 #include "lluuid.h"
@@ -1115,7 +1116,8 @@ 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))
+	LLDirIterator dir_iter(base_dir, "*_*");
+	while (dir_iter.next(filename))
 	{
 		target = base_dir;
 		target += filename;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 3a37f0355f841b2bca13063da20a0c3079a54fdd..7cc04e0338a0e81e8be7c2c3831531e4b471dfed 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -557,7 +557,7 @@ class LLAdvancedCheckConsole : public view_listener_t
 			new_value = get_visibility( (void*)gDebugView->mMemoryView );
 		}
 #endif
-
+		
 		return new_value;
 	}
 };
@@ -4201,9 +4201,9 @@ class LLObjectEnableReturn : public view_listener_t
 					{
 						virtual bool apply(LLViewerObject* obj)
 						{
-							return (obj->isOverAgentOwnedLand() ||
-									obj->isOverGroupOwnedLand() ||
-									obj->permModify());
+							return 
+								obj->permModify() ||
+								obj->isReturnable();
 						}
 					} func;
 					const bool firstonly = true;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 4b7e518af388e743c7369e1871ada2e1d48d4ea8..48794c4c9d24b2a917017465aa439e83608f8255 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -518,20 +518,23 @@ void LLViewerObject::setNameValueList(const std::string& name_value_list)
 
 // This method returns true if the object is over land owned by the
 // agent.
-BOOL LLViewerObject::isOverAgentOwnedLand() const
+bool LLViewerObject::isReturnable()
 {
-	return mRegionp
-		&& mRegionp->getParcelOverlay()
-		&& mRegionp->getParcelOverlay()->isOwnedSelf(getPositionRegion());
-}
+	if (isAttachment())
+	{
+		return false;
+	}
+	std::vector<LLBBox> boxes;
+	boxes.push_back(LLBBox(getPositionRegion(), getRotationRegion(), getScale() * -0.5f, getScale() * 0.5f).getAxisAligned());
+	for (child_list_t::iterator iter = mChildList.begin();
+		 iter != mChildList.end(); iter++)
+	{
+		LLViewerObject* child = *iter;
+		boxes.push_back(LLBBox(child->getPositionRegion(), child->getRotationRegion(), child->getScale() * -0.5f, child->getScale() * 0.5f).getAxisAligned());
+	}
 
-// This method returns true if the object is over land owned by the
-// agent.
-BOOL LLViewerObject::isOverGroupOwnedLand() const
-{
-	return mRegionp 
-		&& mRegionp->getParcelOverlay()
-		&& mRegionp->getParcelOverlay()->isOwnedGroup(getPositionRegion());
+	return mRegionp
+		&& mRegionp->objectIsReturnable(getPositionRegion(), boxes);
 }
 
 BOOL LLViewerObject::setParent(LLViewerObject* parent)
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 78837ec0a1534b8d99b816445e7d5abbb8f23ba9..614a5e59fa20d586b083d23560626f1e9fa66c58 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -227,12 +227,9 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	virtual BOOL hasLightTexture() const			{ return FALSE; }
 
 	// This method returns true if the object is over land owned by
-	// the agent.
-	BOOL isOverAgentOwnedLand() const;
-
-	// True if over land owned by group of which the agent is
-	// either officer or member.
-	BOOL isOverGroupOwnedLand() const;
+	// the agent, one of its groups, or it encroaches and 
+	// anti-encroachment is enabled
+	bool isReturnable();
 
 	/*
 	// This method will scan through this object, and then query the
diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp
index eee653b0c163775d9dd97a99734d5c0d5b3098fc..d07e06f6a7ed171e7864517bcc8b6eaa89f287cf 100644
--- a/indra/newview/llviewerparceloverlay.cpp
+++ b/indra/newview/llviewerparceloverlay.cpp
@@ -145,6 +145,35 @@ BOOL LLViewerParcelOverlay::isOwnedOther(const LLVector3& pos) const
 	return (PARCEL_OWNED == overlay || PARCEL_FOR_SALE == overlay);
 }
 
+bool LLViewerParcelOverlay::encroachesOwned(const std::vector<LLBBox>& boxes) const
+{
+	// boxes are expected to already be axis aligned
+	for (U32 i = 0; i < boxes.size(); ++i)
+	{
+		LLVector3 min = boxes[i].getMinAgent();
+		LLVector3 max = boxes[i].getMaxAgent();
+		
+		S32 left   = S32(llclamp((min.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+		S32 right  = S32(llclamp((max.mV[VX] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+		S32 top    = S32(llclamp((min.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+		S32 bottom = S32(llclamp((max.mV[VY] / PARCEL_GRID_STEP_METERS), 0.f, REGION_WIDTH_METERS - 1));
+	
+		for (S32 row = top; row <= bottom; row++)
+		{
+			for (S32 column = left; column <= right; column++)
+			{
+				U8 type = ownership(row, column);
+				if ((PARCEL_SELF == type)
+					|| (PARCEL_GROUP == type))
+				{
+					return true;
+				}
+			}
+		}
+	}
+	return false;
+}
+
 BOOL LLViewerParcelOverlay::isSoundLocal(const LLVector3& pos) const
 {
 	S32 row =    S32(pos.mV[VY] / PARCEL_GRID_STEP_METERS);
diff --git a/indra/newview/llviewerparceloverlay.h b/indra/newview/llviewerparceloverlay.h
index 61be2203121ff9d842a223a42c2ed21d84b4f38a..c80baedda6c6256d2fe12af5bee53a3476e1e746 100644
--- a/indra/newview/llviewerparceloverlay.h
+++ b/indra/newview/llviewerparceloverlay.h
@@ -30,6 +30,7 @@
 // The ownership data for land parcels.
 // One of these structures per region.
 
+#include "llbbox.h"
 #include "lldarray.h"
 #include "llframetimer.h"
 #include "lluuid.h"
@@ -54,6 +55,12 @@ class LLViewerParcelOverlay : public LLGLUpdate
 	BOOL			isOwnedSelf(const LLVector3& pos) const;
 	BOOL			isOwnedGroup(const LLVector3& pos) const;
 	BOOL			isOwnedOther(const LLVector3& pos) const;
+
+	// "encroaches" means the prim hangs over the parcel, but its center
+	// might be in another parcel. for now, we simply test axis aligned 
+	// bounding boxes which isn't perfect, but is close
+	bool encroachesOwned(const std::vector<LLBBox>& boxes) const;
+	
 	BOOL			isSoundLocal(const LLVector3& pos) const;
 
 	BOOL			isBuildCameraAllowed(const LLVector3& pos) const;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 5241ea4c07a58966e549f7252f9b74bab0c70d46..3b2cfe656f0475cc3ed5e83f7b48250bf90b7f77 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -1407,7 +1407,6 @@ 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");
@@ -1504,6 +1503,20 @@ LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
 	return NULL;
 }
 
+// the viewer can not yet distinquish between normal- and estate-owned objects
+// so we collapse these two bits and enable the UI if either are set
+const U32 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
+											| REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT;
+
+bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const
+{
+	return (mParcelOverlay != NULL)
+		&& (mParcelOverlay->isOwnedSelf(pos)
+			|| mParcelOverlay->isOwnedGroup(pos)
+			|| ((mRegionFlags & ALLOW_RETURN_ENCROACHING_OBJECT)
+				&& mParcelOverlay->encroachesOwned(boxes)) );
+}
+
 void LLViewerRegion::showReleaseNotes()
 {
 	std::string url = this->getCapability("ServerReleaseNotes");
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index dcefe87b6972f12ce54ff6b16c9c0652c2a6f10b..7c6559203e5fa7606685f67a5cc8b328e1ffdf4a 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -33,6 +33,7 @@
 
 #include "lldarray.h"
 #include "llwind.h"
+#include "llbbox.h"
 #include "llcloud.h"
 #include "llstat.h"
 #include "v3dmath.h"
@@ -308,6 +309,8 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	std::string getHttpUrl() const { return mHttpUrl ;}
 
 	LLSpatialPartition* getSpatialPartition(U32 type);
+
+	bool objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const;
 public:
 	struct CompareDistance
 	{
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index bb4c5b180416adbbeb2429aa66fc6efcb6eeb87a..fd89044995aab28a4d7107f698ed147bfcec6581 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -2106,31 +2106,6 @@ void LLVOAvatar::computeBodySize()
 			gAgent.sendAgentSetAppearance();
 		}
 	}
-
-/* debug spam
-	std::cout << "skull = " << skull << std::endl;				// adebug
-	std::cout << "head = " << head << std::endl;				// adebug
-	std::cout << "head_scale = " << head_scale << std::endl;	// adebug
-	std::cout << "neck = " << neck << std::endl;				// adebug
-	std::cout << "neck_scale = " << neck_scale << std::endl;	// adebug
-	std::cout << "chest = " << chest << std::endl;				// adebug
-	std::cout << "chest_scale = " << chest_scale << std::endl;	// adebug
-	std::cout << "torso = " << torso << std::endl;				// adebug
-	std::cout << "torso_scale = " << torso_scale << std::endl;	// adebug
-	std::cout << std::endl;	// adebug
-
-	std::cout << "pelvis_scale = " << pelvis_scale << std::endl;// adebug
-	std::cout << std::endl;	// adebug
-
-	std::cout << "hip = " << hip << std::endl;					// adebug
-	std::cout << "hip_scale = " << hip_scale << std::endl;		// adebug
-	std::cout << "ankle = " << ankle << std::endl;				// adebug
-	std::cout << "ankle_scale = " << ankle_scale << std::endl;	// adebug
-	std::cout << "foot = " << foot << std::endl;				// adebug
-	std::cout << "mBodySize = " << mBodySize << std::endl;		// adebug
-	std::cout << "mPelvisToFoot = " << mPelvisToFoot << std::endl;	// adebug
-	std::cout << std::endl;		// adebug
-*/
 }
 
 //------------------------------------------------------------------------
diff --git a/indra/newview/llwaterparammanager.cpp b/indra/newview/llwaterparammanager.cpp
index d239347810648188b9b7dd2917a8030d8d6d99a7..4f6ec4ca616ccb4721b9eb7b82b016f97acf9817 100644
--- a/indra/newview/llwaterparammanager.cpp
+++ b/indra/newview/llwaterparammanager.cpp
@@ -33,6 +33,7 @@
 #include "pipeline.h"
 #include "llsky.h"
 
+#include "lldiriterator.h"
 #include "llfloaterreg.h"
 #include "llsliderctrl.h"
 #include "llspinctrl.h"
@@ -85,11 +86,12 @@ void LLWaterParamManager::loadAllPresets(const std::string& file_name)
 	std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/water", ""));
 	LL_DEBUGS2("AppInit", "Shaders") << "Loading Default water settings from " << path_name << LL_ENDL;
 			
-	bool found = true;			
+	bool found = true;
+	LLDirIterator app_settings_iter(path_name, "*.xml");
 	while(found) 
 	{
 		std::string name;
-		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name);
+		found = app_settings_iter.next(name);
 		if(found)
 		{
 
@@ -111,11 +113,12 @@ void LLWaterParamManager::loadAllPresets(const std::string& file_name)
 	std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/water", ""));
 	LL_DEBUGS2("AppInit", "Shaders") << "Loading User water settings from " << path_name2 << LL_ENDL;
 			
-	found = true;			
+	found = true;
+	LLDirIterator user_settings_iter(path_name2, "*.xml");
 	while(found) 
 	{
 		std::string name;
-		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name);
+		found = user_settings_iter.next(name);
 		if(found)
 		{
 			name=name.erase(name.length()-4);
diff --git a/indra/newview/llwlparammanager.cpp b/indra/newview/llwlparammanager.cpp
index e5f52dfc979b5ef4cd09c8366d6b5263d541b9ba..848efcbb49e5f8e28f3bd393df7767dd003b27ee 100644
--- a/indra/newview/llwlparammanager.cpp
+++ b/indra/newview/llwlparammanager.cpp
@@ -31,6 +31,7 @@
 #include "pipeline.h"
 #include "llsky.h"
 
+#include "lldiriterator.h"
 #include "llfloaterreg.h"
 #include "llsliderctrl.h"
 #include "llspinctrl.h"
@@ -100,11 +101,12 @@ void LLWLParamManager::loadPresets(const std::string& file_name)
 	std::string path_name(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "windlight/skies", ""));
 	LL_DEBUGS2("AppInit", "Shaders") << "Loading Default WindLight settings from " << path_name << LL_ENDL;
 			
-	bool found = true;			
+	bool found = true;
+	LLDirIterator app_settings_iter(path_name, "*.xml");
 	while(found) 
 	{
 		std::string name;
-		found = gDirUtilp->getNextFileInDir(path_name, "*.xml", name);
+		found = app_settings_iter.next(name);
 		if(found)
 		{
 
@@ -126,11 +128,12 @@ void LLWLParamManager::loadPresets(const std::string& file_name)
 	std::string path_name2(gDirUtilp->getExpandedFilename( LL_PATH_USER_SETTINGS , "windlight/skies", ""));
 	LL_DEBUGS2("AppInit", "Shaders") << "Loading User WindLight settings from " << path_name2 << LL_ENDL;
 			
-	found = true;			
+	found = true;
+	LLDirIterator user_settings_iter(path_name2, "*.xml");
 	while(found) 
 	{
 		std::string name;
-		found = gDirUtilp->getNextFileInDir(path_name2, "*.xml", name);
+		found = user_settings_iter.next(name);
 		if(found)
 		{
 			name=name.erase(name.length()-4);
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 62441fd9841df8d9ea98aa7b9f7423302d0c9dfd..75aec21f93b6c50732591715620b8d8e2bef8a97 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -114,9 +114,6 @@
     <color
      name="AlertCautionTextColor"
      reference="LtYellow" />
-    <color
-     name="AgentLinkColor"
-     reference="EmphasisColor" />
     <color
      name="AlertTextColor"
      value="0.58 0.66 0.84 1" />
@@ -348,9 +345,6 @@
     <color
      name="GridlineShadowColor"
      value="0 0 0 0.31" />
-    <color
-     name="GroupLinkColor"
-     reference="White" />
     <color
      name="GroupNotifyBoxColor"
      value="0.3344 0.5456 0.5159 1" />
diff --git a/indra/newview/skins/default/xui/da/notifications.xml b/indra/newview/skins/default/xui/da/notifications.xml
index 70299c61b4e8506ecc0bc07506a46179d6be2535..593e686d4c126da89574cedc0946567e368c84ee 100644
--- a/indra/newview/skins/default/xui/da/notifications.xml
+++ b/indra/newview/skins/default/xui/da/notifications.xml
@@ -1636,7 +1636,7 @@ Knappen vil blive vist når der er nok plads til den.
 	<notification name="ShareItemsConfirmation">
 		Er du sikker på at du vil dele følgende genstande:
 
-[ITEMS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
 
 Med følgende beboere:
 
diff --git a/indra/newview/skins/default/xui/de/notifications.xml b/indra/newview/skins/default/xui/de/notifications.xml
index 06cc02cd847a5181d9ec94da8d9bbffe6b9310b7..a2d0b5a1702394375b508705f78c376017549bfd 100644
--- a/indra/newview/skins/default/xui/de/notifications.xml
+++ b/indra/newview/skins/default/xui/de/notifications.xml
@@ -2747,7 +2747,7 @@ Die Schaltfläche wird angezeigt, wenn genügend Platz vorhanden ist.
 	<notification name="ShareItemsConfirmation">
 		Möchten Sie diese Objekte wirklich für andere freigeben:
 
-[ITEMS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
 
 Für folgende Einwohner:
 
diff --git a/indra/newview/skins/default/xui/en/floater_web_content.xml b/indra/newview/skins/default/xui/en/floater_web_content.xml
index 2ad46824c25def60bfef10ca725e16947a4184c4..d90d0feda9ae58a1d0216db2d3cc6446ecc40498 100644
--- a/indra/newview/skins/default/xui/en/floater_web_content.xml
+++ b/indra/newview/skins/default/xui/en/floater_web_content.xml
@@ -1,190 +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>
+<?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/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml
index c751aa4e0c2caa949e8530d5cc5237750ab70ebf..719509301b0a9486393c0c5490df6ab4244b1620 100644
--- a/indra/newview/skins/default/xui/en/menu_object.xml
+++ b/indra/newview/skins/default/xui/en/menu_object.xml
@@ -100,7 +100,7 @@
          name="Object Attach HUD" />
    </context_menu>
    <context_menu
-         label="Remove"
+         label="Manage"
          name="Remove">
    <menu_item_call
          enabled="false"
@@ -129,15 +129,6 @@
          <menu_item_call.on_enable
           function="Object.EnableReturn" />
      </menu_item_call>
-     <menu_item_call
-   enabled="false"
-   label="Delete"
-   name="Delete">
-      <menu_item_call.on_click
-       function="Object.Delete" />
-      <menu_item_call.on_enable
-       function="Object.EnableDelete" />
-    </menu_item_call>
     </context_menu>
    <menu_item_separator layout="topleft" />
    <menu_item_call
@@ -176,4 +167,13 @@
       <menu_item_call.on_enable
        function="Object.EnableBuy" />
    </menu_item_call>
+   <menu_item_call
+     enabled="false"
+     label="Delete"
+     name="Delete">
+      <menu_item_call.on_click
+       function="Object.Delete" />
+      <menu_item_call.on_enable
+       function="Object.EnableDelete" />
+  </menu_item_call>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index a6c9fab217ab0228422f01849af0f91521dce5d0..2207e418c8dff036b8e58a3823378bb4cd10abd8 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -2727,6 +2727,18 @@
                  function="Floater.Toggle"
                  parameter="region_debug_console" />
             </menu_item_check>
+            <menu_item_check
+             label="Region Debug Console"
+             name="Region Debug Console"
+             shortcut="control|shift|`"
+             use_mac_ctrl="true">
+                <menu_item_check.on_check
+                 function="Floater.Visible"
+                 parameter="region_debug_console" />
+                <menu_item_check.on_click
+                 function="Floater.Toggle"
+                 parameter="region_debug_console" />
+            </menu_item_check>
 
             <menu_item_separator />
 
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 3df53ac442120dd9872e5c2621a531037a1ab106..6f21938bdb0fd21f9543cec2305f3cfdebce4948 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -6431,7 +6431,7 @@ Select residents to share with.
    type="alertmodal">
 Are you sure you want to share the following items:
 
-[ITEMS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
 
 With the following Residents:
 
diff --git a/indra/newview/skins/default/xui/en/panel_group_land_money.xml b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
index 61d6cbb2d0e1c0d0936a5a14eb7c6ff9897706f0..eff674c628af3d10d055b2c393788ca3271d5298 100644
--- a/indra/newview/skins/default/xui/en/panel_group_land_money.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_land_money.xml
@@ -67,23 +67,23 @@
         <scroll_list.columns
          label="Parcel"
          name="name"
-         width="47" />
+         relative_width="0.2" />
         <scroll_list.columns
          label="Region"
          name="location"
-         width="47" />
+         relative_width="0.2" />
         <scroll_list.columns
          label="Type"
          name="type"
-         width="47" />
+         relative_width="0.2" />
         <scroll_list.columns
          label="Area"
          name="area"
-         width="47" />
+         relative_width="0.2" />
         <scroll_list.columns
          label="Hidden"
          name="hidden"
-         width="47" />
+         relative_width="0.2" />
     </scroll_list>
     <text
      type="string"
diff --git a/indra/newview/skins/default/xui/en/widgets/floater.xml b/indra/newview/skins/default/xui/en/widgets/floater.xml
index 85d0c633af5fb362983869118c12a711f1550fe5..2e5ebafe46bf3dd3a1c21829ecb9a578d6badcdc 100644
--- a/indra/newview/skins/default/xui/en/widgets/floater.xml
+++ b/indra/newview/skins/default/xui/en/widgets/floater.xml
@@ -21,4 +21,5 @@
  tear_off_pressed_image="tearoff_pressed.tga"
  dock_pressed_image="Icon_Dock_Press"
  help_pressed_image="Icon_Help_Press"
+ focus_root="true"
   />
diff --git a/indra/newview/skins/default/xui/es/notifications.xml b/indra/newview/skins/default/xui/es/notifications.xml
index 2dd7a6b0f549de273aa8a827b7a1342fcefa2483..14ce39e8fc673c493d4442ebe5cc79db4bf06be5 100644
--- a/indra/newview/skins/default/xui/es/notifications.xml
+++ b/indra/newview/skins/default/xui/es/notifications.xml
@@ -2734,7 +2734,7 @@ Se mostrará cuando haya suficiente espacio.
 	<notification name="ShareItemsConfirmation">
 		¿Estás seguro de que quieres compartir los elementos siguientes?
 
-[ITEMS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
 
 Con los siguientes residentes:
 
diff --git a/indra/newview/skins/default/xui/fr/notifications.xml b/indra/newview/skins/default/xui/fr/notifications.xml
index ec362d7f22f73a87e66df815fe5463757c9d098e..f0b0e63af0079ca4bac7786f1bdf29268a68901b 100644
--- a/indra/newview/skins/default/xui/fr/notifications.xml
+++ b/indra/newview/skins/default/xui/fr/notifications.xml
@@ -2730,7 +2730,7 @@ Le bouton sera affiché quand il y aura suffisamment de place.
 	<notification name="ShareItemsConfirmation">
 		Voulez-vous vraiment partager les articles suivants :
 
-[ITEMS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
 
 avec les résidents suivants :
 
diff --git a/indra/newview/skins/default/xui/it/notifications.xml b/indra/newview/skins/default/xui/it/notifications.xml
index 32483881b2b6d07aa2a5f62210bf4ab6df776145..5e53080c77b312a87c8d54e4c31e591aeebc2a8e 100644
--- a/indra/newview/skins/default/xui/it/notifications.xml
+++ b/indra/newview/skins/default/xui/it/notifications.xml
@@ -2679,7 +2679,7 @@ Il pulsante verrà visualizzato quando lo spazio sarà sufficiente.
 	<notification name="ShareItemsConfirmation">
 		Sei sicuro di volere condividere gli oggetti
 
-[ITEMS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
 
 Con i seguenti residenti?
 
diff --git a/indra/newview/skins/default/xui/ja/notifications.xml b/indra/newview/skins/default/xui/ja/notifications.xml
index c0af0e03ff2edfddb4ddeb85b97272b97703b3fe..f133bb361afcaf578764b04fc60c07c0f25f1cad 100644
--- a/indra/newview/skins/default/xui/ja/notifications.xml
+++ b/indra/newview/skins/default/xui/ja/notifications.xml
@@ -2731,7 +2731,7 @@ M キーを押して変更します。
 	<notification name="ShareItemsConfirmation">
 		次のアイテムを共有しますか:
 
-[ITEMS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
 
 次の住人と共有しますか:
 
diff --git a/indra/newview/skins/default/xui/pl/notifications.xml b/indra/newview/skins/default/xui/pl/notifications.xml
index 8151c7eb938304846d51f890b8b1d769879b4d9f..57a6b8b8ef9e6cfd258dff586746536f8c7d276c 100644
--- a/indra/newview/skins/default/xui/pl/notifications.xml
+++ b/indra/newview/skins/default/xui/pl/notifications.xml
@@ -2691,7 +2691,7 @@ Przycisk zostanie wyświetlony w przypadku dostatecznej ilości przestrzeni.
 	<notification name="ShareItemsConfirmation">
 		Jesteś pewien/pewna, że chcesz udostępnić następujące obiekty:
 
-[ITEMS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
 
 następującym Rezydentom:
 
diff --git a/indra/newview/skins/default/xui/pt/notifications.xml b/indra/newview/skins/default/xui/pt/notifications.xml
index dc38b740aaf54053ecb2bc2e575919a6937a26f0..a1855f2e892ce26b66be0a7b38aa19bf41fd6153 100644
--- a/indra/newview/skins/default/xui/pt/notifications.xml
+++ b/indra/newview/skins/default/xui/pt/notifications.xml
@@ -477,7 +477,7 @@ Para aumentar a qualidade do vídeo, vá para Preferências &gt; Vídeo.
 	</notification>
 	<notification name="CannotCopyWarning">
 		Você não tem autorização para copiar os itens abaixo:
-[ITENS]
+[ITEMS]
 ao dá-los, você ficará sem eles no seu inventário. Deseja realmente dar estes itens?
 		<usetemplate name="okcancelbuttons" notext="Não" yestext="Sim"/>
 	</notification>
@@ -2714,7 +2714,7 @@ O botão será exibido quando houver espaço suficente.
 	<notification name="ShareItemsConfirmation">
 		Tem certeza de que quer compartilhar os items abaixo?
 
-[ITENS]
+&lt;nolink&gt;[ITEMS]&lt;/nolink&gt;
 
 Com os seguintes residentes:
 
diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp
index a6c1f69c82a4784958da65c248613f320117ae61..7862cce3a1de667ec909a8f26751c9f55a64dd36 100644
--- a/indra/newview/tests/llremoteparcelrequest_test.cpp
+++ b/indra/newview/tests/llremoteparcelrequest_test.cpp
@@ -1,134 +1,136 @@
-/** 
- * @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);
-	}
-}
+/** 
+ * @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"
+#include "llurlentry.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) { }
+void LLUrlEntryParcel::processParcelInfo(const LLUrlEntryParcel::LLParcelData& parcel_data) { }
+
+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/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 5f8cd28f2976501f23f6eef2360ce4c228f6d215..e19d5724f172b5bdc552d2243007611b285076e6 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -1,200 +1,194 @@
-/**
- * @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());
-	}
-}
+/**
+ * @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;
+	}
+
+	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());
+	}
+}