diff --git a/.hgtags b/.hgtags
index 44ca1e0d7d5965485d6d12c1d2503b7459af416a..c9870bfb0fc32b216e228285b6cb696dcf3070ab 100755
--- a/.hgtags
+++ b/.hgtags
@@ -520,3 +520,4 @@ e9d350764dfbf5a46229e627547ef5c1b1eeef00 4.0.2-release
 33981d8130f031597b4c7f4c981b18359afb61a0 4.0.7-release
 45eaee56883df7a439ed3300c44d3126f7e3a41e 4.0.8-release
 b280a1c797a3891e68dbc237e73de9cf19f426e9 4.1.1-release
+bfbba2244320dc2ae47758cd7edd8fa3b67dc756 4.1.2-release
diff --git a/README.md b/README.md
index ad040fb07792215cb595984c9775658f65450ee3..6eddb9aa9ed727c28b7cea1e33e0a35a9ff6822f 100644
--- a/README.md
+++ b/README.md
@@ -1,6 +1,6 @@
 Second Life Viewer
 ====================
-
+ 
 This project manages the source code for the
 [Second Life](https://www.secondlife.com) Viewer.
 
diff --git a/autobuild.xml b/autobuild.xml
index 5ff6d3330539bd2fc1673f06d6a11ca85875bf27..f485aa0cb7d29461f22bd76649874f0ade38cb60 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1484,11 +1484,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>db992d58c46c80df7d4d31f8a4784b98</string>
+              <string>2845033912eb947a1401847ece1469ce</string>
               <key>hash_algorithm</key>
               <string>md5</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/317959/arch/Darwin/installer/llceflib-1.5.3.317959-darwin-317959.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/321153/arch/Darwin/installer/llceflib-1.5.3.321153-darwin-321153.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin</string>
@@ -1498,11 +1498,11 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>bb3818628131a99cd789febfad9dc2c2</string>
+              <string>1156121b4ccbb4aa29bc01f15c589f98</string>
               <key>hash_algorithm</key>
               <string>md5</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/317959/arch/CYGWIN/installer/llceflib-1.5.3.317959-windows-317959.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-llceflib_3p-llceflib/rev/321153/arch/CYGWIN/installer/llceflib-1.5.3.321153-windows-321153.tar.bz2</string>
             </map>
             <key>name</key>
             <string>windows</string>
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 017e77994b2573721109687443c5c991dcf24372..521be7b7e2318a47e4d42de625a34ae7f95655ee 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -191,9 +191,19 @@ Ansariel Hiller
 	STORM-2094
 	MAINT-5756
 	MAINT-4677
+	MAINT-6300
+	MAINT-6397
 	MAINT-6432
+	MAINT-6513
+	MAINT-6514
+	MAINT-6552
 	STORM-2133
 	MAINT-6511
+	MAINT-6612
+	MAINT-6637
+	MAINT-6636
+	MAINT-6744
+	MAINT-6752
 Aralara Rajal
 Arare Chantilly
 	CHUIBUG-191
@@ -792,6 +802,7 @@ Kitty Barnett
 	MAINT-6152
 	MAINT-6153
 	MAINT-6154
+	MAINT-6568
 Kolor Fall
 Komiko Okamoto
 Korvel Noh
@@ -1024,6 +1035,7 @@ Nicky Dasmijn
 	OPEN-187
     STORM-2010
 	STORM-2082
+	MAINT-6665
 Nicky Perian
 	OPEN-1
 	STORM-1087
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 86fc2dfff5d4fc06713e945e3b4356e4be106295..adc134c48cc787495471cdc9ccd20688794ad784 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -83,8 +83,8 @@ if (WINDOWS)
     add_definitions(/WX)
   endif (NOT VS_DISABLE_FATAL_WARNINGS)
 
-  # configure win32 API for windows XP+ compatibility
-  set(WINVER "0x0501" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)")
+  # configure Win32 API for Windows Vista+ compatibility
+  set(WINVER "0x0600" CACHE STRING "Win32 API Target version (see http://msdn.microsoft.com/en-us/library/aa383745%28v=VS.85%29.aspx)")
   add_definitions("/DWINVER=${WINVER}" "/D_WIN32_WINNT=${WINVER}")
 endif (WINDOWS)
 
diff --git a/indra/lib/python/indra/base/__init__.py b/indra/lib/python/indra/base/__init__.py
deleted file mode 100755
index 2904fd338018da1f291d954107f84f9d4da33aa6..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/base/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-"""\
-@file __init__.py
-@brief Initialization file for the indra.base module.
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
diff --git a/indra/lib/python/indra/base/cllsd_test.py b/indra/lib/python/indra/base/cllsd_test.py
deleted file mode 100755
index 1f06898ffd83f828ad6062cea9628ba162f236da..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/base/cllsd_test.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/python
-## 
-## $LicenseInfo:firstyear=2011&license=viewerlgpl$
-## Second Life Viewer Source Code
-## Copyright (C) 2011, Linden Research, Inc.
-## 
-## This library is free software; you can redistribute it and/or
-## modify it under the terms of the GNU Lesser General Public
-## License as published by the Free Software Foundation;
-## version 2.1 of the License only.
-## 
-## This library is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## Lesser General Public License for more details.
-## 
-## You should have received a copy of the GNU Lesser General Public
-## License along with this library; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-## 
-## Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-## $/LicenseInfo$
-from indra.base import llsd, lluuid
-from datetime import datetime
-import cllsd
-import time, sys
-
-class myint(int):
-    pass
-
-values = (
-    '&<>',
-    u'\u81acj',
-    llsd.uri('http://foo<'),
-    lluuid.UUID(),
-    llsd.LLSD(['thing']),
-    1,
-    myint(31337),
-    sys.maxint + 10,
-    llsd.binary('foo'),
-    [],
-    {},
-    {u'f&\u1212': 3},
-    3.1,
-    True,
-    None,
-    datetime.fromtimestamp(time.time()),
-    )
-
-def valuator(values):
-    for v in values:
-        yield v
-
-longvalues = () # (values, list(values), iter(values), valuator(values))
-
-for v in values + longvalues:
-    print '%r => %r' % (v, cllsd.llsd_to_xml(v))
-
-a = [[{'a':3}]] * 1000000
-
-s = time.time()
-print hash(cllsd.llsd_to_xml(a))
-e = time.time()
-t1 = e - s
-print t1
-
-s = time.time()
-print hash(llsd.LLSDXMLFormatter()._format(a))
-e = time.time()
-t2 = e - s
-print t2
-
-print 'Speedup:', t2 / t1
diff --git a/indra/lib/python/indra/base/config.py b/indra/lib/python/indra/base/config.py
deleted file mode 100755
index adafa29b518ed019d07d7013b8dc266945f6eff4..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/base/config.py
+++ /dev/null
@@ -1,266 +0,0 @@
-"""\
-@file config.py
-@brief Utility module for parsing and accessing the indra.xml config file.
-
-$LicenseInfo:firstyear=2006&license=mit$
-
-Copyright (c) 2006-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import copy
-import errno
-import os
-import traceback
-import time
-import types
-
-from os.path import dirname, getmtime, join, realpath
-from indra.base import llsd
-
-_g_config = None
-
-class IndraConfig(object):
-    """
-    IndraConfig loads a 'indra' xml configuration file
-    and loads into memory.  This representation in memory
-    can get updated to overwrite values or add new values.
-
-    The xml configuration file is considered a live file and changes
-    to the file are checked and reloaded periodically.  If a value had
-    been overwritten via the update or set method, the loaded values
-    from the file are ignored (the values from the update/set methods
-    override)
-    """
-    def __init__(self, indra_config_file):
-        self._indra_config_file = indra_config_file
-        self._reload_check_interval = 30 # seconds
-        self._last_check_time = 0
-        self._last_mod_time = 0
-
-        self._config_overrides = {}
-        self._config_file_dict = {}
-        self._combined_dict = {}
-
-        self._load()
-
-    def _load(self):
-        # if you initialize the IndraConfig with None, no attempt
-        # is made to load any files
-        if self._indra_config_file is None:
-            return
-
-        config_file = open(self._indra_config_file)
-        self._config_file_dict = llsd.parse(config_file.read())
-        self._combine_dictionaries()
-        config_file.close()
-
-        self._last_mod_time = self._get_last_modified_time()
-        self._last_check_time = time.time() # now
-
-    def _get_last_modified_time(self):
-        """
-        Returns the mtime (last modified time) of the config file,
-        if such exists.
-        """
-        if self._indra_config_file is not None:
-            return os.path.getmtime(self._indra_config_file)
-
-        return 0
-
-    def _combine_dictionaries(self):
-        self._combined_dict = {}
-        self._combined_dict.update(self._config_file_dict)
-        self._combined_dict.update(self._config_overrides)
-
-    def _reload_if_necessary(self):
-        now = time.time()
-
-        if (now - self._last_check_time) > self._reload_check_interval:
-            self._last_check_time = now
-            try:
-                modtime = self._get_last_modified_time()
-                if modtime > self._last_mod_time:
-                    self._load()
-            except OSError, e:
-                if e.errno == errno.ENOENT: # file not found
-                    # someone messed with our internal state
-                    # or removed the file
-
-                    print 'WARNING: Configuration file has been removed ' + (self._indra_config_file)
-                    print 'Disabling reloading of configuration file.'
-
-                    traceback.print_exc()
-
-                    self._indra_config_file = None
-                    self._last_check_time = 0
-                    self._last_mod_time = 0
-                else:
-                    raise  # pass the exception along to the caller
-
-    def __getitem__(self, key):
-        self._reload_if_necessary()
-
-        return self._combined_dict[key]
-
-    def get(self, key, default = None):
-        try:
-            return self.__getitem__(key)
-        except KeyError:
-            return default
-
-    def __setitem__(self, key, value):
-        """
-        Sets the value of the config setting of key to be newval
-
-        Once any key/value pair is changed via the set method,
-        that key/value pair will remain set with that value until
-        change via the update or set method
-        """
-        self._config_overrides[key] = value
-        self._combine_dictionaries()
-
-    def set(self, key, newval):
-        return self.__setitem__(key, newval)
-
-    def update(self, new_conf):
-        """
-        Load an XML file and apply its map as overrides or additions
-        to the existing config.  Update can be a file or a dict.
-
-        Once any key/value pair is changed via the update method,
-        that key/value pair will remain set with that value until
-        change via the update or set method
-        """
-        if isinstance(new_conf, dict):
-            overrides = new_conf
-        else:
-            # assuming that it is a filename
-            config_file = open(new_conf)
-            overrides = llsd.parse(config_file.read())
-            config_file.close()
-  
-        self._config_overrides.update(overrides)
-        self._combine_dictionaries()
-
-    def as_dict(self):
-        """
-        Returns immutable copy of the IndraConfig as a dictionary
-        """
-        return copy.deepcopy(self._combined_dict)
-
-def load(config_xml_file = None):
-    global _g_config
-
-    load_default_files = config_xml_file is None
-    if load_default_files:
-        ## going from:
-        ## "/opt/linden/indra/lib/python/indra/base/config.py"
-        ## to:
-        ## "/opt/linden/etc/indra.xml"
-        config_xml_file = realpath(
-            dirname(realpath(__file__)) + "../../../../../../etc/indra.xml")
-
-    try:
-        _g_config = IndraConfig(config_xml_file)
-    except IOError:
-        # Failure to load passed in file
-        # or indra.xml default file
-        if load_default_files:
-            try:
-                config_xml_file = realpath(
-                    dirname(realpath(__file__)) + "../../../../../../etc/globals.xml")
-                _g_config = IndraConfig(config_xml_file)
-                return
-            except IOError:
-                # Failure to load globals.xml
-                # fall to code below
-                pass
-
-        # Either failed to load passed in file
-        # or failed to load all default files
-        _g_config = IndraConfig(None)
-
-def dump(indra_xml_file, indra_cfg = None, update_in_mem=False):
-    '''
-    Dump config contents into a file
-    Kindof reverse of load.
-    Optionally takes a new config to dump.
-    Does NOT update global config unless requested.
-    '''
-    global _g_config
-
-    if not indra_cfg:
-        if _g_config is None:
-            return
-
-        indra_cfg = _g_config.as_dict()
-
-    if not indra_cfg:
-        return
-
-    config_file = open(indra_xml_file, 'w')
-    _config_xml = llsd.format_xml(indra_cfg)
-    config_file.write(_config_xml)
-    config_file.close()
-
-    if update_in_mem:
-        update(indra_cfg)
-
-def update(new_conf):
-    global _g_config
-
-    if _g_config is None:
-        # To keep with how this function behaved
-        # previously, a call to update
-        # before the global is defined
-        # make a new global config which does not
-        # load data from a file.
-        _g_config = IndraConfig(None)
-
-    return _g_config.update(new_conf)
-
-def get(key, default = None):
-    global _g_config
-
-    if _g_config is None:
-        load()
-
-    return _g_config.get(key, default)
-
-def set(key, newval):
-    """
-    Sets the value of the config setting of key to be newval
-
-    Once any key/value pair is changed via the set method,
-    that key/value pair will remain set with that value until
-    change via the update or set method or program termination
-    """
-    global _g_config
-
-    if _g_config is None:
-        _g_config = IndraConfig(None)
-
-    _g_config.set(key, newval)
-
-def get_config():
-    global _g_config
-    return _g_config
diff --git a/indra/lib/python/indra/base/llsd.py b/indra/lib/python/indra/base/llsd.py
deleted file mode 100755
index 4527b115f9ad07b6a2f9180090466c2f562112a1..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/base/llsd.py
+++ /dev/null
@@ -1,1052 +0,0 @@
-"""\
-@file llsd.py
-@brief Types as well as parsing and formatting functions for handling LLSD.
-
-$LicenseInfo:firstyear=2006&license=mit$
-
-Copyright (c) 2006-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import datetime
-import base64
-import string
-import struct
-import time
-import types
-import re
-
-from indra.util.fastest_elementtree import ElementTreeError, fromstring
-from indra.base import lluuid
-
-# cllsd.c in server/server-1.25 has memory leaks,
-#   so disabling cllsd for now
-#try:
-#    import cllsd
-#except ImportError:
-#    cllsd = None
-cllsd = None
-
-int_regex = re.compile(r"[-+]?\d+")
-real_regex = re.compile(r"[-+]?(\d+(\.\d*)?|\d*\.\d+)([eE][-+]?\d+)?")
-alpha_regex = re.compile(r"[a-zA-Z]+")
-date_regex = re.compile(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})T"
-                        r"(?P<hour>\d{2}):(?P<minute>\d{2}):(?P<second>\d{2})"
-                        r"(?P<second_float>(\.\d+)?)Z")
-#date: d"YYYY-MM-DDTHH:MM:SS.FFFFFFZ"
-
-class LLSDParseError(Exception):
-    pass
-
-class LLSDSerializationError(TypeError):
-    pass
-
-
-class binary(str):
-    pass
-
-class uri(str):
-    pass
-
-
-BOOL_TRUE = ('1', '1.0', 'true')
-BOOL_FALSE = ('0', '0.0', 'false', '')
-
-
-def format_datestr(v):
-    """ Formats a datetime or date object into the string format shared by xml and notation serializations."""
-    if hasattr(v, 'microsecond'):
-        return v.isoformat() + 'Z'
-    else:
-        return v.strftime('%Y-%m-%dT%H:%M:%SZ')
-
-def parse_datestr(datestr):
-    """Parses a datetime object from the string format shared by xml and notation serializations."""
-    if datestr == "":
-        return datetime.datetime(1970, 1, 1)
-    
-    match = re.match(date_regex, datestr)
-    if not match:
-        raise LLSDParseError("invalid date string '%s'." % datestr)
-    
-    year = int(match.group('year'))
-    month = int(match.group('month'))
-    day = int(match.group('day'))
-    hour = int(match.group('hour'))
-    minute = int(match.group('minute'))
-    second = int(match.group('second'))
-    seconds_float = match.group('second_float')
-    microsecond = 0
-    if seconds_float:
-        microsecond = int(float('0' + seconds_float) * 1e6)
-    return datetime.datetime(year, month, day, hour, minute, second, microsecond)
-
-
-def bool_to_python(node):
-    val = node.text or ''
-    if val in BOOL_TRUE:
-        return True
-    else:
-        return False
-
-def int_to_python(node):
-    val = node.text or ''
-    if not val.strip():
-        return 0
-    return int(val)
-
-def real_to_python(node):
-    val = node.text or ''
-    if not val.strip():
-        return 0.0
-    return float(val)
-
-def uuid_to_python(node):
-    return lluuid.UUID(node.text)
-
-def str_to_python(node):
-    return node.text or ''
-
-def bin_to_python(node):
-    return binary(base64.decodestring(node.text or ''))
-
-def date_to_python(node):
-    val = node.text or ''
-    if not val:
-        val = "1970-01-01T00:00:00Z"
-    return parse_datestr(val)
-    
-
-def uri_to_python(node):
-    val = node.text or ''
-    if not val:
-        return None
-    return uri(val)
-
-def map_to_python(node):
-    result = {}
-    for index in range(len(node))[::2]:
-        result[node[index].text] = to_python(node[index+1])
-    return result
-
-def array_to_python(node):
-    return [to_python(child) for child in node]
-
-
-NODE_HANDLERS = dict(
-    undef=lambda x: None,
-    boolean=bool_to_python,
-    integer=int_to_python,
-    real=real_to_python,
-    uuid=uuid_to_python,
-    string=str_to_python,
-    binary=bin_to_python,
-    date=date_to_python,
-    uri=uri_to_python,
-    map=map_to_python,
-    array=array_to_python,
-    )
-
-def to_python(node):
-    return NODE_HANDLERS[node.tag](node)
-
-class Nothing(object):
-    pass
-
-
-class LLSDXMLFormatter(object):
-    def __init__(self):
-        self.type_map = {
-            type(None) : self.UNDEF,
-            bool : self.BOOLEAN,
-            int : self.INTEGER,
-            long : self.INTEGER,
-            float : self.REAL,
-            lluuid.UUID : self.UUID,
-            binary : self.BINARY,
-            str : self.STRING,
-            unicode : self.STRING,
-            uri : self.URI,
-            datetime.datetime : self.DATE,
-            datetime.date : self.DATE,
-            list : self.ARRAY,
-            tuple : self.ARRAY,
-            types.GeneratorType : self.ARRAY,
-            dict : self.MAP,
-            LLSD : self.LLSD
-        }
-
-    def elt(self, name, contents=None):
-        if(contents is None or contents is ''):
-            return "<%s />" % (name,)
-        else:
-            if type(contents) is unicode:
-                contents = contents.encode('utf-8')
-            return "<%s>%s</%s>" % (name, contents, name)
-
-    def xml_esc(self, v):
-        if type(v) is unicode:
-            v = v.encode('utf-8')
-        return v.replace('&', '&amp;').replace('<', '&lt;').replace('>', '&gt;')
-
-    def LLSD(self, v):
-        return self.generate(v.thing)
-    def UNDEF(self, v):
-        return self.elt('undef')
-    def BOOLEAN(self, v):
-        if v:
-            return self.elt('boolean', 'true')
-        else:
-            return self.elt('boolean', 'false')
-    def INTEGER(self, v):
-        return self.elt('integer', v)
-    def REAL(self, v):
-        return self.elt('real', v)
-    def UUID(self, v):
-        if(v.isNull()):
-            return self.elt('uuid')
-        else:
-            return self.elt('uuid', v)
-    def BINARY(self, v):
-        return self.elt('binary', base64.encodestring(v))
-    def STRING(self, v):
-        return self.elt('string', self.xml_esc(v))
-    def URI(self, v):
-        return self.elt('uri', self.xml_esc(str(v)))
-    def DATE(self, v):
-        return self.elt('date', format_datestr(v))
-    def ARRAY(self, v):
-        return self.elt('array', ''.join([self.generate(item) for item in v]))
-    def MAP(self, v):
-        return self.elt(
-            'map',
-            ''.join(["%s%s" % (self.elt('key', self.xml_esc(str(key))), self.generate(value))
-             for key, value in v.items()]))
-
-    typeof = type
-    def generate(self, something):
-        t = self.typeof(something)
-        if self.type_map.has_key(t):
-            return self.type_map[t](something)
-        else:
-            raise LLSDSerializationError("Cannot serialize unknown type: %s (%s)" % (
-                t, something))
-
-    def _format(self, something):
-        return '<?xml version="1.0" ?>' + self.elt("llsd", self.generate(something))
-
-    def format(self, something):
-        if cllsd:
-            return cllsd.llsd_to_xml(something)
-        return self._format(something)
-
-_g_xml_formatter = None
-def format_xml(something):
-    global _g_xml_formatter
-    if _g_xml_formatter is None:
-        _g_xml_formatter = LLSDXMLFormatter()
-    return _g_xml_formatter.format(something)
-
-class LLSDXMLPrettyFormatter(LLSDXMLFormatter):
-    def __init__(self, indent_atom = None):
-        # Call the super class constructor so that we have the type map
-        super(LLSDXMLPrettyFormatter, self).__init__()
-
-        # Override the type map to use our specialized formatters to
-        # emit the pretty output.
-        self.type_map[list] = self.PRETTY_ARRAY
-        self.type_map[tuple] = self.PRETTY_ARRAY
-        self.type_map[types.GeneratorType] = self.PRETTY_ARRAY,
-        self.type_map[dict] = self.PRETTY_MAP
-
-        # Private data used for indentation.
-        self._indent_level = 1
-        if indent_atom is None:
-            self._indent_atom = '  '
-        else:
-            self._indent_atom = indent_atom
-
-    def _indent(self):
-        "Return an indentation based on the atom and indentation level."
-        return self._indent_atom * self._indent_level
-
-    def PRETTY_ARRAY(self, v):
-        rv = []
-        rv.append('<array>\n')
-        self._indent_level = self._indent_level + 1
-        rv.extend(["%s%s\n" %
-                   (self._indent(),
-                    self.generate(item))
-                   for item in v])
-        self._indent_level = self._indent_level - 1
-        rv.append(self._indent())
-        rv.append('</array>')
-        return ''.join(rv)
-
-    def PRETTY_MAP(self, v):
-        rv = []
-        rv.append('<map>\n')
-        self._indent_level = self._indent_level + 1
-        keys = v.keys()
-        keys.sort()
-        rv.extend(["%s%s\n%s%s\n" %
-                   (self._indent(),
-                    self.elt('key', key),
-                    self._indent(),
-                    self.generate(v[key]))
-                   for key in keys])
-        self._indent_level = self._indent_level - 1
-        rv.append(self._indent())
-        rv.append('</map>')
-        return ''.join(rv)
-
-    def format(self, something):
-        data = []
-        data.append('<?xml version="1.0" ?>\n<llsd>')
-        data.append(self.generate(something))
-        data.append('</llsd>\n')
-        return '\n'.join(data)
-
-def format_pretty_xml(something):
-    """@brief Serialize a python object as 'pretty' llsd xml.
-
-    The output conforms to the LLSD DTD, unlike the output from the
-    standard python xml.dom DOM::toprettyxml() method which does not
-    preserve significant whitespace. 
-    This function is not necessarily suited for serializing very large
-    objects. It is not optimized by the cllsd module, and sorts on
-    dict (llsd map) keys alphabetically to ease human reading.
-    """
-    return LLSDXMLPrettyFormatter().format(something)
-
-class LLSDNotationFormatter(object):
-    def __init__(self):
-        self.type_map = {
-            type(None) : self.UNDEF,
-            bool : self.BOOLEAN,
-            int : self.INTEGER,
-            long : self.INTEGER,
-            float : self.REAL,
-            lluuid.UUID : self.UUID,
-            binary : self.BINARY,
-            str : self.STRING,
-            unicode : self.STRING,
-            uri : self.URI,
-            datetime.datetime : self.DATE,
-            datetime.date : self.DATE,
-            list : self.ARRAY,
-            tuple : self.ARRAY,
-            types.GeneratorType : self.ARRAY,
-            dict : self.MAP,
-            LLSD : self.LLSD
-        }
-
-    def LLSD(self, v):
-        return self.generate(v.thing)
-    def UNDEF(self, v):
-        return '!'
-    def BOOLEAN(self, v):
-        if v:
-            return 'true'
-        else:
-            return 'false'
-    def INTEGER(self, v):
-        return "i%s" % v
-    def REAL(self, v):
-        return "r%s" % v
-    def UUID(self, v):
-        return "u%s" % v
-    def BINARY(self, v):
-        return 'b64"' + base64.encodestring(v) + '"'
-    def STRING(self, v):
-        if isinstance(v, unicode):
-            v = v.encode('utf-8')
-        return "'%s'" % v.replace("\\", "\\\\").replace("'", "\\'")
-    def URI(self, v):
-        return 'l"%s"' % str(v).replace("\\", "\\\\").replace('"', '\\"')
-    def DATE(self, v):
-        return 'd"%s"' % format_datestr(v)
-    def ARRAY(self, v):
-        return "[%s]" % ','.join([self.generate(item) for item in v])
-    def MAP(self, v):
-        def fix(key):
-            if isinstance(key, unicode):
-                return key.encode('utf-8')
-            return key
-        return "{%s}" % ','.join(["'%s':%s" % (fix(key).replace("\\", "\\\\").replace("'", "\\'"), self.generate(value))
-             for key, value in v.items()])
-
-    def generate(self, something):
-        t = type(something)
-        handler = self.type_map.get(t)
-        if handler:
-            return handler(something)
-        else:
-            try:
-                return self.ARRAY(iter(something))
-            except TypeError:
-                raise LLSDSerializationError(
-                    "Cannot serialize unknown type: %s (%s)" % (t, something))
-
-    def format(self, something):
-        return self.generate(something)
-
-def format_notation(something):
-    return LLSDNotationFormatter().format(something)
-
-def _hex_as_nybble(hex):
-    if (hex >= '0') and (hex <= '9'):
-        return ord(hex) - ord('0')
-    elif (hex >= 'a') and (hex <='f'):
-        return 10 + ord(hex) - ord('a')
-    elif (hex >= 'A') and (hex <='F'):
-        return 10 + ord(hex) - ord('A');
-
-class LLSDBinaryParser(object):
-    def __init__(self):
-        pass
-
-    def parse(self, buffer, ignore_binary = False):
-        """
-        This is the basic public interface for parsing.
-
-        @param buffer the binary data to parse in an indexable sequence.
-        @param ignore_binary parser throws away data in llsd binary nodes.
-        @return returns a python object.
-        """
-        self._buffer = buffer
-        self._index = 0
-        self._keep_binary = not ignore_binary
-        return self._parse()
-
-    def _parse(self):
-        cc = self._buffer[self._index]
-        self._index += 1
-        if cc == '{':
-            return self._parse_map()
-        elif cc == '[':
-            return self._parse_array()
-        elif cc == '!':
-            return None
-        elif cc == '0':
-            return False
-        elif cc == '1':
-            return True
-        elif cc == 'i':
-            # 'i' = integer
-            idx = self._index
-            self._index += 4
-            return struct.unpack("!i", self._buffer[idx:idx+4])[0]
-        elif cc == ('r'):
-            # 'r' = real number
-            idx = self._index
-            self._index += 8
-            return struct.unpack("!d", self._buffer[idx:idx+8])[0]
-        elif cc == 'u':
-            # 'u' = uuid
-            idx = self._index
-            self._index += 16
-            return lluuid.uuid_bits_to_uuid(self._buffer[idx:idx+16])
-        elif cc == 's':
-            # 's' = string
-            return self._parse_string()
-        elif cc in ("'", '"'):
-            # delimited/escaped string
-            return self._parse_string_delim(cc)
-        elif cc == 'l':
-            # 'l' = uri
-            return uri(self._parse_string())
-        elif cc == ('d'):
-            # 'd' = date in seconds since epoch
-            idx = self._index
-            self._index += 8
-            seconds = struct.unpack("!d", self._buffer[idx:idx+8])[0]
-            return datetime.datetime.fromtimestamp(seconds)
-        elif cc == 'b':
-            binary = self._parse_string()
-            if self._keep_binary:
-                return binary
-            # *NOTE: maybe have a binary placeholder which has the
-            # length.
-            return None
-        else:
-            raise LLSDParseError("invalid binary token at byte %d: %d" % (
-                self._index - 1, ord(cc)))
-
-    def _parse_map(self):
-        rv = {}
-        size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0]
-        self._index += 4
-        count = 0
-        cc = self._buffer[self._index]
-        self._index += 1
-        key = ''
-        while (cc != '}') and (count < size):
-            if cc == 'k':
-                key = self._parse_string()
-            elif cc in ("'", '"'):
-                key = self._parse_string_delim(cc)
-            else:
-                raise LLSDParseError("invalid map key at byte %d." % (
-                    self._index - 1,))
-            value = self._parse()
-            rv[key] = value
-            count += 1
-            cc = self._buffer[self._index]
-            self._index += 1
-        if cc != '}':
-            raise LLSDParseError("invalid map close token at byte %d." % (
-                self._index,))
-        return rv
-
-    def _parse_array(self):
-        rv = []
-        size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0]
-        self._index += 4
-        count = 0
-        cc = self._buffer[self._index]
-        while (cc != ']') and (count < size):
-            rv.append(self._parse())
-            count += 1
-            cc = self._buffer[self._index]
-        if cc != ']':
-            raise LLSDParseError("invalid array close token at byte %d." % (
-                self._index,))
-        self._index += 1
-        return rv
-
-    def _parse_string(self):
-        size = struct.unpack("!i", self._buffer[self._index:self._index+4])[0]
-        self._index += 4
-        rv = self._buffer[self._index:self._index+size]
-        self._index += size
-        return rv
-
-    def _parse_string_delim(self, delim):
-        list = []
-        found_escape = False
-        found_hex = False
-        found_digit = False
-        byte = 0
-        while True:
-            cc = self._buffer[self._index]
-            self._index += 1
-            if found_escape:
-                if found_hex:
-                    if found_digit:
-                        found_escape = False
-                        found_hex = False
-                        found_digit = False
-                        byte <<= 4
-                        byte |= _hex_as_nybble(cc)
-                        list.append(chr(byte))
-                        byte = 0
-                    else:
-                        found_digit = True
-                        byte = _hex_as_nybble(cc)
-                elif cc == 'x':
-                    found_hex = True
-                else:
-                    if cc == 'a':
-                        list.append('\a')
-                    elif cc == 'b':
-                        list.append('\b')
-                    elif cc == 'f':
-                        list.append('\f')
-                    elif cc == 'n':
-                        list.append('\n')
-                    elif cc == 'r':
-                        list.append('\r')
-                    elif cc == 't':
-                        list.append('\t')
-                    elif cc == 'v':
-                        list.append('\v')
-                    else:
-                        list.append(cc)
-                    found_escape = False
-            elif cc == '\\':
-                found_escape = True
-            elif cc == delim:
-                break
-            else:
-                list.append(cc)
-        return ''.join(list)
-
-class LLSDNotationParser(object):
-    """ Parse LLSD notation:
-    map: { string:object, string:object }
-    array: [ object, object, object ]
-    undef: !
-    boolean: true | false | 1 | 0 | T | F | t | f | TRUE | FALSE
-    integer: i####
-    real: r####
-    uuid: u####
-    string: "g\'day" | 'have a "nice" day' | s(size)"raw data"
-    uri: l"escaped"
-    date: d"YYYY-MM-DDTHH:MM:SS.FFZ"
-    binary: b##"ff3120ab1" | b(size)"raw data"
-    """
-    def __init__(self):
-        pass
-
-    def parse(self, buffer, ignore_binary = False):
-        """
-        This is the basic public interface for parsing.
-
-        @param buffer the notation string to parse.
-        @param ignore_binary parser throws away data in llsd binary nodes.
-        @return returns a python object.
-        """
-        if buffer == "":
-            return False
-
-        self._buffer = buffer
-        self._index = 0
-        return self._parse()
-
-    def _parse(self):
-        cc = self._buffer[self._index]
-        self._index += 1
-        if cc == '{':
-            return self._parse_map()
-        elif cc == '[':
-            return self._parse_array()
-        elif cc == '!':
-            return None
-        elif cc == '0':
-            return False
-        elif cc == '1':
-            return True
-        elif cc in ('F', 'f'):
-            self._skip_alpha()
-            return False
-        elif cc in ('T', 't'):
-            self._skip_alpha()
-            return True
-        elif cc == 'i':
-            # 'i' = integer
-            return self._parse_integer()
-        elif cc == ('r'):
-            # 'r' = real number
-            return self._parse_real()
-        elif cc == 'u':
-            # 'u' = uuid
-            return self._parse_uuid()
-        elif cc in ("'", '"', 's'):
-            return self._parse_string(cc)
-        elif cc == 'l':
-            # 'l' = uri
-            delim = self._buffer[self._index]
-            self._index += 1
-            val = uri(self._parse_string(delim))
-            if len(val) == 0:
-                return None
-            return val
-        elif cc == ('d'):
-            # 'd' = date in seconds since epoch
-            return self._parse_date()
-        elif cc == 'b':
-            return self._parse_binary()
-        else:
-            raise LLSDParseError("invalid token at index %d: %d" % (
-                self._index - 1, ord(cc)))
-
-    def _parse_binary(self):
-        i = self._index
-        if self._buffer[i:i+2] == '64':
-            q = self._buffer[i+2]
-            e = self._buffer.find(q, i+3)
-            try:
-                return base64.decodestring(self._buffer[i+3:e])
-            finally:
-                self._index = e + 1
-        else:
-            raise LLSDParseError('random horrible binary format not supported')
-
-    def _parse_map(self):
-        """ map: { string:object, string:object } """
-        rv = {}
-        cc = self._buffer[self._index]
-        self._index += 1
-        key = ''
-        found_key = False
-        while (cc != '}'):
-            if not found_key:
-                if cc in ("'", '"', 's'):
-                    key = self._parse_string(cc)
-                    found_key = True
-                elif cc.isspace() or cc == ',':
-                    cc = self._buffer[self._index]
-                    self._index += 1
-                else:
-                    raise LLSDParseError("invalid map key at byte %d." % (
-                                        self._index - 1,))
-            elif cc.isspace() or cc == ':':
-                cc = self._buffer[self._index]
-                self._index += 1
-                continue
-            else:
-                self._index += 1
-                value = self._parse()
-                rv[key] = value
-                found_key = False
-                cc = self._buffer[self._index]
-                self._index += 1
-
-        return rv
-
-    def _parse_array(self):
-        """ array: [ object, object, object ] """
-        rv = []
-        cc = self._buffer[self._index]
-        while (cc != ']'):
-            if cc.isspace() or cc == ',':
-                self._index += 1
-                cc = self._buffer[self._index]
-                continue
-            rv.append(self._parse())
-            cc = self._buffer[self._index]
-
-        if cc != ']':
-            raise LLSDParseError("invalid array close token at index %d." % (
-                self._index,))
-        self._index += 1
-        return rv
-
-    def _parse_uuid(self):
-        match = re.match(lluuid.UUID.uuid_regex, self._buffer[self._index:])
-        if not match:
-            raise LLSDParseError("invalid uuid token at index %d." % self._index)
-
-        (start, end) = match.span()
-        start += self._index
-        end += self._index
-        self._index = end
-        return lluuid.UUID(self._buffer[start:end])
-
-    def _skip_alpha(self):
-        match = re.match(alpha_regex, self._buffer[self._index:])
-        if match:
-            self._index += match.end()
-            
-    def _parse_date(self):
-        delim = self._buffer[self._index]
-        self._index += 1
-        datestr = self._parse_string(delim)
-        return parse_datestr(datestr)
-
-    def _parse_real(self):
-        match = re.match(real_regex, self._buffer[self._index:])
-        if not match:
-            raise LLSDParseError("invalid real token at index %d." % self._index)
-
-        (start, end) = match.span()
-        start += self._index
-        end += self._index
-        self._index = end
-        return float( self._buffer[start:end] )
-
-    def _parse_integer(self):
-        match = re.match(int_regex, self._buffer[self._index:])
-        if not match:
-            raise LLSDParseError("invalid integer token at index %d." % self._index)
-
-        (start, end) = match.span()
-        start += self._index
-        end += self._index
-        self._index = end
-        return int( self._buffer[start:end] )
-
-    def _parse_string(self, delim):
-        """ string: "g\'day" | 'have a "nice" day' | s(size)"raw data" """
-        rv = ""
-
-        if delim in ("'", '"'):
-            rv = self._parse_string_delim(delim)
-        elif delim == 's':
-            rv = self._parse_string_raw()
-        else:
-            raise LLSDParseError("invalid string token at index %d." % self._index)
-
-        return rv
-
-
-    def _parse_string_delim(self, delim):
-        """ string: "g'day 'un" | 'have a "nice" day' """
-        list = []
-        found_escape = False
-        found_hex = False
-        found_digit = False
-        byte = 0
-        while True:
-            cc = self._buffer[self._index]
-            self._index += 1
-            if found_escape:
-                if found_hex:
-                    if found_digit:
-                        found_escape = False
-                        found_hex = False
-                        found_digit = False
-                        byte <<= 4
-                        byte |= _hex_as_nybble(cc)
-                        list.append(chr(byte))
-                        byte = 0
-                    else:
-                        found_digit = True
-                        byte = _hex_as_nybble(cc)
-                elif cc == 'x':
-                    found_hex = True
-                else:
-                    if cc == 'a':
-                        list.append('\a')
-                    elif cc == 'b':
-                        list.append('\b')
-                    elif cc == 'f':
-                        list.append('\f')
-                    elif cc == 'n':
-                        list.append('\n')
-                    elif cc == 'r':
-                        list.append('\r')
-                    elif cc == 't':
-                        list.append('\t')
-                    elif cc == 'v':
-                        list.append('\v')
-                    else:
-                        list.append(cc)
-                    found_escape = False
-            elif cc == '\\':
-                found_escape = True
-            elif cc == delim:
-                break
-            else:
-                list.append(cc)
-        return ''.join(list)
-
-    def _parse_string_raw(self):
-        """ string: s(size)"raw data" """
-        # Read the (size) portion.
-        cc = self._buffer[self._index]
-        self._index += 1
-        if cc != '(':
-            raise LLSDParseError("invalid string token at index %d." % self._index)
-
-        rparen = self._buffer.find(')', self._index)
-        if rparen == -1:
-            raise LLSDParseError("invalid string token at index %d." % self._index)
-
-        size = int(self._buffer[self._index:rparen])
-
-        self._index = rparen + 1
-        delim = self._buffer[self._index]
-        self._index += 1
-        if delim not in ("'", '"'):
-            raise LLSDParseError("invalid string token at index %d." % self._index)
-
-        rv = self._buffer[self._index:(self._index + size)]
-        self._index += size
-        cc = self._buffer[self._index]
-        self._index += 1
-        if cc != delim:
-            raise LLSDParseError("invalid string token at index %d." % self._index)
-
-        return rv
-        
-def format_binary(something):
-    return '<?llsd/binary?>\n' + _format_binary_recurse(something)
-
-def _format_binary_recurse(something):
-    def _format_list(something):
-        array_builder = []
-        array_builder.append('[' + struct.pack('!i', len(something)))
-        for item in something:
-            array_builder.append(_format_binary_recurse(item))
-        array_builder.append(']')
-        return ''.join(array_builder)
-
-    if something is None:
-        return '!'
-    elif isinstance(something, LLSD):
-        return _format_binary_recurse(something.thing)
-    elif isinstance(something, bool):
-        if something:
-            return '1'
-        else:
-            return '0'
-    elif isinstance(something, (int, long)):
-        return 'i' + struct.pack('!i', something)
-    elif isinstance(something, float):
-        return 'r' + struct.pack('!d', something)
-    elif isinstance(something, lluuid.UUID):
-        return 'u' + something._bits
-    elif isinstance(something, binary):
-        return 'b' + struct.pack('!i', len(something)) + something
-    elif isinstance(something, str):
-        return 's' + struct.pack('!i', len(something)) + something
-    elif isinstance(something, unicode):
-        something = something.encode('utf-8')
-        return 's' + struct.pack('!i', len(something)) + something
-    elif isinstance(something, uri):
-        return 'l' + struct.pack('!i', len(something)) + something
-    elif isinstance(something, datetime.datetime):
-        seconds_since_epoch = time.mktime(something.timetuple())
-        return 'd' + struct.pack('!d', seconds_since_epoch)
-    elif isinstance(something, (list, tuple)):
-        return _format_list(something)
-    elif isinstance(something, dict):
-        map_builder = []
-        map_builder.append('{' + struct.pack('!i', len(something)))
-        for key, value in something.items():
-            if isinstance(key, unicode):
-                key = key.encode('utf-8')
-            map_builder.append('k' + struct.pack('!i', len(key)) + key)
-            map_builder.append(_format_binary_recurse(value))
-        map_builder.append('}')
-        return ''.join(map_builder)
-    else:
-        try:
-            return _format_list(list(something))
-        except TypeError:
-            raise LLSDSerializationError(
-                "Cannot serialize unknown type: %s (%s)" %
-                (type(something), something))
-
-
-def parse_binary(binary):
-    if binary.startswith('<?llsd/binary?>'):
-        just_binary = binary.split('\n', 1)[1]
-    else:
-        just_binary = binary
-    return LLSDBinaryParser().parse(just_binary)
-
-def parse_xml(something):
-    try:
-        return to_python(fromstring(something)[0])
-    except ElementTreeError, err:
-        raise LLSDParseError(*err.args)
-
-def parse_notation(something):
-    return LLSDNotationParser().parse(something)
-
-def parse(something):
-    try:
-        something = string.lstrip(something)   #remove any pre-trailing whitespace
-        if something.startswith('<?llsd/binary?>'):
-            return parse_binary(something)
-        # This should be better.
-        elif something.startswith('<'):
-            return parse_xml(something)
-        else:
-            return parse_notation(something)
-    except KeyError, e:
-        raise Exception('LLSD could not be parsed: %s' % (e,))
-
-class LLSD(object):
-    def __init__(self, thing=None):
-        self.thing = thing
-
-    def __str__(self):
-        return self.toXML(self.thing)
-
-    parse = staticmethod(parse)
-    toXML = staticmethod(format_xml)
-    toPrettyXML = staticmethod(format_pretty_xml)
-    toBinary = staticmethod(format_binary)
-    toNotation = staticmethod(format_notation)
-
-
-undef = LLSD(None)
-
-XML_MIME_TYPE = 'application/llsd+xml'
-BINARY_MIME_TYPE = 'application/llsd+binary'
-
-# register converters for llsd in mulib, if it is available
-try:
-    from mulib import stacked, mu
-    stacked.NoProducer()  # just to exercise stacked
-    mu.safe_load(None)    # just to exercise mu
-except:
-    # mulib not available, don't print an error message since this is normal
-    pass
-else:
-    mu.add_parser(parse, XML_MIME_TYPE)
-    mu.add_parser(parse, 'application/llsd+binary')
-
-    def llsd_convert_xml(llsd_stuff, request):
-        request.write(format_xml(llsd_stuff))
-
-    def llsd_convert_binary(llsd_stuff, request):
-        request.write(format_binary(llsd_stuff))
-
-    for typ in [LLSD, dict, list, tuple, str, int, long, float, bool, unicode, type(None)]:
-        stacked.add_producer(typ, llsd_convert_xml, XML_MIME_TYPE)
-        stacked.add_producer(typ, llsd_convert_xml, 'application/xml')
-        stacked.add_producer(typ, llsd_convert_xml, 'text/xml')
-
-        stacked.add_producer(typ, llsd_convert_binary, 'application/llsd+binary')
-
-    stacked.add_producer(LLSD, llsd_convert_xml, '*/*')
-
-    # in case someone is using the legacy mu.xml wrapper, we need to
-    # tell mu to produce application/xml or application/llsd+xml
-    # (based on the accept header) from raw xml. Phoenix 2008-07-21
-    stacked.add_producer(mu.xml, mu.produce_raw, XML_MIME_TYPE)
-    stacked.add_producer(mu.xml, mu.produce_raw, 'application/xml')
-
-
-
-# mulib wsgi stuff
-# try:
-#     from mulib import mu, adapters
-#
-#     # try some known attributes from mulib to be ultra-sure we've imported it
-#     mu.get_current
-#     adapters.handlers
-# except:
-#     # mulib not available, don't print an error message since this is normal
-#     pass
-# else:
-#     def llsd_xml_handler(content_type):
-#         def handle_llsd_xml(env, start_response):
-#             llsd_stuff, _ = mu.get_current(env)
-#             result = format_xml(llsd_stuff)
-#             start_response("200 OK", [('Content-Type', content_type)])
-#             env['mu.negotiated_type'] = content_type
-#             yield result
-#         return handle_llsd_xml
-#    
-#     def llsd_binary_handler(content_type):
-#         def handle_llsd_binary(env, start_response):
-#             llsd_stuff, _ = mu.get_current(env)
-#             result = format_binary(llsd_stuff)
-#             start_response("200 OK", [('Content-Type', content_type)])
-#             env['mu.negotiated_type'] = content_type
-#             yield result
-#         return handle_llsd_binary
-#
-#     adapters.DEFAULT_PARSERS[XML_MIME_TYPE] = parse
-    
-#     for typ in [LLSD, dict, list, tuple, str, int, float, bool, unicode, type(None)]:
-#         for content_type in (XML_MIME_TYPE, 'application/xml'):
-#             adapters.handlers.set_handler(typ, llsd_xml_handler(content_type), content_type)
-#
-#         adapters.handlers.set_handler(typ, llsd_binary_handler(BINARY_MIME_TYPE), BINARY_MIME_TYPE)
-#
-#     adapters.handlers.set_handler(LLSD, llsd_xml_handler(XML_MIME_TYPE), '*/*')
diff --git a/indra/lib/python/indra/base/lluuid.py b/indra/lib/python/indra/base/lluuid.py
deleted file mode 100755
index 7413ffe10d151b62bd86d462e841bab0309a42d9..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/base/lluuid.py
+++ /dev/null
@@ -1,319 +0,0 @@
-"""\
-@file lluuid.py
-@brief UUID parser/generator.
-
-$LicenseInfo:firstyear=2004&license=mit$
-
-Copyright (c) 2004-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import random, socket, string, time, re
-import uuid
-try:
-    # Python 2.6
-    from hashlib import md5
-except ImportError:
-    # Python 2.5 and earlier
-    from md5 import new as md5
-
-def _int2binstr(i,l):
-    s=''
-    for a in range(l):
-        s=chr(i&0xFF)+s
-        i>>=8
-    return s
-
-def _binstr2int(s):
-    i = long(0)
-    for c in s:
-        i = (i<<8) + ord(c)
-    return i
-
-class UUID(object):
-    """
-    A class which represents a 16 byte integer. Stored as a 16 byte 8
-    bit character string.
-
-    The string version is to be of the form:
-    AAAAAAAA-AAAA-BBBB-BBBB-BBBBBBCCCCCC  (a 128-bit number in hex)
-    where A=network address, B=timestamp, C=random.
-    """
-
-    NULL_STR = "00000000-0000-0000-0000-000000000000"
-
-    # the UUIDREGEX_STRING is helpful for parsing UUID's in text
-    hex_wildcard = r"[0-9a-fA-F]"
-    word = hex_wildcard + r"{4,4}-"
-    long_word = hex_wildcard + r"{8,8}-"
-    very_long_word = hex_wildcard + r"{12,12}"
-    UUID_REGEX_STRING = long_word + word + word + word + very_long_word
-    uuid_regex = re.compile(UUID_REGEX_STRING)
-
-    rand = random.Random()
-    ip = ''
-    try:
-        ip = socket.gethostbyname(socket.gethostname())
-    except(socket.gaierror, socket.error):
-        # no ip address, so just default to somewhere in 10.x.x.x
-        ip = '10'
-        for i in range(3):
-            ip += '.' + str(rand.randrange(1,254))
-    hexip = ''.join(["%04x" % long(i) for i in ip.split('.')])
-    lastid = ''
-
-    def __init__(self, possible_uuid=None):
-        """
-        Initialize to first valid UUID in argument (if a string),
-        or to null UUID if none found or argument is not supplied.
-
-        If the argument is a UUID, the constructed object will be a copy of it.
-        """
-        self._bits = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-        if possible_uuid is None:
-            return
-
-        if isinstance(possible_uuid, type(self)):
-            self.set(possible_uuid)
-            return
-
-        uuid_match = UUID.uuid_regex.search(possible_uuid)
-        if uuid_match:
-            uuid_string = uuid_match.group()
-            s = string.replace(uuid_string, '-', '')
-            self._bits = _int2binstr(string.atol(s[:8],16),4) + \
-                         _int2binstr(string.atol(s[8:16],16),4) + \
-                         _int2binstr(string.atol(s[16:24],16),4) + \
-                         _int2binstr(string.atol(s[24:],16),4) 
-
-    def __len__(self):
-        """
-        Used by the len() builtin.
-        """
-        return 36
-
-    def __nonzero__(self):
-        return self._bits != "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-
-    def __str__(self):
-        uuid_string = self.toString()
-        return uuid_string
-
-    __repr__ = __str__
-
-    def __getitem__(self, index):
-        return str(self)[index]
-
-    def __eq__(self, other):
-        if isinstance(other, (str, unicode)):
-            return other == str(self)
-        return self._bits == getattr(other, '_bits', '')
-
-    def __ne__(self, other):
-        return not self.__eq__(other)
-
-    def __le__(self, other):
-        return self._bits <= other._bits
-
-    def __ge__(self, other):
-        return self._bits >= other._bits
-
-    def __lt__(self, other):
-        return self._bits < other._bits
-
-    def __gt__(self, other):
-        return self._bits > other._bits
-
-    def __hash__(self):
-        return hash(self._bits)
-
-    def set(self, uuid):
-        self._bits = uuid._bits
-
-    def setFromString(self, uuid_string):
-        """
-        Given a string version of a uuid, set self bits
-        appropriately. Returns self.
-        """
-        s = string.replace(uuid_string, '-', '')
-        self._bits = _int2binstr(string.atol(s[:8],16),4) + \
-                     _int2binstr(string.atol(s[8:16],16),4) + \
-                     _int2binstr(string.atol(s[16:24],16),4) + \
-                     _int2binstr(string.atol(s[24:],16),4) 
-        return self
-
-    def setFromMemoryDump(self, gdb_string):
-        """
-        We expect to get gdb_string as four hex units. eg:
-        0x147d54db      0xc34b3f1b      0x714f989b      0x0a892fd2
-        Which will be translated to:
-        db547d14-1b3f4bc3-9b984f71-d22f890a
-        Returns self.
-        """
-        s = string.replace(gdb_string, '0x', '')
-        s = string.replace(s, ' ', '')
-        t = ''
-        for i in range(8,40,8):
-            for j in range(0,8,2):
-                t = t + s[i-j-2:i-j]
-        self.setFromString(t)
-
-    def toString(self):
-        """
-        Return as a string matching the LL standard
-        AAAAAAAA-AAAA-BBBB-BBBB-BBBBBBCCCCCC  (a 128-bit number in hex)
-        where A=network address, B=timestamp, C=random.
-        """
-        return uuid_bits_to_string(self._bits)
-
-    def getAsString(self):
-        """
-        Return a different string representation of the form
-        AAAAAAAA-AAAABBBB-BBBBBBBB-BBCCCCCC  (a 128-bit number in hex)
-        where A=network address, B=timestamp, C=random.
-        """
-        i1 = _binstr2int(self._bits[0:4])
-        i2 = _binstr2int(self._bits[4:8])
-        i3 = _binstr2int(self._bits[8:12])
-        i4 = _binstr2int(self._bits[12:16])
-        return '%08lx-%08lx-%08lx-%08lx' % (i1,i2,i3,i4)
-
-    def generate(self):
-        """
-        Generate a new uuid. This algorithm is slightly different
-        from c++ implementation for portability reasons.
-        Returns self.
-        """
-        m = md5()
-        m.update(uuid.uuid1().bytes)
-        self._bits = m.digest()
-        return self
-
-    def isNull(self):
-        """
-        Returns 1 if the uuid is null - ie, equal to default uuid.
-        """
-        return (self._bits == "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0")
-
-    def xor(self, rhs):
-        """
-        xors self with rhs.
-        """
-        v1 = _binstr2int(self._bits[0:4]) ^ _binstr2int(rhs._bits[0:4])
-        v2 = _binstr2int(self._bits[4:8]) ^ _binstr2int(rhs._bits[4:8])
-        v3 = _binstr2int(self._bits[8:12]) ^ _binstr2int(rhs._bits[8:12])
-        v4 = _binstr2int(self._bits[12:16]) ^ _binstr2int(rhs._bits[12:16])
-        self._bits = _int2binstr(v1,4) + \
-                     _int2binstr(v2,4) + \
-                     _int2binstr(v3,4) + \
-                     _int2binstr(v4,4) 
-
-
-# module-level null constant
-NULL = UUID()
-
-def printTranslatedMemory(four_hex_uints):
-    """
-    We expect to get the string as four hex units. eg:
-    0x147d54db      0xc34b3f1b      0x714f989b      0x0a892fd2
-    Which will be translated to:
-    db547d14-1b3f4bc3-9b984f71-d22f890a
-    """
-    uuid = UUID()
-    uuid.setFromMemoryDump(four_hex_uints)
-    print uuid.toString()
-
-def isUUID(id_str):
-    """
-    This function returns:
-    - 1 if the string passed is a UUID
-    - 0 is the string passed is not a UUID
-    - None if it neither of the if's below is satisfied
-    """
-    if not id_str or len(id_str) <  5 or len(id_str) > 36:
-        return 0
-
-    if isinstance(id_str, UUID) or UUID.uuid_regex.match(id_str):
-        return 1
-
-    return None
-
-def isPossiblyID(id_str):
-    """
-    This function returns 1 if the string passed has some uuid-like
-    characteristics. Otherwise returns 0.
-    """
-
-    is_uuid = isUUID(id_str)
-    if is_uuid is not None:
-        return is_uuid
-
-    # build a string which matches every character.
-    hex_wildcard = r"[0-9a-fA-F]"
-    chars = len(id_str)
-    next = min(chars, 8)
-    matcher = hex_wildcard+"{"+str(next)+","+str(next)+"}"
-    chars = chars - next
-    if chars > 0:
-        matcher = matcher + "-"
-        chars = chars - 1
-    for block in range(3):
-        next = max(min(chars, 4), 0)
-        if next:
-            matcher = matcher + hex_wildcard+"{"+str(next)+","+str(next)+"}"
-            chars = chars - next
-        if chars > 0:
-            matcher = matcher + "-"
-            chars = chars - 1
-    if chars > 0:
-        next = min(chars, 12)
-        matcher = matcher + hex_wildcard+"{"+str(next)+","+str(next)+"}"
-    #print matcher
-    uuid_matcher = re.compile(matcher)
-    if uuid_matcher.match(id_str):
-        return 1
-    return 0
-
-def uuid_bits_to_string(bits):
-    i1 = _binstr2int(bits[0:4])
-    i2 = _binstr2int(bits[4:6])
-    i3 = _binstr2int(bits[6:8])
-    i4 = _binstr2int(bits[8:10])
-    i5 = _binstr2int(bits[10:12])
-    i6 = _binstr2int(bits[12:16])
-    return '%08lx-%04lx-%04lx-%04lx-%04lx%08lx' % (i1,i2,i3,i4,i5,i6)
-
-def uuid_bits_to_uuid(bits):
-    return UUID(uuid_bits_to_string(bits))
-
-
-try:
-    from mulib import stacked
-    stacked.NoProducer()  # just to exercise stacked
-except:
-    #print "Couldn't import mulib.stacked, not registering UUID converter"
-    pass
-else:
-    def convertUUID(uuid, req):
-        req.write(str(uuid))
-
-    stacked.add_producer(UUID, convertUUID, "*/*")
-    stacked.add_producer(UUID, convertUUID, "text/html")
diff --git a/indra/lib/python/indra/base/metrics.py b/indra/lib/python/indra/base/metrics.py
deleted file mode 100755
index ff8380265f376dd391d1a11edf2a540c53f53a18..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/base/metrics.py
+++ /dev/null
@@ -1,121 +0,0 @@
-"""\
-@file metrics.py
-@author Phoenix
-@date 2007-11-27
-@brief simple interface for logging metrics
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import sys
-try:
-    import syslog
-except ImportError:
-    # Windows
-    import sys
-    class syslog(object):
-        # wrap to a lame syslog for windows
-        _logfp = sys.stderr
-        def syslog(msg):
-            _logfp.write(msg)
-            if not msg.endswith('\n'):
-                _logfp.write('\n')
-        syslog = staticmethod(syslog)
-
-from indra.base.llsd import format_notation
-
-def record_metrics(table, stats):
-    "Write a standard metrics log"
-    _log("LLMETRICS", table, stats)
-
-def record_event(table, data):
-    "Write a standard logmessage log"
-    _log("LLLOGMESSAGE", table, data)
-
-def set_destination(dest):
-    """Set the destination of metrics logs for this process.
-
-    If you do not call this function prior to calling a logging
-    method, that function will open sys.stdout as a destination.
-    Attempts to set dest to None will throw a RuntimeError.
-    @param dest a file-like object which will be the destination for logs."""
-    if dest is None:
-        raise RuntimeError("Attempt to unset metrics destination.")
-    global _destination
-    _destination = dest
-
-def destination():
-    """Get the destination of the metrics logs for this process.
-    Returns None if no destination is set"""
-    global _destination
-    return _destination
-
-class SysLogger(object):
-    "A file-like object which writes to syslog."
-    def __init__(self, ident='indra', logopt = None, facility = None):
-        try:
-            if logopt is None:
-                logopt = syslog.LOG_CONS | syslog.LOG_PID
-            if facility is None:
-                facility = syslog.LOG_LOCAL0
-            syslog.openlog(ident, logopt, facility)
-            import atexit
-            atexit.register(syslog.closelog)
-        except AttributeError:
-            # No syslog module on Windows
-            pass
-
-    def write(str):
-        syslog.syslog(str)
-    write = staticmethod(write)
-
-    def flush():
-        pass
-    flush = staticmethod(flush)
-
-#
-# internal API
-#
-_sequence_id = 0
-_destination = None
-
-def _next_id():
-    global _sequence_id
-    next = _sequence_id
-    _sequence_id += 1
-    return next
-
-def _dest():
-    global _destination
-    if _destination is None:
-        # this default behavior is documented in the metrics functions above.
-        _destination = sys.stdout
-    return _destination
-    
-def _log(header, table, data):
-    log_line = "%s (%d) %s %s" \
-               % (header, _next_id(), table, format_notation(data))
-    dest = _dest()
-    dest.write(log_line)
-    dest.flush()
diff --git a/indra/lib/python/indra/ipc/httputil.py b/indra/lib/python/indra/ipc/httputil.py
deleted file mode 100755
index d53f34a771f96cc4b84b8dc21336fe1aac8b8d57..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/ipc/httputil.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/python
-## $LicenseInfo:firstyear=2011&license=viewerlgpl$
-## Second Life Viewer Source Code
-## Copyright (C) 2011, Linden Research, Inc.
-## 
-## This library is free software; you can redistribute it and/or
-## modify it under the terms of the GNU Lesser General Public
-## License as published by the Free Software Foundation;
-## version 2.1 of the License only.
-## 
-## This library is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## Lesser General Public License for more details.
-## 
-## You should have received a copy of the GNU Lesser General Public
-## License along with this library; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-## 
-## Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-## $/LicenseInfo$
-
-import warnings
-
-warnings.warn("indra.ipc.httputil has been deprecated; use eventlet.httpc instead", DeprecationWarning, 2)
-
-from eventlet.httpc import *
-
-
-makeConnection = make_connection
diff --git a/indra/lib/python/indra/ipc/llsdhttp.py b/indra/lib/python/indra/ipc/llsdhttp.py
deleted file mode 100755
index cbe8ee1eca352c4c1c26ec861b9d4affb950791c..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/ipc/llsdhttp.py
+++ /dev/null
@@ -1,100 +0,0 @@
-"""\
-@file llsdhttp.py
-@brief Functions to ease moving llsd over http
- 
-$LicenseInfo:firstyear=2006&license=mit$
-
-Copyright (c) 2006-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
- 
-import os.path
-import os
-import urlparse
-
-from indra.base import llsd
-
-from eventlet import httpc
-
-suite = httpc.HttpSuite(llsd.format_xml, llsd.parse, 'application/llsd+xml')
-delete = suite.delete
-delete_ = suite.delete_
-get = suite.get
-get_ = suite.get_
-head = suite.head
-head_ = suite.head_
-post = suite.post
-post_ = suite.post_
-put = suite.put
-put_ = suite.put_
-request = suite.request
-request_ = suite.request_
-
-# import every httpc error exception into our namespace for convenience
-for x in httpc.status_to_error_map.itervalues():
-    globals()[x.__name__] = x
-ConnectionError = httpc.ConnectionError
-Retriable = httpc.Retriable
-
-for x in (httpc.ConnectionError,):
-    globals()[x.__name__] = x
-
-
-def postFile(url, filename):
-    f = open(filename)
-    body = f.read()
-    f.close()
-    llsd_body = llsd.parse(body)
-    return post_(url, llsd_body)
-
-
-# deprecated in favor of get_
-def getStatus(url, use_proxy=False):
-    status, _headers, _body = get_(url, use_proxy=use_proxy)
-    return status
-
-# deprecated in favor of put_
-def putStatus(url, data):
-    status, _headers, _body = put_(url, data)
-    return status
-
-# deprecated in favor of delete_
-def deleteStatus(url):
-    status, _headers, _body = delete_(url)
-    return status
-
-# deprecated in favor of post_
-def postStatus(url, data):
-    status, _headers, _body = post_(url, data)
-    return status
-
-
-def postFileStatus(url, filename):
-    status, _headers, body = postFile(url, filename)
-    return status, body
-
-
-def getFromSimulator(path, use_proxy=False):
-    return get('http://' + simulatorHostAndPort + path, use_proxy=use_proxy)
-
-
-def postToSimulator(path, data=None):
-    return post('http://' + simulatorHostAndPort + path, data)
diff --git a/indra/lib/python/indra/ipc/mysql_pool.py b/indra/lib/python/indra/ipc/mysql_pool.py
deleted file mode 100755
index e5855a30919a318877700a08e4bf97f96f4b2858..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/ipc/mysql_pool.py
+++ /dev/null
@@ -1,81 +0,0 @@
-"""\
-@file mysql_pool.py
-@brief Thin wrapper around eventlet.db_pool that chooses MySQLdb and Tpool.
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import MySQLdb
-from eventlet import db_pool
-
-class DatabaseConnector(db_pool.DatabaseConnector):
-    def __init__(self, credentials, *args, **kwargs):
-        super(DatabaseConnector, self).__init__(MySQLdb, credentials,
-                                                conn_pool=db_pool.ConnectionPool,
-                                                *args, **kwargs)
-
-    # get is extended relative to eventlet.db_pool to accept a port argument
-    def get(self, host, dbname, port=3306):
-        key = (host, dbname, port)
-        if key not in self._databases:
-            new_kwargs = self._kwargs.copy()
-            new_kwargs['db'] = dbname
-            new_kwargs['host'] = host
-            new_kwargs['port'] = port
-            new_kwargs.update(self.credentials_for(host))
-            dbpool = ConnectionPool(*self._args, **new_kwargs)
-            self._databases[key] = dbpool
-
-        return self._databases[key]
-
-class ConnectionPool(db_pool.TpooledConnectionPool):
-    """A pool which gives out saranwrapped MySQLdb connections from a pool
-    """
-
-    def __init__(self, *args, **kwargs):
-        super(ConnectionPool, self).__init__(MySQLdb, *args, **kwargs)
-
-    def get(self):
-        conn = super(ConnectionPool, self).get()
-        # annotate the connection object with the details on the
-        # connection; this is used elsewhere to check that you haven't
-        # suddenly changed databases in midstream while making a
-        # series of queries on a connection.
-        arg_names = ['host','user','passwd','db','port','unix_socket','conv','connect_timeout',
-         'compress', 'named_pipe', 'init_command', 'read_default_file', 'read_default_group',
-         'cursorclass', 'use_unicode', 'charset', 'sql_mode', 'client_flag', 'ssl',
-         'local_infile']
-        # you could have constructed this connectionpool with a mix of
-        # keyword and non-keyword arguments, but we want to annotate
-        # the connection object with a dict so it's easy to check
-        # against so here we are converting the list of non-keyword
-        # arguments (in self._args) into a dict of keyword arguments,
-        # and merging that with the actual keyword arguments
-        # (self._kwargs).  The arg_names variable lists the
-        # constructor arguments for MySQLdb Connection objects.
-        converted_kwargs = dict([ (arg_names[i], arg) for i, arg in enumerate(self._args) ])
-        converted_kwargs.update(self._kwargs)
-        conn.connection_parameters = converted_kwargs
-        return conn
-
diff --git a/indra/lib/python/indra/ipc/russ.py b/indra/lib/python/indra/ipc/russ.py
deleted file mode 100755
index ac780f128b6c68ecd5d5ead15632f0c55a11c45b..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/ipc/russ.py
+++ /dev/null
@@ -1,165 +0,0 @@
-"""\
-@file russ.py
-@brief Recursive URL Substitution Syntax helpers
-@author Phoenix
-
-Many details on how this should work is available on the wiki:
-https://wiki.secondlife.com/wiki/Recursive_URL_Substitution_Syntax
-
-Adding features to this should be reflected in that page in the
-implementations section.
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import urllib
-from indra.ipc import llsdhttp
-
-class UnbalancedBraces(Exception):
-    pass
-
-class UnknownDirective(Exception):
-    pass
-
-class BadDirective(Exception):
-    pass
-
-def format_value_for_path(value):
-    if type(value) in [list, tuple]:
-        # *NOTE: treat lists as unquoted path components so that the quoting
-        # doesn't get out-of-hand.  This is a workaround for the fact that
-        # russ always quotes, even if the data it's given is already quoted,
-        # and it's not safe to simply unquote a path directly, so if we want
-        # russ to substitute urls parts inside other url parts we always
-        # have to do so via lists of unquoted path components.
-        return '/'.join([urllib.quote(str(item)) for item in value])
-    else:
-        return urllib.quote(str(value))
-
-def format(format_str, context):
-    """@brief Format format string according to rules for RUSS.
-@see https://osiris.lindenlab.com/mediawiki/index.php/Recursive_URL_Substitution_Syntax
-@param format_str The input string to format.
-@param context A map used for string substitutions.
-@return Returns the formatted string. If no match, the braces remain intact.
-"""
-    while True:
-        #print "format_str:", format_str
-        all_matches = _find_sub_matches(format_str)
-        if not all_matches:
-            break
-        substitutions = 0
-        while True:
-            matches = all_matches.pop()
-            # we work from right to left to make sure we do not
-            # invalidate positions earlier in format_str
-            matches.reverse()
-            for pos in matches:
-                # Use index since _find_sub_matches should have raised
-                # an exception, and failure to find now is an exception.
-                end = format_str.index('}', pos)
-                #print "directive:", format_str[pos+1:pos+5]
-                if format_str[pos + 1] == '$':
-                    value = context[format_str[pos + 2:end]]
-                    if value is not None:
-                        value = format_value_for_path(value)
-                elif format_str[pos + 1] == '%':
-                    value = _build_query_string(
-                        context.get(format_str[pos + 2:end]))
-                elif format_str[pos+1:pos+5] == 'http' or format_str[pos+1:pos+5] == 'file':
-                    value = _fetch_url_directive(format_str[pos + 1:end])
-                else:
-                    raise UnknownDirective, format_str[pos:end + 1]
-                if value is not None:
-                    format_str = format_str[:pos]+str(value)+format_str[end+1:]
-                    substitutions += 1
-
-            # If there were any substitutions at this depth, re-parse
-            # since this may have revealed new things to substitute
-            if substitutions:
-                break
-            if not all_matches:
-                break
-
-        # If there were no substitutions at all, and we have exhausted
-        # the possible matches, bail.
-        if not substitutions:
-            break
-    return format_str
-
-def _find_sub_matches(format_str):
-    """@brief Find all of the substitution matches.
-@param format_str the RUSS conformant format string.    
-@return Returns an array of depths of arrays of positional matches in input.
-"""
-    depth = 0
-    matches = []
-    for pos in range(len(format_str)):
-        if format_str[pos] == '{':
-            depth += 1
-            if not len(matches) == depth:
-                matches.append([])
-            matches[depth - 1].append(pos)
-            continue
-        if format_str[pos] == '}':
-            depth -= 1
-            continue
-    if not depth == 0:
-        raise UnbalancedBraces, format_str
-    return matches
-
-def _build_query_string(query_dict):
-    """\
-    @breif given a dict, return a query string. utility wrapper for urllib.
-    @param query_dict input query dict
-    @returns Returns an urlencoded query string including leading '?'.
-    """
-    if query_dict:
-        keys = query_dict.keys()
-        keys.sort()
-        def stringize(value):
-            if type(value) in (str,unicode):
-                return value
-            else:
-                return str(value)
-        query_list = [urllib.quote(str(key)) + '=' + urllib.quote(stringize(query_dict[key])) for key in keys]
-        return '?' + '&'.join(query_list)
-    else:
-        return ''
-
-def _fetch_url_directive(directive):
-    "*FIX: This only supports GET"
-    commands = directive.split('|')
-    resource = llsdhttp.get(commands[0])
-    if len(commands) == 3:
-        resource = _walk_resource(resource, commands[2])
-    return resource
-
-def _walk_resource(resource, path):
-    path = path.split('/')
-    for child in path:
-        if not child:
-            continue
-        resource = resource[child]
-    return resource
diff --git a/indra/lib/python/indra/ipc/servicebuilder.py b/indra/lib/python/indra/ipc/servicebuilder.py
deleted file mode 100755
index 0a0ce2b4e2d45faecca4ef1447b1d4aa71ba280e..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/ipc/servicebuilder.py
+++ /dev/null
@@ -1,134 +0,0 @@
-"""\
-@file servicebuilder.py
-@author Phoenix
-@brief Class which will generate service urls.
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-from indra.base import config
-from indra.ipc import llsdhttp
-from indra.ipc import russ
-
-# *NOTE: agent presence relies on this variable existing and being current, it is a huge hack
-services_config = {}
-try:
-    services_config = llsdhttp.get(config.get('services-config'))
-except:
-    pass
-
-_g_builder = None
-def _builder():
-    global _g_builder
-    if _g_builder is None:
-        _g_builder = ServiceBuilder()
-    return _g_builder
-
-def build(name, context={}, **kwargs):
-    """ Convenience method for using a global, singleton, service builder.  Pass arguments either via a dict or via python keyword arguments, or both!
-
-    Example use:
-     > context = {'channel':'Second Life Release', 'version':'1.18.2.0'}
-     > servicebuilder.build('version-manager-version', context)
-       'http://int.util.vaak.lindenlab.com/channel/Second%20Life%20Release/1.18.2.0'
-     > servicebuilder.build('version-manager-version', channel='Second Life Release', version='1.18.2.0')
-       'http://int.util.vaak.lindenlab.com/channel/Second%20Life%20Release/1.18.2.0'
-     > servicebuilder.build('version-manager-version', context, version='1.18.1.2')
-       'http://int.util.vaak.lindenlab.com/channel/Second%20Life%20Release/1.18.1.2'
-    """
-    global _g_builder
-    if _g_builder is None:
-        _g_builder = ServiceBuilder()
-    return _g_builder.buildServiceURL(name, context, **kwargs)
-
-def build_path(name, context={}, **kwargs):
-    context = context.copy()  # shouldn't modify the caller's dictionary
-    context.update(kwargs)
-    return _builder().buildPath(name, context)
-
-class ServiceBuilder(object):
-    def __init__(self, services_definition = services_config):
-        """\
-        @brief
-        @brief Create a ServiceBuilder.
-        @param services_definition Complete services definition, services.xml.
-        """
-        # no need to keep a copy of the services section of the
-        # complete services definition, but it doesn't hurt much.
-        self.services = services_definition['services']
-        self.builders = {}
-        for service in self.services:
-            service_builder = service.get('service-builder')
-            if not service_builder:
-                continue
-            if isinstance(service_builder, dict):
-                # We will be constructing several builders
-                for name, builder in service_builder.iteritems():
-                    full_builder_name = service['name'] + '-' + name
-                    self.builders[full_builder_name] = builder
-            else:
-                self.builders[service['name']] = service_builder
-
-    def buildPath(self, name, context):
-        """\
-        @brief given the environment on construction, return a service path.
-        @param name The name of the service.
-        @param context A dict of name value lookups for the service.
-        @returns Returns the 
-        """
-        return russ.format(self.builders[name], context)
-
-    def buildServiceURL(self, name, context={}, **kwargs):
-        """\
-        @brief given the environment on construction, return a service URL.
-        @param name The name of the service.
-        @param context A dict of name value lookups for the service.
-        @param kwargs Any keyword arguments are treated as members of the
-            context, this allows you to be all 31337 by writing shit like:
-            servicebuilder.build('name', param=value)
-        @returns Returns the 
-        """
-        context = context.copy()  # shouldn't modify the caller's dictionary
-        context.update(kwargs)
-        base_url = config.get('services-base-url')
-        svc_path = russ.format(self.builders[name], context)
-        return base_url + svc_path
-
-
-def on_in(query_name, host_key, schema_key):
-    """\
-    @brief Constructs an on/in snippet (for running named queries)
-    from a schema name and two keys referencing values stored in
-    indra.xml.
-
-    @param query_name Name of the query.
-    @param host_key Logical name of destination host.  Will be
-        looked up in indra.xml.
-    @param schema_key Logical name of destination schema.  Will
-        be looked up in indra.xml.
-    """
-    return "on/config:%s/in/config:%s/%s" % (host_key.strip('/'),
-                                             schema_key.strip('/'),
-                                             query_name.lstrip('/'))
-
diff --git a/indra/lib/python/indra/ipc/siesta.py b/indra/lib/python/indra/ipc/siesta.py
deleted file mode 100755
index d867e715378b268ac365bada4b202b3a74d89ede..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/ipc/siesta.py
+++ /dev/null
@@ -1,468 +0,0 @@
-"""\
-@file siesta.py
-@brief A tiny llsd based RESTful web services framework
-
-$LicenseInfo:firstyear=2008&license=mit$
-
-Copyright (c) 2008, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-from indra.base import config
-from indra.base import llsd
-from webob import exc
-import webob
-import re, socket
-
-try:
-    from cStringIO import StringIO
-except ImportError:
-    from StringIO import StringIO
-
-try:
-    import cjson
-    json_decode = cjson.decode
-    json_encode = cjson.encode
-    JsonDecodeError = cjson.DecodeError
-    JsonEncodeError = cjson.EncodeError
-except ImportError:
-    import simplejson
-    json_decode = simplejson.loads
-    json_encode = simplejson.dumps
-    JsonDecodeError = ValueError
-    JsonEncodeError = TypeError
-
-
-llsd_parsers = {
-    'application/json': json_decode,
-    llsd.BINARY_MIME_TYPE: llsd.parse_binary,
-    'application/llsd+notation': llsd.parse_notation,
-    llsd.XML_MIME_TYPE: llsd.parse_xml,
-    'application/xml': llsd.parse_xml,
-    }
-
-
-def mime_type(content_type):
-    '''Given a Content-Type header, return only the MIME type.'''
-
-    return content_type.split(';', 1)[0].strip().lower()
-    
-class BodyLLSD(object):
-    '''Give a webob Request or Response an llsd based "content" property.
-
-    Getting the content property parses the body, and caches the result.
-
-    Setting the content property formats a payload, and the body property
-    is set.'''
-
-    def _llsd__get(self):
-        '''Get, set, or delete the LLSD value stored in this object.'''
-
-        try:
-            return self._llsd
-        except AttributeError:
-            if not self.body:
-                raise AttributeError('No llsd attribute has been set')
-            else:
-                mtype = mime_type(self.content_type)
-                try:
-                    parser = llsd_parsers[mtype]
-                except KeyError:
-                    raise exc.HTTPUnsupportedMediaType(
-                        'Content type %s not supported' % mtype).exception
-                try:
-                    self._llsd = parser(self.body)
-                except (llsd.LLSDParseError, JsonDecodeError, TypeError), err:
-                    raise exc.HTTPBadRequest(
-                        'Could not parse body: %r' % err.args).exception
-            return self._llsd
-
-    def _llsd__set(self, val):
-        req = getattr(self, 'request', None)
-        if req is not None:
-            formatter, ctype = formatter_for_request(req)
-            self.content_type = ctype
-        else:
-            formatter, ctype = formatter_for_mime_type(
-                mime_type(self.content_type))
-        self.body = formatter(val)
-
-    def _llsd__del(self):
-        if hasattr(self, '_llsd'):
-            del self._llsd
-
-    content = property(_llsd__get, _llsd__set, _llsd__del)
-
-
-class Response(webob.Response, BodyLLSD):
-    '''Response class with LLSD support.
-
-    A sensible default content type is used.
-
-    Setting the llsd property also sets the body.  Getting the llsd
-    property parses the body if necessary.
-
-    If you set the body property directly, the llsd property will be
-    deleted.'''
-
-    default_content_type = 'application/llsd+xml'
-
-    def _body__set(self, body):
-        if hasattr(self, '_llsd'):
-            del self._llsd
-        super(Response, self)._body__set(body)
-
-    def cache_forever(self):
-        self.cache_expires(86400 * 365)
-
-    body = property(webob.Response._body__get, _body__set,
-                    webob.Response._body__del,
-                    webob.Response._body__get.__doc__)
-
-
-class Request(webob.Request, BodyLLSD):
-    '''Request class with LLSD support.
-
-    Sensible content type and accept headers are used by default.
-
-    Setting the content property also sets the body. Getting the content
-    property parses the body if necessary.
-
-    If you set the body property directly, the content property will be
-    deleted.'''
-    
-    default_content_type = 'application/llsd+xml'
-    default_accept = ('application/llsd+xml; q=0.5, '
-                      'application/llsd+notation; q=0.3, '
-                      'application/llsd+binary; q=0.2, '
-                      'application/xml; q=0.1, '
-                      'application/json; q=0.0')
-
-    def __init__(self, environ=None, *args, **kwargs):
-        if environ is None:
-            environ = {}
-        else:
-            environ = environ.copy()
-        if 'CONTENT_TYPE' not in environ:
-            environ['CONTENT_TYPE'] = self.default_content_type
-        if 'HTTP_ACCEPT' not in environ:
-            environ['HTTP_ACCEPT'] = self.default_accept
-        super(Request, self).__init__(environ, *args, **kwargs)
-
-    def _body__set(self, body):
-        if hasattr(self, '_llsd'):
-            del self._llsd
-        super(Request, self)._body__set(body)
-
-    def path_urljoin(self, *parts):
-        return '/'.join([path_url.rstrip('/')] + list(parts))
-
-    body = property(webob.Request._body__get, _body__set,
-                    webob.Request._body__del, webob.Request._body__get.__doc__)
-
-    def create_response(self, content=None, status='200 OK',
-                        conditional_response=webob.NoDefault):
-        resp = self.ResponseClass(status=status, request=self,
-                                  conditional_response=conditional_response)
-        resp.content = content
-        return resp
-
-    def curl(self):
-        '''Create and fill out a pycurl easy object from this request.'''
- 
-        import pycurl
-        c = pycurl.Curl()
-        c.setopt(pycurl.URL, self.url())
-        if self.headers:
-            c.setopt(pycurl.HTTPHEADER,
-                     ['%s: %s' % (k, self.headers[k]) for k in self.headers])
-        c.setopt(pycurl.FOLLOWLOCATION, True)
-        c.setopt(pycurl.AUTOREFERER, True)
-        c.setopt(pycurl.MAXREDIRS, 16)
-        c.setopt(pycurl.NOSIGNAL, True)
-        c.setopt(pycurl.READFUNCTION, self.body_file.read)
-        c.setopt(pycurl.SSL_VERIFYHOST, 2)
-        
-        if self.method == 'POST':
-            c.setopt(pycurl.POST, True)
-            post301 = getattr(pycurl, 'POST301', None)
-            if post301 is not None:
-                # Added in libcurl 7.17.1.
-                c.setopt(post301, True)
-        elif self.method == 'PUT':
-            c.setopt(pycurl.PUT, True)
-        elif self.method != 'GET':
-            c.setopt(pycurl.CUSTOMREQUEST, self.method)
-        return c
-
-Request.ResponseClass = Response
-Response.RequestClass = Request
-
-
-llsd_formatters = {
-    'application/json': json_encode,
-    'application/llsd+binary': llsd.format_binary,
-    'application/llsd+notation': llsd.format_notation,
-    'application/llsd+xml': llsd.format_xml,
-    'application/xml': llsd.format_xml,
-    }
-
-formatter_qualities = (
-    ('application/llsd+xml', 1.0),
-    ('application/llsd+notation', 0.5),
-    ('application/llsd+binary', 0.4),
-    ('application/xml', 0.3),
-    ('application/json', 0.2),
-    )
-
-def formatter_for_mime_type(mime_type):
-    '''Return a formatter that encodes to the given MIME type.
-
-    The result is a pair of function and MIME type.'''
-    try:
-        return llsd_formatters[mime_type], mime_type
-    except KeyError:
-        raise exc.HTTPInternalServerError(
-            'Could not use MIME type %r to format response' %
-            mime_type).exception
-
-
-def formatter_for_request(req):
-    '''Return a formatter that encodes to the preferred type of the client.
-
-    The result is a pair of function and actual MIME type.'''
-    ctype = req.accept.best_match(formatter_qualities)
-    try:
-        return llsd_formatters[ctype], ctype
-    except KeyError:
-        raise exc.HTTPNotAcceptable().exception
-
-
-def wsgi_adapter(func, environ, start_response):
-    '''Adapt a Siesta callable to act as a WSGI application.'''
-    # Process the request as appropriate.
-    try:
-        req = Request(environ)
-        #print req.urlvars
-        resp = func(req, **req.urlvars)
-        if not isinstance(resp, webob.Response):
-            try:
-                formatter, ctype = formatter_for_request(req)
-                resp = req.ResponseClass(formatter(resp), content_type=ctype)
-                resp._llsd = resp
-            except (JsonEncodeError, TypeError), err:
-                resp = exc.HTTPInternalServerError(
-                    detail='Could not format response')
-    except exc.HTTPException, e:
-        resp = e
-    except socket.error, e:
-        resp = exc.HTTPInternalServerError(detail=e.args[1])
-    return resp(environ, start_response)
-
-
-def llsd_callable(func):
-    '''Turn a callable into a Siesta application.'''
-
-    def replacement(environ, start_response):
-        return wsgi_adapter(func, environ, start_response)
-
-    return replacement
-
-
-def llsd_method(http_method, func):
-    def replacement(environ, start_response):
-        if environ['REQUEST_METHOD'] == http_method:
-            return wsgi_adapter(func, environ, start_response)
-        return exc.HTTPMethodNotAllowed()(environ, start_response)
-
-    return replacement
-
-
-http11_methods = 'OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT'.split()
-http11_methods.sort()
-
-def llsd_class(cls):
-    '''Turn a class into a Siesta application.
-
-    A new instance is created for each request.  A HTTP method FOO is
-    turned into a call to the handle_foo method of the instance.'''
-
-    def foo(req, **kwargs):
-        instance = cls()
-        method = req.method.lower()
-        try:
-            handler = getattr(instance, 'handle_' + method)
-        except AttributeError:
-            allowed = [m for m in http11_methods
-                       if hasattr(instance, 'handle_' + m.lower())]
-            raise exc.HTTPMethodNotAllowed(
-                headers={'Allow': ', '.join(allowed)}).exception
-        #print "kwargs: ", kwargs
-        return handler(req, **kwargs)
-
-    def replacement(environ, start_response):
-        return wsgi_adapter(foo, environ, start_response)
-
-    return replacement
-
-
-def curl(reqs):
-    import pycurl
-
-    m = pycurl.CurlMulti()
-    curls = [r.curl() for r in reqs]
-    io = {}
-    for c in curls:
-        fp = StringIO()
-        hdr = StringIO()
-        c.setopt(pycurl.WRITEFUNCTION, fp.write)
-        c.setopt(pycurl.HEADERFUNCTION, hdr.write)
-        io[id(c)] = fp, hdr
-    m.handles = curls
-    try:
-        while True:
-            ret, num_handles = m.perform()
-            if ret != pycurl.E_CALL_MULTI_PERFORM:
-                break
-    finally:
-        m.close()
-
-    for req, c in zip(reqs, curls):
-        fp, hdr = io[id(c)]
-        hdr.seek(0)
-        status = hdr.readline().rstrip()
-        headers = []
-        name, values = None, None
-
-        # XXX We don't currently handle bogus header data.
-
-        for line in hdr.readlines():
-            if not line[0].isspace():
-                if name:
-                    headers.append((name, ' '.join(values)))
-                name, value = line.strip().split(':', 1)
-                value = [value]
-            else:
-                values.append(line.strip())
-        if name:
-            headers.append((name, ' '.join(values)))
-
-        resp = c.ResponseClass(fp.getvalue(), status, headers, request=req)
-
-
-route_re = re.compile(r'''
-    \{                 # exact character "{"
-    (\w*)              # "config" or variable (restricted to a-z, 0-9, _)
-    (?:([:~])([^}]+))? # optional :type or ~regex part
-    \}                 # exact character "}"
-    ''', re.VERBOSE)
-
-predefined_regexps = {
-    'uuid': r'[a-f0-9][a-f0-9-]{31,35}',
-    'int': r'\d+',
-    'host': r'[a-z0-9][a-z0-9\-\.]*',
-    }
-
-def compile_route(route):
-    fp = StringIO()
-    last_pos = 0
-    for match in route_re.finditer(route):
-        #print "matches: ", match.groups()
-        fp.write(re.escape(route[last_pos:match.start()]))
-        var_name = match.group(1)
-        sep = match.group(2)
-        expr = match.group(3)
-        if var_name == 'config':
-            expr = re.escape(str(config.get(var_name)))
-        else:
-            if expr:
-                if sep == ':':
-                    expr = predefined_regexps[expr]
-                # otherwise, treat what follows '~' as a regexp
-            else:
-                expr = '[^/]+'
-            if var_name != '':
-                expr = '(?P<%s>%s)' % (var_name, expr)
-            else:
-                expr = '(%s)' % (expr,)
-        fp.write(expr)
-        last_pos = match.end()
-    fp.write(re.escape(route[last_pos:]))
-    compiled_route = '^%s$' % fp.getvalue()
-    #print route, "->", compiled_route
-    return compiled_route
-
-class Router(object):
-    '''WSGI routing class.  Parses a URL and hands off a request to
-    some other WSGI application.  If no suitable application is found,
-    responds with a 404.'''
-
-    def __init__(self):
-        self._new_routes = []
-        self._routes = []
-        self._paths = []
-
-    def add(self, route, app, methods=None):
-        self._new_routes.append((route, app, methods))
-
-    def _create_routes(self):
-        for route, app, methods in self._new_routes:
-            self._paths.append(route)
-            self._routes.append(
-                (re.compile(compile_route(route)),
-                 app,
-                 methods and dict.fromkeys(methods)))
-        self._new_routes = []
-
-    def __call__(self, environ, start_response):
-        # load up the config from the config file. Only needs to be
-        # done once per interpreter. This is the entry point of all
-        # siesta applications, so this is where we trap it.
-        _conf = config.get_config()
-        if _conf is None:
-            import os.path
-            fname = os.path.join(
-                environ.get('ll.config_dir', '/local/linden/etc'),
-                'indra.xml')
-            config.load(fname)
-
-        # proceed with handling the request
-        self._create_routes()
-        path_info = environ['PATH_INFO']
-        request_method = environ['REQUEST_METHOD']
-        allowed = []
-        for regex, app, methods in self._routes:
-            m = regex.match(path_info)
-            if m:
-                #print "groupdict:",m.groupdict()
-                if not methods or request_method in methods:
-                    environ['paste.urlvars'] = m.groupdict()
-                    return app(environ, start_response)
-                else:
-                    allowed += methods
-        if allowed:
-            allowed = dict.fromkeys(allows).keys()
-            allowed.sort()
-            resp = exc.HTTPMethodNotAllowed(
-                headers={'Allow': ', '.join(allowed)})
-        else:
-            resp = exc.HTTPNotFound()
-        return resp(environ, start_response)
diff --git a/indra/lib/python/indra/ipc/siesta_test.py b/indra/lib/python/indra/ipc/siesta_test.py
deleted file mode 100755
index a35eed24604316c097302ecd83785b2abe384d1b..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/ipc/siesta_test.py
+++ /dev/null
@@ -1,235 +0,0 @@
-#!/usr/bin/python
-## $LicenseInfo:firstyear=2011&license=viewerlgpl$
-## Second Life Viewer Source Code
-## Copyright (C) 2011, Linden Research, Inc.
-## 
-## This library is free software; you can redistribute it and/or
-## modify it under the terms of the GNU Lesser General Public
-## License as published by the Free Software Foundation;
-## version 2.1 of the License only.
-## 
-## This library is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## Lesser General Public License for more details.
-## 
-## You should have received a copy of the GNU Lesser General Public
-## License along with this library; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-## 
-## Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-## $/LicenseInfo$
-from indra.base import llsd, lluuid
-from indra.ipc import siesta
-import datetime, math, unittest
-from webob import exc
-
-
-class ClassApp(object):
-    def handle_get(self, req):
-        pass
-
-    def handle_post(self, req):
-        return req.llsd
-    
-
-def callable_app(req):
-    if req.method == 'UNDERPANTS':
-        raise exc.HTTPMethodNotAllowed()
-    elif req.method == 'GET':
-        return None
-    return req.llsd
-
-
-class TestBase:
-    def test_basic_get(self):
-        req = siesta.Request.blank('/')
-        self.assertEquals(req.get_response(self.server).body,
-                          llsd.format_xml(None))
-        
-    def test_bad_method(self):
-        req = siesta.Request.blank('/')
-        req.environ['REQUEST_METHOD'] = 'UNDERPANTS'
-        self.assertEquals(req.get_response(self.server).status_int,
-                          exc.HTTPMethodNotAllowed.code)
-        
-    json_safe = {
-        'none': None,
-        'bool_true': True,
-        'bool_false': False,
-        'int_zero': 0,
-        'int_max': 2147483647,
-        'int_min': -2147483648,
-        'long_zero': 0,
-        'long_max': 2147483647L,
-        'long_min': -2147483648L,
-        'float_zero': 0,
-        'float': math.pi,
-        'float_huge': 3.14159265358979323846e299,
-        'str_empty': '',
-        'str': 'foo',
-        u'unic\u1e51de_empty': u'',
-        u'unic\u1e51de': u'\u1e4exx\u10480',
-        }
-    json_safe['array'] = json_safe.values()
-    json_safe['tuple'] = tuple(json_safe.values())
-    json_safe['dict'] = json_safe.copy()
-
-    json_unsafe = {
-        'uuid_empty': lluuid.UUID(),
-        'uuid_full': lluuid.UUID('dc61ab0530200d7554d23510559102c1a98aab1b'),
-        'binary_empty': llsd.binary(),
-        'binary': llsd.binary('f\0\xff'),
-        'uri_empty': llsd.uri(),
-        'uri': llsd.uri('http://www.secondlife.com/'),
-        'datetime_empty': datetime.datetime(1970,1,1),
-        'datetime': datetime.datetime(1999,9,9,9,9,9),
-        }
-    json_unsafe.update(json_safe)
-    json_unsafe['array'] = json_unsafe.values()
-    json_unsafe['tuple'] = tuple(json_unsafe.values())
-    json_unsafe['dict'] = json_unsafe.copy()
-    json_unsafe['iter'] = iter(json_unsafe.values())
-
-    def _test_client_content_type_good(self, content_type, ll):
-        def run(ll):
-            req = siesta.Request.blank('/')
-            req.environ['REQUEST_METHOD'] = 'POST'
-            req.content_type = content_type
-            req.llsd = ll
-            req.accept = content_type
-            resp = req.get_response(self.server)
-            self.assertEquals(resp.status_int, 200)
-            return req, resp
-        
-        if False and isinstance(ll, dict):
-            def fixup(v):
-                if isinstance(v, float):
-                    return '%.5f' % v
-                if isinstance(v, long):
-                    return int(v)
-                if isinstance(v, (llsd.binary, llsd.uri)):
-                    return v
-                if isinstance(v, (tuple, list)):
-                    return [fixup(i) for i in v]
-                if isinstance(v, dict):
-                    return dict([(k, fixup(i)) for k, i in v.iteritems()])
-                return v
-            for k, v in ll.iteritems():
-                l = [k, v]
-                req, resp = run(l)
-                self.assertEquals(fixup(resp.llsd), fixup(l))
-
-        run(ll)
-
-    def test_client_content_type_json_good(self):
-        self._test_client_content_type_good('application/json', self.json_safe)
-
-    def test_client_content_type_llsd_xml_good(self):
-        self._test_client_content_type_good('application/llsd+xml',
-                                            self.json_unsafe)
-
-    def test_client_content_type_llsd_notation_good(self):
-        self._test_client_content_type_good('application/llsd+notation',
-                                            self.json_unsafe)
-
-    def test_client_content_type_llsd_binary_good(self):
-        self._test_client_content_type_good('application/llsd+binary',
-                                            self.json_unsafe)
-
-    def test_client_content_type_xml_good(self):
-        self._test_client_content_type_good('application/xml',
-                                            self.json_unsafe)
-
-    def _test_client_content_type_bad(self, content_type):
-        req = siesta.Request.blank('/')
-        req.environ['REQUEST_METHOD'] = 'POST'
-        req.body = '\0invalid nonsense under all encodings'
-        req.content_type = content_type
-        self.assertEquals(req.get_response(self.server).status_int,
-                          exc.HTTPBadRequest.code)
-        
-    def test_client_content_type_json_bad(self):
-        self._test_client_content_type_bad('application/json')
-
-    def test_client_content_type_llsd_xml_bad(self):
-        self._test_client_content_type_bad('application/llsd+xml')
-
-    def test_client_content_type_llsd_notation_bad(self):
-        self._test_client_content_type_bad('application/llsd+notation')
-
-    def test_client_content_type_llsd_binary_bad(self):
-        self._test_client_content_type_bad('application/llsd+binary')
-
-    def test_client_content_type_xml_bad(self):
-        self._test_client_content_type_bad('application/xml')
-
-    def test_client_content_type_bad(self):
-        req = siesta.Request.blank('/')
-        req.environ['REQUEST_METHOD'] = 'POST'
-        req.body = 'XXX'
-        req.content_type = 'application/nonsense'
-        self.assertEquals(req.get_response(self.server).status_int,
-                          exc.HTTPUnsupportedMediaType.code)
-
-    def test_request_default_content_type(self):
-        req = siesta.Request.blank('/')
-        self.assertEquals(req.content_type, req.default_content_type)
-
-    def test_request_default_accept(self):
-        req = siesta.Request.blank('/')
-        from webob import acceptparse
-        self.assertEquals(str(req.accept).replace(' ', ''),
-                          req.default_accept.replace(' ', ''))
-
-    def test_request_llsd_auto_body(self):
-        req = siesta.Request.blank('/')
-        req.llsd = {'a': 2}
-        self.assertEquals(req.body, '<?xml version="1.0" ?><llsd><map>'
-                          '<key>a</key><integer>2</integer></map></llsd>')
-
-    def test_request_llsd_mod_body_changes_llsd(self):
-        req = siesta.Request.blank('/')
-        req.llsd = {'a': 2}
-        req.body = '<?xml version="1.0" ?><llsd><integer>1337</integer></llsd>'
-        self.assertEquals(req.llsd, 1337)
-
-    def test_request_bad_llsd_fails(self):
-        def crashme(ctype):
-            def boom():
-                class foo(object): pass
-                req = siesta.Request.blank('/')
-                req.content_type = ctype
-                req.llsd = foo()
-        for mime_type in siesta.llsd_parsers:
-            self.assertRaises(TypeError, crashme(mime_type))
-
-
-class ClassServer(TestBase, unittest.TestCase):
-    def __init__(self, *args, **kwargs):
-        unittest.TestCase.__init__(self, *args, **kwargs)
-        self.server = siesta.llsd_class(ClassApp)
-
-
-class CallableServer(TestBase, unittest.TestCase):
-    def __init__(self, *args, **kwargs):
-        unittest.TestCase.__init__(self, *args, **kwargs)
-        self.server = siesta.llsd_callable(callable_app)
-
-
-class RouterServer(unittest.TestCase):
-    def test_router(self):
-        def foo(req, quux):
-            print quux
-
-        r = siesta.Router()
-        r.add('/foo/{quux:int}', siesta.llsd_callable(foo), methods=['GET'])
-        req = siesta.Request.blank('/foo/33')
-        req.get_response(r)
-
-        req = siesta.Request.blank('/foo/bar')
-        self.assertEquals(req.get_response(r).status_int,
-                          exc.HTTPNotFound.code)
-    
-if __name__ == '__main__':
-    unittest.main()
diff --git a/indra/lib/python/indra/ipc/webdav.py b/indra/lib/python/indra/ipc/webdav.py
deleted file mode 100755
index 98b8499b6acd52d6cf68bc7c0655af9940869e66..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/ipc/webdav.py
+++ /dev/null
@@ -1,597 +0,0 @@
-"""
-@file webdav.py
-@brief Classes to make manipulation of a webdav store easier.
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import sys, os, httplib, urlparse
-import socket, time
-import xml.dom.minidom
-import syslog
-# import signal
-
-__revision__ = '0'
-
-dav_debug = False
-
-
-# def urlsafe_b64decode (enc):
-#     return base64.decodestring (enc.replace ('_', '/').replace ('-', '+'))
-
-# def urlsafe_b64encode (str):
-#     return base64.encodestring (str).replace ('+', '-').replace ('/', '_')
-
-
-class DAVError (Exception):
-    """ Base class for exceptions in this module. """
-    def __init__ (self, status=0, message='', body='', details=''):
-        self.status = status
-        self.message = message
-        self.body = body
-        self.details = details
-        Exception.__init__ (self, '%d:%s:%s%s' % (self.status, self.message,
-                                                   self.body, self.details))
-
-    def print_to_stderr (self):
-        """ print_to_stderr docstring """
-        print >> sys.stderr, str (self.status) + ' ' + self.message
-        print >> sys.stderr, str (self.details)
-
-
-class Timeout (Exception):
-    """ Timeout docstring """
-    def __init__ (self, arg=''):
-        Exception.__init__ (self, arg)
-
-
-def alarm_handler (signum, frame):
-    """ alarm_handler docstring """
-    raise Timeout ('caught alarm')
-
-
-class WebDAV:
-    """ WebDAV docstring """
-    def __init__ (self, url, proxy=None, retries_before_fail=6):
-        self.init_url = url
-        self.init_proxy = proxy
-        self.retries_before_fail = retries_before_fail
-        url_parsed = urlparse.urlsplit (url)
-
-        self.top_path = url_parsed[ 2 ]
-        # make sure top_path has a trailing /
-        if self.top_path == None or self.top_path == '':
-            self.top_path = '/'
-        elif len (self.top_path) > 1 and self.top_path[-1:] != '/':
-            self.top_path += '/'
-
-        if dav_debug:
-            syslog.syslog ('new WebDAV %s : %s' % (str (url), str (proxy)))
-
-        if proxy:
-            proxy_parsed = urlparse.urlsplit (proxy)
-            self.host_header = url_parsed[ 1 ]
-            host_and_port = proxy_parsed[ 1 ].split (':')
-            self.host = host_and_port[ 0 ]
-            if len (host_and_port) > 1:
-                self.port = int(host_and_port[ 1 ])
-            else:
-                self.port = 80
-        else: # no proxy
-            host_and_port = url_parsed[ 1 ].split (':')
-            self.host_header = None
-            self.host = host_and_port[ 0 ]
-            if len (host_and_port) > 1:
-                self.port = int(host_and_port[ 1 ])
-            else:
-                self.port = 80
-
-        self.connection = False
-        self.connect ()
-
-
-    def log (self, msg, depth=0):
-        """ log docstring """
-        if dav_debug and depth == 0:
-            host = str (self.init_url)
-            if host == 'http://int.tuco.lindenlab.com:80/asset/':
-                host = 'tuco'
-            if host == 'http://harriet.lindenlab.com/asset-keep/':
-                host = 'harriet/asset-keep'
-            if host == 'http://harriet.lindenlab.com/asset-flag/':
-                host = 'harriet/asset-flag'
-            if host == 'http://harriet.lindenlab.com/asset/':
-                host = 'harriet/asset'
-            if host == 'http://ozzy.lindenlab.com/asset/':
-                host = 'ozzy/asset'
-            if host == 'http://station11.lindenlab.com:12041/:':
-                host = 'station11:12041'
-            proxy = str (self.init_proxy)
-            if proxy == 'None':
-                proxy = ''
-            if proxy == 'http://int.tuco.lindenlab.com:3128/':
-                proxy = 'tuco'
-            syslog.syslog ('WebDAV (%s:%s) %s' % (host, proxy, str (msg)))
-
-
-    def connect (self):
-        """ connect docstring """
-        self.log ('connect')
-        self.connection = httplib.HTTPConnection (self.host, self.port)
-
-    def __err (self, response, details):
-        """ __err docstring """
-        raise DAVError (response.status, response.reason, response.read (),
-                        str (self.init_url) + ':' + \
-                        str (self.init_proxy) + ':' + str (details))
-
-    def request (self, method, path, body=None, headers=None,
-                 read_all=True, body_hook = None, recurse=0, allow_cache=True):
-        """ request docstring """
-        # self.log ('request %s %s' % (method, path))
-        if headers == None:
-            headers = {}
-        if not allow_cache:
-            headers['Pragma'] = 'no-cache'
-            headers['cache-control'] = 'no-cache'
-        try:
-            if method.lower () != 'purge':
-                if path.startswith ('/'):
-                    path = path[1:]
-                if self.host_header: # use proxy
-                    headers[ 'host' ] = self.host_header
-                    fullpath = 'http://%s%s%s' % (self.host_header,
-                                                  self.top_path, path)
-                else: # no proxy
-                    fullpath = self.top_path + path
-            else:
-                fullpath = path
-
-            self.connection.request (method, fullpath, body, headers)
-            if body_hook:
-                body_hook ()
-
-            # signal.signal (signal.SIGALRM, alarm_handler)
-            # try:
-            #     signal.alarm (120)
-            #     signal.alarm (0)
-            # except Timeout, e:
-            #     if recurse < 6:
-            #         return self.retry_request (method, path, body, headers,
-            #                                    read_all, body_hook, recurse)
-            #     else:
-            #         raise DAVError (0, 'timeout', self.host,
-            #                         (method, path, body, headers, recurse))
-
-            response = self.connection.getresponse ()
-
-            if read_all:
-                while len (response.read (1024)) > 0:
-                    pass
-            if (response.status == 500 or \
-                response.status == 503 or \
-                response.status == 403) and \
-                recurse < self.retries_before_fail:
-                return self.retry_request (method, path, body, headers,
-                                           read_all, body_hook, recurse)
-            return response
-        except (httplib.ResponseNotReady,
-                httplib.BadStatusLine,
-                socket.error):
-            # if the server hangs up on us (keepalive off, broken pipe),
-            # we need to reconnect and try again.
-            if recurse < self.retries_before_fail:
-                return self.retry_request (method, path, body, headers,
-                                           read_all, body_hook, recurse)
-            raise DAVError (0, 'reconnect failed', self.host,
-                            (method, path, body, headers, recurse))
-
-
-    def retry_request (self, method, path, body, headers,
-                       read_all, body_hook, recurse):
-        """ retry_request docstring """
-        time.sleep (10.0 * recurse)
-        self.connect ()
-        return self.request (method, path, body, headers,
-                             read_all, body_hook, recurse+1)
-
-
-
-    def propfind (self, path, body=None, depth=1):
-        """ propfind docstring """
-        # self.log ('propfind %s' % path)
-        headers = {'Content-Type':'text/xml; charset="utf-8"',
-                   'Depth':str(depth)}
-        response = self.request ('PROPFIND', path, body, headers, False)
-        if response.status == 207:
-            return response # Multi-Status
-        self.__err (response, ('PROPFIND', path, body, headers, 0))
-
-
-    def purge (self, path):
-        """ issue a squid purge command """
-        headers = {'Accept':'*/*'}
-        response = self.request ('PURGE', path, None, headers)
-        if response.status == 200 or response.status == 404:
-            # 200 if it was purge, 404 if it wasn't there.
-            return response
-        self.__err (response, ('PURGE', path, None, headers))
-
-
-    def get_file_size (self, path):
-        """
-        Use propfind to ask a webdav server what the size of
-        a file is.  If used on a directory (collection) return 0
-        """
-        self.log ('get_file_size %s' % path)
-        # "getcontentlength" property
-        # 8.1.1 Example - Retrieving Named Properties
-        # http://docs.python.org/lib/module-xml.dom.html
-        nsurl = 'http://apache.org/dav/props/'
-        doc = xml.dom.minidom.Document ()
-        propfind_element = doc.createElementNS (nsurl, "D:propfind")
-        propfind_element.setAttributeNS (nsurl, 'xmlns:D', 'DAV:')
-        doc.appendChild (propfind_element)
-        prop_element = doc.createElementNS (nsurl, "D:prop")
-        propfind_element.appendChild (prop_element)
-        con_len_element = doc.createElementNS (nsurl, "D:getcontentlength")
-        prop_element.appendChild (con_len_element)
-
-        response = self.propfind (path, doc.toxml ())
-        doc.unlink ()
-
-        resp_doc = xml.dom.minidom.parseString (response.read ())
-        cln = resp_doc.getElementsByTagNameNS ('DAV:','getcontentlength')[ 0 ]
-        try:
-            content_length = int (cln.childNodes[ 0 ].nodeValue)
-        except IndexError:
-            return 0
-        resp_doc.unlink ()
-        return content_length
-
-
-    def file_exists (self, path):
-        """
-        do an http head on the given file.  return True if it succeeds
-        """
-        self.log ('file_exists %s' % path)
-        expect_gzip = path.endswith ('.gz')
-        response = self.request ('HEAD', path)
-        got_gzip = response.getheader ('Content-Encoding', '').strip ()
-        if got_gzip.lower () == 'x-gzip' and expect_gzip == False:
-            # the asset server fakes us out if we ask for the non-gzipped
-            # version of an asset, but the server has the gzipped version.
-            return False
-        return response.status == 200
-
-
-    def mkdir (self, path):
-        """ mkdir docstring """
-        self.log ('mkdir %s' % path)
-        headers = {}
-        response = self.request ('MKCOL', path, None, headers)
-        if response.status == 201:
-            return # success
-        if response.status == 405:
-            return # directory already existed?
-        self.__err (response, ('MKCOL', path, None, headers, 0))
-
-
-    def delete (self, path):
-        """ delete docstring """
-        self.log ('delete %s' % path)
-        headers = {'Depth':'infinity'} # collections require infinity
-        response = self.request ('DELETE', path, None, headers)
-        if response.status == 204:
-            return # no content
-        if response.status == 404:
-            return # hmm
-        self.__err (response, ('DELETE', path, None, headers, 0))
-
-
-    def list_directory (self, path, dir_filter=None, allow_cache=True,
-                        minimum_cache_time=False):
-        """
-        Request an http directory listing and parse the filenames out of lines
-        like: '<LI><A HREF="X"> X</A>'. If a filter function is provided,
-        only return filenames that the filter returns True for.
-
-        This is sort of grody, but it seems faster than other ways of getting
-        this information from an isilon.
-        """
-        self.log ('list_directory %s' % path)
-
-        def try_match (lline, before, after):
-            """ try_match docstring """
-            try:
-                blen = len (before)
-                asset_start_index = lline.index (before)
-                asset_end_index = lline.index (after, asset_start_index + blen)
-                asset = line[ asset_start_index + blen : asset_end_index ]
-
-                if not dir_filter or dir_filter (asset):
-                    return [ asset ]
-                return []
-            except ValueError:
-                return []
-
-        if len (path) > 0 and path[-1:] != '/':
-            path += '/'
-
-        response = self.request ('GET', path, None, {}, False,
-                                 allow_cache=allow_cache)
-
-        if allow_cache and minimum_cache_time: # XXX
-            print response.getheader ('Date')
-            # s = "2005-12-06T12:13:14"
-            # from datetime import datetime
-            # from time import strptime
-            # datetime(*strptime(s, "%Y-%m-%dT%H:%M:%S")[0:6])
-            # datetime.datetime(2005, 12, 6, 12, 13, 14)
-
-        if response.status != 200:
-            self.__err (response, ('GET', path, None, {}, 0))
-        assets = []
-        for line in response.read ().split ('\n'):
-            lline = line.lower ()
-            if lline.find ("parent directory") == -1:
-                # isilon file
-                assets += try_match (lline, '<li><a href="', '"> ')
-                # apache dir
-                assets += try_match (lline, 'alt="[dir]"> <a href="', '/">')
-                # apache file
-                assets += try_match (lline, 'alt="[   ]"> <a href="', '">')
-        return assets
-
-
-    def __tmp_filename (self, path_and_file):
-        """ __tmp_filename docstring """
-        head, tail = os.path.split (path_and_file)
-        if head != '':
-            return head + '/.' + tail + '.' + str (os.getpid ())
-        else:
-            return head + '.' + tail + '.' + str (os.getpid ())
-
-
-    def __put__ (self, filesize, body_hook, remotefile):
-        """ __put__ docstring """
-        headers = {'Content-Length' : str (filesize)}
-        remotefile_tmp = self.__tmp_filename (remotefile)
-        response = self.request ('PUT', remotefile_tmp, None,
-                                 headers, True, body_hook)
-        if not response.status in (201, 204): # created, no content
-            self.__err (response, ('PUT', remotefile, None, headers, 0))
-        if filesize != self.get_file_size (remotefile_tmp):
-            try:
-                self.delete (remotefile_tmp)
-            except:
-                pass
-            raise DAVError (0, 'tmp upload error', remotefile_tmp)
-        # move the file to its final location
-        try:
-            self.rename (remotefile_tmp, remotefile)
-        except DAVError, exc:
-            if exc.status == 403: # try to clean up the tmp file
-                try:
-                    self.delete (remotefile_tmp)
-                except:
-                    pass
-            raise
-        if filesize != self.get_file_size (remotefile):
-            raise DAVError (0, 'file upload error', str (remotefile_tmp))
-
-
-    def put_string (self, strng, remotefile):
-        """ put_string docstring """
-        self.log ('put_string %d -> %s' % (len (strng), remotefile))
-        filesize = len (strng)
-        def body_hook ():
-            """ body_hook docstring """
-            self.connection.send (strng)
-        self.__put__ (filesize, body_hook, remotefile)
-
-
-    def put_file (self, localfile, remotefile):
-        """
-        Send a local file to a remote webdav store.  First, upload to
-        a temporary filename.  Next make sure the file is the size we
-        expected.  Next, move the file to its final location.  Next,
-        check the file size at the final location.
-        """
-        self.log ('put_file %s -> %s' % (localfile, remotefile))
-        filesize = os.path.getsize (localfile)
-        def body_hook ():
-            """ body_hook docstring """
-            handle = open (localfile)
-            while True:
-                data = handle.read (1300)
-                if len (data) == 0:
-                    break
-                self.connection.send (data)
-            handle.close ()
-        self.__put__ (filesize, body_hook, remotefile)
-
-
-    def create_empty_file (self, remotefile):
-        """ create an empty file """
-        self.log ('touch_file %s' % (remotefile))
-        headers = {'Content-Length' : '0'}
-        response = self.request ('PUT', remotefile, None, headers)
-        if not response.status in (201, 204): # created, no content
-            self.__err (response, ('PUT', remotefile, None, headers, 0))
-        if self.get_file_size (remotefile) != 0:
-            raise DAVError (0, 'file upload error', str (remotefile))
-
-
-    def __get_file_setup (self, remotefile, check_size=True):
-        """ __get_file_setup docstring """
-        if check_size:
-            remotesize = self.get_file_size (remotefile)
-        response = self.request ('GET', remotefile, None, {}, False)
-        if response.status != 200:
-            self.__err (response, ('GET', remotefile, None, {}, 0))
-        try:
-            content_length = int (response.getheader ("Content-Length"))
-        except TypeError:
-            content_length = None
-        if check_size:
-            if content_length != remotesize:
-                raise DAVError (0, 'file DL size error', remotefile)
-        return (response, content_length)
-
-
-    def __get_file_read (self, writehandle, response, content_length):
-        """ __get_file_read docstring """
-        if content_length != None:
-            so_far_length = 0
-            while so_far_length < content_length:
-                data = response.read (content_length - so_far_length)
-                if len (data) == 0:
-                    raise DAVError (0, 'short file download')
-                so_far_length += len (data)
-                writehandle.write (data)
-            while len (response.read ()) > 0:
-                pass
-        else:
-            while True:
-                data = response.read ()
-                if (len (data) < 1):
-                    break
-                writehandle.write (data)
-
-
-    def get_file (self, remotefile, localfile, check_size=True):
-        """
-        Get a remote file from a webdav server.  Download to a local
-        tmp file, then move into place.  Sanity check file sizes as
-        we go.
-        """
-        self.log ('get_file %s -> %s' % (remotefile, localfile))
-        (response, content_length) = \
-                   self.__get_file_setup (remotefile, check_size)
-        localfile_tmp = self.__tmp_filename (localfile)
-        handle = open (localfile_tmp, 'w')
-        self.__get_file_read (handle, response, content_length)
-        handle.close ()
-        if check_size:
-            if content_length != os.path.getsize (localfile_tmp):
-                raise DAVError (0, 'file DL size error',
-                                remotefile+','+localfile)
-        os.rename (localfile_tmp, localfile)
-
-
-    def get_file_as_string (self, remotefile, check_size=True):
-        """
-        download a file from a webdav server and return it as a string.
-        """
-        self.log ('get_file_as_string %s' % remotefile)
-        (response, content_length) = \
-                   self.__get_file_setup (remotefile, check_size)
-        # (tmp_handle, tmp_filename) = tempfile.mkstemp ()
-        tmp_handle = os.tmpfile ()
-        self.__get_file_read (tmp_handle, response, content_length)
-        tmp_handle.seek (0)
-        ret = tmp_handle.read ()
-        tmp_handle.close ()
-        # os.unlink (tmp_filename)
-        return ret
-
-
-    def get_post_as_string (self, remotefile, body):
-        """
-        Do an http POST, send body, get response and return it.
-        """
-        self.log ('get_post_as_string %s' % remotefile)
-        # headers = {'Content-Type':'application/x-www-form-urlencoded'}
-        headers = {'Content-Type':'text/xml; charset="utf-8"'}
-        # b64body = urlsafe_b64encode (asset_url)
-        response = self.request ('POST', remotefile, body, headers, False)
-        if response.status != 200:
-            self.__err (response, ('POST', remotefile, body, headers, 0))
-        try:
-            content_length = int (response.getheader ('Content-Length'))
-        except TypeError:
-            content_length = None
-        tmp_handle = os.tmpfile ()
-        self.__get_file_read (tmp_handle, response, content_length)
-        tmp_handle.seek (0)
-        ret = tmp_handle.read ()
-        tmp_handle.close ()
-        return ret
-
-
-    def __destination_command (self, verb, remotesrc, dstdav, remotedst):
-        """
-        self and dstdav should point to the same http server.
-        """
-        if len (remotedst) > 0 and remotedst[ 0 ] == '/':
-            remotedst = remotedst[1:]
-        headers = {'Destination': 'http://%s:%d%s%s' % (dstdav.host,
-                                                        dstdav.port,
-                                                        dstdav.top_path,
-                                                        remotedst)}
-        response = self.request (verb, remotesrc, None, headers)
-        if response.status == 201:
-            return # created
-        if response.status == 204:
-            return # no content
-        self.__err (response, (verb, remotesrc, None, headers, 0))
-
-
-    def rename (self, remotesrc, remotedst):
-        """ rename a file on a webdav server """
-        self.log ('rename %s -> %s' % (remotesrc, remotedst))
-        self.__destination_command ('MOVE', remotesrc, self, remotedst)
-    def xrename (self, remotesrc, dstdav, remotedst):
-        """ rename a file on a webdav server """
-        self.log ('xrename %s -> %s' % (remotesrc, remotedst))
-        self.__destination_command ('MOVE', remotesrc, dstdav, remotedst)
-
-
-    def copy (self, remotesrc, remotedst):
-        """ copy a file on a webdav server """
-        self.log ('copy %s -> %s' % (remotesrc, remotedst))
-        self.__destination_command ('COPY', remotesrc, self, remotedst)
-    def xcopy (self, remotesrc, dstdav, remotedst):
-        """ copy a file on a webdav server """
-        self.log ('xcopy %s -> %s' % (remotesrc, remotedst))
-        self.__destination_command ('COPY', remotesrc, dstdav, remotedst)
-
-
-def put_string (data, url):
-    """
-    upload string s to a url
-    """
-    url_parsed = urlparse.urlsplit (url)
-    dav = WebDAV ('%s://%s/' % (url_parsed[ 0 ], url_parsed[ 1 ]))
-    dav.put_string (data, url_parsed[ 2 ])
-
-
-def get_string (url, check_size=True):
-    """
-    return the contents of a url as a string
-    """
-    url_parsed = urlparse.urlsplit (url)
-    dav = WebDAV ('%s://%s/' % (url_parsed[ 0 ], url_parsed[ 1 ]))
-    return dav.get_file_as_string (url_parsed[ 2 ], check_size)
diff --git a/indra/lib/python/indra/ipc/xml_rpc.py b/indra/lib/python/indra/ipc/xml_rpc.py
deleted file mode 100755
index 47536c10c398a7986a7e009fc2ff53538d7d62fa..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/ipc/xml_rpc.py
+++ /dev/null
@@ -1,273 +0,0 @@
-"""\
-@file xml_rpc.py
-@brief An implementation of a parser/generator for the XML-RPC xml format.
-
-$LicenseInfo:firstyear=2006&license=mit$
-
-Copyright (c) 2006-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-
-from greenlet import greenlet
-
-from mulib import mu
-
-from xml.sax import handler
-from xml.sax import parseString
-
-
-# States
-class Expected(object):
-    def __init__(self, tag):
-        self.tag = tag
-
-    def __getattr__(self, name):
-        return type(self)(name)
-
-    def __repr__(self):
-        return '%s(%r)' % (
-            type(self).__name__, self.tag)
-
-
-class START(Expected):
-    pass
-
-
-class END(Expected):
-    pass
-
-
-class STR(object):
-    tag = ''
-
-
-START = START('')
-END = END('')
-
-
-class Malformed(Exception):
-    pass
-
-
-class XMLParser(handler.ContentHandler):
-    def __init__(self, state_machine, next_states):
-        handler.ContentHandler.__init__(self)
-        self.state_machine = state_machine
-        if not isinstance(next_states, tuple):
-            next_states = (next_states, )
-        self.next_states = next_states
-        self._character_buffer = ''
-
-    def assertState(self, state, name, *rest):
-        if not isinstance(self.next_states, tuple):
-            self.next_states = (self.next_states, )
-        for next in self.next_states:
-            if type(state) == type(next):
-                if next.tag and next.tag != name:
-                    raise Malformed(
-                        "Expected %s, got %s %s %s" % (
-                            next, state, name, rest))
-                break
-        else:
-            raise Malformed(
-                "Expected %s, got %s %s %s" % (
-                    self.next_states, state, name, rest))
-
-    def startElement(self, name, attrs):
-        self.assertState(START, name.lower(), attrs)
-        self.next_states = self.state_machine.switch(START, (name.lower(), dict(attrs)))
-
-    def endElement(self, name):
-        if self._character_buffer.strip():
-            characters = self._character_buffer.strip()
-            self._character_buffer = ''
-            self.assertState(STR, characters)
-            self.next_states = self.state_machine.switch(characters)
-        self.assertState(END, name.lower())
-        self.next_states = self.state_machine.switch(END, name.lower())
-
-    def error(self, exc):
-        self.bozo = 1
-        self.exc = exc
-
-    def fatalError(self, exc):
-        self.error(exc)
-        raise exc
-
-    def characters(self, characters):
-        self._character_buffer += characters
-
-
-def parse(what):
-    child = greenlet(xml_rpc)
-    me = greenlet.getcurrent()
-    startup_states = child.switch(me)
-    parser = XMLParser(child, startup_states)
-    try:
-        parseString(what, parser)
-    except Malformed:
-        print what
-        raise
-    return child.switch()
-
-
-def xml_rpc(yielder):
-    yielder.switch(START.methodcall)
-    yielder.switch(START.methodname)
-    methodName = yielder.switch(STR)
-    yielder.switch(END.methodname)
-
-    yielder.switch(START.params)
-
-    root = None
-    params = []
-    while True:
-        state, _ = yielder.switch(START.param, END.params)
-        if state == END:
-            break
-
-        yielder.switch(START.value)
-        
-        params.append(
-            handle(yielder))
-
-        yielder.switch(END.value)
-        yielder.switch(END.param)
-
-    yielder.switch(END.methodcall)
-    ## Resume parse
-    yielder.switch()
-    ## Return result to parse
-    return methodName.strip(), params
-
-
-def handle(yielder):
-    _, (tag, attrs) = yielder.switch(START)
-    if tag in ['int', 'i4']:
-        result = int(yielder.switch(STR))
-    elif tag == 'boolean':
-        result = bool(int(yielder.switch(STR)))
-    elif tag == 'string':
-        result = yielder.switch(STR)
-    elif tag == 'double':
-        result = float(yielder.switch(STR))
-    elif tag == 'datetime.iso8601':
-        result = yielder.switch(STR)
-    elif tag == 'base64':
-        result = base64.b64decode(yielder.switch(STR))
-    elif tag == 'struct':
-        result = {}
-        while True:
-            state, _ = yielder.switch(START.member, END.struct)
-            if state == END:
-                break
-
-            yielder.switch(START.name)
-            key = yielder.switch(STR)
-            yielder.switch(END.name)
-
-            yielder.switch(START.value)
-            result[key] = handle(yielder)
-            yielder.switch(END.value)
-
-            yielder.switch(END.member)
-        ## We already handled </struct> above, don't want to handle it below
-        return result
-    elif tag == 'array':
-        result = []
-        yielder.switch(START.data)
-        while True:
-            state, _ = yielder.switch(START.value, END.data)
-            if state == END:
-                break
-
-            result.append(handle(yielder))
-
-            yielder.switch(END.value)
-
-    yielder.switch(getattr(END, tag))
-
-    return result
-
-
-VALUE = mu.tag_factory('value')
-BOOLEAN = mu.tag_factory('boolean')
-INT = mu.tag_factory('int')
-STRUCT = mu.tag_factory('struct')
-MEMBER = mu.tag_factory('member')
-NAME = mu.tag_factory('name')
-ARRAY = mu.tag_factory('array')
-DATA = mu.tag_factory('data')
-STRING = mu.tag_factory('string')
-DOUBLE = mu.tag_factory('double')
-METHODRESPONSE = mu.tag_factory('methodResponse')
-PARAMS = mu.tag_factory('params')
-PARAM = mu.tag_factory('param')
-
-mu.inline_elements['string'] = True
-mu.inline_elements['boolean'] = True
-mu.inline_elements['name'] = True
-
-
-def _generate(something):
-    if isinstance(something, dict):
-        result = STRUCT()
-        for key, value in something.items():
-            result[
-                MEMBER[
-                    NAME[key], _generate(value)]]
-        return VALUE[result]
-    elif isinstance(something, list):
-        result = DATA()
-        for item in something:
-            result[_generate(item)]
-        return VALUE[ARRAY[[result]]]
-    elif isinstance(something, basestring):
-        return VALUE[STRING[something]]
-    elif isinstance(something, bool):
-        if something:
-            return VALUE[BOOLEAN['1']]
-        return VALUE[BOOLEAN['0']]
-    elif isinstance(something, int):
-        return VALUE[INT[something]]
-    elif isinstance(something, float):
-        return VALUE[DOUBLE[something]]
-
-def generate(*args):
-    params = PARAMS()
-    for arg in args:
-        params[PARAM[_generate(arg)]]
-    return METHODRESPONSE[params]
-
-
-if __name__ == '__main__':
-    print parse("""<?xml version="1.0"?> <methodCall>  <methodName>examples.getStateName</methodName>  <params>  <param>  <value><i4>41</i4></value>  </param>  </params>  </methodCall>
-""")
-    
-        
-        
-        
-        
-        
-        
-        
-        
diff --git a/indra/lib/python/indra/util/fastest_elementtree.py b/indra/lib/python/indra/util/fastest_elementtree.py
deleted file mode 100755
index 4fcf662dd90946ac48b9167cd9eb0e48bca97e2f..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/fastest_elementtree.py
+++ /dev/null
@@ -1,64 +0,0 @@
-"""\
-@file fastest_elementtree.py
-@brief Concealing some gnarly import logic in here.  This should export the interface of elementtree.
-
-$LicenseInfo:firstyear=2008&license=mit$
-
-Copyright (c) 2008-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-# The parsing exception raised by the underlying library depends
-# on the ElementTree implementation we're using, so we provide an
-# alias here.
-#
-# Use ElementTreeError as the exception type for catching parsing
-# errors.
-
-
-# Using cElementTree might cause some unforeseen problems, so here's a
-# convenient off switch.
-use_celementree = True
-
-try:
-    if not use_celementree:
-        raise ImportError()
-    # Python 2.3 and 2.4.
-    from cElementTree import *
-    ElementTreeError = SyntaxError
-except ImportError:
-    try:
-        if not use_celementree:
-            raise ImportError()
-        # Python 2.5 and above.
-        from xml.etree.cElementTree import *
-        ElementTreeError = SyntaxError
-    except ImportError:
-        # Pure Python code.
-        try:
-            # Python 2.3 and 2.4.
-            from elementtree.ElementTree import *
-        except ImportError:
-            # Python 2.5 and above.
-            from xml.etree.ElementTree import *
-
-        # The pure Python ElementTree module uses Expat for parsing.
-        from xml.parsers.expat import ExpatError as ElementTreeError
diff --git a/indra/lib/python/indra/util/helpformatter.py b/indra/lib/python/indra/util/helpformatter.py
deleted file mode 100755
index ba5c9b67d183bb91efcd295dfea7fbc96df7d2de..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/helpformatter.py
+++ /dev/null
@@ -1,52 +0,0 @@
-"""\
-@file helpformatter.py
-@author Phoenix
-@brief Class for formatting optparse descriptions.
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import optparse
-import textwrap
-
-class Formatter(optparse.IndentedHelpFormatter):
-    def __init__(
-        self, 
-        p_indentIncrement = 2, 
-        p_maxHelpPosition = 24,
-        p_width = 79,
-        p_shortFirst = 1) :
-        optparse.HelpFormatter.__init__(
-            self, 
-            p_indentIncrement,
-            p_maxHelpPosition, 
-            p_width, 
-            p_shortFirst)
-    def format_description(self, p_description):
-        t_descWidth = self.width - self.current_indent
-        t_indent = " " * (self.current_indent + 2)
-        return "\n".join(
-            [textwrap.fill(descr, t_descWidth, initial_indent = t_indent,
-                           subsequent_indent = t_indent)
-             for descr in p_description.split("\n")] )
diff --git a/indra/lib/python/indra/util/iterators.py b/indra/lib/python/indra/util/iterators.py
deleted file mode 100755
index 9013fa63036fdc452d502150ec53f558814453b0..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/iterators.py
+++ /dev/null
@@ -1,63 +0,0 @@
-"""\
-@file iterators.py
-@brief Useful general-purpose iterators.
-
-$LicenseInfo:firstyear=2008&license=mit$
-
-Copyright (c) 2008-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-from __future__ import nested_scopes
-
-def iter_chunks(rows, aggregate_size=100):
-    """
-    Given an iterable set of items (@p rows), produces lists of up to @p
-    aggregate_size items at a time, for example:
-    
-    iter_chunks([1,2,3,4,5,6,7,8,9,10], 3)
-
-    Values for @p aggregate_size < 1 will raise ValueError.
-
-    Will return a generator that produces, in the following order:
-    - [1, 2, 3]
-    - [4, 5, 6]
-    - [7, 8, 9]
-    - [10]
-    """
-    if aggregate_size < 1:
-        raise ValueError()
-
-    def iter_chunks_inner():
-        row_iter = iter(rows)
-        done = False
-        agg = []
-        while not done:
-            try:
-                row = row_iter.next()
-                agg.append(row)
-            except StopIteration:
-                done = True
-            if agg and (len(agg) >= aggregate_size or done):
-                yield agg
-                agg = []
-    
-    return iter_chunks_inner()
diff --git a/indra/lib/python/indra/util/iterators_test.py b/indra/lib/python/indra/util/iterators_test.py
deleted file mode 100755
index 66928c8e7d27aae455748559a795068084130c0b..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/iterators_test.py
+++ /dev/null
@@ -1,72 +0,0 @@
-"""\
-@file iterators_test.py
-@brief Test cases for iterators module.
-
-$LicenseInfo:firstyear=2008&license=mit$
-
-Copyright (c) 2008-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import unittest
-
-from indra.util.iterators import iter_chunks
-
-class TestIterChunks(unittest.TestCase):
-    """Unittests for iter_chunks"""
-    def test_bad_agg_size(self):
-        rows = [1,2,3,4]
-        self.assertRaises(ValueError, iter_chunks, rows, 0)
-        self.assertRaises(ValueError, iter_chunks, rows, -1)
-
-        try:
-            for i in iter_chunks(rows, 0):
-                pass
-        except ValueError:
-            pass
-        else:
-            self.fail()
-        
-        try:
-            result = list(iter_chunks(rows, 0))
-        except ValueError:
-            pass
-        else:
-            self.fail()
-    def test_empty(self):
-        rows = []
-        result = list(iter_chunks(rows))
-        self.assertEqual(result, [])
-    def test_small(self):
-        rows = [[1]]
-        result = list(iter_chunks(rows, 2))
-        self.assertEqual(result, [[[1]]])
-    def test_size(self):
-        rows = [[1],[2]]
-        result = list(iter_chunks(rows, 2))
-        self.assertEqual(result, [[[1],[2]]])
-    def test_multi_agg(self):
-        rows = [[1],[2],[3],[4],[5]]
-        result = list(iter_chunks(rows, 2))
-        self.assertEqual(result, [[[1],[2]],[[3],[4]],[[5]]])
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/indra/lib/python/indra/util/llperformance.py b/indra/lib/python/indra/util/llperformance.py
deleted file mode 100755
index 57dd64de3fa04706eb69793361180cf52dee0fe3..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/llperformance.py
+++ /dev/null
@@ -1,182 +0,0 @@
-#!/usr/bin/env python
-"""\
-@file   llperformance.py
-
-$LicenseInfo:firstyear=2010&license=viewerlgpl$
-Second Life Viewer Source Code
-Copyright (C) 2010-2011, Linden Research, Inc.
-
-This library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Lesser General Public
-License as published by the Free Software Foundation;
-version 2.1 of the License only.
-
-This library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public
-License along with this library; if not, write to the Free Software
-Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-
-Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-$/LicenseInfo$
-"""
-
-# ------------------------------------------------
-# Sim metrics utility functions.
-
-import glob, os, time, sys, stat, exceptions
-
-from indra.base import llsd
-
-gBlockMap = {}              #Map of performance metric data with function hierarchy information.
-gCurrentStatPath = ""
-
-gIsLoggingEnabled=False
-
-class LLPerfStat:
-    def __init__(self,key):
-        self.mTotalTime = 0
-        self.mNumRuns = 0
-        self.mName=key
-        self.mTimeStamp = int(time.time()*1000)
-        self.mUTCTime = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
-
-    def __str__(self):
-        return "%f" %  self.mTotalTime
-
-    def start(self):
-        self.mStartTime = int(time.time() * 1000000)
-        self.mNumRuns += 1
-
-    def stop(self):
-        execution_time = int(time.time() * 1000000) - self.mStartTime
-        self.mTotalTime += execution_time
-
-    def get_map(self):
-        results={}
-        results['name']=self.mName
-        results['utc_time']=self.mUTCTime
-        results['timestamp']=self.mTimeStamp
-        results['us']=self.mTotalTime
-        results['count']=self.mNumRuns
-        return results
-
-class PerfError(exceptions.Exception):
-    def __init__(self):
-        return
-
-    def __Str__(self):
-        print "","Unfinished LLPerfBlock"
-
-class LLPerfBlock:
-    def __init__( self, key ):
-        global gBlockMap
-        global gCurrentStatPath
-        global gIsLoggingEnabled
-
-        #Check to see if we're running metrics right now.
-        if gIsLoggingEnabled:
-            self.mRunning = True        #Mark myself as running.
-    
-            self.mPreviousStatPath = gCurrentStatPath
-            gCurrentStatPath += "/" + key
-            if gCurrentStatPath not in gBlockMap:
-                gBlockMap[gCurrentStatPath] = LLPerfStat(key)
-
-            self.mStat = gBlockMap[gCurrentStatPath]
-            self.mStat.start()
-    
-    def finish( self ):
-        global gBlockMap
-        global gIsLoggingEnabled
-
-        if gIsLoggingEnabled:
-            self.mStat.stop()
-            self.mRunning = False
-            gCurrentStatPath = self.mPreviousStatPath
-
-#    def __del__( self ):
-#        if self.mRunning:
-#            #SPATTERS FIXME
-#            raise PerfError
-
-class LLPerformance:
-    #--------------------------------------------------
-    # Determine whether or not we want to log statistics
-
-    def __init__( self, process_name = "python" ):
-        self.process_name = process_name
-        self.init_testing()
-        self.mTimeStamp = int(time.time()*1000)
-        self.mUTCTime = time.strftime("%Y-%m-%dT%H:%M:%SZ", time.gmtime())
-
-    def init_testing( self ):
-        global gIsLoggingEnabled
-
-        host_performance_file = "/dev/shm/simperf/simperf_proc_config.llsd"
-    
-        #If file exists, open
-        if os.path.exists(host_performance_file):
-            file = open (host_performance_file,'r')
-    
-            #Read serialized LLSD from file.
-            body = llsd.parse(file.read())
-    
-            #Calculate time since file last modified.
-            stats = os.stat(host_performance_file)
-            now = time.time()
-            mod = stats[stat.ST_MTIME]
-            age = now - mod
-    
-            if age < ( body['duration'] ):
-                gIsLoggingEnabled = True
-    
-
-    def get ( self ):
-        global gIsLoggingEnabled
-        return gIsLoggingEnabled
-
-    #def output(self,ptr,path):
-    #    if 'stats' in ptr:
-    #        stats = ptr['stats']
-    #        self.mOutputPtr[path] = stats.get_map()
-
-    #    if 'children' in ptr:
-    #        children=ptr['children']
-
-    #        curptr = self.mOutputPtr
-    #        curchildren={}
-    #        curptr['children'] = curchildren
-
-    #        for key in children:
-    #            curchildren[key]={}
-    #            self.mOutputPtr = curchildren[key]
-    #            self.output(children[key],path + '/' + key)
-    
-    def done(self):
-        global gBlockMap
-
-        if not self.get():
-            return
-
-        output_name = "/dev/shm/simperf/%s_proc.%d.llsd" % (self.process_name, os.getpid())
-        output_file = open(output_name, 'w')
-        process_info = {
-            "name"  :   self.process_name,
-            "pid"   :   os.getpid(),
-            "ppid"  :   os.getppid(),
-            "timestamp" :   self.mTimeStamp,
-            "utc_time"  :   self.mUTCTime,
-            }
-        output_file.write(llsd.format_notation(process_info))
-        output_file.write('\n')
-
-        for key in gBlockMap.keys():
-            gBlockMap[key] = gBlockMap[key].get_map()
-        output_file.write(llsd.format_notation(gBlockMap))
-        output_file.write('\n')
-        output_file.close()
-
diff --git a/indra/lib/python/indra/util/llsubprocess.py b/indra/lib/python/indra/util/llsubprocess.py
deleted file mode 100755
index 7e0e115d14600f29fe4b855077232a8d10529271..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/llsubprocess.py
+++ /dev/null
@@ -1,117 +0,0 @@
-"""\
-@file llsubprocess.py
-@author Phoenix
-@date 2008-01-18
-@brief The simplest possible wrapper for a common sub-process paradigm.
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import os
-import popen2
-import time
-import select
-
-class Timeout(RuntimeError):
-    "Exception raised when a subprocess times out."
-    pass
-
-def run(command, args=None, data=None, timeout=None):
-    """\
-@brief Run command with arguments
-
-This is it. This is the function I want to run all the time when doing
-subprocces, but end up copying the code everywhere. none of the
-standard commands are secure and provide a way to specify input, get
-all the output, and get the result.
-@param command A string specifying a process to launch.
-@param args Arguments to be passed to command. Must be list, tuple or None.
-@param data input to feed to the command.
-@param timeout Maximum number of many seconds to run.
-@return Returns (result, stdout, stderr) from process.
-"""
-    cmd = [command]
-    if args:
-        cmd.extend([str(arg) for arg in args])
-    #print  "cmd: ","' '".join(cmd)
-    child = popen2.Popen3(cmd, True)
-    #print child.pid
-    out = []
-    err = []
-    result = -1
-    time_left = timeout
-    tochild = [child.tochild.fileno()]
-    while True:
-        time_start = time.time()
-        #print "time:",time_left
-        p_in, p_out, p_err = select.select(
-            [child.fromchild.fileno(), child.childerr.fileno()],
-            tochild,
-            [],
-            time_left)
-        if p_in:
-            new_line = os.read(child.fromchild.fileno(), 32 * 1024)
-            if new_line:
-                #print "line:",new_line
-                out.append(new_line)
-            new_line = os.read(child.childerr.fileno(), 32 * 1024)
-            if new_line:
-                #print "error:", new_line
-                err.append(new_line)
-        if p_out:
-            if data:
-                #print "p_out"
-                bytes = os.write(child.tochild.fileno(), data)
-                data = data[bytes:]
-                if len(data) == 0:
-                    data = None
-                    tochild = []
-                    child.tochild.close()
-        result = child.poll()
-        if result != -1:
-            # At this point, the child process has exited and result
-            # is the return value from the process. Between the time
-            # we called select() and poll() the process may have
-            # exited so read all the data left on the child process
-            # stdout and stderr.
-            last = child.fromchild.read()
-            if last:
-                out.append(last)
-            last = child.childerr.read()
-            if last:
-                err.append(last)
-            child.tochild.close()
-            child.fromchild.close()
-            child.childerr.close()
-            break
-        if time_left is not None:
-            time_left -= (time.time() - time_start)
-            if time_left < 0:
-                raise Timeout
-    #print "result:",result
-    out = ''.join(out)
-    #print "stdout:", out
-    err = ''.join(err)
-    #print "stderr:", err
-    return result, out, err
diff --git a/indra/lib/python/indra/util/named_query.py b/indra/lib/python/indra/util/named_query.py
deleted file mode 100755
index 6bf956107dec95dc92d042eab0920da463cea872..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/named_query.py
+++ /dev/null
@@ -1,592 +0,0 @@
-"""\
-@file named_query.py
-@author Ryan Williams, Phoenix
-@date 2007-07-31
-@brief An API for running named queries.
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import errno
-import MySQLdb
-import MySQLdb.cursors
-import os
-import os.path
-import re
-import time
-
-from indra.base import llsd
-from indra.base import config
-
-DEBUG = False
-NQ_FILE_SUFFIX = config.get('named-query-file-suffix', '.nq')
-NQ_FILE_SUFFIX_LEN  = len(NQ_FILE_SUFFIX)
-
-_g_named_manager = None
-
-def _init_g_named_manager(sql_dir = None):
-    """Initializes a global NamedManager object to point at a
-    specified named queries hierarchy.
-
-    This function is intended entirely for testing purposes,
-    because it's tricky to control the config from inside a test."""
-    global NQ_FILE_SUFFIX
-    NQ_FILE_SUFFIX = config.get('named-query-file-suffix', '.nq')
-    global NQ_FILE_SUFFIX_LEN
-    NQ_FILE_SUFFIX_LEN  = len(NQ_FILE_SUFFIX)
-
-    if sql_dir is None:
-        sql_dir = config.get('named-query-base-dir')
-
-    # extra fallback directory in case config doesn't return what we want
-    if sql_dir is None:
-        sql_dir = os.path.abspath(
-            os.path.join(
-            os.path.realpath(os.path.dirname(__file__)), "..", "..", "..", "..", "web", "dataservice", "sql"))
-
-    global _g_named_manager
-    _g_named_manager = NamedQueryManager(
-        os.path.abspath(os.path.realpath(sql_dir)))
-
-def get(name, schema = None):
-    "Get the named query object to be used to perform queries"
-    if _g_named_manager is None:
-        _init_g_named_manager()
-    return _g_named_manager.get(name).for_schema(schema)
-
-def sql(connection, name, params):
-    # use module-global NamedQuery object to perform default substitution
-    return get(name).sql(connection, params)
-
-def run(connection, name, params, expect_rows = None):
-    """\
-@brief given a connection, run a named query with the params
-
-Note that this function will fetch ALL rows.
-@param connection The connection to use
-@param name The name of the query to run
-@param params The parameters passed into the query
-@param expect_rows The number of rows expected. Set to 1 if return_as_map is true.  Raises ExpectationFailed if the number of returned rows doesn't exactly match.  Kind of a hack.
-@return Returns the result set as a list of dicts.
-"""
-    return get(name).run(connection, params, expect_rows)
-
-class ExpectationFailed(Exception):
-    """ Exception that is raised when an expectation for an sql query
-    is not met."""
-    def __init__(self, message):
-        Exception.__init__(self, message)
-        self.message = message
-
-class NamedQuery(object):
-    def __init__(self, name, filename):
-        """ Construct a NamedQuery object.  The name argument is an
-        arbitrary name as a handle for the query, and the filename is
-        a path to a file or a file-like object containing an llsd named
-        query document."""
-        self._stat_interval_seconds = 5  # 5 seconds
-        self._name = name
-        if (filename is not None and isinstance(filename, (str, unicode))
-            and NQ_FILE_SUFFIX != filename[-NQ_FILE_SUFFIX_LEN:]):
-            filename = filename + NQ_FILE_SUFFIX
-        self._location = filename
-        self._alternative = dict()
-        self._last_mod_time = 0
-        self._last_check_time = 0
-        self.deleted = False
-        self.load_contents()
-
-    def name(self):
-        """ The name of the query. """
-        return self._name
-
-    def get_modtime(self):
-        """ Returns the mtime (last modified time) of the named query
-        filename. For file-like objects, expect a modtime of 0"""
-        if self._location and isinstance(self._location, (str, unicode)):
-            return os.path.getmtime(self._location)
-        return 0
-
-    def load_contents(self):
-        """ Loads and parses the named query file into self.  Does
-        nothing if self.location is nonexistant."""
-        if self._location:
-            if isinstance(self._location, (str, unicode)):
-                contents = llsd.parse(open(self._location).read())
-            else:
-                # we probably have a file-like object. Godspeed!
-                contents = llsd.parse(self._location.read())
-            self._reference_contents(contents)
-            # Check for alternative implementations
-            try:
-                for name, alt in self._contents['alternative'].items():
-                    nq = NamedQuery(name, None)
-                    nq._reference_contents(alt)
-                    self._alternative[name] = nq
-            except KeyError, e:
-                pass
-            self._last_mod_time = self.get_modtime()
-            self._last_check_time = time.time()
-
-    def _reference_contents(self, contents):
-        "Helper method which builds internal structure from parsed contents"
-        self._contents = contents
-        self._ttl = int(self._contents.get('ttl', 0))
-        self._return_as_map = bool(self._contents.get('return_as_map', False))
-        self._legacy_dbname = self._contents.get('legacy_dbname', None)
-
-        # reset these before doing the sql conversion because we will
-        # read them there. reset these while loading so we pick up
-        # changes.
-        self._around = set()
-        self._append = set()
-        self._integer = set()
-        self._options = self._contents.get('dynamic_where', {})
-        for key in self._options:
-            if isinstance(self._options[key], basestring):
-                self._options[key] = self._convert_sql(self._options[key])
-            elif isinstance(self._options[key], list):
-                lines = []
-                for line in self._options[key]:
-                    lines.append(self._convert_sql(line))
-                self._options[key] = lines
-            else:
-                moreopt = {}
-                for kk in self._options[key]:
-                    moreopt[kk] = self._convert_sql(self._options[key][kk]) 
-                self._options[key] = moreopt
-        self._base_query = self._convert_sql(self._contents['base_query'])
-        self._query_suffix = self._convert_sql(
-            self._contents.get('query_suffix', ''))
-
-    def _convert_sql(self, sql):
-        """convert the parsed sql into a useful internal structure.
-
-        This function has to turn the named query format into a pyformat
-        style. It also has to look for %:name% and :name% and
-        ready them for use in LIKE statements"""
-        if sql:
-            # This first sub is to properly escape any % signs that
-            # are meant to be literally passed through to mysql in the
-            # query.  It leaves any %'s that are used for
-            # like-expressions.
-            expr = re.compile("(?<=[^a-zA-Z0-9_-])%(?=[^:])")
-            sql = expr.sub('%%', sql)
-
-            # This should tackle the rest of the %'s in the query, by
-            # converting them to LIKE clauses.
-            expr = re.compile("(%?):([a-zA-Z][a-zA-Z0-9_-]*)%")
-            sql = expr.sub(self._prepare_like, sql)
-            expr = re.compile("#:([a-zA-Z][a-zA-Z0-9_-]*)")
-            sql = expr.sub(self._prepare_integer, sql)
-            expr = re.compile(":([a-zA-Z][a-zA-Z0-9_-]*)")
-            sql = expr.sub("%(\\1)s", sql)
-        return sql
-
-    def _prepare_like(self, match):
-        """This function changes LIKE statement replace behavior
-
-        It works by turning %:name% to %(_name_around)s and :name% to
-        %(_name_append)s. Since a leading '_' is not a valid keyname
-        input (enforced via unit tests), it will never clash with
-        existing keys. Then, when building the statement, the query
-        runner will generate corrected strings."""
-        if match.group(1) == '%':
-            # there is a leading % so this is treated as prefix/suffix
-            self._around.add(match.group(2))
-            return "%(" + self._build_around_key(match.group(2)) + ")s"
-        else:
-            # there is no leading %, so this is suffix only
-            self._append.add(match.group(2))
-            return "%(" + self._build_append_key(match.group(2)) + ")s"
-
-    def _build_around_key(self, key):
-        return "_" + key + "_around"
-
-    def _build_append_key(self, key):
-        return "_" + key + "_append"
-
-    def _prepare_integer(self, match):
-        """This function adjusts the sql for #:name replacements
-
-        It works by turning #:name to %(_name_as_integer)s. Since a
-        leading '_' is not a valid keyname input (enforced via unit
-        tests), it will never clash with existing keys. Then, when
-        building the statement, the query runner will generate
-        corrected strings."""
-        self._integer.add(match.group(1))
-        return "%(" + self._build_integer_key(match.group(1)) + ")s"
-
-    def _build_integer_key(self, key):
-        return "_" + key + "_as_integer"
-
-    def _strip_wildcards_to_list(self, value):
-        """Take string, and strip out the LIKE special characters.
-
-        Technically, this is database dependant, but postgresql and
-        mysql use the same wildcards, and I am not aware of a general
-        way to handle this. I think you need a sql statement of the
-        form:
-
-        LIKE_STRING( [ANY,ONE,str]... )
-
-        which would treat ANY as their any string, and ONE as their
-        single glyph, and str as something that needs database
-        specific encoding to not allow any % or _ to affect the query.
-
-        As it stands, I believe it's impossible to write a named query
-        style interface which uses like to search the entire space of
-        text available. Imagine the query:
-
-        % of brain used by average linden
-
-        In order to search for %, it must be escaped, so once you have
-        escaped the string to not do wildcard searches, and be escaped
-        for the database, and then prepended the wildcard you come
-        back with one of:
-
-        1) %\% of brain used by average linden
-        2) %%% of brain used by average linden
-
-        Then, when passed to the database to be escaped to be database
-        safe, you get back:
-        
-        1) %\\% of brain used by average linden
-        : which means search for any character sequence, followed by a
-          backslash, followed by any sequence, followed by ' of
-          brain...'
-        2) %%% of brain used by average linden
-        : which (I believe) means search for a % followed by any
-          character sequence followed by 'of brain...'
-
-        Neither of which is what we want!
-
-        So, we need a vendor (or extention) for LIKE_STRING. Anyone
-        want to write it?"""
-        if isinstance(value, unicode):
-            utf8_value = value
-        else:
-            utf8_value = unicode(value, "utf-8")
-        esc_list = []
-        remove_chars = set(u"%_")
-        for glyph in utf8_value:
-            if glyph in remove_chars:
-                continue
-            esc_list.append(glyph.encode("utf-8"))
-        return esc_list
-
-    def delete(self):
-        """ Makes this query unusable by deleting all the members and
-        setting the deleted member.  This is desired when the on-disk
-        query has been deleted but the in-memory copy remains."""
-        # blow away all members except _name, _location, and deleted
-        name, location = self._name, self._location
-        for key in self.__dict__.keys():
-            del self.__dict__[key]
-        self.deleted = True
-        self._name, self._location = name, location
-
-    def ttl(self):
-        """ Estimated time to live of this query. Used for web
-        services to set the Expires header."""
-        return self._ttl
-
-    def legacy_dbname(self):
-        return self._legacy_dbname
-
-    def return_as_map(self):
-        """ Returns true if this query is configured to return its
-        results as a single map (as opposed to a list of maps, the
-        normal behavior)."""
-        
-        return self._return_as_map
-
-    def for_schema(self, db_name):
-        "Look trough the alternates and return the correct query"
-        if db_name is None:
-            return self
-        try:
-            return self._alternative[db_name]
-        except KeyError, e:
-            pass
-        return self
-
-    def run(self, connection, params, expect_rows = None, use_dictcursor = True):
-        """given a connection, run a named query with the params
-
-        Note that this function will fetch ALL rows. We do this because it
-        opens and closes the cursor to generate the values, and this 
-        isn't a generator so the cursor has no life beyond the method call.
-
-        @param cursor The connection to use (this generates its own cursor for the query)
-        @param name The name of the query to run
-        @param params The parameters passed into the query
-        @param expect_rows The number of rows expected. Set to 1 if return_as_map is true.  Raises ExpectationFailed if the number of returned rows doesn't exactly match.  Kind of a hack.
-        @param use_dictcursor Set to false to use a normal cursor and manually convert the rows to dicts.
-        @return Returns the result set as a list of dicts, or, if the named query has return_as_map set to true, returns a single dict.
-        """
-        if use_dictcursor:
-            cursor = connection.cursor(MySQLdb.cursors.DictCursor)
-        else:
-            cursor = connection.cursor()
-
-        full_query, params = self._construct_sql(params)
-        if DEBUG:
-            print "SQL:", self.sql(connection, params)
-        rows = cursor.execute(full_query, params)
-
-        # *NOTE: the expect_rows argument is a very cheesy way to get some
-        # validation on the result set.  If you want to add more expectation
-        # logic, do something more object-oriented and flexible. Or use an ORM.
-        if(self._return_as_map):
-            expect_rows = 1
-        if expect_rows is not None and rows != expect_rows:
-            cursor.close()
-            raise ExpectationFailed("Statement expected %s rows, got %s.  Sql: '%s' %s" % (
-                expect_rows, rows, full_query, params))
-
-        # convert to dicts manually if we're not using a dictcursor
-        if use_dictcursor:
-            result_set = cursor.fetchall()
-        else:
-            if cursor.description is None:
-                # an insert or something
-                x = cursor.fetchall()
-                cursor.close()
-                return x
-
-            names = [x[0] for x in cursor.description]
-
-            result_set = []
-            for row in cursor.fetchall():
-                converted_row = {}
-                for idx, col_name in enumerate(names):
-                    converted_row[col_name] = row[idx]
-                result_set.append(converted_row)
-
-        cursor.close()
-        if self._return_as_map:
-            return result_set[0]
-        return result_set
-
-    def _construct_sql(self, params):
-        """ Returns a query string and a dictionary of parameters,
-        suitable for directly passing to the execute() method."""
-        self.refresh()
-
-        # build the query from the options available and the params
-        base_query = []
-        base_query.append(self._base_query)
-        for opt, extra_where in self._options.items():
-            if type(extra_where) in (dict, list, tuple):
-                if opt in params:
-                    base_query.append(extra_where[params[opt]])
-            else:
-                if opt in params and params[opt]:
-                    base_query.append(extra_where)
-        if self._query_suffix:
-            base_query.append(self._query_suffix)
-        full_query = '\n'.join(base_query)
-
-        # Go through the query and rewrite all of the ones with the
-        # @:name syntax.
-        rewrite = _RewriteQueryForArray(params)
-        expr = re.compile("@%\(([a-zA-Z][a-zA-Z0-9_-]*)\)s")
-        full_query = expr.sub(rewrite.operate, full_query)
-        params.update(rewrite.new_params)
-
-        # build out the params for like. We only have to do this
-        # parameters which were detected to have ued the where syntax
-        # during load.
-        #
-        # * treat the incoming string as utf-8
-        # * strip wildcards
-        # * append or prepend % as appropriate
-        new_params = {}
-        for key in params:
-            if key in self._around:
-                new_value = ['%']
-                new_value.extend(self._strip_wildcards_to_list(params[key]))
-                new_value.append('%')
-                new_params[self._build_around_key(key)] = ''.join(new_value)
-            if key in self._append:
-                new_value = self._strip_wildcards_to_list(params[key])
-                new_value.append('%')
-                new_params[self._build_append_key(key)] = ''.join(new_value)
-            if key in self._integer:
-                new_params[self._build_integer_key(key)] = int(params[key])
-        params.update(new_params)
-
-        return full_query, params
-
-    def sql(self, connection, params):
-        """ Generates an SQL statement from the named query document
-        and a dictionary of parameters.
-
-        *NOTE: Only use for debugging, because it uses the
-         non-standard MySQLdb 'literal' method.
-        """
-        if not DEBUG:
-            import warnings
-            warnings.warn("Don't use named_query.sql() when not debugging.  Used on %s" % self._location)
-        # do substitution using the mysql (non-standard) 'literal'
-        # function to do the escaping.
-        full_query, params = self._construct_sql(params)
-        return full_query % connection.literal(params)
-        
-
-    def refresh(self):
-        """ Refresh self from the file on the filesystem.
-
-        This is optimized to be callable as frequently as you wish,
-        without adding too much load.  It does so by only stat-ing the
-        file every N seconds, where N defaults to 5 and is
-        configurable through the member _stat_interval_seconds.  If the stat
-        reveals that the file has changed, refresh will re-parse the
-        contents of the file and use them to update the named query
-        instance.  If the stat reveals that the file has been deleted,
-        refresh will call self.delete to make the in-memory
-        representation unusable."""
-        now = time.time()
-        if(now - self._last_check_time > self._stat_interval_seconds):
-            self._last_check_time = now
-            try:
-                modtime = self.get_modtime()
-                if(modtime > self._last_mod_time):
-                    self.load_contents()
-            except OSError, e:
-                if e.errno == errno.ENOENT: # file not found
-                    self.delete() # clean up self
-                raise  # pass the exception along to the caller so they know that this query disappeared
-
-class NamedQueryManager(object):
-    """ Manages the lifespan of NamedQuery objects, drawing from a
-    directory hierarchy of named query documents.
-
-    In practice this amounts to a memory cache of NamedQuery objects."""
-    
-    def __init__(self, named_queries_dir):
-        """ Initializes a manager to look for named queries in a
-        directory."""
-        self._dir = os.path.abspath(os.path.realpath(named_queries_dir))
-        self._cached_queries = {}
-
-    def sql(self, connection, name, params):
-        nq = self.get(name)
-        return nq.sql(connection, params)
-        
-    def get(self, name):
-        """ Returns a NamedQuery instance based on the name, either
-        from memory cache, or by parsing from disk.
-
-        The name is simply a relative path to the directory associated
-        with the manager object.  Before returning the instance, the
-        NamedQuery object is cached in memory, so that subsequent
-        accesses don't have to read from disk or do any parsing.  This
-        means that NamedQuery objects returned by this method are
-        shared across all users of the manager object.
-        NamedQuery.refresh is used to bring the NamedQuery objects in
-        sync with the actual files on disk."""
-        nq = self._cached_queries.get(name)
-        if nq is None:
-            nq = NamedQuery(name, os.path.join(self._dir, name))
-            self._cached_queries[name] = nq
-        else:
-            try:
-                nq.refresh()
-            except OSError, e:
-                if e.errno == errno.ENOENT: # file not found
-                    del self._cached_queries[name]
-                raise # pass exception along to caller so they know that the query disappeared
-
-        return nq
-
-class _RewriteQueryForArray(object):
-    "Helper class for rewriting queries with the @:name syntax"
-    def __init__(self, params):
-        self.params = params
-        self.new_params = dict()
-
-    def operate(self, match):
-        "Given a match, return the string that should be in use"
-        key = match.group(1)
-        value = self.params[key]
-        if type(value) in (list,tuple):
-            rv = []
-            for idx in range(len(value)):
-                # if the value@idx is array-like, we are
-                # probably dealing with a VALUES
-                new_key = "_%s_%s"%(key, str(idx))
-                val_item = value[idx]
-                if type(val_item) in (list, tuple, dict):
-                    if type(val_item) is dict:
-                        # this is because in Python, the order of 
-                        # key, value retrieval from the dict is not
-                        # guaranteed to match what the input intended
-                        # and for VALUES, order is important.
-                        # TODO: Implemented ordered dict in LLSD parser?
-                        raise ExpectationFailed('Only lists/tuples allowed,\
-                                received dict')
-                    values_keys = []
-                    for value_idx, item in enumerate(val_item):
-                        # we want a key of the format :
-                        # key_#replacement_#value_row_#value_col
-                        # ugh... so if we are replacing 10 rows in user_note, 
-                        # the first values clause would read (for @:user_notes) :-
-                        # ( :_user_notes_0_1_1,  :_user_notes_0_1_2, :_user_notes_0_1_3 )
-                        # the input LLSD for VALUES will look like:
-                        # <llsd>...
-                        # <map>
-                        #  <key>user_notes</key>
-                        #      <array>
-                        #      <array> <!-- row 1 for VALUES -->
-                        #          <string>...</string>
-                        #          <string>...</string>
-                        #          <string>...</string>
-                        #      </array>
-                        # ...
-                        #      </array>
-                        # </map>
-                        # ... </llsd>
-                        values_key = "%s_%s"%(new_key, value_idx)
-                        self.new_params[values_key] = item
-                        values_keys.append("%%(%s)s"%values_key)
-                    # now collapse all these new place holders enclosed in ()
-                    # from [':_key_0_1_1', ':_key_0_1_2', ':_key_0_1_3,...] 
-                    # rv will have [ '(:_key_0_1_1, :_key_0_1_2, :_key_0_1_3)', ]
-                    # which is flattened a few lines below join(rv)
-                    rv.append('(%s)' % ','.join(values_keys))
-                else:
-                    self.new_params[new_key] = val_item
-                    rv.append("%%(%s)s"%new_key)
-            return ','.join(rv)
-        else:
-            # not something that can be expanded, so just drop the
-            # leading @ in the front of the match. This will mean that
-            # the single value we have, be it a string, int, whatever
-            # (other than dict) will correctly show up, eg:
-            #
-            # where foo in (@:foobar) -- foobar is a string, so we get
-            # where foo in (:foobar)
-            return match.group(0)[1:]
diff --git a/indra/lib/python/indra/util/shutil2.py b/indra/lib/python/indra/util/shutil2.py
deleted file mode 100755
index 9e2e7a6ded8bbe6a7a6776dff0ef6a4fdbcd54b0..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/shutil2.py
+++ /dev/null
@@ -1,84 +0,0 @@
-'''
-@file shutil2.py
-@brief a better shutil.copytree replacement
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-'''
-
-#
-# shutil2.py
-# Taken from http://www.scons.org/wiki/AccumulateBuilder
-# the stock copytree sucks because it insists that the
-# target dir not exist
-#
-
-import os.path
-import shutil
-
-def copytree(src, dest, symlinks=False):
-    """My own copyTree which does not fail if the directory exists.
-    
-    Recursively copy a directory tree using copy2().
-
-    If the optional symlinks flag is true, symbolic links in the
-    source tree result in symbolic links in the destination tree; if
-    it is false, the contents of the files pointed to by symbolic
-    links are copied.
-    
-    Behavior is meant to be identical to GNU 'cp -R'.    
-    """
-    def copyItems(src, dest, symlinks=False):
-        """Function that does all the work.
-        
-        It is necessary to handle the two 'cp' cases:
-        - destination does exist
-        - destination does not exist
-        
-        See 'cp -R' documentation for more details
-        """
-        for item in os.listdir(src):
-           srcPath = os.path.join(src, item)
-           if os.path.isdir(srcPath):
-               srcBasename = os.path.basename(srcPath)
-               destDirPath = os.path.join(dest, srcBasename)
-               if not os.path.exists(destDirPath):
-                   os.makedirs(destDirPath)
-               copyItems(srcPath, destDirPath)
-           elif os.path.islink(item) and symlinks:
-               linkto = os.readlink(item)
-               os.symlink(linkto, dest)
-           else:
-               shutil.copy2(srcPath, dest)
-
-    # case 'cp -R src/ dest/' where dest/ already exists
-    if os.path.exists(dest):
-       destPath = os.path.join(dest, os.path.basename(src))
-       if not os.path.exists(destPath):
-           os.makedirs(destPath)
-    # case 'cp -R src/ dest/' where dest/ does not exist
-    else:
-       os.makedirs(dest)
-       destPath = dest
-    # actually copy the files
-    copyItems(src, destPath)
diff --git a/indra/lib/python/indra/util/simperf_host_xml_parser.py b/indra/lib/python/indra/util/simperf_host_xml_parser.py
deleted file mode 100755
index 672c1050c241c93779b739da2f26d4497a41fb78..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/simperf_host_xml_parser.py
+++ /dev/null
@@ -1,338 +0,0 @@
-#!/usr/bin/env python
-"""\
-@file simperf_host_xml_parser.py
-@brief Digest collector's XML dump and convert to simple dict/list structure
-
-$LicenseInfo:firstyear=2008&license=mit$
-
-Copyright (c) 2008-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import sys, os, getopt, time
-import simplejson
-from xml import sax
-
-
-def usage():
-    print "Usage:"
-    print sys.argv[0] + " [options]"
-    print "  Convert RRD's XML dump to JSON.  Script to convert the simperf_host_collector-"
-    print "  generated RRD dump into JSON.  Steps include converting selected named"
-    print "  fields from GAUGE type to COUNTER type by computing delta with preceding"
-    print "  values.  Top-level named fields are:"
-    print 
-    print "     lastupdate      Time (javascript timestamp) of last data sample"
-    print "     step            Time in seconds between samples"
-    print "     ds              Data specification (name/type) for each column"
-    print "     database        Table of data samples, one time step per row"
-    print 
-    print "Options:"
-    print "  -i, --in      Input settings filename.  (Default:  stdin)"
-    print "  -o, --out     Output settings filename.  (Default:  stdout)"
-    print "  -h, --help    Print this message and exit."
-    print
-    print "Example: %s -i rrddump.xml -o rrddump.json" % sys.argv[0]
-    print
-    print "Interfaces:"
-    print "   class SimPerfHostXMLParser()         # SAX content handler"
-    print "   def simperf_host_xml_fixup(parser)   # post-parse value fixup"
-
-class SimPerfHostXMLParser(sax.handler.ContentHandler):
-
-    def __init__(self):
-        pass
-        
-    def startDocument(self):
-        self.rrd_last_update = 0         # public
-        self.rrd_step = 0                # public
-        self.rrd_ds = []                 # public
-        self.rrd_records = []            # public
-        self._rrd_level = 0
-        self._rrd_parse_state = 0
-        self._rrd_chars = ""
-        self._rrd_capture = False
-        self._rrd_ds_val = {}
-        self._rrd_data_row = []
-        self._rrd_data_row_has_nan = False
-        
-    def endDocument(self):
-        pass
-
-    # Nasty little ad-hoc state machine to extract the elements that are
-    # necessary from the 'rrdtool dump' XML output.  The same element
-    # name '<ds>' is used for two different data sets so we need to pay
-    # some attention to the actual structure to get the ones we want
-    # and ignore the ones we don't.
-    
-    def startElement(self, name, attrs):
-        self._rrd_level = self._rrd_level + 1
-        self._rrd_capture = False
-        if self._rrd_level == 1:
-            if name == "rrd" and self._rrd_parse_state == 0:
-                self._rrd_parse_state = 1     # In <rrd>
-                self._rrd_capture = True
-                self._rrd_chars = ""
-        elif self._rrd_level == 2:
-            if self._rrd_parse_state == 1:
-                if name == "lastupdate":
-                    self._rrd_parse_state = 2         # In <rrd><lastupdate>
-                    self._rrd_capture = True
-                    self._rrd_chars = ""
-                elif name == "step":
-                    self._rrd_parse_state = 3         # In <rrd><step>
-                    self._rrd_capture = True
-                    self._rrd_chars = ""
-                elif name == "ds":
-                    self._rrd_parse_state = 4         # In <rrd><ds>
-                    self._rrd_ds_val = {}
-                    self._rrd_chars = ""
-                elif name == "rra":
-                    self._rrd_parse_state = 5         # In <rrd><rra>
-        elif self._rrd_level == 3:
-            if self._rrd_parse_state == 4:
-                if name == "name":
-                    self._rrd_parse_state = 6         # In <rrd><ds><name>
-                    self._rrd_capture = True
-                    self._rrd_chars = ""
-                elif name == "type":
-                    self._rrd_parse_state = 7         # In <rrd><ds><type>
-                    self._rrd_capture = True
-                    self._rrd_chars = ""
-            elif self._rrd_parse_state == 5:
-                if name == "database":
-                    self._rrd_parse_state = 8         # In <rrd><rra><database>
-        elif self._rrd_level == 4:
-            if self._rrd_parse_state == 8:
-                if name == "row":
-                    self._rrd_parse_state = 9         # In <rrd><rra><database><row>
-                    self._rrd_data_row = []
-                    self._rrd_data_row_has_nan = False
-        elif self._rrd_level == 5:
-            if self._rrd_parse_state == 9:
-                if name == "v":
-                    self._rrd_parse_state = 10        # In <rrd><rra><database><row><v>
-                    self._rrd_capture = True
-                    self._rrd_chars = ""
-
-    def endElement(self, name):
-        self._rrd_capture = False
-        if self._rrd_parse_state == 10:
-            self._rrd_capture = self._rrd_level == 6
-            if self._rrd_level == 5:
-                if self._rrd_chars == "NaN":
-                    self._rrd_data_row_has_nan = True
-                else:
-                    self._rrd_data_row.append(self._rrd_chars)
-                self._rrd_parse_state = 9              # In <rrd><rra><database><row>
-        elif self._rrd_parse_state == 9:
-            if self._rrd_level == 4:
-                if not self._rrd_data_row_has_nan:
-                    self.rrd_records.append(self._rrd_data_row)
-                self._rrd_parse_state = 8              # In <rrd><rra><database>
-        elif self._rrd_parse_state == 8:
-            if self._rrd_level == 3:
-                self._rrd_parse_state = 5              # In <rrd><rra>
-        elif self._rrd_parse_state == 7:
-            if self._rrd_level == 3:
-                self._rrd_ds_val["type"] = self._rrd_chars
-                self._rrd_parse_state = 4              # In <rrd><ds>
-        elif self._rrd_parse_state == 6:
-            if self._rrd_level == 3:
-                self._rrd_ds_val["name"] = self._rrd_chars
-                self._rrd_parse_state = 4              # In <rrd><ds>
-        elif self._rrd_parse_state == 5:
-            if self._rrd_level == 2:
-                self._rrd_parse_state = 1              # In <rrd>
-        elif self._rrd_parse_state == 4:
-            if self._rrd_level == 2:
-                self.rrd_ds.append(self._rrd_ds_val)
-                self._rrd_parse_state = 1              # In <rrd>
-        elif self._rrd_parse_state == 3:
-            if self._rrd_level == 2:
-                self.rrd_step = long(self._rrd_chars)
-                self._rrd_parse_state = 1              # In <rrd>
-        elif self._rrd_parse_state == 2:
-            if self._rrd_level == 2:
-                self.rrd_last_update = long(self._rrd_chars)
-                self._rrd_parse_state = 1              # In <rrd>
-        elif self._rrd_parse_state == 1:
-            if self._rrd_level == 1:
-                self._rrd_parse_state = 0              # At top
-                
-        if self._rrd_level:
-            self._rrd_level = self._rrd_level - 1
-
-    def characters(self, content):
-        if self._rrd_capture:
-            self._rrd_chars = self._rrd_chars + content.strip()
-
-def _make_numeric(value):
-    try:
-        value = float(value)
-    except:
-        value = ""
-    return value
-
-def simperf_host_xml_fixup(parser, filter_start_time = None, filter_end_time = None):
-    # Fixup for GAUGE fields that are really COUNTS.  They
-    # were forced to GAUGE to try to disable rrdtool's
-    # data interpolation/extrapolation for non-uniform time
-    # samples.
-    fixup_tags = [ "cpu_user",
-                   "cpu_nice",
-                   "cpu_sys",
-                   "cpu_idle",
-                   "cpu_waitio",
-                   "cpu_intr",
-                   # "file_active",
-                   # "file_free",
-                   # "inode_active",
-                   # "inode_free",
-                   "netif_in_kb",
-                   "netif_in_pkts",
-                   "netif_in_errs",
-                   "netif_in_drop",
-                   "netif_out_kb",
-                   "netif_out_pkts",
-                   "netif_out_errs",
-                   "netif_out_drop",
-                   "vm_page_in",
-                   "vm_page_out",
-                   "vm_swap_in",
-                   "vm_swap_out",
-                   #"vm_mem_total",
-                   #"vm_mem_used",
-                   #"vm_mem_active",
-                   #"vm_mem_inactive",
-                   #"vm_mem_free",
-                   #"vm_mem_buffer",
-                   #"vm_swap_cache",
-                   #"vm_swap_total",
-                   #"vm_swap_used",
-                   #"vm_swap_free",
-                   "cpu_interrupts",
-                   "cpu_switches",
-                   "cpu_forks" ]
-
-    col_count = len(parser.rrd_ds)
-    row_count = len(parser.rrd_records)
-
-    # Process the last row separately, just to make all values numeric.
-    for j in range(col_count):
-        parser.rrd_records[row_count - 1][j] = _make_numeric(parser.rrd_records[row_count - 1][j])
-
-    # Process all other row/columns.
-    last_different_row = row_count - 1
-    current_row = row_count - 2
-    while current_row >= 0:
-        # Check for a different value than the previous row.  If everything is the same
-        # then this is probably just a filler/bogus entry.
-        is_different = False
-        for j in range(col_count):
-            parser.rrd_records[current_row][j] = _make_numeric(parser.rrd_records[current_row][j])
-            if parser.rrd_records[current_row][j] != parser.rrd_records[last_different_row][j]:
-                # We're good.  This is a different row.
-                is_different = True
-
-        if not is_different:
-            # This is a filler/bogus entry.  Just ignore it.
-            for j in range(col_count):
-                parser.rrd_records[current_row][j] = float('nan')
-        else:
-            # Some tags need to be converted into deltas.
-            for j in range(col_count):
-                if parser.rrd_ds[j]["name"] in fixup_tags:
-                    parser.rrd_records[last_different_row][j] = \
-                        parser.rrd_records[last_different_row][j] - parser.rrd_records[current_row][j]
-            last_different_row = current_row
-
-        current_row -= 1
-
-    # Set fixup_tags in the first row to 'nan' since they aren't useful anymore.
-    for j in range(col_count):
-        if parser.rrd_ds[j]["name"] in fixup_tags:
-            parser.rrd_records[0][j] = float('nan')
-
-    # Add a timestamp to each row and to the catalog.  Format and name
-    # chosen to match other simulator logging (hopefully).
-    start_time = parser.rrd_last_update - (parser.rrd_step * (row_count - 1))
-    # Build a filtered list of rrd_records if we are limited to a time range.
-    filter_records = False
-    if filter_start_time is not None or filter_end_time is not None:
-        filter_records = True
-        filtered_rrd_records = []
-        if filter_start_time is None:
-            filter_start_time = start_time * 1000
-        if filter_end_time is None:
-            filter_end_time = parser.rrd_last_update * 1000
-        
-    for i in range(row_count):
-        record_timestamp = (start_time + (i * parser.rrd_step)) * 1000
-        parser.rrd_records[i].insert(0, record_timestamp)
-        if filter_records:
-            if filter_start_time <= record_timestamp and record_timestamp <= filter_end_time:
-                filtered_rrd_records.append(parser.rrd_records[i])
-
-    if filter_records:
-        parser.rrd_records = filtered_rrd_records
-
-    parser.rrd_ds.insert(0, {"type": "GAUGE", "name": "javascript_timestamp"})
-
-
-def main(argv=None):
-    opts, args = getopt.getopt(sys.argv[1:], "i:o:h", ["in=", "out=", "help"])
-    input_file = sys.stdin
-    output_file = sys.stdout
-    for o, a in opts:
-        if o in ("-i", "--in"):
-            input_file = open(a, 'r')
-        if o in ("-o", "--out"):
-            output_file = open(a, 'w')
-        if o in ("-h", "--help"):
-            usage()
-            sys.exit(0)
-
-    # Using the SAX parser as it is at least 4X faster and far, far
-    # smaller on this dataset than the DOM-based interface in xml.dom.minidom.
-    # With SAX and a 5.4MB xml file, this requires about seven seconds of
-    # wall-clock time and 32MB VSZ.  With the DOM interface, about 22 seconds
-    # and over 270MB VSZ.
-
-    handler = SimPerfHostXMLParser()
-    sax.parse(input_file, handler)
-    if input_file != sys.stdin:
-        input_file.close()
-
-    # Various format fixups:  string-to-num, gauge-to-counts, add
-    # a time stamp, etc.
-    simperf_host_xml_fixup(handler)
-    
-    # Create JSONable dict with interesting data and format/print it
-    print >>output_file, simplejson.dumps({ "step" : handler.rrd_step,
-                                            "lastupdate": handler.rrd_last_update * 1000,
-                                            "ds" : handler.rrd_ds,
-                                            "database" : handler.rrd_records })
-
-    return 0
-
-if __name__ == "__main__":
-    sys.exit(main())
diff --git a/indra/lib/python/indra/util/simperf_oprof_interface.py b/indra/lib/python/indra/util/simperf_oprof_interface.py
deleted file mode 100755
index 547d2f9980989b846b4898a96ed2bcd18372ba89..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/simperf_oprof_interface.py
+++ /dev/null
@@ -1,167 +0,0 @@
-#!/usr/bin/env python
-"""\
-@file simperf_oprof_interface.py
-@brief Manage OProfile data collection on a host
-
-$LicenseInfo:firstyear=2008&license=mit$
-
-Copyright (c) 2008-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-import sys, os, getopt
-import simplejson
-
-
-def usage():
-    print "Usage:"
-    print sys.argv[0] + " [options]"
-    print "  Digest the OProfile report forms that come out of the"
-    print "  simperf_oprof_ctl program's -r/--report command.  The result"
-    print "  is an array of dictionaires with the following keys:"
-    print 
-    print "     symbol        Name of sampled, calling, or called procedure"
-    print "     file          Executable or library where symbol resides"
-    print "     percentage    Percentage contribution to profile, calls or called"
-    print "     samples       Sample count"
-    print "     calls         Methods called by the method in question (full only)"
-    print "     called_by     Methods calling the method (full only)"
-    print 
-    print "  For 'full' reports the two keys 'calls' and 'called_by' are"
-    print "  themselves arrays of dictionaries based on the first four keys."
-    print
-    print "Return Codes:"
-    print "  None.  Aggressively digests everything.  Will likely mung results"
-    print "  if a program or library has whitespace in its name."
-    print
-    print "Options:"
-    print "  -i, --in      Input settings filename.  (Default:  stdin)"
-    print "  -o, --out     Output settings filename.  (Default:  stdout)"
-    print "  -h, --help    Print this message and exit."
-    print
-    print "Interfaces:"
-    print "   class SimPerfOProfileInterface()"
-    
-class SimPerfOProfileInterface:
-    def __init__(self):
-        self.isBrief = True             # public
-        self.isValid = False            # public
-        self.result = []                # public
-
-    def parse(self, input):
-        in_samples = False
-        for line in input:
-            if in_samples:
-                if line[0:6] == "------":
-                    self.isBrief = False
-                    self._parseFull(input)
-                else:
-                    self._parseBrief(input, line)
-                self.isValid = True
-                return
-            try:
-                hd1, remain = line.split(None, 1)
-                if hd1 == "samples":
-                    in_samples = True
-            except ValueError:
-                pass
-
-    def _parseBrief(self, input, line1):
-        try:
-            fld1, fld2, fld3, fld4 = line1.split(None, 3)
-            self.result.append({"samples" : fld1,
-                                "percentage" : fld2,
-                                "file" : fld3,
-                                "symbol" : fld4.strip("\n")})
-        except ValueError:
-            pass
-        for line in input:
-            try:
-                fld1, fld2, fld3, fld4 = line.split(None, 3)
-                self.result.append({"samples" : fld1,
-                                    "percentage" : fld2,
-                                    "file" : fld3,
-                                    "symbol" : fld4.strip("\n")})
-            except ValueError:
-                pass
-
-    def _parseFull(self, input):
-        state = 0       # In 'called_by' section
-        calls = []
-        called_by = []
-        current = {}
-        for line in input:
-            if line[0:6] == "------":
-                if len(current):
-                    current["calls"] = calls
-                    current["called_by"] = called_by
-                    self.result.append(current)
-                state = 0
-                calls = []
-                called_by = []
-                current = {}
-            else:
-                try:
-                    fld1, fld2, fld3, fld4 = line.split(None, 3)
-                    tmp = {"samples" : fld1,
-                           "percentage" : fld2,
-                           "file" : fld3,
-                           "symbol" : fld4.strip("\n")}
-                except ValueError:
-                    continue
-                if line[0] != " ":
-                    current = tmp
-                    state = 1       # In 'calls' section
-                elif state == 0:
-                    called_by.append(tmp)
-                else:
-                    calls.append(tmp)
-        if len(current):
-            current["calls"] = calls
-            current["called_by"] = called_by
-            self.result.append(current)
-
-
-def main(argv=None):
-    opts, args = getopt.getopt(sys.argv[1:], "i:o:h", ["in=", "out=", "help"])
-    input_file = sys.stdin
-    output_file = sys.stdout
-    for o, a in opts:
-        if o in ("-i", "--in"):
-            input_file = open(a, 'r')
-        if o in ("-o", "--out"):
-            output_file = open(a, 'w')
-        if o in ("-h", "--help"):
-            usage()
-            sys.exit(0)
-
-    oprof = SimPerfOProfileInterface()
-    oprof.parse(input_file)
-    if input_file != sys.stdin:
-        input_file.close()
-
-    # Create JSONable dict with interesting data and format/print it
-    print >>output_file, simplejson.dumps(oprof.result)
-
-    return 0
-
-if __name__ == "__main__":
-    sys.exit(main())
diff --git a/indra/lib/python/indra/util/simperf_proc_interface.py b/indra/lib/python/indra/util/simperf_proc_interface.py
deleted file mode 100755
index de061f68ccfda36277b0bb2f558d464c03b3bcc7..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/simperf_proc_interface.py
+++ /dev/null
@@ -1,191 +0,0 @@
-#!/usr/bin/env python
-"""\
-@file simperf_proc_interface.py
-@brief Utility to extract log messages from *.<pid>.llsd files containing performance statistics.
-
-$LicenseInfo:firstyear=2008&license=mit$
-
-Copyright (c) 2008-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-"""
-
-# ----------------------------------------------------
-# Utility to extract log messages from *.<pid>.llsd
-# files that contain performance statistics.
-
-# ----------------------------------------------------
-import sys, os
-
-if os.path.exists("setup-path.py"):
-    execfile("setup-path.py")
-
-from indra.base import llsd
-
-DEFAULT_PATH="/dev/shm/simperf/"
-
-
-# ----------------------------------------------------
-# Pull out the stats and return a single document
-def parse_logfile(filename, target_column=None, verbose=False):
-    full_doc = []
-    # Open source temp log file.  Let exceptions percolate up.
-    sourcefile = open( filename,'r')
-        
-    if verbose:
-        print "Reading " + filename  
-    
-    # Parse and output all lines from the temp file
-    for line in sourcefile.xreadlines():
-        partial_doc = llsd.parse(line)
-        if partial_doc is not None:
-            if target_column is None:
-                full_doc.append(partial_doc)
-            else:
-                trim_doc = { target_column: partial_doc[target_column] }
-                if target_column != "fps":
-                    trim_doc[ 'fps' ] = partial_doc[ 'fps' ]
-                trim_doc[ '/total_time' ] = partial_doc[ '/total_time' ]
-                trim_doc[ 'utc_time' ] = partial_doc[ 'utc_time' ]
-                full_doc.append(trim_doc)
-
-    sourcefile.close()
-    return full_doc
-
-# Extract just the meta info line, and the timestamp of the first/last frame entry.
-def parse_logfile_info(filename, verbose=False):
-    # Open source temp log file.  Let exceptions percolate up.
-    sourcefile = open(filename, 'rU') # U is to open with Universal newline support
-        
-    if verbose:
-        print "Reading " + filename  
-
-    # The first line is the meta info line.
-    info_line = sourcefile.readline()
-    if not info_line:
-        sourcefile.close()
-        return None
-
-    # The rest of the lines are frames.  Read the first and last to get the time range.
-    info = llsd.parse( info_line )
-    info['start_time'] = None
-    info['end_time'] = None
-    first_frame = sourcefile.readline()
-    if first_frame:
-        try:
-            info['start_time'] = int(llsd.parse(first_frame)['timestamp'])
-        except:
-            pass
-
-    # Read the file backwards to find the last two lines.
-    sourcefile.seek(0, 2)
-    file_size = sourcefile.tell()
-    offset = 1024
-    num_attempts = 0
-    end_time = None
-    if file_size < offset:
-        offset = file_size
-    while 1:
-        sourcefile.seek(-1*offset, 2)
-        read_str = sourcefile.read(offset)
-        # Remove newline at the end
-        if read_str[offset - 1] == '\n':
-            read_str = read_str[0:-1]
-        lines = read_str.split('\n')
-        full_line = None
-        if len(lines) > 2:  # Got two line
-            try:
-                end_time = llsd.parse(lines[-1])['timestamp']
-            except:
-                # We couldn't parse this line.  Try once more.
-                try:
-                    end_time = llsd.parse(lines[-2])['timestamp']
-                except:
-                    # Nope.  Just move on.
-                    pass
-            break
-        if len(read_str) == file_size:   # Reached the beginning
-            break
-        offset += 1024
-
-    info['end_time'] = int(end_time)
-
-    sourcefile.close()
-    return info
-    
-
-def parse_proc_filename(filename):
-    try:
-        name_as_list = filename.split(".")
-        cur_stat_type = name_as_list[0].split("_")[0]
-        cur_pid = name_as_list[1]
-    except IndexError, ValueError:
-        return (None, None)
-    return (cur_pid, cur_stat_type)
-
-# ----------------------------------------------------
-def get_simstats_list(path=None):
-    """ Return stats (pid, type) listed in <type>_proc.<pid>.llsd """
-    if path is None:
-        path = DEFAULT_PATH
-    simstats_list = []
-    for file_name in os.listdir(path):
-        if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd":
-            simstats_info = parse_logfile_info(path + file_name)
-            if simstats_info is not None:
-                simstats_list.append(simstats_info)
-    return simstats_list
-
-def get_log_info_list(pid=None, stat_type=None, path=None, target_column=None, verbose=False):
-    """ Return data from all llsd files matching the pid and stat type """
-    if path is None:
-        path = DEFAULT_PATH
-    log_info_list = {}
-    for file_name in os.listdir ( path ):
-        if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd":
-            (cur_pid, cur_stat_type) = parse_proc_filename(file_name)
-            if cur_pid is None:
-                continue
-            if pid is not None and pid != cur_pid:
-                continue
-            if stat_type is not None and stat_type != cur_stat_type:
-                continue
-            log_info_list[cur_pid] = parse_logfile(path + file_name, target_column, verbose)
-    return log_info_list
-
-def delete_simstats_files(pid=None, stat_type=None, path=None):
-    """ Delete *.<pid>.llsd files """
-    if path is None:
-        path = DEFAULT_PATH
-    del_list = []
-    for file_name in os.listdir(path):
-        if file_name.endswith(".llsd") and file_name != "simperf_proc_config.llsd":
-            (cur_pid, cur_stat_type) = parse_proc_filename(file_name)
-            if cur_pid is None:
-                continue
-            if pid is not None and pid != cur_pid:
-                continue
-            if stat_type is not None and stat_type != cur_stat_type:
-                continue
-            del_list.append(cur_pid)
-            # Allow delete related exceptions to percolate up if this fails.
-            os.unlink(os.path.join(DEFAULT_PATH, file_name))
-    return del_list
-
diff --git a/indra/lib/python/indra/util/term.py b/indra/lib/python/indra/util/term.py
deleted file mode 100755
index 8c316a1f1209e9e56d3657877db810383bf61e35..0000000000000000000000000000000000000000
--- a/indra/lib/python/indra/util/term.py
+++ /dev/null
@@ -1,222 +0,0 @@
-'''
-@file term.py
-@brief a better shutil.copytree replacement
-
-$LicenseInfo:firstyear=2007&license=mit$
-
-Copyright (c) 2007-2009, Linden Research, Inc.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in
-all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
-$/LicenseInfo$
-'''
-
-#http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/475116
-
-import sys, re
-
-class TerminalController:
-    """
-    A class that can be used to portably generate formatted output to
-    a terminal.  
-    
-    `TerminalController` defines a set of instance variables whose
-    values are initialized to the control sequence necessary to
-    perform a given action.  These can be simply included in normal
-    output to the terminal:
-
-        >>> term = TerminalController()
-        >>> print 'This is '+term.GREEN+'green'+term.NORMAL
-
-    Alternatively, the `render()` method can used, which replaces
-    '${action}' with the string required to perform 'action':
-
-        >>> term = TerminalController()
-        >>> print term.render('This is ${GREEN}green${NORMAL}')
-
-    If the terminal doesn't support a given action, then the value of
-    the corresponding instance variable will be set to ''.  As a
-    result, the above code will still work on terminals that do not
-    support color, except that their output will not be colored.
-    Also, this means that you can test whether the terminal supports a
-    given action by simply testing the truth value of the
-    corresponding instance variable:
-
-        >>> term = TerminalController()
-        >>> if term.CLEAR_SCREEN:
-        ...     print 'This terminal supports clearning the screen.'
-
-    Finally, if the width and height of the terminal are known, then
-    they will be stored in the `COLS` and `LINES` attributes.
-    """
-    # Cursor movement:
-    BOL = ''             #: Move the cursor to the beginning of the line
-    UP = ''              #: Move the cursor up one line
-    DOWN = ''            #: Move the cursor down one line
-    LEFT = ''            #: Move the cursor left one char
-    RIGHT = ''           #: Move the cursor right one char
-
-    # Deletion:
-    CLEAR_SCREEN = ''    #: Clear the screen and move to home position
-    CLEAR_EOL = ''       #: Clear to the end of the line.
-    CLEAR_BOL = ''       #: Clear to the beginning of the line.
-    CLEAR_EOS = ''       #: Clear to the end of the screen
-
-    # Output modes:
-    BOLD = ''            #: Turn on bold mode
-    BLINK = ''           #: Turn on blink mode
-    DIM = ''             #: Turn on half-bright mode
-    REVERSE = ''         #: Turn on reverse-video mode
-    NORMAL = ''          #: Turn off all modes
-
-    # Cursor display:
-    HIDE_CURSOR = ''     #: Make the cursor invisible
-    SHOW_CURSOR = ''     #: Make the cursor visible
-
-    # Terminal size:
-    COLS = None          #: Width of the terminal (None for unknown)
-    LINES = None         #: Height of the terminal (None for unknown)
-
-    # Foreground colors:
-    BLACK = BLUE = GREEN = CYAN = RED = MAGENTA = YELLOW = WHITE = ''
-    
-    # Background colors:
-    BG_BLACK = BG_BLUE = BG_GREEN = BG_CYAN = ''
-    BG_RED = BG_MAGENTA = BG_YELLOW = BG_WHITE = ''
-    
-    _STRING_CAPABILITIES = """
-    BOL=cr UP=cuu1 DOWN=cud1 LEFT=cub1 RIGHT=cuf1
-    CLEAR_SCREEN=clear CLEAR_EOL=el CLEAR_BOL=el1 CLEAR_EOS=ed BOLD=bold
-    BLINK=blink DIM=dim REVERSE=rev UNDERLINE=smul NORMAL=sgr0
-    HIDE_CURSOR=cinvis SHOW_CURSOR=cnorm""".split()
-    _COLORS = """BLACK BLUE GREEN CYAN RED MAGENTA YELLOW WHITE""".split()
-    _ANSICOLORS = "BLACK RED GREEN YELLOW BLUE MAGENTA CYAN WHITE".split()
-
-    def __init__(self, term_stream=sys.stdout):
-        """
-        Create a `TerminalController` and initialize its attributes
-        with appropriate values for the current terminal.
-        `term_stream` is the stream that will be used for terminal
-        output; if this stream is not a tty, then the terminal is
-        assumed to be a dumb terminal (i.e., have no capabilities).
-        """
-        # Curses isn't available on all platforms
-        try: import curses
-        except: return
-
-        # If the stream isn't a tty, then assume it has no capabilities.
-        if not term_stream.isatty(): return
-
-        # Check the terminal type.  If we fail, then assume that the
-        # terminal has no capabilities.
-        try: curses.setupterm()
-        except: return
-
-        # Look up numeric capabilities.
-        self.COLS = curses.tigetnum('cols')
-        self.LINES = curses.tigetnum('lines')
-        
-        # Look up string capabilities.
-        for capability in self._STRING_CAPABILITIES:
-            (attrib, cap_name) = capability.split('=')
-            setattr(self, attrib, self._tigetstr(cap_name) or '')
-
-        # Colors
-        set_fg = self._tigetstr('setf')
-        if set_fg:
-            for i,color in zip(range(len(self._COLORS)), self._COLORS):
-                setattr(self, color, curses.tparm(set_fg, i) or '')
-        set_fg_ansi = self._tigetstr('setaf')
-        if set_fg_ansi:
-            for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
-                setattr(self, color, curses.tparm(set_fg_ansi, i) or '')
-        set_bg = self._tigetstr('setb')
-        if set_bg:
-            for i,color in zip(range(len(self._COLORS)), self._COLORS):
-                setattr(self, 'BG_'+color, curses.tparm(set_bg, i) or '')
-        set_bg_ansi = self._tigetstr('setab')
-        if set_bg_ansi:
-            for i,color in zip(range(len(self._ANSICOLORS)), self._ANSICOLORS):
-                setattr(self, 'BG_'+color, curses.tparm(set_bg_ansi, i) or '')
-
-    def _tigetstr(self, cap_name):
-        # String capabilities can include "delays" of the form "$<2>".
-        # For any modern terminal, we should be able to just ignore
-        # these, so strip them out.
-        import curses
-        cap = curses.tigetstr(cap_name) or ''
-        return re.sub(r'\$<\d+>[/*]?', '', cap)
-
-    def render(self, template):
-        """
-        Replace each $-substitutions in the given template string with
-        the corresponding terminal control string (if it's defined) or
-        '' (if it's not).
-        """
-        return re.sub(r'\$\$|\${\w+}', self._render_sub, template)
-
-    def _render_sub(self, match):
-        s = match.group()
-        if s == '$$': return s
-        else: return getattr(self, s[2:-1])
-
-#######################################################################
-# Example use case: progress bar
-#######################################################################
-
-class ProgressBar:
-    """
-    A 3-line progress bar, which looks like::
-    
-                                Header
-        20% [===========----------------------------------]
-                           progress message
-
-    The progress bar is colored, if the terminal supports color
-    output; and adjusts to the width of the terminal.
-    """
-    BAR = '%3d%% ${GREEN}[${BOLD}%s%s${NORMAL}${GREEN}]${NORMAL}\n'
-    HEADER = '${BOLD}${CYAN}%s${NORMAL}\n\n'
-        
-    def __init__(self, term, header):
-        self.term = term
-        if not (self.term.CLEAR_EOL and self.term.UP and self.term.BOL):
-            raise ValueError("Terminal isn't capable enough -- you "
-                             "should use a simpler progress dispaly.")
-        self.width = self.term.COLS or 75
-        self.bar = term.render(self.BAR)
-        self.header = self.term.render(self.HEADER % header.center(self.width))
-        self.cleared = 1 #: true if we haven't drawn the bar yet.
-        self.update(0, '')
-
-    def update(self, percent, message):
-        if self.cleared:
-            sys.stdout.write(self.header)
-            self.cleared = 0
-        n = int((self.width-10)*percent)
-        sys.stdout.write(
-            self.term.BOL + self.term.UP + self.term.CLEAR_EOL +
-            (self.bar % (100*percent, '='*n, '-'*(self.width-10-n))) +
-            self.term.CLEAR_EOL + message.center(self.width))
-
-    def clear(self):
-        if not self.cleared:
-            sys.stdout.write(self.term.BOL + self.term.CLEAR_EOL +
-                             self.term.UP + self.term.CLEAR_EOL +
-                             self.term.UP + self.term.CLEAR_EOL)
-            self.cleared = 1
diff --git a/indra/lib/python/uuid.py b/indra/lib/python/uuid.py
deleted file mode 100755
index e956383ccabbdc4b425f16096bad95f3aa9db7e7..0000000000000000000000000000000000000000
--- a/indra/lib/python/uuid.py
+++ /dev/null
@@ -1,508 +0,0 @@
-#!/usr/bin/python
-## $LicenseInfo:firstyear=2011&license=viewerlgpl$
-## Second Life Viewer Source Code
-## Copyright (C) 2011, Linden Research, Inc.
-## 
-## This library is free software; you can redistribute it and/or
-## modify it under the terms of the GNU Lesser General Public
-## License as published by the Free Software Foundation;
-## version 2.1 of the License only.
-## 
-## This library is distributed in the hope that it will be useful,
-## but WITHOUT ANY WARRANTY; without even the implied warranty of
-## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-## Lesser General Public License for more details.
-## 
-## You should have received a copy of the GNU Lesser General Public
-## License along with this library; if not, write to the Free Software
-## Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-## 
-## Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-## $/LicenseInfo$
-r"""UUID objects (universally unique identifiers) according to RFC 4122.
-
-This module provides immutable UUID objects (class UUID) and the functions
-uuid1(), uuid3(), uuid4(), uuid5() for generating version 1, 3, 4, and 5
-UUIDs as specified in RFC 4122.
-
-If all you want is a unique ID, you should probably call uuid1() or uuid4().
-Note that uuid1() may compromise privacy since it creates a UUID containing
-the computer's network address.  uuid4() creates a random UUID.
-
-Typical usage:
-
-    >>> import uuid
-
-    # make a UUID based on the host ID and current time
-    >>> uuid.uuid1()
-    UUID('a8098c1a-f86e-11da-bd1a-00112444be1e')
-
-    # make a UUID using an MD5 hash of a namespace UUID and a name
-    >>> uuid.uuid3(uuid.NAMESPACE_DNS, 'python.org')
-    UUID('6fa459ea-ee8a-3ca4-894e-db77e160355e')
-
-    # make a random UUID
-    >>> uuid.uuid4()
-    UUID('16fd2706-8baf-433b-82eb-8c7fada847da')
-
-    # make a UUID using a SHA-1 hash of a namespace UUID and a name
-    >>> uuid.uuid5(uuid.NAMESPACE_DNS, 'python.org')
-    UUID('886313e1-3b8a-5372-9b90-0c9aee199e5d')
-
-    # make a UUID from a string of hex digits (braces and hyphens ignored)
-    >>> x = uuid.UUID('{00010203-0405-0607-0809-0a0b0c0d0e0f}')
-
-    # convert a UUID to a string of hex digits in standard form
-    >>> str(x)
-    '00010203-0405-0607-0809-0a0b0c0d0e0f'
-
-    # get the raw 16 bytes of the UUID
-    >>> x.bytes
-    '\x00\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f'
-
-    # make a UUID from a 16-byte string
-    >>> uuid.UUID(bytes=x.bytes)
-    UUID('00010203-0405-0607-0809-0a0b0c0d0e0f')
-
-This module works with Python 2.3 or higher."""
-
-__author__ = 'Ka-Ping Yee <ping@zesty.ca>'
-__date__ = '$Date: 2006/06/12 23:15:40 $'.split()[1].replace('/', '-')
-__version__ = '$Revision: 1.30 $'.split()[1]
-
-RESERVED_NCS, RFC_4122, RESERVED_MICROSOFT, RESERVED_FUTURE = [
-    'reserved for NCS compatibility', 'specified in RFC 4122',
-    'reserved for Microsoft compatibility', 'reserved for future definition']
-
-class UUID(object):
-    """Instances of the UUID class represent UUIDs as specified in RFC 4122.
-    UUID objects are immutable, hashable, and usable as dictionary keys.
-    Converting a UUID to a string with str() yields something in the form
-    '12345678-1234-1234-1234-123456789abc'.  The UUID constructor accepts
-    four possible forms: a similar string of hexadecimal digits, or a
-    string of 16 raw bytes as an argument named 'bytes', or a tuple of
-    six integer fields (with 32-bit, 16-bit, 16-bit, 8-bit, 8-bit, and
-    48-bit values respectively) as an argument named 'fields', or a single
-    128-bit integer as an argument named 'int'.
-    
-    UUIDs have these read-only attributes:
-
-        bytes       the UUID as a 16-byte string
-
-        fields      a tuple of the six integer fields of the UUID,
-                    which are also available as six individual attributes
-                    and two derived attributes:
-
-            time_low                the first 32 bits of the UUID
-            time_mid                the next 16 bits of the UUID
-            time_hi_version         the next 16 bits of the UUID
-            clock_seq_hi_variant    the next 8 bits of the UUID
-            clock_seq_low           the next 8 bits of the UUID
-            node                    the last 48 bits of the UUID
-
-            time                    the 60-bit timestamp
-            clock_seq               the 14-bit sequence number
-
-        hex         the UUID as a 32-character hexadecimal string
-
-        int         the UUID as a 128-bit integer
-
-        urn         the UUID as a URN as specified in RFC 4122
-
-        variant     the UUID variant (one of the constants RESERVED_NCS,
-                    RFC_4122, RESERVED_MICROSOFT, or RESERVED_FUTURE)
-
-        version     the UUID version number (1 through 5, meaningful only
-                    when the variant is RFC_4122)
-    """
-
-    def __init__(self, hex=None, bytes=None, fields=None, int=None,
-                       version=None):
-        r"""Create a UUID from either a string of 32 hexadecimal digits,
-        a string of 16 bytes as the 'bytes' argument, a tuple of six
-        integers (32-bit time_low, 16-bit time_mid, 16-bit time_hi_version,
-        8-bit clock_seq_hi_variant, 8-bit clock_seq_low, 48-bit node) as
-        the 'fields' argument, or a single 128-bit integer as the 'int'
-        argument.  When a string of hex digits is given, curly braces,
-        hyphens, and a URN prefix are all optional.  For example, these
-        expressions all yield the same UUID:
-
-        UUID('{12345678-1234-5678-1234-567812345678}')
-        UUID('12345678123456781234567812345678')
-        UUID('urn:uuid:12345678-1234-5678-1234-567812345678')
-        UUID(bytes='\x12\x34\x56\x78'*4)
-        UUID(fields=(0x12345678, 0x1234, 0x5678, 0x12, 0x34, 0x567812345678))
-        UUID(int=0x12345678123456781234567812345678)
-
-        Exactly one of 'hex', 'bytes', 'fields', or 'int' must be given.
-        The 'version' argument is optional; if given, the resulting UUID
-        will have its variant and version number set according to RFC 4122,
-        overriding bits in the given 'hex', 'bytes', 'fields', or 'int'.
-        """
-
-        if [hex, bytes, fields, int].count(None) != 3:
-            raise TypeError('need just one of hex, bytes, fields, or int')
-        if hex is not None:
-            hex = hex.replace('urn:', '').replace('uuid:', '')
-            hex = hex.strip('{}').replace('-', '')
-            if len(hex) != 32:
-                raise ValueError('badly formed hexadecimal UUID string')
-            int = long(hex, 16)
-        if bytes is not None:
-            if len(bytes) != 16:
-                raise ValueError('bytes is not a 16-char string')
-            int = long(('%02x'*16) % tuple(map(ord, bytes)), 16)
-        if fields is not None:
-            if len(fields) != 6:
-                raise ValueError('fields is not a 6-tuple')
-            (time_low, time_mid, time_hi_version,
-             clock_seq_hi_variant, clock_seq_low, node) = fields
-            if not 0 <= time_low < 1<<32L:
-                raise ValueError('field 1 out of range (need a 32-bit value)')
-            if not 0 <= time_mid < 1<<16L:
-                raise ValueError('field 2 out of range (need a 16-bit value)')
-            if not 0 <= time_hi_version < 1<<16L:
-                raise ValueError('field 3 out of range (need a 16-bit value)')
-            if not 0 <= clock_seq_hi_variant < 1<<8L:
-                raise ValueError('field 4 out of range (need an 8-bit value)')
-            if not 0 <= clock_seq_low < 1<<8L:
-                raise ValueError('field 5 out of range (need an 8-bit value)')
-            if not 0 <= node < 1<<48L:
-                raise ValueError('field 6 out of range (need a 48-bit value)')
-            clock_seq = (clock_seq_hi_variant << 8L) | clock_seq_low
-            int = ((time_low << 96L) | (time_mid << 80L) |
-                   (time_hi_version << 64L) | (clock_seq << 48L) | node)
-        if int is not None:
-            if not 0 <= int < 1<<128L:
-                raise ValueError('int is out of range (need a 128-bit value)')
-        if version is not None:
-            if not 1 <= version <= 5:
-                raise ValueError('illegal version number')
-            # Set the variant to RFC 4122.
-            int &= ~(0xc000 << 48L)
-            int |= 0x8000 << 48L
-            # Set the version number.
-            int &= ~(0xf000 << 64L)
-            int |= version << 76L
-        self.__dict__['int'] = int
-
-    def __cmp__(self, other):
-        if isinstance(other, UUID):
-            return cmp(self.int, other.int)
-        return NotImplemented
-
-    def __hash__(self):
-        return hash(self.int)
-
-    def __int__(self):
-        return self.int
-
-    def __repr__(self):
-        return 'UUID(%r)' % str(self)
-
-    def __setattr__(self, name, value):
-        raise TypeError('UUID objects are immutable')
-
-    def __str__(self):
-        hex = '%032x' % self.int
-        return '%s-%s-%s-%s-%s' % (
-            hex[:8], hex[8:12], hex[12:16], hex[16:20], hex[20:])
-
-    def get_bytes(self):
-        bytes = ''
-        for shift in range(0, 128, 8):
-            bytes = chr((self.int >> shift) & 0xff) + bytes
-        return bytes
-
-    bytes = property(get_bytes)
-
-    def get_fields(self):
-        return (self.time_low, self.time_mid, self.time_hi_version,
-                self.clock_seq_hi_variant, self.clock_seq_low, self.node)
-
-    fields = property(get_fields)
-
-    def get_time_low(self):
-        return self.int >> 96L
-   
-    time_low = property(get_time_low)
-
-    def get_time_mid(self):
-        return (self.int >> 80L) & 0xffff
-
-    time_mid = property(get_time_mid)
-
-    def get_time_hi_version(self):
-        return (self.int >> 64L) & 0xffff
-    
-    time_hi_version = property(get_time_hi_version)
-
-    def get_clock_seq_hi_variant(self):
-        return (self.int >> 56L) & 0xff
-
-    clock_seq_hi_variant = property(get_clock_seq_hi_variant)
-    
-    def get_clock_seq_low(self):
-        return (self.int >> 48L) & 0xff
-
-    clock_seq_low = property(get_clock_seq_low)
-
-    def get_time(self):
-        return (((self.time_hi_version & 0x0fffL) << 48L) |
-                (self.time_mid << 32L) | self.time_low)
-
-    time = property(get_time)
-
-    def get_clock_seq(self):
-        return (((self.clock_seq_hi_variant & 0x3fL) << 8L) |
-                self.clock_seq_low)
-
-    clock_seq = property(get_clock_seq)
-    
-    def get_node(self):
-        return self.int & 0xffffffffffff
-
-    node = property(get_node)
-
-    def get_hex(self):
-        return '%032x' % self.int
-
-    hex = property(get_hex)
-
-    def get_urn(self):
-        return 'urn:uuid:' + str(self)
-
-    urn = property(get_urn)
-
-    def get_variant(self):
-        if not self.int & (0x8000 << 48L):
-            return RESERVED_NCS
-        elif not self.int & (0x4000 << 48L):
-            return RFC_4122
-        elif not self.int & (0x2000 << 48L):
-            return RESERVED_MICROSOFT
-        else:
-            return RESERVED_FUTURE
-
-    variant = property(get_variant)
-
-    def get_version(self):
-        # The version bits are only meaningful for RFC 4122 UUIDs.
-        if self.variant == RFC_4122:
-            return int((self.int >> 76L) & 0xf)
-
-    version = property(get_version)
-
-def _ifconfig_getnode():
-    """Get the hardware address on Unix by running ifconfig."""
-    import os
-    for dir in ['', '/sbin/', '/usr/sbin']:
-        try:
-            path = os.path.join(dir, 'ifconfig')
-            if os.path.exists(path):
-                pipe = os.popen(path)
-            else:
-                continue
-        except IOError:
-            continue
-        for line in pipe:
-            words = line.lower().split()
-            for i in range(len(words)):
-                if words[i] in ['hwaddr', 'ether']:
-                    return int(words[i + 1].replace(':', ''), 16)
-
-def _ipconfig_getnode():
-    """Get the hardware address on Windows by running ipconfig.exe."""
-    import os, re
-    dirs = ['', r'c:\windows\system32', r'c:\winnt\system32']
-    try:
-        import ctypes
-        buffer = ctypes.create_string_buffer(300)
-        ctypes.windll.kernel32.GetSystemDirectoryA(buffer, 300)
-        dirs.insert(0, buffer.value.decode('mbcs'))
-    except:
-        pass
-    for dir in dirs:
-        try:
-            pipe = os.popen(os.path.join(dir, 'ipconfig') + ' /all')
-        except IOError:
-            continue
-        for line in pipe:
-            value = line.split(':')[-1].strip().lower()
-            if re.match('([0-9a-f][0-9a-f]-){5}[0-9a-f][0-9a-f]', value):
-                return int(value.replace('-', ''), 16)
-
-def _netbios_getnode():
-    """Get the hardware address on Windows using NetBIOS calls.
-    See http://support.microsoft.com/kb/118623 for details."""
-    import win32wnet, netbios
-    ncb = netbios.NCB()
-    ncb.Command = netbios.NCBENUM
-    ncb.Buffer = adapters = netbios.LANA_ENUM()
-    adapters._pack()
-    if win32wnet.Netbios(ncb) != 0:
-        return
-    adapters._unpack()
-    for i in range(adapters.length):
-        ncb.Reset()
-        ncb.Command = netbios.NCBRESET
-        ncb.Lana_num = ord(adapters.lana[i])
-        if win32wnet.Netbios(ncb) != 0:
-            continue
-        ncb.Reset()
-        ncb.Command = netbios.NCBASTAT
-        ncb.Lana_num = ord(adapters.lana[i])
-        ncb.Callname = '*'.ljust(16)
-        ncb.Buffer = status = netbios.ADAPTER_STATUS()
-        if win32wnet.Netbios(ncb) != 0:
-            continue
-        status._unpack()
-        bytes = map(ord, status.adapter_address)
-        return ((bytes[0]<<40L) + (bytes[1]<<32L) + (bytes[2]<<24L) +
-                (bytes[3]<<16L) + (bytes[4]<<8L) + bytes[5])
-
-# Thanks to Thomas Heller for ctypes and for his help with its use here.
-
-# If ctypes is available, use it to find system routines for UUID generation.
-_uuid_generate_random = _uuid_generate_time = _UuidCreate = None
-try:
-    import ctypes, ctypes.util
-    _buffer = ctypes.create_string_buffer(16)
-
-    # The uuid_generate_* routines are provided by libuuid on at least
-    # Linux and FreeBSD, and provided by libc on Mac OS X.
-    for libname in ['uuid', 'c']:
-        try:
-            lib = ctypes.CDLL(ctypes.util.find_library(libname))
-        except:
-            continue
-        if hasattr(lib, 'uuid_generate_random'):
-            _uuid_generate_random = lib.uuid_generate_random
-        if hasattr(lib, 'uuid_generate_time'):
-            _uuid_generate_time = lib.uuid_generate_time
-
-    # On Windows prior to 2000, UuidCreate gives a UUID containing the
-    # hardware address.  On Windows 2000 and later, UuidCreate makes a
-    # random UUID and UuidCreateSequential gives a UUID containing the
-    # hardware address.  These routines are provided by the RPC runtime.
-    try:
-        lib = ctypes.windll.rpcrt4
-    except:
-        lib = None
-    _UuidCreate = getattr(lib, 'UuidCreateSequential',
-                          getattr(lib, 'UuidCreate', None))
-except:
-    pass
-
-def _unixdll_getnode():
-    """Get the hardware address on Unix using ctypes."""
-    _uuid_generate_time(_buffer)
-    return UUID(bytes=_buffer.raw).node
-
-def _windll_getnode():
-    """Get the hardware address on Windows using ctypes."""
-    if _UuidCreate(_buffer) == 0:
-        return UUID(bytes=_buffer.raw).node
-
-def _random_getnode():
-    """Get a random node ID, with eighth bit set as suggested by RFC 4122."""
-    import random
-    return random.randrange(0, 1<<48L) | 0x010000000000L
-
-_node = None
-
-def getnode():
-    """Get the hardware address as a 48-bit integer.  The first time this
-    runs, it may launch a separate program, which could be quite slow.  If
-    all attempts to obtain the hardware address fail, we choose a random
-    48-bit number with its eighth bit set to 1 as recommended in RFC 4122."""
-
-    global _node
-    if _node is not None:
-        return _node
-
-    import sys
-    if sys.platform == 'win32':
-        getters = [_windll_getnode, _netbios_getnode, _ipconfig_getnode]
-    else:
-        getters = [_unixdll_getnode, _ifconfig_getnode]
-
-    for getter in getters + [_random_getnode]:
-        try:
-            _node = getter()
-        except:
-            continue
-        if _node is not None:
-            return _node
-
-def uuid1(node=None, clock_seq=None):
-    """Generate a UUID from a host ID, sequence number, and the current time.
-    If 'node' is not given, getnode() is used to obtain the hardware
-    address.  If 'clock_seq' is given, it is used as the sequence number;
-    otherwise a random 14-bit sequence number is chosen."""
-
-    # When the system provides a version-1 UUID generator, use it (but don't
-    # use UuidCreate here because its UUIDs don't conform to RFC 4122).
-    if _uuid_generate_time and node is clock_seq is None:
-        _uuid_generate_time(_buffer)
-        return UUID(bytes=_buffer.raw)
-
-    import time
-    nanoseconds = int(time.time() * 1e9)
-    # 0x01b21dd213814000 is the number of 100-ns intervals between the
-    # UUID epoch 1582-10-15 00:00:00 and the Unix epoch 1970-01-01 00:00:00.
-    timestamp = int(nanoseconds/100) + 0x01b21dd213814000L
-    if clock_seq is None:
-        import random
-        clock_seq = random.randrange(1<<14L) # instead of stable storage
-    time_low = timestamp & 0xffffffffL
-    time_mid = (timestamp >> 32L) & 0xffffL
-    time_hi_version = (timestamp >> 48L) & 0x0fffL
-    clock_seq_low = clock_seq & 0xffL
-    clock_seq_hi_variant = (clock_seq >> 8L) & 0x3fL
-    if node is None:
-        node = getnode()
-    return UUID(fields=(time_low, time_mid, time_hi_version,
-                        clock_seq_hi_variant, clock_seq_low, node), version=1)
-
-def uuid3(namespace, name):
-    """Generate a UUID from the MD5 hash of a namespace UUID and a name."""
-    try:
-        # Python 2.6
-        from hashlib import md5
-    except ImportError:
-        # Python 2.5 and earlier
-        from md5 import new as md5
-        
-    hash = md5(namespace.bytes + name).digest()
-    return UUID(bytes=hash[:16], version=3)
-
-def uuid4():
-    """Generate a random UUID."""
-
-    # When the system provides a version-4 UUID generator, use it.
-    if _uuid_generate_random:
-        _uuid_generate_random(_buffer)
-        return UUID(bytes=_buffer.raw)
-
-    # Otherwise, get randomness from urandom or the 'random' module.
-    try:
-        import os
-        return UUID(bytes=os.urandom(16), version=4)
-    except:
-        import random
-        bytes = [chr(random.randrange(256)) for i in range(16)]
-        return UUID(bytes=bytes, version=4)
-
-def uuid5(namespace, name):
-    """Generate a UUID from the SHA-1 hash of a namespace UUID and a name."""
-    import sha
-    hash = sha.sha(namespace.bytes + name).digest()
-    return UUID(bytes=hash[:16], version=5)
-
-# The following standard UUIDs are for use with uuid3() or uuid5().
-
-NAMESPACE_DNS = UUID('6ba7b810-9dad-11d1-80b4-00c04fd430c8')
-NAMESPACE_URL = UUID('6ba7b811-9dad-11d1-80b4-00c04fd430c8')
-NAMESPACE_OID = UUID('6ba7b812-9dad-11d1-80b4-00c04fd430c8')
-NAMESPACE_X500 = UUID('6ba7b814-9dad-11d1-80b4-00c04fd430c8')
diff --git a/indra/llcharacter/llkeyframemotion.cpp b/indra/llcharacter/llkeyframemotion.cpp
index d16c2731b3450362d5795cd00b177ec0216c8e8f..89f34a92c84f4a362793f09165bc9d01161cb0e2 100644
--- a/indra/llcharacter/llkeyframemotion.cpp
+++ b/indra/llcharacter/llkeyframemotion.cpp
@@ -2243,7 +2243,7 @@ void LLKeyframeMotion::onLoadComplete(LLVFS *vfs,
 	LLCharacter* character = *char_iter;
 
 	// look for an existing instance of this motion
-	LLKeyframeMotion* motionp = (LLKeyframeMotion*) character->findMotion(asset_uuid);
+	LLKeyframeMotion* motionp = dynamic_cast<LLKeyframeMotion*> (character->findMotion(asset_uuid));
 	if (motionp)
 	{
 		if (0 == status)
diff --git a/indra/llcommon/llapr.cpp b/indra/llcommon/llapr.cpp
index a548c96002413ebfaa943a93049a547b2061a4c0..86f407cdb0f8829d3f76d0af3d4fb633589cc0d0 100644
--- a/indra/llcommon/llapr.cpp
+++ b/indra/llcommon/llapr.cpp
@@ -294,9 +294,11 @@ void LLScopedLock::unlock()
 bool ll_apr_warn_status(apr_status_t status)
 {
 	if(APR_SUCCESS == status) return false;
+#if !LL_LINUX
 	char buf[MAX_STRING];	/* Flawfinder: ignore */
 	apr_strerror(status, buf, sizeof(buf));
 	LL_WARNS("APR") << "APR: " << buf << LL_ENDL;
+#endif
 	return true;
 }
 
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 16ae1f06041f98635afac6a3ee9f2fc429323dc6..7887a942e991d2cf033373b5337bd763e03f6de2 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -921,11 +921,6 @@ namespace
 			
 			std::ostringstream message_stream;
 
-			if (show_location && (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation))
-			{
-				message_stream << site.mLocationString << " ";
-			}
-
 			if (show_time && r->wantsTime() && s->mTimeFunction != NULL)
 			{
 				message_stream << s->mTimeFunction() << " ";
@@ -933,17 +928,17 @@ namespace
 
 			if (show_level && r->wantsLevel())
             {
-				message_stream << site.mLevelString;
+				message_stream << site.mLevelString << " ";
             }
 				
 			if (show_tags && r->wantsTags())
 			{
 				message_stream << site.mTagString;
 			}
-			if ((show_level && r->wantsLevel())||
-                (show_tags && r->wantsTags()))
+
+            if (show_location && (r->wantsLocation() || level == LLError::LEVEL_ERROR || s->mPrintLocation))
             {
-                message_stream << " ";
+                message_stream << site.mLocationString << " ";
             }
 
 			if (show_function && r->wantsFunctionName())
diff --git a/indra/llcommon/llevents.cpp b/indra/llcommon/llevents.cpp
index 19d700a3b06073d7793cf0a5a0f066bed8ece11f..97270e4931d7cfc7a0b7196173abffd94a62c728 100644
--- a/indra/llcommon/llevents.cpp
+++ b/indra/llcommon/llevents.cpp
@@ -276,6 +276,8 @@ LLEventPumps::~LLEventPumps()
 #pragma warning (push)
 #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
 #endif
+const std::string LLEventPump::ANONYMOUS = std::string();
+
 
 LLEventPump::LLEventPump(const std::string& name, bool tweak):
     // Register every new instance with LLEventPumps
@@ -314,145 +316,162 @@ LLBoundListener LLEventPump::listen_impl(const std::string& name, const LLEventL
                                          const NameList& after,
                                          const NameList& before)
 {
-    // Check for duplicate name before connecting listener to mSignal
-    ConnectionMap::const_iterator found = mConnections.find(name);
-    // In some cases the user might disconnect a connection explicitly -- or
-    // might use LLEventTrackable to disconnect implicitly. Either way, we can
-    // end up retaining in mConnections a zombie connection object that's
-    // already been disconnected. Such a connection object can't be
-    // reconnected -- nor, in the case of LLEventTrackable, would we want to
-    // try, since disconnection happens with the destruction of the listener
-    // object. That means it's safe to overwrite a disconnected connection
-    // object with the new one we're attempting. The case we want to prevent
-    // is only when the existing connection object is still connected.
-    if (found != mConnections.end() && found->second.connected())
+    float nodePosition = 1.0;
+
+    // if the supplied name is empty we are not interested in the ordering mechanism 
+    // and can bypass attempting to find the optimal location to insert the new 
+    // listener.  We'll just tack it on to the end.
+    if (!name.empty()) // should be the same as testing against ANONYMOUS
     {
+        // Check for duplicate name before connecting listener to mSignal
+        ConnectionMap::const_iterator found = mConnections.find(name);
+        // In some cases the user might disconnect a connection explicitly -- or
+        // might use LLEventTrackable to disconnect implicitly. Either way, we can
+        // end up retaining in mConnections a zombie connection object that's
+        // already been disconnected. Such a connection object can't be
+        // reconnected -- nor, in the case of LLEventTrackable, would we want to
+        // try, since disconnection happens with the destruction of the listener
+        // object. That means it's safe to overwrite a disconnected connection
+        // object with the new one we're attempting. The case we want to prevent
+        // is only when the existing connection object is still connected.
+        if (found != mConnections.end() && found->second.connected())
+        {
         LLTHROW(DupListenerName("Attempt to register duplicate listener name '" + name +
                                 "' on " + typeid(*this).name() + " '" + getName() + "'"));
-    }
-    // Okay, name is unique, try to reconcile its dependencies. Specify a new
-    // "node" value that we never use for an mSignal placement; we'll fix it
-    // later.
-    DependencyMap::node_type& newNode = mDeps.add(name, -1.0, after, before);
-    // What if this listener has been added, removed and re-added? In that
-    // case newNode already has a non-negative value because we never remove a
-    // listener from mDeps. But keep processing uniformly anyway in case the
-    // listener was added back with different dependencies. Then mDeps.sort()
-    // would put it in a different position, and the old newNode placement
-    // value would be wrong, so we'd have to reassign it anyway. Trust that
-    // re-adding a listener with the same dependencies is the trivial case for
-    // mDeps.sort(): it can just replay its cache.
-    DependencyMap::sorted_range sorted_range;
-    try
-    {
-        // Can we pick an order that works including this new entry?
-        sorted_range = mDeps.sort();
-    }
-    catch (const DependencyMap::Cycle& e)
-    {
-        // No: the new node's after/before dependencies have made mDeps
-        // unsortable. If we leave the new node in mDeps, it will continue
-        // to screw up all future attempts to sort()! Pull it out.
-        mDeps.remove(name);
+        }
+        // Okay, name is unique, try to reconcile its dependencies. Specify a new
+        // "node" value that we never use for an mSignal placement; we'll fix it
+        // later.
+        DependencyMap::node_type& newNode = mDeps.add(name, -1.0, after, before);
+        // What if this listener has been added, removed and re-added? In that
+        // case newNode already has a non-negative value because we never remove a
+        // listener from mDeps. But keep processing uniformly anyway in case the
+        // listener was added back with different dependencies. Then mDeps.sort()
+        // would put it in a different position, and the old newNode placement
+        // value would be wrong, so we'd have to reassign it anyway. Trust that
+        // re-adding a listener with the same dependencies is the trivial case for
+        // mDeps.sort(): it can just replay its cache.
+        DependencyMap::sorted_range sorted_range;
+        try
+        {
+            // Can we pick an order that works including this new entry?
+            sorted_range = mDeps.sort();
+        }
+        catch (const DependencyMap::Cycle& e)
+        {
+            // No: the new node's after/before dependencies have made mDeps
+            // unsortable. If we leave the new node in mDeps, it will continue
+            // to screw up all future attempts to sort()! Pull it out.
+            mDeps.remove(name);
         LLTHROW(Cycle("New listener '" + name + "' on " + typeid(*this).name() +
                       " '" + getName() + "' would cause cycle: " + e.what()));
-    }
-    // Walk the list to verify that we haven't changed the order.
-    float previous = 0.0, myprev = 0.0;
-    DependencyMap::sorted_iterator mydmi = sorted_range.end(); // need this visible after loop
-    for (DependencyMap::sorted_iterator dmi = sorted_range.begin();
-         dmi != sorted_range.end(); ++dmi)
-    {
-        // Since we've added the new entry with an invalid placement,
-        // recognize it and skip it.
-        if (dmi->first == name)
-        {
-            // Remember the iterator belonging to our new node, and which
-            // placement value was 'previous' at that point.
-            mydmi = dmi;
-            myprev = previous;
-            continue;
         }
-        // If the new node has rearranged the existing nodes, we'll find
-        // that their placement values are no longer in increasing order.
-        if (dmi->second < previous)
+        // Walk the list to verify that we haven't changed the order.
+        float previous = 0.0, myprev = 0.0;
+        DependencyMap::sorted_iterator mydmi = sorted_range.end(); // need this visible after loop
+        for (DependencyMap::sorted_iterator dmi = sorted_range.begin();
+            dmi != sorted_range.end(); ++dmi)
         {
-            // This is another scenario in which we'd better back out the
-            // newly-added node from mDeps -- but don't do it yet, we want to
-            // traverse the existing mDeps to report on it!
-            // Describe the change to the order of our listeners. Copy
-            // everything but the newest listener to a vector we can sort to
-            // obtain the old order.
-            typedef std::vector< std::pair<float, std::string> > SortNameList;
-            SortNameList sortnames;
-            for (DependencyMap::sorted_iterator cdmi(sorted_range.begin()), cdmend(sorted_range.end());
-                 cdmi != cdmend; ++cdmi)
+            // Since we've added the new entry with an invalid placement,
+            // recognize it and skip it.
+            if (dmi->first == name)
             {
-                if (cdmi->first != name)
-                {
-                    sortnames.push_back(SortNameList::value_type(cdmi->second, cdmi->first));
-                }
+                // Remember the iterator belonging to our new node, and which
+                // placement value was 'previous' at that point.
+                mydmi = dmi;
+                myprev = previous;
+                continue;
             }
-            std::sort(sortnames.begin(), sortnames.end());
-            std::ostringstream out;
-            out << "New listener '" << name << "' on " << typeid(*this).name() << " '" << getName()
-                << "' would move previous listener '" << dmi->first << "'\nwas: ";
-            SortNameList::const_iterator sni(sortnames.begin()), snend(sortnames.end());
-            if (sni != snend)
+            // If the new node has rearranged the existing nodes, we'll find
+            // that their placement values are no longer in increasing order.
+            if (dmi->second < previous)
             {
-                out << sni->second;
-                while (++sni != snend)
+                // This is another scenario in which we'd better back out the
+                // newly-added node from mDeps -- but don't do it yet, we want to
+                // traverse the existing mDeps to report on it!
+                // Describe the change to the order of our listeners. Copy
+                // everything but the newest listener to a vector we can sort to
+                // obtain the old order.
+                typedef std::vector< std::pair<float, std::string> > SortNameList;
+                SortNameList sortnames;
+                for (DependencyMap::sorted_iterator cdmi(sorted_range.begin()), cdmend(sorted_range.end());
+                    cdmi != cdmend; ++cdmi)
                 {
-                    out << ", " << sni->second;
+                    if (cdmi->first != name)
+                    {
+                        sortnames.push_back(SortNameList::value_type(cdmi->second, cdmi->first));
+                    }
                 }
-            }
-            out << "\nnow: ";
-            DependencyMap::sorted_iterator ddmi(sorted_range.begin()), ddmend(sorted_range.end());
-            if (ddmi != ddmend)
-            {
-                out << ddmi->first;
-                while (++ddmi != ddmend)
+                std::sort(sortnames.begin(), sortnames.end());
+                std::ostringstream out;
+                out << "New listener '" << name << "' on " << typeid(*this).name() << " '" << getName()
+                    << "' would move previous listener '" << dmi->first << "'\nwas: ";
+                SortNameList::const_iterator sni(sortnames.begin()), snend(sortnames.end());
+                if (sni != snend)
                 {
-                    out << ", " << ddmi->first;
+                    out << sni->second;
+                    while (++sni != snend)
+                    {
+                        out << ", " << sni->second;
+                    }
                 }
-            }
-            // NOW remove the offending listener node.
-            mDeps.remove(name);
-            // Having constructed a description of the order change, inform caller.
+                out << "\nnow: ";
+                DependencyMap::sorted_iterator ddmi(sorted_range.begin()), ddmend(sorted_range.end());
+                if (ddmi != ddmend)
+                {
+                    out << ddmi->first;
+                    while (++ddmi != ddmend)
+                    {
+                        out << ", " << ddmi->first;
+                    }
+                }
+                // NOW remove the offending listener node.
+                mDeps.remove(name);
+                // Having constructed a description of the order change, inform caller.
             LLTHROW(OrderChange(out.str()));
+            }
+            // This node becomes the previous one.
+            previous = dmi->second;
         }
-        // This node becomes the previous one.
-        previous = dmi->second;
-    }
-    // We just got done with a successful mDeps.add(name, ...) call. We'd
-    // better have found 'name' somewhere in that sorted list!
-    assert(mydmi != sorted_range.end());
-    // Four cases:
-    // 0. name is the only entry: placement 1.0
-    // 1. name is the first of several entries: placement (next placement)/2
-    // 2. name is between two other entries: placement (myprev + (next placement))/2
-    // 3. name is the last entry: placement ceil(myprev) + 1.0
-    // Since we've cleverly arranged for myprev to be 0.0 if name is the
-    // first entry, this folds down to two cases. Case 1 is subsumed by
-    // case 2, and case 0 is subsumed by case 3. So we need only handle
-    // cases 2 and 3, which means we need only detect whether name is the
-    // last entry. Increment mydmi to see if there's anything beyond.
-    if (++mydmi != sorted_range.end())
-    {
-        // The new node isn't last. Place it between the previous node and
-        // the successor.
-        newNode = (myprev + mydmi->second)/2.f;
-    }
-    else
-    {
-        // The new node is last. Bump myprev up to the next integer, add
-        // 1.0 and use that.
-        newNode = std::ceil(myprev) + 1.f;
+        // We just got done with a successful mDeps.add(name, ...) call. We'd
+        // better have found 'name' somewhere in that sorted list!
+        assert(mydmi != sorted_range.end());
+        // Four cases:
+        // 0. name is the only entry: placement 1.0
+        // 1. name is the first of several entries: placement (next placement)/2
+        // 2. name is between two other entries: placement (myprev + (next placement))/2
+        // 3. name is the last entry: placement ceil(myprev) + 1.0
+        // Since we've cleverly arranged for myprev to be 0.0 if name is the
+        // first entry, this folds down to two cases. Case 1 is subsumed by
+        // case 2, and case 0 is subsumed by case 3. So we need only handle
+        // cases 2 and 3, which means we need only detect whether name is the
+        // last entry. Increment mydmi to see if there's anything beyond.
+        if (++mydmi != sorted_range.end())
+        {
+            // The new node isn't last. Place it between the previous node and
+            // the successor.
+            newNode = (myprev + mydmi->second) / 2.f;
+        }
+        else
+        {
+            // The new node is last. Bump myprev up to the next integer, add
+            // 1.0 and use that.
+            newNode = std::ceil(myprev) + 1.f;
+        }
+
+        nodePosition = newNode;
     }
     // Now that newNode has a value that places it appropriately in mSignal,
     // connect it.
-    LLBoundListener bound = mSignal->connect(newNode, listener);
-    mConnections[name] = bound;
+    LLBoundListener bound = mSignal->connect(nodePosition, listener);
+    
+    if (!name.empty())
+    {   // note that we are not tracking anonymous listeners here either.
+        // This means that it is the caller's responsibility to either assign 
+        // to a TempBoundListerer (scoped_connection) or manually disconnect 
+        // when done. 
+        mConnections[name] = bound;
+    }
     return bound;
 }
 
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index 15261287252c7deb5d9dc52450cc1dced5975622..a3b9ec02e0d9894ecf06b5e358a21a0a7fc2144f 100644
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -385,6 +385,8 @@ typedef boost::signals2::trackable LLEventTrackable;
 class LL_COMMON_API LLEventPump: public LLEventTrackable
 {
 public:
+    static const std::string ANONYMOUS; // constant for anonymous listeners.
+
     /**
      * Exception thrown by LLEventPump(). You are trying to instantiate an
      * LLEventPump (subclass) using the same name as some other instance, and
@@ -496,6 +498,12 @@ class LL_COMMON_API LLEventPump: public LLEventTrackable
      * instantiate your listener, then passing the same name on each listen()
      * call, allows us to optimize away the second and subsequent dependency
      * sorts.
+     * 
+     * If name is set to LLEventPump::ANONYMOUS listen will bypass the entire 
+     * dependency and ordering calculation. In this case, it is critical that 
+     * the result be assigned to a LLTempBoundListener or the listener is 
+     * manually disconnected when no longer needed since there will be no
+     * way to later find and disconnect this listener manually.
      *
      * If (as is typical) you pass a <tt>boost::bind()</tt> expression as @a
      * listener, listen() will inspect the components of that expression. If a
diff --git a/indra/llcommon/lluriparser.cpp b/indra/llcommon/lluriparser.cpp
index 82d0dc8b4b25889b35c12b64f53bcf3bc094573a..c275b90120d976123822300688aa568dbeda0efa 100644
--- a/indra/llcommon/lluriparser.cpp
+++ b/indra/llcommon/lluriparser.cpp
@@ -205,9 +205,9 @@ void LLUriParser::glue(std::string& uri) const
 	uri = first_part + second_part;
 }
 
-void LLUriParser::glueFirst(std::string& uri) const
+void LLUriParser::glueFirst(std::string& uri, bool use_scheme) const
 {
-	if (mScheme.size())
+	if (use_scheme && mScheme.size())
 	{
 		uri = mScheme;
 		uri += "://";
diff --git a/indra/llcommon/lluriparser.h b/indra/llcommon/lluriparser.h
index 2df8085ae6330582453cd0c0e839a97a5ad5994a..cfbf54f3c8592fb597a1c297988b67ff8d7ad96e 100644
--- a/indra/llcommon/lluriparser.h
+++ b/indra/llcommon/lluriparser.h
@@ -60,7 +60,7 @@ class LL_COMMON_API LLUriParser
 
 	void extractParts();
 	void glue(std::string& uri) const;
-	void glueFirst(std::string& uri) const;
+	void glueFirst(std::string& uri, bool use_scheme = true) const;
 	void glueSecond(std::string& uri) const;
 	bool test() const;
 	S32 normalize();
diff --git a/indra/llcommon/tests/llerror_test.cpp b/indra/llcommon/tests/llerror_test.cpp
index 8bace8ac41f031f1643afb37b91c276b75bab5d1..20de2054547b97d051393ce2b06c85d73ea08a1e 100644
--- a/indra/llcommon/tests/llerror_test.cpp
+++ b/indra/llcommon/tests/llerror_test.cpp
@@ -564,9 +564,9 @@ namespace tut
 					function;
 		writeReturningLocationAndFunction(location, function);
 
-		ensure_equals("order is location time type function message",
+		ensure_equals("order is time location type function message",
 			message(0),
-			location + roswell() + " INFO: " + function + ": apple");
+			roswell() + " INFO: " + location + function + ": apple");
 	}
 
 	template<> template<>
diff --git a/indra/llcommon/tests/llleap_test.cpp b/indra/llcommon/tests/llleap_test.cpp
index d342dece8425e28300f45a392f06d1bc8b00aca4..c387da6c4828b4806b1e913e614fcef8d5a7ff1b 100644
--- a/indra/llcommon/tests/llleap_test.cpp
+++ b/indra/llcommon/tests/llleap_test.cpp
@@ -110,10 +110,7 @@ namespace tut
                    // finding indra/lib/python. Use our __FILE__, with
                    // raw-string syntax to deal with Windows pathnames.
                    "mydir = os.path.dirname(r'" << __FILE__ << "')\n"
-                   // We expect mydir to be .../indra/llcommon/tests.
-                   "sys.path.insert(0,\n"
-                   "    os.path.join(mydir, os.pardir, os.pardir, 'lib', 'python'))\n"
-                   "from indra.base import llsd\n"
+                   "from llbase import llsd\n"
                    "\n"
                    "class ProtocolError(Exception):\n"
                    "    def __init__(self, msg, data):\n"
diff --git a/indra/llcommon/tests/llsdserialize_test.cpp b/indra/llcommon/tests/llsdserialize_test.cpp
index 6fbb9abfc001b4dabe91b3dd8b413653fb66de31..81b930e1e2ce698bf4f4628e11c231839896b9b5 100644
--- a/indra/llcommon/tests/llsdserialize_test.cpp
+++ b/indra/llcommon/tests/llsdserialize_test.cpp
@@ -1518,10 +1518,7 @@ namespace tut
             // scanner.
             import_llsd("import os.path\n"
                         "import sys\n"
-                        "sys.path.insert(0,\n"
-                        "    os.path.join(os.path.dirname(r'" __FILE__ "'),\n"
-                        "                 os.pardir, os.pardir, 'lib', 'python'))\n"
-                        "from indra.base import llsd\n")
+                        "from llbase import llsd\n")
         {}
         ~TestPythonCompatible() {}
 
diff --git a/indra/llcorehttp/tests/test_llcorehttp_peer.py b/indra/llcorehttp/tests/test_llcorehttp_peer.py
index 04cde651c452f288a953e70d77f48e6c2dd9f828..6c5f37d407af356b1f4fd4760280c5af2d1fa72d 100755
--- a/indra/llcorehttp/tests/test_llcorehttp_peer.py
+++ b/indra/llcorehttp/tests/test_llcorehttp_peer.py
@@ -42,10 +42,8 @@
 from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
 from SocketServer import ThreadingMixIn
 
-mydir = os.path.dirname(__file__)       # expected to be .../indra/llcorehttp/tests/
-sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python"))
-from indra.util.fastest_elementtree import parse as xml_parse
-from indra.base import llsd
+from llbase.fastest_elementtree import parse as xml_parse
+from llbase import llsd
 from testrunner import freeport, run, debug, VERBOSE
 
 class TestHTTPRequestHandler(BaseHTTPRequestHandler):
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index d57fe81de4faa03d371aa75ba4a89bc4dc68e071..bd24a46e8d175d38bd7b98ce9c48b4fe51691f7f 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -2143,19 +2143,22 @@ BOOL LLVolume::generate()
 	
 	F32 profile_detail = mDetail;
 	F32 path_detail = mDetail;
-	
-	U8 path_type = mParams.getPathParams().getCurveType();
-	U8 profile_type = mParams.getProfileParams().getCurveType();
-	
-	if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE)
-	{ //cylinders don't care about Z-Axis
-		mLODScaleBias.setVec(0.6f, 0.6f, 0.0f);
-	}
-	else if (path_type == LL_PCODE_PATH_CIRCLE) 
-	{	
-		mLODScaleBias.setVec(0.6f, 0.6f, 0.6f);
+
+	if ((mParams.getSculptType() & LL_SCULPT_TYPE_MASK) != LL_SCULPT_TYPE_MESH)
+	{
+		U8 path_type = mParams.getPathParams().getCurveType();
+		U8 profile_type = mParams.getProfileParams().getCurveType();
+		if (path_type == LL_PCODE_PATH_LINE && profile_type == LL_PCODE_PROFILE_CIRCLE)
+		{
+			//cylinders don't care about Z-Axis
+			mLODScaleBias.setVec(0.6f, 0.6f, 0.0f);
+		}
+		else if (path_type == LL_PCODE_PATH_CIRCLE)
+		{
+			mLODScaleBias.setVec(0.6f, 0.6f, 0.6f);
+		}
 	}
-	
+
 	BOOL regenPath = mPathp->generate(mParams.getPathParams(), path_detail, split);
 	BOOL regenProf = mProfilep->generate(mParams.getProfileParams(), mPathp->isOpen(),profile_detail, split);
 
diff --git a/indra/llmessage/llcorehttputil.cpp b/indra/llmessage/llcorehttputil.cpp
index 7742cbc18235c5fb0ae42f028871f63e3b9373cd..9bf38fb336e7af383e07b8b65cc520c5e6e616b5 100644
--- a/indra/llmessage/llcorehttputil.cpp
+++ b/indra/llmessage/llcorehttputil.cpp
@@ -642,7 +642,7 @@ HttpRequestPumper::HttpRequestPumper(const LLCore::HttpRequest::ptr_t &request)
     mHttpRequest(request)
 {
     mBoundListener = LLEventPumps::instance().obtain("mainloop").
-        listen(LLEventPump::inventName(), boost::bind(&HttpRequestPumper::pollRequest, this, _1));
+        listen(LLEventPump::ANONYMOUS, boost::bind(&HttpRequestPumper::pollRequest, this, _1));
 }
 
 HttpRequestPumper::~HttpRequestPumper()
diff --git a/indra/llmessage/llxfer.cpp b/indra/llmessage/llxfer.cpp
index 4aba5cae72eb9eb197066550f154a96ac2a79501..e0590dfdff094b4dac451b7629ecc0b8ecdac285 100644
--- a/indra/llmessage/llxfer.cpp
+++ b/indra/llmessage/llxfer.cpp
@@ -294,7 +294,7 @@ S32 LLXfer::processEOF()
 	}
 	else
 	{
-		LL_INFOS() << "xfer from " << mRemoteHost << " failed, code "
+		LL_INFOS() << "xfer from " << mRemoteHost << " failed or aborted, code "
 				<< mCallbackResult << ": " << getFileName() << LL_ENDL;
 	}
 
diff --git a/indra/llmessage/llxfermanager.cpp b/indra/llmessage/llxfermanager.cpp
index 0ab67b8dda13743744dc438f8e2116d465ddaca8..272dbbc785dc2d561be4790fda94566e7e99dd3f 100644
--- a/indra/llmessage/llxfermanager.cpp
+++ b/indra/llmessage/llxfermanager.cpp
@@ -401,7 +401,7 @@ U64 LLXferManager::registerXfer(const void *datap, const S32 length)
 
 ///////////////////////////////////////////////////////////
 
-void LLXferManager::requestFile(const std::string& local_filename,
+U64 LLXferManager::requestFile(const std::string& local_filename,
 								const std::string& remote_filename,
 								ELLPath remote_path,
 								const LLHost& remote_host,
@@ -424,10 +424,12 @@ void LLXferManager::requestFile(const std::string& local_filename,
 
 		{
 			// cout << "requested a xfer already in progress" << endl;
-			return;
+			return xferp->mID;
 		}
 	}
 
+	U64 xfer_id = 0;
+
 	S32 chunk_size = use_big_packets ? LL_XFER_LARGE_PAYLOAD : -1;
 	xferp = (LLXfer *) new LLXfer_File(chunk_size);
 	if (xferp)
@@ -438,13 +440,15 @@ void LLXferManager::requestFile(const std::string& local_filename,
 		// around.
 		// Note: according to AaronB, this is here to deal with locks on files that were
 		// in transit during a crash,
-		if(delete_remote_on_completion &&
-		   (remote_filename.substr(remote_filename.length()-4) == ".tmp"))
+		if( delete_remote_on_completion
+			&& (remote_filename.substr(remote_filename.length()-4) == ".tmp")
+			&& gDirUtilp->fileExists(local_filename))
 		{
 			LLFile::remove(local_filename);
 		}
+		xfer_id = getNextID();
 		((LLXfer_File *)xferp)->initializeRequest(
-			getNextID(),
+			xfer_id,
 			local_filename,
 			remote_filename,
 			remote_path,
@@ -457,6 +461,7 @@ void LLXferManager::requestFile(const std::string& local_filename,
 	{
 		LL_ERRS() << "Xfer allocation error" << LL_ENDL;
 	}
+	return xfer_id;
 }
 
 void LLXferManager::requestFile(const std::string& remote_filename,
@@ -616,7 +621,7 @@ void LLXferManager::processReceiveData (LLMessageSystem *mesgsys, void ** /*user
 	if (!xferp) 
 	{
 		char U64_BUF[MAX_STRING];		/* Flawfinder : ignore */
-		LL_WARNS() << "received xfer data from " << mesgsys->getSender()
+		LL_INFOS() << "received xfer data from " << mesgsys->getSender()
 			<< " for non-existent xfer id: "
 			<< U64_to_str(id, U64_BUF, sizeof(U64_BUF)) << LL_ENDL;
 		return;
@@ -1103,6 +1108,29 @@ void LLXferManager::retransmitUnackedPackets ()
 	}
 }
 
+///////////////////////////////////////////////////////////
+
+void LLXferManager::abortRequestById(U64 xfer_id, S32 result_code)
+{
+	LLXfer * xferp = findXfer(xfer_id, mReceiveList);
+	if (xferp)
+	{
+		if (xferp->mStatus == e_LL_XFER_IN_PROGRESS)
+		{
+			// causes processAbort();
+			xferp->abort(result_code);
+		}
+		else
+		{
+			xferp->mCallbackResult = result_code;
+			xferp->processEOF(); //should notify requester
+			removeXfer(xferp, &mReceiveList);
+		}
+		// Since already removed or marked as aborted no need
+		// to wait for processAbort() to start new download
+		startPendingDownloads();
+	}
+}
 
 ///////////////////////////////////////////////////////////
 
diff --git a/indra/llmessage/llxfermanager.h b/indra/llmessage/llxfermanager.h
index b3d110e7a145bf897fa67725765c7fda0ff6c723..d258f0a5ce2d82ffa2c56801bfa8dbbf416094a7 100644
--- a/indra/llmessage/llxfermanager.h
+++ b/indra/llmessage/llxfermanager.h
@@ -140,7 +140,7 @@ class LLXferManager
 
 // file requesting routines
 // .. to file
-	virtual void requestFile(const std::string& local_filename,
+	virtual U64 requestFile(const std::string& local_filename,
 							 const std::string& remote_filename,
 							 ELLPath remote_path,
 							 const LLHost& remote_host,
@@ -202,6 +202,7 @@ class LLXferManager
 	virtual void retransmitUnackedPackets ();
 
 // error handling
+	void abortRequestById(U64 xfer_id, S32 result_code);
 	virtual void processAbort (LLMessageSystem *mesgsys, void **user_data);
 };
 
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index cecb2021e7e9888d979b90965a56042befef1ab4..290b67feb3c46b7eb5470f285557e36d76c4879a 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -4007,7 +4007,7 @@ void LLMessageSystem::sendUntrustedSimulatorMessageCoro(std::string url, std::st
 {
     LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
     LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
-        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("groupMembersRequest", httpPolicy));
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("untrustedSimulatorMessage", httpPolicy));
     LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
     LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
 
diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py
index e45249b1cba1ca41b539b2dfa1d2aff1034409fe..bac18fa37404b4c3451012bed3641735ae38732e 100755
--- a/indra/llmessage/tests/test_llsdmessage_peer.py
+++ b/indra/llmessage/tests/test_llsdmessage_peer.py
@@ -34,10 +34,8 @@
 from threading import Thread
 from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler
 
-mydir = os.path.dirname(__file__)       # expected to be .../indra/llmessage/tests/
-sys.path.insert(0, os.path.join(mydir, os.pardir, os.pardir, "lib", "python"))
-from indra.util.fastest_elementtree import parse as xml_parse
-from indra.base import llsd
+from llbase.fastest_elementtree import parse as xml_parse
+from llbase import llsd
 from testrunner import freeport, run, debug, VERBOSE
 import time
 
diff --git a/indra/llplugin/llpluginclassmedia.cpp b/indra/llplugin/llpluginclassmedia.cpp
index d672650658599c1ebe175f06b00d65757a3b2f3b..f1b6fe0a1246048da6e5035d81200f5f4d212c02 100644
--- a/indra/llplugin/llpluginclassmedia.cpp
+++ b/indra/llplugin/llpluginclassmedia.cpp
@@ -73,6 +73,7 @@ bool LLPluginClassMedia::init(const std::string &launcher_filename, const std::s
 	// Queue up the media init message -- it will be sent after all the currently queued messages.
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA, "init");
 	message.setValue("target", mTarget);
+	message.setValueReal("factor", mZoomFactor);
 	sendMessage(message);
 
 	mPlugin->init(launcher_filename, plugin_dir, plugin_filename, debug);
@@ -1259,7 +1260,7 @@ void LLPluginClassMedia::focus(bool focused)
 	sendMessage(message);
 }
 
-void LLPluginClassMedia::set_page_zoom_factor( double factor )
+void LLPluginClassMedia::set_page_zoom_factor( F64 factor )
 {
 	LLPluginMessage message(LLPLUGIN_MESSAGE_CLASS_MEDIA_BROWSER, "set_page_zoom_factor");
 
diff --git a/indra/llplugin/llpluginclassmedia.h b/indra/llplugin/llpluginclassmedia.h
index fc27b7bea368436f220273084e93ac6f5637188f..3b0739d044ca7999783bb6d6516d9d3173312880 100644
--- a/indra/llplugin/llpluginclassmedia.h
+++ b/indra/llplugin/llpluginclassmedia.h
@@ -68,6 +68,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	int getTextureHeight() const;
 	int getFullWidth() const { return mFullMediaWidth; };
 	int getFullHeight() const { return mFullMediaHeight; };
+	F64 getZoomFactor() const { return mZoomFactor; };
 	
 	// This may return NULL.  Callers need to check for and handle this case.
 	unsigned char* getBitsData();
@@ -83,7 +84,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 
 	void setSize(int width, int height);
 	void setAutoScale(bool auto_scale);
-	
+	void setZoomFactor(F64 zoom_factor) { mZoomFactor = zoom_factor; }
+
 	void setBackgroundColor(LLColor4 color) { mBackgroundColor = color; };
 	
 	void setOwner(LLPluginClassMediaOwner *owner) { mOwner = owner; };
@@ -204,7 +206,7 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	bool pluginSupportsMediaBrowser(void);
 	
 	void focus(bool focused);
-	void set_page_zoom_factor( double factor );
+	void set_page_zoom_factor( F64 factor );
 	void clear_cache();
 	void clear_cookies();
 	void set_cookies(const std::string &cookies);
@@ -367,6 +369,8 @@ class LLPluginClassMedia : public LLPluginProcessParentOwner
 	int			mTextureHeight;
 	int			mMediaWidth;
 	int			mMediaHeight;
+
+	F64			mZoomFactor;
 	
 	float		mRequestedVolume;
 	
diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp
index 3e279924a87ee6fa8f46cfaf04f8560766a084c7..d73bdd769326da29de463dd7ea191760c858331d 100644
--- a/indra/llprimitive/lldaeloader.cpp
+++ b/indra/llprimitive/lldaeloader.cpp
@@ -1075,7 +1075,7 @@ bool LLDAELoader::OpenFile(const std::string& filename)
 std::string LLDAELoader::preprocessDAE(std::string filename)
 {
 	// Open a DAE file for some preprocessing (like removing space characters in IDs), see MAINT-5678
-	std::ifstream inFile;
+	llifstream inFile;
 	inFile.open(filename.c_str(), std::ios_base::in);
 	std::stringstream strStream;
 	strStream << inFile.rdbuf();
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 0e2946632a7170ef88ec86a78aebc97e17e5cd7b..cf0a1175676fd8d426873643c63b7fd32f1f595a 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -364,12 +364,7 @@ S32 LLFontGL::render(const LLWString &wstr, S32 begin_offset, F32 x, F32 y, cons
 
 	if (right_x)
 	{
-        F32 cr_x = (cur_x - origin.mV[VX]) / sScaleX;
-        if (*right_x < cr_x)
-        {
-            // rightmost edge of previously drawn text, don't draw over previous text
-            *right_x = cr_x;
-        }
+		*right_x = (cur_x - origin.mV[VX]) / sScaleX;
 	}
 
 	//FIXME: add underline as glyph?
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index ebed4542712a03625b12d2862252e75305a19993..81a5537f78df20809532bc10e586d23ebf2ac322 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -487,14 +487,15 @@ bool LLImageGL::checkSize(S32 width, S32 height)
 	return check_power_of_two(width) && check_power_of_two(height);
 }
 
-void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level)
+bool LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level)
 {
 	if (width != mWidth || height != mHeight || ncomponents != mComponents)
 	{
 		// Check if dimensions are a power of two!
 		if (!checkSize(width,height))
 		{
-			LL_ERRS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << LL_ENDL;
+			LL_WARNS() << llformat("Texture has non power of two dimension: %dx%d",width,height) << LL_ENDL;
+			return false;
 		}
 		
 		if (mTexName)
@@ -529,6 +530,8 @@ void LLImageGL::setSize(S32 width, S32 height, S32 ncomponents, S32 discard_leve
 			mMaxDiscardLevel = MAX_DISCARD_LEVEL;
 		}
 	}
+
+	return true;
 }
 
 //----------------------------------------------------------------------------
@@ -909,7 +912,11 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image)
 	S32 h = raw_image->getHeight() << discard_level;
 
 	// setSize may call destroyGLTexture if the size does not match
-	setSize(w, h, raw_image->getComponents(), discard_level);
+	if (!setSize(w, h, raw_image->getComponents(), discard_level))
+	{
+		LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
+		return FALSE;
+	}
 
 	if( !mHasExplicitFormat )
 	{
@@ -1273,7 +1280,11 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
 	S32 h = raw_h << discard_level;
 
 	// setSize may call destroyGLTexture if the size does not match
-	setSize(w, h, imageraw->getComponents(), discard_level);
+	if (!setSize(w, h, imageraw->getComponents(), discard_level))
+	{
+		LL_WARNS() << "Trying to create a texture with incorrect dimensions!" << LL_ENDL;
+		return FALSE;
+	}
 
 	if( !mHasExplicitFormat )
 	{
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index 21982eab1dd8276a575399dafa364b00be4a0e91..ad2aea90675e9b63d5f1bb6229e562fc44b1be68 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -94,7 +94,7 @@ class LLImageGL : public LLRefCount, public LLTrace::MemTrackable<LLImageGL>
 public:
 	virtual void dump();	// debugging info to LL_INFOS()
 	
-	void setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level = -1);
+	bool setSize(S32 width, S32 height, S32 ncomponents, S32 discard_level = -1);
 	void setComponents(S32 ncomponents) { mComponents = (S8)ncomponents ;}
 	void setAllowCompression(bool allow) { mAllowCompression = allow; }
 
diff --git a/indra/llui/llclipboard.cpp b/indra/llui/llclipboard.cpp
index 1d18cb2bb039173911f85608e27903314d7d0a01..06fac190ed225ca80f7cf3bddf8564a5acb0d6ec 100644
--- a/indra/llui/llclipboard.cpp
+++ b/indra/llui/llclipboard.cpp
@@ -123,7 +123,15 @@ bool LLClipboard::copyToClipboard(const LLWString &src, S32 pos, S32 len, bool u
 // Concatenate the input string to the LL and the system clipboard
 bool LLClipboard::addToClipboard(const LLWString &src, S32 pos, S32 len, bool use_primary)
 {
-	mString = src.substr(pos, len);
+	try
+	{
+		mString = src.substr(pos, len);
+	}
+	catch (const std::exception& e)
+	{
+		LL_WARNS() << "Can't add the substring to clipboard: " << e.what() << LL_ENDL;
+		return false;
+	}
 	return (use_primary ? LLView::getWindow()->copyTextToPrimary(mString) : LLView::getWindow()->copyTextToClipboard(mString));
 }
 
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 8166ef6a07ad777efa1387cd7572af1576d3b9a4..f9664e0658549d35e4ec4c04b292c3b92b8c19f1 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -684,6 +684,13 @@ void LLFolderView::draw()
 		}
 	}
 
+	if (mRenameItem && mRenamer && mRenamer->getVisible() && !getVisibleRect().overlaps(mRenamer->getRect()))
+	{
+		// renamer is not connected to the item we are renaming in any form so manage it manually
+		// TODO: consider stopping on any scroll action instead of when out of visible area
+		finishRenamingItem();
+	}
+
 	// skip over LLFolderViewFolder::draw since we don't want the folder icon, label, 
 	// and arrow for the root folder
 	LLView::draw();
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index 5eb5ca4f82783e1f958c8129f83dc6d0b823db4a..3d618548c4ffc1a8f5366f4ecfd1ac81a8ce84b7 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -127,6 +127,8 @@ LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
 	mIsSelected( FALSE ),
 	mIsCurSelection( FALSE ),
 	mSelectPending(FALSE),
+	mIsItemCut(false),
+	mCutGeneration(0),
 	mLabelStyle( LLFontGL::NORMAL ),
 	mHasVisibleChildren(FALSE),
 	mIsFolderComplete(true),
@@ -694,6 +696,19 @@ void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const L
 	return mIsCurSelection;
 }
 
+/*virtual*/ bool LLFolderViewItem::isFadeItem()
+{
+    LLClipboard& clipboard = LLClipboard::instance();
+    if (mCutGeneration != clipboard.getGeneration())
+    {
+        mCutGeneration = clipboard.getGeneration();
+        mIsItemCut = clipboard.isCutMode()
+                     && ((getParentFolder() && getParentFolder()->isFadeItem())
+                        || getViewModelItem()->isCutToClipboard());
+    }
+    return mIsItemCut;
+}
+
 void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor,  
                                                         const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor)
 {
@@ -875,6 +890,12 @@ void LLFolderViewItem::draw()
     }
 
     LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor;
+
+    if (isFadeItem())
+    {
+         // Fade out item color to indicate it's being cut
+         color.mV[VALPHA] *= 0.5f;
+    }
     drawLabel(font, text_left, y, color, right_x);
 
 	//--------------------------------------------------------------------------------//
@@ -882,7 +903,7 @@ void LLFolderViewItem::draw()
 	//
 	if (!mLabelSuffix.empty())
 	{
-		font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
+		font->renderUTF8( mLabelSuffix, 0, right_x, y, isFadeItem() ? color : (LLColor4)sSuffixColor,
 						  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
 						  S32_MAX, S32_MAX, &right_x, FALSE );
 	}
diff --git a/indra/llui/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
index 0322c8836db293a26ed5a9b744160e43120150ac..61c39e0175fb0680cd37bab6e3d87c28f55a5673 100644
--- a/indra/llui/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -121,8 +121,11 @@ class LLFolderViewItem : public LLView
 								mIsMouseOverTitle,
 								mAllowWear,
                                 mAllowDrop,
-								mSelectPending;
-	
+								mSelectPending,
+								mIsItemCut;
+
+	S32							mCutGeneration;
+
 	LLUIColor                   mFontColor;
 	LLUIColor                   mFontHighlightColor;
 
@@ -145,6 +148,7 @@ class LLFolderViewItem : public LLView
 	virtual void addFolder(LLFolderViewFolder*) { }
 	virtual bool isHighlightAllowed();
 	virtual bool isHighlightActive();
+	virtual bool isFadeItem();
 	virtual bool isFlashing() { return false; }
 	virtual void setFlashState(bool) { }
 
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
index a395af537a01713e094462e1ec2674ca88571dd3..641241a88c48822e4cc349ed22716901935de751 100644
--- a/indra/llui/llfolderviewmodel.h
+++ b/indra/llui/llfolderviewmodel.h
@@ -173,6 +173,7 @@ class LLFolderViewModelItem : public LLRefCount, public LLTrace::MemTrackable<LL
 	virtual BOOL isItemCopyable() const = 0;
 	virtual BOOL copyToClipboard() const = 0;
 	virtual BOOL cutToClipboard() = 0;
+	virtual bool isCutToClipboard() { return false; };
 
 	virtual BOOL isClipboardPasteable() const = 0;
 	virtual void pasteFromClipboard() = 0;
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 492c9315d13bb3dd4bd292a173c3b4b720be389e..c89e1dac1d19eb2d0ac57f05b9c41312a34bb4a5 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -2636,10 +2636,17 @@ void LLLineEditor::showContextMenu(S32 x, S32 y)
 
 void LLLineEditor::setContextMenu(LLContextMenu* new_context_menu)
 {
-	if (new_context_menu)
-		mContextMenuHandle = new_context_menu->getHandle();
-	else
-		mContextMenuHandle.markDead();
+    LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
+    if (menu)
+    {
+        menu->die();
+        mContextMenuHandle.markDead();
+    }
+
+    if (new_context_menu)
+    {
+        mContextMenuHandle = new_context_menu->getHandle();
+    }
 }
 
 void LLLineEditor::setFont(const LLFontGL* font)
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index c6d472f59b7b7d12ca8ee33056fc1c24e5a652c4..ccbd305a168dc1257473b070e9d900f08d92c357 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -272,7 +272,7 @@ class LLLineEditor
 
 	void			setReplaceNewlinesWithSpaces(BOOL replace);
 
-	void			setContextMenu(LLContextMenu* new_context_menu);
+	void			resetContextMenu() { setContextMenu(NULL); };
 
 private:
 	// private helper methods
@@ -308,6 +308,8 @@ class LLLineEditor
 	virtual S32		getPreeditFontSize() const;
 	virtual LLWString getPreeditString() const { return getWText(); }
 
+	void			setContextMenu(LLContextMenu* new_context_menu);
+
 protected:
 	LLUIString		mText;					// The string being edited.
 	std::string		mPrevText;				// Saved string for 'ESC' revert
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index c7d7535f87cc2aab862ec296bf680aa5005a7d49..20be73928677d920806dc2c492e53269657b19b4 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -181,7 +181,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 	mMaxTextByteLength( p.max_text_length ),
 	mFont(p.font),
 	mFontShadow(p.font_shadow),
-	mPopupMenu(NULL),
+	mPopupMenuHandle(),
 	mReadOnly(p.read_only),
 	mSpellCheck(p.spellcheck),
 	mSpellCheckStart(-1),
@@ -1263,9 +1263,10 @@ void LLTextBase::setReadOnlyColor(const LLColor4 &c)
 //virtual
 void LLTextBase::onVisibilityChange( BOOL new_visibility )
 {
-	if(!new_visibility && mPopupMenu)
+	LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
+	if(!new_visibility && menu)
 	{
-		mPopupMenu->hide();
+		menu->hide();
 	}
 	LLUICtrl::onVisibilityChange(new_visibility);
 }
@@ -1956,41 +1957,48 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
 	registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
 
 	// create and return the context menu from the XUI file
-	delete mPopupMenu;
+
+    LLContextMenu* menu = static_cast<LLContextMenu*>(mPopupMenuHandle.get());
+    if (menu)
+    {
+        menu->die();
+        mPopupMenuHandle.markDead();
+    }
 	llassert(LLMenuGL::sMenuContainer != NULL);
-	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer,
-																		 LLMenuHolderGL::child_registry_t::instance());	
-	if (mIsFriendSignal)
-	{
-		bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url)));
-		LLView* addFriendButton = mPopupMenu->getChild<LLView>("add_friend");
-		LLView* removeFriendButton = mPopupMenu->getChild<LLView>("remove_friend");
+    menu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>(xui_file, LLMenuGL::sMenuContainer,
+																		 LLMenuHolderGL::child_registry_t::instance());
+    if (menu)
+    {
+        mPopupMenuHandle = menu->getHandle();
 
-		if (addFriendButton && removeFriendButton)
-		{
-			addFriendButton->setEnabled(!isFriend);
-			removeFriendButton->setEnabled(isFriend);
-		}
-	}
+        if (mIsFriendSignal)
+        {
+            bool isFriend = *(*mIsFriendSignal)(LLUUID(LLUrlAction::getUserID(url)));
+            LLView* addFriendButton = menu->getChild<LLView>("add_friend");
+            LLView* removeFriendButton = menu->getChild<LLView>("remove_friend");
 
-	if (mIsObjectBlockedSignal)
-	{
-		bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url));
-		LLView* blockButton = mPopupMenu->getChild<LLView>("block_object");
-		LLView* unblockButton = mPopupMenu->getChild<LLView>("unblock_object");
+            if (addFriendButton && removeFriendButton)
+            {
+                addFriendButton->setEnabled(!isFriend);
+                removeFriendButton->setEnabled(isFriend);
+            }
+        }
 
-		if (blockButton && unblockButton)
-		{
-			blockButton->setVisible(!is_blocked);
-			unblockButton->setVisible(is_blocked);
-		}
-	}
-	
-	if (mPopupMenu)
-	{
-		mPopupMenu->show(x, y);
-		LLMenuGL::showPopup(this, mPopupMenu, x, y);
-	}
+        if (mIsObjectBlockedSignal)
+        {
+            bool is_blocked = *(*mIsObjectBlockedSignal)(LLUUID(LLUrlAction::getObjectId(url)), LLUrlAction::getObjectName(url));
+            LLView* blockButton = menu->getChild<LLView>("block_object");
+            LLView* unblockButton = menu->getChild<LLView>("unblock_object");
+
+            if (blockButton && unblockButton)
+            {
+                blockButton->setVisible(!is_blocked);
+                unblockButton->setVisible(is_blocked);
+            }
+        }
+        menu->show(x, y);
+        LLMenuGL::showPopup(this, menu, x, y);
+    }
 }
 
 void LLTextBase::setText(const LLStringExplicit &utf8str, const LLStyle::Params& input_params)
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 85641fd89920463bf5a94b7c0ccd45193170a07e..3d3a6ca869678051206ccf633e7dee73e7d061b9 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -673,7 +673,7 @@ class LLTextBase
 	S32							mMaxTextByteLength;	// Maximum length mText is allowed to be in bytes
 
 	// support widgets
-	LLContextMenu*				mPopupMenu;
+	LLHandle<LLContextMenu>		mPopupMenuHandle;
 	LLView*						mDocumentView;
 	LLScrollContainer*			mScroller;
 
diff --git a/indra/llui/lltextvalidate.cpp b/indra/llui/lltextvalidate.cpp
index 324ceb7fbab88a9fd84fba6a18b740ecd63e8920..bfe0a5bb5d46d4fee27d28bc3cbcd87a431bd40f 100644
--- a/indra/llui/lltextvalidate.cpp
+++ b/indra/llui/lltextvalidate.cpp
@@ -328,6 +328,15 @@ namespace LLTextValidate
 		return rv;
 	}
 
+	bool validateASCIINoLeadingSpace(const LLWString &str)
+	{
+		if (LLStringOps::isSpace(str[0]))
+		{
+			return FALSE;
+		}
+		return validateASCII(str);
+	}
+
 	// Used for multiline text stored on the server.
 	// Example is landmark description in Places SP.
 	bool validateASCIIWithNewLine(const LLWString &str)
diff --git a/indra/llui/lltextvalidate.h b/indra/llui/lltextvalidate.h
index 5c830d7db394fa50a9f01695c5fa07e73d0cca0c..e2b6c313d6d8ac3df9a938e7f76544f345cbf36f 100644
--- a/indra/llui/lltextvalidate.h
+++ b/indra/llui/lltextvalidate.h
@@ -52,6 +52,7 @@ namespace LLTextValidate
 	bool	validateASCIIPrintableNoPipe(const LLWString &str); 
 	bool	validateASCIIPrintableNoSpace(const LLWString &str);
 	bool	validateASCII(const LLWString &str);
+	bool	validateASCIINoLeadingSpace(const LLWString &str);
 	bool	validateASCIIWithNewLine(const LLWString &str);
 }
 
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index aabc7ed2e423b61fc6cbff0a63b7f5cfeb4fd121..f790d8e005bf992a01e8d8b4e9836edc70988521 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -522,7 +522,7 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)
 		else
 		{
 			std::string part(ti->begin(), ti->end());
-			context = context->findChildView(part, recurse);
+			context = context->findChildView(LLURI::unescape(part), recurse);
 			recurse = false;
 		}
 	}
diff --git a/indra/llui/llurlentry.cpp b/indra/llui/llurlentry.cpp
index e4848362a76bcfd4ac0edf8f4ee52f9cfb86c798..27a2456debbf48051f152064e57c6f60e1552716 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -183,8 +183,9 @@ bool LLUrlEntryBase::isLinkDisabled() const
 
 bool LLUrlEntryBase::isWikiLinkCorrect(std::string url)
 {
-	std::string label = getLabelFromWikiLink(url);
-	return (LLUrlRegistry::instance().hasUrl(label)) ? false : true;
+	LLWString label = utf8str_to_wstring(getLabelFromWikiLink(url));
+	label.erase(std::remove(label.begin(), label.end(), L'\u200B'), label.end());
+	return (LLUrlRegistry::instance().hasUrl(wstring_to_utf8str(label))) ? false : true;
 }
 
 std::string LLUrlEntryBase::urlToLabelWithGreyQuery(const std::string &url) const
@@ -205,9 +206,15 @@ std::string LLUrlEntryBase::urlToGreyQuery(const std::string &url) const
 
 	std::string label;
 	up.extractParts();
-	up.glueFirst(label);
-	std::string query = url.substr(label.size());
-	return query;
+	up.glueFirst(label, false);
+
+	size_t pos = url.find(label);
+	if (pos == std::string::npos)
+	{
+		return "";
+	}
+	pos += label.size();
+	return url.substr(pos);
 }
 
 
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index fd7406b653808fa04fcf282322d1a849dfa8f4df..9604e5ce10e38d435b46b00f895a03d0abd0bdbe 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -391,7 +391,27 @@ static void buildPathname(std::ostream& out, const LLView* view)
 	buildPathname(out, view->getParent());
 
 	// Build pathname into ostream on the way back from recursion.
-	out << '/' << view->getName();
+	out << '/';
+
+	// substitute all '/' in name with appropriate code
+	std::string name = view->getName();
+	std::size_t found = name.find('/');
+	std::size_t start = 0;
+	while (found != std::string::npos)
+	{
+		std::size_t sub_len = found - start;
+		if (sub_len > 0)
+		{
+			out << name.substr(start, sub_len);
+		}
+		out << "%2F";
+		start = found + 1;
+		found = name.find('/', start);
+	}
+	if (start < name.size())
+	{
+		out << name.substr(start, name.size() - start);
+	}
 }
 
 std::string LLView::getPathname() const
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 5f4fb8f4a00fdab8c332def5c3f708cfa71b241f..86a15f2ef2c4e1a9a6764fb4a2e55d3b4fdddf1c 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -531,6 +531,13 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
 		
 	case LL_PATH_PER_ACCOUNT_CHAT_LOGS:
 		prefix = getPerAccountChatLogsDir();
+		if (prefix.empty())
+		{
+			// potentially directory was not set yet
+			// intentionally return a blank string to the caller
+			LL_DEBUGS("LLDir") << "Conversation log directory is not yet set" << LL_ENDL;
+			return std::string();
+		}
 		break;
 
 	case LL_PATH_LOGS:
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 0a30f4c807fefa91ca85edf89ab2bfc455584aec..a05ba8cbbaea578e0069bd918d9e950e41fa4427 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -166,6 +166,8 @@ class LLWindow : public LLInstanceTracker<LLWindow>
 	// Provide native key event data
 	virtual LLSD getNativeKeyData() { return LLSD::emptyMap(); }
 
+	// Get system UI size based on DPI (for 96 DPI UI size should be 1.0)
+	virtual F32 getSystemUISize() { return 1.0; }
 protected:
 	LLWindow(LLWindowCallbacks* callbacks, BOOL fullscreen, U32 flags);
 	virtual ~LLWindow();
diff --git a/indra/llwindow/llwindowcallbacks.cpp b/indra/llwindow/llwindowcallbacks.cpp
index d2afb3f91b304ad1621e1020692fae5c5983f77d..474953d3a4bf958ae7cba823a23b58476cb665a4 100644
--- a/indra/llwindow/llwindowcallbacks.cpp
+++ b/indra/llwindow/llwindowcallbacks.cpp
@@ -175,6 +175,11 @@ BOOL LLWindowCallbacks::handleDeviceChange(LLWindow *window)
 	return FALSE;
 }
 
+void LLWindowCallbacks::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height)
+{
+
+}
+
 void LLWindowCallbacks::handlePingWatchdog(LLWindow *window, const char * msg)
 {
 
diff --git a/indra/llwindow/llwindowcallbacks.h b/indra/llwindow/llwindowcallbacks.h
index 6a7137e5933fd5e21cb817db96bfdeb64a2c1d01..de789a71d98e27aaae464c475c3855876987bca5 100644
--- a/indra/llwindow/llwindowcallbacks.h
+++ b/indra/llwindow/llwindowcallbacks.h
@@ -65,6 +65,7 @@ class LLWindowCallbacks
 	virtual void handleDataCopy(LLWindow *window, S32 data_type, void *data);
 	virtual BOOL handleTimerEvent(LLWindow *window);
 	virtual BOOL handleDeviceChange(LLWindow *window);
+	virtual void handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
 
 	enum DragNDropAction {
 		DNDA_START_TRACKING = 0,// Start tracking an incoming drag
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 875ffe4cd43c02db968708e53844e87d5ed02afe..4086db8e524069ef53c1ed4557934ac85fc31e6a 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -60,24 +60,50 @@
 #include <dinput.h>
 #include <Dbt.h.>
 
-// culled from winuser.h
-#ifndef WM_MOUSEWHEEL /* Added to be compatible with later SDK's */
-const S32	WM_MOUSEWHEEL = 0x020A;
-#endif
-#ifndef WHEEL_DELTA /* Added to be compatible with later SDK's */
-const S32	WHEEL_DELTA = 120;     /* Value for rolling one detent */
-#endif
 const S32	MAX_MESSAGE_PER_UPDATE = 20;
 const S32	BITS_PER_PIXEL = 32;
 const S32	MAX_NUM_RESOLUTIONS = 32;
 const F32	ICON_FLASH_TIME = 0.5f;
 
+#ifndef WM_DPICHANGED
+#define WM_DPICHANGED 0x02E0
+#endif
+
 extern BOOL gDebugWindowProc;
 
 LPWSTR gIconResource = IDI_APPLICATION;
 
 LLW32MsgCallback gAsyncMsgCallback = NULL;
 
+#ifndef DPI_ENUMS_DECLARED
+
+typedef enum PROCESS_DPI_AWARENESS {
+	PROCESS_DPI_UNAWARE = 0,
+	PROCESS_SYSTEM_DPI_AWARE = 1,
+	PROCESS_PER_MONITOR_DPI_AWARE = 2
+} PROCESS_DPI_AWARENESS;
+
+typedef enum MONITOR_DPI_TYPE {
+	MDT_EFFECTIVE_DPI = 0,
+	MDT_ANGULAR_DPI = 1,
+	MDT_RAW_DPI = 2,
+	MDT_DEFAULT = MDT_EFFECTIVE_DPI
+} MONITOR_DPI_TYPE;
+
+#endif
+
+typedef HRESULT(STDAPICALLTYPE *SetProcessDpiAwarenessType)(_In_ PROCESS_DPI_AWARENESS value);
+
+typedef HRESULT(STDAPICALLTYPE *GetProcessDpiAwarenessType)(
+	_In_ HANDLE hprocess,
+	_Out_ PROCESS_DPI_AWARENESS *value);
+
+typedef HRESULT(STDAPICALLTYPE *GetDpiForMonitorType)(
+	_In_ HMONITOR hmonitor,
+	_In_ MONITOR_DPI_TYPE dpiType,
+	_Out_ UINT *dpiX,
+	_Out_ UINT *dpiY);
+
 //
 // LLWindowWin32
 //
@@ -2593,6 +2619,24 @@ LRESULT CALLBACK LLWindowWin32::mainWindowProc(HWND h_wnd, UINT u_msg, WPARAM w_
 
 				return 0;
 			}
+        
+		case WM_DPICHANGED:
+			{
+				LPRECT lprc_new_scale;
+				F32 new_scale = LOWORD(w_param) / USER_DEFAULT_SCREEN_DPI;
+				lprc_new_scale = (LPRECT)l_param;
+				S32 new_width = lprc_new_scale->right - lprc_new_scale->left;
+				S32 new_height = lprc_new_scale->bottom - lprc_new_scale->top;
+				window_imp->mCallbacks->handleDPIChanged(window_imp, new_scale, new_width, new_height);
+				SetWindowPos(h_wnd,
+					HWND_TOP,
+					lprc_new_scale->left,
+					lprc_new_scale->top,
+					new_width,
+					new_height,
+					SWP_NOZORDER | SWP_NOACTIVATE);
+					return 0;
+			}
 
 		case WM_SETFOCUS:
 			window_imp->mCallbacks->handlePingWatchdog(window_imp, "Main:WM_SETFOCUS");
@@ -3878,6 +3922,92 @@ BOOL LLWindowWin32::handleImeRequests(U32 request, U32 param, LRESULT *result)
 	return FALSE;
 }
 
+//static
+void LLWindowWin32::setDPIAwareness()
+{
+	HMODULE hShcore = LoadLibrary(L"shcore.dll");
+	if (hShcore != NULL)
+	{
+		SetProcessDpiAwarenessType pSPDA;
+		pSPDA = (SetProcessDpiAwarenessType)GetProcAddress(hShcore, "SetProcessDpiAwareness");
+		if (pSPDA)
+		{
+			
+			HRESULT hr = pSPDA(PROCESS_PER_MONITOR_DPI_AWARE);
+			if (hr != S_OK)
+			{
+				LL_WARNS() << "SetProcessDpiAwareness() function returned an error. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL;
+			}
+		}
+		FreeLibrary(hShcore);	
+	}
+	else
+	{
+		LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK. Will use legacy DPI awareness API of Win XP/7" << LL_ENDL;
+	}
+}
+
+F32 LLWindowWin32::getSystemUISize()
+{
+	float scale_value = 0;
+	HWND hWnd = (HWND)getPlatformWindow();
+	HDC hdc = GetDC(hWnd);
+	HMONITOR hMonitor;
+	HANDLE hProcess = GetCurrentProcess();
+	PROCESS_DPI_AWARENESS dpi_awareness;
+
+	HMODULE hShcore = LoadLibrary(L"shcore.dll");
+
+	if (hShcore != NULL)
+	{
+		GetProcessDpiAwarenessType pGPDA;
+		pGPDA = (GetProcessDpiAwarenessType)GetProcAddress(hShcore, "GetProcessDpiAwareness");
+		GetDpiForMonitorType pGDFM;
+		pGDFM = (GetDpiForMonitorType)GetProcAddress(hShcore, "GetDpiForMonitor");
+		if (pGPDA != NULL && pGDFM != NULL)
+		{
+			pGPDA(hProcess, &dpi_awareness);
+			if (dpi_awareness == PROCESS_PER_MONITOR_DPI_AWARE)
+			{
+				POINT    pt;
+				UINT     dpix = 0, dpiy = 0;
+				HRESULT  hr = E_FAIL;
+				RECT     rect;
+
+				GetWindowRect(hWnd, &rect);
+				// Get the DPI for the monitor, on which the center of window is displayed and set the scaling factor
+				pt.x = (rect.left + rect.right) / 2;
+				pt.y = (rect.top + rect.bottom) / 2;
+				hMonitor = MonitorFromPoint(pt, MONITOR_DEFAULTTONEAREST);
+				hr = pGDFM(hMonitor, MDT_EFFECTIVE_DPI, &dpix, &dpiy);
+				if (hr == S_OK)
+				{
+					scale_value = dpix / USER_DEFAULT_SCREEN_DPI;
+				}
+				else
+				{
+					LL_WARNS() << "Could not determine DPI for monitor. Setting scale to default 100 %" << LL_ENDL;
+					scale_value = 1.0f;
+				}
+			}
+			else
+			{
+				LL_WARNS() << "Process is not per-monitor DPI-aware. Setting scale to default 100 %" << LL_ENDL;
+				scale_value = 1.0f;
+			}
+		}
+		FreeLibrary(hShcore);
+	}
+	else
+	{
+		LL_WARNS() << "Could not load shcore.dll library (included by <ShellScalingAPI.h> from Win 8.1 SDK). Using legacy DPI awareness API of Win XP/7" << LL_ENDL;
+		scale_value = GetDeviceCaps(hdc, LOGPIXELSX) / USER_DEFAULT_SCREEN_DPI;
+	}
+
+	ReleaseDC(hWnd, hdc);
+	return scale_value;
+}
+
 //static
 std::vector<std::string> LLWindowWin32::getDynamicFallbackFontList()
 {
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 1a775eadaf46caad3648f1bd8eb3d8cda35c21a6..39ef9b31a4e1ca8f16881e0fbd60c931c01fd867 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -110,10 +110,12 @@ class LLWindowWin32 : public LLWindow
 	/*virtual*/ void interruptLanguageTextInput();
 	/*virtual*/ void spawnWebBrowser(const std::string& escaped_url, bool async);
 
+	/*virtual*/ F32 getSystemUISize();
+
 	LLWindowCallbacks::DragNDropResult completeDragNDropRequest( const LLCoordGL gl_coord, const MASK mask, LLWindowCallbacks::DragNDropAction action, const std::string url );
 
 	static std::vector<std::string> getDynamicFallbackFontList();
-
+	static void setDPIAwareness();
 protected:
 	LLWindowWin32(LLWindowCallbacks* callbacks,
 		const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, 
diff --git a/indra/media_plugins/cef/media_plugin_cef.cpp b/indra/media_plugins/cef/media_plugin_cef.cpp
index 28a8a5886a4ac340331edfbc48054cdaa6c95136..4eb29c98f9aa6ea4cd96ecd991c22c6967b91d9f 100644
--- a/indra/media_plugins/cef/media_plugin_cef.cpp
+++ b/indra/media_plugins/cef/media_plugin_cef.cpp
@@ -501,6 +501,7 @@ void MediaPluginCEF::receiveMessage(const char* message_string)
 				LLCEFLib::LLCEFLibSettings settings;
 				settings.initial_width = 1024;
 				settings.initial_height = 1024;
+				settings.page_zoom_factor = message_in.getValueReal("factor");
 				settings.plugins_enabled = mPluginsEnabled;
 				settings.media_stream_enabled = false; // MAINT-6060 - WebRTC media removed until we can add granualrity/query UI
 				settings.javascript_enabled = mJavascriptEnabled;
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 4cc2fcba5274f413126b53313bbac822654ade7a..6621b9e269f6a2f0fcb937f4886de22e6dbe4570 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -4537,28 +4537,6 @@
       <key>Value</key>
       <string>http://search.secondlife.com/viewer/[CATEGORY]/?q=[QUERY]&amp;p=[AUTH_TOKEN]&amp;r=[MATURITY]&amp;lang=[LANGUAGE]&amp;g=[GODLIKE]&amp;sid=[SESSION_ID]&amp;rid=[REGION_ID]&amp;pid=[PARCEL_ID]&amp;channel=[CHANNEL]&amp;version=[VERSION]&amp;major=[VERSION_MAJOR]&amp;minor=[VERSION_MINOR]&amp;patch=[VERSION_PATCH]&amp;build=[VERSION_BUILD]</string>
     </map>
-    <key>WebProfileURL</key>
-    <map>
-      <key>Comment</key>
-      <string>URL for Web Profiles</string>
-      <key>Persist</key>
-      <integer>0</integer>
-      <key>Type</key>
-      <string>String</string>
-      <key>Value</key>
-      <string>https://my.secondlife.com/[AGENT_NAME]</string>
-    </map>
-	<key>WebProfileNonProductionURL</key>
-	<map>
-		<key>Comment</key>
-		<string>URL for Web Profiles on Non-Production grids</string>
-		<key>Persist</key>
-		<integer>0</integer>
-		<key>Type</key>
-		<string>String</string>
-		<key>Value</key>
-		<string>https://my-demo.secondlife.com/[AGENT_NAME]</string>
-	</map>
     <key>HighResSnapshot</key>
     <map>
       <key>Comment</key>
@@ -4903,7 +4881,7 @@
     <key>InventoryTrashMaxCapacity</key>
     <map>
         <key>Comment</key>
-        <string>Maximum capacity of the Trash folder. User will ve offered to clean it up when exceeded.</string>
+        <string>Maximum capacity of the Trash folder. User will be offered to clean it up when exceeded.</string>
         <key>Persist</key>
         <integer>1</integer>
         <key>Type</key>
@@ -7973,6 +7951,17 @@
       <key>Value</key>
       <integer>100000</integer>
     </map>
+    <key>PrimTextMaxDrawDistance</key>
+    <map>
+      <key>Comment</key>
+      <string>Maximum draw distance beyond which PRIM_TEXT won't be rendered</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>64.0</real>
+    </map>
     <key>ProbeHardwareOnStartup</key>
     <map>
       <key>Comment</key>
@@ -10125,6 +10114,17 @@
     <key>Value</key>
     <integer>10</integer>
   </map>
+  <key>ComplexityChangesPopUpDelay</key>
+  <map>
+    <key>Comment</key>
+    <string>Delay before viewer will show avatar complexity notice again</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>300</integer>
+  </map>
   <key>RenderAvatarMaxComplexity</key>
   <map>
     <key>Comment</key>
@@ -10137,6 +10137,50 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
+  <key>RenderHUDObjectsWarning</key>
+  <map>
+    <key>Comment</key>
+    <string>Viewer will warn user about HUD containing to many objects if objects count is above this value</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>1000</integer>
+  </map>
+  <key>RenderHUDTexturesWarning</key>
+  <map>
+    <key>Comment</key>
+    <string>Viewer will warn user about HUD containing to many textures if texture count is above this value</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>200</integer>
+  </map>
+  <key>RenderHUDOversizedTexturesWarning</key>
+  <map>
+    <key>Comment</key>
+    <string>How many textures with size 1024 * 1024 or bigger HUD can contain before notifying user</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>6</integer>
+  </map>
+  <key>RenderHUDTexturesMemoryWarning</key>
+  <map>
+    <key>Comment</key>
+    <string>Viewer will warn user about HUD textures using memory above this value (in bytes)</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>U32</string>
+    <key>Value</key>
+    <integer>32000000</integer>
+  </map>
   <key>RenderAutoMuteSurfaceAreaLimit</key>
   <map>
     <key>Comment</key>
@@ -12825,6 +12869,17 @@
       <key>Value</key>
       <real>1.0</real>
     </map>
+    <key>LastSystemUIScaleFactor</key>
+    <map>
+      <key>Comment</key>
+      <string>Size of system UI during last run. On Windows 100% (96 DPI) system setting is 1.0 UI size</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>1.0</real>
+    </map>
     <key>UIScrollbarSize</key>
     <map>
       <key>Comment</key>
@@ -13320,6 +13375,17 @@
       <key>Value</key>
       <string>1</string>
     </map>
+    <key>UpdaterShowReleaseNotes</key>
+    <map>
+        <key>Comment</key>
+        <string>Enables displaying of the Release notes in a web floater after update.</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>Boolean</string>
+        <key>Value</key>
+        <integer>1</integer>
+    </map>
     <key>UploadBakedTexOld</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index b00c9608229b06a859014f787a35147d03af99a7..66e2d6fa6afa6f7888581595007a1970c7a9ffa4 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3895,11 +3895,17 @@ void LLAgent::handleTeleportFinished()
 		mIsMaturityRatingChangingDuringTeleport = false;
 	}
     
-    // Init SLM Marketplace connection so we know which UI should be used for the user as a merchant
-    // Note: Eventually, all merchant will be migrated to the new SLM system and there will be no reason to show the old UI at all.
-    // Note: Some regions will not support the SLM cap for a while so we need to do that check for each teleport.
-    // *TODO : Suppress that line from here once the whole grid migrated to SLM and move it to idle_startup() (llstartup.cpp)
-    check_merchant_status();
+    if (mRegionp)
+    {
+        if (mRegionp->capabilitiesReceived())
+        {
+            onCapabilitiesReceivedAfterTeleport();
+        }
+        else
+        {
+            mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::onCapabilitiesReceivedAfterTeleport));
+        }
+    }
 }
 
 void LLAgent::handleTeleportFailed()
@@ -3931,6 +3937,14 @@ void LLAgent::handleTeleportFailed()
 	}
 }
 
+/*static*/
+void LLAgent::onCapabilitiesReceivedAfterTeleport()
+{
+
+    check_merchant_status();
+}
+
+
 void LLAgent::teleportRequest(
 	const U64& region_handle,
 	const LLVector3& pos_local,
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 3a533c2cba7564b981020476845af74eaab26ebd..d82ff7a67fb0db4506388abdc43e76771994696e 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -676,6 +676,8 @@ class LLAgent : public LLOldEvents::LLObservable
 	void            handleTeleportFinished();
 	void            handleTeleportFailed();
 
+    static void     onCapabilitiesReceivedAfterTeleport();
+
 	//--------------------------------------------------------------------
 	// Teleport State
 	//--------------------------------------------------------------------
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index b76a66ab392f9cb5bdabd7a84e6dccff2dd29dc2..170e4063a1524b22d1eb62d69490194db116526b 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -62,23 +62,37 @@ using namespace LLAvatarAppearanceDefines;
 
 ///////////////////////////////////////////////////////////////////////////////
 
-// Callback to wear and start editing an item that has just been created.
-void wear_and_edit_cb(const LLUUID& inv_item)
+void set_default_permissions(LLViewerInventoryItem* item)
 {
-	if (inv_item.isNull()) return;
-	
-		LLViewerInventoryItem* item = gInventory.getItem(inv_item);
-		if (!item) return;
-
-		LLPermissions perm = item->getPermissions();
+	llassert(item);
+	LLPermissions perm = item->getPermissions();
+	if (perm.getMaskNextOwner() != LLFloaterPerms::getNextOwnerPerms("Wearables")
+		|| perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms("Wearables")
+		|| perm.getMaskGroup() != LLFloaterPerms::getGroupPerms("Wearables"))
+	{
 		perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables"));
 		perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables"));
 		perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables"));
+
 		item->setPermissions(perm);
 
 		item->updateServer(FALSE);
-		gInventory.updateItem(item);
-		gInventory.notifyObservers();
+	}
+}
+
+// Callback to wear and start editing an item that has just been created.
+void wear_and_edit_cb(const LLUUID& inv_item)
+{
+	if (inv_item.isNull()) return;
+	
+	LLViewerInventoryItem* item = gInventory.getItem(inv_item);
+	if (!item) return;
+
+	set_default_permissions(item);
+
+	// item was just created, update even if permissions did not changed
+	gInventory.updateItem(item);
+	gInventory.notifyObservers();
 
 	// Request editing the item after it gets worn.
 	gAgentWearables.requestEditingWearable(inv_item);
@@ -94,13 +108,8 @@ void wear_cb(const LLUUID& inv_item)
 		LLViewerInventoryItem* item = gInventory.getItem(inv_item);
 		if (item)
 		{
-			LLPermissions perm = item->getPermissions();
-			perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("Wearables"));
-			perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Wearables"));
-			perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Wearables"));
-			item->setPermissions(perm);
+			set_default_permissions(item);
 
-			item->updateServer(FALSE);
 			gInventory.updateItem(item);
 			gInventory.notifyObservers();
 		}
@@ -253,6 +262,7 @@ void LLAgentWearables::AddWearableToAgentInventoryCallback::fire(const LLUUID& i
 	{
 		LLAppearanceMgr::instance().addCOFItemLink(inv_item, 
 			new LLUpdateAppearanceAndEditWearableOnDestroy(inv_item), mDescription);
+		editWearable(inv_item);
 	}
 }
 
@@ -423,7 +433,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 	// old_wearable may still be referred to by other inventory items. Revert
 	// unsaved changes so other inventory items aren't affected by the changes
 	// that were just saved.
-	old_wearable->revertValues();
+	old_wearable->revertValuesWithoutUpdate();
 }
 
 void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index)
@@ -1364,6 +1374,30 @@ void LLAgentWearables::findAttachmentsAddRemoveInfo(LLInventoryModel::item_array
 	// LL_INFOS() << "remove " << remove_count << " add " << add_count << LL_ENDL;
 }
 
+std::vector<LLViewerObject*> LLAgentWearables::getTempAttachments()
+{
+	llvo_vec_t temp_attachs;
+	if (isAgentAvatarValid())
+	{
+		for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); iter != gAgentAvatarp->mAttachmentPoints.end();)
+		{
+			LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+			LLViewerJointAttachment* attachment = curiter->second;
+			for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+				attachment_iter != attachment->mAttachedObjects.end();
+				++attachment_iter)
+			{
+				LLViewerObject *objectp = (*attachment_iter);
+				if (objectp && objectp->isTempAttachment())
+				{
+					temp_attachs.push_back(objectp);
+				}
+			}
+		}
+	}
+	return temp_attachs;
+}
+
 void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remove)
 {
 	if (!isAgentAvatarValid()) return;
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 100448202080c8a2f6ecdfae5dd086e01dc4a5b5..b27698fd8f7110187ca3fa2b614f2357d7c27a5e 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -185,6 +185,8 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>, public LLWearable
 	static void		userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
 	static void		userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
 
+	static llvo_vec_t getTempAttachments();
+
 	//--------------------------------------------------------------------
 	// Signals
 	//--------------------------------------------------------------------
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index d403e393295fec09de439a6611c2e523ddd997e8..4d6d7a9d89e91e7ecb7f722a0cb8958fde4fd87f 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -1875,15 +1875,15 @@ bool LLAppearanceMgr::getCanReplaceCOF(const LLUUID& outfit_cat_id)
 		return false;
 	}
 
-	// Check whether the outfit contains any wearables we aren't wearing already (STORM-702).
+	// Check whether the outfit contains any wearables
 	LLInventoryModel::cat_array_t cats;
 	LLInventoryModel::item_array_t items;
-	LLFindWearablesEx is_worn(/*is_worn=*/ false, /*include_body_parts=*/ true);
+	LLFindWearables is_wearable;
 	gInventory.collectDescendentsIf(outfit_cat_id,
 		cats,
 		items,
 		LLInventoryModel::EXCLUDE_TRASH,
-		is_worn);
+		is_wearable);
 
 	return items.size() > 0;
 }
@@ -3477,13 +3477,13 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
         }
         else
         {
-            if (cofVersion < lastRcv)
+            if (cofVersion <= lastRcv)
             {
                 LL_WARNS("Avatar") << "Have already received update for cof version " << lastRcv
                     << " but requesting for " << cofVersion << LL_ENDL;
                 return;
             }
-            if (lastReq > cofVersion)
+            if (lastReq >= cofVersion)
             {
                 LL_WARNS("Avatar") << "Request already in flight for cof version " << lastReq
                     << " but requesting for " << cofVersion << LL_ENDL;
@@ -3503,7 +3503,7 @@ void LLAppearanceMgr::serverAppearanceUpdateCoro(LLCoreHttpUtil::HttpCoroutineAd
             LL_WARNS("Avatar") << "Forcing version failure on COF Baking" << LL_ENDL;
         }
 
-        LL_INFOS() << "Requesting bake for COF version " << cofVersion << LL_ENDL;
+        LL_INFOS("Avatar") << "Requesting bake for COF version " << cofVersion << LL_ENDL;
 
         LLSD postData;
         if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate"))
@@ -3969,6 +3969,10 @@ void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
 	LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int) val << LL_ENDL;
 	mAttachmentInvLinkEnabled = val;
 }
+boost::signals2::connection LLAppearanceMgr::setAttachmentsChangedCallback(attachments_changed_callback_t cb)
+{
+	return mAttachmentsChangeSignal.connect(cb);
+}
 
 void dumpAttachmentSet(const std::set<LLUUID>& atts, const std::string& msg)
 {
@@ -3995,6 +3999,8 @@ void LLAppearanceMgr::registerAttachment(const LLUUID& item_id)
 	gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
 
 	LLAttachmentsMgr::instance().onAttachmentArrived(item_id);
+
+	mAttachmentsChangeSignal();
 }
 
 void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
@@ -4015,6 +4021,8 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
 	{
 		//LL_INFOS() << "no link changes, inv link not enabled" << LL_ENDL;
 	}
+
+	mAttachmentsChangeSignal();
 }
 
 BOOL LLAppearanceMgr::getIsInCOF(const LLUUID& obj_id) const
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index 2e570b918815e3dd574794f83e9af540489bec17..f0d3f80f5966870f47eca8247221b7aa160c70e1 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -229,6 +229,10 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
 	std::string getAppearanceServiceURL() const;
 
+	typedef boost::function<void ()> attachments_changed_callback_t;
+	typedef boost::signals2::signal<void ()> attachments_changed_signal_t;
+	boost::signals2::connection setAttachmentsChangedCallback(attachments_changed_callback_t cb);
+
 
 
 private:
@@ -272,6 +276,8 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	LLTimer mInFlightTimer;
 	static bool mActive;
 
+	attachments_changed_signal_t		mAttachmentsChangeSignal;
+	
 	LLUUID mCOFImageID;
 
 	std::auto_ptr<LLOutfitUnLockTimer> mUnlockOutfitTimer;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index ff1d91ebe2617bf1b61cef6c69390b35ccb7d4a2..a0ebae119e57f864dccd7a92e40f81c9046c1af5 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -702,7 +702,8 @@ LLAppViewer::LLAppViewer()
 	mPeriodicSlowFrame(LLCachedControl<bool>(gSavedSettings,"Periodic Slow Frame", FALSE)),
 	mFastTimerLogThread(NULL),
 	mUpdater(new LLUpdaterService()),
-	mSettingsLocationList(NULL)
+	mSettingsLocationList(NULL),
+	mIsFirstRun(false)
 {
 	if(NULL != sInstance)
 	{
@@ -1128,17 +1129,23 @@ bool LLAppViewer::init()
 #if LL_WINDOWS
 	if (gGLManager.mGLVersion < LLFeatureManager::getInstance()->getExpectedGLVersion())
 	{
+		std::string url;
 		if (gGLManager.mIsIntel)
 		{
-			LLNotificationsUtil::add("IntelOldDriver");
+			url = LLTrans::getString("IntelDriverPage");
 		}
 		else if (gGLManager.mIsNVIDIA)
 		{
-			LLNotificationsUtil::add("NVIDIAOldDriver");
+			url = LLTrans::getString("NvidiaDriverPage");
 		}
 		else if (gGLManager.mIsATI)
 		{
-			LLNotificationsUtil::add("AMDOldDriver");
+			url = LLTrans::getString("AMDDriverPage");
+		}
+
+		if (!url.empty())
+		{
+			LLNotificationsUtil::add("OldGPUDriver", LLSD().with("URL", url));
 		}
 	}
 #endif
@@ -1226,6 +1233,8 @@ bool LLAppViewer::init()
         boost::bind(&LLControlGroup::getU32, boost::ref(gSavedSettings), _1),
         boost::bind(&LLControlGroup::declareU32, boost::ref(gSavedSettings), _1, _2, _3, LLControlVariable::PERSIST_ALWAYS));
 
+	showReleaseNotesIfRequired();
+
 	/*----------------------------------------------------------------------*/
 	// nat 2016-06-29 moved the following here from the former mainLoop().
 	mMainloopTimeout = new LLWatchdogTimeout();
@@ -2477,7 +2486,10 @@ bool LLAppViewer::initConfiguration()
 
 	if (gSavedSettings.getBOOL("FirstRunThisInstall"))
 	{
-		// Note that the "FirstRunThisInstall" settings is currently unused.
+		// Set firstrun flag to indicate that some further init actiona should be taken 
+		// like determining screen DPI value and so on
+		mIsFirstRun = true;
+
 		gSavedSettings.setBOOL("FirstRunThisInstall", FALSE);
 	}
 
@@ -3134,7 +3146,8 @@ bool LLAppViewer::initWindow()
 		.min_width(gSavedSettings.getU32("MinWindowWidth"))
 		.min_height(gSavedSettings.getU32("MinWindowHeight"))
 		.fullscreen(gSavedSettings.getBOOL("FullScreen"))
-		.ignore_pixel_depth(ignorePixelDepth);
+		.ignore_pixel_depth(ignorePixelDepth)
+		.first_run(mIsFirstRun);
 
 	gViewerWindow = new LLViewerWindow(window_params);
 
@@ -5805,6 +5818,20 @@ void LLAppViewer::launchUpdater()
 	// LLAppViewer::instance()->forceQuit();
 }
 
+/**
+* Check if user is running a new version of the viewer.
+* Display the Release Notes if it's not overriden by the "UpdaterShowReleaseNotes" setting.
+*/
+void LLAppViewer::showReleaseNotesIfRequired()
+{
+	if (LLVersionInfo::getChannelAndVersion() != gLastRunVersion
+		&& gSavedSettings.getBOOL("UpdaterShowReleaseNotes")
+		&& !gSavedSettings.getBOOL("FirstLoginThisInstall"))
+	{
+		LLSD info(getViewerInfo());
+		LLWeb::loadURLInternal(info["VIEWER_RELEASE_NOTES_URL"]);
+	}
+}
 
 //virtual
 void LLAppViewer::setMasterSystemAudioMute(bool mute)
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index f7c1bb58b481178a071485d84a3f482b4f76512a..948d316009aebda5c65519365aeecab072b8b8dd 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -254,6 +254,8 @@ class LLAppViewer : public LLApp
 
     void sendLogoutRequest();
     void disconnectViewer();
+
+	void showReleaseNotesIfRequired();
 	
 	// *FIX: the app viewer class should be some sort of singleton, no?
 	// Perhaps its child class is the singleton and this should be an abstract base.
@@ -315,6 +317,7 @@ class LLAppViewer : public LLApp
 	// llcorehttp library init/shutdown helper
 	LLAppCoreHttp mAppCoreHttp;
 
+	bool mIsFirstRun;
 	//---------------------------------------------
 	//*NOTE: Mani - legacy updater stuff
 	// Still useable?
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index af0cd27fd5b628257829d56d3fe73cdb704a7535..5107030476eaf49e94a19eb0c84d783b3465a4a8 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -231,6 +231,8 @@ int APIENTRY WINMAIN(HINSTANCE hInstance,
 	DWORD heap_enable_lfh_error[MAX_HEAPS];
 	S32 num_heaps = 0;
 	
+	LLWindowWin32::setDPIAwareness();
+
 #if WINDOWS_CRT_MEM_CHECKS && !INCLUDE_VLD
 	_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF ); // dump memory leaks on exit
 #elif 0
@@ -567,7 +569,7 @@ bool LLAppViewerWin32::initHardwareTest()
 	// Do driver verification and initialization based on DirectX
 	// hardware polling and driver versions
 	//
-	if (FALSE == gSavedSettings.getBOOL("NoHardwareProbe"))
+	if (TRUE == gSavedSettings.getBOOL("ProbeHardwareOnStartup") && FALSE == gSavedSettings.getBOOL("NoHardwareProbe"))
 	{
 		// per DEV-11631 - disable hardware probing for everything
 		// but vram.
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index a6e745448a98c921cd4a1aa46238d01b18251426..7b8c630837264c7baccad48150f8616043140c00 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -950,15 +950,22 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 	const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList();
 	if (inventory_selected.empty()) return false; // nothing selected
 
+	const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
 	bool can_share = true;
 	std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin();
 	const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();
 	for (; it != it_end; ++it)
 	{
-		LLViewerInventoryCategory* inv_cat = gInventory.getCategory(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
-		// any category can be offered.
+		LLUUID cat_id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID();
+		LLViewerInventoryCategory* inv_cat = gInventory.getCategory(cat_id);
+		// any category can be offered if it's not in trash.
 		if (inv_cat)
 		{
+			if ((cat_id == trash_id) || gInventory.isObjectDescendentOf(cat_id, trash_id))
+			{
+				can_share = false;
+				break;
+			}
 			continue;
 		}
 
diff --git a/indra/newview/llavatarrendernotifier.cpp b/indra/newview/llavatarrendernotifier.cpp
index 24934fdb73c8008e910a60b7029816b3d43871db..94584a623b95b56b202b16fd3cc9c720d3bc565a 100644
--- a/indra/newview/llavatarrendernotifier.cpp
+++ b/indra/newview/llavatarrendernotifier.cpp
@@ -38,6 +38,7 @@
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llnotificationtemplate.h"
+#include "llslurl.h"
 #include "lltimer.h"
 #include "llvoavatarself.h"
 #include "llviewercontrol.h"
@@ -51,6 +52,11 @@ static const F32 RENDER_ALLOWED_CHANGE_PCT = 0.1;
 // wait seconds before processing over limit updates after last complexity change
 static const U32 OVER_LIMIT_UPDATE_DELAY = 70;
 
+static const U32 WARN_HUD_OBJECTS_LIMIT = 1000;
+static const U32 WARN_HUD_TEXTURES_LIMIT = 200;
+static const U32 WARN_HUD_OVERSIZED_TEXTURES_LIMIT = 6;
+static const U32 WARN_HUD_TEXTURE_MEMORY_LIMIT = 32000000; // in bytes
+
 
 LLAvatarRenderNotifier::LLAvatarRenderNotifier() :
 mAgentsCount(0),
@@ -264,3 +270,220 @@ void LLAvatarRenderNotifier::updateNotificationAgent(U32 agentComplexity)
     }
 }
 
+// LLHUDRenderNotifier
+
+static const char* e_hud_messages[] =
+{
+    "hud_render_textures_warning",
+    "hud_render_cramped_warning",
+    "hud_render_heavy_textures_warning",
+    "hud_render_cost_warning",
+    "hud_render_memory_warning",
+};
+
+LLHUDRenderNotifier::LLHUDRenderNotifier() :
+mReportedHUDWarning(WARN_NONE)
+{
+}
+
+LLHUDRenderNotifier::~LLHUDRenderNotifier()
+{
+}
+
+void LLHUDRenderNotifier::updateNotificationHUD(hud_complexity_list_t complexity)
+{
+    if (!isAgentAvatarValid() || !gAgentWearables.areWearablesLoaded())
+    {
+        // data not ready.
+        return;
+    }
+
+    // TODO:
+    // Find a way to show message with list of issues, but without making it too large
+    // and intrusive.
+
+    LLHUDComplexity new_total_complexity;
+    LLHUDComplexity report_complexity;
+
+    hud_complexity_list_t::iterator iter = complexity.begin();
+    hud_complexity_list_t::iterator end = complexity.end();
+    EWarnLevel warning_level = WARN_NONE;
+    for (; iter != end; ++iter)
+    {
+        LLHUDComplexity object_complexity = *iter;
+        EWarnLevel object_level = getWarningType(object_complexity, report_complexity);
+        if (object_level >= 0)
+        {
+            warning_level = object_level;
+            report_complexity = object_complexity;
+        }
+        new_total_complexity.objectsCost += object_complexity.objectsCost;
+        new_total_complexity.objectsCount += object_complexity.objectsCount;
+        new_total_complexity.texturesCost += object_complexity.texturesCost;
+        new_total_complexity.texturesCount += object_complexity.texturesCount;
+        new_total_complexity.largeTexturesCount += object_complexity.largeTexturesCount;
+        new_total_complexity.texturesMemoryTotal += object_complexity.texturesMemoryTotal;
+    }
+
+    if (mHUDPopUpDelayTimer.hasExpired() || isNotificationVisible())
+    {
+        if (warning_level >= 0)
+        {
+            // Display info about most complex HUD object
+            // make sure it shown only once unless object's complexity or object itself changed
+            if (mReportedHUDComplexity.objectId != report_complexity.objectId
+                || mReportedHUDWarning != warning_level)
+            {
+                displayHUDNotification(warning_level, report_complexity.objectId, report_complexity.objectName, report_complexity.jointName);
+                mReportedHUDComplexity = report_complexity;
+                mReportedHUDWarning = warning_level;
+            }
+        }
+        else
+        {
+            // Check if total complexity is above threshold and above previous warning
+            // Show warning with highest importance (5m delay between warnings by default)
+            if (!mReportedHUDComplexity.objectId.isNull())
+            {
+                mReportedHUDComplexity.reset();
+                mReportedHUDWarning = WARN_NONE;
+            }
+
+            warning_level = getWarningType(new_total_complexity, mReportedHUDComplexity);
+            if (warning_level >= 0 && mReportedHUDWarning != warning_level)
+            {
+                displayHUDNotification(warning_level);
+            }
+            mReportedHUDComplexity = new_total_complexity;
+            mReportedHUDWarning = warning_level;
+        }
+    }
+    else if (warning_level >= 0)
+    {
+        LL_DEBUGS("HUDdetail") << "HUD individual warning postponed" << LL_ENDL;
+    }
+
+    if (mLatestHUDComplexity.objectsCost != new_total_complexity.objectsCost
+        || mLatestHUDComplexity.objectsCount != new_total_complexity.objectsCount
+        || mLatestHUDComplexity.texturesCost != new_total_complexity.texturesCost
+        || mLatestHUDComplexity.texturesCount != new_total_complexity.texturesCount
+        || mLatestHUDComplexity.largeTexturesCount != new_total_complexity.largeTexturesCount
+        || mLatestHUDComplexity.texturesMemoryTotal != new_total_complexity.texturesMemoryTotal)
+    {
+        LL_INFOS("HUDdetail") << "HUD textures count: " << new_total_complexity.texturesCount
+            << " HUD textures cost: " << new_total_complexity.texturesCost
+            << " Large textures: " << new_total_complexity.largeTexturesCount
+            << " HUD objects cost: " << new_total_complexity.objectsCost
+            << " HUD objects count: " << new_total_complexity.objectsCount << LL_ENDL;
+
+        mLatestHUDComplexity = new_total_complexity;
+    }
+}
+
+bool LLHUDRenderNotifier::isNotificationVisible()
+{
+    return mHUDNotificationPtr != NULL && mHUDNotificationPtr->isActive();
+}
+
+// private static
+LLHUDRenderNotifier::EWarnLevel LLHUDRenderNotifier::getWarningType(LLHUDComplexity object_complexity, LLHUDComplexity cmp_complexity)
+{
+    static LLCachedControl<U32> max_render_cost(gSavedSettings, "RenderAvatarMaxComplexity", 0U); // ties max HUD cost to avatar cost
+    static LLCachedControl<U32> max_objects_count(gSavedSettings, "RenderHUDObjectsWarning", WARN_HUD_OBJECTS_LIMIT);
+    static LLCachedControl<U32> max_textures_count(gSavedSettings, "RenderHUDTexturesWarning", WARN_HUD_TEXTURES_LIMIT);
+    static LLCachedControl<U32> max_oversized_count(gSavedSettings, "RenderHUDOversizedTexturesWarning", WARN_HUD_OVERSIZED_TEXTURES_LIMIT);
+    static LLCachedControl<U32> max_texture_memory(gSavedSettings, "RenderHUDTexturesMemoryWarning", WARN_HUD_TEXTURE_MEMORY_LIMIT);
+
+    if (cmp_complexity.texturesMemoryTotal < object_complexity.texturesMemoryTotal
+        && object_complexity.texturesMemoryTotal > (F64Bytes)max_texture_memory)
+    {
+        // Note: Memory might not be accurate since texture is still loading or discard level changes
+
+        LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " memory usage over limit, "
+            << " was " << cmp_complexity.texturesMemoryTotal
+            << " is " << object_complexity.texturesMemoryTotal << LL_ENDL;
+
+        return WARN_MEMORY;
+    }
+    else if ((cmp_complexity.objectsCost < object_complexity.objectsCost
+        || cmp_complexity.texturesCost < object_complexity.texturesCost)
+        && max_render_cost > 0
+        && object_complexity.objectsCost + object_complexity.texturesCost > max_render_cost)
+    {
+        LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " complexity over limit,"
+            << " HUD textures cost: " << object_complexity.texturesCost
+            << " HUD objects cost: " << object_complexity.objectsCost << LL_ENDL;
+
+        return WARN_COST;
+    }
+    else if (cmp_complexity.largeTexturesCount < object_complexity.largeTexturesCount
+        && object_complexity.largeTexturesCount > max_oversized_count)
+    {
+        LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " contains to many large textures: "
+            << object_complexity.largeTexturesCount << LL_ENDL;
+
+        return WARN_HEAVY;
+    }
+    else if (cmp_complexity.texturesCount < object_complexity.texturesCount
+        && object_complexity.texturesCount > max_textures_count)
+    {
+        LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " contains too many textures: "
+            << object_complexity.texturesCount << LL_ENDL;
+
+        return WARN_CRAMPED;
+    }
+    else if (cmp_complexity.objectsCount < object_complexity.objectsCount
+        && object_complexity.objectsCount > max_objects_count)
+    {
+        LL_DEBUGS("HUDdetail") << "HUD " << object_complexity.objectName << " contains too many objects: "
+            << object_complexity.objectsCount << LL_ENDL;
+
+        return WARN_TEXTURES;
+    }
+    return WARN_NONE;
+}
+
+void LLHUDRenderNotifier::displayHUDNotification(EWarnLevel warn_type, LLUUID obj_id, std::string obj_name, std::string joint_name)
+{
+    static LLCachedControl<U32> pop_up_delay(gSavedSettings, "ComplexityChangesPopUpDelay", 300);
+    static LLCachedControl<U32> expire_delay(gSavedSettings, "ShowMyComplexityChanges", 20);
+    LLDate expire_date(LLDate::now().secondsSinceEpoch() + expire_delay);
+
+    // Since we need working "ignoretext" there is no other way but to
+    // use single notification while constructing it from multiple pieces
+    LLSD reason_args;
+    if (obj_id.isNull())
+    {
+        reason_args["HUD_DETAILS"] = LLTrans::getString("hud_description_total");
+    }
+    else
+    {
+        if (obj_name.empty())
+        {
+            LL_WARNS("HUDdetail") << "Object name not assigned" << LL_ENDL;
+        }
+        if (joint_name.empty())
+        {
+            std::string verb = "select?name=" + LLURI::escape(obj_name);
+            reason_args["HUD_DETAILS"] = LLSLURL("inventory", obj_id, verb.c_str()).getSLURLString();
+        }
+        else
+        {
+            LLSD object_args;
+            std::string verb = "select?name=" + LLURI::escape(obj_name);
+            object_args["OBJ_NAME"] = LLSLURL("inventory", obj_id, verb.c_str()).getSLURLString();
+            object_args["JNT_NAME"] = LLTrans::getString(joint_name);
+            reason_args["HUD_DETAILS"] = LLTrans::getString("hud_name_with_joint", object_args);
+        }
+    }
+
+    LLSD msg_args;
+    msg_args["HUD_REASON"] = LLTrans::getString(e_hud_messages[warn_type], reason_args);
+
+    mHUDNotificationPtr = LLNotifications::instance().add(LLNotification::Params()
+        .name("HUDComplexityWarning")
+        .expiry(expire_date)
+        .substitutions(msg_args));
+    mHUDPopUpDelayTimer.resetWithExpiry(pop_up_delay);
+}
+
diff --git a/indra/newview/llavatarrendernotifier.h b/indra/newview/llavatarrendernotifier.h
index 2a2704de28550719508abf44421039b50cbbcc34..a169baef40f4ad6c64e769af59984c2d6468b1d1 100644
--- a/indra/newview/llavatarrendernotifier.h
+++ b/indra/newview/llavatarrendernotifier.h
@@ -33,6 +33,36 @@
 
 class LLViewerRegion;
 
+struct LLHUDComplexity
+{
+    LLHUDComplexity()
+    {
+        reset();
+    }
+    void reset()
+    {
+        objectId = LLUUID::null;
+        objectName = "";
+        objectsCost = 0;
+        objectsCount = 0;
+        texturesCost = 0;
+        texturesCount = 0;
+        largeTexturesCount = 0;
+        texturesMemoryTotal = (F64Bytes)0;
+    }
+    LLUUID objectId;
+    std::string objectName;
+    std::string jointName;
+    U32 objectsCost;
+    U32 objectsCount;
+    U32 texturesCost;
+    U32 texturesCount;
+    U32 largeTexturesCount;
+    F64Bytes texturesMemoryTotal;
+};
+
+typedef std::list<LLHUDComplexity> hud_complexity_list_t;
+
 // Class to notify user about drastic changes in agent's render weights or if other agents
 // reported that user's agent is too 'heavy' for their settings
 class LLAvatarRenderNotifier : public LLSingleton<LLAvatarRenderNotifier>
@@ -81,4 +111,36 @@ class LLAvatarRenderNotifier : public LLSingleton<LLAvatarRenderNotifier>
     S32 mLastOutfitRezStatus;
 };
 
+// Class to notify user about heavy set of HUD
+class LLHUDRenderNotifier : public LLSingleton<LLHUDRenderNotifier>
+{
+public:
+    LLHUDRenderNotifier();
+    ~LLHUDRenderNotifier();
+
+    void updateNotificationHUD(hud_complexity_list_t complexity);
+    bool isNotificationVisible();
+
+private:
+    enum EWarnLevel
+    {
+        WARN_NONE = -1,
+        WARN_TEXTURES = 0, // least important
+        WARN_CRAMPED,
+        WARN_HEAVY,
+        WARN_COST,
+        WARN_MEMORY, //most important
+    };
+
+    LLNotificationPtr mHUDNotificationPtr;
+
+    static EWarnLevel getWarningType(LLHUDComplexity object_complexity, LLHUDComplexity cmp_complexity);
+    void displayHUDNotification(EWarnLevel warn_type, LLUUID obj_id = LLUUID::null,  std::string object_name = "", std::string joint_name = "");
+
+    LLHUDComplexity mReportedHUDComplexity;
+    EWarnLevel mReportedHUDWarning;
+    LLHUDComplexity mLatestHUDComplexity;
+    LLFrameTimer mHUDPopUpDelayTimer;
+};
+
 #endif /* ! defined(LL_llavatarrendernotifier_H) */
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 00fa6dd9798793d036595787ecfdfc65d3520fe0..54c6c985d6b5d2c040601916e13d7de7558ec262 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -311,7 +311,8 @@ LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)
 	}
 	else if (mesg[0] == '/'
 			 && mesg[1]
-			 && LLStringOps::isDigit(mesg[1]))
+			 && (LLStringOps::isDigit(mesg[1])
+				 || (mesg[1] == '-' && mesg[2] && LLStringOps::isDigit(mesg[2]))))
 	{
 		// This a special "/20" speak on a channel
 		S32 pos = 0;
@@ -325,7 +326,7 @@ LLWString LLChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)
 			channel_string.push_back(c);
 			pos++;
 		}
-		while(c && pos < 64 && LLStringOps::isDigit(c));
+		while(c && pos < 64 && (LLStringOps::isDigit(c) || (pos == 1 && c == '-')));
 		
 		// Move the pointer forward to the first non-whitespace char
 		// Check isspace before looping, so we can handle "/33foo"
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
index 05c7e6caa5ddf93287d507b1ed0b6bd2c6f4e180..4e69896b693b48d3a5aa250ce454b8aa1724bdb3 100644
--- a/indra/newview/llconversationlog.cpp
+++ b/indra/newview/llconversationlog.cpp
@@ -448,7 +448,12 @@ bool LLConversationLog::moveLog(const std::string &originDirectory, const std::s
 std::string LLConversationLog::getFileName()
 {
 	std::string filename = "conversation";
-	return gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename) + ".log";
+	std::string log_address = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename);
+	if (!log_address.empty())
+	{
+		log_address += ".log";
+	}
+	return log_address;
 }
 
 bool LLConversationLog::saveToFile(const std::string& filename)
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index bababca6524bf4fe5eb53feeef3124a313e2e92a..c2d0d9f06b75dc8a26a33de5723e02e6bd237cda 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -108,6 +108,7 @@ class LLFloaterAbout
 	static const std::string sCheckUpdateListenerName;
 	
     static void startFetchServerReleaseNotes();
+    static void fetchServerReleaseNotesCoro(const std::string& cap_url);
     static void handleServerReleaseNotes(LLSD results);
 };
 
@@ -224,35 +225,62 @@ void LLFloaterAbout::startFetchServerReleaseNotes()
     // an URL suitable for external browsers in the "Location:" HTTP header.
     std::string cap_url = region->getCapability("ServerReleaseNotes");
 
-    LLCoreHttpUtil::HttpCoroutineAdapter::callbackHttpGet(cap_url,
-        &LLFloaterAbout::handleServerReleaseNotes, &LLFloaterAbout::handleServerReleaseNotes);
+    LLCoros::instance().launch("fetchServerReleaseNotesCoro", boost::bind(&LLFloaterAbout::fetchServerReleaseNotesCoro, cap_url));
 
 }
 
+/*static*/
+void LLFloaterAbout::fetchServerReleaseNotesCoro(const std::string& cap_url)
+{
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("fetchServerReleaseNotesCoro", LLCore::HttpRequest::DEFAULT_POLICY_ID));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
+
+    httpOpts->setWantHeaders(true);
+    httpOpts->setFollowRedirects(false);
+
+    LLSD result = httpAdapter->getAndSuspend(httpRequest, cap_url, httpOpts);
+
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+    if (!status)
+    {
+        handleServerReleaseNotes(httpResults);
+    }
+    else
+    {
+        handleServerReleaseNotes(result);
+    }
+}
+
 /*static*/
 void LLFloaterAbout::handleServerReleaseNotes(LLSD results)
 {
-//     LLFloaterAbout* floater_about = LLFloaterReg::getTypedInstance<LLFloaterAbout>("sl_about");
-//     if (floater_about)
-//     {
-        LLSD http_headers;
-        if (results.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS))
-        {
-            LLSD http_results = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
-            http_headers = http_results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
-        }
-        else
-        {
-            http_headers = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
-        }
-        
-        std::string location = http_headers[HTTP_IN_HEADER_LOCATION].asString();
-        if (location.empty())
-        {
-            location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL");
-        }
-        LLAppViewer::instance()->setServerReleaseNotesURL(location);
-//    }
+    LLSD http_headers;
+    if (results.has(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS))
+    {
+        LLSD http_results = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+        http_headers = http_results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+    }
+    else
+    {
+        http_headers = results[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_HEADERS];
+    }
+
+    std::string location = http_headers[HTTP_IN_HEADER_LOCATION].asString();
+    if (location.empty())
+    {
+        location = LLTrans::getString("ErrorFetchingServerReleaseNotesURL");
+    }
+    LLAppViewer::instance()->setServerReleaseNotesURL(location);
+
+    LLFloaterAbout* floater_about = LLFloaterReg::findTypedInstance<LLFloaterAbout>("sl_about");
+    if (floater_about)
+    {
+        floater_about->setSupportText(location);
+    }
 }
 
 class LLFloaterAboutListener: public LLEventAPI
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 72892b47a492dd38623550c86fa88acfb6200598..aa7bfbfdb7e61a196afe7337807c6babd30eb518 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -55,6 +55,8 @@
 
 //#include "llsdserialize.h"
 
+static const U32 AVATAR_PICKER_SEARCH_TIMEOUT = 180U;
+
 //put it back as a member once the legacy path is out?
 static std::map<LLUUID, LLAvatarName> sAvatarNameMap;
 
@@ -463,10 +465,13 @@ void LLFloaterAvatarPicker::findCoro(std::string url, LLUUID queryID, std::strin
     LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
         httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("genericPostCoro", httpPolicy));
     LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions);
 
     LL_INFOS("HttpCoroutineAdapter", "genericPostCoro") << "Generic POST for " << url << LL_ENDL;
 
-    LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+    httpOpts->setTimeout(AVATAR_PICKER_SEARCH_TIMEOUT);
+
+    LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts);
 
     LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
     LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
diff --git a/indra/newview/llfloaterbuycurrency.cpp b/indra/newview/llfloaterbuycurrency.cpp
index e21a8594bc0e4f37c3087a65dab274c874807f2b..91436e52fe663962ab0328b636740e4add4d3390 100644
--- a/indra/newview/llfloaterbuycurrency.cpp
+++ b/indra/newview/llfloaterbuycurrency.cpp
@@ -280,7 +280,7 @@ void LLFloaterBuyCurrencyUI::onClickCancel()
 
 void LLFloaterBuyCurrencyUI::onClickErrorWeb()
 {
-	LLWeb::loadURLExternal(mManager.errorURI());
+	LLWeb::loadURL(mManager.errorURI());
 	closeFloater();
 	// Update L$ balance
 	LLStatusBar::sendMoneyBalanceRequest();
diff --git a/indra/newview/llfloatergesture.cpp b/indra/newview/llfloatergesture.cpp
index d842106146e0b3198bd1b5deaf1eabe7f487b86c..b840d37c4d99fe0af8612c5452365468e760d6bf 100644
--- a/indra/newview/llfloatergesture.cpp
+++ b/indra/newview/llfloatergesture.cpp
@@ -328,7 +328,7 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur
 		element["columns"][0]["font"]["name"] = "SANSSERIF";
 		element["columns"][0]["font"]["style"] = font_style;
 
-		std::string key_string = LLKeyboard::stringFromKey(gesture->mKey);
+		std::string key_string;
 		std::string buffer;
 
 		if (gesture->mKey == KEY_NONE)
@@ -338,6 +338,7 @@ void LLFloaterGesture::addGesture(const LLUUID& item_id , LLMultiGesture* gestur
 		}
 		else
 		{
+			key_string = LLKeyboard::stringFromKey(gesture->mKey);
 			buffer = LLKeyboard::stringFromAccelerator(gesture->mMask,
 					gesture->mKey);
 		}
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 7a989806a1ff2ff1ead578d21ddd1b3e6e55afc3..257b39a7dda1f4cafa3153fd6c153411f83ec597 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -798,7 +798,8 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*
 	}
 	else if (mesg[0] == '/'
 			 && mesg[1]
-			 && LLStringOps::isDigit(mesg[1]))
+			 && (LLStringOps::isDigit(mesg[1])
+				 || (mesg[1] == '-' && mesg[2] && LLStringOps::isDigit(mesg[2]))))
 	{
 		// This a special "/20" speak on a channel
 		S32 pos = 0;
@@ -812,7 +813,7 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*
 			channel_string.push_back(c);
 			pos++;
 		}
-		while(c && pos < 64 && LLStringOps::isDigit(c));
+		while(c && pos < 64 && (LLStringOps::isDigit(c) || (pos==1 && c =='-')));
 		
 		// Move the pointer forward to the first non-whitespace char
 		// Check isspace before looping, so we can handle "/33foo"
@@ -837,19 +838,36 @@ LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32*
 
 void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
 {
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_ChatFromViewer);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_ChatData);
-	msg->addStringFast(_PREHASH_Message, utf8_out_text);
-	msg->addU8Fast(_PREHASH_Type, type);
-	msg->addS32("Channel", channel);
-
-	gAgent.sendReliableMessage();
-
-	add(LLStatViewer::CHAT_COUNT, 1);
+    LLMessageSystem* msg = gMessageSystem;
+
+    if (channel >= 0)
+    {
+        msg->newMessageFast(_PREHASH_ChatFromViewer);
+        msg->nextBlockFast(_PREHASH_AgentData);
+        msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+        msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+        msg->nextBlockFast(_PREHASH_ChatData);
+        msg->addStringFast(_PREHASH_Message, utf8_out_text);
+        msg->addU8Fast(_PREHASH_Type, type);
+        msg->addS32("Channel", channel);
+
+    }
+    else
+    {
+        // Hack: ChatFromViewer doesn't allow negative channels
+        msg->newMessage("ScriptDialogReply");
+        msg->nextBlock("AgentData");
+        msg->addUUID("AgentID", gAgentID);
+        msg->addUUID("SessionID", gAgentSessionID);
+        msg->nextBlock("Data");
+        msg->addUUID("ObjectID", gAgentID);
+        msg->addS32("ChatChannel", channel);
+        msg->addS32("ButtonIndex", 0);
+        msg->addString("ButtonLabel", utf8_out_text);
+    }
+
+    gAgent.sendReliableMessage();
+    add(LLStatViewer::CHAT_COUNT, 1);
 }
 
 class LLChatCommandHandler : public LLCommandHandler
diff --git a/indra/newview/llfloaterpay.cpp b/indra/newview/llfloaterpay.cpp
index 31245db34450f97bff6bf04f9556b4bbf68ec4d1..dfe462c8d1e2d07452c05c838be35a3a6b2866d7 100644
--- a/indra/newview/llfloaterpay.cpp
+++ b/indra/newview/llfloaterpay.cpp
@@ -72,6 +72,8 @@ struct LLGiveMoneyInfo
 		mFloater(floater), mAmount(amount){}
 };
 
+typedef boost::shared_ptr<LLGiveMoneyInfo> give_money_ptr;
+
 ///----------------------------------------------------------------------------
 /// Class LLFloaterPay
 ///----------------------------------------------------------------------------
@@ -94,18 +96,18 @@ class LLFloaterPay : public LLFloater
 							bool is_group);
 	static bool payConfirmationCallback(const LLSD& notification,
 										const LLSD& response,
-										LLGiveMoneyInfo* info);
+										give_money_ptr info);
 
 private:
 	static void onCancel(void* data);
 	static void onKeystroke(LLLineEditor* editor, void* data);
-	static void onGive(void* data);
+	static void onGive(give_money_ptr info);
 	void give(S32 amount);
 	static void processPayPriceReply(LLMessageSystem* msg, void **userdata);
 	void finishPayUI(const LLUUID& target_id, BOOL is_group);
 
 protected:
-	std::vector<LLGiveMoneyInfo*> mCallbackData;
+	std::vector<give_money_ptr> mCallbackData;
 	money_callback mCallback;
 	LLTextBox* mObjectNameText;
 	LLUUID mTargetUUID;
@@ -113,7 +115,7 @@ class LLFloaterPay : public LLFloater
 	BOOL mHaveName;
 
 	LLButton* mQuickPayButton[MAX_PAY_BUTTONS];
-	LLGiveMoneyInfo* mQuickPayInfo[MAX_PAY_BUTTONS];
+	give_money_ptr mQuickPayInfo[MAX_PAY_BUTTONS];
 
 	LLSafeHandle<LLObjectSelection> mObjectSelection;
 };
@@ -136,7 +138,11 @@ LLFloaterPay::LLFloaterPay(const LLSD& key)
 // Destroys the object
 LLFloaterPay::~LLFloaterPay()
 {
-	std::for_each(mCallbackData.begin(), mCallbackData.end(), DeletePointer());
+    std::vector<give_money_ptr>::iterator iter;
+    for (iter = mCallbackData.begin(); iter != mCallbackData.end(); ++iter)
+    {
+        (*iter)->mFloater = NULL;
+    }
 	mCallbackData.clear();
 	// Name callbacks will be automatically disconnected since LLFloater is trackable
 	
@@ -148,40 +154,40 @@ BOOL LLFloaterPay::postBuild()
 {
 	S32 i = 0;
 	
-	LLGiveMoneyInfo* info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_0);
+	give_money_ptr info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_0));
 	mCallbackData.push_back(info);
 
-	childSetAction("fastpay 1",&LLFloaterPay::onGive,info);
+	childSetAction("fastpay 1", boost::bind(LLFloaterPay::onGive, info));
 	getChildView("fastpay 1")->setVisible(FALSE);
 
 	mQuickPayButton[i] = getChild<LLButton>("fastpay 1");
 	mQuickPayInfo[i] = info;
 	++i;
 
-	info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_1);
+	info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_1));
 	mCallbackData.push_back(info);
 
-	childSetAction("fastpay 5",&LLFloaterPay::onGive,info);
+	childSetAction("fastpay 5", boost::bind(LLFloaterPay::onGive, info));
 	getChildView("fastpay 5")->setVisible(FALSE);
 
 	mQuickPayButton[i] = getChild<LLButton>("fastpay 5");
 	mQuickPayInfo[i] = info;
 	++i;
 
-	info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_2);
+	info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_2));
 	mCallbackData.push_back(info);
 
-	childSetAction("fastpay 10",&LLFloaterPay::onGive,info);
+	childSetAction("fastpay 10", boost::bind(LLFloaterPay::onGive, info));
 	getChildView("fastpay 10")->setVisible(FALSE);
 
 	mQuickPayButton[i] = getChild<LLButton>("fastpay 10");
 	mQuickPayInfo[i] = info;
 	++i;
 
-	info = new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_3);
+	info = give_money_ptr(new LLGiveMoneyInfo(this, PAY_BUTTON_DEFAULT_3));
 	mCallbackData.push_back(info);
 
-	childSetAction("fastpay 20",&LLFloaterPay::onGive,info);
+	childSetAction("fastpay 20", boost::bind(LLFloaterPay::onGive, info));
 	getChildView("fastpay 20")->setVisible(FALSE);
 
 	mQuickPayButton[i] = getChild<LLButton>("fastpay 20");
@@ -195,10 +201,10 @@ BOOL LLFloaterPay::postBuild()
 	getChild<LLLineEditor>("amount")->setKeystrokeCallback(&LLFloaterPay::onKeystroke, this);
 	getChild<LLLineEditor>("amount")->setPrevalidate(LLTextValidate::validateNonNegativeS32);
 
-	info = new LLGiveMoneyInfo(this, 0);
+	info = give_money_ptr(new LLGiveMoneyInfo(this, 0));
 	mCallbackData.push_back(info);
 
-	childSetAction("pay btn",&LLFloaterPay::onGive,info);
+	childSetAction("pay btn", boost::bind(LLFloaterPay::onGive, info));
 	setDefaultBtn("pay btn");
 	getChildView("pay btn")->setVisible(FALSE);
 	getChildView("pay btn")->setEnabled(FALSE);
@@ -415,9 +421,9 @@ void LLFloaterPay::payDirectly(money_callback callback,
 	floater->finishPayUI(target_id, is_group);
 }
 
-bool LLFloaterPay::payConfirmationCallback(const LLSD& notification, const LLSD& response, LLGiveMoneyInfo* info)
+bool LLFloaterPay::payConfirmationCallback(const LLSD& notification, const LLSD& response, give_money_ptr info)
 {
-	if (!info || !info->mFloater)
+	if (!info.get() || !info->mFloater)
 	{
 		return false;
 	}
@@ -479,54 +485,61 @@ void LLFloaterPay::onKeystroke(LLLineEditor*, void* data)
 }
 
 // static
-void LLFloaterPay::onGive(void* data)
+void LLFloaterPay::onGive(give_money_ptr info)
 {
-	LLGiveMoneyInfo* info = reinterpret_cast<LLGiveMoneyInfo*>(data);
-	LLFloaterPay* floater = info->mFloater;
-	if(info && floater)
-	{
-		S32 amount = info->mAmount;
-		if(amount == 0)
-		{
-			amount = atoi(floater->getChild<LLUICtrl>("amount")->getValue().asString().c_str());
-		}
-		if (amount > PAY_AMOUNT_NOTIFICATION && gStatusBar && gStatusBar->getBalance() > amount)
-		{
-			LLUUID payee_id = LLUUID::null;
-			BOOL is_group = false;
-			if (floater->mObjectSelection.notNull())
-			{
-				LLSelectNode* node = floater->mObjectSelection->getFirstRootNode();
-				if (node)
-				{
-					node->mPermissions->getOwnership(payee_id, is_group);
-				}
-				else
-				{
-					// object no longer exists
-					LLNotificationsUtil::add("PayObjectFailed");
-					floater->closeFloater();
-					return;
-				}
-			}
-			else
-			{
-				is_group = floater->mTargetIsGroup;
-				payee_id = floater->mTargetUUID;
-			}
-
-			LLSD args;
-			args["TARGET"] = LLSLURL( is_group ? "group" : "agent", payee_id, "completename").getSLURLString();
-			args["AMOUNT"] = amount;
-
-			LLNotificationsUtil::add("PayConfirmation", args, LLSD(), boost::bind(&LLFloaterPay::payConfirmationCallback, _1, _2, info));
-		}
-		else
-		{
-			floater->give(amount);
-			floater->closeFloater();
-		}
-	}
+    if (!info.get() || !info->mFloater)
+    {
+        return;
+    }
+
+    LLFloaterPay* floater = info->mFloater;
+    S32 amount = info->mAmount;
+    if (amount == 0)
+    {
+        LLUICtrl* text_field = floater->getChild<LLUICtrl>("amount");
+        if (!text_field)
+        {
+            return;
+        }
+        amount = atoi(text_field->getValue().asString().c_str());
+    }
+
+    if (amount > PAY_AMOUNT_NOTIFICATION && gStatusBar && gStatusBar->getBalance() > amount)
+    {
+        LLUUID payee_id = LLUUID::null;
+        BOOL is_group = false;
+        if (floater->mObjectSelection.notNull())
+        {
+            LLSelectNode* node = floater->mObjectSelection->getFirstRootNode();
+            if (node)
+            {
+                node->mPermissions->getOwnership(payee_id, is_group);
+            }
+            else
+            {
+                // object no longer exists
+                LLNotificationsUtil::add("PayObjectFailed");
+                floater->closeFloater();
+                return;
+            }
+        }
+        else
+        {
+            is_group = floater->mTargetIsGroup;
+            payee_id = floater->mTargetUUID;
+        }
+
+        LLSD args;
+        args["TARGET"] = LLSLURL(is_group ? "group" : "agent", payee_id, "completename").getSLURLString();
+        args["AMOUNT"] = amount;
+
+        LLNotificationsUtil::add("PayConfirmation", args, LLSD(), boost::bind(&LLFloaterPay::payConfirmationCallback, _1, _2, info));
+    }
+    else
+    {
+        floater->give(amount);
+        floater->closeFloater();
+    }
 }
 
 void LLFloaterPay::give(S32 amount)
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 853224b5044ab2887779cdb1ba553644eab50f6e..100ee5ab72dd49cb3a64a5fb01dcd12276794586 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1232,6 +1232,9 @@ void LLFloaterPreference::refreshEnabledState()
 						(ctrl_wind_light->get()) ? TRUE : FALSE;
 
 	ctrl_deferred->setEnabled(enabled);
+
+	// Cannot have floater active until caps have been received
+	getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true);
 }
 
 void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
@@ -1369,9 +1372,6 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState()
 	disableUnavailableSettings();
 
 	getChildView("block_list")->setEnabled(LLLoginInstance::getInstance()->authSuccess());
-
-	// Cannot have floater active until caps have been received
-	getChild<LLButton>("default_creation_permissions")->setEnabled(LLStartUp::getStartupState() < STATE_STARTED ? false : true);
 }
 
 // static
@@ -1411,7 +1411,7 @@ void LLAvatarComplexityControls::setIndirectMaxArc()
 	else
 	{
 		// This is the inverse of the calculation in updateMaxComplexity
-		indirect_max_arc = (U32)((log(max_arc) - MIN_ARC_LOG) / ARC_LIMIT_MAP_SCALE) + MIN_INDIRECT_ARC_LIMIT;
+		indirect_max_arc = (U32)ll_round(((log(F32(max_arc)) - MIN_ARC_LOG) / ARC_LIMIT_MAP_SCALE)) + MIN_INDIRECT_ARC_LIMIT;
 	}
 	gSavedSettings.setU32("IndirectMaxComplexity", indirect_max_arc);
 }
@@ -1930,7 +1930,7 @@ void LLAvatarComplexityControls::updateMax(LLSliderCtrl* slider, LLTextBox* valu
 	{
 		// if this is changed, the inverse calculation in setIndirectMaxArc
 		// must be changed to match
-		max_arc = (U32)exp(MIN_ARC_LOG + (ARC_LIMIT_MAP_SCALE * (indirect_value - MIN_INDIRECT_ARC_LIMIT)));
+		max_arc = (U32)ll_round(exp(MIN_ARC_LOG + (ARC_LIMIT_MAP_SCALE * (indirect_value - MIN_INDIRECT_ARC_LIMIT))));
 	}
 
 	gSavedSettings.setU32("RenderAvatarMaxComplexity", (U32)max_arc);
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index ed6f4ede9f4a6e86ab9abd4090b056f0e36858ac..a6ce0ba67803469a2b1091aa79d3dc21487c026a 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -192,7 +192,6 @@ BOOL LLFloaterReporter::postBuild()
 	mOwnerName = LLStringUtil::null;
 
 	getChild<LLUICtrl>("summary_edit")->setFocus(TRUE);
-	getChild<LLCheckBoxCtrl>("screen_check")->set(TRUE);
 
 	mDefaultSummary = getChild<LLUICtrl>("details_edit")->getValue().asString();
 
@@ -246,8 +245,6 @@ LLFloaterReporter::~LLFloaterReporter()
 // virtual
 void LLFloaterReporter::draw()
 {
-	getChildView("screen_check")->setEnabled(TRUE );
-
 	LLFloater::draw();
 }
 
@@ -255,7 +252,6 @@ void LLFloaterReporter::enableControls(BOOL enable)
 {
 	getChildView("category_combo")->setEnabled(enable);
 	getChildView("chat_check")->setEnabled(enable);
-	getChildView("screen_check")->setEnabled(enable);
 	getChildView("screenshot")->setEnabled(FALSE);
 	getChildView("pick_btn")->setEnabled(enable);
 	getChildView("summary_edit")->setEnabled(enable);
@@ -448,23 +444,15 @@ void LLFloaterReporter::onClickSend(void *userdata)
 		if(!url.empty() || !sshot_url.empty())
 		{
 			self->sendReportViaCaps(url, sshot_url, self->gatherReport());
+			LLNotificationsUtil::add("HelpReportAbuseConfirm");
 			self->closeFloater();
 		}
 		else
 		{
-			if(self->getChild<LLUICtrl>("screen_check")->getValue())
-			{
-				self->getChildView("send_btn")->setEnabled(FALSE);
-				self->getChildView("cancel_btn")->setEnabled(FALSE);
-				// the callback from uploading the image calls sendReportViaLegacy()
-				self->uploadImage();
-			}
-			else
-			{
-				self->sendReportViaLegacy(self->gatherReport());
-				LLUploadDialog::modalUploadFinished();
-				self->closeFloater();
-			}
+			self->getChildView("send_btn")->setEnabled(FALSE);
+			self->getChildView("cancel_btn")->setEnabled(FALSE);
+			// the callback from uploading the image calls sendReportViaLegacy()
+			self->uploadImage();
 		}
 	}
 }
@@ -713,10 +701,7 @@ LLSD LLFloaterReporter::gatherReport()
 	// only send a screenshot ID if we're asked to and the email is 
 	// going to LL - Estate Owners cannot see the screenshot asset
 	LLUUID screenshot_id = LLUUID::null;
-	if (getChild<LLUICtrl>("screen_check")->getValue())
-	{
-		screenshot_id = getChild<LLUICtrl>("screenshot")->getValue();
-	};
+	screenshot_id = getChild<LLUICtrl>("screenshot")->getValue();
 
 	LLSD report = LLSD::emptyMap();
 	report["report-type"] = (U8) mReportType;
@@ -770,7 +755,7 @@ void LLFloaterReporter::finishedARPost(const LLSD &)
 
 void LLFloaterReporter::sendReportViaCaps(std::string url, std::string sshot_url, const LLSD& report)
 {
-	if(getChild<LLUICtrl>("screen_check")->getValue().asBoolean() && !sshot_url.empty())
+	if(!sshot_url.empty())
     {
 		// try to upload screenshot
         LLResourceUploadInfo::ptr_t uploadInfo(new  LLARScreenShotUploader(report, mResourceDatap->mAssetInfo.mUuid, mResourceDatap->mAssetInfo.mType));
@@ -885,6 +870,7 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,
 		self->mScreenID = uuid;
 		LL_INFOS() << "Got screen shot " << uuid << LL_ENDL;
 		self->sendReportViaLegacy(self->gatherReport());
+		LLNotificationsUtil::add("HelpReportAbuseConfirm");
 		self->closeFloater();
 	}
 }
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index 7b8fc5b35bf53be4a970fbceb8ab51e06eed4704..eae16b9f03de98a99a5e0c6c753bfd03e7e37f09 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -660,6 +660,8 @@ BOOL LLPanelScriptLimitsRegionMemory::postBuild()
 	{
 		return FALSE;
 	}
+	list->setCommitCallback(boost::bind(&LLPanelScriptLimitsRegionMemory::checkButtonsEnabled, this));
+	checkButtonsEnabled();
 
 	//set all columns to resizable mode even if some columns will be empty
 	for(S32 column = 0; column < list->getNumColumns(); column++)
@@ -750,6 +752,14 @@ void LLPanelScriptLimitsRegionMemory::clearList()
 	getChild<LLUICtrl>("parcels_listed")->setValue(LLSD(msg_empty_string));
 
 	mObjectListItems.clear();
+	checkButtonsEnabled();
+}
+
+void LLPanelScriptLimitsRegionMemory::checkButtonsEnabled()
+{
+	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("scripts_list");
+	getChild<LLButton>("highlight_btn")->setEnabled(list->getNumSelected() > 0);
+	getChild<LLButton>("return_btn")->setEnabled(list->getNumSelected() > 0);
 }
 
 // static
diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h
index e3cbbd185fc64b73d8b4f61ce7e7d4ee6f776c9e..2ac3862b4f3507f66c89bcc0bfa02234a71549f3 100644
--- a/indra/newview/llfloaterscriptlimits.h
+++ b/indra/newview/llfloaterscriptlimits.h
@@ -113,6 +113,7 @@ class LLPanelScriptLimitsRegionMemory : public LLPanelScriptLimitsInfo, LLRemote
 	void showBeacon();
 	void returnObjectsFromParcel(S32 local_id);
 	void returnObjects();
+	void checkButtonsEnabled();
 
 private:
 	void onNameCache(const LLUUID& id,
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index 0cb37dabe7ccb8cd0005198156afc795b1cab3fe..b139e5daf5c290ed48ea2f81c5a374305a3390d4 100644
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -257,7 +257,6 @@ void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)
 	static std::string badgeOK("badge_ok.j2c");
 	static std::string badgeNote("badge_note.j2c");
 	static std::string badgeWarn("badge_warn.j2c");
-	static std::string badgeError("badge_error.j2c");
 	
 	std::string badgeName;
 	switch (badge)
@@ -266,7 +265,7 @@ void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)
 		case BADGE_OK:		badgeName = badgeOK;	break;
 		case BADGE_NOTE:	badgeName = badgeNote;	break;
 		case BADGE_WARN:	badgeName = badgeWarn;	break;
-		case BADGE_ERROR:	badgeName = badgeError;	break;
+		case BADGE_ERROR:	badgeName = badgeWarn;	break;
 	}
 	
 	getChild<LLUICtrl>(id)->setValue(badgeName);
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index ff7594a531b921580c7c77d2f2fc6a80e94e7b0e..b5ba64716da29114566db23a3fdddb315bb492a0 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -1375,7 +1375,7 @@ const LLVector3d& LLFloaterSnapshotBase::getPosTakenGlobal()
 // static
 void LLFloaterSnapshot::setAgentEmail(const std::string& email)
 {
-	LLFloaterSnapshot* instance = getInstance();
+	LLFloaterSnapshot* instance = findInstance();
 	if (instance)
 	{
 		LLSideTrayPanelContainer* panel_container = instance->getChild<LLSideTrayPanelContainer>("panel_container");
diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp
index 271dd44c1f94ae013ece7998bbc8659f7bc5ad86..7c2a3cad43b79a30da54b2f8099e533706c5136e 100644
--- a/indra/newview/llgroupiconctrl.cpp
+++ b/indra/newview/llgroupiconctrl.cpp
@@ -74,9 +74,16 @@ LLGroupIconCtrl::~LLGroupIconCtrl()
 	LLGroupMgr::getInstance()->removeObserver(this);
 }
 
-void LLGroupIconCtrl::setIconId(const LLSD& value)
+void LLGroupIconCtrl::setIconId(const LLUUID& icon_id)
 {
-    LLIconCtrl::setValue(value);
+    if (icon_id.notNull())
+    {
+        LLIconCtrl::setValue(icon_id);
+    }
+    else
+    {
+        LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
+    }
 }
 
 void LLGroupIconCtrl::setValue(const LLSD& value)
@@ -122,14 +129,7 @@ bool LLGroupIconCtrl::updateFromCache()
 	LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(mGroupId);
 	if (!group_data) return false;
 
-	if (group_data->mInsigniaID.notNull())
-	{
-		LLIconCtrl::setValue(group_data->mInsigniaID);
-	}
-	else
-	{
-		LLIconCtrl::setValue(mDefaultIconName, LLViewerFetchedTexture::BOOST_UI);
-	}
+	setIconId(group_data->mInsigniaID);
 
 	if (mDrawTooltip && !group_data->mName.empty())
 	{
diff --git a/indra/newview/llgroupiconctrl.h b/indra/newview/llgroupiconctrl.h
index f8b22cf581e60f7dcb6d57f5fa7d3c74415a2706..43e384d3e277746ef77889f5a23ea01d8d1484da 100644
--- a/indra/newview/llgroupiconctrl.h
+++ b/indra/newview/llgroupiconctrl.h
@@ -66,7 +66,13 @@ class LLGroupIconCtrl
 	 */
 	virtual void setValue(const LLSD& value);
 
-	void setIconId(const LLSD& value);
+	/**
+	 * Sets icon_id as icon value directly. Avoids LLGroupMgr cache checks for group id
+	 * Uses default icon in case id is null.
+	 *
+	 * @params icon_id - it is processed as icon id, default image will be used in case id is null.
+	 */
+	void setIconId(const LLUUID& icon_id);
 
 	// LLGroupMgrObserver observer trigger
 	virtual void changed(LLGroupChange gc);
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 6126db2988c98e9e3b7e47310d3e40ffbc7f925d..62414d3bbb745e3e2b607e59321f09abbd0f161c 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -379,10 +379,7 @@ void LLGroupListItem::setGroupID(const LLUUID& group_id)
 
 void LLGroupListItem::setGroupIconID(const LLUUID& group_icon_id)
 {
-	if (group_icon_id.notNull())
-	{
-		mGroupIcon->setIconId(group_icon_id);
-	}
+	mGroupIcon->setIconId(group_icon_id);
 }
 
 void LLGroupListItem::setGroupIconVisible(bool visible)
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 52e83fe412c78971a2f729c7e3f200f353ad765b..6b1e196182dc9b74929253c6685fa0956c9dcaac 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -53,7 +53,7 @@ const F32 VERTICAL_PADDING = 12.f;
 const F32 BUFFER_SIZE = 2.f;
 const F32 HUD_TEXT_MAX_WIDTH = 190.f;
 const F32 HUD_TEXT_MAX_WIDTH_NO_BUBBLE = 1000.f;
-const F32 MAX_DRAW_DISTANCE = 64.f;
+const F32 MAX_DRAW_DISTANCE = 300.f;
 
 std::set<LLPointer<LLHUDText> > LLHUDText::sTextObjects;
 std::vector<LLPointer<LLHUDText> > LLHUDText::sVisibleTextObjects;
@@ -394,7 +394,20 @@ void LLHUDText::updateVisibility()
 
 	LLVector3 pos_agent_center = gAgent.getPosAgentFromGlobal(mPositionGlobal) - dir_from_camera;
 	F32 last_distance_center = (pos_agent_center - LLViewerCamera::getInstance()->getOrigin()).magVec();
-	if(last_distance_center > MAX_DRAW_DISTANCE)
+	F32 max_draw_distance = gSavedSettings.getF32("PrimTextMaxDrawDistance");
+
+	if(max_draw_distance < 0)
+	{
+		max_draw_distance = 0;
+		gSavedSettings.setF32("PrimTextMaxDrawDistance", max_draw_distance);
+	}
+	else if(max_draw_distance > MAX_DRAW_DISTANCE)
+	{
+		max_draw_distance = MAX_DRAW_DISTANCE;
+		gSavedSettings.setF32("PrimTextMaxDrawDistance", MAX_DRAW_DISTANCE);
+	}
+
+	if(last_distance_center > max_draw_distance)
 	{
 		mVisible = FALSE;
 		return;
diff --git a/indra/newview/llinspectgroup.cpp b/indra/newview/llinspectgroup.cpp
index 8e91af321e294953659a2d74b7b22647f7ef2cf8..a4fce36783f4d6202fea59e52791c994f0c3362a 100644
--- a/indra/newview/llinspectgroup.cpp
+++ b/indra/newview/llinspectgroup.cpp
@@ -41,6 +41,7 @@
 #include "lltooltip.h"	// positionViewNearMouse()
 #include "lltrans.h"
 #include "lluictrl.h"
+#include "llgroupiconctrl.h"
 
 //////////////////////////////////////////////////////////////////////////////
 // LLInspectGroup
@@ -233,7 +234,7 @@ void LLInspectGroup::processGroupData()
 
 		getChild<LLUICtrl>("group_details")->setValue( LLSD(data->mCharter) );
 
-		getChild<LLUICtrl>("group_icon")->setValue( LLSD(data->mInsigniaID) );
+		getChild<LLGroupIconCtrl>("group_icon")->setIconId(data->mInsigniaID);
 
 		std::string cost;
 		bool is_member = LLGroupActions::isInGroup(mGroupID);
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 9f0b35fc8cc1296e3cafbb8939874094c64c7936..eebb6a0384323965c923ab497f6199f6bf8c8285 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -286,6 +286,16 @@ BOOL LLInvFVBridge::cutToClipboard()
 	return FALSE;
 }
 
+// virtual
+bool LLInvFVBridge::isCutToClipboard()
+{
+    if (LLClipboard::instance().isCutMode())
+    {
+        return LLClipboard::instance().isOnClipboard(mUUID);
+    }
+    return false;
+}
+
 // Callback for cutToClipboard if DAMA required...
 BOOL LLInvFVBridge::callback_cutToClipboard(const LLSD& notification, const LLSD& response)
 {
@@ -307,9 +317,7 @@ BOOL LLInvFVBridge::perform_cutToClipboard()
 	if (obj && isItemMovable() && isItemRemovable())
 	{
 		LLClipboard::instance().setCutMode(true);
-		BOOL added_to_clipboard = LLClipboard::instance().addToClipboard(mUUID);
-        removeObject(&gInventory, mUUID);   // Always perform the remove even if the object couldn't make it to the clipboard
-        return added_to_clipboard;
+		return LLClipboard::instance().addToClipboard(mUUID);
 	}
 	return FALSE;
 }
@@ -1390,6 +1398,12 @@ bool LLInvFVBridge::canShare() const
 				// Categories can be given.
 				can_share = (model->getCategory(mUUID) != NULL);
 			}
+
+			const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+			if ((mUUID == trash_id) || gInventory.isObjectDescendentOf(mUUID, trash_id))
+			{
+				can_share = false;
+			}
 		}
 	}
 
@@ -1925,13 +1939,15 @@ BOOL LLItemBridge::removeItem()
 	}
 
 	// move it to the trash
-	LLPreview::hide(mUUID, TRUE);
 	LLInventoryModel* model = getInventoryModel();
 	if(!model) return FALSE;
 	const LLUUID& trash_id = model->findCategoryUUIDForType(LLFolderType::FT_TRASH);
 	LLViewerInventoryItem* item = getItem();
 	if (!item) return FALSE;
-
+	if (item->getType() != LLAssetType::AT_LSL_TEXT)
+	{
+		LLPreview::hide(mUUID, TRUE);
+	}
 	// Already in trash
 	if (model->isObjectDescendentOf(mUUID, trash_id)) return FALSE;
 
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 9053c61171f877141da63ed7398e3c1581829324..df25e01688a2be73c4d948435c096904d8c8ba21 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -116,6 +116,7 @@ class LLInvFVBridge : public LLFolderViewModelItemInventory
 	virtual BOOL isItemCopyable() const { return FALSE; }
 	virtual BOOL copyToClipboard() const;
 	virtual BOOL cutToClipboard();
+	virtual bool isCutToClipboard();
 	virtual BOOL isClipboardPasteable() const;
 	virtual BOOL isClipboardPasteableAsLink() const;
 	virtual void pasteFromClipboard() {}
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 003bbcafeda23d8835e50eb263428251d2f8a7d5..e995c138b4e77305198ab1455f1e523bb8de3232 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -84,21 +84,18 @@ LLInventoryFilter::LLInventoryFilter(const Params& p)
 bool LLInventoryFilter::check(const LLFolderViewModelItem* item) 
 {
 	const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item);
-	// Clipboard cut items are *always* filtered so we need this value upfront
-	const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);
 
 	// If it's a folder and we're showing all folders, return automatically.
 	const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;
 	if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
 	{
-		return passed_clipboard;
+		return true;
 	}
 
 	bool passed = (mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) != std::string::npos : true);
 	passed = passed && checkAgainstFilterType(listener);
 	passed = passed && checkAgainstPermissions(listener);
 	passed = passed && checkAgainstFilterLinks(listener);
-	passed = passed && passed_clipboard;
 
 	return passed;
 }
@@ -108,9 +105,8 @@ bool LLInventoryFilter::check(const LLInventoryItem* item)
 	const bool passed_string = (mFilterSubString.size() ? item->getName().find(mFilterSubString) != std::string::npos : true);
 	const bool passed_filtertype = checkAgainstFilterType(item);
 	const bool passed_permissions = checkAgainstPermissions(item);
-	const bool passed_clipboard = checkAgainstClipboard(item->getUUID());
 
-	return passed_filtertype && passed_permissions && passed_clipboard && passed_string;
+	return passed_filtertype && passed_permissions && passed_string;
 }
 
 bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
@@ -129,13 +125,10 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
 
 bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 {
-	// Always check against the clipboard
-	const BOOL passed_clipboard = checkAgainstClipboard(folder_id);
-	
 	// we're showing all folders, overriding filter
 	if (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS)
 	{
-		return passed_clipboard;
+		return true;
 	}
 
 	// when applying a filter, matching folders get their contents downloaded first
@@ -201,7 +194,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 	LLViewerInventoryItem* item = gInventory.getItem(folder_id);
 	if (item && item->getActualType() == LLAssetType::AT_LINK_FOLDER)
 	{
-		return passed_clipboard;
+		return true;
 	}
 
 	if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
@@ -216,7 +209,7 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 			return false;
 	}
 
-	return passed_clipboard;
+	return true;
 }
 
 bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInventory* listener) const
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
index 9a33e210ff3352128e92a2a7af79aee05f82244b..503fa28a335f3a950077f12361026324d1f8f29a 100644
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -582,7 +582,7 @@ LLUUID LLInventoryModel::createNewCategory(const LLUUID& parent_id,
 	// Add the category to the internal representation
 	LLPointer<LLViewerInventoryCategory> cat =
 		new LLViewerInventoryCategory(id, parent_id, preferred_type, name, gAgent.getID());
-	cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL);
+	cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
 	cat->setDescendentCount(0);
 	LLCategoryUpdate update(cat->getParentUUID(), 1);
 	accountForUpdate(update);
@@ -640,7 +640,7 @@ void LLInventoryModel::createNewCategoryCoro(std::string url, LLSD postData, inv
         result["parent_id"].asUUID(), (LLFolderType::EType)result["type"].asInteger(),
         result["name"].asString(), gAgent.getID());
 
-    cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL);
+    cat->setVersion(LLViewerInventoryCategory::VERSION_INITIAL - 1); // accountForUpdate() will icrease version by 1
     cat->setDescendentCount(0);
     LLInventoryModel::LLCategoryUpdate update(cat->getParentUUID(), 1);
     
@@ -914,8 +914,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
 			item_array_t* item_array = get_ptr_in_map(mParentChildItemTree, category_id);
 			if( item_array )
 			{
+				LLInventoryModel::LLCategoryUpdate update(category_id, 1);
+				gInventory.accountForUpdate(update);
+
 				// *FIX: bit of a hack to call update server from here...
-				new_item->updateServer(TRUE);
+				new_item->updateParentOnServer(FALSE);
 				item_array->push_back(new_item);
 			}
 			else
@@ -956,9 +959,11 @@ U32 LLInventoryModel::updateItem(const LLViewerInventoryItem* item, U32 mask)
 				item_array = get_ptr_in_map(mParentChildItemTree, parent_id);
 				if(item_array)
 				{
+					LLInventoryModel::LLCategoryUpdate update(parent_id, 1);
+					gInventory.accountForUpdate(update);
 					// *FIX: bit of a hack to call update server from
 					// here...
-					new_item->updateServer(TRUE);
+					new_item->updateParentOnServer(FALSE);
 					item_array->push_back(new_item);
 				}
 				else
@@ -1045,7 +1050,6 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32
 	if(old_cat)
 	{
 		// We already have an old category, modify its values
-		U32 mask = LLInventoryObserver::NONE;
 		LLUUID old_parent_id = old_cat->getParentUUID();
 		LLUUID new_parent_id = cat->getParentUUID();
 		if(old_parent_id != new_parent_id)
@@ -1100,7 +1104,8 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat, U32
 		item_array_t* itemsp = new item_array_t;
 		mParentChildCategoryTree[new_cat->getUUID()] = catsp;
 		mParentChildItemTree[new_cat->getUUID()] = itemsp;
-		addChangedMask(LLInventoryObserver::ADD, cat->getUUID());
+		mask |= LLInventoryObserver::ADD;
+		addChangedMask(mask, cat->getUUID());
 	}
 }
 
@@ -1390,7 +1395,11 @@ void LLInventoryModel::onObjectDeletedFromServer(const LLUUID& object_id, bool f
 		}
 
 		// From purgeObject()
-		LLPreview::hide(object_id);
+		LLViewerInventoryItem *item = getItem(object_id);
+		if (item && (item->getType() != LLAssetType::AT_LSL_TEXT))
+		{
+			LLPreview::hide(object_id, TRUE);
+		}
 		deleteObject(object_id, fix_broken_links, do_notify_observers);
 	}
 }
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index aa934f95a1ed3faedb434082deb11801de4a1fe5..a55938f334d12fe39ba911218dd72cb3fc582d26 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -181,7 +181,12 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
 		if (gDirUtilp->fileExists(mFilename))
 		{
 			// verifying that the file has indeed been modified
+
+#ifndef LL_WINDOWS
 			const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(mFilename));
+#else
+			const std::time_t temp_time = boost::filesystem::last_write_time(boost::filesystem::path(utf8str_to_utf16str(mFilename)));
+#endif
 			LLSD new_last_modified = asctime(localtime(&temp_time));
 
 			if (mLastModified.asString() != new_last_modified.asString())
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 53b2ca2b74a12b4ea241778edb37897409b8d3a5..11bc1425f902566721a15e32ec5231fd1fe2d8de 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -243,7 +243,7 @@ LLLocationInputCtrl::LLLocationInputCtrl(const LLLocationInputCtrl::Params& p)
 	params.commit_on_focus_lost(false);
 	params.follows.flags(FOLLOWS_ALL);
 	mTextEntry = LLUICtrlFactory::create<LLURLLineEditor>(params);
-	mTextEntry->setContextMenu(NULL);
+	mTextEntry->resetContextMenu();
 	addChild(mTextEntry);
 	// LLLineEditor is replaced with LLLocationLineEditor
 
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 639641d1c25bf07c71e75322bba7a6724034558a..485d4677b1ca7ee702490b1e9d255d213771e97a 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -244,7 +244,10 @@ std::string LLLogChat::makeLogFileName(std::string filename)
 
 	filename = cleanFileName(filename);
 	filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename);
-	filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+	if (!filename.empty())
+	{
+		filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+	}
 
 	return filename;
 }
diff --git a/indra/newview/llmanip.h b/indra/newview/llmanip.h
index 1fb05e047a93b6b41605c301c7228be973d1108d..69881e8589399ca3392576b6f18643468e818b82 100644
--- a/indra/newview/llmanip.h
+++ b/indra/newview/llmanip.h
@@ -1,4 +1,4 @@
-/** 
+/** 
  * @file llmanip.h
  * @brief LLManip class definition
  *
@@ -37,7 +37,7 @@ class LLToolComposite;
 class LLVector3;
 class LLObjectSelection;
 
-const S32 MIN_DIVISION_PIXEL_WIDTH = 9;
+const S32 MIN_DIVISION_PIXEL_WIDTH = 3;
 
 class LLManip : public LLTool
 {
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index b4259a456cc1e773ee58c2a49b99d99510a64da3..3975d3980b174652b5e640c930e3fd5e6758147b 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -1,4 +1,4 @@
-/** 
+/** 
  * @file llmaniptranslate.cpp
  * @brief LLManipTranslate class implementation
  *
@@ -548,12 +548,7 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 		if (off_axis_magnitude > mSnapOffsetMeters)
 		{
 			mInSnapRegime = TRUE;
-			LLVector3 mouse_down_offset(mDragCursorStartGlobal - mDragSelectionStartGlobal);
 			LLVector3 cursor_snap_agent = gAgent.getPosAgentFromGlobal(cursor_point_snap_line);
-			if (!gSavedSettings.getBOOL("SnapToMouseCursor"))
-			{
-				cursor_snap_agent -= mouse_down_offset;
-			}
 
 			F32 cursor_grid_dist = (cursor_snap_agent - mGridOrigin) * axis_f;
 			
diff --git a/indra/newview/llmarketplacefunctions.cpp b/indra/newview/llmarketplacefunctions.cpp
index 6cc7a0fc9967136e8f0e49fe0aa0b924b7d02862..54f95520db263353364d6c29deac6689c69255b7 100644
--- a/indra/newview/llmarketplacefunctions.cpp
+++ b/indra/newview/llmarketplacefunctions.cpp
@@ -773,7 +773,9 @@ void LLMarketplaceData::getMerchantStatusCoro()
     std::string url = getSLMConnectURL("/merchant");
     if (url.empty())
     {
-        LL_INFOS("Marketplace") << "No marketplace capability on Sim" << LL_ENDL;
+        LL_WARNS("Marketplace") << "No marketplace capability on Sim" << LL_ENDL;
+        setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_CONNECTION_FAILURE);
+        return;
     }
 
     LLSD result = httpAdapter->getAndSuspend(httpRequest, url, httpOpts);
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 9cf32499838f6e05c45edb3d7441323014cd4863..00043d1e721cdd190149dbd5dd39db5ce27d5ad5 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -1007,7 +1007,11 @@ void LLMediaCtrl::handleMediaEvent(LLPluginClassMedia* self, EMediaEvent event)
 			std::string uuid = self->getClickUUID();
 			LL_DEBUGS("Media") << "Media event:  MEDIA_EVENT_CLICK_LINK_HREF, target is \"" << target << "\", uri is " << url << LL_ENDL;
 
-			LLWeb::loadURL(url, target, std::string());
+			// try as slurl first
+			if (!LLURLDispatcher::dispatch(url, "clicked", NULL, mTrusted))
+			{
+				LLWeb::loadURL(url, target, std::string());
+			}
 
 			// CP: removing this code because we no longer support popups so this breaks the flow.
 			//     replaced with a bare call to LLWeb::LoadURL(...)
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 5f8f42a1d6b6b461b64845eb4204bdca7e35f689..9dacae2c4eff711ccd89fa7d9ebfeb7a00b28bee 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -1753,6 +1753,11 @@ bool LLMeshRepoThread::headerReceived(const LLVolumeParams& mesh_params, U8* dat
 
 bool LLMeshRepoThread::lodReceived(const LLVolumeParams& mesh_params, S32 lod, U8* data, S32 data_size)
 {
+	if (data == NULL || data_size == 0)
+	{
+		return false;
+	}
+
 	LLPointer<LLVolume> volume = new LLVolume(mesh_params, LLVolumeLODGroup::getVolumeScaleFromDetail(lod));
 	std::string mesh_string((char*) data, data_size);
 	std::istringstream stream(mesh_string);
@@ -3014,12 +3019,23 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
 	}
 	else if (data && data_size > 0)
 	{
-		// header was successfully retrieved from sim, cache in vfs
-		LLSD header = gMeshRepo.mThread->mMeshHeader[mesh_id];
+		// header was successfully retrieved from sim and parsed, cache in vfs
+		S32 header_bytes = 0;
+		LLSD header;
 
-		S32 version = header["version"].asInteger();
+		gMeshRepo.mThread->mHeaderMutex->lock();
+		LLMeshRepoThread::mesh_header_map::iterator iter = gMeshRepo.mThread->mMeshHeader.find(mesh_id);
+		if (iter != gMeshRepo.mThread->mMeshHeader.end())
+		{
+			header_bytes = (S32)gMeshRepo.mThread->mMeshHeaderSize[mesh_id];
+			header = iter->second;
+		}
+		gMeshRepo.mThread->mHeaderMutex->unlock();
 
-		if (version <= MAX_MESH_VERSION)
+		if (header_bytes > 0
+			&& !header.has("404")
+			&& header.has("version")
+			&& header["version"].asInteger() <= MAX_MESH_VERSION)
 		{
 			std::stringstream str;
 
@@ -3068,6 +3084,17 @@ void LLMeshHeaderHandler::processData(LLCore::BufferArray * /* body */, S32 /* b
 				}
 			}
 		}
+		else
+		{
+			LL_WARNS(LOG_MESH) << "Trying to cache nonexistent mesh, mesh id: " << mesh_id << LL_ENDL;
+
+			// headerReceived() parsed header, but header's data is invalid so none of the LODs will be available
+			LLMutexLock lock(gMeshRepo.mThread->mMutex);
+			for (int i(0); i < 4; ++i)
+			{
+				gMeshRepo.mThread->mUnavailableQ.push(LLMeshRepoThread::LODRequest(mMeshParams, i));
+			}
+		}
 	}
 }
 
@@ -4121,7 +4148,7 @@ F32 LLMeshRepository::getStreamingCost(LLSD& header, F32 radius, S32* bytes, S32
 		}
 	}
 
-	F32 max_area = 102932.f; //area of circle that encompasses region
+	F32 max_area = 102944.f; //area of circle that encompasses region (see MAINT-6559)
 	F32 min_area = 1.f;
 
 	F32 high_area = llmin(F_PI*dmid*dmid, max_area);
diff --git a/indra/newview/llmoveview.cpp b/indra/newview/llmoveview.cpp
index 70035bcc74eff63f30436bbd7473a1d4786142b4..c3dd08c327fb55a7489c1688f54f55f1a0e5ec3e 100644
--- a/indra/newview/llmoveview.cpp
+++ b/indra/newview/llmoveview.cpp
@@ -252,7 +252,7 @@ void LLFloaterMove::setSittingMode(BOOL bSitting)
 			LLPanelStandStopFlying::setStandStopFlyingMode(LLPanelStandStopFlying::SSFM_STOP_FLYING);
 		}
 	}
-	enableInstance(!bSitting);
+	enableInstance();
 }
 
 // protected 
@@ -459,7 +459,7 @@ void LLFloaterMove::showModeButtons(BOOL bShow)
 }
 
 //static
-void LLFloaterMove::enableInstance(BOOL bEnable)
+void LLFloaterMove::enableInstance()
 {
 	LLFloaterMove* instance = LLFloaterReg::findTypedInstance<LLFloaterMove>("moveview");
 	if (instance)
@@ -470,7 +470,7 @@ void LLFloaterMove::enableInstance(BOOL bEnable)
 		}
 		else
 		{
-			instance->showModeButtons(bEnable);
+            instance->showModeButtons(isAgentAvatarValid() && !gAgentAvatarp->isSitting());
 		}
 	}
 }
@@ -566,7 +566,7 @@ BOOL LLPanelStandStopFlying::postBuild()
 {
 	mStandButton = getChild<LLButton>("stand_btn");
 	mStandButton->setCommitCallback(boost::bind(&LLPanelStandStopFlying::onStandButtonClick, this));
-	mStandButton->setCommitCallback(boost::bind(&LLFloaterMove::enableInstance, TRUE));
+	mStandButton->setCommitCallback(boost::bind(&LLFloaterMove::enableInstance));
 	mStandButton->setVisible(FALSE);
 	LLHints::registerHintTarget("stand_btn", mStandButton->getHandle());
 	
@@ -685,8 +685,7 @@ void LLPanelStandStopFlying::onStandButtonClick()
 	LLSelectMgr::getInstance()->deselectAllForStandingUp();
 	gAgent.setControlFlags(AGENT_CONTROL_STAND_UP);
 
-	setFocus(FALSE); // EXT-482
-	mStandButton->setVisible(FALSE); // force visibility changing to avoid seeing Stand & Move buttons at once.
+	setFocus(FALSE); 
 }
 
 void LLPanelStandStopFlying::onStopFlyingButtonClick()
@@ -694,7 +693,6 @@ void LLPanelStandStopFlying::onStopFlyingButtonClick()
 	gAgent.setFlying(FALSE);
 
 	setFocus(FALSE); // EXT-482
-	mStopFlyingButton->setVisible(FALSE);
 }
 
 /**
diff --git a/indra/newview/llmoveview.h b/indra/newview/llmoveview.h
index c525d9dfdb6580d1c5bb1ea62c89fe01a3840cb1..4a31f2a8148d018affc43f6918e7e52933781086 100644
--- a/indra/newview/llmoveview.h
+++ b/indra/newview/llmoveview.h
@@ -56,7 +56,7 @@ class LLFloaterMove
 	static void setAlwaysRunMode(bool run);
 	void setAlwaysRunModeImpl(bool run);
 	static void setSittingMode(BOOL bSitting);
-	static void enableInstance(BOOL bEnable);
+	static void enableInstance();
 	/*virtual*/ void onOpen(const LLSD& key);
 
 	static void sUpdateFlyingStatus();
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 2657b84ef30379962260d45674ee1bd7d33604d2..63ab88da425fb60f729cd3886ba32cce945cce0f 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -96,17 +96,21 @@ bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 
 			LLUUID from_id = notification->getPayload()["from_id"];
 
-			//Will not play a notification sound for inventory and teleport offer based upon chat preference
-			bool playSound = (!notification->isDND()
-							  && ((notification->getName() == "UserGiveItem"
-			                  && gSavedSettings.getBOOL("PlaySoundInventoryOffer"))
-			                  || (notification->getName() == "TeleportOffered"
-			                  && gSavedSettings.getBOOL("PlaySoundTeleportOffer"))));
-
-			            if(playSound)
-			            {
-			                notification->playSound();
-			            }
+			if (!notification->isDND())
+			{
+				//Will not play a notification sound for inventory and teleport offer based upon chat preference
+				bool playSound = (notification->getName() == "UserGiveItem"
+								  && gSavedSettings.getBOOL("PlaySoundInventoryOffer"))
+								 || ((notification->getName() == "TeleportOffered"
+								     || notification->getName() == "TeleportOffered_MaturityExceeded"
+								     || notification->getName() == "TeleportOffered_MaturityBlocked")
+								    && gSavedSettings.getBOOL("PlaySoundTeleportOffer"));
+
+				if (playSound)
+				{
+					notification->playSound();
+				}
+			}
 
 			LLHandlerUtil::spawnIMSession(name, from_id);
 			LLHandlerUtil::addNotifPanelToIM(notification);
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index 65fd3f95ab83ae1d9cc6d63c4c29b676f7e6798a..de6a36ce2f76a87433e58236c1aa5e42167c5988 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -999,7 +999,7 @@ void LLOutfitGallery::refreshOutfit(const LLUUID& category_id)
         }
     }
     
-    if (mGalleryCreated)
+    if (mGalleryCreated && !LLApp::isQuitting())
     {
         reArrangeRows();
     }
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index b2164c1f21f2683cc87e3b583fe2c4ad8a5af49b..d17f5494a05e1fddc4a7617e6fe468bd0c89680c 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -199,7 +199,7 @@ void LLPanelGroupGeneral::setupCtrls(LLPanel* panel_group)
 
 
 	mGroupNameEditor = panel_group->getChild<LLLineEditor>("group_name_editor");
-	mGroupNameEditor->setPrevalidate( LLTextValidate::validateASCII );
+	mGroupNameEditor->setPrevalidate( LLTextValidate::validateASCIINoLeadingSpace );
 	
 
 }
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 8331c152e206a34fc2f3f3c9b006e1e53963f91b..8b9941c0ca48cfaeea722a9496aded6759864de8 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -1059,9 +1059,6 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)
 		case LLAssetType::AT_BODYPART:
 			applyListViewFilter(LVIT_BODYPART);
 			break;
-		case LLAssetType::AT_GESTURE:
-			applyListViewFilter(LVIT_GESTURES);
-			break;
 		case LLAssetType::AT_CLOTHING:
 		default:
 			applyListViewFilter(LVIT_CLOTHING);
diff --git a/indra/newview/llpaneloutfitedit.h b/indra/newview/llpaneloutfitedit.h
index 841bb4337a8f78b91b10ae9614425c237505835d..30870daf406297f220ab4e335fd9acf8e5feb9ac 100644
--- a/indra/newview/llpaneloutfitedit.h
+++ b/indra/newview/llpaneloutfitedit.h
@@ -80,7 +80,6 @@ class LLPanelOutfitEdit : public LLPanel
 	{
 		LVIT_ALL = 0,
 		LVIT_CLOTHING,
-		LVIT_GESTURES,
 		LVIT_BODYPART,
 		LVIT_ATTACHMENT,
 		LVIT_SHAPE,
diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp
index 184238c40ca1373b0e5b412ee0e4ba2fde30bef0..8afa35efa0b4066ab1e10b58d8af234cf792106f 100644
--- a/indra/newview/llpanelprofile.cpp
+++ b/indra/newview/llpanelprofile.cpp
@@ -44,19 +44,11 @@ static const std::string PANEL_PICKS = "panel_picks";
 
 std::string getProfileURL(const std::string& agent_name)
 {
-	std::string url;
-
-	if (LLGridManager::getInstance()->isInProductionGrid())
-	{
-		url = gSavedSettings.getString("WebProfileURL");
-	}
-	else
-	{
-		url = gSavedSettings.getString("WebProfileNonProductionURL");
-	}
+	std::string url = "[WEB_PROFILE_URL][AGENT_NAME]";
 	LLSD subs;
+	subs["WEB_PROFILE_URL"] = LLGridManager::getInstance()->getWebProfileURL();
 	subs["AGENT_NAME"] = agent_name;
-	url = LLWeb::expandURLSubstitutions(url,subs);
+	url = LLWeb::expandURLSubstitutions(url, subs);
 	LLStringUtil::toLower(url);
 	return url;
 }
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index d0353259a52f860da324a1383e7269cb3c115f9c..796372ba04cdf5ca0dd2832c35ab3fd9c6211d85 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -30,13 +30,19 @@
 
 #include "lltoggleablemenu.h"
 
+#include "llagent.h"
+#include "llaccordionctrl.h"
+#include "llaccordionctrltab.h"
 #include "llappearancemgr.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"
 #include "llinventoryobserver.h"
 #include "llmenubutton.h"
+#include "llscrolllistctrl.h"
 #include "llviewermenu.h"
+#include "llviewerregion.h"
 #include "llwearableitemslist.h"
 #include "llsdserialize.h"
 #include "llclipboard.h"
@@ -146,11 +152,47 @@ class LLWearingContextMenu : public LLListContextMenu
 		menu->setItemVisible("detach",		allow_detach);
 		menu->setItemVisible("edit_outfit_separator", allow_take_off || allow_detach);
 		menu->setItemVisible("show_original", mUUIDs.size() == 1);
+		menu->setItemVisible("edit_item", FALSE);
 	}
 };
 
 //////////////////////////////////////////////////////////////////////////
 
+class LLTempAttachmentsContextMenu : public LLListContextMenu
+{
+public:
+	LLTempAttachmentsContextMenu(LLPanelWearing* panel_wearing)
+		:	mPanelWearing(panel_wearing)
+	{}
+protected:
+	/* virtual */ LLContextMenu* createMenu()
+	{
+		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+
+		registrar.add("Wearing.EditItem", boost::bind(&LLPanelWearing::onEditAttachment, mPanelWearing));
+		registrar.add("Wearing.Detach", boost::bind(&LLPanelWearing::onRemoveAttachment, mPanelWearing));
+		LLContextMenu* menu = createFromFile("menu_wearing_tab.xml");
+
+		updateMenuItemsVisibility(menu);
+
+		return menu;
+	}
+
+	void updateMenuItemsVisibility(LLContextMenu* menu)
+	{
+		menu->setItemVisible("take_off", FALSE);
+		menu->setItemVisible("detach", TRUE);
+		menu->setItemVisible("edit_outfit_separator", TRUE);
+		menu->setItemVisible("show_original", FALSE);
+		menu->setItemVisible("edit_item", TRUE);
+		menu->setItemVisible("edit", FALSE);
+	}
+
+	LLPanelWearing* 		mPanelWearing;
+};
+
+//////////////////////////////////////////////////////////////////////////
+
 std::string LLPanelAppearanceTab::sFilterSubString = LLStringUtil::null;
 
 static LLPanelInjector<LLPanelWearing> t_panel_wearing("panel_wearing");
@@ -159,30 +201,47 @@ LLPanelWearing::LLPanelWearing()
 	:	LLPanelAppearanceTab()
 	,	mCOFItemsList(NULL)
 	,	mIsInitialized(false)
+	,	mAttachmentsChangedConnection()
 {
 	mCategoriesObserver = new LLInventoryCategoriesObserver();
 
 	mGearMenu = new LLWearingGearMenu(this);
 	mContextMenu = new LLWearingContextMenu();
+	mAttachmentsMenu = new LLTempAttachmentsContextMenu(this);
 }
 
 LLPanelWearing::~LLPanelWearing()
 {
 	delete mGearMenu;
 	delete mContextMenu;
+	delete mAttachmentsMenu;
 
 	if (gInventory.containsObserver(mCategoriesObserver))
 	{
 		gInventory.removeObserver(mCategoriesObserver);
 	}
 	delete mCategoriesObserver;
+
+	if (mAttachmentsChangedConnection.connected())
+	{
+		mAttachmentsChangedConnection.disconnect();
+	}
 }
 
 BOOL LLPanelWearing::postBuild()
 {
+	mAccordionCtrl = getChild<LLAccordionCtrl>("wearables_accordion");
+	mWearablesTab = getChild<LLAccordionCtrlTab>("tab_wearables");
+	mAttachmentsTab = getChild<LLAccordionCtrlTab>("tab_temp_attachments");
+	mAttachmentsTab->setDropDownStateChangedCallback(boost::bind(&LLPanelWearing::onAccordionTabStateChanged, this));
+
 	mCOFItemsList = getChild<LLWearableItemsList>("cof_items_list");
 	mCOFItemsList->setRightMouseDownCallback(boost::bind(&LLPanelWearing::onWearableItemsListRightClick, this, _1, _2, _3));
 
+	mTempItemsList = getChild<LLScrollListCtrl>("temp_attachments_list");
+	mTempItemsList->setFgUnselectedColor(LLColor4::white);
+	mTempItemsList->setRightMouseDownCallback(boost::bind(&LLPanelWearing::onTempAttachmentsListRightClick, this, _1, _2, _3));
+
 	LLMenuButton* menu_gear_btn = getChild<LLMenuButton>("options_gear_btn");
 
 	menu_gear_btn->setMenu(mGearMenu->getMenu());
@@ -223,6 +282,44 @@ void LLPanelWearing::onOpen(const LLSD& /*info*/)
 	}
 }
 
+void LLPanelWearing::draw()
+{
+	if (mUpdateTimer.getStarted() && (mUpdateTimer.getElapsedTimeF32() > 0.1))
+	{
+		mUpdateTimer.stop();
+		updateAttachmentsList();
+	}
+	LLPanel::draw();
+}
+
+void LLPanelWearing::onAccordionTabStateChanged()
+{
+	if(mAttachmentsTab->isExpanded())
+	{
+		startUpdateTimer();
+		mAttachmentsChangedConnection = LLAppearanceMgr::instance().setAttachmentsChangedCallback(boost::bind(&LLPanelWearing::startUpdateTimer, this));
+	}
+	else
+	{
+		if (mAttachmentsChangedConnection.connected())
+		{
+			mAttachmentsChangedConnection.disconnect();
+		}
+	}
+}
+
+void LLPanelWearing::startUpdateTimer()
+{
+	if (!mUpdateTimer.getStarted())
+	{
+		mUpdateTimer.start();
+	}
+	else
+	{
+		mUpdateTimer.reset();
+	}
+}
+
 // virtual
 void LLPanelWearing::setFilterSubString(const std::string& string)
 {
@@ -251,6 +348,124 @@ bool LLPanelWearing::isActionEnabled(const LLSD& userdata)
 	return false;
 }
 
+void LLPanelWearing::updateAttachmentsList()
+{
+	std::vector<LLViewerObject*> attachs = LLAgentWearables::getTempAttachments();
+	mTempItemsList->deleteAllItems();
+	mAttachmentsMap.clear();
+	if(!attachs.empty())
+	{
+		if(!populateAttachmentsList())
+		{
+			requestAttachmentDetails();
+		}
+	}
+	else
+	{
+		std::string no_attachments = getString("no_attachments");
+		LLSD row;
+		row["columns"][0]["column"] = "text";
+		row["columns"][0]["value"] = no_attachments;
+		row["columns"][0]["font"] = "SansSerifBold";
+		mTempItemsList->addElement(row);
+	}
+}
+
+bool LLPanelWearing::populateAttachmentsList(bool update)
+{
+	bool populated = true;
+	if(mTempItemsList)
+	{
+		mTempItemsList->deleteAllItems();
+		mAttachmentsMap.clear();
+		std::vector<LLViewerObject*> attachs = LLAgentWearables::getTempAttachments();
+
+		std::string icon_name = LLInventoryIcon::getIconName(LLAssetType::AT_OBJECT, LLInventoryType::IT_OBJECT);
+		for (std::vector<LLViewerObject*>::iterator iter = attachs.begin();
+				iter != attachs.end(); ++iter)
+		{
+			LLViewerObject *attachment = *iter;
+			LLSD row;
+			row["id"] = attachment->getID();
+			row["columns"][0]["column"] = "icon";
+			row["columns"][0]["type"] = "icon";
+			row["columns"][0]["value"] = icon_name;
+			row["columns"][1]["column"] = "text";
+			if(mObjectNames.count(attachment->getID()) && !mObjectNames[attachment->getID()].empty())
+			{
+				row["columns"][1]["value"] = mObjectNames[attachment->getID()];
+			}
+			else if(update)
+			{
+				row["columns"][1]["value"] = attachment->getID();
+				populated = false;
+			}
+			else
+			{
+				row["columns"][1]["value"] = "Loading...";
+				populated = false;
+			}
+			mTempItemsList->addElement(row);
+			mAttachmentsMap[attachment->getID()] = attachment;
+		}
+	}
+	return populated;
+}
+
+void LLPanelWearing::requestAttachmentDetails()
+{
+	LLSD body;
+	std::string url = gAgent.getRegion()->getCapability("AttachmentResources");
+	if (!url.empty())
+	{
+		LLCoros::instance().launch("LLPanelWearing::getAttachmentLimitsCoro",
+		boost::bind(&LLPanelWearing::getAttachmentLimitsCoro, this, url));
+	}
+}
+
+void LLPanelWearing::getAttachmentLimitsCoro(std::string url)
+{
+	LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID);
+	LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+	httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("getAttachmentLimitsCoro", httpPolicy));
+	LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+
+	LLSD result = httpAdapter->getAndSuspend(httpRequest, url);
+
+	LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+	LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+
+	if (!status)
+	{
+		LL_WARNS() << "Unable to retrieve attachment limits." << LL_ENDL;
+		return;
+	}
+
+	result.erase(LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS);
+	setAttachmentDetails(result);
+}
+
+
+void LLPanelWearing::setAttachmentDetails(LLSD content)
+{
+	mObjectNames.clear();
+	S32 number_attachments = content["attachments"].size();
+	for(int i = 0; i < number_attachments; i++)
+	{
+		S32 number_objects = content["attachments"][i]["objects"].size();
+		for(int j = 0; j < number_objects; j++)
+		{
+			LLUUID task_id = content["attachments"][i]["objects"][j]["id"].asUUID();
+			std::string name = content["attachments"][i]["objects"][j]["name"].asString();
+			mObjectNames[task_id] = name;
+		}
+	}
+	if(!mObjectNames.empty())
+	{
+		populateAttachmentsList(true);
+	}
+}
+
 boost::signals2::connection LLPanelWearing::setSelectionChangeCallback(commit_callback_t cb)
 {
 	if (!mCOFItemsList) return boost::signals2::connection();
@@ -270,6 +485,20 @@ void LLPanelWearing::onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
 	mContextMenu->show(ctrl, selected_uuids, x, y);
 }
 
+void LLPanelWearing::onTempAttachmentsListRightClick(LLUICtrl* ctrl, S32 x, S32 y)
+{
+	LLScrollListCtrl* list = dynamic_cast<LLScrollListCtrl*>(ctrl);
+	if (!list) return;
+	list->selectItemAt(x, y, MASK_NONE);
+	uuid_vec_t selected_uuids;
+
+	if(list->getCurrentID().notNull())
+	{
+		selected_uuids.push_back(list->getCurrentID());
+		mAttachmentsMenu->show(ctrl, selected_uuids, x, y);
+	}
+}
+
 bool LLPanelWearing::hasItemSelected()
 {
 	return mCOFItemsList->getSelectedItem() != NULL;
@@ -280,6 +509,28 @@ void LLPanelWearing::getSelectedItemsUUIDs(uuid_vec_t& selected_uuids) const
 	mCOFItemsList->getSelectedUUIDs(selected_uuids);
 }
 
+void LLPanelWearing::onEditAttachment()
+{
+	LLScrollListItem* item = mTempItemsList->getFirstSelected();
+	if (item)
+	{
+		LLSelectMgr::getInstance()->deselectAll();
+		LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]);
+		handle_object_edit();
+	}
+}
+
+void LLPanelWearing::onRemoveAttachment()
+{
+	LLScrollListItem* item = mTempItemsList->getFirstSelected();
+	if (item)
+	{
+		LLSelectMgr::getInstance()->deselectAll();
+		LLSelectMgr::getInstance()->selectObjectAndFamily(mAttachmentsMap[item->getUUID()]);
+		LLSelectMgr::getInstance()->sendDropAttachment();
+	}
+}
+
 void LLPanelWearing::copyToClipboard()
 {
 	std::string text;
diff --git a/indra/newview/llpanelwearing.h b/indra/newview/llpanelwearing.h
index 9a212b3cca92c2feafd0e644c1ba1f44c5794e7c..c5cb79092ad5aee9c15b50c3369ab68c7431f6bb 100644
--- a/indra/newview/llpanelwearing.h
+++ b/indra/newview/llpanelwearing.h
@@ -31,9 +31,14 @@
 
 // newview
 #include "llpanelappearancetab.h"
+#include "llselectmgr.h"
+#include "lltimer.h"
 
+class LLAccordionCtrl;
+class LLAccordionCtrlTab;
 class LLInventoryCategoriesObserver;
 class LLListContextMenu;
+class LLScrollListCtrl;
 class LLWearableItemsList;
 class LLWearingGearMenu;
 
@@ -52,6 +57,8 @@ class LLPanelWearing : public LLPanelAppearanceTab
 
 	/*virtual*/ BOOL postBuild();
 
+	/*virtual*/ void draw();
+
 	/*virtual*/ void onOpen(const LLSD& info);
 
 	/*virtual*/ void setFilterSubString(const std::string& string);
@@ -62,17 +69,43 @@ class LLPanelWearing : public LLPanelAppearanceTab
 
 	/*virtual*/ void copyToClipboard();
 
+	void startUpdateTimer();
+	void updateAttachmentsList();
+
 	boost::signals2::connection setSelectionChangeCallback(commit_callback_t cb);
 
 	bool hasItemSelected();
 
+	bool populateAttachmentsList(bool update = false);
+	void onAccordionTabStateChanged();
+	void setAttachmentDetails(LLSD content);
+	void requestAttachmentDetails();
+	void onEditAttachment();
+	void onRemoveAttachment();
+
 private:
 	void onWearableItemsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
+	void onTempAttachmentsListRightClick(LLUICtrl* ctrl, S32 x, S32 y);
+
+	void getAttachmentLimitsCoro(std::string url);
 
 	LLInventoryCategoriesObserver* 	mCategoriesObserver;
 	LLWearableItemsList* 			mCOFItemsList;
+	LLScrollListCtrl*				mTempItemsList;
 	LLWearingGearMenu*				mGearMenu;
 	LLListContextMenu*				mContextMenu;
+	LLListContextMenu*				mAttachmentsMenu;
+
+	LLAccordionCtrlTab* 			mWearablesTab;
+	LLAccordionCtrlTab* 			mAttachmentsTab;
+	LLAccordionCtrl*				mAccordionCtrl;
+
+	std::map<LLUUID, LLViewerObject*> mAttachmentsMap;
+
+	std::map<LLUUID, std::string> 	mObjectNames;
+
+	boost::signals2::connection 	mAttachmentsChangedConnection;
+	LLFrameTimer					mUpdateTimer;
 
 	bool							mIsInitialized;
 };
diff --git a/indra/newview/llpathfindinglinksetlist.cpp b/indra/newview/llpathfindinglinksetlist.cpp
index b886e46765804bf92bc9d1978eaaf90580be33d3..eb7b95552e371809324b56b49e1887655493c279 100644
--- a/indra/newview/llpathfindinglinksetlist.cpp
+++ b/indra/newview/llpathfindinglinksetlist.cpp
@@ -204,7 +204,10 @@ void LLPathfindingLinksetList::parseLinksetListData(const LLSD& pLinksetListData
 	{
 		const std::string& uuid(linksetDataIter->first);
 		const LLSD& linksetData = linksetDataIter->second;
-		LLPathfindingObjectPtr linksetPtr(new LLPathfindingLinkset(uuid, linksetData));
-		objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, linksetPtr));
+		if(linksetData.size() != 0)
+		{
+			LLPathfindingObjectPtr linksetPtr(new LLPathfindingLinkset(uuid, linksetData));
+			objectMap.insert(std::pair<std::string, LLPathfindingObjectPtr>(uuid, linksetPtr));
+		}
 	}
 }
diff --git a/indra/newview/llpresetsmanager.cpp b/indra/newview/llpresetsmanager.cpp
index 9957039f728e326c8d88ccaa1709651e82eb1f30..836f63bffa696996cb8f262549cb3a729c91578e 100644
--- a/indra/newview/llpresetsmanager.cpp
+++ b/indra/newview/llpresetsmanager.cpp
@@ -104,8 +104,7 @@ void LLPresetsManager::loadPresetNamesFromDir(const std::string& dir, preset_nam
 		if (found)
 		{
 			std::string path = gDirUtilp->add(dir, file);
-			std::string name = gDirUtilp->getBaseFileName(LLURI::unescape(path), /*strip_exten = */ true);
-
+			std::string name = LLURI::unescape(gDirUtilp->getBaseFileName(path, /*strip_exten = */ true));
             LL_DEBUGS() << "  Found preset '" << name << "'" << LL_ENDL;
 
 			if (PRESETS_DEFAULT != name)
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index ba9845ef04519df0d3e7cc7890f464771b934d80..510d91839d6b6cff88a8cb0b83ccf0ff4ac0c851 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -437,6 +437,23 @@ void LLPreviewNotecard::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId,
     }
 }
 
+void LLPreviewNotecard::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId)
+{
+
+    LLSD floater_key;
+    floater_key["taskid"] = taskId;
+    floater_key["itemid"] = itemId;
+    LLPreviewNotecard* nc = LLFloaterReg::findTypedInstance<LLPreviewNotecard>("preview_notecard", floater_key);
+    if (nc)
+    {
+        if (nc->hasEmbeddedInventory())
+        {
+            gVFS->removeFile(newAssetId, LLAssetType::AT_NOTECARD);
+        }
+        nc->setAssetId(newAssetId);
+        nc->refreshFromInventory();
+    }
+}
 
 bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
 {
@@ -485,7 +502,7 @@ bool LLPreviewNotecard::saveIfNeeded(LLInventoryItem* copyitem)
                 else if (!mObjectUUID.isNull() && !task_url.empty())
                 {
                     uploadInfo = LLResourceUploadInfo::ptr_t(new LLBufferedAssetUploadInfo(mObjectUUID, mItemUUID, LLAssetType::AT_NOTECARD, buffer, 
-                        boost::bind(&LLPreviewNotecard::finishInventoryUpload, _1, _3, LLUUID::null)));
+                        boost::bind(&LLPreviewNotecard::finishTaskUpload, _1, _3, mObjectUUID)));
                     url = task_url;
                 }
 
diff --git a/indra/newview/llpreviewnotecard.h b/indra/newview/llpreviewnotecard.h
index ba571995f6d2b359b4c8e4668285f8cb0f09d8ac..017c4485bae4744440b98de9383870459dbf1ab9 100644
--- a/indra/newview/llpreviewnotecard.h
+++ b/indra/newview/llpreviewnotecard.h
@@ -96,6 +96,7 @@ class LLPreviewNotecard : public LLPreview
 	bool handleConfirmDeleteDialog(const LLSD& notification, const LLSD& response);
 
     static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId);
+    static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId);
 
 protected:
 	LLViewerTextEditor* mEditor;
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 5b1b3565978b09ba7ad0b3ae0fadb8de209f6204..f28ffce602b677b0d52b887f285cec421db4513a 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -375,7 +375,8 @@ LLScriptEdCore::LLScriptEdCore(
 	mLiveFile(NULL),
 	mLive(live),
 	mContainer(container),
-	mHasScriptData(FALSE)
+	mHasScriptData(FALSE),
+	mScriptRemoved(FALSE)
 {
 	setFollowsAll();
 	setBorderVisible(FALSE);
@@ -666,7 +667,7 @@ bool LLScriptEdCore::hasChanged()
 void LLScriptEdCore::draw()
 {
 	BOOL script_changed	= hasChanged();
-	getChildView("Save_btn")->setEnabled(script_changed);
+	getChildView("Save_btn")->setEnabled(script_changed && !mScriptRemoved);
 
 	if( mEditor->hasFocus() )
 	{
@@ -840,7 +841,7 @@ void LLScriptEdCore::addHelpItemToHistory(const std::string& help_string)
 
 BOOL LLScriptEdCore::canClose()
 {
-	if(mForceClose || !hasChanged())
+	if(mForceClose || !hasChanged() || mScriptRemoved)
 	{
 		return TRUE;
 	}
@@ -1511,6 +1512,17 @@ BOOL LLPreviewLSL::postBuild()
 	return LLPreview::postBuild();
 }
 
+void LLPreviewLSL::draw()
+{
+	const LLInventoryItem* item = getItem();
+	if(!item)
+	{
+		setTitle(LLTrans::getString("ScriptWasDeleted"));
+		mScriptEd->setItemRemoved(TRUE);
+	}
+
+	LLPreview::draw();
+}
 // virtual
 void LLPreviewLSL::callbackLSLCompileSucceeded()
 {
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index a8c6a6eeebd9ba5f2ca929830e275b1eb1584d1f..6b311256417fac16f3415c0c0ef89439605ed111 100644
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -119,6 +119,8 @@ class LLScriptEdCore : public LLPanel
 
 	void 			setScriptName(const std::string& name){mScriptName = name;};
 
+	void 			setItemRemoved(bool script_removed){mScriptRemoved = script_removed;};
+
 private:
 	void		onBtnHelp();
 	void		onBtnDynamicHelp();
@@ -163,6 +165,7 @@ class LLScriptEdCore : public LLPanel
 	BOOL			mHasScriptData;
 	LLLiveLSLFile*	mLiveFile;
 	LLUUID			mAssociatedExperience;
+	BOOL			mScriptRemoved;
 
 	LLScriptEdContainer* mContainer; // parent view
 
@@ -198,6 +201,7 @@ class LLPreviewLSL : public LLScriptEdContainer
 	/*virtual*/ BOOL postBuild();
 
 protected:
+	virtual void draw();
 	virtual BOOL canClose();
 	void closeIfNeeded();
 
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index 86135ee6e83a0df031548f01b87b12e6dd7b0ece..f07f0ed86c76bf6cd7315b13b5ed2c81c495cb13 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -383,7 +383,7 @@ void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_cam
 
 void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearable *wearable, BOOL disable_camera_switch)
 {
-	if (!mEditWearable || mEditWearable->getVisible() == visible)
+	if (!mEditWearable || ((mEditWearable->getWearable() == wearable) && mEditWearable->getVisible() == visible))
 	{
 		// visibility isn't changing, hence nothing to do
 		return;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 7631f59e8f7dad558bd36de91a591611de46000e..dab25f144ba971fc2a135c6ae3d0fc29957cbf1d 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -774,7 +774,11 @@ bool idle_startup()
 					LL_DEBUGS("AppInit") << "FirstLoginThisInstall off" << LL_ENDL;
 				}
 			}
-
+			display_startup();
+			if (gViewerWindow->getSystemUIScaleFactorChanged())
+			{
+				LLViewerWindow::showSystemUIScaleFactorChanged();
+			}
 			LLStartUp::setStartupState( STATE_LOGIN_WAIT );		// Wait for user input
 		}
 		else
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 37cc908e8456dc09da792e873da5048c9afe7e24..36c4f0d5165a1ebaed882716b2b8525a47d2aaf7 100644
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -1928,6 +1928,12 @@ bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 dis
 		{
 			//make a duplicate to keep the original raw image untouched.
 			raw = raw->duplicate();
+			if (raw->isBufferInvalid())
+			{
+				LL_WARNS() << "Invalid image duplicate buffer" << LL_ENDL;
+				return false;
+			}
+
 			raw->scale(w, h) ;
 			
 			discardlevel += i ;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index ad4f903dff0e800d8d04ae221d634f06c2e679cc..24bc55c998af9e5129eebe70158bc6b0d4150d57 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -1327,7 +1327,7 @@ void LLTextureCtrl::setOnTextureSelectedCallback(texture_selected_callback cb)
 
 void	LLTextureCtrl::setImageAssetName(const std::string& name)
 {
-	LLPointer<LLUIImage> imagep = LLUI::getUIImage(name, LLGLTexture::BOOST_PREVIEW);
+	LLPointer<LLUIImage> imagep = LLUI::getUIImage(name);
 	if(imagep)
 	{
 		LLViewerFetchedTexture* pTexture = dynamic_cast<LLViewerFetchedTexture*>(imagep->getImage().get());
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index c4696c3a01208eb7e4f55eefe64178ea0f28db48..caa055e5e08c9dfe19637dcb3103a1425f5adc4d 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -223,6 +223,7 @@ void LLToolCamera::pickCallback(const LLPickInfo& pick_info)
 		}
 
 		if (!(pick_info.mKeyMask & MASK_ALT) &&
+			!LLFloaterCamera::inFreeCameraMode() &&
 			gAgentCamera.cameraThirdPerson() &&
 			gViewerWindow->getLeftMouseDown() && 
 			!gSavedSettings.getBOOL("FreezeTime") &&
diff --git a/indra/newview/lltoolmgr.cpp b/indra/newview/lltoolmgr.cpp
index b0e3b5bf898b2944c8a0a575c16b397596feea13..f6eb290bc34660297224b132b9b6189440e1e294 100644
--- a/indra/newview/lltoolmgr.cpp
+++ b/indra/newview/lltoolmgr.cpp
@@ -267,7 +267,7 @@ bool LLToolMgr::canEdit()
 
 bool LLToolMgr::buildEnabledOrActive()
 {
-	return inEdit() || canEdit();
+	return LLFloaterReg::instanceVisible("build") || canEdit();
 }
 
 void LLToolMgr::toggleBuildMode(const LLSD& sdname)
diff --git a/indra/newview/llviewchildren.cpp b/indra/newview/llviewchildren.cpp
index 5c5bbdc8f589ab25809a89efb95bf9e8e724bf59..32b2f7e9f5b8cf382efd13f41f824f5c95fec178 100644
--- a/indra/newview/llviewchildren.cpp
+++ b/indra/newview/llviewchildren.cpp
@@ -79,8 +79,9 @@ void LLViewChildren::setBadge(const std::string& id, Badge badge, bool visible)
 			default:
 			case BADGE_OK:		child->setValue(std::string("badge_ok.j2c"));	break;
 			case BADGE_NOTE:	child->setValue(std::string("badge_note.j2c"));	break;
-			case BADGE_WARN:	child->setValue(std::string("badge_warn.j2c"));	break;
-			case BADGE_ERROR:	child->setValue(std::string("badge_error.j2c"));	break;
+			case BADGE_WARN:
+			case BADGE_ERROR:
+				child->setValue(std::string("badge_warn.j2c"));	break;
 		}
 	}
 }
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index d0813544f8c1456850ecc33198e699f4b42f6104..0bbe9fa2c2ab190b0fe133e20315601e3acd3254 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -1007,6 +1007,22 @@ void activate_gesture_cb(const LLUUID& inv_item)
 	LLGestureMgr::instance().activateGesture(inv_item);
 }
 
+void set_default_permissions(LLViewerInventoryItem* item, std::string perm_type)
+{
+	llassert(item);
+	LLPermissions perm = item->getPermissions();
+	if (perm.getMaskEveryone() != LLFloaterPerms::getEveryonePerms(perm_type)
+		|| perm.getMaskGroup() != LLFloaterPerms::getGroupPerms(perm_type))
+	{
+		perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms(perm_type));
+		perm.setMaskGroup(LLFloaterPerms::getGroupPerms(perm_type));
+
+		item->setPermissions(perm);
+
+		item->updateServer(FALSE);
+	}
+}
+
 void create_script_cb(const LLUUID& inv_item)
 {
 	if (!inv_item.isNull())
@@ -1014,13 +1030,9 @@ void create_script_cb(const LLUUID& inv_item)
 		LLViewerInventoryItem* item = gInventory.getItem(inv_item);
 		if (item)
 		{
-			LLPermissions perm = item->getPermissions();
-			perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Scripts"));
-			perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Scripts"));
-
-			item->setPermissions(perm);
+			set_default_permissions(item, "Scripts");
 
-			item->updateServer(FALSE);
+			// item was just created, update even if permissions did not changed
 			gInventory.updateItem(item);
 			gInventory.notifyObservers();
 		}
@@ -1036,13 +1048,8 @@ void create_gesture_cb(const LLUUID& inv_item)
 		LLViewerInventoryItem* item = gInventory.getItem(inv_item);
 		if (item)
 		{
-			LLPermissions perm = item->getPermissions();
-			perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Gestures"));
-			perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Gestures"));
+			set_default_permissions(item, "Gestures");
 
-			item->setPermissions(perm);
-
-			item->updateServer(FALSE);
 			gInventory.updateItem(item);
 			gInventory.notifyObservers();
 
@@ -1061,13 +1068,8 @@ void create_notecard_cb(const LLUUID& inv_item)
 		LLViewerInventoryItem* item = gInventory.getItem(inv_item);
 		if (item)
 		{
-			LLPermissions perm = item->getPermissions();
-			perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("Notecards"));
-			perm.setMaskGroup(LLFloaterPerms::getGroupPerms("Notecards"));
-
-			item->setPermissions(perm);
+			set_default_permissions(item, "Notecards");
 
-			item->updateServer(FALSE);
 			gInventory.updateItem(item);
 			gInventory.notifyObservers();
 		}
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index 6ed063e06637fd8c5238612c4d97742177370450..78c4d98d558c0620e7d6ee54864c77f4c0ffc341 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -1490,7 +1490,7 @@ void LLViewerMedia::createSpareBrowserMediaSource()
 		// The null owner will keep the browser plugin from fully initializing
 		// (specifically, it keeps LLPluginClassMedia from negotiating a size change,
 		// which keeps MediaPluginWebkit::initBrowserWindow from doing anything until we have some necessary data, like the background color)
-		sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType(HTTP_CONTENT_TEXT_HTML, NULL, 0, 0);
+		sSpareBrowserMediaSource = LLViewerMediaImpl::newSourceFromMediaType(HTTP_CONTENT_TEXT_HTML, NULL, 0, 0, 1.0);
 	}
 }
 
@@ -1762,7 +1762,7 @@ void LLViewerMediaImpl::setMediaType(const std::string& media_type)
 
 //////////////////////////////////////////////////////////////////////////////////////////
 /*static*/
-LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, const std::string target, bool clean_browser)
+LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, F64 zoom_factor, const std::string target, bool clean_browser)
 {
 	std::string plugin_basename = LLMIMETypes::implType(media_type);
 	LLPluginClassMedia* media_source = NULL;
@@ -1779,6 +1779,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 			media_source->setOwner(owner);
 			media_source->setTarget(target);
 			media_source->setSize(default_width, default_height);
+			media_source->setZoomFactor(zoom_factor);
 
 			return media_source;
 		}
@@ -1827,6 +1828,7 @@ LLPluginClassMedia* LLViewerMediaImpl::newSourceFromMediaType(std::string media_
 			media_source->setSize(default_width, default_height);
 			media_source->setUserDataPath(user_data_path_cache, user_data_path_cookies);
 			media_source->setLanguageCode(LLUI::getLanguage());
+			media_source->setZoomFactor(zoom_factor);
 
 			// collect 'cookies enabled' setting from prefs and send to embedded browser
 			bool cookies_enabled = gSavedSettings.getBOOL( "CookiesEnabled" );
@@ -1883,6 +1885,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
 		// Save the previous media source's last set size before destroying it.
 		mMediaWidth = mMediaSource->getSetWidth();
 		mMediaHeight = mMediaSource->getSetHeight();
+		mZoomFactor = mMediaSource->getZoomFactor();
 	}
 
 	// Always delete the old media impl first.
@@ -1905,7 +1908,7 @@ bool LLViewerMediaImpl::initializePlugin(const std::string& media_type)
 	// Save the MIME type that really caused the plugin to load
 	mCurrentMimeType = mMimeType;
 
-	LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight, mTarget, mCleanBrowser);
+	LLPluginClassMedia* media_source = newSourceFromMediaType(mMimeType, this, mMediaWidth, mMediaHeight, mZoomFactor, mTarget, mCleanBrowser);
 
 	if (media_source)
 	{
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 48f0d9dc4df8039c049755bce9eb43514feec544..1fecf15fc95b500bdc26bcc1eea5c706f363691c 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -299,7 +299,7 @@ class LLViewerMediaImpl
 	void setTarget(const std::string& target) { mTarget = target; }
 	
 	// utility function to create a ready-to-use media instance from a desired media type.
-	static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, const std::string target = LLStringUtil::null, bool clean_browser = false);
+	static LLPluginClassMedia* newSourceFromMediaType(std::string media_type, LLPluginClassMediaOwner *owner /* may be NULL */, S32 default_width, S32 default_height, F64 zoom_factor, const std::string target = LLStringUtil::null, bool clean_browser = false);
 
 	// Internally set our desired browser user agent string, including
 	// the Second Life version and skin name.  Used because we can
diff --git a/indra/newview/llviewermedia_streamingaudio.cpp b/indra/newview/llviewermedia_streamingaudio.cpp
index c107e8472c8a6b375c59c9435e702ba39ad40f08..3ccf3070ab181a919417c9ae9b4acd3ca28bf408 100644
--- a/indra/newview/llviewermedia_streamingaudio.cpp
+++ b/indra/newview/llviewermedia_streamingaudio.cpp
@@ -154,7 +154,8 @@ LLPluginClassMedia* LLStreamingAudio_MediaPlugins::initializeMedia(const std::st
 {
 	LLPluginClassMediaOwner* owner = NULL;
 	S32 default_size = 1; // audio-only - be minimal, doesn't matter
-	LLPluginClassMedia* media_source = LLViewerMediaImpl::newSourceFromMediaType(media_type, owner, default_size, default_size);
+	F64 default_zoom = 1.0;
+	LLPluginClassMedia* media_source = LLViewerMediaImpl::newSourceFromMediaType(media_type, owner, default_size, default_size, default_zoom);
 
 	if (media_source)
 	{
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 09bc5a9f75f7e1acbd915a7714857f5ebdcd330f..72579d4d7a429cac24f462ce676e190c6f4e0168 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -397,13 +397,15 @@ void set_merchant_SLM_menu()
 	gToolBarView->enableCommand(command->id(), true);
 }
 
-void check_merchant_status()
+void check_merchant_status(bool force)
 {
     if (!gSavedSettings.getBOOL("InventoryOutboxDisplayBoth"))
     {
-        // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status()
-        LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED);
-        
+        if (force)
+        {
+            // Reset the SLM status: we actually want to check again, that's the point of calling check_merchant_status()
+            LLMarketplaceData::instance().setSLMStatus(MarketplaceStatusCodes::MARKET_PLACE_NOT_INITIALIZED);
+        }
         // Hide SLM related menu item
         gMenuHolder->getChild<LLView>("MarketplaceListings")->setVisible(FALSE);
         
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 8ce3c697871a64ef63312053b53359c0ecdea662..7abb0c8e748f9c833d9e9b769badb963e9db4a1f 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -83,7 +83,7 @@ BOOL enable_god_full(void* user_data);
 BOOL enable_god_liaison(void* user_data);
 BOOL enable_god_basic(void* user_data);
 void set_underclothes_menu_options();
-void check_merchant_status();
+void check_merchant_status(bool force = false);
 
 void exchange_callingcard(const LLUUID& dest_id);
 
@@ -108,6 +108,7 @@ void handle_look_at_selection(const LLSD& param);
 void handle_zoom_to_object(LLUUID object_id);
 void handle_object_return();
 void handle_object_delete();
+void handle_object_edit();
 
 void handle_buy_land();
 
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 54b12cae12df6685b96091def5bf129c1b31b178..b48b45502bc843a156b9195fe0f4402e18eda1ce 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -508,8 +508,8 @@ class LLFileEnableCloseAllWindows : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::getInstance();
-		LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::getInstance();
+		LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
+		LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance();
 		bool is_floaters_snapshot_opened = (floater_snapshot && floater_snapshot->isInVisibleChain())
 			|| (floater_outfit_snapshot && floater_outfit_snapshot->isInVisibleChain());
 		bool open_children = gFloaterView->allChildrenClosed() && !is_floaters_snapshot_opened;
@@ -523,10 +523,10 @@ class LLFileCloseAllWindows : public view_listener_t
 	{
 		bool app_quitting = false;
 		gFloaterView->closeAllChildren(app_quitting);
-		LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::getInstance();
+		LLFloaterSnapshot* floater_snapshot = LLFloaterSnapshot::findInstance();
 		if (floater_snapshot)
 			floater_snapshot->closeFloater(app_quitting);
-		LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::getInstance();
+		LLFloaterOutfitSnapshot* floater_outfit_snapshot = LLFloaterOutfitSnapshot::findInstance();
 		if (floater_outfit_snapshot)
 			floater_outfit_snapshot->closeFloater(app_quitting);
 		if (gMenuHolder) gMenuHolder->hideMenus();
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 92df3866f72634a6bf7b78a7872f29aaf07f832e..f472db080fad536d046201bd9e05cdd125d818cc 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1639,7 +1639,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 			
 			LLDiscardAgentOffer* discard_agent_offer = new LLDiscardAgentOffer(mFolderID, mObjectID);
 			discard_agent_offer->startFetch();
-			if (catp || (itemp && itemp->isFinished()))
+			if ((catp && gInventory.isCategoryComplete(mObjectID)) || (itemp && itemp->isFinished()))
 			{
 				discard_agent_offer->done();
 			}
@@ -4719,7 +4719,9 @@ void process_sound_trigger(LLMessageSystem *msg, void **)
 {
 	if (!gAudiop)
 	{
+#if !LL_LINUX
 		LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+#endif
 		return;
 	}
 
@@ -4781,7 +4783,9 @@ void process_preload_sound(LLMessageSystem *msg, void **user_data)
 {
 	if (!gAudiop)
 	{
+#if !LL_LINUX
 		LL_WARNS("AudioEngine") << "LLAudioEngine instance doesn't exist!" << LL_ENDL;
+#endif
 		return;
 	}
 
@@ -6601,6 +6605,11 @@ void process_script_question(LLMessageSystem *msg, void **user_data)
 				if (("ScriptTakeMoney" == script_perm.question) && has_not_only_debit)
 					continue;
 
+                if (script_perm.question == "JoinAnExperience")
+                { // Some experience only permissions do not have an explicit permission bit.  Add them here.
+                    script_question += "    " + LLTrans::getString("ForceSitAvatar") + "\n";
+                }
+
 				script_question += "    " + LLTrans::getString(script_perm.question) + "\n";
 			}
 		}
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 6666aecca207f4c984bbd6e20d68bd7e638ba46f..25258862226aa35249e49b79c6736e76ecad7a58 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -49,6 +49,8 @@ const std::string  GRID_UPDATE_SERVICE_URL = "update_query_url_base";
 const std::string  GRID_HELPER_URI_VALUE = "helper_uri";
 /// the splash page url
 const std::string  GRID_LOGIN_PAGE_VALUE = "login_page";
+/// url for the web profile site
+const std::string  GRID_WEB_PROFILE_VALUE = "web_profile_url";
 /// internal data on system grids
 const std::string  GRID_IS_SYSTEM_GRID_VALUE = "system_grid";
 /// whether this is single or double names
@@ -70,6 +72,8 @@ const std::string SL_UPDATE_QUERY_URL = "https://update.secondlife.com/update";
 const std::string MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/";
 const std::string SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app";
 
+const std::string MAIN_GRID_WEB_PROFILE_URL = "https://my.secondlife.com/";
+
 const char* SYSTEM_GRID_SLURL_BASE = "secondlife://%s/secondlife/";
 const char* DEFAULT_SLURL_BASE = "https://%s/region/";
 const char* DEFAULT_APP_SLURL_BASE = "x-grid-location-info://%s/app";
@@ -125,6 +129,7 @@ void LLGridManager::initialize(const std::string& grid_file)
 				  "https://secondlife.com/helpers/",
 				  DEFAULT_LOGIN_PAGE,
 				  SL_UPDATE_QUERY_URL,
+				  MAIN_GRID_WEB_PROFILE_URL,
 				  "Agni");
 	addSystemGrid(LLTrans::getString("AditiGridLabel"),
 				  "util.aditi.lindenlab.com",
@@ -132,6 +137,7 @@ void LLGridManager::initialize(const std::string& grid_file)
 				  "http://aditi-secondlife.webdev.lindenlab.com/helpers/",
 				  DEFAULT_LOGIN_PAGE,
 				  SL_UPDATE_QUERY_URL,
+				  "https://my.aditi.lindenlab.com/",
 				  "Aditi");
 
 	LLSD other_grids;
@@ -288,6 +294,10 @@ bool LLGridManager::addGrid(LLSD& grid_data)
 				{
 					grid_data[GRID_HELPER_URI_VALUE] = std::string("https://") + grid + "/helpers/";
 				}
+				if (!grid_data.has(GRID_WEB_PROFILE_VALUE))
+				{
+					grid_data[GRID_WEB_PROFILE_VALUE] = std::string("https://") + grid + "/";
+				}
 
 				if (!grid_data.has(GRID_LOGIN_IDENTIFIER_TYPES))
 				{
@@ -302,7 +312,8 @@ bool LLGridManager::addGrid(LLSD& grid_data)
 										 <<"  id:          "<<grid_data[GRID_ID_VALUE].asString()<<"\n"
 										 <<"  label:       "<<grid_data[GRID_LABEL_VALUE].asString()<<"\n"
 										 <<"  login page:  "<<grid_data[GRID_LOGIN_PAGE_VALUE].asString()<<"\n"
-										 <<"  helper page: "<<grid_data[GRID_HELPER_URI_VALUE].asString()<<"\n";
+										 <<"  helper page: "<<grid_data[GRID_HELPER_URI_VALUE].asString()<<"\n"
+										 <<"  web profile: "<<grid_data[GRID_WEB_PROFILE_VALUE].asString()<<"\n";
 				/* still in LL_DEBUGS */ 
 				for (LLSD::array_const_iterator login_uris = grid_data[GRID_LOGIN_URI_VALUE].beginArray();
 					 login_uris != grid_data[GRID_LOGIN_URI_VALUE].endArray();
@@ -339,6 +350,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 								  const std::string& helper,
 								  const std::string& login_page,
 								  const std::string& update_url_base,
+								  const std::string& web_profile_url,
 								  const std::string& login_id)
 {
 	LLSD grid = LLSD::emptyMap();
@@ -349,6 +361,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 	grid[GRID_LOGIN_URI_VALUE].append(login_uri);
 	grid[GRID_LOGIN_PAGE_VALUE] = login_page;
 	grid[GRID_UPDATE_SERVICE_URL] = update_url_base;
+	grid[GRID_WEB_PROFILE_VALUE] = web_profile_url;
 	grid[GRID_IS_SYSTEM_GRID_VALUE] = true;
 	grid[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray();
 	grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT);
@@ -535,6 +548,21 @@ std::string LLGridManager::getLoginPage()
 	return login_page;
 }
 
+std::string LLGridManager::getWebProfileURL(const std::string& grid)
+{
+	std::string web_profile_url;
+	std::string grid_name = getGrid(grid);
+	if (!grid_name.empty())
+	{
+		web_profile_url = mGridList[grid_name][GRID_WEB_PROFILE_VALUE].asString();
+	}
+	else
+	{
+		LL_WARNS("GridManager")<<"invalid grid '"<<grid<<"'"<<LL_ENDL;
+	}
+	return web_profile_url;
+}
+
 void LLGridManager::getLoginIdentifierTypes(LLSD& idTypes)
 {
 	idTypes = mGridList[mGrid][GRID_LOGIN_IDENTIFIER_TYPES];
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index 8526c0ba7f35959b41e90fc81b3a072d3f128b22..228303d8e2d0a3b3d23cdef2c1582cbd451aaa8d 100644
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -166,6 +166,13 @@ class LLGridManager : public LLSingleton<LLGridManager>
 	/// Return the application URL prefix for the selected grid
 	std::string getAppSLURLBase() { return getAppSLURLBase(mGrid); }	
 
+	/// Return the url of the resident profile web site for the given grid
+	std::string getWebProfileURL(const std::string& grid);
+
+	/// Return the url of the resident profile web site for the selected grid
+	std::string getWebProfileURL() { return getWebProfileURL(mGrid); }
+
+
 	//@}
 
 	/* ================================================================
@@ -216,6 +223,7 @@ class LLGridManager : public LLSingleton<LLGridManager>
 					   const std::string& helper,
 					   const std::string& login_page,
 					   const std::string& update_url_base,
+					   const std::string& web_profile_url,
 					   const std::string& login_id = "");	
 	
 	
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index db0adad3c01479f3b0d81cc3e3eaa9c32fab4ef0..4da26404e5efc1b0d768c80f4b780697296acddc 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -244,9 +244,10 @@ LLViewerObject::LLViewerObject(const LLUUID &id, const LLPCode pcode, LLViewerRe
 	mPixelArea(1024.f),
 	mInventory(NULL),
 	mInventorySerialNum(0),
-	mRegionp( regionp ),
-	mInventoryPending(FALSE),
+	mInvRequestState(INVENTORY_REQUEST_STOPPED),
+	mInvRequestXFerId(0),
 	mInventoryDirty(FALSE),
+	mRegionp(regionp),
 	mDead(FALSE),
 	mOrphaned(FALSE),
 	mUserSelected(FALSE),
@@ -1434,10 +1435,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 
 					setChanged(MOVED | SILHOUETTE);
 				}
-				else if (mText.notNull())
+				else
 				{
-					mText->markDead();
-					mText = NULL;
+					if (mText.notNull())
+					{
+						mText->markDead();
+						mText = NULL;
+					}
+					mHudText.clear();
 				}
 
 				std::string media_url;
@@ -1812,10 +1817,14 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 
 					setChanged(TEXTURE);
 				}
-				else if(mText.notNull())
+				else
 				{
-					mText->markDead();
-					mText = NULL;
+					if (mText.notNull())
+					{
+						mText->markDead();
+						mText = NULL;
+					}
+					mHudText.clear();
 				}
 
                 std::string media_url;
@@ -2832,6 +2841,11 @@ void LLViewerObject::removeInventoryListener(LLVOInventoryListener* listener)
 	}
 }
 
+BOOL LLViewerObject::isInventoryPending()
+{
+    return mInvRequestState != INVENTORY_REQUEST_STOPPED;
+}
+
 void LLViewerObject::clearInventoryListeners()
 {
 	for_each(mInventoryCallbacks.begin(), mInventoryCallbacks.end(), DeletePointer());
@@ -2870,7 +2884,7 @@ void LLViewerObject::requestInventory()
 
 void LLViewerObject::fetchInventoryFromServer()
 {
-	if (!mInventoryPending)
+	if (!isInventoryPending())
 	{
 		delete mInventory;
 		LLMessageSystem* msg = gMessageSystem;
@@ -2883,7 +2897,7 @@ void LLViewerObject::fetchInventoryFromServer()
 		msg->sendReliable(mRegionp->getHost());
 
 		// this will get reset by dirtyInventory or doInventoryCallback
-		mInventoryPending = TRUE;
+		mInvRequestState = INVENTORY_REQUEST_PENDING;
 	}
 }
 
@@ -2944,7 +2958,7 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
 	std::string unclean_filename;
 	msg->getStringFast(_PREHASH_InventoryData, _PREHASH_Filename, unclean_filename);
 	ft->mFilename = LLDir::getScrubbedFileName(unclean_filename);
-	
+
 	if(ft->mFilename.empty())
 	{
 		LL_DEBUGS() << "Task has no inventory" << LL_ENDL;
@@ -2966,13 +2980,27 @@ void LLViewerObject::processTaskInv(LLMessageSystem* msg, void** user_data)
 		delete ft;
 		return;
 	}
-	gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename), 
+	U64 new_id = gXferManager->requestFile(gDirUtilp->getExpandedFilename(LL_PATH_CACHE, ft->mFilename), 
 								ft->mFilename, LL_PATH_CACHE,
 								object->mRegionp->getHost(),
 								TRUE,
 								&LLViewerObject::processTaskInvFile,
 								(void**)ft,
 								LLXferManager::HIGH_PRIORITY);
+	if (object->mInvRequestState == INVENTORY_XFER)
+	{
+		if (new_id > 0 && new_id != object->mInvRequestXFerId)
+		{
+			// we started new download.
+			gXferManager->abortRequestById(object->mInvRequestXFerId, -1);
+			object->mInvRequestXFerId = new_id;
+		}
+	}
+	else
+	{
+		object->mInvRequestState = INVENTORY_XFER;
+		object->mInvRequestXFerId = new_id;
+	}
 }
 
 void LLViewerObject::processTaskInvFile(void** user_data, S32 error_code, LLExtStat ext_status)
@@ -3099,7 +3127,10 @@ void LLViewerObject::doInventoryCallback()
 			mInventoryCallbacks.erase(curiter);
 		}
 	}
-	mInventoryPending = FALSE;
+
+	// release inventory loading state
+	mInvRequestXFerId = 0;
+	mInvRequestState = INVENTORY_REQUEST_STOPPED;
 }
 
 void LLViewerObject::removeInventory(const LLUUID& item_id)
@@ -4990,8 +5021,26 @@ void LLViewerObject::initHudText()
 
 void LLViewerObject::restoreHudText()
 {
-    if(mText)
+    if (mHudText.empty())
     {
+        if (mText)
+        {
+            mText->markDead();
+            mText = NULL;
+        }
+    }
+    else
+    {
+        if (!mText)
+        {
+            initHudText();
+        }
+        else
+        {
+            // Restore default values
+            mText->setZCompare(TRUE);
+            mText->setDoFade(TRUE);
+        }
         mText->setColor(mHudTextColor);
         mText->setString(mHudText);
     }
@@ -6271,7 +6320,7 @@ const LLUUID &LLViewerObject::extractAttachmentItemID()
 	return getAttachmentItemID();
 }
 
-const std::string& LLViewerObject::getAttachmentItemName()
+const std::string& LLViewerObject::getAttachmentItemName() const
 {
 	static std::string empty;
 	LLInventoryItem *item = gInventory.getItem(getAttachmentItemID());
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index cb8acfdcf82dd9ca0fadd4889a88c329c4aec8db..1e8f3f4ec2d5755e15153caa3d185c3867a97ac0 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -172,7 +172,7 @@ class LLViewerObject
 	void			setOnActiveList(BOOL on_active)		{ mOnActiveList = on_active; }
 
 	virtual BOOL	isAttachment() const { return FALSE; }
-	const std::string& getAttachmentItemName();
+	const std::string& getAttachmentItemName() const;
 
 	virtual LLVOAvatar* getAvatar() const;  //get the avatar this object is attached to, or NULL if object is not an attachment
 	virtual BOOL	isHUDAttachment() const { return FALSE; }
@@ -437,7 +437,7 @@ class LLViewerObject
 	// viewer object has the inventory stored locally.
 	void registerInventoryListener(LLVOInventoryListener* listener, void* user_data);
 	void removeInventoryListener(LLVOInventoryListener* listener);
-	BOOL isInventoryPending() { return mInventoryPending; }
+	BOOL isInventoryPending();
 	void clearInventoryListeners();
 	bool hasInventoryListeners();
 	void requestInventory();
@@ -720,6 +720,7 @@ class LLViewerObject
 	void deleteTEImages(); // correctly deletes list of images
 	
 protected:
+
 	typedef std::map<char *, LLNameValue *> name_value_map_t;
 	name_value_map_t mNameValuePairs;	// Any name-value pairs stored by script
 
@@ -756,9 +757,17 @@ class LLViewerObject
 	callback_list_t mInventoryCallbacks;
 	S16 mInventorySerialNum;
 
+	enum EInventoryRequestState
+	{
+		INVENTORY_REQUEST_STOPPED,
+		INVENTORY_REQUEST_PENDING,
+		INVENTORY_XFER
+	};
+	EInventoryRequestState	mInvRequestState;
+	U64						mInvRequestXFerId;
+	BOOL					mInventoryDirty;
+
 	LLViewerRegion	*mRegionp;					// Region that this object belongs to.
-	BOOL			mInventoryPending;
-	BOOL			mInventoryDirty;
 	BOOL			mDead;
 	BOOL			mOrphaned;					// This is an orphaned child
 	BOOL			mUserSelected;				// Cached user select information
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index ed719ae41827b8127bc55ec813f1c541eb6a4164..178aa1e64641d41808e198d52508fad8b19e5461 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1200,7 +1200,7 @@ void LLViewerFetchedTexture::loadFromFastCache()
             {
                 S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
                 S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
-                if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
+                if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
                 {
                     // scale oversized icon, no need to give more work to gl
                     mRawImage->scale(expected_width, expected_height);
@@ -1981,7 +1981,7 @@ bool LLViewerFetchedTexture::updateFetch()
                 {
                     S32 expected_width = mKnownDrawWidth > 0 ? mKnownDrawWidth : DEFAULT_ICON_DIMENTIONS;
                     S32 expected_height = mKnownDrawHeight > 0 ? mKnownDrawHeight : DEFAULT_ICON_DIMENTIONS;
-                    if (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height)
+                    if (mRawImage && (mRawImage->getWidth() > expected_width || mRawImage->getHeight() > expected_height))
                     {
                         // scale oversized icon, no need to give more work to gl
                         mRawImage->scale(expected_width, expected_height);
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
index 8d482b2e34eb4b2f820c18bcc29bea056311e9f0..ae9ce37a28cfd6c5307459d1999d7bcacb227d49 100644
--- a/indra/newview/llviewerwearable.cpp
+++ b/indra/newview/llviewerwearable.cpp
@@ -451,7 +451,7 @@ void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)
 
 	// Probably reduntant, but ensure that the newly created wearable is not dirty by setting current value of params in new wearable
 	// to be the same as the saved values (which were loaded from src at param->cloneParam(this))
-	revertValues();
+	revertValuesWithoutUpdate();
 }
 
 void LLViewerWearable::setItemID(const LLUUID& item_id)
@@ -471,6 +471,11 @@ void LLViewerWearable::revertValues()
 	}
 }
 
+void LLViewerWearable::revertValuesWithoutUpdate()
+{
+	LLWearable::revertValues();
+}
+
 void LLViewerWearable::saveValues()
 {
 	LLWearable::saveValues();
diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h
index 62cd5e21add899551997d32ba06a1b773e315f4a..cc99f6af2f72f812ac10e827c32cff9c89a0d261 100644
--- a/indra/newview/llviewerwearable.h
+++ b/indra/newview/llviewerwearable.h
@@ -85,6 +85,8 @@ class LLViewerWearable : public LLWearable
 	/*virtual*/ void	revertValues();
 	/*virtual*/ void	saveValues();
 
+	void 				revertValuesWithoutUpdate();
+
 	// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
 	/*virtual*/void		setUpdated() const;
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index cd9ab3e6724b7b61169919cb12b98d45f63102dd..9e68bb78e0900f3bee15c7b2ba474857134a121a 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -251,6 +251,11 @@ BOOL				gDisplayBadge = FALSE;
 static const U8 NO_FACE = 255;
 BOOL gQuietSnapshot = FALSE;
 
+// Minimum value for UIScaleFactor, also defined in preferences, ui_scale_slider
+static const F32 MIN_UI_SCALE = 0.75f;
+// 4.0 in preferences, but win10 supports larger scaling and value is used more as
+// sanity check, so leaving space for larger values from DPI updates.
+static const F32 MAX_UI_SCALE = 7.0f;
 static const F32 MIN_DISPLAY_SCALE = 0.75f;
 
 std::string	LLViewerWindow::sSnapshotBaseName;
@@ -1593,6 +1598,20 @@ BOOL LLViewerWindow::handleDeviceChange(LLWindow *window)
 	return FALSE;
 }
 
+void LLViewerWindow::handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height)
+{
+    if (ui_scale_factor >= MIN_UI_SCALE && ui_scale_factor <= MAX_UI_SCALE)
+    {
+        gSavedSettings.setF32("UIScaleFactor", ui_scale_factor);
+        LLViewerWindow::reshape(window_width, window_height);
+        mResDirty = true;
+    }
+    else
+    {
+        LL_WARNS() << "DPI change caused UI scale to go out of bounds: " << ui_scale_factor << LL_ENDL;
+    }
+}
+
 void LLViewerWindow::handlePingWatchdog(LLWindow *window, const char * msg)
 {
 	LLAppViewer::instance()->pingMainloopTimeout(msg);
@@ -1655,7 +1674,8 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	mResDirty(false),
 	mStatesDirty(false),
 	mCurrResolutionIndex(0),
-	mProgressView(NULL)
+	mProgressView(NULL),
+	mSystemUIScaleFactorChanged(false)
 {
 	// gKeyboard is still NULL, so it doesn't do LLWindowListener any good to
 	// pass its value right now. Instead, pass it a nullary function that
@@ -1743,9 +1763,24 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 		gSavedSettings.setS32("FullScreenHeight",scr.mY);
     }
 
+
+	F32 system_scale_factor = mWindow->getSystemUISize();
+	if (system_scale_factor < MIN_UI_SCALE || system_scale_factor > MAX_UI_SCALE)
+	{
+		// reset to default;
+		system_scale_factor = 1.f;
+	}
+	if (p.first_run || gSavedSettings.getF32("LastSystemUIScaleFactor") != system_scale_factor)
+	{
+		mSystemUIScaleFactorChanged = !p.first_run;
+		gSavedSettings.setF32("LastSystemUIScaleFactor", system_scale_factor);
+		gSavedSettings.setF32("UIScaleFactor", system_scale_factor);
+	}
+
+
 	// Get the real window rect the window was created with (since there are various OS-dependent reasons why
 	// the size of a window or fullscreen context may have been adjusted slightly...)
-	F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
+	F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE);
 	
 	mDisplayScale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
 	mDisplayScale *= ui_scale_factor;
@@ -1838,6 +1873,28 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	mWorldViewRectScaled = calcScaledRect(mWorldViewRectRaw, mDisplayScale);
 }
 
+//static
+void LLViewerWindow::showSystemUIScaleFactorChanged()
+{
+	LLNotificationsUtil::add("SystemUIScaleFactorChanged", LLSD(), LLSD(), onSystemUIScaleFactorChanged);
+}
+
+//static
+bool LLViewerWindow::onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if(option == 0)
+	{
+		LLFloaterReg::toggleInstanceOrBringToFront("preferences");
+		LLFloater* pref_floater = LLFloaterReg::getInstance("preferences");
+		LLTabContainer* tab_container = pref_floater->getChild<LLTabContainer>("pref core");
+		tab_container->selectTabByName("advanced1");
+
+	}
+	return false; 
+}
+
+
 void LLViewerWindow::initGLDefaults()
 {
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
@@ -5211,7 +5268,7 @@ F32	LLViewerWindow::getWorldViewAspectRatio() const
 
 void LLViewerWindow::calcDisplayScale()
 {
-	F32 ui_scale_factor = gSavedSettings.getF32("UIScaleFactor");
+	F32 ui_scale_factor = llclamp(gSavedSettings.getF32("UIScaleFactor"), MIN_UI_SCALE, MAX_UI_SCALE);
 	LLVector2 display_scale;
 	display_scale.setVec(llmax(1.f / mWindow->getPixelAspectRatio(), 1.f), llmax(mWindow->getPixelAspectRatio(), 1.f));
 	display_scale *= ui_scale_factor;
@@ -5224,7 +5281,7 @@ void LLViewerWindow::calcDisplayScale()
 	
 	if (display_scale != mDisplayScale)
 	{
-		LL_INFOS() << "Setting display scale to " << display_scale << LL_ENDL;
+		LL_INFOS() << "Setting display scale to " << display_scale << " for ui scale: " << ui_scale_factor << LL_ENDL;
 
 		mDisplayScale = display_scale;
 		// Init default fonts
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index cdf5b686a7ffac30590964cb08cf2013f890293b..72b7370621a0d550d2a28f8c415ef0a3b5e3c608 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -156,7 +156,8 @@ class LLViewerWindow : public LLWindowCallbacks
 									min_width,
 									min_height;
 		Optional<bool>				fullscreen,
-									ignore_pixel_depth;
+									ignore_pixel_depth,
+									first_run;
 
 		Params();
 	};
@@ -210,6 +211,7 @@ class LLViewerWindow : public LLWindowCallbacks
 	/*virtual*/ void handleDataCopy(LLWindow *window, S32 data_type, void *data);
 	/*virtual*/ BOOL handleTimerEvent(LLWindow *window);
 	/*virtual*/ BOOL handleDeviceChange(LLWindow *window);
+	/*virtual*/ void handleDPIChanged(LLWindow *window, F32 ui_scale_factor, S32 window_width, S32 window_height);
 
 	/*virtual*/ void handlePingWatchdog(LLWindow *window, const char * msg);
 	/*virtual*/ void handlePauseWatchdog(LLWindow *window);
@@ -415,6 +417,9 @@ class LLViewerWindow : public LLWindowCallbacks
 	void			calcDisplayScale();
 	static LLRect 	calcScaledRect(const LLRect & rect, const LLVector2& display_scale);
 
+	bool getSystemUIScaleFactorChanged() { return mSystemUIScaleFactorChanged; }
+	static void showSystemUIScaleFactorChanged();
+
 private:
 	bool                    shouldShowToolTipFor(LLMouseHandler *mh);
 
@@ -428,6 +433,7 @@ class LLViewerWindow : public LLWindowCallbacks
 	S32				getChatConsoleBottomPad(); // Vertical padding for child console rect, varied by bottom clutter
 	LLRect			getChatConsoleRect(); // Get optimal cosole rect.
 
+	static bool onSystemUIScaleFactorChanged(const LLSD& notification, const LLSD& response);
 private:
 	LLWindow*		mWindow;						// graphical window object
 	bool			mActive;
@@ -506,6 +512,7 @@ class LLViewerWindow : public LLWindowCallbacks
 	LLPointer<LLViewerObject>	mDragHoveredObject;
 
 	static LLTrace::SampleStatHandle<>	sMouseVelocityStat;
+	bool mSystemUIScaleFactorChanged; // system UI scale factor changed from last run
 };
 
 //
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index b25ced4b7efb71c41fcca858cbfd2ba6b37edad1..96a1beffbc326354a47cf26765220df5b853087c 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -188,6 +188,7 @@ const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f;
 const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f;
 
 const U32 LLVOAvatar::VISUAL_COMPLEXITY_UNKNOWN = 0;
+const F64 HUD_OVERSIZED_TEXTURE_DATA_SIZE = 1024 * 1024;
 
 enum ERenderName
 {
@@ -9018,6 +9019,7 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 	{
 		U32 cost = VISUAL_COMPLEXITY_UNKNOWN;
 		LLVOVolume::texture_cost_t textures;
+		hud_complexity_list_t hud_complexity_list;
 
 		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 		{
@@ -9094,6 +9096,63 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 						}
 					}
 				}
+                if (isSelf()
+                    && attached_object
+                    && attached_object->isHUDAttachment()
+                    && !attached_object->isTempAttachment()
+                    && attached_object->mDrawable)
+                {
+                    textures.clear();
+
+                    const LLVOVolume* volume = attached_object->mDrawable->getVOVolume();
+                    if (volume)
+                    {
+                        LLHUDComplexity hud_object_complexity;
+                        hud_object_complexity.objectName = attached_object->getAttachmentItemName();
+                        hud_object_complexity.objectId = attached_object->getAttachmentItemID();
+                        std::string joint_name;
+                        gAgentAvatarp->getAttachedPointName(attached_object->getAttachmentItemID(), joint_name);
+                        hud_object_complexity.jointName = joint_name;
+                        // get cost and individual textures
+                        hud_object_complexity.objectsCost += volume->getRenderCost(textures);
+                        hud_object_complexity.objectsCount++;
+
+                        LLViewerObject::const_child_list_t& child_list = attached_object->getChildren();
+                        for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
+                            iter != child_list.end(); ++iter)
+                        {
+                            LLViewerObject* childp = *iter;
+                            const LLVOVolume* chld_volume = dynamic_cast<LLVOVolume*>(childp);
+                            if (chld_volume)
+                            {
+                                // get cost and individual textures
+                                hud_object_complexity.objectsCost += chld_volume->getRenderCost(textures);
+                                hud_object_complexity.objectsCount++;
+                            }
+                        }
+
+                        hud_object_complexity.texturesCount += textures.size();
+
+                        for (LLVOVolume::texture_cost_t::iterator volume_texture = textures.begin();
+                            volume_texture != textures.end();
+                            ++volume_texture)
+                        {
+                            // add the cost of each individual texture (ignores duplicates)
+                            hud_object_complexity.texturesCost += volume_texture->second;
+                            LLViewerFetchedTexture *tex = LLViewerTextureManager::getFetchedTexture(volume_texture->first);
+                            if (tex)
+                            {
+                                // Note: Texture memory might be incorect since texture might be still loading.
+                                hud_object_complexity.texturesMemoryTotal += tex->getTextureMemory();
+                                if (tex->getOriginalHeight() * tex->getOriginalWidth() >= HUD_OVERSIZED_TEXTURE_DATA_SIZE)
+                                {
+                                    hud_object_complexity.largeTexturesCount++;
+                                }
+                            }
+                        }
+                        hud_complexity_list.push_back(hud_object_complexity);
+                    }
+                }
 			}
 		}
 
@@ -9155,11 +9214,15 @@ void LLVOAvatar::calculateUpdateRenderComplexity()
 
         static LLCachedControl<U32> show_my_complexity_changes(gSavedSettings, "ShowMyComplexityChanges", 20);
 
-		if (isSelf() && show_my_complexity_changes)
-		{
-			LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity);
-		}
-	}
+        if (isSelf() && show_my_complexity_changes)
+        {
+            // Avatar complexity
+            LLAvatarRenderNotifier::getInstance()->updateNotificationAgent(mVisualComplexity);
+
+            // HUD complexity
+            LLHUDRenderNotifier::getInstance()->updateNotificationHUD(hud_complexity_list);
+        }
+    }
 }
 
 void LLVOAvatar::setVisualMuteSettings(VisualMuteSettings set)
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 5b3354a4720dc9b67d8adca0c517135535b6e8f4..657babd92cc8bfc89a7bc5401f3a792506f7a3ac 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -4386,7 +4386,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
 	LL_RECORD_BLOCK_TIME(FTM_REGISTER_FACE);
 	if (type == LLRenderPass::PASS_ALPHA && facep->getTextureEntry()->getMaterialParams().notNull() && !facep->getVertexBuffer()->hasDataType(LLVertexBuffer::TYPE_TANGENT))
 	{
-		LL_WARNS("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
+		LL_WARNS_ONCE("RenderMaterials") << "Oh no! No binormals for this alpha blended face!" << LL_ENDL;
 	}
 
 	if (facep->getViewerObject()->isSelected() && LLSelectMgr::getInstance()->mHideSelectedObjects)
diff --git a/indra/newview/llxmlrpclistener.cpp b/indra/newview/llxmlrpclistener.cpp
index 97a9eb7f5fc557accfd4d7fc555f8098f0f8f6e7..cc3645131dd0efb9a7ef9336c2e88f2bb30687ce 100644
--- a/indra/newview/llxmlrpclistener.cpp
+++ b/indra/newview/llxmlrpclistener.cpp
@@ -322,7 +322,7 @@ class Poller
         mBoundListener =
             LLEventPumps::instance().
             obtain("mainloop").
-            listen(LLEventPump::inventName(), boost::bind(&Poller::poll, this, _1));
+            listen(LLEventPump::ANONYMOUS, boost::bind(&Poller::poll, this, _1));
 
         LL_INFOS("LLXMLRPCListener") << mMethod << " request sent to " << mUri << LL_ENDL;
     }
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 670410c3d494572af8e781338064ddc863ea5df8..f2da22256c4914d9d91ea83df73e56302d87ee3e 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -777,6 +777,9 @@ with the same filename but different name
   <texture name="default_land_picture.j2c" />
   <texture name="default_profile_picture.j2c" />
   <texture name="locked_image.j2c" />
+  <texture name="badge_note.j2c" />
+  <texture name="badge_warn.j2c" />
+  <texture name="badge_ok.j2c" />
   <texture name="materials_ui_x_24.png" />
 
   <texture name="Progress_1" file_name="icons/Progress_1.png" preload="true" />
diff --git a/indra/newview/skins/default/xui/de/panel_status_bar.xml b/indra/newview/skins/default/xui/de/panel_status_bar.xml
index d3d85de3c3a6fa33577adb594bb6803494e9130e..b0cb1e0592f41f4a535681b5e2e2d9078b97f921 100644
--- a/indra/newview/skins/default/xui/de/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">[AMT] L$</panel.string>
-	<panel left="-415" name="balance_bg" width="205">
+	<panel left="-436" name="balance_bg" width="205">
 		<text name="balance" tool_tip="Klicken, um L$-Guthaben zu aktualisieren" value="L$ ??"/>
 		<button label="L$ kaufen" name="buyL" tool_tip="Hier klicken, um mehr L$ zu kaufen"/>
 		<button label="Einkaufen" name="goShop" tool_tip="Second Life-Marktplatz öffnen" width="85"/>
diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
index 2bd3aa8bcc165d7bd7c0583b924e6d958acad2e9..c6b91a8b2f3ade8c3d72e242d0757717f531b27c 100644
--- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
+++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml
@@ -117,7 +117,7 @@
 
   <slider
     control_name="IndirectMaxComplexity"
-    tool_tip="Controls at what point a visually complex avatar is drawn as a jelly doll"
+    tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
     follows="left|top"
     height="16"
     initial_value="101"
diff --git a/indra/newview/skins/default/xui/en/floater_report_abuse.xml b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
index af62c7a9bcf4053f21e41eec7dd4605b1b55ce8f..225266af8649334b3935927b7b4a1078b90b9064 100644
--- a/indra/newview/skins/default/xui/en/floater_report_abuse.xml
+++ b/indra/newview/skins/default/xui/en/floater_report_abuse.xml
@@ -21,14 +21,6 @@
      name="screenshot"
      top="15"
      width="220" />
-    <check_box
-     height="15"
-     label="Use this screenshot"
-     layout="topleft"
-     left="8"
-     name="screen_check"
-     top_pad="-12"
-     width="116" />
     <text
      type="string"
      length="1"
@@ -39,7 +31,7 @@
      layout="topleft"
      left="10"
      name="reporter_title"
-     top_pad="0"
+     top_pad="-2"
      width="100">
         Reporter:
     </text>
diff --git a/indra/newview/skins/default/xui/en/fonts.xml b/indra/newview/skins/default/xui/en/fonts.xml
index 5d05ecf12738f30803807e3c8aaca4bcabdefdfb..550af03683ff6cab2da8392115bfe236129c5605 100644
--- a/indra/newview/skins/default/xui/en/fonts.xml
+++ b/indra/newview/skins/default/xui/en/fonts.xml
@@ -10,6 +10,7 @@
       <file>ArialUni.ttf</file>
     </os>
     <os name="Mac">
+      <file>ヒラギノ角ゴシック W3.ttc</file>  
       <file>ヒラギノ角ゴ Pro W3.otf</file>
       <file>ヒラギノ角ゴ ProN W3.otf</file>
       <file>ヒラギノ明朝 ProN W3.ttc</file>
diff --git a/indra/newview/skins/default/xui/en/inspect_group.xml b/indra/newview/skins/default/xui/en/inspect_group.xml
index 324ff3eabd6b7e23850502e2ec85af8a6b0299d8..a69585074ca189b505c5433f02495aaadd34d3e6 100644
--- a/indra/newview/skins/default/xui/en/inspect_group.xml
+++ b/indra/newview/skins/default/xui/en/inspect_group.xml
@@ -66,7 +66,7 @@ Fear the moose!  Fear it!  And the mongoose too!
    width="220">
 L$123 to join
   </text>
-  <icon
+  <group_icon
      follows="all"
      height="38"
      right="-10"
diff --git a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
index 44b2727671c609f2dee6b5eb40dd9c62493a6b1a..75c1de24aa229a2f68c2698b3cdbc22c7d632e29 100644
--- a/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
+++ b/indra/newview/skins/default/xui/en/menu_wearing_tab.xml
@@ -27,6 +27,13 @@
         <on_click
          function="Wearing.Edit" />
     </menu_item_call>
+    <menu_item_call
+     label="Edit"
+     layout="topleft"
+     name="edit_item">
+        <on_click
+         function="Wearing.EditItem" />
+    </menu_item_call>
     <menu_item_call
      label="Show Original"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/mime_types.xml b/indra/newview/skins/default/xui/en/mime_types.xml
index c27fac6731bf3a5e79d23df78e94c14a5ac48849..8d8d546b249b2c0c4ae2c3513f9aafa91356b688 100644
--- a/indra/newview/skins/default/xui/en/mime_types.xml
+++ b/indra/newview/skins/default/xui/en/mime_types.xml
@@ -130,7 +130,7 @@
 			movie
 		</widgettype>
 		<impl>
-			media_plugin_cef
+			media_plugin_libvlc
 		</impl>
 	</scheme>
   <scheme name="libvlc">
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index b8edc6e10e48f8d361ebdb7adf3c5193aa339293..11e019e153bf213bdf93d1c008fc0618b0c0d69e 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -831,6 +831,13 @@ If you no longer wish to have these abilities granted to this role, disable them
       yestext="Ban"/>
   </notification>
 
+  <notification
+    icon="notify.tga"
+    name="GroupBanUserOnBanlist"
+    type="notify">
+Some residents have not been sent an invite due to being banned from the group.
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="AttachmentDrop"
@@ -1483,6 +1490,7 @@ Save Changes?
    icon="alertmodal.tga"
    name="DeleteNotecard"
    type="alertmodal">
+   <unique/>
 Delete Notecard?
     <tag>confirm</tag>
     <usetemplate
@@ -1638,14 +1646,14 @@ Visit [_URL] for more information?
 
   <notification
    icon="alertmodal.tga"
-   name="IntelOldDriver"
+   name="OldGPUDriver"
    type="alertmodal">
      There is likely a newer driver for your graphics chip.  Updating graphics drivers can substantially improve performance.
 
-    Visit [_URL] to check for driver updates?
+    Visit [URL] to check for driver updates?
     <tag>confirm</tag>
     <url option="0" name="url">
-      http://www.intel.com/p/en_US/support/detect/graphics
+    [URL]
     </url>
     <usetemplate
      ignoretext="My graphics driver is out of date"
@@ -1655,45 +1663,6 @@ Visit [_URL] for more information?
     <tag>fail</tag>
   </notification>
 
-  <notification
-   icon="alertmodal.tga"
-   name="AMDOldDriver"
-   type="alertmodal">
-    There is likely a newer driver for your graphics chip.  Updating graphics drivers can substantially improve performance.
-
-    Visit [_URL] to check for driver updates?
-    <tag>confirm</tag>
-    <url option="0" name="url">
-      http://support.amd.com/us/Pages/AMDSupportHub.aspx
-    </url>
-    <usetemplate
-     ignoretext="My graphics driver is out of date"
-     name="okcancelignore"
-     notext="No"
-     yestext="Yes"/>
-    <tag>fail</tag>
-  </notification>
-
-  <notification
- icon="alertmodal.tga"
- name="NVIDIAOldDriver"
- type="alertmodal">
-    There is likely a newer driver for your graphics chip.  Updating graphics drivers can substantially improve performance.
-
-    Visit [_URL] to check for driver updates?
-    <tag>confirm</tag>
-    <url option="0" name="url">
-      http://www.nvidia.com/Download/index.aspx?lang=en-us
-    </url>
-    <usetemplate
-     ignoretext="My graphics driver is out of date"
-     name="okcancelignore"
-     notext="No"
-     yestext="Yes"/>
-    <tag>fail</tag>
-  </notification>
-
-
   <notification
    icon="alertmodal.tga"
    name="UnknownGPU"
@@ -3356,6 +3325,23 @@ Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Renderin
      <context>AgentComplexityNotice</context>
    </unique>
 Your [https://community.secondlife.com/t5/English-Knowledge-Base/Avatar-Rendering-Complexity/ta-p/2967838 avatar complexity] is [AGENT_COMPLEXITY].
+    <usetemplate
+     ignoretext="Warn me about my avatar complexity changes"
+     name="notifyignore"/>
+  </notification>
+
+  <notification
+   icon = "notifytip.tga"
+   name = "HUDComplexityWarning"
+   type = "notifytip"
+   log_to_chat = "false">
+    <unique combine = "cancel_old">
+      <context>HUDComplexityWarning</context>
+    </unique>
+    [HUD_REASON], it is likely to negatively affect your performance.
+    <usetemplate
+     ignoretext="Warn me when my HUD complexity is too high"
+     name="notifyignore"/>
   </notification>
 
   <notification
@@ -3670,6 +3656,13 @@ You can only have [MAX_MANAGER] Estate Managers.
 Can&apos;t add estate owner to estate &apos;Banned Resident&apos; list.
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="ProblemAddingEstateManagerBanned"
+   type="alertmodal">
+Unable to add banned resident to estate manager list.
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="CanNotChangeAppearanceUntilLoaded"
@@ -4064,6 +4057,18 @@ Do you want to open your Web browser to view this content?
      yestext="OK"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="SystemUIScaleFactorChanged"
+   type="alertmodal">
+System UI size factor has changed since last run. Do you want to open UI size adjustment settings page?
+    <tag>confirm</tag>
+    <usetemplate
+     name="okcancelbuttons"
+     notext="Cancel"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="WebLaunchJoinNow"
@@ -4184,6 +4189,14 @@ Leave Group?
      yestext="OK"/>
   </notification>
 
+  <notification
+   icon="notify.tga"
+   name="GroupDepart"
+   type="notify">
+You have left the group &apos;[group_name]&apos;.
+    <tag>group</tag>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="OwnerCannotLeaveGroup"
@@ -4195,6 +4208,17 @@ Leave Group?
      yestext="OK"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="GroupDepartError"
+   type="alertmodal">
+    Unable to leave group.
+    <tag>group</tag>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="alert.tga"
    name="ConfirmKick"
@@ -5310,6 +5334,17 @@ You won't receive any more notifications that you're about to visit a region wit
 	  name="TooManyPrimsSelected"
 	  type="alertmodal">
 There are too many prims selected.  Please select [MAX_PRIM_COUNT] or fewer prims and try again
+  <tag>fail</tag>
+		<usetemplate
+		 name="okbutton"
+		 yestext="OK"/>
+	</notification>
+
+	<notification
+	  icon="alertmodal.tga"
+	  name="TooManyScriptsSelected"
+	  type="alertmodal">
+Too many scripts in the objects selected.  Please select fewer objects and try again
   <tag>fail</tag>
 		<usetemplate
 		 name="okbutton"
@@ -5733,6 +5768,17 @@ Warning: The &apos;Pay object&apos; click action has been set, but it will only
      yestext="OK"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="PaymentBlockedButtonMismatch"
+   type="alertmodal">
+    Payment stopped:  the price paid does not match any of the pay buttons set for this object.
+    <tag>fail</tag>
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="OpenObjectCannotCopy"
@@ -5837,7 +5883,20 @@ You cannot undo this action.
      notext="Cancel"
      yestext="Unlink"/>
   </notification>
-
+  
+  <notification
+   icon="alertmodal.tga"
+   name="HelpReportAbuseConfirm"
+   type="alertmodal">
+   <unique/>
+Thank you for taking the time to inform us of this issue. 
+We will review your report for possible violations and take
+the appropriate action.
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+  
   <notification
    icon="alertmodal.tga"
    name="HelpReportAbuseSelectCategory"
@@ -7346,7 +7405,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
    name="TeleportOffered_MaturityExceeded"
    log_to_im="true"
    log_to_chat="false"
-   type="offer">
+   type="offer"
+   sound="UISndNewIncomingIMSession">
 [NAME_SLURL] has offered to teleport you to their location:
 
 “[MESSAGE]”
@@ -7371,7 +7431,8 @@ This region contains [REGION_CONTENT_MATURITY] content, but your current prefere
    name="TeleportOffered_MaturityBlocked"
    log_to_im="true"
    log_to_chat="false"
-   type="notifytip">
+   type="notifytip"
+   sound="UISndNewIncomingIMSession">
 [NAME_SLURL] has offered to teleport you to their location:
 
 “[MESSAGE]”
@@ -8810,23 +8871,6 @@ Click and drag anywhere on the world to rotate your view
     SL will quit in 30 seconds due to out of memory.
   </notification>
 
-  <notification
-  name="PopupAttempt"
-  icon="Popup_Caution"
-  type="browser">
-    A pop-up was prevented from opening.
-    <form name="form">
-      <ignore name="ignore"
-              control="MediaEnablePopups"
-              invert_control="true"
-              text="Enable all pop-ups"/>
-      <button default="true"
-              index="0"
-              name="open"
-              text="Open pop-up window"/>
-    </form>
-  </notification>
-
   <notification
    icon="alertmodal.tga"
    name="SOCKS_NOT_PERMITTED"
@@ -9807,6 +9851,14 @@ Can't move object '[OBJECT_NAME]' to
 [OBJ_POSITION] in region [REGION_NAME] because there are not enough resources for this object on this parcel.
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="NoParcelPermsNoObject"
+   type="notify">
+   <tag>fail</tag>
+Copy failed because you lack access to that parcel.
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="CantMoveObjectRegionVersion"
@@ -9842,6 +9894,17 @@ Can't move object '[OBJECT_NAME]' to
 You don't have permission to modify that object
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="TooMuchObjectInventorySelected"
+   type="alertmodal">
+    <tag>fail</tag>
+    Too many objects with large inventory are selected. Please select fewer objects and try again.
+    <usetemplate
+     name="okbutton"
+     yestext="OK"/>
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="CantEnablePhysObjContributesToNav"
@@ -9939,6 +10002,22 @@ Cannot save to object contents: Item with that name already exists in inventory
 Cannot save to object contents: This would modify the attachment permissions.
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="AttachmentHasTooMuchInventory"
+   type="notify">
+   <tag>fail</tag>
+Your attachments contain too much inventory to add more.
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="IllegalAttachment"
+   type="notify">
+   <tag>fail</tag>
+The attachment has requested a nonexistent point on the avatar. It has been attached to the chest instead.
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="TooManyScripts"
@@ -10188,6 +10267,22 @@ You have been teleported by the object '[OBJECT_NAME]' owned by [OWNER_ID]
 You have been teleported by the object '[OBJECT_NAME]' owned by an unknown user.
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="StandDeniedByObject"
+   type="notify">
+    <tag>fail</tag>
+'[OBJECT_NAME]' will not allow you to stand at this time.
+  </notification>
+
+  <notification
+   icon="alertmodal.tga"
+   name="ResitDeniedByObject"
+   type="notify">
+    <tag>fail</tag>
+'[OBJECT_NAME]' will not allow you to change your seat at this time.
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="CantCreateObjectRegionFull"
@@ -10985,6 +11080,14 @@ Unable to find object.
 Money transfers to objects are currently disabled in this region.
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="DroppedMoneyTransferRequest"
+   type="notify">
+   <tag>fail</tag>
+Unable to make payment due to system load.
+  </notification>
+
   <notification
    icon="alertmodal.tga"
    name="CantPayNoAgent"
diff --git a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
index d85b778db2174ab3f0a7a8cdd59e4c1203998355..42a79743169aba8c1364624ea0ea42173ba4ee7c 100644
--- a/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
+++ b/indra/newview/skins/default/xui/en/panel_outfits_wearing.xml
@@ -9,6 +9,26 @@
  name="Wearing"
  top="0"
  width="312">
+<panel.string
+    name="no_attachments">
+    No attachments worn.
+   </panel.string>
+     <accordion
+     fit_parent="true"
+     follows="all"
+     height="400"
+     layout="topleft"
+     left="0"
+     single_expansion="true"
+     top="0"
+     name="wearables_accordion"
+     background_visible="true"
+     bg_alpha_color="DkGray2"
+     width="309">
+     <accordion_tab
+     layout="topleft"
+     name="tab_wearables"
+     title="Wearables">
     <wearable_items_list
      follows="all"
      height="400"
@@ -20,6 +40,27 @@
      top="0"
      width="309"
      worn_indication_enabled="false" />
+     </accordion_tab>
+     <accordion_tab
+     layout="topleft"
+     name="tab_temp_attachments"
+     title="Temporary attachments">
+    <scroll_list
+     draw_heading="false"
+     left="3"
+     width="309"
+     height="400"
+     follows="all"
+     name="temp_attachments_list">
+        <scroll_list.columns
+         name="icon"
+         width="15" />
+        <scroll_list.columns
+         name="text"
+         width="210" />
+  </scroll_list>
+     </accordion_tab>
+     </accordion>
     <panel
      background_visible="true"
      follows="bottom|left|right"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 4a5117adacf766635e572422a73f4f594d53ca98..0deb1d03cff6a39123979f82a4b59e20fb0bd431 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -138,7 +138,7 @@
    initial_value="1"
    layout="topleft"
    left_pad="0"
-   max_val="2.0"
+   max_val="4.0"
    min_val="0.75"
    name="ui_scale_slider"
    top_pad="-14"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index 9e99916ca080d81095b5c30f119619083a5fac0b..32cbbff8b772cb5280241dff48ce6be9888c3a2c 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -233,7 +233,7 @@
 
   <slider
     control_name="IndirectMaxComplexity"
-    tool_tip="Controls at what point a visually complex avatar is drawn as a jelly doll"
+    tool_tip="Controls at what point a visually complex avatar is drawn as a JellyDoll"
     follows="left|top"
     height="16"
     initial_value="101"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
index 0b605cf6f7e33a6238b7e1422c500a337d110d95..c20f9b2c510c119a3fdb52ce7e0c46a3babca79c 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_setup.xml
@@ -273,6 +273,18 @@
     name="update_willing_to_test"
     width="400"           
     top_pad="5"/>
+  <check_box
+    top_delta="4"
+    enabled="true"
+    follows="left|top"
+    height="14"
+    control_name="UpdaterShowReleaseNotes"
+    label="Show Release Notes after update"
+    left_delta="0"
+    mouse_opaque="true"
+    name="update_show_release_notes"
+    width="400"
+    top_pad="5"/>
   <text
      type="string"
      length="1"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 6420644f09d6125c83873acbfba9bebe7e987dfe..dcb259f2bbe8c4babdb27517e0641fa30f66282c 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -500,6 +500,7 @@ Please try logging in again in a minute.</string>
 	<string name="TeleportYourAgent">Teleport you</string>
 	<string name="ManageEstateSilently">Manage your estates silently</string>
 	<string name="ChangeYourDefaultAnimations">Change your default animations</string>
+	<string name="ForceSitAvatar">Force your avatar to sit</string>
 	
 	<string name="NotConnected">Not Connected</string>
 	<string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name -->
@@ -2516,6 +2517,15 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f
   <string name="av_render_most_of">You may not be rendered by most of those around you.</string>
   <string name="av_render_anyone">You may not be rendered by anyone around you.</string>
 
+  <!-- HUD complexity rendering messages, see llavatarrendernotifier. -->
+  <string name="hud_description_total">Your HUD</string>
+  <string name="hud_name_with_joint">[OBJ_NAME] (worn on [JNT_NAME])</string>
+  <string name="hud_render_memory_warning">[HUD_DETAILS] uses a lot of texture memory</string>
+  <string name="hud_render_cost_warning">[HUD_DETAILS] contains a lot of expensive objects and textures</string>
+  <string name="hud_render_heavy_textures_warning">[HUD_DETAILS] contains a lot of large textures</string>
+  <string name="hud_render_cramped_warning">[HUD_DETAILS] contains too many objects</string>
+  <string name="hud_render_textures_warning">[HUD_DETAILS] contains too many textures</string>
+
   <!-- AgeYearsA = singular,
        AgeYearsB = plural,
        AgeYearsC = plural for non-English languages like Russian
@@ -2583,7 +2593,8 @@ This feature is currently in Beta. Please add your name to this [http://goo.gl/f
 	<string name="SaveComplete">Save complete.</string>
 	<string name="UploadFailed">File upload failed: </string>
 	<string name="ObjectOutOfRange">Script (object out of range)</string>
-
+	<string name="ScriptWasDeleted">Script (deleted from inventory)</string>
+	
 	<!-- god tools -->
 	<string name="GodToolsObjectOwnedBy">Object [OBJECT] owned by [OWNER]</string>
 
@@ -2866,6 +2877,12 @@ Expected .wav, .tga, .bmp, .jpg, .jpeg, or .bvh
 	<string name="Multiple Media">Multiple Media</string>
 	<string name="Play Media">Play/Pause Media</string>
 
+	<!-- Drivers support/update pages -->
+	<string name="IntelDriverPage">http://www.intel.com/p/en_US/support/detect/graphics</string>
+	<string name="NvidiaDriverPage">http://www.nvidia.com/Download/index.aspx?lang=en-us</string>
+	<string name="AMDDriverPage">http://support.amd.com/us/Pages/AMDSupportHub.aspx</string>
+
+
 	<!-- OSMessageBox messages -->
 	<string name="MBCmdLineError">
 		An error was found parsing the command line.
diff --git a/indra/newview/skins/default/xui/es/panel_status_bar.xml b/indra/newview/skins/default/xui/es/panel_status_bar.xml
index 8ea56c52628f9811025f4750017c5be7b759a05b..8aaa236475fee4626c99070a8be2b5e828cfe48b 100644
--- a/indra/newview/skins/default/xui/es/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">[AMT] L$</panel.string>
-	<panel left="-410" name="balance_bg" width="200">
+	<panel left="-431" name="balance_bg" width="200">
 		<text name="balance" tool_tip="Haz clic para actualizar tu saldo en L$" value="L$??"/>
 		<button label="Comprar L$" name="buyL" tool_tip="Pulsa para comprar más L$"/>
 		<button label="Comprar" name="goShop" tool_tip="Abrir el mercado de Second Life" width="80"/>
diff --git a/indra/newview/skins/default/xui/fr/panel_status_bar.xml b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
index e2f05a525e53840ceff92fb4d8c99720c5fe19bd..fef0379c2ceccbdbb31792f5c61366decc521597 100644
--- a/indra/newview/skins/default/xui/fr/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt] [sday, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">[AMT] L$</panel.string>
-	<panel left="-405" name="balance_bg" width="195">
+	<panel left="-426" name="balance_bg" width="195">
 		<text name="balance" tool_tip="Cliquer sur ce bouton pour actualiser votre solde en L$." value="L$ ??"/>
 		<button label="Acheter L$" name="buyL" tool_tip="Cliquer pour acheter plus de L$."/>
 		<button label="Achats" name="goShop" tool_tip="Ouvrir la Place du marché Second Life." width="75"/>
diff --git a/indra/newview/skins/default/xui/it/panel_status_bar.xml b/indra/newview/skins/default/xui/it/panel_status_bar.xml
index 83d2ae5babfe68e07d5ae7bbd48ebc83c7fc1eb7..295ca8d9f2df0f47afc939559477eda0e1b078ba 100644
--- a/indra/newview/skins/default/xui/it/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">L$ [AMT]</panel.string>
-	<panel left="-405" name="balance_bg" width="195">
+	<panel left="-426" name="balance_bg" width="195">
 		<text name="balance" tool_tip="Clicca per aggiornare il tuo saldo in L$" value="L$ ??"/>
 		<button label="Acquista L$" name="buyL" tool_tip="Clicca per acquistare più L$"/>
 		<button label="Acquisti" name="goShop" tool_tip="Apri Mercato Second Life" width="75"/>
diff --git a/indra/newview/skins/default/xui/ja/panel_status_bar.xml b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
index 2e1446d45093de620f18d5ec157a5d391b69487f..3f3845e491bdcd4454e6343c5f1c228bf36eec01 100644
--- a/indra/newview/skins/default/xui/ja/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[year, datetime, slt] [month, datetime, slt] [day, datetime, slt] ([weekday, datetime, slt])</panel.string>
 	<panel.string name="buycurrencylabel">L$ [AMT]</panel.string>
-	<panel left="-370" name="balance_bg" width="160">
+	<panel left="-391" name="balance_bg" width="160">
 		<text name="balance" tool_tip="クリックして L$ 残高を更新" value="L$??"/>
 		<button label="L$ の購入" name="buyL" tool_tip="クリックして L$ を購入します"/>
 		<button label="店" name="goShop" tool_tip="Second Life マーケットプレイスを開く" width="40"/>
diff --git a/indra/newview/skins/default/xui/pt/panel_status_bar.xml b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
index cfe52ff404012b82b4358f401807dc468ad1a3cb..c35863734fb2a0f50826861290b93799904b3799 100644
--- a/indra/newview/skins/default/xui/pt/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">L$ [AMT]</panel.string>
-	<panel left="-410" name="balance_bg" width="200">
+	<panel left="-431" name="balance_bg" width="200">
 		<text name="balance" tool_tip="Atualizar saldo de L$" value="L$??"/>
 		<button label="Comprar L$" name="buyL" tool_tip="Comprar mais L$"/>
 		<button label="Comprar" name="goShop" tool_tip="Abrir Mercado do Second Life" width="80"/>
diff --git a/indra/newview/skins/default/xui/ru/panel_status_bar.xml b/indra/newview/skins/default/xui/ru/panel_status_bar.xml
index 630925fa6024f4afeb8cfc627e36bcbe3993a454..49c48ae6545618ec910b36426122ae28978494d1 100644
--- a/indra/newview/skins/default/xui/ru/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour, datetime, slt]:[min, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">L$ [AMT]</panel.string>
-	<panel left="-450" name="balance_bg" width="240">
+	<panel left="-471" name="balance_bg" width="240">
 		<text name="balance" tool_tip="Щелкните для обновления вашего баланса L$" value="L$??"/>
 		<button label="Купить L$" name="buyL" tool_tip="Щелкните для покупки L$"/>
 		<button label="Торговый центр" name="goShop" tool_tip="Открыть торговый центр Second Life" width="121"/>
diff --git a/indra/newview/skins/default/xui/tr/panel_status_bar.xml b/indra/newview/skins/default/xui/tr/panel_status_bar.xml
index 9e2669ec2b38280e3a07523fdf14f2c2b35c3a5e..7c7bfc7e144061af06e7c33ae4013898bd5dea2c 100644
--- a/indra/newview/skins/default/xui/tr/panel_status_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_status_bar.xml
@@ -5,7 +5,7 @@
 	<panel.string name="time">[hour12, datetime, slt]:[min, datetime, slt] [ampm, datetime, slt] [timezone,datetime, slt]</panel.string>
 	<panel.string name="timeTooltip">[weekday, datetime, slt], [day, datetime, slt] [month, datetime, slt] [year, datetime, slt]</panel.string>
 	<panel.string name="buycurrencylabel">L$ [AMT]</panel.string>
-	<panel left="-425" name="balance_bg" width="215">
+	<panel left="-446" name="balance_bg" width="215">
 		<text name="balance" tool_tip="L$ bakiyenizi yenilemek için buraya tıklayın" value="L$??"/>
 		<button label="L$ Satın Al" name="buyL" tool_tip="Daha fazla L$ satın almak için tıklayın"/>
 		<button label="Alışveriş yap" name="goShop" tool_tip="Second Life Pazaryeri Aç" width="95"/>
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index 1b0334498e25f264b79c65f42133196f21dbb8a0..b603157ca75d67ba27f17d6bc9c3304a08a759dc 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -136,6 +136,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 								  const std::string& helper,
 								  const std::string& login_page,
 								  const std::string& update_url_base,
+								  const std::string& web_profile_url,
 								  const std::string& login_id)
 {
 }