diff --git a/.hgignore b/.hgignore
index b180d9200349eb5cb3f63baa0126d399860bf30a..c845758e7ce33da2c381bae3eb96459cffaa4cc7 100644
--- a/.hgignore
+++ b/.hgignore
@@ -10,7 +10,7 @@ syntax: glob
 .*.swp
 #OSX image cache file
 *.DS_Store
-*.orig
+#*.orig
 LICENSES
 indra/.distcc
 build-linux-*
@@ -50,6 +50,11 @@ indra/web/doc/asset-upload/plugins/verify-texture
 installed.xml
 libraries
 tarfile_tmp
+debian/secondlife-viewer*
+debian/secondlife-appearance-utility*
+debian/files
+build-stamp
+configure-stamp
 ^indra/lib/python/mulib.*
 ^web/locale.*
 ^web/secondlife.com.*
@@ -69,4 +74,4 @@ glob:indra/newview/filters.xml
 glob:indra/newview/avatar_icons_cache.txt
 glob:indra/newview/avatar_lad.log
 glob:*.diff
-*.rej
+#*.rej
diff --git a/.hgtags b/.hgtags
index 310c6fbc189de050d11061a4e2b62b76d78d653f..d07ac6dbdabf9cffec7dc77b50fd721f77254da9 100644
--- a/.hgtags
+++ b/.hgtags
@@ -435,3 +435,4 @@ fd6b510e83f56830e45670c428653134899d3e25 DRTVWR-305
 5c6098fd17d40ee3a38ca6b64f6be9db7f61f0a8 3.5.0-beta7
 adc360e6bf21390d2665380951d85937cd29a604 3.5.0-release
 0ca3910763cec967703e45bc6208a325dccb9f95 3.5.1-beta1
+1ada73295ed0eaa4a772ef079c29f57069342c32 DRTVWR-310
diff --git a/BuildParams b/BuildParams
index e00fc384d4a98e626b7ce507245d1874d1d16cd2..c929c2d90d1a9ea1db0adfef985e8a5e627a13ba 100644
--- a/BuildParams
+++ b/BuildParams
@@ -21,6 +21,11 @@ email_status_this_is_os = true
 # Limit extent of codeticket updates to revisions after...
 codeticket_since = 3.3.0-release
 
+# Override build system default toolchain
+# Note that this will only affect automated builds.
+Linux.gcc_version = /usr/bin/gcc-4.6
+Linux.cxx_version = /usr/bin/g++-4.6
+
 # ========================================
 # Viewer Development
 # ========================================
diff --git a/autobuild.xml b/autobuild.xml
index 11c2da52dc25642bda3b04818f32043b2749004a..80a44ec75dba602f268adc759c3b0d94cbd9dad4 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -18,9 +18,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b2fe1c860613a68e74d4384be418ffee</string>
+              <string>e6071abd822c0688390382a26f8a782c</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/Darwin/installer/glod-1.0pre4-darwin-20110610.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/267984/arch/Darwin/installer/glod-1.0pre4-darwin-20121211.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin</string>
@@ -30,9 +30,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c0c64dae149d0892343e2ff300fd06b9</string>
+              <string>176736c52b3cde6ca8e7d9e173d91731</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/Linux/installer/glod-1.0pre4-linux-20110611.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/268002/arch/Linux/installer/glod-1.0pre4-linux-20121212.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -606,9 +606,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9f8a9dc39fd7c3da0fb3533782d1fddf</string>
+              <string>ca95bbdabd2bed612af79a3704fdbe79</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-freetype/rev/226814/arch/Linux/installer/freetype-2.3.9-linux-20110418.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-freetype/rev/265843/arch/Linux/installer/freetype-2.3.9-linux-20121013.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -690,9 +690,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>26f2df1f0b0fa01e94e0253e322f3583</string>
+              <string>1b1f1e9975e3a671c9faf32fcf4b6d43</string>
               <key>url</key>
-              <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glh_linear-linux-20101001.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glh_linear/rev/263308/arch/Linux/installer/glh_linear-0.0.0-linux-20120810.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -843,6 +843,42 @@
           </map>
         </map>
       </map>
+      <key>gperftools</key>
+      <map>
+        <key>license</key>
+        <string>bsd</string>
+        <key>license_file</key>
+        <string>LICENSES/gperftools.txt</string>
+        <key>name</key>
+        <string>gperftools</string>
+        <key>platforms</key>
+        <map>
+          <key>linux</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>8aedfdcf670348c18a9991ae1b384a61</string>
+              <key>url</key>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/Linux/installer/gperftools-2.0-linux-20120727.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>linux</string>
+          </map>
+          <key>windows</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>f62841804acb91e1309603a84f3f0ce8</string>
+              <key>url</key>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/CYGWIN/installer/gperftools-2.0-windows-20120727.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows</string>
+          </map>
+        </map>
+      </map>
       <key>gstreamer</key>
       <map>
         <key>license</key>
@@ -1239,6 +1275,32 @@
           </map>
         </map>
       </map>
+      <key>llappearanceutility-source</key>
+      <map>
+        <key>license</key>
+        <string>TEMPORARY</string>
+        <key>license_file</key>
+        <string>LICENSES/llappearanceutility.txt</string>
+        <key>name</key>
+        <string>llappearanceutility-source</string>
+        <key>platforms</key>
+        <map>
+          <key>linux</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>5bc44db15eb3cca021382e40e04a9a38</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llappearanceutility-source/rev/271972/arch/Linux/installer/llappearanceutility_source-0.1-linux-20130315.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>linux</string>
+          </map>
+        </map>
+        <key>version</key>
+        <string>0.1</string>
+      </map>
       <key>llphysicsextensions_source</key>
       <map>
         <key>license</key>
@@ -1268,9 +1330,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b706fdeed4ce2182d434043dc33d9d1d</string>
+              <string>a6856b4d58a3b71321acad7e1fa9c8d4</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source/rev/263415/arch/Linux/installer/llphysicsextensions_source-0.3-linux-20120814.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source/rev/265749/arch/Linux/installer/llphysicsextensions_source-0.3-linux-20121011.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -1779,42 +1841,6 @@
           </map>
         </map>
       </map>
-      <key>tcmalloc</key>
-      <map>
-        <key>license</key>
-        <string>bsd</string>
-        <key>license_file</key>
-        <string>LICENSES/google-perftools.txt</string>
-        <key>name</key>
-        <string>tcmalloc</string>
-        <key>platforms</key>
-        <map>
-          <key>linux</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>8aedfdcf670348c18a9991ae1b384a61</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/Linux/installer/gperftools-2.0-linux-20120727.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>linux</string>
-          </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>f62841804acb91e1309603a84f3f0ce8</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/CYGWIN/installer/gperftools-2.0-windows-20120727.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
-        </map>
-      </map>
       <key>tut</key>
       <map>
         <key>license</key>
diff --git a/build.sh b/build.sh
index 15f0463aff43eb5d526d8e94bc9a6647b7aba9d6..964f9ef0a60a5de2b8bfe95630ba4b23ceeb1073 100755
--- a/build.sh
+++ b/build.sh
@@ -113,11 +113,23 @@ build()
     check_for "Before 'autobuild build'" ${build_dir}/packages/dictionaries
 
     "$AUTOBUILD" build --no-configure -c $variant
-    viewer_build_ok=$?
+    build_ok=$?
     end_section "Viewer$variant"
+
+    # Run build extensions
+    if [ $build_ok -eq 0 -a -d ${build_dir}/packages/build-extensions ]; then
+        for extension in ${build_dir}/packages/build-extensions/*.sh; do
+            . $extension
+            if [ $build_ok -ne 0 ]; then
+                break
+            fi
+        done
+    fi
+
+    # *TODO: Make this a build extension.
     package_llphysicsextensions_tpv
     tpvlib_build_ok=$?
-    if [ $viewer_build_ok -eq 0 -a $tpvlib_build_ok -eq 0 ]
+    if [ $build_ok -eq 0 -a $tpvlib_build_ok -eq 0 ]
     then
       echo true >"$build_dir"/build_ok
     else
@@ -292,12 +304,86 @@ then
   end_section WaitParallel
 fi
 
+# build debian package
+if [ "$arch" == "Linux" ]
+then
+  if $succeeded
+  then
+    if $build_viewer_deb && [ "$last_built_variant" == "Release" ]
+    then
+      begin_section "Build Viewer Debian Package"
+      local have_private_repo=false
+      # mangle the changelog
+      dch --force-bad-version \
+          --distribution unstable \
+          --newversion "${VIEWER_VERSION}" \
+          "Automated build #$build_id, repository $branch revision $revision." \
+          >> "$build_log" 2>&1
+
+      # build the debian package
+      $pkg_default_debuild_command  >>"$build_log" 2>&1 || record_failure "\"$pkg_default_debuild_command\" failed."
+
+      # Unmangle the changelog file
+      hg revert debian/changelog
+
+      end_section "Build Viewer Debian Package"
+
+      # Run debian extensions
+      if [ -d ${build_dir}/packages/debian-extensions ]; then
+          for extension in ${build_dir}/packages/debian-extensions/*.sh; do
+              . $extension
+          done
+      fi
+      # Move any .deb results.
+      mkdir -p ../packages_public
+      mkdir -p ../packages_private
+      mv ${build_dir}/packages/*.deb ../packages_public 2>/dev/null || true
+      mv ${build_dir}/packages/packages_private/*.deb ../packages_private 2>/dev/null || true
+
+      # upload debian package and create repository
+      begin_section "Upload Debian Repository"
+      for deb_file in `/bin/ls ../packages_public/*.deb ../*.deb 2>/dev/null`; do
+        upload_item debian $deb_file binary/octet-stream
+      done
+      for deb_file in `/bin/ls ../packages_private/*.deb 2>/dev/null`; do
+        upload_item debian_private $deb_file binary/octet-stream
+        have_private_repo=true
+      done
+
+      create_deb_repo
+
+      # Rename the local debian_repo* directories so that the master buildscript
+      # doesn't make a remote repo again.
+      for debian_repo_type in debian_repo debian_repo_private; do
+        if [ -d "$build_log_dir/$debian_repo_type" ]; then
+          mv $build_log_dir/$debian_repo_type $build_log_dir/${debian_repo_type}_pushed
+        fi
+      done
+
+      if [ $have_private_repo = true ]; then
+        eval "$python_command \"$redirect\" '\${private_S3PROXY_URL}${S3PREFIX}repo/$repo/rev/$revision/index.html'"\
+            >"$build_log_dir/private.html" || fatal generating redirect
+        upload_item global_redirect "$build_log_dir/private.html" text/html
+        
+      fi
+
+      end_section "Upload Debian Repository"
+      
+    else
+      echo skipping debian build
+    fi
+  else
+    echo skipping debian build due to failed build.
+  fi
+fi
+
+
 # check status and upload results to S3
 if $succeeded
 then
   if $build_viewer
   then
-    begin_section Upload
+    begin_section Upload Installer
     # Upload installer - note that ONLY THE FIRST ITEM uploaded as "installer"
     # will appear in the version manager.
     package=$(installer_$arch)
@@ -317,8 +403,9 @@ then
         do
           upload_item symbolfile "$build_dir/$symbolfile" binary/octet-stream
         done
-        
+
         # Upload the llphysicsextensions_tpv package, if one was produced
+        # *TODO: Make this an upload-extension
         if [ -r "$build_dir/llphysicsextensions_package" ]
         then
             llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
@@ -332,15 +419,22 @@ then
         ;;
       esac
 
+      # Run upload extensions
+      if [ -d ${build_dir}/packages/upload-extensions ]; then
+          for extension in ${build_dir}/packages/upload-extensions/*.sh; do
+              . $extension
+          done
+      fi
+
       # Upload stub installers
       upload_stub_installers "$build_dir_stubs"
     fi
-    end_section Upload
+    end_section Upload Installer
   else
-    echo skipping viewer
+    echo skipping upload of installer
   fi
 else
-  echo skipping upload of build results due to failed build.
+  echo skipping upload of installer due to failed build.
 fi
 
 # The branch independent build.sh script invoking this script will finish processing
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000000000000000000000000000000000000..ce54b54c6f107de19d88453456b9a243b6559ed4
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,18 @@
+secondlife-viewer (0.3) unstable; urgency=low
+
+  * Initial debian configuration
+
+ -- Don Kjer <don@lindenlab.com>  Wed, 04 Jul 2012 00:43:03 +0000
+
+secondlife-viewer (0.2) unstable; urgency=low
+
+  * Adding default LSB headers for squeeze
+
+ -- Tyler Kohler <tyler@lindenlab.com>  Thu, 24 Mar 2011 09:43:36 -0700
+
+secondlife-viewer (0.1) unstable; urgency=low
+
+  * Cloned from debian package skeleton.
+
+ -- Lex Linden <lex@lindenlab.com>  Mon, 20 Sep 2010 08:01:59 -0700
+
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000000000000000000000000000000000000..7ed6ff82de6bcc2a78243fc9c54d3ef5ac14da69
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000000000000000000000000000000000000..50b9ed9a264abf7dbf48dc789484056635f36753
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,16 @@
+Source: secondlife-viewer
+Section: unknown
+Priority: extra
+Maintainer: Don Linden <don@lindenlab.com>
+Build-Depends: debhelper (>= 5)
+Homepage: http://secondlife.com
+Standards-Version: 3.7.2
+
+Package: secondlife-viewer
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends},
+ ia32-libs,
+ ia32-libs-gtk
+Description: Second Life Viewer
+ Second Life is an online virtual world developed by Linden Lab.
+ 
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000000000000000000000000000000000000..106fa3802f1b7d6b7550167cb8d928ef098ee197
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,32 @@
+Second Life Viewer Copyright: 2000-2012 Linden Research, Inc.
+
+License:
+
+3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
+APR Copyright (C) 2011 The Apache Software Foundation
+Collada DOM Copyright 2006 Sony Computer Entertainment Inc.
+cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
+DBus/dbus-glib Copyright (C) 2002, 2003  CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
+expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
+GL Copyright (C) 1999-2004 Brian Paul.
+GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
+google-perftools Copyright (c) 2005, Google Inc.
+Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
+jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
+jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
+ogg/vorbis Copyright (C) 2002, Xiphophorus
+OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.
+PCRE Copyright (c) 1997-2012 University of Cambridge
+SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
+SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
+zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler.
+
+Second Life Viewer uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details.
+
+This software contains source code provided by NVIDIA Corporation.
+
+All rights reserved.  See licenses.txt for details.
+
+Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
diff --git a/debian/postinst b/debian/postinst
new file mode 100644
index 0000000000000000000000000000000000000000..2c4f8ea8588b62b63d5ba8106d8e18964903307e
--- /dev/null
+++ b/debian/postinst
@@ -0,0 +1,43 @@
+#!/bin/sh
+# postinst script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+#          <new-version>
+#        * <postinst> `abort-remove'
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    configure)
+    ;;
+
+    abort-upgrade|abort-remove|abort-deconfigure)
+    ;;
+
+    *)
+        echo "postinst called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/postrm b/debian/postrm
new file mode 100644
index 0000000000000000000000000000000000000000..a575936ab04060765153060adf711ba28bb02890
--- /dev/null
+++ b/debian/postrm
@@ -0,0 +1,41 @@
+#!/bin/sh
+# postrm script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postrm> `remove'
+#        * <postrm> `purge'
+#        * <old-postrm> `upgrade' <new-version>
+#        * <new-postrm> `failed-upgrade' <old-version>
+#        * <new-postrm> `abort-install'
+#        * <new-postrm> `abort-install' <old-version>
+#        * <new-postrm> `abort-upgrade' <old-version>
+#        * <disappearer's-postrm> `disappear' <overwriter>
+#          <overwriter-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+    ;;
+
+    *)
+        echo "postrm called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/preinst b/debian/preinst
new file mode 100644
index 0000000000000000000000000000000000000000..f62243440f6cf253026d0926576fa0c99535e524
--- /dev/null
+++ b/debian/preinst
@@ -0,0 +1,39 @@
+#!/bin/sh
+# preinst script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <new-preinst> `install'
+#        * <new-preinst> `install' <old-version>
+#        * <new-preinst> `upgrade' <old-version>
+#        * <old-preinst> `abort-upgrade' <new-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    install|upgrade)
+    ;;
+
+    abort-upgrade)
+    ;;
+
+    *)
+        echo "preinst called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/prerm b/debian/prerm
new file mode 100644
index 0000000000000000000000000000000000000000..405b8f9c87bcfe6e3bcca23b7eb192a9dd6ee0e2
--- /dev/null
+++ b/debian/prerm
@@ -0,0 +1,42 @@
+#!/bin/sh
+# prerm script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <prerm> `remove'
+#        * <old-prerm> `upgrade' <new-version>
+#        * <new-prerm> `failed-upgrade' <old-version>
+#        * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
+#        * <deconfigured's-prerm> `deconfigure' `in-favour'
+#          <package-being-installed> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    remove|upgrade|deconfigure)
+    ;;
+
+    failed-upgrade)
+    ;;
+
+    *)
+        echo "prerm called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/rules b/debian/rules
new file mode 100644
index 0000000000000000000000000000000000000000..305fc58bb401b7ca74dbcabb111b80ea4f925530
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,118 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+BASEDIR=opt/linden
+
+VIEWER_PKG=secondlife-viewer
+VIEWER_PACKAGEDIR=build-linux-i686/newview/packaged
+VIEWER_DESTDIR=$(CURDIR)/debian/$(VIEWER_PKG)
+VIEWER_VERSION:=$(shell dpkg-parsechangelog | grep ^Version | sed 's/^Version: //')
+VIEWER_INSTALLDIR:=$(BASEDIR)/viewer/SecondLife-i686-$(VIEWER_VERSION)
+
+configure: configure-stamp
+configure-stamp:
+	dh_testdir
+	# Add here commands to configure the package.
+
+	touch configure-stamp
+
+build: build-stamp
+
+build-stamp: configure-stamp 
+	dh_testdir
+
+	# Add here commands to compile the package.
+	#$(MAKE)
+	#docbook-to-man debian/secondlife-viewer.sgml > secondlife-viewer.1
+
+	touch $@
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp configure-stamp
+
+	# Add here commands to clean up after the build process.
+	#-$(MAKE) clean
+
+	dh_clean 
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k 
+	dh_installdirs
+
+	# Add here commands to install the package into debian/secondlife-viewer.
+	for file in $$(find $(VIEWER_PACKAGEDIR) -type f -o -type l | sed 's~$(VIEWER_PACKAGEDIR)/~~'); do \
+		# create containing directory \
+		install -v -m 755 -o root -g root -d "$$(dirname "$(VIEWER_DESTDIR)/$(VIEWER_INSTALLDIR)/$$file")"; \
+		PERM=644; \
+		if [ -x "$(VIEWER_PACKAGEDIR)/$$file" ]; then \
+			PERM=755; \
+		fi; \
+		if [ -L "$(VIEWER_PACKAGEDIR)/$$file" ]; then \
+			REAL="$$( readlink -f $(VIEWER_PACKAGEDIR)/$$file )"; \
+			RELATIVE="$$( echo $$REAL | sed 's~$(CURDIR)/$(VIEWER_PACKAGEDIR)/~~' )"; \
+			echo dh_link -p $(VIEWER_PKG) "$(VIEWER_INSTALLDIR)/$$RELATIVE" "$(VIEWER_INSTALLDIR)/$$file" ; \
+			dh_link -p $(VIEWER_PKG) "$(VIEWER_INSTALLDIR)/$$RELATIVE" "$(VIEWER_INSTALLDIR)/$$file" ; \
+		else \
+			install -v -m $$PERM -o root -g root "$(VIEWER_PACKAGEDIR)/$$file" "$(VIEWER_DESTDIR)/$(VIEWER_INSTALLDIR)/$$file"; \
+		fi; \
+	done
+	dh_link -p $(VIEWER_PKG) /$(VIEWER_INSTALLDIR)/secondlife /usr/bin/secondlife
+	dh_link -p $(VIEWER_PKG) $(BASEDIR)/viewer/SecondLife-i686-$(VIEWER_VERSION) $(BASEDIR)/viewer/SecondLife
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+	dh_testdir
+	dh_testroot
+	dh_installchangelogs 
+	dh_installdocs
+	dh_installexamples
+#	dh_install
+#	dh_installmenu
+#	dh_installdebconf	
+#	dh_installlogrotate
+#	dh_installemacsen
+#	dh_installpam
+#	dh_installmime
+#	dh_python
+
+# To add an init script, uncomment this line and edit debian/init.d and 
+# customize debian/secondlife-viewer.default to suit your needs.
+#	dh_installinit
+
+# To add cron jobs, uncomment this line and make a crontab file named 
+# debian/cron.d, and it will be installed in /etc/cron.d/
+#	dh_installcron
+
+#	dh_installinfo
+	dh_installman
+	dh_link
+#	dh_strip
+	dh_compress
+#	dh_fixperms
+#	dh_perl
+#	dh_makeshlibs
+	dh_installdeb
+#	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 001bb4b9359aa6e930c9b9158e0cf27a1da1d758..0a54163644cc09fdf8d43060fafa940e91992d67 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -41,6 +41,7 @@ endif ("${CMAKE_SOURCE_DIR}/../autobuild.xml" IS_NEWER_THAN "${CMAKE_BINARY_DIR}
 add_subdirectory(cmake)
 
 add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
+add_subdirectory(${LIBS_OPEN_PREFIX}llappearance)
 add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)
 add_subdirectory(${LIBS_OPEN_PREFIX}llcommon)
 add_subdirectory(${LIBS_OPEN_PREFIX}llcorehttp)
@@ -63,71 +64,53 @@ if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
 endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
 
 add_custom_target(viewer)
-if (VIEWER)
-  add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
-  add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
-  add_subdirectory(${LIBS_OPEN_PREFIX}llui)
-  add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
-
-  # Legacy C++ tests. Build always, run if LL_TESTS is true.
-  add_subdirectory(${VIEWER_PREFIX}test)
-
-  # viewer media plugins
-  add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
-
-  # llplugin testbed code (is this the right way to include it?)
-  if (LL_TESTS AND NOT LINUX)
-    add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
-  endif (LL_TESTS AND NOT LINUX)
-
-  if (LINUX)
-    add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
-    add_dependencies(viewer linux-crash-logger-strip-target)
-  elseif (DARWIN)
-    add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
-    add_subdirectory(${VIEWER_PREFIX}mac_updater)
-    add_dependencies(viewer mac-updater mac-crash-logger)
-  elseif (WINDOWS)
-    add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
-    # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
-    if (EXISTS ${VIEWER_DIR}win_setup)
-      add_subdirectory(${VIEWER_DIR}win_setup)
-    endif (EXISTS ${VIEWER_DIR}win_setup)
-    add_subdirectory(${VIEWER_PREFIX}win_updater)
-    # add_dependencies(viewer windows-updater windows-setup windows-crash-logger)
-    add_dependencies(viewer windows-updater windows-crash-logger)
-  elseif (SOLARIS)
-    add_subdirectory(solaris_crash_logger)
-    add_dependencies(viewer solaris-crash-logger)
-  endif (LINUX)
-
-  add_subdirectory(${VIEWER_PREFIX}newview)
-  add_dependencies(viewer secondlife-bin)
-endif (VIEWER)
-
-# Linux builds the viewer and server in 2 separate projects
-# In order for build server to work on linux, 
-# the viewer project needs a server target.
-# This is not true for mac and windows.
-if (LINUX) 
-  add_custom_target(server)
+add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
+add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
+add_subdirectory(${LIBS_OPEN_PREFIX}llui)
+add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
+
+# Legacy C++ tests. Build always, run if LL_TESTS is true.
+add_subdirectory(${VIEWER_PREFIX}test)
+
+# viewer media plugins
+add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
+
+# llplugin testbed code (is this the right way to include it?)
+if (LL_TESTS AND NOT LINUX)
+  add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
+endif (LL_TESTS AND NOT LINUX)
+
+if (LINUX)
+  add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
+  add_subdirectory(${VIEWER_PREFIX}linux_updater)
+  if (INSTALL_PROPRIETARY)
+      include(LLAppearanceUtility)
+      add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
+  endif (INSTALL_PROPRIETARY)
+  add_dependencies(viewer linux-crash-logger-strip-target linux-updater)
+elseif (DARWIN)
+  add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
+  add_subdirectory(${VIEWER_PREFIX}mac_updater)
+  add_dependencies(viewer mac-updater mac-crash-logger)
+elseif (WINDOWS)
+  add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
+  # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
+  if (EXISTS ${VIEWER_DIR}win_setup)
+    add_subdirectory(${VIEWER_DIR}win_setup)
+  endif (EXISTS ${VIEWER_DIR}win_setup)
+  add_subdirectory(${VIEWER_PREFIX}win_updater)
+  # add_dependencies(viewer windows-updater windows-setup windows-crash-logger)
+  add_dependencies(viewer windows-updater windows-crash-logger)
+elseif (SOLARIS)
+  add_subdirectory(solaris_crash_logger)
+  add_dependencies(viewer solaris-crash-logger)
 endif (LINUX)
-if (SERVER)
-  if (NOT LINUX)
-    add_custom_target(server)
-  endif (NOT LINUX)
-  include(${SERVER_PREFIX}Server.cmake)
-endif (SERVER)
-
-# Windows builds include tools like VFS tool
-if (SERVER)
-  if (WINDOWS)
-    add_subdirectory(${SERVER_PREFIX}tools)
-  endif (WINDOWS)
-endif (SERVER)
+
+add_subdirectory(${VIEWER_PREFIX}newview)
+add_dependencies(viewer secondlife-bin)
 
 if (LL_TESTS)
-  # Define after the custom viewer and server targets are created so
+  # Define after the custom targets are created so
   # individual apps can add themselves as dependencies
   add_subdirectory(${INTEGRATION_TESTS_PREFIX}integration_tests)
 endif (LL_TESTS)
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 452fd5f35602e259915acab77a068d1bd6e16be4..fb5c759493672cfd968cb3a0535c01f59df91d80 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -2,6 +2,9 @@
 #
 # Compilation options shared by all Second Life components.
 
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
 include(Variables)
 
 # Portable compilation flags.
@@ -150,41 +153,21 @@ if (LINUX)
       -pthread
       )
 
-  if (SERVER)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-60")
-    if (EXISTS /etc/debian_version)
-      FILE(READ /etc/debian_version DEBIAN_VERSION)
-    else (EXISTS /etc/debian_version)
-      set(DEBIAN_VERSION "")
-    endif (EXISTS /etc/debian_version)
-
-    if (NOT DEBIAN_VERSION STREQUAL "3.1")
-      add_definitions(-DCTYPE_WORKAROUND)
-    endif (NOT DEBIAN_VERSION STREQUAL "3.1")
-
-    if (EXISTS /usr/lib/mysql4/mysql)
-      link_directories(/usr/lib/mysql4/mysql)
-    endif (EXISTS /usr/lib/mysql4/mysql)
-
-  endif (SERVER)
-
-  if (VIEWER)
-    add_definitions(-DAPPID=secondlife)
-    add_definitions(-fvisibility=hidden)
-    # don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work.  Sigh!  The viewer doesn't need to catch SIGCHLD anyway.
-    add_definitions(-DLL_IGNORE_SIGCHLD)
-    if (WORD_SIZE EQUAL 32)
-      add_definitions(-march=pentium4)
-    endif (WORD_SIZE EQUAL 32)
-    add_definitions(-mfpmath=sse)
-    #add_definitions(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2
-    if (NOT STANDALONE)
-      # this stops us requiring a really recent glibc at runtime
-      add_definitions(-fno-stack-protector)
-      # linking can be very memory-hungry, especially the final viewer link
-      set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory")
-    endif (NOT STANDALONE)
-  endif (VIEWER)
+  add_definitions(-DAPPID=secondlife)
+  add_definitions(-fvisibility=hidden)
+  # don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work.  Sigh!  The viewer doesn't need to catch SIGCHLD anyway.
+  add_definitions(-DLL_IGNORE_SIGCHLD)
+  if (WORD_SIZE EQUAL 32)
+    add_definitions(-march=pentium4)
+  endif (WORD_SIZE EQUAL 32)
+  add_definitions(-mfpmath=sse)
+  #add_definitions(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2
+  if (NOT STANDALONE)
+    # this stops us requiring a really recent glibc at runtime
+    add_definitions(-fno-stack-protector)
+    # linking can be very memory-hungry, especially the final viewer link
+    set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory")
+  endif (NOT STANDALONE)
 
   set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
   set(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}")
@@ -198,7 +181,7 @@ if (DARWIN)
   # ucontext_t struct when _XOPEN_SOURCE is not defined (rdar://problem/5578699 ).
   # As a workaround, define _XOPEN_SOURCE before including ucontext.h.
   add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE)
-  set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
+  set(CMAKE_CXX_LINK_FLAGS "-Wl,-no_compact_unwind -Wl,-headerpad_max_install_names,-search_paths_first")
   set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
   set(DARWIN_extra_cstar_flags "-mlong-branch -g")
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags}")
@@ -254,6 +237,4 @@ else (STANDALONE)
       )
 endif (STANDALONE)
 
-if(SERVER)
-  include_directories(${LIBS_PREBUILT_DIR}/include/havok)
-endif(SERVER)
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake
index daafa00fe27ef5e8d7093a4661683bf915e597fe..492ba2adea1249606fe704ad404f42b791e5a80e 100644
--- a/indra/cmake/APR.cmake
+++ b/indra/cmake/APR.cmake
@@ -49,9 +49,7 @@ else (STANDALONE)
   set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/apr-1)
 
   if (LINUX)
-    if (VIEWER)
-      list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)
-    endif (VIEWER)
+    list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)
     list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} rt)
   endif (LINUX)
 endif (STANDALONE)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index 569034a6fb97d615d60af6ed7a17aae61312cebf..a21fa9095073456a2dad5a9ad18bf07e44729c82 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -14,48 +14,66 @@ set(cmake_SOURCE_FILES
     Boost.cmake
     BuildVersion.cmake
     CARes.cmake
-    CURL.cmake
     CMakeCopyIfDifferent.cmake
+    ConfigurePkgConfig.cmake
+    CURL.cmake
     Copy3rdPartyLibs.cmake
-    CSharpMacros.cmake
     DBusGlib.cmake
+    DeploySharedLibs.cmake
     DirectX.cmake
+    DragDrop.cmake
     EXPAT.cmake
+    ExamplePlugin.cmake
+    FMOD.cmake
     FindAPR.cmake
+    FindAutobuild.cmake
     FindBerkeleyDB.cmake
     FindCARes.cmake
-    FindELFIO.cmake
     FindFMOD.cmake
+    FindGLH.cmake
+    FindGoogleBreakpad.cmake
     FindGooglePerfTools.cmake
-    FindMono.cmake
-    FindMySQL.cmake
+    FindHUNSPELL.cmake
+    FindJsonCpp.cmake
+    FindNDOF.cmake
     FindOpenJPEG.cmake
+    FindSCP.cmake
     FindXmlRpcEpi.cmake
     FindZLIB.cmake
-    FMOD.cmake
     FreeType.cmake
+    GLEXT.cmake
+    GLH.cmake
     GLOD.cmake
     GStreamer010Plugin.cmake
+    GetPrerequisites_2_8.cmake
+    Glui.cmake
+    Glut.cmake
+    GoogleBreakpad.cmake
+    GoogleMock.cmake
     GooglePerfTools.cmake
+    Havok.cmake
     Hunspell.cmake
     JPEG.cmake
+    JsonCpp.cmake
     LLAddBuildTest.cmake
+    LLAppearance.cmake
+    LLAppearanceUtility.cmake
     LLAudio.cmake
     LLCharacter.cmake
     LLCommon.cmake
     LLCrashLogger.cmake
-    LLDatabase.cmake
     LLImage.cmake
     LLImageJ2COJ.cmake
     LLInventory.cmake
     LLKDU.cmake
+    LLLogin.cmake
     LLMath.cmake
     LLMessage.cmake
+    LLPhysicsExtensions.cmake
     LLPlugin.cmake
     LLPrimitive.cmake
-    LLPhysicsExtensions.cmake
     LLRender.cmake
-    LLScene.cmake
+    LLSharedLibs.cmake
     LLTestCommand.cmake
     LLUI.cmake
     LLVFS.cmake
@@ -63,21 +81,26 @@ set(cmake_SOURCE_FILES
     LLXML.cmake
     LScript.cmake
     Linking.cmake
-    MonoEmbed.cmake
-    MySQL.cmake
+    MediaPluginBase.cmake
     NDOF.cmake
     OPENAL.cmake
     OpenGL.cmake
     OpenJPEG.cmake
     OpenSSL.cmake
     PNG.cmake
-    Python.cmake
+    PluginAPI.cmake
     Prebuilt.cmake
+    PulseAudio.cmake
+    Python.cmake
+    QuickTimePlugin.cmake
     TemplateCheck.cmake
     Tut.cmake
     UI.cmake
     UnixInstall.cmake
     Variables.cmake
+    ViewerMiscLibs.cmake
+    VisualLeakDetector.cmake
+    WebKitLibPlugin.cmake
     XmlRpcEpi.cmake
     ZLIB.cmake
     )
@@ -88,10 +111,6 @@ set(master_SOURCE_FILES
     ../CMakeLists.txt
     )
 
-if (SERVER)
-  list(APPEND master_SOURCE_FILES ../Server.cmake)
-endif (SERVER)
-
 source_group("Master Rules" FILES ${master_SOURCE_FILES})
 
 set_source_files_properties(${cmake_SOURCE_FILES} ${master_SOURCE_FILES}
diff --git a/indra/cmake/CSharpMacros.cmake b/indra/cmake/CSharpMacros.cmake
deleted file mode 100644
index a4dd81504304db576763d0660552073da88fca3e..0000000000000000000000000000000000000000
--- a/indra/cmake/CSharpMacros.cmake
+++ /dev/null
@@ -1,142 +0,0 @@
-# - This is a support module for easy Mono/C# handling with CMake
-# It defines the following macros:
-#
-# ADD_CS_LIBRARY (<target> <source>)
-# ADD_CS_EXECUTABLE (<target> <source>)
-# INSTALL_GAC (<target>)
-#
-# Note that the order of the arguments is important.
-#
-# You can optionally set the variable CS_FLAGS to tell the macros whether
-# to pass additional flags to the compiler. This is particularly useful to
-# set assembly references, unsafe code, etc... These flags are always reset
-# after the target was added so you don't have to care about that.
-#
-# copyright (c) 2007 Arno Rehn arno@arnorehn.de
-#
-# Redistribution and use is allowed according to the terms of the GPL license.
-
-
-# ----- support macros -----
-MACRO(GET_CS_LIBRARY_TARGET_DIR)
-        IF (NOT LIBRARY_OUTPUT_PATH)
-                SET(CS_LIBRARY_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
-        ELSE (NOT LIBRARY_OUTPUT_PATH)
-                SET(CS_LIBRARY_TARGET_DIR ${LIBRARY_OUTPUT_PATH})
-        ENDIF (NOT LIBRARY_OUTPUT_PATH)
-ENDMACRO(GET_CS_LIBRARY_TARGET_DIR)
-
-MACRO(GET_CS_EXECUTABLE_TARGET_DIR)
-        IF (NOT EXECUTABLE_OUTPUT_PATH)
-                SET(CS_EXECUTABLE_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
-        ELSE (NOT EXECUTABLE_OUTPUT_PATH)
-                SET(CS_EXECUTABLE_TARGET_DIR ${EXECUTABLE_OUTPUT_PATH})
-        ENDIF (NOT EXECUTABLE_OUTPUT_PATH)
-ENDMACRO(GET_CS_EXECUTABLE_TARGET_DIR)
-
-MACRO(MAKE_PROPER_FILE_LIST)
-        FOREACH(file ${ARGN})
-                # first assume it's a relative path
-                FILE(GLOB globbed ${CMAKE_CURRENT_SOURCE_DIR}/${file})
-                IF(globbed)
-                        FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${file} native)
-                ELSE(globbed)
-                        FILE(TO_NATIVE_PATH ${file} native)
-                ENDIF(globbed)
-                SET(proper_file_list ${proper_file_list} ${native})
-                SET(native "")
-        ENDFOREACH(file)
-ENDMACRO(MAKE_PROPER_FILE_LIST)
-# ----- end support macros -----
-
-MACRO(ADD_CS_LIBRARY target)
-        GET_CS_LIBRARY_TARGET_DIR()
-        
-        SET(target_DLL "${CS_LIBRARY_TARGET_DIR}/${target}.dll")
-        MAKE_PROPER_FILE_LIST(${ARGN})
-        FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_DLL})
-        
-        SET(target_KEY "${CMAKE_CURRENT_SOURCE_DIR}/${target}.key")
-        SET(target_CS_FLAGS "${CS_FLAGS}")
-        IF(${target}_CS_FLAGS)
-                LIST(APPEND target_CS_FLAGS ${${target}_CS_FLAGS})
-        ENDIF(${target}_CS_FLAGS)
-        IF(EXISTS ${target_KEY})
-                LIST(APPEND target_CS_FLAGS -keyfile:${target_KEY})
-        ENDIF(EXISTS ${target_KEY})
-
-        FOREACH(ref ${${target}_REFS})
-                SET(ref_DLL ${CMAKE_CURRENT_BINARY_DIR}/${ref}.dll)
-                IF(EXISTS ${ref_DLL})
-                        LIST(APPEND target_CS_FLAGS -r:${ref_DLL})
-                ELSE(EXISTS ${ref_DLL})
-                        LIST(APPEND target_CS_FLAGS -r:${ref})
-                ENDIF(EXISTS ${ref_DLL})
-        ENDFOREACH(ref ${${target}_REFS})
-
-        ADD_CUSTOM_COMMAND (OUTPUT ${target_DLL}
-                COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_DLL} -target:library ${proper_file_list}
-                MAIN_DEPENDENCY ${proper_file_list}
-                DEPENDS ${ARGN}
-                COMMENT "Building ${relative_path}")
-        ADD_CUSTOM_TARGET (${target} ALL DEPENDS ${target_DLL})
-
-        FOREACH(ref ${${target}_REFS})
-                GET_TARGET_PROPERTY(is_target ${ref} TYPE)
-                IF(is_target)
-                        ADD_DEPENDENCIES(${target} ${ref})
-                ENDIF(is_target)
-        ENDFOREACH(ref ${${target}_REFS})
-
-        SET(relative_path "")
-        SET(proper_file_list "")
-ENDMACRO(ADD_CS_LIBRARY)
-
-MACRO(ADD_CS_EXECUTABLE target)
-        GET_CS_EXECUTABLE_TARGET_DIR()
-        
-        # Seems like cmake doesn't like the ".exe" ending for custom commands.
-        # If we call it ${target}.exe, 'make' will later complain about a missing rule.
-        # Create a fake target instead.
-        SET(target_EXE "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe")
-        SET(target_TOUCH "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe-built")
-        GET_DIRECTORY_PROPERTY(clean ADDITIONAL_MAKE_CLEAN_FILES)
-        LIST(APPEND clean ${target}.exe)
-        SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${clean}")
-        MAKE_PROPER_FILE_LIST(${ARGN})
-        FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_EXE})
-        SET(target_CS_FLAGS "${CS_FLAGS}")
-        
-        FOREACH(ref ${${target}_REFS})
-                SET(ref_DLL ${CMAKE_CURRENT_SOURCE_DIR}/${ref}.dll)
-                IF(EXISTS ${ref_DLL})
-                        LIST(APPEND target_CS_FLAGS -r:${ref_DLL})
-                ELSE(EXISTS ${ref_DLL})
-                        LIST(APPEND target_CS_FLAGS -r:${ref})
-                ENDIF(EXISTS ${ref_DLL})
-        ENDFOREACH(ref ${${target}_REFS})
-
-        ADD_CUSTOM_COMMAND (OUTPUT "${target_TOUCH}"
-                COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_EXE} ${proper_file_list}
-                COMMAND ${CMAKE_COMMAND} -E touch ${target_TOUCH}
-                MAIN_DEPENDENCY ${ARGN}
-                DEPENDS ${ARGN}
-                COMMENT "Building ${relative_path}")
-        ADD_CUSTOM_TARGET ("${target}" ALL DEPENDS "${target_TOUCH}")
-
-        FOREACH(ref ${${target}_REFS})
-                GET_TARGET_PROPERTY(is_target ${ref} TYPE)
-                IF(is_target)
-                        ADD_DEPENDENCIES(${target} ${ref})
-                ENDIF(is_target)
-        ENDFOREACH(ref ${${target}_REFS})
-
-        SET(relative_path "")
-        SET(proper_file_list "")
-ENDMACRO(ADD_CS_EXECUTABLE)
-
-MACRO(INSTALL_GAC target)
-        GET_CS_LIBRARY_TARGET_DIR()
-        
-        INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${GACUTIL_EXECUTABLE} -i ${CS_LIBRARY_TARGET_DIR}/${target}.dll -package 2.0)")
-ENDMACRO(INSTALL_GAC target)
diff --git a/indra/cmake/ConfigurePkgConfig.cmake b/indra/cmake/ConfigurePkgConfig.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..82ee3e7a5b54d107e852ea17bab037c76c3d9c16
--- /dev/null
+++ b/indra/cmake/ConfigurePkgConfig.cmake
@@ -0,0 +1,74 @@
+# -*- cmake -*-
+
+SET(DEBUG_PKG_CONFIG "YES")
+
+# Don't change this if manually set by user.
+IF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
+
+  # Guess at architecture-specific system library paths.
+  if (WORD_SIZE EQUAL 32)
+    SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib32 /usr/lib)
+    SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib32 /usr/local/lib)
+    SET(PKG_CONFIG_MULTI_GUESS /usr/lib/i386-linux-gnu)
+    SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/i386-linux-gnu)
+  else (WORD_SIZE EQUAL 32)
+    SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib64 /usr/lib)
+    SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib64 /usr/local/lib)
+    SET(PKG_CONFIG_MULTI_GUESS /usr/local/lib/x86_64-linux-gnu)
+    SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/x86_64-linux-gnu)
+  endif (WORD_SIZE EQUAL 32)
+  
+  # Use DPKG architecture, if available.
+  IF (${DPKG_ARCH})
+    SET(PKG_CONFIG_MULTI_GUESS /usr/lib/${DPKG_ARCH})
+    SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usrlocal/lib/${DPKG_ARCH})
+  ENDIF (${DPKG_ARCH})
+  
+  # Explicitly include anything listed in PKG_CONFIG_PATH
+  string(REPLACE ":" ";" PKG_CONFIG_PATH_LIST "$ENV{PKG_CONFIG_PATH}")
+  FOREACH(PKG_CONFIG_DIR ${PKG_CONFIG_PATH_LIST})
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_DIR}/pkgconfig")
+  ENDFOREACH(PKG_CONFIG_DIR)
+
+  # Look for valid pkgconfig directories.
+  FIND_PATH(PKG_CONFIG_ENV pkgconfig ENV LD_LIBRARY_PATH)
+  FIND_PATH(PKG_CONFIG_MULTI pkgconfig HINT ${PKG_CONFIG_MULTI_GUESS})
+  FIND_PATH(PKG_CONFIG_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_MULTI_LOCAL_GUESS})
+  FIND_PATH(PKG_CONFIG_NO_MULTI pkgconfig HINT ${PKG_CONFIG_NO_MULTI_GUESS})
+  FIND_PATH(PKG_CONFIG_NO_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_NO_MULTI_LOCAL_GUESS})
+
+  # Add anything we found to our list.
+  IF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND) 
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_ENV}/pkgconfig")
+  ENDIF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND) 
+
+  IF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND) 
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI}/pkgconfig")
+  ENDIF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND) 
+
+  IF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND) 
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI_LOCAL}/pkgconfig")
+  ENDIF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND) 
+
+  IF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND) 
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI}/pkgconfig")
+  ENDIF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND) 
+
+  IF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND) 
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI_LOCAL}/pkgconfig")
+  ENDIF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND) 
+
+  # Also add some non-architecture specific package locations.
+  SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:/usr/share/pkgconfig:/usr/local/share/pkgconfig")
+
+  # Remove first unwanted ':'
+  string(SUBSTRING ${VALID_PKG_LIBDIRS} 1 -1 VALID_PKG_LIBDIRS)
+
+  # Set PKG_CONFIG_LIBDIR environment.
+  SET(ENV{PKG_CONFIG_LIBDIR} ${VALID_PKG_LIBDIRS})
+ENDIF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
+
+IF(DEBUG_PKG_CONFIG)
+  MESSAGE(STATUS "Using PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}")
+ENDIF(DEBUG_PKG_CONFIG)
+
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index c32e357da3dc9714fa048a03ebc8fdb0777fda30..338da4743e5252c08fe6278d5f5501894c186e76 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -266,7 +266,7 @@ elseif(LINUX)
         libdb-5.1.so
         libexpat.so
         libexpat.so.1
-        libglod.so
+        libGLOD.so
         libgmock_main.so
         libgmock.so.0
         libgmodule-2.0.so
diff --git a/indra/cmake/CopyBackToSource.cmake b/indra/cmake/CopyBackToSource.cmake
deleted file mode 100644
index d217df9aecf1f05284525cbad1d3132af94a1b88..0000000000000000000000000000000000000000
--- a/indra/cmake/CopyBackToSource.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- cmake -*-
-# Copies a binary back to the source directory
-
-MACRO(COPY_BACK_TO_SOURCE target)
-   GET_TARGET_PROPERTY(FROM ${target} LOCATION)
-   SET(TO ${CMAKE_CURRENT_SOURCE_DIR})
-   #MESSAGE("TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${FROM} ${TO}")
-   ADD_CUSTOM_COMMAND(
-        TARGET ${target} POST_BUILD
-        COMMAND ${CMAKE_COMMAND} -E copy ${FROM} ${TO}
-        DEPENDS ${FROM}
-        COMMENT "Copying ${target} to ${CMAKE_CURRENT_BINARY_DIR}"
-        )
-ENDMACRO(COPY_BACK_TO_SOURCE)
-
-
diff --git a/indra/cmake/DirectX.cmake b/indra/cmake/DirectX.cmake
index b2a18805d478fc5cd12633a1464999d7900cda72..25163d03226dbdfba43492d921635cb82e814549 100644
--- a/indra/cmake/DirectX.cmake
+++ b/indra/cmake/DirectX.cmake
@@ -1,8 +1,9 @@
 # -*- cmake -*-
 
-if (VIEWER AND WINDOWS)
+if (WINDOWS)
   find_path(DIRECTX_INCLUDE_DIR dxdiag.h
             "$ENV{DXSDK_DIR}/Include"
+            "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Include"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Include"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Include"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Include"
@@ -25,6 +26,7 @@ if (VIEWER AND WINDOWS)
 
   find_path(DIRECTX_LIBRARY_DIR dxguid.lib
             "$ENV{DXSDK_DIR}/Lib/x86"
+            "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Lib/x86"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Lib/x86"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Lib/x86"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Lib/x86"
@@ -43,4 +45,4 @@ if (VIEWER AND WINDOWS)
     message(FATAL_ERROR "Could not find DirectX SDK Libraries")
   endif (DIRECTX_LIBRARY_DIR)
 
-endif (VIEWER AND WINDOWS)
+endif (WINDOWS)
diff --git a/indra/cmake/DragDrop.cmake b/indra/cmake/DragDrop.cmake
index c0424396e5f83109aa29b45457b03bad91289388..b70aa6b6ee8c28c3b3887ac961cbafd0227a4160 100644
--- a/indra/cmake/DragDrop.cmake
+++ b/indra/cmake/DragDrop.cmake
@@ -1,23 +1,20 @@
 # -*- cmake -*-
 
-if (VIEWER)
+set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
 
-  set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
+if (OS_DRAG_DROP)
 
-  if (OS_DRAG_DROP)
+  if (WINDOWS)
+    add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
+  endif (WINDOWS)
 
-    if (WINDOWS)
-      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
-    endif (WINDOWS)
+  if (DARWIN)
+    add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
+  endif (DARWIN)
 
-    if (DARWIN)
-      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
-    endif (DARWIN)
+  if (LINUX)
+    add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
+  endif (LINUX)
 
-    if (LINUX)
-      add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
-    endif (LINUX)
+endif (OS_DRAG_DROP)
 
-  endif (OS_DRAG_DROP)
-
-endif (VIEWER)
diff --git a/indra/cmake/Externals.cmake b/indra/cmake/Externals.cmake
deleted file mode 100644
index 26f3b5604937a781490838532276b2e67717e8d1..0000000000000000000000000000000000000000
--- a/indra/cmake/Externals.cmake
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- cmake -*-
-
-include(Python)
-include(FindSVN)
-
-macro (use_svn_external _binary _path _url _rev)
-  if (NOT STANDALONE)
-    if(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)
-      if(SVN_FOUND)
-        if(DEBUG_EXTERNALS)
-          message("cd ${_path} && ${SVN_EXECUTABLE} checkout -r ${_rev} ${_url} ${_binary}")
-        endif(DEBUG_EXTERNALS)
-        execute_process(COMMAND ${SVN_EXECUTABLE}
-          checkout
-          -r ${_rev}
-          ${_url}
-          ${_binary}
-          WORKING_DIRECTORY ${_path}
-          RESULT_VARIABLE ${_binary}_installed
-          )
-      else(SVN_FOUND)
-        message(FATAL_ERROR "Failed to find SVN_EXECUTABLE")
-      endif(SVN_FOUND)
-      file(WRITE ${CMAKE_BINARY_DIR}/temp/${_binary}_installed "${${_binary}_installed}")
-    else(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)
-      set(${_binary}_installed 0)
-    endif(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)
-    if(NOT ${_binary}_installed EQUAL 0)
-      message(FATAL_ERROR
-              "Failed to download or unpack prebuilt '${_binary}'."
-              " Process returned ${${_binary}_installed}.")
-    endif (NOT ${_binary}_installed EQUAL 0)
-  endif (NOT STANDALONE)
-endmacro (use_svn_external _binary _path _url _rev)
diff --git a/indra/cmake/FindELFIO.cmake b/indra/cmake/FindELFIO.cmake
deleted file mode 100644
index 8a5421ab9c8e636cc16abc9c826ddf6efb42d223..0000000000000000000000000000000000000000
--- a/indra/cmake/FindELFIO.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- cmake -*-
-
-# - Find ELFIO
-# Find the ELFIO includes and library
-# This module defines
-#  ELFIO_INCLUDE_DIR, where to find elfio.h, etc.
-#  ELFIO_LIBRARIES, the libraries needed to use ELFIO.
-#  ELFIO_FOUND, If false, do not try to use ELFIO.
-# also defined, but not for general use are
-#  ELFIO_LIBRARY, where to find the ELFIO library.
-
-FIND_PATH(ELFIO_INCLUDE_DIR ELFIO/ELFIO.h
-/usr/local/include
-/usr/include
-)
-
-SET(ELFIO_NAMES ${ELFIO_NAMES} ELFIO)
-FIND_LIBRARY(ELFIO_LIBRARY
-  NAMES ${ELFIO_NAMES}
-  PATHS /usr/lib /usr/local/lib
-  )
-
-IF (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR)
-    SET(ELFIO_LIBRARIES ${ELFIO_LIBRARY})
-    SET(ELFIO_FOUND "YES")
-ELSE (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR)
-  SET(ELFIO_FOUND "NO")
-ENDIF (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR)
-
-
-IF (ELFIO_FOUND)
-   IF (NOT ELFIO_FIND_QUIETLY)
-      MESSAGE(STATUS "Found ELFIO: ${ELFIO_LIBRARIES}")
-   ENDIF (NOT ELFIO_FIND_QUIETLY)
-ELSE (ELFIO_FOUND)
-   IF (ELFIO_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find ELFIO library")
-   ENDIF (ELFIO_FIND_REQUIRED)
-ENDIF (ELFIO_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_ELFIO_INCLUDE_PATH ${ELFIO_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_ELFIO_LIB_PATH ${ELFIO_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  ELFIO_LIBRARY
-  ELFIO_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindLLQtWebkit.cmake b/indra/cmake/FindLLQtWebkit.cmake
deleted file mode 100644
index 2f666d3bf01e42587c340f7bbfbe94e7b54bb04b..0000000000000000000000000000000000000000
--- a/indra/cmake/FindLLQtWebkit.cmake
+++ /dev/null
@@ -1,62 +0,0 @@
-# -*- cmake -*-
-
-# - Find llqtwebkit
-# Find the llqtwebkit includes and library
-# This module defines
-#  LLQTWEBKIT_INCLUDE_DIR, where to find llqtwebkit.h, etc.
-#  LLQTWEBKIT_LIBRARY, the llqtwebkit library with full path.
-#  LLQTWEBKIT_FOUND, If false, do not try to use llqtwebkit.
-# also defined, but not for general use are
-#  LLQTWEBKIT_LIBRARIES, the libraries needed to use llqtwebkit.
-#  LLQTWEBKIT_LIBRARY_DIRS, where to find the llqtwebkit library.
-#  LLQTWEBKIT_DEFINITIONS - You should add_definitions(${LLQTWEBKIT_DEFINITIONS})
-#      before compiling code that includes llqtwebkit library files.
-
-# Try to use pkg-config first.
-# This allows to have two different libllqtwebkit packages installed:
-# one for viewer 2.x and one for viewer 1.x.
-include(FindPkgConfig)
-if (PKG_CONFIG_FOUND)
-    if (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
-        set(_PACKAGE_ARGS libllqtwebkit>=${LLQtWebkit_FIND_VERSION} REQUIRED)
-    else (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
-        set(_PACKAGE_ARGS libllqtwebkit)
-    endif (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
-    if (NOT "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_LESS "2.8.2")
-      # As virtually nobody will have a pkg-config file for this, do this check always quiet.
-      # Unfortunately cmake 2.8.2 or higher is required for pkg_check_modules to have a 'QUIET'.
-      set(_PACKAGE_ARGS ${_PACKAGE_ARGS} QUIET)
-    endif ()
-    pkg_check_modules(LLQTWEBKIT ${_PACKAGE_ARGS})
-endif (PKG_CONFIG_FOUND)
-set(LLQTWEBKIT_DEFINITIONS ${LLQTWEBKIT_CFLAGS_OTHER})
-
-find_path(LLQTWEBKIT_INCLUDE_DIR llqtwebkit.h NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_INCLUDE_DIRS})
-
-find_library(LLQTWEBKIT_LIBRARY NAMES llqtwebkit NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_LIBRARY_DIRS})
-
-if (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND)   # If pkg-config couldn't find it, pretend we don't have pkg-config.
-   set(LLQTWEBKIT_LIBRARIES llqtwebkit)
-   get_filename_component(LLQTWEBKIT_LIBRARY_DIRS ${LLQTWEBKIT_LIBRARY} PATH)
-endif (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND)
-
-# Handle the QUIETLY and REQUIRED arguments and set LLQTWEBKIT_FOUND
-# to TRUE if all listed variables are TRUE.
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(
-  LLQTWEBKIT
-  DEFAULT_MSG
-  LLQTWEBKIT_LIBRARY
-  LLQTWEBKIT_INCLUDE_DIR
-  LLQTWEBKIT_LIBRARIES
-  LLQTWEBKIT_LIBRARY_DIRS
-  )
-
-mark_as_advanced(
-  LLQTWEBKIT_LIBRARY
-  LLQTWEBKIT_INCLUDE_DIR
-  LLQTWEBKIT_LIBRARIES
-  LLQTWEBKIT_LIBRARY_DIRS
-  LLQTWEBKIT_DEFINITIONS
-  )
-
diff --git a/indra/cmake/FindMT.cmake b/indra/cmake/FindMT.cmake
deleted file mode 100644
index 5239a4c2f5a549c5c2e4ecd143640904618d6da2..0000000000000000000000000000000000000000
--- a/indra/cmake/FindMT.cmake
+++ /dev/null
@@ -1,15 +0,0 @@
-#Find the windows manifest tool.
-
-FIND_PROGRAM(HAVE_MANIFEST_TOOL NAMES mt
-                 PATHS
-                 "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/VC/bin"
-                 "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/Common7/Tools/Bin"
-                 "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/SDK/v2.0/Bin")
-IF(HAVE_MANIFEST_TOOL)
-    MESSAGE(STATUS "Found Mainfest Tool. Embedding custom manifests.")
-ELSE(HAVE_MANIFEST_TOOL)
-    MESSAGE(FATAL_ERROR "Manifest tool, mt.exe, can't be found.")
-ENDIF(HAVE_MANIFEST_TOOL)
-
-STRING(REPLACE "/MANIFEST" "/MANIFEST:NO" CMAKE_EXE_LINKER_FLAGS 
-      ${CMAKE_EXE_LINKER_FLAGS})
diff --git a/indra/cmake/FindMono.cmake b/indra/cmake/FindMono.cmake
deleted file mode 100644
index d956c48656a51db6a691688e6fcafff91f432560..0000000000000000000000000000000000000000
--- a/indra/cmake/FindMono.cmake
+++ /dev/null
@@ -1,68 +0,0 @@
-# - Try to find the mono, mcs, gmcs and gacutil
-#
-# defines
-#
-# MONO_FOUND - system has mono, mcs, gmcs and gacutil
-# MONO_PATH - where to find 'mono'
-# MCS_PATH - where to find 'mcs'
-# GMCS_PATH - where to find 'gmcs'
-# GACUTIL_PATH - where to find 'gacutil'
-#
-# copyright (c) 2007 Arno Rehn arno@arnorehn.de
-#
-# Redistribution and use is allowed according to the terms of the GPL license.
-# Removed the check for gmcs
-
-FIND_PROGRAM (MONO_EXECUTABLE mono
-             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
-             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
-             /bin
-             /usr/bin
-             /usr/local/bin
-)
-FIND_PROGRAM (MCS_EXECUTABLE mcs
-             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
-             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
-             /bin
-             /usr/bin
-             /usr/local/bin
-)
-FIND_PROGRAM (GMCS_EXECUTABLE gmcs
-             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
-             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
-             /bin
-             /usr/bin
-             /usr/local/bin
-)
-FIND_PROGRAM (GACUTIL_EXECUTABLE gacutil
-             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
-             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
-             /bin
-             /usr/bin
-             /usr/local/bin
-)
-FIND_PROGRAM (ILASM_EXECUTABLE
-             NAMES ilasm.bat ilasm
-             NO_DEFAULT_PATH
-             PATHS "$ENV{PROGRAMFILES}/Mono-1.9.1/bin" "$ENV{PROGRAMFILES}/Mono-1.2.6/bin" /bin /usr/bin /usr/local/bin
-)
-
-SET (MONO_FOUND FALSE)
-
-IF (MONO_EXECUTABLE AND MCS_EXECUTABLE AND GACUTIL_EXECUTABLE)
-        SET (MONO_FOUND TRUE)
-ENDIF (MONO_EXECUTABLE AND MCS_EXECUTABLE AND GACUTIL_EXECUTABLE)
-
-IF (MONO_FOUND)
-        IF (NOT Mono_FIND_QUIETLY)
-                MESSAGE(STATUS "Found mono: ${MONO_EXECUTABLE}")
-                MESSAGE(STATUS "Found mcs: ${MCS_EXECUTABLE}")
-                MESSAGE(STATUS "Found gacutil: ${GACUTIL_EXECUTABLE}")
-        ENDIF (NOT Mono_FIND_QUIETLY)
-ELSE (MONO_FOUND)
-        IF (Mono_FIND_REQUIRED)
-                MESSAGE(FATAL_ERROR "Could not find one or more of the following programs: mono, mcs, gacutil")
-        ENDIF (Mono_FIND_REQUIRED)
-ENDIF (MONO_FOUND)
-
-MARK_AS_ADVANCED(MONO_EXECUTABLE MCS_EXECUTABLE GACUTIL_EXECUTABLE)
diff --git a/indra/cmake/FindMySQL.cmake b/indra/cmake/FindMySQL.cmake
deleted file mode 100644
index 431940328f97ddcc81c0cb802fd094782cbb49d5..0000000000000000000000000000000000000000
--- a/indra/cmake/FindMySQL.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- cmake -*-
-
-# - Find MySQL
-# Find the MySQL includes and library
-# This module defines
-#  MYSQL_INCLUDE_DIR, where to find mysql.h, etc.
-#  MYSQL_LIBRARIES, the libraries needed to use Mysql.
-#  MYSQL_FOUND, If false, do not try to use Mysql.
-# also defined, but not for general use are
-#  MYSQL_LIBRARY, where to find the Mysql library.
-
-FIND_PATH(MYSQL_INCLUDE_DIR mysql/mysql.h
-/usr/local/include
-/usr/include
-)
-
-SET(MYSQL_NAMES ${MYSQL_NAMES} mysqlclient)
-FIND_LIBRARY(MYSQL_LIBRARY
-  NAMES ${MYSQL_NAMES}
-  PATHS /usr/lib/mysql /usr/lib /usr/local/lib/mysql /usr/local/lib
-  )
-
-IF (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR)
-    SET(MYSQL_LIBRARIES ${MYSQL_LIBRARY})
-    SET(MYSQL_FOUND "YES")
-ELSE (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR)
-  SET(MYSQL_FOUND "NO")
-ENDIF (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR)
-
-
-IF (MYSQL_FOUND)
-   IF (NOT MYSQL_FIND_QUIETLY)
-      MESSAGE(STATUS "Found MySQL: ${MYSQL_LIBRARIES}")
-   ENDIF (NOT MYSQL_FIND_QUIETLY)
-ELSE (MYSQL_FOUND)
-   IF (MYSQL_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find MySQL library")
-   ENDIF (MYSQL_FIND_REQUIRED)
-ENDIF (MYSQL_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_MYSQL_INCLUDE_PATH ${MYSQL_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_MYSQL_LIB_PATH ${MYSQL_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  MYSQL_LIBRARY
-  MYSQL_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindSVN.cmake b/indra/cmake/FindSVN.cmake
deleted file mode 100644
index 3322be4ca9213bffcae36da3922d4ef8e539ecd1..0000000000000000000000000000000000000000
--- a/indra/cmake/FindSVN.cmake
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- cmake -*-
-#
-# Find the svn executable for exporting old svn:externals.
-#
-# Input variables:
-#   SVN_FIND_REQUIRED - set this if configuration should fail without scp
-#
-# Output variables:
-#
-#   SVN_FOUND - set if svn was found
-#   SVN_EXECUTABLE - path to svn executable
-#   SVN_BATCH_FLAG - how to put svn into batch mode
-
-
-SET(SVN_EXECUTABLE)
-FIND_PROGRAM(SVN_EXECUTABLE NAMES svn svn.exe)
-
-IF (SVN_EXECUTABLE)
-  SET(SVN_FOUND ON)
-ELSE (SVN_EXECUTABLE)
-  SET(SVN_FOUND OFF)
-ENDIF (SVN_EXECUTABLE)
-
-IF (SVN_FOUND)
-  GET_FILENAME_COMPONENT(_svn_name ${SVN_EXECUTABLE} NAME_WE)
-  SET(SVN_BATCH_FLAG --non-interactive)
-ELSE (SVN_FOUND)
-  IF (SVN_FIND_REQUIRED)
-    MESSAGE(FATAL_ERROR "Could not find svn executable")
-  ENDIF (SVN_FIND_REQUIRED)
-ENDIF (SVN_FOUND)
-
-MARK_AS_ADVANCED(SVN_EXECUTABLE SVN_FOUND SVN_BATCH_FLAG)
-
diff --git a/indra/cmake/GLEXT.cmake b/indra/cmake/GLEXT.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..0a3dd976b43354adf1d5d2768356e95b004fc10e
--- /dev/null
+++ b/indra/cmake/GLEXT.cmake
@@ -0,0 +1,8 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+if (NOT STANDALONE)
+  use_prebuilt_binary(glext)
+  use_prebuilt_binary(glh_linear)
+  set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
+endif (NOT STANDALONE)
diff --git a/indra/cmake/GLOD.cmake b/indra/cmake/GLOD.cmake
index 77221d55ede01056ed6b2e83228173907b064a03..6bdbaf621edf12e714299791c2cba7f675a11fbd 100644
--- a/indra/cmake/GLOD.cmake
+++ b/indra/cmake/GLOD.cmake
@@ -6,4 +6,4 @@ if (NOT STANDALONE)
 endif (NOT STANDALONE)
 
 set(GLOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-set(GLOD_LIBRARIES glod)
+set(GLOD_LIBRARIES GLOD)
diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake
index 73b3642ae646c3e5ff493157e92d32b9fcb7c9fb..f3fd008e492cb99183507e4acfc980f69ef301a2 100644
--- a/indra/cmake/GooglePerfTools.cmake
+++ b/indra/cmake/GooglePerfTools.cmake
@@ -10,7 +10,7 @@ if (STANDALONE)
 else (STANDALONE)
   if (WINDOWS)
     if (USE_TCMALLOC)
-       use_prebuilt_binary(tcmalloc)
+       use_prebuilt_binary(gperftools)
        set(TCMALLOC_LIBRARIES 
          debug libtcmalloc_minimal-debug
          optimized libtcmalloc_minimal)
@@ -23,7 +23,7 @@ else (STANDALONE)
   endif (WINDOWS)
   if (LINUX)
     if (USE_TCMALLOC)
-      use_prebuilt_binary(tcmalloc)
+      use_prebuilt_binary(gperftools)
       set(TCMALLOC_LIBRARIES 
         tcmalloc)
     else (USE_TCMALLOC)
diff --git a/indra/cmake/Havok.cmake b/indra/cmake/Havok.cmake
index 5c0768abfa91c50ed25b72ce219fd890c5c651ac..44f81ce332a92a6b77b786d2e88773bb70ed7aca 100644
--- a/indra/cmake/Havok.cmake
+++ b/indra/cmake/Havok.cmake
@@ -1,6 +1,10 @@
 # -*- cmake -*-
 
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
 use_prebuilt_binary(havok-source)
+
 set(Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Source)
 list(APPEND Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Demo)
 
@@ -8,14 +12,14 @@ set(HAVOK_DEBUG_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
 set(HAVOK_RELEASE_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
 
 if (LL_DEBUG_HAVOK)
-   if (WIN32)
-      # Always link relwithdebinfo to havok-hybrid on windows.
-      set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid)
-   else (WIN32)
-      set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
-   endif (WIN32)
+  if (WIN32)
+    # Always link relwithdebinfo to havok-hybrid on windows.
+    set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid)
+  else (WIN32)
+    set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
+  endif (WIN32)
 else (LL_DEBUG_HAVOK)
-   set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
+  set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
 endif (LL_DEBUG_HAVOK)
 
 set(HAVOK_LIBS
@@ -45,39 +49,89 @@ unset(HK_DEBUG_LIBRARIES)
 unset(HK_RELEASE_LIBRARIES)
 unset(HK_RELWITHDEBINFO_LIBRARIES)
 
+# *TODO: Figure out why we need to extract like this...
 foreach(HAVOK_LIB ${HAVOK_LIBS})
-        find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
-        find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
-        find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
-        
-        if(LINUX)
-            set(cmd "mkdir")
-            set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
-            set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
-            set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
-
-            exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
-            exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
-            exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
-
-            set(cmd "ar")
-            set(arg " -xv")
-            set(arg "${arg} ../lib${HAVOK_LIB}.a")
-            exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
-            exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
-            exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
-
-            file(GLOB extracted_debug "${debug_dir}/*.o")
-            file(GLOB extracted_release "${release_dir}/*.o")
-            file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
-            list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
-            list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
-            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
-        else(LINUX)
-        # Win32
-            list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
-            list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
-            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
-        endif (LINUX)
+  find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
+  find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
+  find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
+  
+  if(LINUX)
+    set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
+    set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
+    set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
+
+    # Try to avoid extracting havok library each time we run cmake.
+    if("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted")
+      file(READ ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted "havok_${HAVOK_LIB}_extracted")
+      if(DEBUG_PREBUILT)
+        message(STATUS "havok_${HAVOK_LIB}_extracted: \"${havok_${HAVOK_LIB}_extracted}\"")
+      endif(DEBUG_PREBUILT)
+    endif("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted")
+
+    if(${CMAKE_BINARY_DIR}/temp/havok-source_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "Extracting ${HAVOK_LIB}...")
+      endif(DEBUG_PREBUILT)
+      set(cmd "mkdir")
+
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "${cmd} ${debug_dir}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
+
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "${cmd} ${release_dir}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
+
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "${cmd} ${relwithdebinfo_dir}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
+
+      set(cmd "ar")
+      set(arg " -xv")
+      set(arg "${arg} ../lib${HAVOK_LIB}.a")
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "cd ${debug_dir} && ${cmd} ${arg}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "cd ${release_dir} && ${cmd} ${arg}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "cd ${relwithdebinfo_dir} && ${cmd} ${arg}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+
+      # Just assume success for now.
+      set(havok_${HAVOK_LIB}_extracted 0)
+      file(WRITE ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted "${havok_${HAVOK_LIB}_extracted}")
+
+    endif(${CMAKE_BINARY_DIR}/temp/havok-source_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
+
+    file(GLOB extracted_debug "${debug_dir}/*.o")
+    file(GLOB extracted_release "${release_dir}/*.o")
+    file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
+
+    if(DEBUG_PREBUILT)
+      MESSAGE(STATUS "extracted_debug ${debug_dir}/*.o")
+      MESSAGE(STATUS "extracted_release ${release_dir}/*.o")
+      MESSAGE(STATUS "extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o")
+    endif(DEBUG_PREBUILT)
+
+    list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
+    list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
+    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
+  else(LINUX)
+  # Win32
+    list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
+    list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
+    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
+  endif (LINUX)
 endforeach(HAVOK_LIB)
 
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/LLAppearance.cmake b/indra/cmake/LLAppearance.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..bd3795a5262b0dcbca26779ba7353e382ad38c77
--- /dev/null
+++ b/indra/cmake/LLAppearance.cmake
@@ -0,0 +1,17 @@
+# -*- cmake -*-
+
+include(Variables)
+
+set(LLAPPEARANCE_INCLUDE_DIRS
+    ${LIBS_OPEN_DIR}/llappearance
+    )
+
+if (BUILD_HEADLESS)
+  set(LLAPPEARANCE_HEADLESS_LIBRARIES
+    llappearanceheadless
+    )
+endif (BUILD_HEADLESS)
+
+set(LLAPPEARANCE_LIBRARIES llappearance)
+
+
diff --git a/indra/cmake/LLAppearanceUtility.cmake b/indra/cmake/LLAppearanceUtility.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..bea45543dea2fbe0e37381f4d6f0b162660f478f
--- /dev/null
+++ b/indra/cmake/LLAppearanceUtility.cmake
@@ -0,0 +1,12 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+# Linux proprietary build only
+if (INSTALL_PROPRIETARY)
+    if(LINUX)
+        use_prebuilt_binary(llappearanceutility-source)
+        set(LLAPPEARANCEUTILITY_SRC_DIR ${LIBS_PREBUILT_DIR}/llappearanceutility/src)
+        set(LLAPPEARANCEUTILITY_BIN_DIR ${CMAKE_BINARY_DIR}/llappearanceutility)
+    endif (LINUX)
+endif (INSTALL_PROPRIETARY)
+
diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake
index c254bf6f053b337ac6637f8a6b96e4f6cf9b2afc..b52556a73e4fead0f075cf631f8203de6e8a3203 100644
--- a/indra/cmake/LLCommon.cmake
+++ b/indra/cmake/LLCommon.cmake
@@ -10,6 +10,8 @@ set(LLCOMMON_INCLUDE_DIRS
     ${LIBS_OPEN_DIR}/llcommon
     ${APRUTIL_INCLUDE_DIR}
     ${APR_INCLUDE_DIR}
+    )
+set(LLCOMMON_SYSTEM_INCLUDE_DIRS
     ${Boost_INCLUDE_DIRS}
     )
 
diff --git a/indra/cmake/LLDatabase.cmake b/indra/cmake/LLDatabase.cmake
deleted file mode 100644
index 65261013861f5844a99cd4d43594507961da7da4..0000000000000000000000000000000000000000
--- a/indra/cmake/LLDatabase.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- cmake -*-
-
-include(MySQL)
-
-set(LLDATABASE_INCLUDE_DIRS
-    ${LIBS_SERVER_DIR}/lldatabase
-    ${MYSQL_INCLUDE_DIR}
-    )
-
-set(LLDATABASE_LIBRARIES lldatabase)
diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake
index 8427928151dfe48cf65c71e769e660e979982c43..ae71ee4c0d611e09cd9e8d98f16bb21ececc4c1d 100644
--- a/indra/cmake/LLRender.cmake
+++ b/indra/cmake/LLRender.cmake
@@ -1,5 +1,6 @@
 # -*- cmake -*-
 
+include(Variables)
 include(FreeType)
 include(GLH)
 
@@ -8,27 +9,12 @@ set(LLRENDER_INCLUDE_DIRS
     ${GLH_INCLUDE_DIR}
     )
 
-if (SERVER AND LINUX)
-  set(LLRENDER_LIBRARIES
-      llrenderheadless
-      )
-else (SERVER AND LINUX)
+if (BUILD_HEADLESS)
+  set(LLRENDER_HEADLESS_LIBRARIES
+    llrenderheadless
+    )
+endif (BUILD_HEADLESS)
 set(LLRENDER_LIBRARIES
     llrender
     )
-endif (SERVER AND LINUX)
 
-# mapserver requires certain files to be copied so LL_MESA_HEADLESS can be set
-# differently for different object files.
-macro (copy_server_sources )
-  foreach (PREFIX ${ARGV})
-    add_custom_command(
-        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp
-        COMMAND ${CMAKE_COMMAND}
-        ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${PREFIX}.cpp
-             ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp
-        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${PREFIX}.cpp
-        )
-    list(APPEND server_SOURCE_FILES ${PREFIX}_server.cpp)
-  endforeach (PREFIX ${_copied_SOURCES})
-endmacro (copy_server_sources _copied_SOURCES)
diff --git a/indra/cmake/LLScene.cmake b/indra/cmake/LLScene.cmake
deleted file mode 100644
index 96ad5085a24aa45642ef60d8bf829447e899bedc..0000000000000000000000000000000000000000
--- a/indra/cmake/LLScene.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLSCENE_INCLUDE_DIRS
-    ${LIBS_SERVER_DIR}/llscene
-    )
-
-set(LLSCENE_LIBRARIES llscene)
diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake
index b4bb9a078a9c8dbac63312638d2839842ac54aaa..0def507e659aca39bd2cc67a3f496f55c79e71d2 100644
--- a/indra/cmake/LLWindow.cmake
+++ b/indra/cmake/LLWindow.cmake
@@ -1,6 +1,7 @@
 # -*- cmake -*-
 
-include(OpenGL)
+include(Variables)
+include(GLEXT)
 include(Prebuilt)
 
 if (STANDALONE)
@@ -13,17 +14,15 @@ if (STANDALONE)
       SDL_LIBRARY
       )
 else (STANDALONE)
-  use_prebuilt_binary(mesa)
-  if (LINUX AND VIEWER)
+  if (LINUX)
     use_prebuilt_binary(SDL)
     set (SDL_FOUND TRUE)
     set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/i686-linux)
     set (SDL_LIBRARY SDL directfb fusion direct)
-  endif (LINUX AND VIEWER)
+  endif (LINUX)
 endif (STANDALONE)
 
 if (SDL_FOUND)
-  add_definitions(-DLL_SDL=1)
   include_directories(${SDL_INCLUDE_DIR})
 endif (SDL_FOUND)
 
@@ -32,12 +31,12 @@ set(LLWINDOW_INCLUDE_DIRS
     ${LIBS_OPEN_DIR}/llwindow
     )
 
-if (SERVER AND LINUX)
-  set(LLWINDOW_LIBRARIES
-      llwindowheadless
-      )
-else (SERVER AND LINUX)
-  set(LLWINDOW_LIBRARIES
-      llwindow
-      )
-endif (SERVER AND LINUX)
+if (BUILD_HEADLESS)
+  set(LLWINDOW_HEADLESS_LIBRARIES
+    llwindowheadless
+    )
+endif (BUILD_HEADLESS)
+
+set(LLWINDOW_LIBRARIES
+    llwindow
+    )
diff --git a/indra/cmake/LLXML.cmake b/indra/cmake/LLXML.cmake
index 64dfdb604f1cf71922e175020deef1ea160e66cf..b093c762975efc4771464bc6e6efcadf28faff7f 100644
--- a/indra/cmake/LLXML.cmake
+++ b/indra/cmake/LLXML.cmake
@@ -5,8 +5,10 @@ include(EXPAT)
 
 set(LLXML_INCLUDE_DIRS
     ${LIBS_OPEN_DIR}/llxml
-    ${Boost_INCLUDE_DIRS}
     ${EXPAT_INCLUDE_DIRS}
     )
+set(LLXML_SYSTEM_INCLUDE_DIRS
+    ${Boost_INCLUDE_DIRS}
+    )
 
 set(LLXML_LIBRARIES llxml)
diff --git a/indra/cmake/LLXUIXML.cmake b/indra/cmake/LLXUIXML.cmake
deleted file mode 100644
index b8bfe48c77660cb81495e23314795dfa48a8afc4..0000000000000000000000000000000000000000
--- a/indra/cmake/LLXUIXML.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLXUIXML_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llxuixml
-    )
-
-set(LLXUIXML_LIBRARIES llxuixml)
diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index c3e3a80fd0d06cf20d8d1af12e3952ff7864d78b..b9c9e531fce292acc672e6ef9643626d4b6b41b5 100644
--- a/indra/cmake/Linking.cmake
+++ b/indra/cmake/Linking.cmake
@@ -1,5 +1,8 @@
 # -*- cmake -*-
 
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
 include(Variables)
 
 set(ARCH_PREBUILT_DIRS ${AUTOBUILD_INSTALL_DIR}/lib)
@@ -69,3 +72,5 @@ else (WINDOWS)
 endif (WINDOWS)
     
 mark_as_advanced(DL_LIBRARY PTHREAD_LIBRARY WINDOWS_LIBRARIES)
+
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/MonoDeps.cmake b/indra/cmake/MonoDeps.cmake
deleted file mode 100644
index 52d5491563607396342669cdbefbd40fa40fba3d..0000000000000000000000000000000000000000
--- a/indra/cmake/MonoDeps.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- cmake -*-
-
-set(MONO_PREBUILT_LIBRARIES_DIR ${LIBS_PREBUILT_DIR}/mono/1.0)
-
-set(MONO_PREBUILT_LIBRARIES
-     Iesi.Collections.dll
-     Iesi.Collections.pdb
-     Mono.CompilerServices.SymbolWriter.dll
-     Mono.PEToolkit.dll
-     Mono.PEToolkit.pdb
-     Mono.Security.dll
-     PEAPI.dll
-     RAIL.dll
-     RAIL.pdb
-  )
-  
-  set(MONO_CORE_LIBRARIES
-    System.dll
-    System.Xml.dll
-    mscorlib.dll)
-    
-if(WINDOWS)
-    set(MONO_DEPENDENCIES
-        DomainCreator
-        DomainRegister
-        LslLibrary
-        LslUserScript
-        Script
-        ScriptTypes
-        TestFormat
-        UserScript
-        UThread
-        UThreadInjector
-        )
-else(WINDOWS)
-    set(MONO_DEPENDENCIES
-        DomainCreator_POST_BUILD
-        DomainRegister_POST_BUILD
-        LslLibrary_POST_BUILD
-        LslUserScript_POST_BUILD
-        Script_POST_BUILD
-        ScriptTypes_POST_BUILD
-        TestFormat_POST_BUILD
-        UserScript_POST_BUILD
-        UThread_POST_BUILD
-        UThreadInjector_POST_BUILD
-        )
-endif(WINDOWS)
diff --git a/indra/cmake/MonoEmbed.cmake b/indra/cmake/MonoEmbed.cmake
deleted file mode 100644
index 30890aed217ad31b262fe4803ba716fae1617df5..0000000000000000000000000000000000000000
--- a/indra/cmake/MonoEmbed.cmake
+++ /dev/null
@@ -1,57 +0,0 @@
-# -*- cmake -*-
-
-include(Prebuilt)
-use_prebuilt_binary(libmono)
-
-SET(GLIB_2_0 glib-2.0)
-
-if (WINDOWS)
-    SET(MONO_LIB mono) 
-else (WINDOWS)
-    SET(MONO_LIB mono)
-    SET(M_LIBRARIES m)
-    SET(GTHREAD_2_0 gthread-2.0)
-endif(WINDOWS)
-
-
-IF (DARWIN)
-
-  FIND_LIBRARY(MONO_LIBRARY NAMES Mono)
-  # Find_file doesnt work as expected. Hardcode relative to Mono.framework. 
-  #FIND_FILE(GLIB_CONFIG glibconfig.h ${MONO_LIBRARY})
-  #FIND_FILE(MONO_GLIB_LIBRARY glib.h ${MONO_LIBRARY})
-  SET(MONO_GLIB_LIBRARY ${MONO_LIBRARY}/Headers/glib-2.0/)
-  SET(GLIB_CONFIG ${MONO_LIBRARY}/Libraries/glib-2.0/include/)
-  SET(MONO_LIB_DIRECTORY ${MONO_LIBRARY}/Libraries)
-
-  IF (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
-    MESSAGE(STATUS "Found Mono for embedding")
-    INCLUDE_DIRECTORIES(${MONO_GLIB_LIBRARY} ${GLIB_CONFIG})
-    LINK_DIRECTORIES(${MONO_LIB_DIRECTORY})
-  ELSE (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
-    MESSAGE(FATAL_ERROR "Mono not found for embedding")   
-    MESSAGE(${MONO_LIBRARY})
-    MESSAGE(${MONO_GLIB_LIBRARY})
-    MESSAGE(${GLIB_CONFIG})
-  ENDIF (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
-
-ELSE (DARWIN)
-
-  SET(MONO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)  
-  SET(GLIB_2_0_PLATFORM_INCLUDE_DIR
-    ${LIBS_PREBUILT_DIR}/include/glib-2.0)
-  SET(GLIB_2_0_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/glib-2.0)
-
-  INCLUDE_DIRECTORIES(
-    ${MONO_INCLUDE_DIR} 
-    ${GLIB_2_0_PLATFORM_INCLUDE_DIR} 
-    ${GLIB_2_0_INCLUDE_DIR})
-    
-ENDIF (DARWIN) 
-
-SET(MONO_LIBRARIES 
-    ${MONO_LIB} 
-    ${M_LIBRARIES} 
-    ${GLIB_2_0}
-    ${GTHREAD_2_0} 
-)
diff --git a/indra/cmake/MySQL.cmake b/indra/cmake/MySQL.cmake
deleted file mode 100644
index 218482449dc0daa6a02596ebf4de274cbb7d2114..0000000000000000000000000000000000000000
--- a/indra/cmake/MySQL.cmake
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- cmake -*-
-include(Linking)
-include(Prebuilt)
-
-use_prebuilt_binary(mysql)
-
-if (LINUX)
-  if (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
-    set(MYSQL_LIBRARIES mysqlclient)
-    set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-  else (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
-    # Use the native MySQL library on a 64-bit system.
-    set(MYSQL_FIND_QUIETLY ON)
-    set(MYSQL_FIND_REQUIRED ON)
-    include(FindMySQL)
-  endif (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
-elseif (WINDOWS)
-  set(MYSQL_LIBRARIES mysqlclient)
-  set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-elseif (DARWIN)
-  set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-  set(MYSQL_LIBRARIES
-    optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libmysqlclient.a
-    debug ${ARCH_PREBUILT_DIRS_DEBUG}/libmysqlclient.a
-    )
-endif (LINUX)
diff --git a/indra/cmake/OpenGL.cmake b/indra/cmake/OpenGL.cmake
index 0a3dd976b43354adf1d5d2768356e95b004fc10e..2259c992935ff42dbbf46eb4105467a7ec7584d8 100644
--- a/indra/cmake/OpenGL.cmake
+++ b/indra/cmake/OpenGL.cmake
@@ -1,8 +1,12 @@
 # -*- cmake -*-
+
+include(Variables)
 include(Prebuilt)
 
-if (NOT STANDALONE)
-  use_prebuilt_binary(glext)
-  use_prebuilt_binary(glh_linear)
-  set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-endif (NOT STANDALONE)
+if (BUILD_HEADLESS)
+  SET(OPENGL_glu_LIBRARY GLU)
+  SET(OPENGL_HEADLESS_LIBRARIES OSMesa16 dl GLU)
+endif (BUILD_HEADLESS)
+
+include(FindOpenGL)
+
diff --git a/indra/cmake/Prebuilt.cmake b/indra/cmake/Prebuilt.cmake
index dbb4dfc46c7f034c792224ac52a33269be1e8028..ac0cbde25322fa81a1b7a27197fb874a51f1abc1 100644
--- a/indra/cmake/Prebuilt.cmake
+++ b/indra/cmake/Prebuilt.cmake
@@ -1,5 +1,8 @@
 # -*- cmake -*-
 
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
 include(FindAutobuild)
 if(INSTALL_PROPRIETARY)
   include(FindSCP)
@@ -51,3 +54,5 @@ macro (use_prebuilt_binary _binary)
     endif (NOT ${_binary}_installed EQUAL 0)
   endif (NOT STANDALONE_${_binary})
 endmacro (use_prebuilt_binary _binary)
+
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake
index 748c8c2bec1b80b3680c2b7e410fbf3de1830df5..a81c9307fc062c8ba18e168ad8779b0e47ab93ac 100644
--- a/indra/cmake/Python.cmake
+++ b/indra/cmake/Python.cmake
@@ -23,7 +23,7 @@ if (WINDOWS)
 elseif (EXISTS /etc/debian_version)
   # On Debian and Ubuntu, avoid Python 2.4 if possible.
 
-  find_program(PYTHON_EXECUTABLE python2.5 python2.3 python PATHS /usr/bin)
+  find_program(PYTHON_EXECUTABLE python PATHS /usr/bin)
 
   if (PYTHON_EXECUTABLE)
     set(PYTHONINTERP_FOUND ON)
diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake
index 91e5258fb704ed7169e4d5e7bba61b7ca652f53b..d0fd4df03a225550b84f72ad650ade3a6bfda6b3 100644
--- a/indra/cmake/UI.cmake
+++ b/indra/cmake/UI.cmake
@@ -1,5 +1,6 @@
 # -*- cmake -*-
 include(Prebuilt)
+include(FreeType)
 
 if (STANDALONE)
   include(FindPkgConfig)
@@ -47,6 +48,7 @@ else (STANDALONE)
         pangoft2-1.0
         pangox-1.0
         pangoxft-1.0
+        ${FREETYPE_LIBRARIES}
         )
   endif (LINUX)
 
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 4b459f1a486195758e3caf1a4f9917c7ef66e276..6ec621632b8356213e145e33bd04a0a73d7b134e 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -8,24 +8,20 @@
 #   DARWIN  - Mac OS X
 #   LINUX   - Linux
 #   WINDOWS - Windows
-#
-# What to build:
-#
-#   VIEWER - viewer and other viewer-side components
-#   SERVER - simulator and other server-side bits
 
 
 # Relative and absolute paths to subtrees.
 
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
 if(NOT DEFINED COMMON_CMAKE_DIR)
     set(COMMON_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake")
 endif(NOT DEFINED COMMON_CMAKE_DIR)
 
 set(LIBS_CLOSED_PREFIX)
 set(LIBS_OPEN_PREFIX)
-set(LIBS_SERVER_PREFIX)
 set(SCRIPTS_PREFIX ../scripts)
-set(SERVER_PREFIX)
 set(VIEWER_PREFIX)
 set(INTEGRATION_TESTS_PREFIX)
 set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation")
@@ -43,9 +39,7 @@ else(LIBS_COMMON_DIR)
 endif(LIBS_COMMON_DIR)
 set(LIBS_OPEN_DIR ${LIBS_COMMON_DIR})
 
-set(LIBS_SERVER_DIR ${CMAKE_SOURCE_DIR}/${LIBS_SERVER_PREFIX})
 set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX})
-set(SERVER_DIR ${CMAKE_SOURCE_DIR}/${SERVER_PREFIX})
 set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX})
 
 set(AUTOBUILD_INSTALL_DIR ${CMAKE_BINARY_DIR}/packages)
@@ -79,21 +73,57 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
   # If someone has specified a word size, use that to determine the
   # architecture.  Otherwise, let the architecture specify the word size.
   if (WORD_SIZE EQUAL 32)
+    #message(STATUS "WORD_SIZE is 32")
     set(ARCH i686)
   elseif (WORD_SIZE EQUAL 64)
+    #message(STATUS "WORD_SIZE is 64")
     set(ARCH x86_64)
   else (WORD_SIZE EQUAL 32)
+    #message(STATUS "WORD_SIZE is UNDEFINED")
     execute_process(COMMAND uname -m COMMAND sed s/i.86/i686/
                     OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
     if (ARCH STREQUAL x86_64)
+      #message(STATUS "ARCH is detected as 64; ARCH is ${ARCH}")
       set(WORD_SIZE 64)
     else (ARCH STREQUAL x86_64)
+      #message(STATUS "ARCH is detected as 32; ARCH is ${ARCH}")
       set(WORD_SIZE 32)
     endif (ARCH STREQUAL x86_64)
   endif (WORD_SIZE EQUAL 32)
 
+  if (WORD_SIZE EQUAL 32)
+    set(DEB_ARCHITECTURE i386)
+    set(FIND_LIBRARY_USE_LIB64_PATHS OFF)
+    set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib32 ${CMAKE_SYSTEM_LIBRARY_PATH})
+  else (WORD_SIZE EQUAL 32)
+    set(DEB_ARCHITECTURE amd64)
+    set(FIND_LIBRARY_USE_LIB64_PATHS ON)
+  endif (WORD_SIZE EQUAL 32)
+
+  execute_process(COMMAND dpkg-architecture -a${DEB_ARCHITECTURE} -qDEB_HOST_MULTIARCH 
+      RESULT_VARIABLE DPKG_RESULT
+      OUTPUT_VARIABLE DPKG_ARCH
+      OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
+  #message (STATUS "DPKG_RESULT ${DPKG_RESULT}, DPKG_ARCH ${DPKG_ARCH}")
+  if (DPKG_RESULT EQUAL 0)
+    set(CMAKE_LIBRARY_ARCHITECTURE ${DPKG_ARCH})
+    set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib/${DPKG_ARCH} /usr/local/lib/${DPKG_ARCH} ${CMAKE_SYSTEM_LIBRARY_PATH})
+  endif (DPKG_RESULT EQUAL 0)
+
+  include(ConfigurePkgConfig)
+
   set(LL_ARCH ${ARCH}_linux)
   set(LL_ARCH_DIR ${ARCH}-linux)
+
+  if (INSTALL_PROPRIETARY)
+    # Only turn on headless if we can find osmesa libraries.
+    include(FindPkgConfig)
+    #pkg_check_modules(OSMESA osmesa)
+    #if (OSMESA_FOUND)
+    #  set(BUILD_HEADLESS ON CACHE BOOL "Build headless libraries.")
+    #endif (OSMESA_FOUND)
+  endif (INSTALL_PROPRIETARY)
+
 endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 
 if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
@@ -140,7 +170,6 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
 # Default deploy grid
 set(GRID agni CACHE STRING "Target Grid")
 
-set(VIEWER ON CACHE BOOL "Build Second Life viewer.")
 set(VIEWER_CHANNEL "LindenDeveloper" CACHE STRING "Viewer Channel Name")
 set(VIEWER_LOGIN_CHANNEL ${VIEWER_CHANNEL} CACHE STRING "Fake login channel for A/B Testing")
 
@@ -153,21 +182,8 @@ set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
 set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.")
 set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.")
 
-if (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
-    set(SERVER ON CACHE BOOL "Build Second Life server software.")
-endif (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
-
-if (LINUX AND SERVER AND VIEWER)
-  MESSAGE(FATAL_ERROR "
-The indra source does not currently support building SERVER and VIEWER at the same time.
-Please set one of these values to OFF in your CMake cache file.
-(either by running ccmake or by editing CMakeCache.txt by hand)
-For more information, please see JIRA DEV-14943 - Cmake Linux cannot build both VIEWER and SERVER in one build environment
-  ")
-endif (LINUX AND SERVER AND VIEWER)
-
-
 set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
 
 source_group("CMake Rules" FILES CMakeLists.txt)
 
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/VisualLeakDetector.cmake b/indra/cmake/VisualLeakDetector.cmake
index d3ba554e462621cbc6bff6d0d670f0a89055f01e..27e93e28bb483f85fd9980beb5404f7339babca5 100644
--- a/indra/cmake/VisualLeakDetector.cmake
+++ b/indra/cmake/VisualLeakDetector.cmake
@@ -1,15 +1,12 @@
 # -*- cmake -*-
 
-if (VIEWER)
+set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off")
 
-  set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off")
+if (INCLUDE_VLD_CMAKE)
 
-  if (INCLUDE_VLD_CMAKE)
+  if (WINDOWS)
+    add_definitions(-DINCLUDE_VLD=1)
+  endif (WINDOWS)
 
-    if (WINDOWS)
-      add_definitions(-DINCLUDE_VLD=1)
-    endif (WINDOWS)
+endif (INCLUDE_VLD_CMAKE)
 
-  endif (INCLUDE_VLD_CMAKE)
-
-endif (VIEWER)
diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt
index af5c9fb2e75dfbb1b9a6af401b115f6380139ad9..36a7d38bb71609d836222a2f60248a20b65b3b26 100644
--- a/indra/integration_tests/llimage_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt
@@ -16,6 +16,9 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLIMAGE_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llimage_libtest_SOURCE_FILES
     llimage_libtest.cpp
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index 91c9f20c107f51f4e6c54a29d7a4fdb3db4765d6..e83b4e8cd7210dc6d4907da4f63451c382089da9 100644
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -34,6 +34,10 @@ include_directories(
     ${LLXML_INCLUDE_DIRS}
     ${LIBS_PREBUILD_DIR}/include/hunspell
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llui_libtest_SOURCE_FILES
     llui_libtest.cpp
diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
index 98ebdc748739f0ffcba0265e138a5293d8d08a83..e0d0c9fc6974639f7bd9d3f3735c1d01194448e3 100644
--- a/indra/linux_crash_logger/CMakeLists.txt
+++ b/indra/linux_crash_logger/CMakeLists.txt
@@ -20,6 +20,10 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(linux_crash_logger_SOURCE_FILES
     linux_crash_logger.cpp
diff --git a/indra/linux_updater/CMakeLists.txt b/indra/linux_updater/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4a9e82f9b620b3a0202e974d60c73c868f25bccb
--- /dev/null
+++ b/indra/linux_updater/CMakeLists.txt
@@ -0,0 +1,57 @@
+# -*- cmake -*-
+
+project(linux_updater)
+
+include(00-Common)
+include(CURL)
+include(CARes)
+include(OpenSSL)
+include(UI)
+include(LLCommon)
+include(LLMessage)
+include(LLVFS)
+include(LLXML)
+include(LLUI)
+include(Linking)
+
+include_directories(
+    ${LLCOMMON_INCLUDE_DIRS}
+    ${LLVFS_INCLUDE_DIRS}
+    ${LLXML_INCLUDE_DIRS}
+    ${LLUI_INCLUDE_DIRS}
+    ${CURL_INCLUDE_DIRS}
+    ${CARES_INCLUDE_DIRS}
+    ${OPENSSL_INCLUDE_DIRS}
+    ${UI_INCLUDE_DIRS}
+    )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
+
+set(linux_updater_SOURCE_FILES linux_updater.cpp)
+
+set(linux_updater_HEADER_FILES CMakeLists.txt)
+
+set_source_files_properties(${linux_updater_HEADER_FILES}
+                            PROPERTIES HEADER_FILES_ONLY TRUE)
+
+list(APPEND linux_updater_SOURCE_FILES ${linux_updater_HEADER_FILES})
+
+add_executable(linux-updater ${linux_updater_SOURCE_FILES})
+
+target_link_libraries(linux-updater
+    ${CURL_LIBRARIES}
+    ${CARES_LIBRARIES}
+    ${OPENSSL_LIBRARIES}
+    ${CRYPTO_LIBRARIES}
+    ${LLMESSAGE_LIBRARIES}
+    ${UI_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    ${LLUI_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLCOMMON_LIBRARIES}
+    )
+
+add_custom_target(linux-updater-target ALL
+                  DEPENDS linux-updater)
diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..86fa596aef6d98d0eb982aed22a796e64376c88f
--- /dev/null
+++ b/indra/linux_updater/linux_updater.cpp
@@ -0,0 +1,924 @@
+/**
+ * @file linux_updater.cpp
+ * @author Kyle Ambroff <ambroff@lindenlab.com>, Tofu Linden
+ * @brief Viewer update program for unix platforms that support GTK+
+ *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "linden_common.h"
+#include "llerrorcontrol.h"
+#include "llfile.h"
+#include "lldir.h"
+#include "lldiriterator.h"
+
+/*==========================================================================*|
+// IQA-490: Use of LLTrans -- by this program at least -- appears to be buggy.
+// With it, the 3.3.2 beta 1 linux-updater.bin crashes; without it seems stable.
+#include "llxmlnode.h"
+#include "lltrans.h"
+|*==========================================================================*/
+
+static class LLTrans
+{
+public:
+	LLTrans();
+	static std::string getString(const std::string& key);
+
+private:
+	std::string _getString(const std::string& key) const;
+
+	typedef std::map<std::string, std::string> MessageMap;
+	MessageMap mMessages;
+} sLLTransInstance;
+
+#include <curl/curl.h>
+#include <map>
+#include <boost/foreach.hpp>
+
+extern "C" {
+#include <gtk/gtk.h>
+}
+
+const guint UPDATE_PROGRESS_TIMEOUT = 100;
+const guint UPDATE_PROGRESS_TEXT_TIMEOUT = 1000;
+const guint ROTATE_IMAGE_TIMEOUT = 8000;
+
+typedef struct _updater_app_state {
+	std::string app_name;
+	std::string url;
+	std::string file;
+	std::string image_dir;
+	std::string dest_dir;
+	std::string strings_dirs;
+	std::string strings_file;
+
+	LLDirIterator *image_dir_iter;
+
+	GtkWidget *window;
+	GtkWidget *progress_bar;
+	GtkWidget *image;
+
+	double progress_value;
+	bool activity_mode;
+
+	guint image_rotation_timeout_id;
+	guint progress_update_timeout_id;
+	guint update_progress_text_timeout_id;
+
+	bool failure;
+} UpdaterAppState;
+
+// List of entries from strings.xml to always replace
+static std::set<std::string> default_trans_args;
+void init_default_trans_args()
+{
+        default_trans_args.insert("SECOND_LIFE"); // World
+        default_trans_args.insert("APP_NAME");
+        default_trans_args.insert("SECOND_LIFE_GRID");
+        default_trans_args.insert("SUPPORT_SITE");
+}
+
+bool translate_init(std::string comma_delim_path_list,
+		    std::string base_xml_name)
+{
+	return true;
+/*==========================================================================*|
+	init_default_trans_args();
+
+	// extract paths string vector from comma-delimited flat string
+	std::vector<std::string> paths;
+	LLStringUtil::getTokens(comma_delim_path_list, paths, ","); // split over ','
+
+	for(std::vector<std::string>::iterator it = paths.begin(), end_it = paths.end();
+		it != end_it;
+		++it)
+	{
+		(*it) = gDirUtilp->findSkinnedFilename(*it, base_xml_name);
+	}
+
+	// suck the translation xml files into memory
+	LLXMLNodePtr root;
+	bool success = LLXMLNode::getLayeredXMLNode(root, paths);
+	if (!success)
+	{
+		// couldn't load string table XML
+		return false;
+	}
+	else
+	{
+		// get those strings out of the XML
+		LLTrans::parseStrings(root, default_trans_args);
+		return true;
+	}
+|*==========================================================================*/
+}
+
+
+void updater_app_ui_init(void);
+void updater_app_quit(UpdaterAppState *app_state);
+void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state);
+std::string next_image_filename(std::string& image_path, LLDirIterator& iter);
+void display_error(GtkWidget *parent, std::string title, std::string message);
+BOOL install_package(std::string package_file, std::string destination);
+BOOL spawn_viewer(UpdaterAppState *app_state);
+
+extern "C" {
+	void on_window_closed(GtkWidget *sender, GdkEvent *event, gpointer state);
+	gpointer worker_thread_cb(gpointer *data);
+	int download_progress_cb(gpointer data, double t, double d, double utotal, double ulnow);
+	gboolean rotate_image_cb(gpointer data);
+	gboolean progress_update_timeout(gpointer data);
+	gboolean update_progress_text_timeout(gpointer data);
+}
+
+void updater_app_ui_init(UpdaterAppState *app_state)
+{
+	GtkWidget *vbox;
+	GtkWidget *summary_label;
+	GtkWidget *description_label;
+	GtkWidget *frame;
+
+	llassert(app_state != NULL);
+
+	// set up window and main container
+	std::string window_title = LLTrans::getString("UpdaterWindowTitle");
+	app_state->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+	gtk_window_set_title(GTK_WINDOW(app_state->window),
+			     window_title.c_str());
+	gtk_window_set_resizable(GTK_WINDOW(app_state->window), FALSE);
+	gtk_window_set_position(GTK_WINDOW(app_state->window),
+				GTK_WIN_POS_CENTER_ALWAYS);
+
+	gtk_container_set_border_width(GTK_CONTAINER(app_state->window), 12);
+	g_signal_connect(G_OBJECT(app_state->window), "delete-event",
+			 G_CALLBACK(on_window_closed), app_state);
+
+	vbox = gtk_vbox_new(FALSE, 6);
+	gtk_container_add(GTK_CONTAINER(app_state->window), vbox);
+
+	// set top label
+	std::ostringstream label_ostr;
+	label_ostr << "<big><b>"
+		   << LLTrans::getString("UpdaterNowUpdating")
+		   << "</b></big>";
+
+	summary_label = gtk_label_new(NULL);
+	gtk_label_set_use_markup(GTK_LABEL(summary_label), TRUE);
+	gtk_label_set_markup(GTK_LABEL(summary_label),
+			     label_ostr.str().c_str());
+	gtk_misc_set_alignment(GTK_MISC(summary_label), 0, 0.5);
+	gtk_box_pack_start(GTK_BOX(vbox), summary_label, FALSE, FALSE, 0);
+
+	// create the description label
+	description_label = gtk_label_new(LLTrans::getString("UpdaterUpdatingDescriptive").c_str());
+	gtk_label_set_line_wrap(GTK_LABEL(description_label), TRUE);
+	gtk_misc_set_alignment(GTK_MISC(description_label), 0, 0.5);
+	gtk_box_pack_start(GTK_BOX(vbox), description_label, FALSE, FALSE, 0);
+
+	// If an image path has been set, load the background images
+	if (!app_state->image_dir.empty()) {
+		frame = gtk_frame_new(NULL);
+		gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
+		gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+
+		// load the first image
+		app_state->image = gtk_image_new_from_file
+			(next_image_filename(app_state->image_dir, *app_state->image_dir_iter).c_str());
+		gtk_widget_set_size_request(app_state->image, 340, 310);
+		gtk_container_add(GTK_CONTAINER(frame), app_state->image);
+
+		// rotate the images every 5 seconds
+		app_state->image_rotation_timeout_id = g_timeout_add
+			(ROTATE_IMAGE_TIMEOUT, rotate_image_cb, app_state);
+	}
+
+	// set up progress bar, and update it roughly every 1/10 of a second
+	app_state->progress_bar = gtk_progress_bar_new();
+	gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar),
+				  LLTrans::getString("UpdaterProgressBarTextWithEllipses").c_str());
+	gtk_box_pack_start(GTK_BOX(vbox),
+			   app_state->progress_bar, FALSE, TRUE, 0);
+	app_state->progress_update_timeout_id = g_timeout_add
+		(UPDATE_PROGRESS_TIMEOUT, progress_update_timeout, app_state);
+	app_state->update_progress_text_timeout_id = g_timeout_add
+		(UPDATE_PROGRESS_TEXT_TIMEOUT, update_progress_text_timeout, app_state);
+
+	gtk_widget_show_all(app_state->window);
+}
+
+gboolean rotate_image_cb(gpointer data)
+{
+	UpdaterAppState *app_state;
+	std::string filename;
+
+	llassert(data != NULL);
+	app_state = (UpdaterAppState *) data;
+
+	filename = next_image_filename(app_state->image_dir, *app_state->image_dir_iter);
+
+	gdk_threads_enter();
+	gtk_image_set_from_file(GTK_IMAGE(app_state->image), filename.c_str());
+	gdk_threads_leave();
+
+	return TRUE;
+}
+
+std::string next_image_filename(std::string& image_path, LLDirIterator& iter)
+{
+	std::string image_filename;
+	iter.next(image_filename);
+	return gDirUtilp->add(image_path, image_filename);
+}
+
+void on_window_closed(GtkWidget *sender, GdkEvent* event, gpointer data)
+{
+	UpdaterAppState *app_state;
+
+	llassert(data != NULL);
+	app_state = (UpdaterAppState *) data;
+
+	updater_app_quit(app_state);
+}
+
+void updater_app_quit(UpdaterAppState *app_state)
+{
+	if (app_state != NULL)
+	{
+		g_source_remove(app_state->progress_update_timeout_id);
+
+		if (!app_state->image_dir.empty())
+		{
+			g_source_remove(app_state->image_rotation_timeout_id);
+		}
+	}
+
+	gtk_main_quit();
+}
+
+void display_error(GtkWidget *parent, std::string title, std::string message)
+{
+	GtkWidget *dialog;
+
+	dialog = gtk_message_dialog_new(GTK_WINDOW(parent),
+					GTK_DIALOG_DESTROY_WITH_PARENT,
+					GTK_MESSAGE_ERROR,
+					GTK_BUTTONS_OK,
+					"%s", message.c_str());
+	gtk_window_set_title(GTK_WINDOW(dialog), title.c_str());
+	gtk_dialog_run(GTK_DIALOG(dialog));
+	gtk_widget_destroy(dialog);
+}
+
+gpointer worker_thread_cb(gpointer data)
+{
+	UpdaterAppState *app_state;
+	CURL *curl;
+	CURLcode result;
+	FILE *package_file;
+	GError *error = NULL;
+	int fd;
+
+	//g_return_val_if_fail (data != NULL, NULL);
+	app_state = (UpdaterAppState *) data;
+
+	try {
+
+		if(!app_state->url.empty())
+		{
+			char* tmp_local_filename = NULL;
+			// create temporary file to store the package.
+			fd = g_file_open_tmp
+				("secondlife-update-XXXXXX", &tmp_local_filename, &error);
+			if (error != NULL)
+			{
+				llerrs << "Unable to create temporary file: "
+					   << error->message
+					   << llendl;
+
+				g_error_free(error);
+				throw 0;
+			}
+
+			if(tmp_local_filename != NULL)
+			{
+				app_state->file = tmp_local_filename;
+				g_free(tmp_local_filename);
+			}
+
+			package_file = fdopen(fd, "wb");
+			if (package_file == NULL)
+			{
+				llerrs << "Failed to create temporary file: "
+					   << app_state->file.c_str()
+					   << llendl;
+
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
+				throw 0;
+			}
+
+			// initialize curl and start downloading the package
+			llinfos << "Downloading package: " << app_state->url << llendl;
+
+			curl = curl_easy_init();
+			if (curl == NULL)
+			{
+				llerrs << "Failed to initialize libcurl" << llendl;
+
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
+				throw 0;
+			}
+
+			curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str());
+			curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE);
+			curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE);
+			curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file);
+			curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
+			curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION,
+							 &download_progress_cb);
+			curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state);
+
+			result = curl_easy_perform(curl);
+			fclose(package_file);
+			curl_easy_cleanup(curl);
+
+			if (result)
+			{
+				llerrs << "Failed to download update: "
+					   << app_state->url
+					   << llendl;
+
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
+
+				throw 0;
+			}
+		}
+
+		// now pulse the progres bar back and forth while the package is
+		// being unpacked
+		gdk_threads_enter();
+		std::string installing_msg = LLTrans::getString("UpdaterNowInstalling");
+		gtk_progress_bar_set_text(
+			GTK_PROGRESS_BAR(app_state->progress_bar),
+			installing_msg.c_str());
+		app_state->activity_mode = TRUE;
+		gdk_threads_leave();
+
+		// *TODO: if the destination is not writable, terminate this
+		// thread and show file chooser?
+		if (!install_package(app_state->file.c_str(), app_state->dest_dir))
+		{
+			llwarns << "Failed to install package to destination: "
+				<< app_state->dest_dir
+				<< llendl;
+
+			gdk_threads_enter();
+			display_error(app_state->window,
+						  LLTrans::getString("UpdaterFailInstallTitle"),
+						  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+			//"Failed to update " + app_state->app_name,
+			gdk_threads_leave();
+			throw 0;
+		}
+
+		// try to spawn the new viewer
+		if (!spawn_viewer(app_state))
+		{
+			llwarns << "Viewer was not installed properly in : "
+				<< app_state->dest_dir
+				<< llendl;
+
+			gdk_threads_enter();
+			display_error(app_state->window,
+						  LLTrans::getString("UpdaterFailStartTitle"),
+						  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+			gdk_threads_leave();
+			throw 0;
+		}
+	}
+	catch (...)
+	{
+		app_state->failure = TRUE;
+	}
+
+	gdk_threads_enter();
+	updater_app_quit(app_state);
+	gdk_threads_leave();
+
+	return NULL;
+}
+
+
+gboolean less_anal_gspawnsync(gchar **argv,
+			      gchar **stderr_output,
+			      gint *child_exit_status,
+			      GError **spawn_error)
+{
+	// store current SIGCHLD handler if there is one, replace with default
+	// handler to make glib happy
+	struct sigaction sigchld_backup;
+	struct sigaction sigchld_appease_glib;
+	sigchld_appease_glib.sa_handler = SIG_DFL;
+	sigemptyset(&sigchld_appease_glib.sa_mask);
+	sigchld_appease_glib.sa_flags = 0;
+	sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup);
+
+	gboolean rtn = g_spawn_sync(NULL,
+				    argv,
+				    NULL,
+				    (GSpawnFlags) (G_SPAWN_STDOUT_TO_DEV_NULL),
+				    NULL,
+				    NULL,
+				    NULL,
+				    stderr_output,
+				    child_exit_status,
+				    spawn_error);
+
+	// restore SIGCHLD handler
+	sigaction(SIGCHLD, &sigchld_backup, NULL);
+
+	return rtn;
+}
+
+
+// perform a rename, or perform a (prompted) root rename if that fails
+int
+rename_with_sudo_fallback(const std::string& filename, const std::string& newname)
+{
+	int rtncode = ::rename(filename.c_str(), newname.c_str());
+	lldebugs << "rename result is: " << rtncode << " / " << errno << llendl;
+	if (rtncode && (EACCES == errno || EPERM == errno || EXDEV == errno))
+	{
+		llinfos << "Permission problem in rename, or moving between different mount points.  Retrying as a mv under a sudo." << llendl;
+		// failed due to permissions, try again as a gksudo or kdesu mv wrapper hack
+		char *sudo_cmd = NULL;
+		sudo_cmd = g_find_program_in_path("gksudo");
+		if (!sudo_cmd)
+		{
+			sudo_cmd = g_find_program_in_path("kdesu");
+		}
+		if (sudo_cmd)
+		{
+			char *mv_cmd = NULL;
+			mv_cmd = g_find_program_in_path("mv");
+			if (mv_cmd)
+			{
+				char *src_string_copy = g_strdup(filename.c_str());
+				char *dst_string_copy = g_strdup(newname.c_str());
+				char* argv[] =
+					{
+						sudo_cmd,
+						mv_cmd,
+						src_string_copy,
+						dst_string_copy,
+						NULL
+					};
+
+				gchar *stderr_output = NULL;
+				gint child_exit_status = 0;
+				GError *spawn_error = NULL;
+				if (!less_anal_gspawnsync(argv, &stderr_output,
+							  &child_exit_status, &spawn_error))
+				{
+					llwarns << "Failed to spawn child process: "
+						<< spawn_error->message
+						<< llendl;
+				}
+				else if (child_exit_status)
+				{
+					llwarns << "mv command failed: "
+						<< (stderr_output ? stderr_output : "(no reason given)")
+						<< llendl;
+				}
+				else
+				{
+					// everything looks good, clear the error code
+					rtncode = 0;
+				}
+
+				g_free(src_string_copy);
+				g_free(dst_string_copy);
+				if (spawn_error) g_error_free(spawn_error);
+			}
+		}
+	}
+	return rtncode;
+}
+
+gboolean install_package(std::string package_file, std::string destination)
+{
+	char *tar_cmd = NULL;
+	std::ostringstream command;
+
+	// Find the absolute path to the 'tar' command.
+	tar_cmd = g_find_program_in_path("tar");
+	if (!tar_cmd)
+	{
+		llerrs << "`tar' was not found in $PATH" << llendl;
+		return FALSE;
+	}
+	llinfos << "Found tar command: " << tar_cmd << llendl;
+
+	// Unpack the tarball in a temporary place first, then move it to
+	// its final destination
+	std::string tmp_dest_dir = gDirUtilp->getTempFilename();
+	if (LLFile::mkdir(tmp_dest_dir, 0744))
+	{
+		llerrs << "Failed to create directory: "
+		       << destination
+		       << llendl;
+
+		return FALSE;
+	}
+
+	char *package_file_string_copy = g_strdup(package_file.c_str());
+	char *tmp_dest_dir_string_copy = g_strdup(tmp_dest_dir.c_str());
+	gchar *argv[8] = {
+		tar_cmd,
+		const_cast<gchar*>("--strip"), const_cast<gchar*>("1"),
+		const_cast<gchar*>("-xjf"),
+		package_file_string_copy,
+		const_cast<gchar*>("-C"), tmp_dest_dir_string_copy,
+		NULL,
+	};
+
+	llinfos << "Untarring package: " << package_file << llendl;
+
+	// store current SIGCHLD handler if there is one, replace with default
+	// handler to make glib happy
+	struct sigaction sigchld_backup;
+	struct sigaction sigchld_appease_glib;
+	sigchld_appease_glib.sa_handler = SIG_DFL;
+	sigemptyset(&sigchld_appease_glib.sa_mask);
+	sigchld_appease_glib.sa_flags = 0;
+	sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup);
+
+	gchar *stderr_output = NULL;
+	gint child_exit_status = 0;
+	GError *untar_error = NULL;
+	if (!less_anal_gspawnsync(argv, &stderr_output,
+				  &child_exit_status, &untar_error))
+	{
+		llwarns << "Failed to spawn child process: "
+			<< untar_error->message
+			<< llendl;
+		return FALSE;
+	}
+
+	if (child_exit_status)
+	{
+	 	llwarns << "Untar command failed: "
+			<< (stderr_output ? stderr_output : "(no reason given)")
+			<< llendl;
+		return FALSE;
+	}
+
+	g_free(tar_cmd);
+	g_free(package_file_string_copy);
+	g_free(tmp_dest_dir_string_copy);
+	g_free(stderr_output);
+	if (untar_error) g_error_free(untar_error);
+
+	// move the existing package out of the way if it exists
+	if (gDirUtilp->fileExists(destination))
+	{
+		std::string backup_dir = destination + ".backup";
+		int oldcounter = 1;
+		while (gDirUtilp->fileExists(backup_dir))
+		{
+			// find a foo.backup.N folder name that isn't taken yet
+			backup_dir = destination + ".backup." + llformat("%d", oldcounter);
+			++oldcounter;
+		}
+
+		if (rename_with_sudo_fallback(destination, backup_dir))
+		{
+			llwarns << "Failed to move directory: '"
+				<< destination << "' -> '" << backup_dir
+				<< llendl;
+			return FALSE;
+		}
+	}
+
+	// The package has been unpacked in a staging directory, now we just
+	// need to move it to its destination.
+	if (rename_with_sudo_fallback(tmp_dest_dir, destination))
+	{
+		llwarns << "Failed to move installation to the destination: "
+			<< destination
+			<< llendl;
+		return FALSE;
+	}
+
+	// \0/ Success!
+	return TRUE;
+}
+
+gboolean progress_update_timeout(gpointer data)
+{
+	UpdaterAppState *app_state;
+
+	llassert(data != NULL);
+
+	app_state = (UpdaterAppState *) data;
+
+	gdk_threads_enter();
+	if (app_state->activity_mode)
+	{
+		gtk_progress_bar_pulse
+			(GTK_PROGRESS_BAR(app_state->progress_bar));
+	}
+	else
+	{
+		gtk_progress_set_value(GTK_PROGRESS(app_state->progress_bar),
+				       app_state->progress_value);
+	}
+	gdk_threads_leave();
+
+	return TRUE;
+}
+
+gboolean update_progress_text_timeout(gpointer data)
+{
+	UpdaterAppState *app_state;
+
+	llassert(data != NULL);
+	app_state = (UpdaterAppState *) data;
+
+	if (app_state->activity_mode == TRUE)
+	{
+		// We no longer need this timeout, it will be removed.
+		return FALSE;
+	}
+
+	if (!app_state->progress_value)
+	{
+		return TRUE;
+	}
+
+	std::string progress_text = llformat((LLTrans::getString("UpdaterProgressBarText")+" (%.0f%%)").c_str(), app_state->progress_value);
+
+	gdk_threads_enter();
+	gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar),
+				  progress_text.c_str());
+	gdk_threads_leave();
+
+	return TRUE;
+}
+
+int download_progress_cb(gpointer data,
+			 double t,
+			 double d,
+			 double utotal,
+			 double ulnow)
+{
+	UpdaterAppState *app_state;
+
+	llassert(data != NULL);
+	app_state = (UpdaterAppState *) data;
+
+	if (t <= 0.0)
+	{
+		app_state->progress_value = 0;
+	}
+	else
+	{
+		app_state->progress_value = d * 100.0 / t;
+	}
+	return 0;
+}
+
+BOOL spawn_viewer(UpdaterAppState *app_state)
+{
+	llassert(app_state != NULL);
+
+	std::string cmd = app_state->dest_dir + "/secondlife";
+	GError *error = NULL;
+
+	// We want to spawn the Viewer on the same display as the updater app
+	gboolean success = gdk_spawn_command_line_on_screen
+		(gtk_widget_get_screen(app_state->window), cmd.c_str(), &error);
+
+	if (!success)
+	{
+		llwarns << "Failed to launch viewer: " << error->message
+			<< llendl;
+	}
+
+	if (error) g_error_free(error);
+
+	return success;
+}
+
+void show_usage_and_exit()
+{
+	std::cout << "Usage: linux-updater <--url URL | --file FILE> --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE"
+		  << "[--image-dir PATH]"
+		  << std::endl;
+	exit(1);
+}
+
+void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
+{
+	int i;
+
+	for (i = 1; i < argc; i++)
+	{
+		if ((!strcmp(argv[i], "--url")) && (++i < argc))
+		{
+			app_state->url = argv[i];
+		}
+		else if ((!strcmp(argv[i], "--file")) && (++i < argc))
+		{
+			app_state->file = argv[i];
+		}
+		else if ((!strcmp(argv[i], "--name")) && (++i < argc))
+		{
+			app_state->app_name = argv[i];
+		}
+		else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc))
+		{
+			app_state->image_dir = argv[i];
+			app_state->image_dir_iter = new LLDirIterator(argv[i], "*.jpg");
+		}
+		else if ((!strcmp(argv[i], "--dest")) && (++i < argc))
+		{
+			app_state->dest_dir = argv[i];
+		}
+		else if ((!strcmp(argv[i], "--stringsdir")) && (++i < argc))
+		{
+			app_state->strings_dirs = argv[i];
+		}
+		else if ((!strcmp(argv[i], "--stringsfile")) && (++i < argc))
+		{
+			app_state->strings_file = argv[i];
+		}
+		else
+		{
+			// show usage, an invalid option was given.
+			show_usage_and_exit();
+		}
+	}
+
+	if (app_state->app_name.empty()
+	    || (app_state->url.empty() && app_state->file.empty())
+	    || app_state->dest_dir.empty())
+	{
+		show_usage_and_exit();
+	}
+
+	app_state->progress_value = 0.0;
+	app_state->activity_mode = FALSE;
+	app_state->failure = FALSE;
+
+	translate_init(app_state->strings_dirs, app_state->strings_file);
+}
+
+int main(int argc, char **argv)
+{
+	UpdaterAppState* app_state = new UpdaterAppState;
+
+	parse_args_and_init(argc, argv, app_state);
+
+	// Initialize logger, and rename old log file
+	gDirUtilp->initAppDirs("SecondLife");
+	LLError::initForApplication
+		(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+	std::string old_log_file = gDirUtilp->getExpandedFilename
+		(LL_PATH_LOGS, "updater.log.old");
+	std::string log_file =
+		gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log");
+	LLFile::rename(log_file, old_log_file);
+	LLError::logToFile(log_file);
+
+	// initialize gthreads and gtk+
+	if (!g_thread_supported())
+	{
+		g_thread_init(NULL);
+		gdk_threads_init();
+	}
+
+	gtk_init(&argc, &argv);
+
+	// create UI
+	updater_app_ui_init(app_state);
+
+	//llinfos << "SAMPLE TRANSLATION IS: " << LLTrans::getString("LoginInProgress") << llendl;
+
+	// create download thread
+	g_thread_create(GThreadFunc(worker_thread_cb), app_state, FALSE, NULL);
+
+	gdk_threads_enter();
+	gtk_main();
+	gdk_threads_leave();
+
+	// Delete the file only if created from url download.
+	if(!app_state->url.empty() && !app_state->file.empty())
+	{
+		if (gDirUtilp->fileExists(app_state->file))
+		{
+			LLFile::remove(app_state->file);
+		}
+	}
+
+	bool success = !app_state->failure;
+	delete app_state->image_dir_iter;
+	delete app_state;
+	return success ? 0 : 1;
+}
+
+/*****************************************************************************
+*   Dummy LLTrans implementation (IQA-490)
+*****************************************************************************/
+static LLTrans sStaticStrings;
+
+// lookup
+std::string LLTrans::_getString(const std::string& key) const
+{
+	MessageMap::const_iterator found = mMessages.find(key);
+	if (found != mMessages.end())
+	{
+		return found->second;
+	}
+	LL_WARNS("linux_updater") << "No message for key '" << key
+							  << "' -- add to LLTrans::LLTrans() in linux_updater.cpp"
+							  << LL_ENDL;
+	return key;
+}
+
+// static lookup
+std::string LLTrans::getString(const std::string& key)
+{
+    return sLLTransInstance._getString(key);
+}
+
+// initialization
+LLTrans::LLTrans()
+{
+	typedef std::pair<const char*, const char*> Pair;
+	static const Pair data[] =
+	{
+		Pair("UpdaterFailDownloadTitle",
+			 "Failed to download update"),
+		Pair("UpdaterFailInstallTitle",
+			 "Failed to install update"),
+		Pair("UpdaterFailStartTitle",
+			 "Failed to start viewer"),
+		Pair("UpdaterFailUpdateDescriptive",
+			 "An error occurred while updating Second Life. "
+			 "Please download the latest version from www.secondlife.com."),
+		Pair("UpdaterNowInstalling",
+			 "Installing Second Life..."),
+		Pair("UpdaterNowUpdating",
+			 "Now updating Second Life..."),
+		Pair("UpdaterProgressBarText",
+			 "Downloading update"),
+		Pair("UpdaterProgressBarTextWithEllipses",
+			 "Downloading update..."),
+		Pair("UpdaterUpdatingDescriptive",
+			 "Your Second Life Viewer is being updated to the latest release. "
+			 "This may take some time, so please be patient."),
+		Pair("UpdaterWindowTitle",
+			 "Second Life Update")
+	};
+
+	BOOST_FOREACH(Pair pair, data)
+	{
+		mMessages[pair.first] = pair.second;
+	}
+}
diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0dbd58b7cd7e6a22aa6a7e630923e9636ac9b764
--- /dev/null
+++ b/indra/llappearance/CMakeLists.txt
@@ -0,0 +1,118 @@
+# -*- cmake -*-
+
+project(llappearance)
+
+include(00-Common)
+include(LLCommon)
+include(LLCharacter)
+include(LLImage)
+include(LLInventory)
+include(LLMath)
+include(LLMessage)
+include(LLRender)
+include(LLVFS)
+include(LLWindow)
+include(LLXML)
+include(Linking)
+
+include_directories(
+    ${LLCOMMON_INCLUDE_DIRS}
+    ${LLCHARACTER_INCLUDE_DIRS}
+    ${LLIMAGE_INCLUDE_DIRS}
+    ${LLINVENTORY_INCLUDE_DIRS}
+    ${LLMATH_INCLUDE_DIRS}
+    ${LLRENDER_INCLUDE_DIRS}
+    ${LLVFS_INCLUDE_DIRS}
+    ${LLWINDOW_INCLUDE_DIRS}
+    ${LLXML_INCLUDE_DIRS}
+    )
+
+set(llappearance_SOURCE_FILES
+    llavatarappearance.cpp
+    llavatarjoint.cpp
+    llavatarjointmesh.cpp
+    lldriverparam.cpp
+    lllocaltextureobject.cpp
+    llpolyskeletaldistortion.cpp
+    llpolymesh.cpp
+    llpolymorph.cpp
+    lltexglobalcolor.cpp
+    lltexlayer.cpp
+    lltexlayerparams.cpp
+    lltexturemanagerbridge.cpp
+    llwearable.cpp
+    llwearabledata.cpp
+    llwearabletype.cpp
+    llviewervisualparam.cpp
+    llavatarappearancedefines.cpp
+    )
+    
+set(llappearance_HEADER_FILES
+    CMakeLists.txt
+
+    llavatarappearance.h
+    llavatarjoint.h
+    llavatarjointmesh.h
+    lldriverparam.h
+    lljointpickname.h
+    lllocaltextureobject.h
+    llpolyskeletaldistortion.h
+    llpolymesh.h
+    llpolymorph.h
+    lltexglobalcolor.h
+    lltexlayer.h
+    lltexlayerparams.h
+    lltexturemanagerbridge.h
+    llwearable.h
+    llwearabledata.h
+    llwearabletype.h
+    llviewervisualparam.h
+    llavatarappearancedefines.h
+    )
+
+set_source_files_properties(${llappearance_HEADER_FILES}
+                            PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES})
+
+add_library (llappearance ${llappearance_SOURCE_FILES})
+
+target_link_libraries(llappearance
+    ${LLCHARACTER_LIBRARIES}
+    ${LLINVENTORY_LIBRARIES}
+    ${LLIMAGE_LIBRARIES}
+    ${LLRENDER_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLCOMMON_LIBRARIES}
+    )
+
+if (BUILD_HEADLESS)
+  add_library (llappearanceheadless ${llappearance_SOURCE_FILES})
+  
+  target_link_libraries(llappearanceheadless
+      ${LLCHARACTER_LIBRARIES}
+      ${LLINVENTORY_LIBRARIES}
+      ${LLIMAGE_LIBRARIES}
+      ${LLRENDERHEADLESS_LIBRARIES}
+      ${LLVFS_LIBRARIES}
+      ${LLMATH_LIBRARIES}
+      ${LLXML_LIBRARIES}
+      ${LLMATH_LIBRARIES}
+      ${LLCOMMON_LIBRARIES}
+      )
+endif (BUILD_HEADLESS)
+
+#add unit tests
+#if (LL_TESTS)
+#    INCLUDE(LLAddBuildTest)
+#    SET(llappearance_TEST_SOURCE_FILES
+#      # no real unit tests yet!
+#      )
+#    LL_ADD_PROJECT_UNIT_TESTS(llappearance "${llappearance_TEST_SOURCE_FILES}")
+
+    #set(TEST_DEBUG on)
+#    set(test_libs llappearance ${LLCOMMON_LIBRARIES})
+#endif (LL_TESTS)
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3bb759d45879890b3e81b78be9b9db48971d7a0b
--- /dev/null
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -0,0 +1,1953 @@
+/** 
+ * @File llavatarappearance.cpp
+ * @brief Implementation of LLAvatarAppearance class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#if LL_MSVC
+// disable warning about boost::lexical_cast returning uninitialized data
+// when it fails to parse the string
+#pragma warning (disable:4701)
+#endif
+
+#include "linden_common.h"
+
+#include "llavatarappearance.h"
+#include "llavatarappearancedefines.h"
+#include "llavatarjointmesh.h"
+#include "imageids.h"
+#include "lldir.h"
+#include "lldeleteutils.h"
+#include "llpolymorph.h"
+#include "llpolymesh.h"
+#include "llpolyskeletaldistortion.h"
+#include "llstl.h"
+#include "lltexglobalcolor.h"
+#include "llwearabledata.h"
+
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+#include <boost/lexical_cast.hpp>
+
+using namespace LLAvatarAppearanceDefines;
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+const std::string AVATAR_DEFAULT_CHAR = "avatar";
+const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
+
+/*********************************************************************************
+ **                                                                             **
+ ** Begin private LLAvatarAppearance Support classes
+ **
+ **/
+
+//------------------------------------------------------------------------
+// LLAvatarBoneInfo
+// Trans/Scale/Rot etc. info about each avatar bone.  Used by LLVOAvatarSkeleton.
+//------------------------------------------------------------------------
+class LLAvatarBoneInfo
+{
+	friend class LLAvatarAppearance;
+	friend class LLAvatarSkeletonInfo;
+public:
+	LLAvatarBoneInfo() : mIsJoint(FALSE) {}
+	~LLAvatarBoneInfo()
+	{
+		std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
+	}
+	BOOL parseXml(LLXmlTreeNode* node);
+	
+private:
+	std::string mName;
+	BOOL mIsJoint;
+	LLVector3 mPos;
+	LLVector3 mRot;
+	LLVector3 mScale;
+	LLVector3 mPivot;
+	typedef std::vector<LLAvatarBoneInfo*> child_list_t;
+	child_list_t mChildList;
+};
+
+//------------------------------------------------------------------------
+// LLAvatarSkeletonInfo
+// Overall avatar skeleton
+//------------------------------------------------------------------------
+class LLAvatarSkeletonInfo
+{
+	friend class LLAvatarAppearance;
+public:
+	LLAvatarSkeletonInfo() :
+		mNumBones(0), mNumCollisionVolumes(0) {}
+	~LLAvatarSkeletonInfo()
+	{
+		std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer());
+	}
+	BOOL parseXml(LLXmlTreeNode* node);
+	S32 getNumBones() const { return mNumBones; }
+	S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; }
+	
+private:
+	S32 mNumBones;
+	S32 mNumCollisionVolumes;
+	typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t;
+	bone_info_list_t mBoneInfoList;
+};
+
+//-----------------------------------------------------------------------------
+// LLAvatarXmlInfo
+//-----------------------------------------------------------------------------
+
+LLAvatarAppearance::LLAvatarXmlInfo::LLAvatarXmlInfo()
+	: mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0)
+{
+}
+
+LLAvatarAppearance::LLAvatarXmlInfo::~LLAvatarXmlInfo()
+{
+	std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer());
+	std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());		
+	std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer());
+	deleteAndClear(mTexSkinColorInfo);
+	deleteAndClear(mTexHairColorInfo);
+	deleteAndClear(mTexEyeColorInfo);
+	std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());		
+	std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer());
+	std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
+}
+
+
+/**
+ **
+ ** End LLAvatarAppearance Support classes
+ **                                                                             **
+ *********************************************************************************/
+
+//-----------------------------------------------------------------------------
+// Static Data
+//-----------------------------------------------------------------------------
+LLXmlTree LLAvatarAppearance::sXMLTree;
+LLXmlTree LLAvatarAppearance::sSkeletonXMLTree;
+LLAvatarSkeletonInfo* LLAvatarAppearance::sAvatarSkeletonInfo = NULL;
+LLAvatarAppearance::LLAvatarXmlInfo* LLAvatarAppearance::sAvatarXmlInfo = NULL;
+
+
+LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
+	LLCharacter(),
+	mIsDummy(FALSE),
+	mTexSkinColor( NULL ),
+	mTexHairColor( NULL ),
+	mTexEyeColor( NULL ),
+	mPelvisToFoot(0.f),
+	mHeadOffset(),
+	mRoot(NULL),
+	mWearableData(wearable_data)
+{
+	llassert_always(mWearableData);
+	mBakedTextureDatas.resize(LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
+	for (U32 i = 0; i < mBakedTextureDatas.size(); i++ )
+	{
+		mBakedTextureDatas[i].mLastTextureID = IMG_DEFAULT_AVATAR;
+		mBakedTextureDatas[i].mTexLayerSet = NULL;
+		mBakedTextureDatas[i].mIsLoaded = false;
+		mBakedTextureDatas[i].mIsUsed = false;
+		mBakedTextureDatas[i].mMaskTexName = 0;
+		mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i);
+	}
+
+	mIsBuilt = FALSE;
+
+	mNumCollisionVolumes = 0;
+	mCollisionVolumes = NULL;
+}
+
+// virtual
+void LLAvatarAppearance::initInstance()
+{
+	//-------------------------------------------------------------------------
+	// initialize joint, mesh and shape members
+	//-------------------------------------------------------------------------
+	mRoot = createAvatarJoint();
+	mRoot->setName( "mRoot" );
+
+	for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+		 ++iter)
+	{
+		const EMeshIndex mesh_index = iter->first;
+		const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second;
+		LLAvatarJoint* joint = createAvatarJoint();
+		joint->setName(mesh_dict->mName);
+		joint->setMeshID(mesh_index);
+		mMeshLOD.push_back(joint);
+		
+		/* mHairLOD.setName("mHairLOD");
+		   mHairMesh0.setName("mHairMesh0");
+		   mHairMesh0.setMeshID(MESH_ID_HAIR);
+		   mHairMesh1.setName("mHairMesh1"); */
+		for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
+		{
+			LLAvatarJointMesh* mesh = createAvatarJointMesh();
+			std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast<std::string>(lod);
+			// We pre-pended an m - need to capitalize first character for camelCase
+			mesh_name[1] = toupper(mesh_name[1]);
+			mesh->setName(mesh_name);
+			mesh->setMeshID(mesh_index);
+			mesh->setPickName(mesh_dict->mPickName);
+			mesh->setIsTransparent(FALSE);
+			switch((int)mesh_index)
+			{
+				case MESH_ID_HAIR:
+					mesh->setIsTransparent(TRUE);
+					break;
+				case MESH_ID_SKIRT:
+					mesh->setIsTransparent(TRUE);
+					break;
+				case MESH_ID_EYEBALL_LEFT:
+				case MESH_ID_EYEBALL_RIGHT:
+					mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
+					break;
+			}
+			
+			joint->mMeshParts.push_back(mesh);
+		}
+	}
+
+	//-------------------------------------------------------------------------
+	// associate baked textures with meshes
+	//-------------------------------------------------------------------------
+	for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+		 ++iter)
+	{
+		const EMeshIndex mesh_index = iter->first;
+		const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second;
+		const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID;
+		// Skip it if there's no associated baked texture.
+		if (baked_texture_index == BAKED_NUM_INDICES) continue;
+		
+		for (avatar_joint_mesh_list_t::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();
+			 iter != mMeshLOD[mesh_index]->mMeshParts.end(); 
+			 ++iter)
+		{
+			LLAvatarJointMesh* mesh = (*iter);
+			mBakedTextureDatas[(int)baked_texture_index].mJointMeshes.push_back(mesh);
+		}
+	}
+
+	buildCharacter();
+
+}
+
+// virtual
+LLAvatarAppearance::~LLAvatarAppearance()
+{
+	deleteAndClear(mTexSkinColor);
+	deleteAndClear(mTexHairColor);
+	deleteAndClear(mTexEyeColor);
+
+	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+	{
+		deleteAndClear(mBakedTextureDatas[i].mTexLayerSet);
+		mBakedTextureDatas[i].mJointMeshes.clear();
+
+		for (morph_list_t::iterator iter2 = mBakedTextureDatas[i].mMaskedMorphs.begin();
+			 iter2 != mBakedTextureDatas[i].mMaskedMorphs.end(); iter2++)
+		{
+			LLMaskedMorph* masked_morph = (*iter2);
+			delete masked_morph;
+		}
+	}
+
+	if (mRoot) mRoot->removeAllChildren();
+	mJointMap.clear();
+
+	clearSkeleton();
+	deleteAndClearArray(mCollisionVolumes);
+
+	deleteAndClear(mTexSkinColor);
+	deleteAndClear(mTexHairColor);
+	deleteAndClear(mTexEyeColor);
+
+	std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer());
+	mPolyMeshes.clear();
+
+	for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin();
+		 jointIter != mMeshLOD.end(); 
+		 ++jointIter)
+	{
+		LLAvatarJoint* joint = *jointIter;
+		std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer());
+		joint->mMeshParts.clear();
+	}
+	std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer());
+	mMeshLOD.clear();
+}
+
+//static
+void LLAvatarAppearance::initClass()
+{
+	std::string xmlFile;
+
+	xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml";
+	BOOL success = sXMLTree.parseFile( xmlFile, FALSE );
+	if (!success)
+	{
+		llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl;
+	}
+
+	// now sanity check xml file
+	LLXmlTreeNode* root = sXMLTree.getRoot();
+	if (!root) 
+	{
+		llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl;
+		return;
+	}
+
+	//-------------------------------------------------------------------------
+	// <linden_avatar version="1.0"> (root)
+	//-------------------------------------------------------------------------
+	if( !root->hasName( "linden_avatar" ) )
+	{
+		llerrs << "Invalid avatar file header: " << xmlFile << llendl;
+	}
+	
+	std::string version;
+	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
+	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
+	{
+		llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl;
+	}
+
+	S32 wearable_def_version = 1;
+	static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version");
+	root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version );
+	LLWearable::setCurrentDefinitionVersion( wearable_def_version );
+
+	std::string mesh_file_name;
+
+	LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" );
+	if (!skeleton_node)
+	{
+		llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl;
+		return;
+	}
+	
+	std::string skeleton_file_name;
+	static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
+	if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name))
+	{
+		llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl;
+	}
+	
+	std::string skeleton_path;
+	skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name);
+	if (!parseSkeletonFile(skeleton_path))
+	{
+		llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;
+	}
+
+	// Process XML data
+
+	// avatar_skeleton.xml
+	if (sAvatarSkeletonInfo)
+	{ //this can happen if a login attempt failed
+		delete sAvatarSkeletonInfo;
+	}
+	sAvatarSkeletonInfo = new LLAvatarSkeletonInfo;
+	if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
+	{
+		llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl;
+	}
+	// parse avatar_lad.xml
+	if (sAvatarXmlInfo)
+	{ //this can happen if a login attempt failed
+		deleteAndClear(sAvatarXmlInfo);
+	}
+	sAvatarXmlInfo = new LLAvatarXmlInfo;
+	if (!sAvatarXmlInfo->parseXmlSkeletonNode(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+	if (!sAvatarXmlInfo->parseXmlMeshNodes(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+	if (!sAvatarXmlInfo->parseXmlColorNodes(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+	if (!sAvatarXmlInfo->parseXmlLayerNodes(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+	if (!sAvatarXmlInfo->parseXmlDriverNodes(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+	if (!sAvatarXmlInfo->parseXmlMorphNodes(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+}
+
+void LLAvatarAppearance::cleanupClass()
+{
+	deleteAndClear(sAvatarXmlInfo);
+	// *TODO: What about sAvatarSkeletonInfo ???
+	sSkeletonXMLTree.cleanup();
+	sXMLTree.cleanup();
+}
+
+using namespace LLAvatarAppearanceDefines;
+
+//------------------------------------------------------------------------
+// The viewer can only suggest a good size for the agent,
+// the simulator will keep it inside a reasonable range.
+void LLAvatarAppearance::computeBodySize() 
+{
+	LLVector3 pelvis_scale = mPelvisp->getScale();
+
+	// some of the joints have not been cached
+	LLVector3 skull = mSkullp->getPosition();
+	//LLVector3 skull_scale = mSkullp->getScale();
+
+	LLVector3 neck = mNeckp->getPosition();
+	LLVector3 neck_scale = mNeckp->getScale();
+
+	LLVector3 chest = mChestp->getPosition();
+	LLVector3 chest_scale = mChestp->getScale();
+
+	// the rest of the joints have been cached
+	LLVector3 head = mHeadp->getPosition();
+	LLVector3 head_scale = mHeadp->getScale();
+
+	LLVector3 torso = mTorsop->getPosition();
+	LLVector3 torso_scale = mTorsop->getScale();
+
+	LLVector3 hip = mHipLeftp->getPosition();
+	LLVector3 hip_scale = mHipLeftp->getScale();
+
+	LLVector3 knee = mKneeLeftp->getPosition();
+	LLVector3 knee_scale = mKneeLeftp->getScale();
+
+	LLVector3 ankle = mAnkleLeftp->getPosition();
+	LLVector3 ankle_scale = mAnkleLeftp->getScale();
+
+	LLVector3 foot  = mFootLeftp->getPosition();
+
+	F32 old_offset = mAvatarOffset.mV[VZ];
+
+	mAvatarOffset.mV[VZ] = getVisualParamWeight(AVATAR_HOVER);
+
+	mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
+				 	knee.mV[VZ] * hip_scale.mV[VZ] -
+				 	ankle.mV[VZ] * knee_scale.mV[VZ] -
+				 	foot.mV[VZ] * ankle_scale.mV[VZ];
+
+	LLVector3 new_body_size;
+	new_body_size.mV[VZ] = mPelvisToFoot +
+					   // the sqrt(2) correction below is an approximate
+					   // correction to get to the top of the head
+					   F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) + 
+					   head.mV[VZ] * neck_scale.mV[VZ] + 
+					   neck.mV[VZ] * chest_scale.mV[VZ] + 
+					   chest.mV[VZ] * torso_scale.mV[VZ] + 
+					   torso.mV[VZ] * pelvis_scale.mV[VZ]; 
+
+	// TODO -- measure the real depth and width
+	new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
+	new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
+
+	mAvatarOffset.mV[VX] = 0.0f;
+	mAvatarOffset.mV[VY] = 0.0f;
+
+	// Certain configurations of avatars can force the overall height (with offset) to go negative.
+	// Enforce a constraint to make sure we don't go below 0.1 meters.
+	// Camera positioning and other things start to break down when your avatar is "walking" while being fully underground
+	if (new_body_size.mV[VZ] + mAvatarOffset.mV[VZ] < 0.1f) 
+	{
+		mAvatarOffset.mV[VZ] = -(new_body_size.mV[VZ] - 0.11f); // avoid floating point rounding making the above check continue to fail.
+
+		llassert(new_body_size.mV[VZ] + mAvatarOffset.mV[VZ] >= 0.1f);
+
+		if (mWearableData && isSelf()) 
+		{
+			LLWearable* shape = mWearableData->getWearable(LLWearableType::WT_SHAPE, 0);
+			if (shape) 
+			{
+				shape->setVisualParamWeight(AVATAR_HOVER, mAvatarOffset.mV[VZ], false);
+			}
+		}
+	}
+
+	if (new_body_size != mBodySize || old_offset != mAvatarOffset.mV[VZ])
+	{
+		mBodySize = new_body_size;
+		bodySizeChanged();
+	}
+}
+
+//-----------------------------------------------------------------------------
+// parseSkeletonFile()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename)
+{
+	//-------------------------------------------------------------------------
+	// parse the file
+	//-------------------------------------------------------------------------
+	BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
+
+	if (!parsesuccess)
+	{
+		llerrs << "Can't parse skeleton file: " << filename << llendl;
+		return FALSE;
+	}
+
+	// now sanity check xml file
+	LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
+	if (!root) 
+	{
+		llerrs << "No root node found in avatar skeleton file: " << filename << llendl;
+		return FALSE;
+	}
+
+	if( !root->hasName( "linden_skeleton" ) )
+	{
+		llerrs << "Invalid avatar skeleton file header: " << filename << llendl;
+		return FALSE;
+	}
+
+	std::string version;
+	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
+	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
+	{
+		llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// setupBone()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &volume_num, S32 &joint_num)
+{
+	LLJoint* joint = NULL;
+
+	if (info->mIsJoint)
+	{
+		joint = getCharacterJoint(joint_num);
+		if (!joint)
+		{
+			llwarns << "Too many bones" << llendl;
+			return FALSE;
+		}
+		joint->setName( info->mName );
+	}
+	else // collision volume
+	{
+		if (volume_num >= (S32)mNumCollisionVolumes)
+		{
+			llwarns << "Too many bones" << llendl;
+			return FALSE;
+		}
+		joint = (&mCollisionVolumes[volume_num]);
+		joint->setName( info->mName );
+	}
+
+	// add to parent
+	if (parent)
+	{
+		parent->addChild( joint );
+	}
+
+	joint->setPosition(info->mPos);
+	joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
+							 info->mRot.mV[VZ], LLQuaternion::XYZ));
+	joint->setScale(info->mScale);
+
+	joint->setDefaultFromCurrentXform();
+	
+	if (info->mIsJoint)
+	{
+		joint->setSkinOffset( info->mPivot );
+		joint_num++;
+	}
+	else // collision volume
+	{
+		volume_num++;
+	}
+
+	// setup children
+	LLAvatarBoneInfo::child_list_t::const_iterator iter;
+	for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter)
+	{
+		LLAvatarBoneInfo *child_info = *iter;
+		if (!setupBone(child_info, joint, volume_num, joint_num))
+		{
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// allocateCharacterJoints()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::allocateCharacterJoints( U32 num )
+{
+	clearSkeleton();
+
+	for(S32 joint_num = 0; joint_num < (S32)num; joint_num++)
+	{
+		mSkeleton.push_back(createAvatarJoint(joint_num));
+	}
+
+	return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// buildSkeleton()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info)
+{
+	//-------------------------------------------------------------------------
+	// allocate joints
+	//-------------------------------------------------------------------------
+	if (!allocateCharacterJoints(info->mNumBones))
+	{
+		llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl;
+		return FALSE;
+	}
+	
+	//-------------------------------------------------------------------------
+	// allocate volumes
+	//-------------------------------------------------------------------------
+	if (info->mNumCollisionVolumes)
+	{
+		if (!allocateCollisionVolumes(info->mNumCollisionVolumes))
+		{
+			llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl;
+			return FALSE;
+		}
+	}
+
+	S32 current_joint_num = 0;
+	S32 current_volume_num = 0;
+	LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
+	for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter)
+	{
+		LLAvatarBoneInfo *info = *iter;
+		if (!setupBone(info, NULL, current_volume_num, current_joint_num))
+		{
+			llerrs << "Error parsing bone in skeleton file" << llendl;
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// clearSkeleton()
+//-----------------------------------------------------------------------------
+void LLAvatarAppearance::clearSkeleton()
+{
+	std::for_each(mSkeleton.begin(), mSkeleton.end(), DeletePointer());
+	mSkeleton.clear();
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::buildCharacter()
+// Deferred initialization and rebuild of the avatar.
+//-----------------------------------------------------------------------------
+void LLAvatarAppearance::buildCharacter()
+{
+	//-------------------------------------------------------------------------
+	// remove all references to our existing skeleton
+	// so we can rebuild it
+	//-------------------------------------------------------------------------
+	flushAllMotions();
+
+	//-------------------------------------------------------------------------
+	// remove all of mRoot's children
+	//-------------------------------------------------------------------------
+	mRoot->removeAllChildren();
+	mJointMap.clear();
+	mIsBuilt = FALSE;
+
+	//-------------------------------------------------------------------------
+	// clear mesh data
+	//-------------------------------------------------------------------------
+	for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin();
+		 jointIter != mMeshLOD.end(); ++jointIter)
+	{
+		LLAvatarJoint* joint = *jointIter;
+		for (avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin();
+			 meshIter != joint->mMeshParts.end(); ++meshIter)
+		{
+			LLAvatarJointMesh * mesh = *meshIter;
+			mesh->setMesh(NULL);
+		}
+	}
+
+	//-------------------------------------------------------------------------
+	// (re)load our skeleton and meshes
+	//-------------------------------------------------------------------------
+	LLTimer timer;
+
+	BOOL status = loadAvatar();
+	stop_glerror();
+
+// 	gPrintMessagesThisFrame = TRUE;
+	lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl;
+
+	if (!status)
+	{
+		if (isSelf())
+		{
+			llerrs << "Unable to load user's avatar" << llendl;
+		}
+		else
+		{
+			llwarns << "Unable to load other's avatar" << llendl;
+		}
+		return;
+	}
+
+	//-------------------------------------------------------------------------
+	// initialize "well known" joint pointers
+	//-------------------------------------------------------------------------
+	mPelvisp		= mRoot->findJoint("mPelvis");
+	mTorsop			= mRoot->findJoint("mTorso");
+	mChestp			= mRoot->findJoint("mChest");
+	mNeckp			= mRoot->findJoint("mNeck");
+	mHeadp			= mRoot->findJoint("mHead");
+	mSkullp			= mRoot->findJoint("mSkull");
+	mHipLeftp		= mRoot->findJoint("mHipLeft");
+	mHipRightp		= mRoot->findJoint("mHipRight");
+	mKneeLeftp		= mRoot->findJoint("mKneeLeft");
+	mKneeRightp		= mRoot->findJoint("mKneeRight");
+	mAnkleLeftp		= mRoot->findJoint("mAnkleLeft");
+	mAnkleRightp	= mRoot->findJoint("mAnkleRight");
+	mFootLeftp		= mRoot->findJoint("mFootLeft");
+	mFootRightp		= mRoot->findJoint("mFootRight");
+	mWristLeftp		= mRoot->findJoint("mWristLeft");
+	mWristRightp	= mRoot->findJoint("mWristRight");
+	mEyeLeftp		= mRoot->findJoint("mEyeLeft");
+	mEyeRightp		= mRoot->findJoint("mEyeRight");
+
+	//-------------------------------------------------------------------------
+	// Make sure "well known" pointers exist
+	//-------------------------------------------------------------------------
+	if (!(mPelvisp && 
+		  mTorsop &&
+		  mChestp &&
+		  mNeckp &&
+		  mHeadp &&
+		  mSkullp &&
+		  mHipLeftp &&
+		  mHipRightp &&
+		  mKneeLeftp &&
+		  mKneeRightp &&
+		  mAnkleLeftp &&
+		  mAnkleRightp &&
+		  mFootLeftp &&
+		  mFootRightp &&
+		  mWristLeftp &&
+		  mWristRightp &&
+		  mEyeLeftp &&
+		  mEyeRightp))
+	{
+		llerrs << "Failed to create avatar." << llendl;
+		return;
+	}
+
+	//-------------------------------------------------------------------------
+	// initialize the pelvis
+	//-------------------------------------------------------------------------
+	mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) );
+
+	mIsBuilt = TRUE;
+	stop_glerror();
+
+}
+
+BOOL LLAvatarAppearance::loadAvatar()
+{
+// 	LLFastTimer t(FTM_LOAD_AVATAR);
+	
+	// avatar_skeleton.xml
+	if( !buildSkeleton(sAvatarSkeletonInfo) )
+	{
+		llwarns << "avatar file: buildSkeleton() failed" << llendl;
+		return FALSE;
+	}
+
+	// avatar_lad.xml : <skeleton>
+	if( !loadSkeletonNode() )
+	{
+		llwarns << "avatar file: loadNodeSkeleton() failed" << llendl;
+		return FALSE;
+	}
+	
+	// avatar_lad.xml : <mesh>
+	if( !loadMeshNodes() )
+	{
+		llwarns << "avatar file: loadNodeMesh() failed" << llendl;
+		return FALSE;
+	}
+	
+	// avatar_lad.xml : <global_color>
+	if( sAvatarXmlInfo->mTexSkinColorInfo )
+	{
+		mTexSkinColor = new LLTexGlobalColor( this );
+		if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) )
+		{
+			llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl;
+			return FALSE;
+		}
+	}
+	else
+	{
+		llwarns << "<global_color> name=\"skin_color\" not found" << llendl;
+		return FALSE;
+	}
+	if( sAvatarXmlInfo->mTexHairColorInfo )
+	{
+		mTexHairColor = new LLTexGlobalColor( this );
+		if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) )
+		{
+			llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl;
+			return FALSE;
+		}
+	}
+	else
+	{
+		llwarns << "<global_color> name=\"hair_color\" not found" << llendl;
+		return FALSE;
+	}
+	if( sAvatarXmlInfo->mTexEyeColorInfo )
+	{
+		mTexEyeColor = new LLTexGlobalColor( this );
+		if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) )
+		{
+			llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl;
+			return FALSE;
+		}
+	}
+	else
+	{
+		llwarns << "<global_color> name=\"eye_color\" not found" << llendl;
+		return FALSE;
+	}
+	
+	// avatar_lad.xml : <layer_set>
+	if (sAvatarXmlInfo->mLayerInfoList.empty())
+	{
+		llwarns << "avatar file: missing <layer_set> node" << llendl;
+		return FALSE;
+	}
+
+	if (sAvatarXmlInfo->mMorphMaskInfoList.empty())
+	{
+		llwarns << "avatar file: missing <morph_masks> node" << llendl;
+		return FALSE;
+	}
+
+	// avatar_lad.xml : <morph_masks>
+	for (LLAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin();
+		 iter != sAvatarXmlInfo->mMorphMaskInfoList.end();
+		 ++iter)
+	{
+		LLAvatarXmlInfo::LLAvatarMorphInfo *info = *iter;
+
+		EBakedTextureIndex baked = LLAvatarAppearanceDictionary::findBakedByRegionName(info->mRegion); 
+		if (baked != BAKED_NUM_INDICES)
+		{
+			LLVisualParam* morph_param;
+			const std::string *name = &info->mName;
+			morph_param = getVisualParam(name->c_str());
+			if (morph_param)
+			{
+				BOOL invert = info->mInvert;
+				addMaskedMorph(baked, morph_param, invert, info->mLayer);
+			}
+		}
+
+	}
+
+	loadLayersets();
+	
+	// avatar_lad.xml : <driver_parameters>
+	for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
+		 iter != sAvatarXmlInfo->mDriverInfoList.end(); 
+		 ++iter)
+	{
+		LLDriverParamInfo *info = *iter;
+		LLDriverParam* driver_param = new LLDriverParam( this );
+		if (driver_param->setInfo(info))
+		{
+			addVisualParam( driver_param );
+			driver_param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+			LLVisualParam*(LLAvatarAppearance::*avatar_function)(S32)const = &LLAvatarAppearance::getVisualParam; 
+			if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLAvatarAppearance*)this,_1 ), false))
+			{
+				llwarns << "could not link driven params for avatar " << getID().asString() << " param id: " << driver_param->getID() << llendl;
+				continue;
+			}
+		}
+		else
+		{
+			delete driver_param;
+			llwarns << "avatar file: driver_param->parseData() failed" << llendl;
+			return FALSE;
+		}
+	}
+
+	
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadSkeletonNode(): loads <skeleton> node from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadSkeletonNode ()
+{
+	mRoot->addChild( mSkeleton[0] );
+
+	// make meshes children before calling parent version of the function
+	for (avatar_joint_list_t::iterator iter = mMeshLOD.begin();
+		 iter != mMeshLOD.end(); 
+		 ++iter)
+	{
+		LLAvatarJoint *joint = *iter;
+		joint->mUpdateXform = FALSE;
+		joint->setMeshesToChildren();
+	}
+
+	mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
+	mRoot->addChild(mMeshLOD[MESH_ID_EYELASH]);
+	mRoot->addChild(mMeshLOD[MESH_ID_UPPER_BODY]);
+	mRoot->addChild(mMeshLOD[MESH_ID_LOWER_BODY]);
+	mRoot->addChild(mMeshLOD[MESH_ID_SKIRT]);
+	mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
+
+	LLAvatarJoint *skull = (LLAvatarJoint*)mRoot->findJoint("mSkull");
+	if (skull)
+	{
+		skull->addChild(mMeshLOD[MESH_ID_HAIR] );
+	}
+
+	LLAvatarJoint *eyeL = (LLAvatarJoint*)mRoot->findJoint("mEyeLeft");
+	if (eyeL)
+	{
+		eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] );
+	}
+
+	LLAvatarJoint *eyeR = (LLAvatarJoint*)mRoot->findJoint("mEyeRight");
+	if (eyeR)
+	{
+		eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] );
+	}
+
+	// SKELETAL DISTORTIONS
+	{
+		LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter;
+		for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin();
+			 iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end(); 
+			 ++iter)
+		{
+			LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter;
+			LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this);
+			if (!param->setInfo(info))
+			{
+				delete param;
+				return FALSE;
+			}
+			else
+			{
+				addVisualParam(param);
+				param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+			}				
+		}
+	}
+
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadMeshNodes(): loads <mesh> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadMeshNodes()
+{
+	for (LLAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin();
+		 meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end(); 
+		 ++meshinfo_iter)
+	{
+		const LLAvatarXmlInfo::LLAvatarMeshInfo *info = *meshinfo_iter;
+		const std::string &type = info->mType;
+		S32 lod = info->mLOD;
+
+		LLAvatarJointMesh* mesh = NULL;
+		U8 mesh_id = 0;
+		BOOL found_mesh_id = FALSE;
+
+		/* if (type == "hairMesh")
+			switch(lod)
+			  case 0:
+				mesh = &mHairMesh0; */
+		for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator mesh_iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+			 mesh_iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+			 ++mesh_iter)
+		{
+			const EMeshIndex mesh_index = mesh_iter->first;
+			const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = mesh_iter->second;
+			if (type.compare(mesh_dict->mName) == 0)
+			{
+				mesh_id = mesh_index;
+				found_mesh_id = TRUE;
+				break;
+			}
+		}
+
+		if (found_mesh_id)
+		{
+			if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size())
+			{
+				mesh = mMeshLOD[mesh_id]->mMeshParts[lod];
+			}
+			else
+			{
+				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
+				return FALSE;
+			}
+		}
+		else 
+		{
+			llwarns << "Ignoring unrecognized mesh type: " << type << llendl;
+			return FALSE;
+		}
+
+		//	llinfos << "Parsing mesh data for " << type << "..." << llendl;
+
+		// If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings.
+		// Do not touch!!!
+		mesh->setColor( LLColor4::white );
+
+		LLPolyMesh *poly_mesh = NULL;
+
+		if (!info->mReferenceMeshName.empty())
+		{
+			polymesh_map_t::const_iterator polymesh_iter = mPolyMeshes.find(info->mReferenceMeshName);
+			if (polymesh_iter != mPolyMeshes.end())
+			{
+				poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second);
+				poly_mesh->setAvatar(this);
+			}
+			else
+			{
+				// This should never happen
+				LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL;
+			}
+		}
+		else
+		{
+			poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName);
+			poly_mesh->setAvatar(this);
+		}
+
+		if( !poly_mesh )
+		{
+			llwarns << "Failed to load mesh of type " << type << llendl;
+			return FALSE;
+		}
+
+		// Multimap insert
+		mPolyMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh));
+	
+		mesh->setMesh( poly_mesh );
+		mesh->setLOD( info->mMinPixelArea );
+
+		for (LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin();
+			 xmlinfo_iter != info->mPolyMorphTargetInfoList.end(); 
+			 ++xmlinfo_iter)
+		{
+			const LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter);
+			LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh());
+			if (!param->setInfo((LLPolyMorphTargetInfo*)info_pair->first))
+			{
+				delete param;
+				return FALSE;
+			}
+			else
+			{
+				if (info_pair->second)
+				{
+					addSharedVisualParam(param);
+					param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+				}
+				else
+				{
+					addVisualParam(param);
+					param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+				}
+			}				
+		}
+	}
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadLayerSets()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadLayersets()
+{
+	BOOL success = TRUE;
+	for (LLAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin();
+		 layerset_iter != sAvatarXmlInfo->mLayerInfoList.end(); 
+		 ++layerset_iter)
+	{
+		LLTexLayerSetInfo *layerset_info = *layerset_iter;
+		if (isSelf())
+		{
+			// Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+			LLTexLayerSet* layer_set = createTexLayerSet();
+			
+			if (!layer_set->setInfo(layerset_info))
+			{
+				stop_glerror();
+				delete layer_set;
+				llwarns << "avatar file: layer_set->setInfo() failed" << llendl;
+				return FALSE;
+			}
+
+			// scan baked textures and associate the layerset with the appropriate one
+			EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
+			for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+				 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+				 ++baked_iter)
+			{
+				const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+				if (layer_set->isBodyRegion(baked_dict->mName))
+				{
+					baked_index = baked_iter->first;
+					// ensure both structures are aware of each other
+					mBakedTextureDatas[baked_index].mTexLayerSet = layer_set;
+					layer_set->setBakedTexIndex(baked_index);
+					break;
+				}
+			}
+			// if no baked texture was found, warn and cleanup
+			if (baked_index == BAKED_NUM_INDICES)
+			{
+				llwarns << "<layer_set> has invalid body_region attribute" << llendl;
+				delete layer_set;
+				return FALSE;
+			}
+
+			// scan morph masks and let any affected layers know they have an associated morph
+			for (LLAvatarAppearance::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin();
+				morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end();
+				 ++morph_iter)
+			{
+				LLMaskedMorph *morph = *morph_iter;
+				LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer);
+				if (layer)
+				{
+					layer->setHasMorph(TRUE);
+				}
+				else
+				{
+					llwarns << "Could not find layer named " << morph->mLayer << " to set morph flag" << llendl;
+					success = FALSE;
+				}
+			}
+		}
+		else // !isSelf()
+		{
+			// Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+			LLTexLayerSetInfo *layerset_info = *layerset_iter;
+			layerset_info->createVisualParams(this);
+		}
+	}
+	return success;
+}
+
+//-----------------------------------------------------------------------------
+// getCharacterJoint()
+//-----------------------------------------------------------------------------
+LLJoint *LLAvatarAppearance::getCharacterJoint( U32 num )
+{
+	if ((S32)num >= mSkeleton.size()
+	    || (S32)num < 0)
+	{
+		return NULL;
+	}
+	return mSkeleton[num];
+}
+
+
+//-----------------------------------------------------------------------------
+// getVolumePos()
+//-----------------------------------------------------------------------------
+LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_offset)
+{
+	if (joint_index > mNumCollisionVolumes)
+	{
+		return LLVector3::zero;
+	}
+
+	return mCollisionVolumes[joint_index].getVolumePos(volume_offset);
+}
+
+//-----------------------------------------------------------------------------
+// findCollisionVolume()
+//-----------------------------------------------------------------------------
+LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id)
+{
+	if ((S32)volume_id > mNumCollisionVolumes)
+	{
+		return NULL;
+	}
+	
+	return &mCollisionVolumes[volume_id];
+}
+
+//-----------------------------------------------------------------------------
+// findCollisionVolume()
+//-----------------------------------------------------------------------------
+S32 LLAvatarAppearance::getCollisionVolumeID(std::string &name)
+{
+	for (S32 i = 0; i < mNumCollisionVolumes; i++)
+	{
+		if (mCollisionVolumes[i].getName() == name)
+		{
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::getHeadMesh()
+//-----------------------------------------------------------------------------
+LLPolyMesh*	LLAvatarAppearance::getHeadMesh()
+{
+	return mMeshLOD[MESH_ID_HEAD]->mMeshParts[0]->getMesh();
+}
+
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::getUpperBodyMesh()
+//-----------------------------------------------------------------------------
+LLPolyMesh*	LLAvatarAppearance::getUpperBodyMesh()
+{
+	return mMeshLOD[MESH_ID_UPPER_BODY]->mMeshParts[0]->getMesh();
+}
+
+
+
+// virtual
+BOOL LLAvatarAppearance::isValid() const
+{
+	// This should only be called on ourself.
+	if (!isSelf())
+	{
+		llerrs << "Called LLAvatarAppearance::isValid() on when isSelf() == false" << llendl;
+	}
+	return TRUE;
+}
+
+
+// adds a morph mask to the appropriate baked texture structure
+void LLAvatarAppearance::addMaskedMorph(EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer)
+{
+	if (index < BAKED_NUM_INDICES)
+	{
+		LLMaskedMorph *morph = new LLMaskedMorph(morph_target, invert, layer);
+		mBakedTextureDatas[index].mMaskedMorphs.push_front(morph);
+	}
+}
+
+
+//static
+BOOL LLAvatarAppearance::teToColorParams( ETextureIndex te, U32 *param_name )
+{
+	switch( te )
+	{
+		case TEX_UPPER_SHIRT:
+			param_name[0] = 803; //"shirt_red";
+			param_name[1] = 804; //"shirt_green";
+			param_name[2] = 805; //"shirt_blue";
+			break;
+
+		case TEX_LOWER_PANTS:
+			param_name[0] = 806; //"pants_red";
+			param_name[1] = 807; //"pants_green";
+			param_name[2] = 808; //"pants_blue";
+			break;
+
+		case TEX_LOWER_SHOES:
+			param_name[0] = 812; //"shoes_red";
+			param_name[1] = 813; //"shoes_green";
+			param_name[2] = 817; //"shoes_blue";
+			break;
+
+		case TEX_LOWER_SOCKS:
+			param_name[0] = 818; //"socks_red";
+			param_name[1] = 819; //"socks_green";
+			param_name[2] = 820; //"socks_blue";
+			break;
+
+		case TEX_UPPER_JACKET:
+		case TEX_LOWER_JACKET:
+			param_name[0] = 834; //"jacket_red";
+			param_name[1] = 835; //"jacket_green";
+			param_name[2] = 836; //"jacket_blue";
+			break;
+
+		case TEX_UPPER_GLOVES:
+			param_name[0] = 827; //"gloves_red";
+			param_name[1] = 829; //"gloves_green";
+			param_name[2] = 830; //"gloves_blue";
+			break;
+
+		case TEX_UPPER_UNDERSHIRT:
+			param_name[0] = 821; //"undershirt_red";
+			param_name[1] = 822; //"undershirt_green";
+			param_name[2] = 823; //"undershirt_blue";
+			break;
+	
+		case TEX_LOWER_UNDERPANTS:
+			param_name[0] = 824; //"underpants_red";
+			param_name[1] = 825; //"underpants_green";
+			param_name[2] = 826; //"underpants_blue";
+			break;
+
+		case TEX_SKIRT:
+			param_name[0] = 921; //"skirt_red";
+			param_name[1] = 922; //"skirt_green";
+			param_name[2] = 923; //"skirt_blue";
+			break;
+
+		case TEX_HEAD_TATTOO:
+		case TEX_LOWER_TATTOO:
+		case TEX_UPPER_TATTOO:
+			param_name[0] = 1071; //"tattoo_red";
+			param_name[1] = 1072; //"tattoo_green";
+			param_name[2] = 1073; //"tattoo_blue";
+			break;	
+
+		default:
+			llassert(0);
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+void LLAvatarAppearance::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL upload_bake )
+{
+	U32 param_name[3];
+	if( teToColorParams( te, param_name ) )
+	{
+		setVisualParamWeight( param_name[0], new_color.mV[VX], upload_bake );
+		setVisualParamWeight( param_name[1], new_color.mV[VY], upload_bake );
+		setVisualParamWeight( param_name[2], new_color.mV[VZ], upload_bake );
+	}
+}
+
+LLColor4 LLAvatarAppearance::getClothesColor( ETextureIndex te )
+{
+	LLColor4 color;
+	U32 param_name[3];
+	if( teToColorParams( te, param_name ) )
+	{
+		color.mV[VX] = getVisualParamWeight( param_name[0] );
+		color.mV[VY] = getVisualParamWeight( param_name[1] );
+		color.mV[VZ] = getVisualParamWeight( param_name[2] );
+	}
+	return color;
+}
+
+// static
+LLColor4 LLAvatarAppearance::getDummyColor()
+{
+	return DUMMY_COLOR;
+}
+
+LLColor4 LLAvatarAppearance::getGlobalColor( const std::string& color_name ) const
+{
+	if (color_name=="skin_color" && mTexSkinColor)
+	{
+		return mTexSkinColor->getColor();
+	}
+	else if(color_name=="hair_color" && mTexHairColor)
+	{
+		return mTexHairColor->getColor();
+	}
+	if(color_name=="eye_color" && mTexEyeColor)
+	{
+		return mTexEyeColor->getColor();
+	}
+	else
+	{
+//		return LLColor4( .5f, .5f, .5f, .5f );
+		return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
+	}
+}
+
+// Unlike most wearable functions, this works for both self and other.
+// virtual
+BOOL LLAvatarAppearance::isWearingWearableType(LLWearableType::EType type) const
+{
+	return mWearableData->getWearableCount(type) > 0;
+}
+
+LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_index) const
+{
+	/* switch(index)
+		case TEX_HEAD_BAKED:
+		case TEX_HEAD_BODYPAINT:
+			return mHeadLayerSet; */
+	return mBakedTextureDatas[baked_index].mTexLayerSet;
+}
+
+//-----------------------------------------------------------------------------
+// allocateCollisionVolumes()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num )
+{
+	deleteAndClearArray(mCollisionVolumes);
+	mNumCollisionVolumes = 0;
+
+	mCollisionVolumes = new LLAvatarJointCollisionVolume[num];
+	if (!mCollisionVolumes)
+	{
+		return FALSE;
+	}
+
+	mNumCollisionVolumes = num;
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarBoneInfo::parseXml()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
+{
+	if (node->hasName("bone"))
+	{
+		mIsJoint = TRUE;
+		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+		if (!node->getFastAttributeString(name_string, mName))
+		{
+			llwarns << "Bone without name" << llendl;
+			return FALSE;
+		}
+	}
+	else if (node->hasName("collision_volume"))
+	{
+		mIsJoint = FALSE;
+		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+		if (!node->getFastAttributeString(name_string, mName))
+		{
+			mName = "Collision Volume";
+		}
+	}
+	else
+	{
+		llwarns << "Invalid node " << node->getName() << llendl;
+		return FALSE;
+	}
+
+	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
+	if (!node->getFastAttributeVector3(pos_string, mPos))
+	{
+		llwarns << "Bone without position" << llendl;
+		return FALSE;
+	}
+
+	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
+	if (!node->getFastAttributeVector3(rot_string, mRot))
+	{
+		llwarns << "Bone without rotation" << llendl;
+		return FALSE;
+	}
+	
+	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+	if (!node->getFastAttributeVector3(scale_string, mScale))
+	{
+		llwarns << "Bone without scale" << llendl;
+		return FALSE;
+	}
+
+	if (mIsJoint)
+	{
+		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
+		if (!node->getFastAttributeVector3(pivot_string, mPivot))
+		{
+			llwarns << "Bone without pivot" << llendl;
+			return FALSE;
+		}
+	}
+
+	// parse children
+	LLXmlTreeNode* child;
+	for( child = node->getFirstChild(); child; child = node->getNextChild() )
+	{
+		LLAvatarBoneInfo *child_info = new LLAvatarBoneInfo;
+		if (!child_info->parseXml(child))
+		{
+			delete child_info;
+			return FALSE;
+		}
+		mChildList.push_back(child_info);
+	}
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarSkeletonInfo::parseXml()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
+{
+	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
+	if (!node->getFastAttributeS32(num_bones_string, mNumBones))
+	{
+		llwarns << "Couldn't find number of bones." << llendl;
+		return FALSE;
+	}
+
+	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
+	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
+
+	LLXmlTreeNode* child;
+	for( child = node->getFirstChild(); child; child = node->getNextChild() )
+	{
+		LLAvatarBoneInfo *info = new LLAvatarBoneInfo;
+		if (!info->parseXml(child))
+		{
+			delete info;
+			llwarns << "Error parsing bone in skeleton file" << llendl;
+			return FALSE;
+		}
+		mBoneInfoList.push_back(info);
+	}
+	return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)
+{
+	LLXmlTreeNode* node = root->getChildByName( "skeleton" );
+	if( !node )
+	{
+		llwarns << "avatar file: missing <skeleton>" << llendl;
+		return FALSE;
+	}
+
+	LLXmlTreeNode* child;
+
+	// SKELETON DISTORTIONS
+	for (child = node->getChildByName( "param" );
+		 child;
+		 child = node->getNextNamedChild())
+	{
+		if (!child->getChildByName("param_skeleton"))
+		{
+			if (child->getChildByName("param_morph"))
+			{
+				llwarns << "Can't specify morph param in skeleton definition." << llendl;
+			}
+			else
+			{
+				llwarns << "Unknown param type." << llendl;
+			}
+			continue;
+		}
+		
+		LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo;
+		if (!info->parseXml(child))
+		{
+			delete info;
+			return FALSE;
+		}
+
+		mSkeletalDistortionInfoList.push_back(info);
+	}
+
+	// ATTACHMENT POINTS
+	for (child = node->getChildByName( "attachment_point" );
+		 child;
+		 child = node->getNextNamedChild())
+	{
+		LLAvatarAttachmentInfo* info = new LLAvatarAttachmentInfo();
+
+		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+		if (!child->getFastAttributeString(name_string, info->mName))
+		{
+			llwarns << "No name supplied for attachment point." << llendl;
+			delete info;
+			continue;
+		}
+
+		static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint");
+		if (!child->getFastAttributeString(joint_string, info->mJointName))
+		{
+			llwarns << "No bone declared in attachment point " << info->mName << llendl;
+			delete info;
+			continue;
+		}
+
+		static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position");
+		if (child->getFastAttributeVector3(position_string, info->mPosition))
+		{
+			info->mHasPosition = TRUE;
+		}
+
+		static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation");
+		if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler))
+		{
+			info->mHasRotation = TRUE;
+		}
+		 static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group");
+		if (child->getFastAttributeS32(group_string, info->mGroup))
+		{
+			if (info->mGroup == -1)
+				info->mGroup = -1111; // -1 = none parsed, < -1 = bad value
+		}
+
+		static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
+		if (!child->getFastAttributeS32(id_string, info->mAttachmentID))
+		{
+			llwarns << "No id supplied for attachment point " << info->mName << llendl;
+			delete info;
+			continue;
+		}
+
+		static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice");
+		child->getFastAttributeS32(slot_string, info->mPieMenuSlice);
+			
+		static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person");
+		child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson);
+
+		static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud");
+		child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment);
+
+		mAttachmentInfoList.push_back(info);
+	}
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlMeshNodes(): parses <mesh> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root)
+{
+	for (LLXmlTreeNode* node = root->getChildByName( "mesh" );
+		 node;
+		 node = root->getNextNamedChild())
+	{
+		LLAvatarMeshInfo *info = new LLAvatarMeshInfo;
+
+		// attribute: type
+		static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type");
+		if( !node->getFastAttributeString( type_string, info->mType ) )
+		{
+			llwarns << "Avatar file: <mesh> is missing type attribute.  Ignoring element. " << llendl;
+			delete info;
+			return FALSE;  // Ignore this element
+		}
+		
+		static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod");
+		if (!node->getFastAttributeS32( lod_string, info->mLOD ))
+		{
+			llwarns << "Avatar file: <mesh> is missing lod attribute.  Ignoring element. " << llendl;
+			delete info;
+			return FALSE;  // Ignore this element
+		}
+
+		static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
+		if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) )
+		{
+			llwarns << "Avatar file: <mesh> is missing file_name attribute.  Ignoring: " << info->mType << llendl;
+			delete info;
+			return FALSE;  // Ignore this element
+		}
+
+		static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference");
+		node->getFastAttributeString( reference_string, info->mReferenceMeshName );
+		
+		// attribute: min_pixel_area
+		static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area");
+		static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width");
+		if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea ))
+		{
+			F32 min_pixel_area = 0.1f;
+			if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area ))
+			{
+				// this is square root of pixel area (sensible to use linear space in defining lods)
+				min_pixel_area = min_pixel_area * min_pixel_area;
+			}
+			info->mMinPixelArea = min_pixel_area;
+		}
+		
+		// Parse visual params for this node only if we haven't already
+		for (LLXmlTreeNode* child = node->getChildByName( "param" );
+			 child;
+			 child = node->getNextNamedChild())
+		{
+			if (!child->getChildByName("param_morph"))
+			{
+				if (child->getChildByName("param_skeleton"))
+				{
+					llwarns << "Can't specify skeleton param in a mesh definition." << llendl;
+				}
+				else
+				{
+					llwarns << "Unknown param type." << llendl;
+				}
+				continue;
+			}
+
+			LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo();
+			if (!morphinfo->parseXml(child))
+			{
+				delete morphinfo;
+				delete info;
+				return -1;
+			}
+			BOOL shared = FALSE;
+			static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared");
+			child->getFastAttributeBOOL(shared_string, shared);
+
+			info->mPolyMorphTargetInfoList.push_back(LLAvatarMeshInfo::morph_info_pair_t(morphinfo, shared));
+		}
+
+		mMeshInfoList.push_back(info);
+	}
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlColorNodes(): parses <global_color> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
+{
+	for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" );
+		 color_node;
+		 color_node = root->getNextNamedChild())
+	{
+		std::string global_color_name;
+		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+		if (color_node->getFastAttributeString( name_string, global_color_name ) )
+		{
+			if( global_color_name == "skin_color" )
+			{
+				if (mTexSkinColorInfo)
+				{
+					llwarns << "avatar file: multiple instances of skin_color" << llendl;
+					return FALSE;
+				}
+				mTexSkinColorInfo = new LLTexGlobalColorInfo;
+				if( !mTexSkinColorInfo->parseXml( color_node ) )
+				{
+					deleteAndClear(mTexSkinColorInfo);
+					llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl;
+					return FALSE;
+				}
+			}
+			else if( global_color_name == "hair_color" )
+			{
+				if (mTexHairColorInfo)
+				{
+					llwarns << "avatar file: multiple instances of hair_color" << llendl;
+					return FALSE;
+				}
+				mTexHairColorInfo = new LLTexGlobalColorInfo;
+				if( !mTexHairColorInfo->parseXml( color_node ) )
+				{
+					deleteAndClear(mTexHairColorInfo);
+					llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl;
+					return FALSE;
+				}
+			}
+			else if( global_color_name == "eye_color" )
+			{
+				if (mTexEyeColorInfo)
+				{
+					llwarns << "avatar file: multiple instances of eye_color" << llendl;
+					return FALSE;
+				}
+				mTexEyeColorInfo = new LLTexGlobalColorInfo;
+				if( !mTexEyeColorInfo->parseXml( color_node ) )
+				{
+					llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl;
+					return FALSE;
+				}
+			}
+		}
+	}
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlLayerNodes(): parses <layer_set> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root)
+{
+	for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" );
+		 layer_node;
+		 layer_node = root->getNextNamedChild())
+	{
+		LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo();
+		if( layer_info->parseXml( layer_node ) )
+		{
+			mLayerInfoList.push_back(layer_info);
+		}
+		else
+		{
+			delete layer_info;
+			llwarns << "avatar file: layer_set->parseXml() failed" << llendl;
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root)
+{
+	LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" );
+	if( driver )
+	{
+		for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" );
+			 grand_child;
+			 grand_child = driver->getNextNamedChild())
+		{
+			if( grand_child->getChildByName( "param_driver" ) )
+			{
+				LLDriverParamInfo* driver_info = new LLDriverParamInfo();
+				if( driver_info->parseXml( grand_child ) )
+				{
+					mDriverInfoList.push_back(driver_info);
+				}
+				else
+				{
+					delete driver_info;
+					llwarns << "avatar file: driver_param->parseXml() failed" << llendl;
+					return FALSE;
+				}
+			}
+		}
+	}
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root)
+{
+	LLXmlTreeNode* masks = root->getChildByName( "morph_masks" );
+	if( !masks )
+	{
+		return FALSE;
+	}
+
+	for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" );
+		 grand_child;
+		 grand_child = masks->getNextNamedChild())
+	{
+		LLAvatarMorphInfo* info = new LLAvatarMorphInfo();
+
+		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name");
+		if (!grand_child->getFastAttributeString(name_string, info->mName))
+		{
+			llwarns << "No name supplied for morph mask." << llendl;
+			delete info;
+			continue;
+		}
+
+		static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region");
+		if (!grand_child->getFastAttributeString(region_string, info->mRegion))
+		{
+			llwarns << "No region supplied for morph mask." << llendl;
+			delete info;
+			continue;
+		}
+
+		static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer");
+		if (!grand_child->getFastAttributeString(layer_string, info->mLayer))
+		{
+			llwarns << "No layer supplied for morph mask." << llendl;
+			delete info;
+			continue;
+		}
+
+		// optional parameter. don't throw a warning if not present.
+		static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert");
+		grand_child->getFastAttributeBOOL(invert_string, info->mInvert);
+
+		mMorphMaskInfoList.push_back(info);
+	}
+
+	return TRUE;
+}
+
+//virtual 
+LLAvatarAppearance::LLMaskedMorph::LLMaskedMorph(LLVisualParam *morph_target, BOOL invert, std::string layer) :
+			mMorphTarget(morph_target), 
+			mInvert(invert),
+			mLayer(layer)
+{
+	LLPolyMorphTarget *target = dynamic_cast<LLPolyMorphTarget*>(morph_target);
+	if (target)
+	{
+		target->addPendingMorphMask();
+	}
+}
+
+
+
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
new file mode 100644
index 0000000000000000000000000000000000000000..bce25402581032514c6cce838ddc26e69c0d951a
--- /dev/null
+++ b/indra/llappearance/llavatarappearance.h
@@ -0,0 +1,448 @@
+/**
+ * @file llavatarappearance.h
+ * @brief Declaration of LLAvatarAppearance class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_AVATAR_APPEARANCE_H
+#define LL_AVATAR_APPEARANCE_H
+
+#include "llcharacter.h"
+#include "llavatarappearancedefines.h"
+#include "llavatarjointmesh.h"
+#include "lldriverparam.h"
+#include "lltexlayer.h"
+#include "llviewervisualparam.h"
+#include "llxmltree.h"
+
+class LLTexLayerSet;
+class LLTexGlobalColor;
+class LLTexGlobalColorInfo;
+class LLWearableData;
+class LLAvatarBoneInfo;
+class LLAvatarSkeletonInfo;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLAvatarAppearance
+// 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLAvatarAppearance : public LLCharacter
+{
+	LOG_CLASS(LLAvatarAppearance);
+
+protected:
+	struct LLAvatarXmlInfo;
+
+/********************************************************************************
+ **                                                                            **
+ **                    INITIALIZATION
+ **/
+private:
+	// Hide default constructor.
+	LLAvatarAppearance() {}
+
+public:
+	LLAvatarAppearance(LLWearableData* wearable_data);
+	virtual ~LLAvatarAppearance();
+
+	static void			initClass(); // initializes static members
+	static void			cleanupClass();	// Cleanup data that's only init'd once per class.
+	virtual void 		initInstance(); // Called after construction to initialize the instance.
+	virtual BOOL		loadSkeletonNode();
+	BOOL				loadMeshNodes();
+	BOOL				loadLayersets();
+
+
+/**                    Initialization
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    INHERITED
+ **/
+
+	//--------------------------------------------------------------------
+	// LLCharacter interface and related
+	//--------------------------------------------------------------------
+public:
+	/*virtual*/ LLJoint*		getCharacterJoint(U32 num);
+
+	/*virtual*/ const char*		getAnimationPrefix() { return "avatar"; }
+	/*virtual*/ LLVector3		getVolumePos(S32 joint_index, LLVector3& volume_offset);
+	/*virtual*/ LLJoint*		findCollisionVolume(U32 volume_id);
+	/*virtual*/ S32				getCollisionVolumeID(std::string &name);
+	/*virtual*/ LLPolyMesh*		getHeadMesh();
+	/*virtual*/ LLPolyMesh*		getUpperBodyMesh();
+
+/**                    Inherited
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    STATE
+ **/
+public:
+	virtual bool 	isSelf() const { return false; } // True if this avatar is for this viewer's agent
+	virtual BOOL	isValid() const;
+	virtual BOOL	isUsingServerBakes() const = 0;
+	virtual BOOL	isUsingLocalAppearance() const = 0;
+	virtual BOOL	isEditingAppearance() const = 0;
+
+	bool isBuilt() const { return mIsBuilt; }
+
+	
+/**                    State
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    SKELETON
+ **/
+
+protected:
+	virtual LLAvatarJoint*	createAvatarJoint() = 0;
+	virtual LLAvatarJoint*	createAvatarJoint(S32 joint_num) = 0;
+	virtual LLAvatarJointMesh*	createAvatarJointMesh() = 0;
+public:
+	F32					getPelvisToFoot() const { return mPelvisToFoot; }
+	/*virtual*/ LLJoint*	getRootJoint() { return mRoot; }
+
+	LLVector3			mHeadOffset; // current head position
+	LLAvatarJoint		*mRoot;
+
+	typedef std::map<std::string, LLJoint*> joint_map_t;
+	joint_map_t			mJointMap;
+	
+	void				computeBodySize();
+
+
+protected:
+	static BOOL			parseSkeletonFile(const std::string& filename);
+	virtual void		buildCharacter();
+	virtual BOOL		loadAvatar();
+	virtual void		bodySizeChanged() = 0;
+
+	BOOL				setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
+	BOOL				allocateCharacterJoints(U32 num);
+	BOOL				buildSkeleton(const LLAvatarSkeletonInfo *info);
+protected:
+	void				clearSkeleton();
+	BOOL				mIsBuilt; // state of deferred character building
+	typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
+	avatar_joint_list_t	mSkeleton;
+	
+	//--------------------------------------------------------------------
+	// Pelvis height adjustment members.
+	//--------------------------------------------------------------------
+public:
+	LLVector3			mBodySize;
+	LLVector3			mAvatarOffset;
+protected:
+	F32					mPelvisToFoot;
+
+	//--------------------------------------------------------------------
+	// Cached pointers to well known joints
+	//--------------------------------------------------------------------
+public:
+	LLJoint* 		mPelvisp;
+	LLJoint* 		mTorsop;
+	LLJoint* 		mChestp;
+	LLJoint* 		mNeckp;
+	LLJoint* 		mHeadp;
+	LLJoint* 		mSkullp;
+	LLJoint* 		mEyeLeftp;
+	LLJoint* 		mEyeRightp;
+	LLJoint* 		mHipLeftp;
+	LLJoint* 		mHipRightp;
+	LLJoint* 		mKneeLeftp;
+	LLJoint* 		mKneeRightp;
+	LLJoint* 		mAnkleLeftp;
+	LLJoint* 		mAnkleRightp;
+	LLJoint* 		mFootLeftp;
+	LLJoint* 		mFootRightp;
+	LLJoint* 		mWristLeftp;
+	LLJoint* 		mWristRightp;
+
+	//--------------------------------------------------------------------
+	// XML parse tree
+	//--------------------------------------------------------------------
+protected:
+	static LLXmlTree 	sXMLTree; // avatar config file
+	static LLXmlTree 	sSkeletonXMLTree; // avatar skeleton file
+
+	static LLAvatarSkeletonInfo* 					sAvatarSkeletonInfo;
+	static LLAvatarXmlInfo* 						sAvatarXmlInfo;
+
+
+/**                    Skeleton
+ **                                                                            **
+ *******************************************************************************/
+
+
+/********************************************************************************
+ **                                                                            **
+ **                    RENDERING
+ **/
+public:
+	BOOL		mIsDummy; // for special views
+
+	//--------------------------------------------------------------------
+	// Morph masks
+	//--------------------------------------------------------------------
+public:
+	void 	addMaskedMorph(LLAvatarAppearanceDefines::EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer);
+	virtual void	applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES) = 0;
+
+/**                    Rendering
+ **                                                                            **
+ *******************************************************************************/
+
+	//--------------------------------------------------------------------
+	// Composites
+	//--------------------------------------------------------------------
+public:
+	virtual void	invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result) = 0;
+
+/********************************************************************************
+ **                                                                            **
+ **                    MESHES
+ **/
+
+public:
+	virtual void	updateMeshTextures() = 0;
+	virtual void	dirtyMesh() = 0; // Dirty the avatar mesh
+protected:
+	virtual void	dirtyMesh(S32 priority) = 0; // Dirty the avatar mesh, with priority
+
+protected:
+	typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
+	polymesh_map_t 									mPolyMeshes;
+	avatar_joint_list_t								mMeshLOD;
+
+/**                    Meshes
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    APPEARANCE
+ **/
+
+	//--------------------------------------------------------------------
+	// Clothing colors (convenience functions to access visual parameters)
+	//--------------------------------------------------------------------
+public:
+	void			setClothesColor(LLAvatarAppearanceDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);
+	LLColor4		getClothesColor(LLAvatarAppearanceDefines::ETextureIndex te);
+	static BOOL		teToColorParams(LLAvatarAppearanceDefines::ETextureIndex te, U32 *param_name);
+
+	//--------------------------------------------------------------------
+	// Global colors
+	//--------------------------------------------------------------------
+public:
+	LLColor4		getGlobalColor(const std::string& color_name ) const;
+	virtual void	onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake) = 0;
+protected:
+	LLTexGlobalColor* mTexSkinColor;
+	LLTexGlobalColor* mTexHairColor;
+	LLTexGlobalColor* mTexEyeColor;
+
+	//--------------------------------------------------------------------
+	// Visibility
+	//--------------------------------------------------------------------
+public:
+	static LLColor4 getDummyColor();
+/**                    Appearance
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    WEARABLES
+ **/
+
+public:
+	LLWearableData*			getWearableData() { return mWearableData; }
+	const LLWearableData*	getWearableData() const { return mWearableData; }
+	virtual BOOL isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index = 0 ) const = 0;
+	virtual BOOL			isWearingWearableType(LLWearableType::EType type ) const;
+
+private:
+	LLWearableData* mWearableData;
+
+/********************************************************************************
+ **                                                                            **
+ **                    BAKED TEXTURES
+ **/
+public:
+	LLTexLayerSet*		getAvatarLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
+
+protected:
+	virtual LLTexLayerSet*	createTexLayerSet() = 0;
+
+protected:
+	class LLMaskedMorph;
+	typedef std::deque<LLMaskedMorph *> 	morph_list_t;
+	struct BakedTextureData
+	{
+		LLUUID								mLastTextureID;
+		LLTexLayerSet*		 				mTexLayerSet; // Only exists for self
+		bool								mIsLoaded;
+		bool								mIsUsed;
+		LLAvatarAppearanceDefines::ETextureIndex 	mTextureIndex;
+		U32									mMaskTexName;
+		// Stores pointers to the joint meshes that this baked texture deals with
+		avatar_joint_mesh_list_t			mJointMeshes;
+		morph_list_t						mMaskedMorphs;
+	};
+	typedef std::vector<BakedTextureData> 	bakedtexturedata_vec_t;
+	bakedtexturedata_vec_t 					mBakedTextureDatas;
+
+/********************************************************************************
+ **                                                                            **
+ **                    PHYSICS
+ **/
+
+	//--------------------------------------------------------------------
+	// Collision volumes
+	//--------------------------------------------------------------------
+public:
+  	S32			mNumCollisionVolumes;
+	LLAvatarJointCollisionVolume* mCollisionVolumes;
+protected:
+	BOOL		allocateCollisionVolumes(U32 num);
+
+/**                    Physics
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    SUPPORT CLASSES
+ **/
+
+	struct LLAvatarXmlInfo
+	{
+		LLAvatarXmlInfo();
+		~LLAvatarXmlInfo();
+
+		BOOL 	parseXmlSkeletonNode(LLXmlTreeNode* root);
+		BOOL 	parseXmlMeshNodes(LLXmlTreeNode* root);
+		BOOL 	parseXmlColorNodes(LLXmlTreeNode* root);
+		BOOL 	parseXmlLayerNodes(LLXmlTreeNode* root);
+		BOOL 	parseXmlDriverNodes(LLXmlTreeNode* root);
+		BOOL	parseXmlMorphNodes(LLXmlTreeNode* root);
+
+		struct LLAvatarMeshInfo
+		{
+			typedef std::pair<LLViewerVisualParamInfo*,BOOL> morph_info_pair_t; // LLPolyMorphTargetInfo stored here
+			typedef std::vector<morph_info_pair_t> morph_info_list_t;
+
+			LLAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {}
+			~LLAvatarMeshInfo()
+			{
+				morph_info_list_t::iterator iter;
+				for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++)
+				{
+					delete iter->first;
+				}
+				mPolyMorphTargetInfoList.clear();
+			}
+
+			std::string mType;
+			S32			mLOD;
+			std::string	mMeshFileName;
+			std::string	mReferenceMeshName;
+			F32			mMinPixelArea;
+			morph_info_list_t mPolyMorphTargetInfoList;
+		};
+		typedef std::vector<LLAvatarMeshInfo*> mesh_info_list_t;
+		mesh_info_list_t mMeshInfoList;
+
+		typedef std::vector<LLViewerVisualParamInfo*> skeletal_distortion_info_list_t; // LLPolySkeletalDistortionInfo stored here
+		skeletal_distortion_info_list_t mSkeletalDistortionInfoList;
+
+		struct LLAvatarAttachmentInfo
+		{
+			LLAvatarAttachmentInfo()
+				: mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE),
+				  mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {}
+			std::string mName;
+			std::string mJointName;
+			LLVector3 mPosition;
+			LLVector3 mRotationEuler;
+			S32 mGroup;
+			S32 mAttachmentID;
+			S32 mPieMenuSlice;
+			BOOL mVisibleFirstPerson;
+			BOOL mIsHUDAttachment;
+			BOOL mHasPosition;
+			BOOL mHasRotation;
+		};
+		typedef std::vector<LLAvatarAttachmentInfo*> attachment_info_list_t;
+		attachment_info_list_t mAttachmentInfoList;
+
+		LLTexGlobalColorInfo *mTexSkinColorInfo;
+		LLTexGlobalColorInfo *mTexHairColorInfo;
+		LLTexGlobalColorInfo *mTexEyeColorInfo;
+
+		typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t;
+		layer_info_list_t mLayerInfoList;
+
+		typedef std::vector<LLDriverParamInfo*> driver_info_list_t;
+		driver_info_list_t mDriverInfoList;
+
+		struct LLAvatarMorphInfo
+		{
+			LLAvatarMorphInfo()
+				: mInvert(FALSE) {}
+			std::string mName;
+			std::string mRegion;
+			std::string mLayer;
+			BOOL mInvert;
+		};
+
+		typedef std::vector<LLAvatarMorphInfo*> morph_info_list_t;
+		morph_info_list_t	mMorphMaskInfoList;
+	};
+
+
+	class LLMaskedMorph
+	{
+	public:
+		LLMaskedMorph(LLVisualParam *morph_target, BOOL invert, std::string layer);
+
+		LLVisualParam	*mMorphTarget;
+		BOOL				mInvert;
+		std::string			mLayer;
+	};
+/**                    Support Classes
+ **                                                                            **
+ *******************************************************************************/
+};
+
+#endif // LL_AVATAR_APPEARANCE_H
diff --git a/indra/newview/llvoavatardefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp
similarity index 79%
rename from indra/newview/llvoavatardefines.cpp
rename to indra/llappearance/llavatarappearancedefines.cpp
index 1ed4e3b61c34f6e61c9fb4931784a696874d7bf3..f1c78946a11e95db72686ab1add4ccd04a788cd4 100644
--- a/indra/newview/llvoavatardefines.cpp
+++ b/indra/llappearance/llavatarappearancedefines.cpp
@@ -1,6 +1,6 @@
 /** 
- * @file llvoavatar.cpp
- * @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject
+ * @file llavatarappearancedefines.cpp
+ * @brief Implementation of LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary 
  *
  * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -24,21 +24,20 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
-#include "llvoavatardefines.h"
-#include "llviewercontrol.h" // gSavedSettings
+#include "linden_common.h"
+#include "llavatarappearancedefines.h"
 
-const S32 LLVOAvatarDefines::SCRATCH_TEX_WIDTH = 512;
-const S32 LLVOAvatarDefines::SCRATCH_TEX_HEIGHT = 512;
-const S32 LLVOAvatarDefines::IMPOSTOR_PERIOD = 2;
+const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 512;
+const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 512;
+const S32 LLAvatarAppearanceDefines::IMPOSTOR_PERIOD = 2;
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 /*********************************************************************************
  * Edit this function to add/remove/change textures and mesh definitions for avatars.
  */
 
-LLVOAvatarDictionary::Textures::Textures()
+LLAvatarAppearanceDictionary::Textures::Textures()
 {
 	addEntry(TEX_HEAD_BODYPAINT,              new TextureEntry("head_bodypaint",   TRUE,  BAKED_NUM_INDICES, "",                          LLWearableType::WT_SKIN));
 	addEntry(TEX_UPPER_SHIRT,                 new TextureEntry("upper_shirt",      TRUE,  BAKED_NUM_INDICES, "UIImgDefaultShirtUUID",     LLWearableType::WT_SHIRT));
@@ -66,15 +65,15 @@ LLVOAvatarDictionary::Textures::Textures()
 	addEntry(TEX_UPPER_TATTOO,                new TextureEntry("upper_tattoo",     TRUE,  BAKED_NUM_INDICES, "",     LLWearableType::WT_TATTOO));
 	addEntry(TEX_LOWER_TATTOO,                new TextureEntry("lower_tattoo",     TRUE,  BAKED_NUM_INDICES, "",     LLWearableType::WT_TATTOO));
 
-	addEntry(TEX_HEAD_BAKED,                  new TextureEntry("head-baked",       FALSE, BAKED_HEAD));
-	addEntry(TEX_UPPER_BAKED,                 new TextureEntry("upper-baked",      FALSE, BAKED_UPPER));
-	addEntry(TEX_LOWER_BAKED,                 new TextureEntry("lower-baked",      FALSE, BAKED_LOWER));
-	addEntry(TEX_EYES_BAKED,                  new TextureEntry("eyes-baked",       FALSE, BAKED_EYES));
-	addEntry(TEX_HAIR_BAKED,                  new TextureEntry("hair-baked",       FALSE, BAKED_HAIR));
-	addEntry(TEX_SKIRT_BAKED,                 new TextureEntry("skirt-baked",      FALSE, BAKED_SKIRT));
+	addEntry(TEX_HEAD_BAKED,                  new TextureEntry("head-baked",       FALSE, BAKED_HEAD, "head"));
+	addEntry(TEX_UPPER_BAKED,                 new TextureEntry("upper-baked",      FALSE, BAKED_UPPER, "upper"));
+	addEntry(TEX_LOWER_BAKED,                 new TextureEntry("lower-baked",      FALSE, BAKED_LOWER, "lower"));
+	addEntry(TEX_EYES_BAKED,                  new TextureEntry("eyes-baked",       FALSE, BAKED_EYES, "eyes"));
+	addEntry(TEX_HAIR_BAKED,                  new TextureEntry("hair-baked",       FALSE, BAKED_HAIR, "hair"));
+	addEntry(TEX_SKIRT_BAKED,                 new TextureEntry("skirt-baked",      FALSE, BAKED_SKIRT, "skirt"));
 }
 
-LLVOAvatarDictionary::BakedTextures::BakedTextures()
+LLAvatarAppearanceDictionary::BakedTextures::BakedTextures()
 {
 	// Baked textures
 	addEntry(BAKED_HEAD,       new BakedEntry(TEX_HEAD_BAKED,  
@@ -110,36 +109,36 @@ LLVOAvatarDictionary::BakedTextures::BakedTextures()
 											  2, LLWearableType::WT_HAIR, LLWearableType::WT_ALPHA));
 }
 
-LLVOAvatarDictionary::Meshes::Meshes()
+LLAvatarAppearanceDictionary::MeshEntries::MeshEntries()
 {
-	// Meshes
-	addEntry(MESH_ID_HAIR,             new MeshEntry(BAKED_HAIR,  "hairMesh",         6, LLViewerJoint::PN_4));
-	addEntry(MESH_ID_HEAD,             new MeshEntry(BAKED_HEAD,  "headMesh",         5, LLViewerJoint::PN_5));
-	addEntry(MESH_ID_EYELASH,          new MeshEntry(BAKED_HEAD,  "eyelashMesh",      1, LLViewerJoint::PN_0)); // no baked mesh associated currently
-	addEntry(MESH_ID_UPPER_BODY,       new MeshEntry(BAKED_UPPER, "upperBodyMesh",    5, LLViewerJoint::PN_1));
-	addEntry(MESH_ID_LOWER_BODY,       new MeshEntry(BAKED_LOWER, "lowerBodyMesh",    5, LLViewerJoint::PN_2));
-	addEntry(MESH_ID_EYEBALL_LEFT,     new MeshEntry(BAKED_EYES,  "eyeBallLeftMesh",  2, LLViewerJoint::PN_3));
-	addEntry(MESH_ID_EYEBALL_RIGHT,    new MeshEntry(BAKED_EYES,  "eyeBallRightMesh", 2, LLViewerJoint::PN_3));
-	addEntry(MESH_ID_SKIRT,            new MeshEntry(BAKED_SKIRT, "skirtMesh",        5, LLViewerJoint::PN_5));
+	// MeshEntries
+	addEntry(MESH_ID_HAIR,             new MeshEntry(BAKED_HAIR,  "hairMesh",         6, PN_4));
+	addEntry(MESH_ID_HEAD,             new MeshEntry(BAKED_HEAD,  "headMesh",         5, PN_5));
+	addEntry(MESH_ID_EYELASH,          new MeshEntry(BAKED_HEAD,  "eyelashMesh",      1, PN_0)); // no baked mesh associated currently
+	addEntry(MESH_ID_UPPER_BODY,       new MeshEntry(BAKED_UPPER, "upperBodyMesh",    5, PN_1));
+	addEntry(MESH_ID_LOWER_BODY,       new MeshEntry(BAKED_LOWER, "lowerBodyMesh",    5, PN_2));
+	addEntry(MESH_ID_EYEBALL_LEFT,     new MeshEntry(BAKED_EYES,  "eyeBallLeftMesh",  2, PN_3));
+	addEntry(MESH_ID_EYEBALL_RIGHT,    new MeshEntry(BAKED_EYES,  "eyeBallRightMesh", 2, PN_3));
+	addEntry(MESH_ID_SKIRT,            new MeshEntry(BAKED_SKIRT, "skirtMesh",        5, PN_5));
 }
 
 /*
  *
  *********************************************************************************/
 
-LLVOAvatarDictionary::LLVOAvatarDictionary()
+LLAvatarAppearanceDictionary::LLAvatarAppearanceDictionary()
 {
 	createAssociations();
 }
 
 //virtual 
-LLVOAvatarDictionary::~LLVOAvatarDictionary()
+LLAvatarAppearanceDictionary::~LLAvatarAppearanceDictionary()
 {
 }
 
 // Baked textures are composites of textures; for each such composited texture,
 // map it to the baked texture.
-void LLVOAvatarDictionary::createAssociations()
+void LLAvatarAppearanceDictionary::createAssociations()
 {
 	for (BakedTextures::const_iterator iter = mBakedTextures.begin(); iter != mBakedTextures.end(); iter++)
 	{
@@ -160,7 +159,7 @@ void LLVOAvatarDictionary::createAssociations()
 		
 }
 
-LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name,
+LLAvatarAppearanceDictionary::TextureEntry::TextureEntry(const std::string &name,
 												 bool is_local_texture, 
 												 EBakedTextureIndex baked_texture_index,
 												 const std::string &default_image_name,
@@ -175,17 +174,17 @@ LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name,
 {
 }
 
-LLVOAvatarDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index, 
+LLAvatarAppearanceDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index, 
 										   const std::string &name, 
 										   U8 level,
-										   LLViewerJoint::PickName pick) :
+										   LLJointPickName pick) :
 	LLDictionaryEntry(name),
 	mBakedID(baked_index),
 	mLOD(level),
 	mPickName(pick)
 {
 }
-LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index, 
+LLAvatarAppearanceDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index, 
 											 const std::string &name, 
 											 const std::string &hash_name,
 											 U32 num_local_textures,
@@ -216,18 +215,18 @@ LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
 }
 
 // static
-ETextureIndex LLVOAvatarDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
+ETextureIndex LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
 {
-	return LLVOAvatarDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
+	return LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
 }
 
-//static 
-EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name)
+// static
+EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::string name)
 {
 	U8 index = 0;
 	while (index < BAKED_NUM_INDICES)
 	{
-		const BakedEntry *be = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
+		const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
 		if (be && be->mName.compare(name) == 0)
 		{
 			// baked texture found
@@ -239,23 +238,30 @@ EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name)
 	return BAKED_NUM_INDICES;
 }
 
-//static
-const LLUUID LLVOAvatarDictionary::getDefaultTextureImageID(ETextureIndex index)
+// static 
+EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::string name)
 {
-	const TextureEntry *texture_dict = getInstance()->getTexture(index);
-	const std::string &default_image_name = texture_dict->mDefaultImageName;
-	if (default_image_name == "")
-	{
-		return IMG_DEFAULT_AVATAR;
-	}
-	else
+	U8 index = 0;
+	while (index < BAKED_NUM_INDICES)
 	{
-		return LLUUID(gSavedSettings.getString(default_image_name));
+		const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
+		if (be)
+		{
+			const TextureEntry *te = LLAvatarAppearanceDictionary::getInstance()->getTexture(be->mTextureIndex);
+			if (te && te->mDefaultImageName.compare(name) == 0)
+			{
+				// baked texture found
+				return (EBakedTextureIndex) index;
+			}
+		}
+		index++;
 	}
+	// baked texture could not be found
+	return BAKED_NUM_INDICES;
 }
 
 // static
-LLWearableType::EType LLVOAvatarDictionary::getTEWearableType(ETextureIndex index )
+LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index )
 {
 	return getInstance()->getTexture(index)->mWearableType;
 }
diff --git a/indra/newview/llvoavatardefines.h b/indra/llappearance/llavatarappearancedefines.h
similarity index 86%
rename from indra/newview/llvoavatardefines.h
rename to indra/llappearance/llavatarappearancedefines.h
index 35bb37463ae3f69be96d2b1536a119d12f3435e0..8a1d2c4707e735823e94e17018240c4e8ad2fe9b 100644
--- a/indra/newview/llvoavatardefines.h
+++ b/indra/llappearance/llavatarappearancedefines.h
@@ -1,6 +1,6 @@
 /** 
- * @file llvoavatar.h
- * @brief Declaration of LLVOAvatar class which is a derivation fo
+ * @file llavatarappearancedefines.h
+ * @brief Various LLAvatarAppearance related definitions
  * LLViewerObject
  *
  * $LicenseInfo:firstyear=2001&license=viewerlgpl$
@@ -25,26 +25,30 @@
  * $/LicenseInfo$
  */
 
-#ifndef LLVOAVATAR_DEFINES_H
-#define LLVOAVATAR_DEFINES_H
+#ifndef LL_AVATARAPPEARANCE_DEFINES_H
+#define LL_AVATARAPPEARANCE_DEFINES_H
 
 #include <vector>
-#include "llwearable.h"
-#include "llviewerjoint.h"
+#include "lljointpickname.h"
 #include "lldictionary.h"
+#include "llwearabletype.h"
+#include "lluuid.h"
 
-namespace LLVOAvatarDefines
+namespace LLAvatarAppearanceDefines
 {
 
 extern const S32 SCRATCH_TEX_WIDTH;
 extern const S32 SCRATCH_TEX_HEIGHT;
 extern const S32 IMPOSTOR_PERIOD;
 
+static const U32 AVATAR_HOVER = 11001;
+
 //--------------------------------------------------------------------
 // Enums
 //--------------------------------------------------------------------
 enum ETextureIndex
 {
+	TEX_INVALID = -1,
 	TEX_HEAD_BODYPAINT = 0,
 	TEX_UPPER_SHIRT,
 	TEX_LOWER_PANTS,
@@ -111,21 +115,21 @@ typedef std::vector<EMeshIndex> mesh_vec_t;
 typedef std::vector<LLWearableType::EType> wearables_vec_t;
 
 //------------------------------------------------------------------------
-// LLVOAvatarDictionary
+// LLAvatarAppearanceDictionary
 // 
 // Holds dictionary static entries for textures, baked textures, meshes, etc.; i.e.
 // information that is common to all avatars.
 // 
 // This holds const data - it is initialized once and the contents never change after that.
 //------------------------------------------------------------------------
-class LLVOAvatarDictionary : public LLSingleton<LLVOAvatarDictionary>
+class LLAvatarAppearanceDictionary : public LLSingleton<LLAvatarAppearanceDictionary>
 {
 	//--------------------------------------------------------------------
 	// Constructors and Destructors
 	//--------------------------------------------------------------------
 public:
-	LLVOAvatarDictionary();
-	virtual ~LLVOAvatarDictionary();
+	LLAvatarAppearanceDictionary();
+	virtual ~LLAvatarAppearanceDictionary();
 private:
 	void createAssociations();
 	
@@ -166,20 +170,20 @@ class LLVOAvatarDictionary : public LLSingleton<LLVOAvatarDictionary>
 		MeshEntry(EBakedTextureIndex baked_index, 
 				  const std::string &name, // names of mesh types as they are used in avatar_lad.xml
 				  U8 level,
-				  LLViewerJoint::PickName pick);
+				  LLJointPickName pick);
 		// Levels of Detail for each mesh.  Must match levels of detail present in avatar_lad.xml
         // Otherwise meshes will be unable to be found, or levels of detail will be ignored
 		const U8 						mLOD;
 		const EBakedTextureIndex 		mBakedID;
-		const LLViewerJoint::PickName 	mPickName;
+		const LLJointPickName 	mPickName;
 	};
 
-	struct Meshes : public LLDictionary<EMeshIndex, MeshEntry>
+	struct MeshEntries : public LLDictionary<EMeshIndex, MeshEntry>
 	{
-		Meshes();
-	} mMeshes;
-	const MeshEntry*		getMesh(EMeshIndex index) const { return mMeshes.lookup(index); }
-	const Meshes&			getMeshes() const { return mMeshes; }
+		MeshEntries();
+	} mMeshEntries;
+	const MeshEntry*		getMeshEntry(EMeshIndex index) const { return mMeshEntries.lookup(index); }
+	const MeshEntries&		getMeshEntries() const { return mMeshEntries; }
 
 	//--------------------------------------------------------------------
 	// Baked Textures
@@ -215,14 +219,13 @@ class LLVOAvatarDictionary : public LLSingleton<LLVOAvatarDictionary>
 
 	// find a baked texture index based on its name
 	static EBakedTextureIndex 	findBakedByRegionName(std::string name);
-
-	static const LLUUID			getDefaultTextureImageID(ETextureIndex index);
+	static EBakedTextureIndex 	findBakedByImageName(std::string name);
 
 	// Given a texture entry, determine which wearable type owns it.
 	static LLWearableType::EType 		getTEWearableType(ETextureIndex index);
 
-}; // End LLVOAvatarDictionary
+}; // End LLAvatarAppearanceDictionary
 
-} // End namespace LLVOAvatarDefines
+} // End namespace LLAvatarAppearanceDefines
 
-#endif //LL_VO_AVATARDEFINES_H
+#endif //LL_AVATARAPPEARANCE_DEFINES_H
diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6ab341af64ee270f0475f3ad43912e5959041dbe
--- /dev/null
+++ b/indra/llappearance/llavatarjoint.cpp
@@ -0,0 +1,326 @@
+/** 
+ * @file llavatarjoint.cpp
+ * @brief Implementation of LLAvatarJoint class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "llavatarjoint.h"
+
+#include "llgl.h"
+#include "llrender.h"
+#include "llmath.h"
+#include "llglheaders.h"
+#include "llavatarappearance.h"
+
+const F32 DEFAULT_AVATAR_JOINT_LOD = 0.0f;
+
+//-----------------------------------------------------------------------------
+// Static Data
+//-----------------------------------------------------------------------------
+BOOL					LLAvatarJoint::sDisableLOD = FALSE;
+
+//-----------------------------------------------------------------------------
+// LLAvatarJoint()
+// Class Constructors
+//-----------------------------------------------------------------------------
+LLAvatarJoint::LLAvatarJoint() :
+	LLJoint()
+{
+	init();
+}
+
+LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) :
+	LLJoint(name, parent)
+{
+	init();
+}
+
+LLAvatarJoint::LLAvatarJoint(S32 joint_num) :
+	LLJoint(joint_num)
+{
+	init();
+}
+
+
+void LLAvatarJoint::init()
+{
+	mValid = FALSE;
+	mComponents = SC_JOINT | SC_BONE | SC_AXES;
+	mMinPixelArea = DEFAULT_AVATAR_JOINT_LOD;
+	mPickName = PN_DEFAULT;
+	mVisible = TRUE;
+	mMeshID = 0;
+	mIsTransparent = FALSE;
+}
+
+
+//-----------------------------------------------------------------------------
+// ~LLAvatarJoint()
+// Class Destructor
+//-----------------------------------------------------------------------------
+LLAvatarJoint::~LLAvatarJoint()
+{
+}
+
+
+//--------------------------------------------------------------------
+// setValid()
+//--------------------------------------------------------------------
+void LLAvatarJoint::setValid( BOOL valid, BOOL recursive )
+{
+	//----------------------------------------------------------------
+	// set visibility for this joint
+	//----------------------------------------------------------------
+	mValid = valid;
+	
+	//----------------------------------------------------------------
+	// set visibility for children
+	//----------------------------------------------------------------
+	if (recursive)
+	{
+		for (child_list_t::iterator iter = mChildren.begin();
+			 iter != mChildren.end(); ++iter)
+		{
+			LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
+			joint->setValid(valid, TRUE);
+		}
+	}
+
+}
+
+//--------------------------------------------------------------------
+// setSkeletonComponents()
+//--------------------------------------------------------------------
+void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive )
+{
+	mComponents = comp;
+	if (recursive)
+	{
+		for (child_list_t::iterator iter = mChildren.begin();
+			 iter != mChildren.end(); ++iter)
+		{
+			LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+			joint->setSkeletonComponents(comp, recursive);
+		}
+	}
+}
+
+void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive)
+{
+	mVisible = visible;
+
+	if (recursive)
+	{
+		for (child_list_t::iterator iter = mChildren.begin();
+			 iter != mChildren.end(); ++iter)
+		{
+			LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
+			joint->setVisible(visible, recursive);
+		}
+	}
+}
+
+void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
+{
+	for (child_list_t::iterator iter = mChildren.begin();
+		 iter != mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+		joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
+	}
+}
+
+void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
+{
+	for (child_list_t::iterator iter = mChildren.begin();
+		 iter != mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+		joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
+	}
+}
+
+void LLAvatarJoint::updateJointGeometry()
+{
+	for (child_list_t::iterator iter = mChildren.begin();
+		 iter != mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+		joint->updateJointGeometry();
+	}
+}
+
+
+BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate)
+{
+	BOOL lod_changed = FALSE;
+	BOOL found_lod = FALSE;
+
+	for (child_list_t::iterator iter = mChildren.begin();
+		 iter != mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+		F32 jointLOD = joint->getLOD();
+		
+		if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD)
+		{
+			// we've already found a joint to enable, so enable the rest as alternatives
+			lod_changed |= joint->updateLOD(pixel_area, TRUE);
+		}
+		else
+		{
+			if (pixel_area >= jointLOD || sDisableLOD)
+			{
+				lod_changed |= joint->updateLOD(pixel_area, TRUE);
+				found_lod = TRUE;
+			}
+			else
+			{
+				lod_changed |= joint->updateLOD(pixel_area, FALSE);
+			}
+		}
+	}
+	return lod_changed;
+}
+
+void LLAvatarJoint::dump()
+{
+	for (child_list_t::iterator iter = mChildren.begin();
+		 iter != mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+		joint->dump();
+	}
+}
+
+
+void LLAvatarJoint::setMeshesToChildren()
+{
+	removeAllChildren();
+	for (avatar_joint_mesh_list_t::iterator iter = mMeshParts.begin();
+		iter != mMeshParts.end(); iter++)
+	{
+		addChild((*iter));
+	}
+}
+//-----------------------------------------------------------------------------
+// LLAvatarJointCollisionVolume()
+//-----------------------------------------------------------------------------
+
+LLAvatarJointCollisionVolume::LLAvatarJointCollisionVolume()
+{
+	mUpdateXform = FALSE;
+}
+
+/*virtual*/
+U32 LLAvatarJointCollisionVolume::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
+{
+	llerrs << "Cannot call render() on LLAvatarJointCollisionVolume" << llendl;
+	return 0;
+}
+
+LLVector3 LLAvatarJointCollisionVolume::getVolumePos(LLVector3 &offset)
+{
+	mUpdateXform = TRUE;
+	
+	LLVector3 result = offset;
+	result.scaleVec(getScale());
+	result.rotVec(getWorldRotation());
+	result += getWorldPosition();
+
+	return result;
+}
+
+void LLAvatarJointCollisionVolume::renderCollision()
+{
+	updateWorldMatrix();
+	
+	gGL.pushMatrix();
+	gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] );
+
+	gGL.diffuseColor3f( 0.f, 0.f, 1.f );
+	
+	gGL.begin(LLRender::LINES);
+	
+	LLVector3 v[] = 
+	{
+		LLVector3(1,0,0),
+		LLVector3(-1,0,0),
+		LLVector3(0,1,0),
+		LLVector3(0,-1,0),
+
+		LLVector3(0,0,-1),
+		LLVector3(0,0,1),
+	};
+
+	//sides
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[2].mV);
+
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[3].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[2].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[3].mV);
+
+
+	//top
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+	gGL.vertex3fv(v[2].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+	gGL.vertex3fv(v[3].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+
+	//bottom
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.vertex3fv(v[2].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.vertex3fv(v[3].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.end();
+
+	gGL.popMatrix();
+}
+
+
+// End
diff --git a/indra/llappearance/llavatarjoint.h b/indra/llappearance/llavatarjoint.h
new file mode 100644
index 0000000000000000000000000000000000000000..fec91503c787b863ca0a7223561649ce9a257dd4
--- /dev/null
+++ b/indra/llappearance/llavatarjoint.h
@@ -0,0 +1,140 @@
+/** 
+ * @file llavatarjoint.h
+ * @brief Implementation of LLAvatarJoint class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAVATARJOINT_H
+#define LL_LLAVATARJOINT_H
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "lljoint.h"
+#include "lljointpickname.h"
+
+class LLFace;
+class LLAvatarJointMesh;
+
+extern const F32 DEFAULT_AVATAR_JOINT_LOD;
+
+//-----------------------------------------------------------------------------
+// class LLViewerJoint
+//-----------------------------------------------------------------------------
+class LLAvatarJoint :
+	public LLJoint
+{
+public:
+	LLAvatarJoint();
+	LLAvatarJoint(S32 joint_num);
+	// *TODO: Only used for LLVOAvatarSelf::mScreenp.  *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
+	LLAvatarJoint(const std::string &name, LLJoint *parent = NULL);
+	virtual ~LLAvatarJoint();
+
+	// Gets the validity of this joint
+	BOOL getValid() { return mValid; }
+
+	// Sets the validity of this joint
+	virtual void setValid( BOOL valid, BOOL recursive=FALSE );
+
+	// Returns true if this object is transparent.
+	// This is used to determine in which order to draw objects.
+	virtual BOOL isTransparent() { return mIsTransparent; }
+
+	// Returns true if this object should inherit scale modifiers from its immediate parent
+	virtual BOOL inheritScale() { return FALSE; }
+
+	enum Components
+	{
+		SC_BONE		= 1,
+		SC_JOINT	= 2,
+		SC_AXES		= 4
+	};
+
+	// Selects which skeleton components to draw
+	void setSkeletonComponents( U32 comp, BOOL recursive = TRUE );
+
+	// Returns which skeleton components are enables for drawing
+	U32 getSkeletonComponents() { return mComponents; }
+
+	// Sets the level of detail for this node as a minimum
+	// pixel area threshold.  If the current pixel area for this
+	// object is less than the specified threshold, the node is
+	// not traversed.  In addition, if a value is specified (not
+	// default of 0.0), and the pixel area is larger than the
+	// specified minimum, the node is rendered, but no other siblings
+	// of this node under the same parent will be.
+	F32 getLOD() { return mMinPixelArea; }
+	void setLOD( F32 pixelArea ) { mMinPixelArea = pixelArea; }
+
+	void setPickName(LLJointPickName name) { mPickName = name; }
+	LLJointPickName getPickName() { return mPickName; }
+
+	void setVisible( BOOL visible, BOOL recursive );
+
+	// Takes meshes in mMeshParts and sets each one as a child joint
+	void setMeshesToChildren();
+
+	// LLViewerJoint interface
+	virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ) = 0;
+	virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
+	virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
+	virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
+	virtual void updateJointGeometry();
+	virtual void dump();
+	
+
+public:
+	static BOOL	sDisableLOD;
+	avatar_joint_mesh_list_t mMeshParts; //LLViewerJointMesh*
+	void setMeshID( S32 id ) {mMeshID = id;}
+
+protected:
+	void init();
+
+	BOOL		mValid;
+	BOOL		mIsTransparent;
+	U32			mComponents;
+	F32			mMinPixelArea;
+	LLJointPickName	mPickName;
+	BOOL		mVisible;
+	S32			mMeshID;
+};
+
+class LLAvatarJointCollisionVolume : public LLAvatarJoint
+{
+public:
+	LLAvatarJointCollisionVolume();
+	virtual ~LLAvatarJointCollisionVolume() {};
+
+	/*virtual*/ BOOL inheritScale() { return TRUE; }
+	/*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );
+
+	void renderCollision();
+
+	LLVector3 getVolumePos(LLVector3 &offset);
+};
+
+#endif // LL_LLAVATARJOINT_H
+
+
diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4a5cff1dc36a8805f7c1e309daeccc517acc1e28
--- /dev/null
+++ b/indra/llappearance/llavatarjointmesh.cpp
@@ -0,0 +1,375 @@
+/** 
+ * @file LLAvatarJointMesh.cpp
+ * @brief Implementation of LLAvatarJointMesh class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "linden_common.h"
+#include "imageids.h"
+#include "llfasttimer.h"
+#include "llrender.h"
+
+#include "llavatarjointmesh.h"
+#include "llavatarappearance.h"
+//#include "llapr.h"
+//#include "llbox.h"
+//#include "lldrawable.h"
+//#include "lldrawpoolavatar.h"
+//#include "lldrawpoolbump.h"
+//#include "lldynamictexture.h"
+//#include "llface.h"
+//#include "llgldbg.h"
+//#include "llglheaders.h"
+#include "lltexlayer.h"
+//#include "llviewercamera.h"
+//#include "llviewercontrol.h"
+//#include "llviewertexturelist.h"
+//#include "llsky.h"
+//#include "pipeline.h"
+//#include "llviewershadermgr.h"
+#include "llmath.h"
+#include "v4math.h"
+#include "m3math.h"
+#include "m4math.h"
+#include "llmatrix4a.h"
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::LLSkinJoint
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// LLSkinJoint
+//-----------------------------------------------------------------------------
+LLSkinJoint::LLSkinJoint()
+{
+	mJoint       = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// ~LLSkinJoint
+//-----------------------------------------------------------------------------
+LLSkinJoint::~LLSkinJoint()
+{
+	mJoint = NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// LLSkinJoint::setupSkinJoint()
+//-----------------------------------------------------------------------------
+BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint)
+{
+	// find the named joint
+	mJoint = joint;
+	if ( !mJoint )
+	{
+		llinfos << "Can't find joint" << llendl;
+	}
+
+	// compute the inverse root skin matrix
+	mRootToJointSkinOffset.clearVec();
+
+	LLVector3 rootSkinOffset;
+	while (joint)
+	{
+		rootSkinOffset += joint->getSkinOffset();
+		joint = (LLAvatarJoint*)joint->getParent();
+	}
+
+	mRootToJointSkinOffset = -rootSkinOffset;
+	mRootToParentJointSkinOffset = mRootToJointSkinOffset;
+	mRootToParentJointSkinOffset += mJoint->getSkinOffset();
+
+	return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+BOOL LLAvatarJointMesh::sPipelineRender = FALSE;
+EAvatarRenderPass LLAvatarJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;
+U32 LLAvatarJointMesh::sClothingMaskImageName = 0;
+LLColor4 LLAvatarJointMesh::sClothingInnerColor;
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh()
+//-----------------------------------------------------------------------------
+LLAvatarJointMesh::LLAvatarJointMesh()
+	:
+	mTexture( NULL ),
+	mLayerSet( NULL ),
+	mTestImageName( 0 ),
+	mFaceIndexCount(0)
+{
+
+	mColor[0] = 1.0f;
+	mColor[1] = 1.0f;
+	mColor[2] = 1.0f;
+	mColor[3] = 1.0f;
+	mShiny = 0.0f;
+	mCullBackFaces = TRUE;
+
+	mMesh = NULL;
+
+	mNumSkinJoints = 0;
+	mSkinJoints = NULL;
+
+	mFace = NULL;
+
+	mMeshID = 0;
+	mUpdateXform = FALSE;
+
+	mValid = FALSE;
+
+	mIsTransparent = FALSE;
+}
+
+
+//-----------------------------------------------------------------------------
+// ~LLAvatarJointMesh()
+// Class Destructor
+//-----------------------------------------------------------------------------
+LLAvatarJointMesh::~LLAvatarJointMesh()
+{
+	mMesh = NULL;
+	mTexture = NULL;
+	freeSkinData();
+}
+
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::allocateSkinData()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarJointMesh::allocateSkinData( U32 numSkinJoints )
+{
+	mSkinJoints = new LLSkinJoint[ numSkinJoints ];
+	mNumSkinJoints = numSkinJoints;
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::freeSkinData()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::freeSkinData()
+{
+	mNumSkinJoints = 0;
+	delete [] mSkinJoints;
+	mSkinJoints = NULL;
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getColor()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha )
+{
+	*red   = mColor[0];
+	*green = mColor[1];
+	*blue  = mColor[2];
+	*alpha = mColor[3];
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setColor()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha )
+{
+	mColor[0] = red;
+	mColor[1] = green;
+	mColor[2] = blue;
+	mColor[3] = alpha;
+}
+
+void LLAvatarJointMesh::setColor( const LLColor4& color )
+{
+	mColor = color;
+}
+
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getTexture()
+//--------------------------------------------------------------------
+//LLViewerTexture *LLAvatarJointMesh::getTexture()
+//{
+//	return mTexture;
+//}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setTexture()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setTexture( LLGLTexture *texture )
+{
+	mTexture = texture;
+
+	// texture and dynamic_texture are mutually exclusive
+	if( texture )
+	{
+		mLayerSet = NULL;
+		//texture->bindTexture(0);
+		//texture->setClamp(TRUE, TRUE);
+	}
+}
+
+
+BOOL LLAvatarJointMesh::hasGLTexture() const
+{
+	return mTexture.notNull() && mTexture->hasGLTexture();
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setLayerSet()
+// Sets the shape texture (takes precedence over normal texture)
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setLayerSet( LLTexLayerSet* layer_set )
+{
+	mLayerSet = layer_set;
+	
+	// texture and dynamic_texture are mutually exclusive
+	if( layer_set )
+	{
+		mTexture = NULL;
+	}
+}
+
+BOOL LLAvatarJointMesh::hasComposite() const
+{
+	return (mLayerSet && mLayerSet->hasComposite());
+}
+
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getMesh()
+//--------------------------------------------------------------------
+LLPolyMesh *LLAvatarJointMesh::getMesh()
+{
+	return mMesh;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::setMesh()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh )
+{
+	// set the mesh pointer
+	mMesh = mesh;
+
+	// release any existing skin joints
+	freeSkinData();
+
+	if ( mMesh == NULL )
+	{
+		return;
+	}
+
+	// acquire the transform from the mesh object
+	setPosition( mMesh->getPosition() );
+	setRotation( mMesh->getRotation() );
+	setScale( mMesh->getScale() );
+
+	// create skin joints if necessary
+	if ( mMesh->hasWeights() && !mMesh->isLOD())
+	{
+		U32 numJointNames = mMesh->getNumJointNames();
+		
+		allocateSkinData( numJointNames );
+		std::string *jointNames = mMesh->getJointNames();
+
+		U32 jn;
+		for (jn = 0; jn < numJointNames; jn++)
+		{
+			//llinfos << "Setting up joint " << jointNames[jn] << llendl;
+			LLAvatarJoint* joint = (LLAvatarJoint*)(getRoot()->findJoint(jointNames[jn]) );
+			mSkinJoints[jn].setupSkinJoint( joint );
+		}
+	}
+
+	// setup joint array
+	if (!mMesh->isLOD())
+	{
+		setupJoint((LLAvatarJoint*)getRoot());
+	}
+
+//	llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl;
+}
+
+//-----------------------------------------------------------------------------
+// setupJoint()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint)
+{
+//	llinfos << "Mesh: " << getName() << llendl;
+
+//	S32 joint_count = 0;
+	U32 sj;
+	for (sj=0; sj<mNumSkinJoints; sj++)
+	{
+		LLSkinJoint &js = mSkinJoints[sj];
+
+		if (js.mJoint != current_joint)
+		{
+			continue;
+		}
+
+		// we've found a skinjoint for this joint..
+
+		// is the last joint in the array our parent?
+		if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == &current_joint->getParent()->getWorldMatrix())
+		{
+			// ...then just add ourselves
+			LLAvatarJoint* jointp = js.mJoint;
+			mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js));
+//			llinfos << "joint " << joint_count << js.mJoint->getName() << llendl;
+//			joint_count++;
+		}
+		// otherwise add our parent and ourselves
+		else
+		{
+			mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getParent()->getWorldMatrix(), NULL));
+//			llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl;
+//			joint_count++;
+			mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getWorldMatrix(), &js));
+//			llinfos << "joint " << joint_count << current_joint->getName() << llendl;
+//			joint_count++;
+		}
+	}
+
+	// depth-first traversal
+	for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin();
+		 iter != current_joint->mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);
+		setupJoint(child_joint);
+	}
+}
+
+
+// End
diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h
new file mode 100644
index 0000000000000000000000000000000000000000..6486932cdfcd38ea5e7441da037cfabaa50c3603
--- /dev/null
+++ b/indra/llappearance/llavatarjointmesh.h
@@ -0,0 +1,145 @@
+/** 
+ * @file llavatarjointmesh.h
+ * @brief Declaration of LLAvatarJointMesh class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAVATARJOINTMESH_H
+#define LL_LLAVATARJOINTMESH_H
+
+#include "llavatarjoint.h"
+#include "llgltexture.h"
+#include "llpolymesh.h"
+#include "v4color.h"
+
+class LLDrawable;
+class LLFace;
+class LLCharacter;
+class LLTexLayerSet;
+
+typedef enum e_avatar_render_pass
+{
+	AVATAR_RENDER_PASS_SINGLE,
+	AVATAR_RENDER_PASS_CLOTHING_INNER,
+	AVATAR_RENDER_PASS_CLOTHING_OUTER
+} EAvatarRenderPass;
+
+class LLSkinJoint
+{
+public:
+	LLSkinJoint();
+	~LLSkinJoint();
+	BOOL setupSkinJoint( LLAvatarJoint *joint);
+
+	LLAvatarJoint	*mJoint;
+	LLVector3		mRootToJointSkinOffset;
+	LLVector3		mRootToParentJointSkinOffset;
+};
+
+//-----------------------------------------------------------------------------
+// class LLViewerJointMesh
+//-----------------------------------------------------------------------------
+class LLAvatarJointMesh : public virtual LLAvatarJoint
+{
+protected:
+	LLColor4					mColor;			// color value
+// 	LLColor4					mSpecular;		// specular color (always white for now)
+	F32							mShiny;			// shiny value
+	LLPointer<LLGLTexture>		mTexture;		// ptr to a global texture
+	LLTexLayerSet*				mLayerSet;		// ptr to a layer set owned by the avatar
+	U32 						mTestImageName;		// handle to a temporary texture for previewing uploads
+	LLPolyMesh*					mMesh;			// ptr to a global polymesh
+	BOOL						mCullBackFaces;	// true by default
+	LLFace*						mFace;			// ptr to a face w/ AGP copy of mesh
+
+	U32							mFaceIndexCount;
+
+	U32							mNumSkinJoints;
+	LLSkinJoint*				mSkinJoints;
+	S32							mMeshID;
+
+public:
+	static BOOL					sPipelineRender;
+	//RN: this is here for testing purposes
+	static U32					sClothingMaskImageName;
+	static EAvatarRenderPass	sRenderPass;
+	static LLColor4				sClothingInnerColor;
+
+public:
+	// Constructor
+	LLAvatarJointMesh();
+
+	// Destructor
+	virtual ~LLAvatarJointMesh();
+
+	// Gets the shape color
+	void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha );
+
+	// Sets the shape color
+	void setColor( F32 red, F32 green, F32 blue, F32 alpha );
+	void setColor( const LLColor4& color );
+
+	// Sets the shininess
+	void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; };
+
+	// Sets the shape texture
+	void setTexture( LLGLTexture *texture );
+
+	BOOL hasGLTexture() const;
+
+	void setTestTexture( U32 name ) { mTestImageName = name; }
+
+	// Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture)
+	void setLayerSet( LLTexLayerSet* layer_set );
+
+	BOOL hasComposite() const;
+
+	// Gets the poly mesh
+	LLPolyMesh *getMesh();
+
+	// Sets the poly mesh
+	void setMesh( LLPolyMesh *mesh );
+
+	// Sets up joint matrix data for rendering
+	void setupJoint(LLAvatarJoint* current_joint);
+
+	// Render time method to upload batches of joint matrices
+	void uploadJointMatrices();
+
+	// Sets ID for picking
+	void setMeshID( S32 id ) {mMeshID = id;}
+
+	// Gets ID for picking
+	S32 getMeshID() { return mMeshID; }	
+
+	void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; }
+
+private:
+	// Allocate skin data
+	BOOL allocateSkinData( U32 numSkinJoints );
+
+	// Free skin data
+	void freeSkinData();
+};
+
+#endif // LL_LLAVATARJOINTMESH_H
diff --git a/indra/newview/lldriverparam.cpp b/indra/llappearance/lldriverparam.cpp
similarity index 88%
rename from indra/newview/lldriverparam.cpp
rename to indra/llappearance/lldriverparam.cpp
index 885cae1737003f2f489139ca583b2c0251f405fc..1f7e8b86524a667bd8a46f5a2ac080acaab53ff1 100644
--- a/indra/newview/lldriverparam.cpp
+++ b/indra/llappearance/lldriverparam.cpp
@@ -24,22 +24,20 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 
 #include "lldriverparam.h"
 
-#include "llfasttimer.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "llagent.h"
+#include "llavatarappearance.h"
 #include "llwearable.h"
-#include "llagentwearables.h"
+#include "llwearabledata.h"
 
 //-----------------------------------------------------------------------------
 // LLDriverParamInfo
 //-----------------------------------------------------------------------------
 
-LLDriverParamInfo::LLDriverParamInfo()
+LLDriverParamInfo::LLDriverParamInfo() :
+	mDriverParam(NULL)
 {
 }
 
@@ -112,12 +110,14 @@ void LLDriverParamInfo::toStream(std::ostream &out)
 
 	out << std::endl;
 
-	if(isAgentAvatarValid())
+	if(mDriverParam && mDriverParam->getAvatarAppearance()->isSelf() &&
+		mDriverParam->getAvatarAppearance()->isValid())
 	{
 		for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
 		{
 			LLDrivenEntryInfo driven = *iter;
-			LLViewerVisualParam *param = (LLViewerVisualParam*)gAgentAvatarp->getVisualParam(driven.mDrivenID);
+			LLViewerVisualParam *param = 
+				(LLViewerVisualParam*)mDriverParam->getAvatarAppearance()->getVisualParam(driven.mDrivenID);
 			if (param)
 			{
 				param->getInfo()->toStream(out);
@@ -139,7 +139,9 @@ void LLDriverParamInfo::toStream(std::ostream &out)
 			}
 			else
 			{
-				llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp.get() << " for driver parameter " << getID() << llendl;
+				llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " 
+						<< mDriverParam->getAvatarAppearance() 
+						<< " for driver parameter " << getID() << llendl;
 			}
 			out << std::endl;
 		}
@@ -150,19 +152,16 @@ void LLDriverParamInfo::toStream(std::ostream &out)
 // LLDriverParam
 //-----------------------------------------------------------------------------
 
-LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) : 
+LLDriverParam::LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable /* = NULL */) :
 	mCurrentDistortionParam( NULL ), 
-	mAvatarp(avatarp), 
-	mWearablep(NULL)
-{
-	mDefaultVec.clear();
-}
-
-LLDriverParam::LLDriverParam(LLWearable *wearablep) : 
-	mCurrentDistortionParam( NULL ), 
-	mAvatarp(NULL), 
-	mWearablep(wearablep)
+	mAvatarAppearance(appearance), 
+	mWearablep(wearable)
 {
+	llassert(mAvatarAppearance);
+	if (mWearablep)
+	{
+		llassert(mAvatarAppearance->isSelf());
+	}
 	mDefaultVec.clear();
 }
 
@@ -177,67 +176,25 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)
 		return FALSE;
 	mInfo = info;
 	mID = info->mID;
+	info->mDriverParam = this;
 
 	setWeight(getDefaultWeight(), FALSE );
 
 	return TRUE;
 }
 
-void LLDriverParam::setWearable(LLWearable *wearablep)
-{
-	if (wearablep)
-	{
-		mWearablep = wearablep;
-		mAvatarp = NULL;
-	}
-}
-
-void LLDriverParam::setAvatar(LLVOAvatar *avatarp)
-{
-	if (avatarp)
-	{
-		mWearablep = NULL;
-		mAvatarp = avatarp;
-	}
-}
-
 /*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
 {
-	LLDriverParam *new_param;
-	if (wearable)
-	{
-		new_param = new LLDriverParam(wearable);
-	}
-	else
-	{
-		if (mWearablep)
-		{
-			new_param = new LLDriverParam(mWearablep);
-		}
-		else
-		{
-			new_param = new LLDriverParam(mAvatarp);
-		}
-	}
+	llassert(wearable);
+	LLDriverParam *new_param = new LLDriverParam(mAvatarAppearance, wearable);
+	// FIXME DRANO this clobbers mWearablep, which means any code
+	// currently using mWearablep is wrong, or at least untested.
 	*new_param = *this;
+	//new_param->mWearablep = wearable;
+//	new_param->mDriven.clear(); // clear driven list to avoid overwriting avatar driven params from wearables. 
 	return new_param;
 }
 
-#if 0 // obsolete
-BOOL LLDriverParam::parseData(LLXmlTreeNode* node)
-{
-	LLDriverParamInfo* info = new LLDriverParamInfo;
-
-	info->parseXml(node);
-	if (!setInfo(info))
-	{
-		delete info;
-		return FALSE;
-	}
-	return TRUE;
-}
-#endif
-
 void LLDriverParam::setWeight(F32 weight, BOOL upload_bake)
 {
 	F32 min_weight = getMinWeight();
@@ -456,6 +413,20 @@ const LLVector4a*	LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly
 	return v;
 };
 
+S32 LLDriverParam::getDrivenParamsCount() const
+{
+	return mDriven.size();
+}
+
+const LLViewerVisualParam* LLDriverParam::getDrivenParam(S32 index) const
+{
+	if (0 > index || index >= mDriven.size())
+	{
+		return NULL;
+	}
+	return mDriven[index].mParam;
+}
+
 //-----------------------------------------------------------------------------
 // setAnimationTarget()
 //-----------------------------------------------------------------------------
@@ -511,6 +482,7 @@ BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross
 		if (!found)
 		{
 			LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id);
+			if (param) param->setParamLocation(this->getParamLocation());
 			bool push = param && (!only_cross_params || param->getCrossWearable());
 			if (push)
 			{
@@ -555,7 +527,7 @@ void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)
 		// Thus this wearable needs to get updates from the driver wearable.
 		// The call to setVisualParamWeight seems redundant, but is necessary
 		// as the number of driven wearables has changed since the last update. -Nyx
-		LLWearable *wearable = gAgentWearables.getTopWearable(driver_type);
+		LLWearable *wearable = mAvatarAppearance->getWearableData()->getTopWearable(driver_type);
 		if (wearable)
 		{
 			wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false);
@@ -623,13 +595,22 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight
 
 void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)
 {
-	if(isAgentAvatarValid() &&
-	   mWearablep && 
-	   driven->mParam->getCrossWearable() &&
-	   mWearablep->isOnTop())
+	bool use_self = false;
+	if(mWearablep &&
+		mAvatarAppearance->isValid() &&
+		driven->mParam->getCrossWearable())
+	{
+		LLWearable* wearable = dynamic_cast<LLWearable*> (mWearablep);
+		if (mAvatarAppearance->getWearableData()->isOnTop(wearable))
+		{
+			use_self = true;
+		}
+	}
+
+	if (use_self)
 	{
 		// call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
-		gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
+		mAvatarAppearance->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
 	}
 	else
 	{
diff --git a/indra/newview/lldriverparam.h b/indra/llappearance/lldriverparam.h
similarity index 87%
rename from indra/newview/lldriverparam.h
rename to indra/llappearance/lldriverparam.h
index 216cf003e1105a2efb69920ab60947d4a168afa2..040c9cf5be1dce89df81b2b31b49b27f3be3fb92 100644
--- a/indra/newview/lldriverparam.h
+++ b/indra/llappearance/lldriverparam.h
@@ -30,8 +30,8 @@
 #include "llviewervisualparam.h"
 #include "llwearabletype.h"
 
-class LLPhysicsMotion;
-class LLVOAvatar;
+class LLAvatarAppearance;
+class LLDriverParam;
 class LLWearable;
 
 //-----------------------------------------------------------------------------
@@ -71,6 +71,7 @@ class LLDriverParamInfo : public LLViewerVisualParamInfo
 protected:
 	typedef std::deque<LLDrivenEntryInfo> entry_info_list_t;
 	entry_info_list_t mDrivenInfoList;
+	LLDriverParam* mDriverParam; // backpointer
 };
 
 //-----------------------------------------------------------------------------
@@ -78,10 +79,11 @@ class LLDriverParamInfo : public LLViewerVisualParamInfo
 LL_ALIGN_PREFIX(16)
 class LLDriverParam : public LLViewerVisualParam
 {
-	friend class LLPhysicsMotion; // physics motion needs to access driven params directly.
+private:
+	// Hide the default constructor.  Force construction with LLAvatarAppearance.
+	LLDriverParam() {}
 public:
-	LLDriverParam(LLVOAvatar *avatarp);
-	LLDriverParam(LLWearable *wearablep);
+	LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable = NULL);
 	~LLDriverParam();
 
 	void* operator new(size_t size)
@@ -99,14 +101,14 @@ class LLDriverParam : public LLViewerVisualParam
 	//   This sets mInfo and calls initialization functions
 	BOOL					setInfo(LLDriverParamInfo *info);
 
-	void					setWearable(LLWearable *wearablep);
-	void					setAvatar(LLVOAvatar *avatarp);
+	LLAvatarAppearance* getAvatarAppearance() { return mAvatarAppearance; }
+	const LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
+
 	void					updateCrossDrivenParams(LLWearableType::EType driven_type);
 
 	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
 
 	// LLVisualParam Virtual functions
-	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node);
 	/*virtual*/ void				apply( ESex sex ) {} // apply is called separately for each driven param.
 	/*virtual*/ void				setWeight(F32 weight, BOOL upload_bake);
 	/*virtual*/ void				setAnimationTarget( F32 target_value, BOOL upload_bake );
@@ -122,6 +124,9 @@ class LLDriverParam : public LLViewerVisualParam
 	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
 	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
 
+	S32								getDrivenParamsCount() const;
+	const LLViewerVisualParam*		getDrivenParam(S32 index) const;
+
 protected:
 	F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
 	void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
@@ -132,7 +137,7 @@ class LLDriverParam : public LLViewerVisualParam
 	entry_list_t mDriven;
 	LLViewerVisualParam* mCurrentDistortionParam;
 	// Backlink only; don't make this an LLPointer.
-	LLVOAvatar* mAvatarp;
+	LLAvatarAppearance* mAvatarAppearance;
 	LLWearable* mWearablep;
 } LL_ALIGN_POSTFIX(16);
 
diff --git a/indra/llappearance/lljointpickname.h b/indra/llappearance/lljointpickname.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d41a761fc3970057ba2f3867567db366341f8e5
--- /dev/null
+++ b/indra/llappearance/lljointpickname.h
@@ -0,0 +1,49 @@
+/** 
+ * @file lljointpickname.h
+ * @brief Defines OpenGL seleciton stack names
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_LLJOINTPICKNAME_H
+#define LL_LLJOINTPICKNAME_H
+
+class LLAvatarJointMesh;
+
+// Sets the OpenGL selection stack name that is pushed and popped
+// with this joint state.  The default value indicates that no name
+// should be pushed/popped.
+enum LLJointPickName
+{
+	PN_DEFAULT = -1,
+	PN_0 = 0,
+	PN_1 = 1,
+	PN_2 = 2,
+	PN_3 = 3,
+	PN_4 = 4,
+	PN_5 = 5
+};
+
+typedef std::vector<LLAvatarJointMesh*> avatar_joint_mesh_list_t;
+
+#endif // LL_LLJOINTPICKNAME_H
diff --git a/indra/newview/lllocaltextureobject.cpp b/indra/llappearance/lllocaltextureobject.cpp
similarity index 92%
rename from indra/newview/lllocaltextureobject.cpp
rename to indra/llappearance/lllocaltextureobject.cpp
index 07ec0fab95c7c87f92bc62fd4163d12798555ef7..7e36a06797456fbb12be34d171524a5d126e1aab 100644
--- a/indra/newview/lllocaltextureobject.cpp
+++ b/indra/llappearance/lllocaltextureobject.cpp
@@ -23,13 +23,14 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 
 #include "lllocaltextureobject.h"
 
+#include "llimage.h"
+#include "llrender.h"
 #include "lltexlayer.h"
-#include "llviewertexture.h"
-#include "lltextureentry.h"
+#include "llgltexture.h"
 #include "lluuid.h"
 #include "llwearable.h"
 
@@ -41,7 +42,7 @@ LLLocalTextureObject::LLLocalTextureObject() :
 	mImage = NULL;
 }
 
-LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id) :
+LLLocalTextureObject::LLLocalTextureObject(LLGLTexture* image, const LLUUID& id) :
 	mIsBakedReady(FALSE),
 	mDiscard(MAX_DISCARD_LEVEL+1)
 {
@@ -77,7 +78,7 @@ LLLocalTextureObject::~LLLocalTextureObject()
 {
 }
 
-LLViewerFetchedTexture* LLLocalTextureObject::getImage() const
+LLGLTexture* LLLocalTextureObject::getImage() const
 {
 	return mImage;
 }
@@ -126,7 +127,7 @@ BOOL LLLocalTextureObject::getBakedReady() const
 	return mIsBakedReady;
 }
 
-void LLLocalTextureObject::setImage(LLViewerFetchedTexture* new_image)
+void LLLocalTextureObject::setImage(LLGLTexture* new_image)
 {
 	mImage = new_image;
 }
diff --git a/indra/newview/lllocaltextureobject.h b/indra/llappearance/lllocaltextureobject.h
similarity index 89%
rename from indra/newview/lllocaltextureobject.h
rename to indra/llappearance/lllocaltextureobject.h
index b9bfc5472fa4e7aca81e9e2f4ecb5db8aa1b6e00..9b9f41fd1961e0ca30b149a8a0a647734ad36f12 100644
--- a/indra/newview/lllocaltextureobject.h
+++ b/indra/llappearance/lllocaltextureobject.h
@@ -29,11 +29,10 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include "llviewertexture.h"
+#include "llpointer.h"
+#include "llgltexture.h"
 
-class LLUUID;
 class LLTexLayer;
-class LLTextureEntry;
 class LLTexLayerTemplate;
 class LLWearable;
 
@@ -44,11 +43,11 @@ class LLLocalTextureObject
 {
 public:
 	LLLocalTextureObject();
-	LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id);
+	LLLocalTextureObject(LLGLTexture* image, const LLUUID& id);
 	LLLocalTextureObject(const LLLocalTextureObject& lto);
 	~LLLocalTextureObject();
 
-	LLViewerFetchedTexture* getImage() const;
+	LLGLTexture* getImage() const;
 	LLTexLayer* getTexLayer(U32 index) const;
 	LLTexLayer* getTexLayer(const std::string &name);
 	U32 		getNumTexLayers() const;
@@ -56,7 +55,7 @@ class LLLocalTextureObject
 	S32			getDiscard() const;
 	BOOL		getBakedReady() const;
 
-	void setImage(LLViewerFetchedTexture* new_image);
+	void setImage(LLGLTexture* new_image);
 	BOOL setTexLayer(LLTexLayer *new_tex_layer, U32 index);
 	BOOL addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable);
 	BOOL addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable);
@@ -70,7 +69,7 @@ class LLLocalTextureObject
 
 private:
 
-	LLPointer<LLViewerFetchedTexture>  			mImage;
+	LLPointer<LLGLTexture>			mImage;
 	// NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer
 	// using shared pointers here only for smart assignment & cleanup
 	// do NOT create new shared pointers to these objects, or keep pointers to them around
diff --git a/indra/newview/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp
similarity index 81%
rename from indra/newview/llpolymesh.cpp
rename to indra/llappearance/llpolymesh.cpp
index 5f5258bbceb05bb120259f1ba25dcefe75f4130b..a01457246e19de1ff115e9e16bfa08d4f6ed6d27 100644
--- a/indra/newview/llpolymesh.cpp
+++ b/indra/llappearance/llpolymesh.cpp
@@ -27,25 +27,24 @@
 //-----------------------------------------------------------------------------
 // Header Files
 //-----------------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
-
+#include "linden_common.h"
+#include "llpolymesh.h"
 #include "llfasttimer.h"
 #include "llmemory.h"
 
-#include "llviewercontrol.h"
+//#include "llviewercontrol.h"
 #include "llxmltree.h"
-#include "llvoavatar.h"
+#include "llavatarappearance.h"
 #include "llwearable.h"
 #include "lldir.h"
 #include "llvolume.h"
 #include "llendianswizzle.h"
 
-#include "llpolymesh.h"
 
 #define HEADER_ASCII "Linden Mesh 1.0"
 #define HEADER_BINARY "Linden Binary Mesh 1.0"
 
-extern LLControlGroup gSavedSettings;                           // read only
+//extern LLControlGroup gSavedSettings;                           // read only
 
 LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
 					     const std::string &name);
@@ -241,7 +240,7 @@ BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
 			mBaseNormals[i].clear();
 			mBaseBinormals[i].clear();
 			mTexCoords[i].clear();
-			mWeights[i] = 0.f;
+            mWeights[i] = 0.f;
         }
         mNumVertices = numVertices;
         return TRUE;
@@ -1046,250 +1045,4 @@ F32*    LLPolyMesh::getWritableWeights() const
         return mSharedData->mWeights;
 }
 
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDistortionInfo()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
-{
-}
-
-BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
-{
-        llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
-        
-        if (!LLViewerVisualParamInfo::parseXml(node))
-                return FALSE;
-
-        LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
-
-        if (NULL == skeletalParam)
-        {
-                llwarns << "Failed to getChildByName(\"param_skeleton\")"
-                        << llendl;
-                return FALSE;
-        }
-
-        for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
-        {
-                if (bone->hasName("bone"))
-                {
-                        std::string name;
-                        LLVector3 scale;
-                        LLVector3 pos;
-                        BOOL haspos = FALSE;
-                        
-                        static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-                        if (!bone->getFastAttributeString(name_string, name))
-                        {
-                                llwarns << "No bone name specified for skeletal param." << llendl;
-                                continue;
-                        }
-
-                        static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
-                        if (!bone->getFastAttributeVector3(scale_string, scale))
-                        {
-                                llwarns << "No scale specified for bone " << name << "." << llendl;
-                                continue;
-                        }
-
-                        // optional offset deformation (translation)
-                        static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
-                        if (bone->getFastAttributeVector3(offset_string, pos))
-                        {
-                                haspos = TRUE;
-                        }
-                        mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
-                }
-                else
-                {
-                        llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
-                        continue;
-                }
-        }
-        return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDistortion()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)
-{
-        mAvatar = avatarp;
-        mDefaultVec.splat(0.001f);
-}
-
-//-----------------------------------------------------------------------------
-// ~LLPolySkeletalDistortion()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
-{
-}
-
-BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
-{
-        llassert(mInfo == NULL);
-        if (info->mID < 0)
-                return FALSE;
-        mInfo = info;
-        mID = info->mID;
-        setWeight(getDefaultWeight(), FALSE );
-
-        LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
-        for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
-        {
-                LLPolySkeletalBoneInfo *bone_info = &(*iter);
-                LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
-                if (!joint)
-                {
-                        llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
-                        continue;
-                }
-
-                if (mJointScales.find(joint) != mJointScales.end())
-                {
-                        llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
-                }
-
-                // store it
-                mJointScales[joint] = bone_info->mScaleDeformation;
-
-                // apply to children that need to inherit it
-                for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
-                     iter != joint->mChildren.end(); ++iter)
-                {
-                        LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
-                        if (child_joint->inheritScale())
-                        {
-                                LLVector3 childDeformation = LLVector3(child_joint->getScale());
-                                childDeformation.scaleVec(bone_info->mScaleDeformation);
-                                mJointScales[child_joint] = childDeformation;
-                        }
-                }
-
-                if (bone_info->mHasPositionDeformation)
-                {
-                        if (mJointOffsets.find(joint) != mJointOffsets.end())
-                        {
-                                llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
-                        }
-                        mJointOffsets[joint] = bone_info->mPositionDeformation;
-                }
-        }
-        return TRUE;
-}
-
-/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
-{
-        LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
-        *new_param = *this;
-        return new_param;
-}
-
-//-----------------------------------------------------------------------------
-// apply()
-//-----------------------------------------------------------------------------
-static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion");
-
-void LLPolySkeletalDistortion::apply( ESex avatar_sex )
-{
-	LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY);
-
-        F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
-
-        LLJoint* joint;
-        joint_vec_map_t::iterator iter;
-
-        for (iter = mJointScales.begin();
-             iter != mJointScales.end();
-             iter++)
-        {
-                joint = iter->first;
-                LLVector3 newScale = joint->getScale();
-                LLVector3 scaleDelta = iter->second;
-                newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
-                joint->setScale(newScale);
-        }
-
-        for (iter = mJointOffsets.begin();
-             iter != mJointOffsets.end();
-             iter++)
-        {
-                joint = iter->first;
-                LLVector3 newPosition = joint->getPosition();
-                LLVector3 positionDelta = iter->second;
-                newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
-                joint->setPosition(newPosition);
-        }
-
-        if (mLastWeight != mCurWeight && !mIsAnimating)
-        {
-                mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
-        }
-        mLastWeight = mCurWeight;
-}
-
-
-LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
-					     const std::string &name)
-{
-        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
-        cloned_morph_data->mName = name;
-        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
-        {
-                cloned_morph_data->mCoords[v] = src_data->mCoords[v];
-                cloned_morph_data->mNormals[v] = src_data->mNormals[v];
-                cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
-        }
-        return cloned_morph_data;
-}
-
-LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
-					     const LLVector3 &direction,
-					     const std::string &name)
-{
-        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
-        cloned_morph_data->mName = name;
-		LLVector4a dir;
-		dir.load3(direction.mV);
-
-        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
-        {
-                cloned_morph_data->mCoords[v] = dir;
-                cloned_morph_data->mNormals[v].clear();
-                cloned_morph_data->mBinormals[v].clear();
-        }
-        return cloned_morph_data;
-}
-
-LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
-                                            F32 scale,
-                                            const std::string &name)
-{
-        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
-        cloned_morph_data->mName = name;
-
-		LLVector4a sc;
-		sc.splat(scale);
-
-		LLVector4a nsc;
-		nsc.set(scale, -scale, scale, scale);
-
-        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
-        {
-            if (cloned_morph_data->mCoords[v][1] < 0)
-            {
-                cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc);
-				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc);
-				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc);
-			}
-			else
-			{
-				cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc);
-				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc);
-				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc);
-			}
-        }
-        return cloned_morph_data;
-}
-
 // End
diff --git a/indra/newview/llpolymesh.h b/indra/llappearance/llpolymesh.h
similarity index 75%
rename from indra/newview/llpolymesh.h
rename to indra/llappearance/llpolymesh.h
index 28da230541a0a422881fccb26790616faab7204c..ef1dfb1adb25feb94f105bde280589ae588a0511 100644
--- a/indra/newview/llpolymesh.h
+++ b/indra/llappearance/llpolymesh.h
@@ -24,8 +24,8 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_LLPOLYMESH_H
-#define LL_LLPOLYMESH_H
+#ifndef LL_LLPOLYMESHINTERFACE_H
+#define LL_LLPOLYMESHINTERFACE_H
 
 #include <string>
 #include <map>
@@ -39,7 +39,7 @@
 //#include "lldarray.h"
 
 class LLSkinJoint;
-class LLVOAvatar;
+class LLAvatarAppearance;
 class LLWearable;
 
 //#define USE_STRIPS	// Use tri-strips for rendering.
@@ -319,8 +319,8 @@ class LLPolyMesh
 
 	BOOL	isLOD() { return mSharedData && mSharedData->isLOD(); }
 
-	void setAvatar(LLVOAvatar* avatarp) { mAvatarp = avatarp; }
-	LLVOAvatar* getAvatar() { return mAvatarp; }
+	void setAvatar(LLAvatarAppearance* avatarp) { mAvatarp = avatarp; }
+	LLAvatarAppearance* getAvatar() { return mAvatarp; }
 
 	LLDynamicArray<LLJointRenderData*>	mJointRenderData;
 
@@ -362,90 +362,8 @@ class LLPolyMesh
 	static LLPolyMeshSharedDataTable sGlobalSharedMeshList;
 
 	// Backlink only; don't make this an LLPointer.
-	LLVOAvatar* mAvatarp;
+	LLAvatarAppearance* mAvatarp;
 };
 
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDeformationInfo
-// Shared information for LLPolySkeletalDeformations
-//-----------------------------------------------------------------------------
-struct LLPolySkeletalBoneInfo
-{
-	LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos)
-		: mBoneName(name),
-		  mScaleDeformation(scale),
-		  mPositionDeformation(pos),
-		  mHasPositionDeformation(haspos) {}
-	std::string mBoneName;
-	LLVector3 mScaleDeformation;
-	LLVector3 mPositionDeformation;
-	BOOL mHasPositionDeformation;
-};
-
-class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
-{
-	friend class LLPolySkeletalDistortion;
-public:
-	LLPolySkeletalDistortionInfo();
-	/*virtual*/ ~LLPolySkeletalDistortionInfo() {};
-	
-	/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
-
-protected:
-	typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
-	bone_info_list_t mBoneInfoList;
-};
-
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDeformation
-// A set of joint scale data for deforming the avatar mesh
-//-----------------------------------------------------------------------------
-
-LL_ALIGN_PREFIX(16)
-class LLPolySkeletalDistortion : public LLViewerVisualParam
-{
-public:
-	LLPolySkeletalDistortion(LLVOAvatar *avatarp);
-	~LLPolySkeletalDistortion();
-
-	void* operator new(size_t size)
-	{
-		return ll_aligned_malloc_16(size);
-	}
-
-	void operator delete(void* ptr)
-	{
-		ll_aligned_free_16(ptr);
-	}
-
-	// Special: These functions are overridden by child classes
-	LLPolySkeletalDistortionInfo*	getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; }
-	//   This sets mInfo and calls initialization functions
-	BOOL							setInfo(LLPolySkeletalDistortionInfo *info);
-
-	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
-
-	// LLVisualParam Virtual functions
-	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node);
-	/*virtual*/ void				apply( ESex sex );
-	
-	// LLViewerVisualParam Virtual functions
-	/*virtual*/ F32					getTotalDistortion() { return 0.1f; }
-	/*virtual*/ const LLVector4a&	getAvgDistortion()	{ return mDefaultVec; }
-	/*virtual*/ F32					getMaxDistortion() { return 0.1f; }
-	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);}
-	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
-	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
-
-protected:
-	LL_ALIGN_16(LLVector4a	mDefaultVec);
-
-	typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
-	joint_vec_map_t mJointScales;
-	joint_vec_map_t mJointOffsets;
-	// Backlink only; don't make this an LLPointer.
-	LLVOAvatar *mAvatar;
-} LL_ALIGN_POSTFIX(16);
-
-#endif // LL_LLPOLYMESH_H
+#endif // LL_LLPOLYMESHINTERFACE_H
 
diff --git a/indra/newview/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp
similarity index 99%
rename from indra/newview/llpolymorph.cpp
rename to indra/llappearance/llpolymorph.cpp
index 495fdc348c043f9da78394d2e1da58887f9ad097..8a178190833ca463c15499e9722cb4e7300ca8af 100644
--- a/indra/newview/llpolymorph.cpp
+++ b/indra/llappearance/llpolymorph.cpp
@@ -27,13 +27,14 @@
 //-----------------------------------------------------------------------------
 // Header Files
 //-----------------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
 
 #include "llpolymorph.h"
-#include "llvoavatar.h"
+#include "llavatarappearance.h"
+#include "llavatarjoint.h"
 #include "llwearable.h"
 #include "llxmltree.h"
 #include "llendianswizzle.h"
+#include "llpolymesh.h"
 
 //#include "../tools/imdebug/imdebug.h"
 
@@ -343,7 +344,7 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
 	mID = info->mID;
 	setWeight(getDefaultWeight(), FALSE );
 
-	LLVOAvatar* avatarp = mMesh->getAvatar();
+	LLAvatarAppearance* avatarp = mMesh->getAvatar();
 	LLPolyMorphTargetInfo::volume_info_list_t::iterator iter;
 	for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++)
 	{
diff --git a/indra/newview/llpolymorph.h b/indra/llappearance/llpolymorph.h
similarity index 97%
rename from indra/newview/llpolymorph.h
rename to indra/llappearance/llpolymorph.h
index 24940c52e0fa390cb529822cea09cda021a7480b..ee380ae7c3792bf2b85217deadd8b19d282ddd27 100644
--- a/indra/newview/llpolymorph.h
+++ b/indra/llappearance/llpolymorph.h
@@ -32,10 +32,10 @@
 
 #include "llviewervisualparam.h"
 
+class LLAvatarJointCollisionVolume;
 class LLPolyMeshSharedData;
-class LLVOAvatar;
 class LLVector2;
-class LLViewerJointCollisionVolume;
+class LLAvatarJointCollisionVolume;
 class LLWearable;
 
 //-----------------------------------------------------------------------------
@@ -119,10 +119,10 @@ struct LLPolyVolumeMorphInfo
 
 struct LLPolyVolumeMorph
 {
-	LLPolyVolumeMorph(LLViewerJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos)
+	LLPolyVolumeMorph(LLAvatarJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos)
 		: mVolume(volume), mScale(scale), mPos(pos) {};
 
-	LLViewerJointCollisionVolume*	mVolume;
+	LLAvatarJointCollisionVolume*	mVolume;
 	LLVector3						mScale;
 	LLVector3						mPos;
 };
diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ba16691c28b48ec0318be80537cf76f898cc965
--- /dev/null
+++ b/indra/llappearance/llpolyskeletaldistortion.cpp
@@ -0,0 +1,293 @@
+/** 
+ * @file llpolyskeletaldistortion.cpp
+ * @brief Implementation of LLPolySkeletalDistortion classes
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "llpreprocessor.h"
+#include "llerrorlegacy.h"
+//#include "llcommon.h"
+//#include "llmemory.h"
+#include "llavatarappearance.h"
+#include "llavatarjoint.h"
+#include "llpolymorph.h"
+//#include "llviewercontrol.h"
+//#include "llxmltree.h"
+//#include "llvoavatar.h"
+#include "llwearable.h"
+//#include "lldir.h"
+//#include "llvolume.h"
+//#include "llendianswizzle.h"
+
+#include "llpolyskeletaldistortion.h"
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDistortionInfo()
+//-----------------------------------------------------------------------------
+LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
+{
+}
+
+BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
+{
+        llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
+        
+        if (!LLViewerVisualParamInfo::parseXml(node))
+                return FALSE;
+
+        LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
+
+        if (NULL == skeletalParam)
+        {
+                llwarns << "Failed to getChildByName(\"param_skeleton\")"
+                        << llendl;
+                return FALSE;
+        }
+
+        for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
+        {
+                if (bone->hasName("bone"))
+                {
+                        std::string name;
+                        LLVector3 scale;
+                        LLVector3 pos;
+                        BOOL haspos = FALSE;
+                        
+                        static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+                        if (!bone->getFastAttributeString(name_string, name))
+                        {
+                                llwarns << "No bone name specified for skeletal param." << llendl;
+                                continue;
+                        }
+
+                        static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+                        if (!bone->getFastAttributeVector3(scale_string, scale))
+                        {
+                                llwarns << "No scale specified for bone " << name << "." << llendl;
+                                continue;
+                        }
+
+                        // optional offset deformation (translation)
+                        static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
+                        if (bone->getFastAttributeVector3(offset_string, pos))
+                        {
+                                haspos = TRUE;
+                        }
+                        mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
+                }
+                else
+                {
+                        llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
+                        continue;
+                }
+        }
+        return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDistortion()
+//-----------------------------------------------------------------------------
+LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLAvatarAppearance *avatarp)
+{
+        mAvatar = avatarp;
+        mDefaultVec.splat(0.001f);
+}
+
+//-----------------------------------------------------------------------------
+// ~LLPolySkeletalDistortion()
+//-----------------------------------------------------------------------------
+LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
+{
+}
+
+BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
+{
+        llassert(mInfo == NULL);
+        if (info->mID < 0)
+                return FALSE;
+        mInfo = info;
+        mID = info->mID;
+        setWeight(getDefaultWeight(), FALSE );
+
+        LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
+        for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
+        {
+                LLPolySkeletalBoneInfo *bone_info = &(*iter);
+                LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
+                if (!joint)
+                {
+                        llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
+                        continue;
+                }
+
+                if (mJointScales.find(joint) != mJointScales.end())
+                {
+                        llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
+                }
+
+                // store it
+                mJointScales[joint] = bone_info->mScaleDeformation;
+
+                // apply to children that need to inherit it
+                for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
+                     iter != joint->mChildren.end(); ++iter)
+                {
+                        LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);
+                        if (child_joint->inheritScale())
+                        {
+                                LLVector3 childDeformation = LLVector3(child_joint->getScale());
+                                childDeformation.scaleVec(bone_info->mScaleDeformation);
+                                mJointScales[child_joint] = childDeformation;
+                        }
+                }
+
+                if (bone_info->mHasPositionDeformation)
+                {
+                        if (mJointOffsets.find(joint) != mJointOffsets.end())
+                        {
+                                llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
+                        }
+                        mJointOffsets[joint] = bone_info->mPositionDeformation;
+                }
+        }
+        return TRUE;
+}
+
+/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
+{
+        LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
+        *new_param = *this;
+        return new_param;
+}
+
+//-----------------------------------------------------------------------------
+// apply()
+//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion");
+
+void LLPolySkeletalDistortion::apply( ESex avatar_sex )
+{
+	LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY);
+
+        F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
+
+        LLJoint* joint;
+        joint_vec_map_t::iterator iter;
+
+        for (iter = mJointScales.begin();
+             iter != mJointScales.end();
+             iter++)
+        {
+                joint = iter->first;
+                LLVector3 newScale = joint->getScale();
+                LLVector3 scaleDelta = iter->second;
+                newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
+                joint->setScale(newScale);
+        }
+
+        for (iter = mJointOffsets.begin();
+             iter != mJointOffsets.end();
+             iter++)
+        {
+                joint = iter->first;
+                LLVector3 newPosition = joint->getPosition();
+                LLVector3 positionDelta = iter->second;
+                newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
+                joint->setPosition(newPosition);
+        }
+
+        if (mLastWeight != mCurWeight && !mIsAnimating)
+        {
+                mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
+        }
+        mLastWeight = mCurWeight;
+}
+
+
+LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
+					     const std::string &name)
+{
+        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+        cloned_morph_data->mName = name;
+        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+        {
+                cloned_morph_data->mCoords[v] = src_data->mCoords[v];
+                cloned_morph_data->mNormals[v] = src_data->mNormals[v];
+                cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
+        }
+        return cloned_morph_data;
+}
+
+LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
+					     const LLVector3 &direction,
+					     const std::string &name)
+{
+        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+        cloned_morph_data->mName = name;
+		LLVector4a dir;
+		dir.load3(direction.mV);
+
+        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+        {
+                cloned_morph_data->mCoords[v] = dir;
+                cloned_morph_data->mNormals[v].clear();
+                cloned_morph_data->mBinormals[v].clear();
+        }
+        return cloned_morph_data;
+}
+
+LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
+                                            F32 scale,
+                                            const std::string &name)
+{
+        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+        cloned_morph_data->mName = name;
+
+		LLVector4a sc;
+		sc.splat(scale);
+
+		LLVector4a nsc;
+		nsc.set(scale, -scale, scale, scale);
+
+        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+        {
+            if (cloned_morph_data->mCoords[v][1] < 0)
+            {
+                cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc);
+				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc);
+				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc);
+			}
+			else
+			{
+				cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc);
+				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc);
+				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc);
+			}
+        }
+        return cloned_morph_data;
+}
+
+// End
diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h
new file mode 100644
index 0000000000000000000000000000000000000000..774bc7dfa2a8071ad89ae8c680e4326a17f0c033
--- /dev/null
+++ b/indra/llappearance/llpolyskeletaldistortion.h
@@ -0,0 +1,131 @@
+/** 
+ * @file llpolyskeletaldistortion.h
+ * @brief Implementation of LLPolyMesh class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPOLYSKELETALDISTORTION_H
+#define LL_LLPOLYSKELETALDISTORTION_H
+
+#include "llcommon.h"
+
+#include <string>
+#include <map>
+#include "llstl.h"
+
+#include "v3math.h"
+#include "v2math.h"
+#include "llquaternion.h"
+//#include "llpolymorph.h"
+#include "lljoint.h"
+#include "llviewervisualparam.h"
+//#include "lldarray.h"
+
+//class LLSkinJoint;
+class LLAvatarAppearance;
+
+//#define USE_STRIPS	// Use tri-strips for rendering.
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDeformationInfo
+// Shared information for LLPolySkeletalDeformations
+//-----------------------------------------------------------------------------
+struct LLPolySkeletalBoneInfo
+{
+	LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos)
+		: mBoneName(name),
+		  mScaleDeformation(scale),
+		  mPositionDeformation(pos),
+		  mHasPositionDeformation(haspos) {}
+	std::string mBoneName;
+	LLVector3 mScaleDeformation;
+	LLVector3 mPositionDeformation;
+	BOOL mHasPositionDeformation;
+};
+
+LL_ALIGN_PREFIX(16)
+class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
+{
+	friend class LLPolySkeletalDistortion;
+public:
+	
+	LLPolySkeletalDistortionInfo();
+	/*virtual*/ ~LLPolySkeletalDistortionInfo() {};
+	
+	/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
+
+protected:
+	typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
+	bone_info_list_t mBoneInfoList;
+};
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDeformation
+// A set of joint scale data for deforming the avatar mesh
+//-----------------------------------------------------------------------------
+class LLPolySkeletalDistortion : public LLViewerVisualParam
+{
+public:
+	void* operator new(size_t size)
+	{
+		return ll_aligned_malloc_16(size);
+	}
+
+	void operator delete(void* ptr)
+	{
+		ll_aligned_free_16(ptr);
+	}
+
+	LLPolySkeletalDistortion(LLAvatarAppearance *avatarp);
+	~LLPolySkeletalDistortion();
+
+	// Special: These functions are overridden by child classes
+	LLPolySkeletalDistortionInfo*	getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; }
+	//   This sets mInfo and calls initialization functions
+	BOOL							setInfo(LLPolySkeletalDistortionInfo *info);
+
+	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
+
+	// LLVisualParam Virtual functions
+	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node);
+	/*virtual*/ void				apply( ESex sex );
+	
+	// LLViewerVisualParam Virtual functions
+	/*virtual*/ F32					getTotalDistortion() { return 0.1f; }
+	/*virtual*/ const LLVector4a&	getAvgDistortion()	{ return mDefaultVec; }
+	/*virtual*/ F32					getMaxDistortion() { return 0.1f; }
+	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);}
+	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
+	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
+
+protected:
+	LL_ALIGN_16(LLVector4a mDefaultVec);
+	typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
+	joint_vec_map_t mJointScales;
+	joint_vec_map_t mJointOffsets;
+	// Backlink only; don't make this an LLPointer.
+	LLAvatarAppearance *mAvatar;
+} LL_ALIGN_POSTFIX(16);
+
+#endif // LL_LLPOLYSKELETALDISTORTION_H
+
diff --git a/indra/newview/lltexglobalcolor.cpp b/indra/llappearance/lltexglobalcolor.cpp
similarity index 92%
rename from indra/newview/lltexglobalcolor.cpp
rename to indra/llappearance/lltexglobalcolor.cpp
index ebe5ccd6c05149d2099b866a9c7af666f749236a..f38b98210422667fcf93b373670e2bfe2ecebdd4 100644
--- a/indra/newview/lltexglobalcolor.cpp
+++ b/indra/llappearance/lltexglobalcolor.cpp
@@ -24,20 +24,20 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
-#include "llagent.h"
+#include "linden_common.h"
+#include "llavatarappearance.h"
 #include "lltexlayer.h"
-#include "llvoavatar.h"
-#include "llwearable.h"
 #include "lltexglobalcolor.h"
 
+class LLWearable;
+
 //-----------------------------------------------------------------------------
 // LLTexGlobalColor
 //-----------------------------------------------------------------------------
 
-LLTexGlobalColor::LLTexGlobalColor(LLVOAvatar* avatar) 
+LLTexGlobalColor::LLTexGlobalColor(LLAvatarAppearance* appearance)
 	:
-	mAvatar(avatar),
+	mAvatarAppearance(appearance),
 	mInfo(NULL)
 {
 }
@@ -91,7 +91,7 @@ const std::string& LLTexGlobalColor::getName() const
 // LLTexParamGlobalColor
 //-----------------------------------------------------------------------------
 LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) :
-	LLTexLayerParamColor(tex_global_color->getAvatar()),
+	LLTexLayerParamColor(tex_global_color->getAvatarAppearance()),
 	mTexGlobalColor(tex_global_color)
 {
 }
@@ -105,7 +105,7 @@ LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color)
 
 void LLTexParamGlobalColor::onGlobalColorChanged(bool upload_bake)
 {
-	mAvatar->onGlobalColorChanged(mTexGlobalColor, upload_bake);
+	mAvatarAppearance->onGlobalColorChanged(mTexGlobalColor, upload_bake);
 }
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/lltexglobalcolor.h b/indra/llappearance/lltexglobalcolor.h
similarity index 84%
rename from indra/newview/lltexglobalcolor.h
rename to indra/llappearance/lltexglobalcolor.h
index ae0479844528ec46dc8ef74804df8494de737a7b..2867479876d72f9c434132bca2821bd1a3b3429a 100644
--- a/indra/newview/lltexglobalcolor.h
+++ b/indra/llappearance/lltexglobalcolor.h
@@ -1,6 +1,6 @@
 /** 
  * @file lltexglobalcolor.h
- * @brief This is global texture color info used by llvoavatar.
+ * @brief This is global texture color info used by llavatarappearance.
  *
  * $LicenseInfo:firstyear=2008&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -30,31 +30,31 @@
 #include "lltexlayer.h"
 #include "lltexlayerparams.h"
 
-class LLVOAvatar;
+class LLAvatarAppearance;
 class LLWearable;
 class LLTexGlobalColorInfo;
 
 class LLTexGlobalColor
 {
 public:
-	LLTexGlobalColor( LLVOAvatar* avatar );
+	LLTexGlobalColor( LLAvatarAppearance* appearance );
 	~LLTexGlobalColor();
 
 	LLTexGlobalColorInfo*	getInfo() const { return mInfo; }
 	//   This sets mInfo and calls initialization functions
 	BOOL					setInfo(LLTexGlobalColorInfo *info);
 	
-	LLVOAvatar*				getAvatar()	const			   	{ return mAvatar; }
+	LLAvatarAppearance*		getAvatarAppearance()	const	   	{ return mAvatarAppearance; }
 	LLColor4				getColor() const;
 	const std::string&		getName() const;
 
 private:
 	param_color_list_t		mParamGlobalColorList;
-	LLVOAvatar*				mAvatar;  // just backlink, don't LLPointer 
+	LLAvatarAppearance*		mAvatarAppearance;  // just backlink, don't LLPointer 
 	LLTexGlobalColorInfo	*mInfo;
 };
 
-// Used by llvoavatar to determine skin/eye/hair color.
+// Used by llavatarappearance to determine skin/eye/hair color.
 class LLTexGlobalColorInfo
 {
 	friend class LLTexGlobalColor;
diff --git a/indra/newview/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
similarity index 64%
rename from indra/newview/lltexlayer.cpp
rename to indra/llappearance/lltexlayer.cpp
index ad09af6594e7a7fdefa92f353197e921c4729d89..f951a982e5b5c5ec190e3f0651eb4ab74eb37249 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -24,36 +24,29 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 
 #include "lltexlayer.h"
 
-#include "llagent.h"
+#include "llavatarappearance.h"
+#include "llcrc.h"
+#include "imageids.h"
 #include "llimagej2c.h"
 #include "llimagetga.h"
-#include "llnotificationsutil.h"
+#include "lldir.h"
 #include "llvfile.h"
 #include "llvfs.h"
-#include "llviewerstats.h"
-#include "llviewerregion.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "pipeline.h"
-#include "llassetuploadresponders.h"
 #include "lltexlayerparams.h"
-#include "llui.h"
-#include "llagentwearables.h"
+#include "lltexturemanagerbridge.h"
+#include "../llui/llui.h"
 #include "llwearable.h"
-#include "llviewercontrol.h"
-#include "llviewershadermgr.h"
+#include "llwearabledata.h"
+#include "llvertexbuffer.h"
 #include "llviewervisualparam.h"
 
 //#include "../tools/imdebug/imdebug.h"
 
-using namespace LLVOAvatarDefines;
-
-static const S32 BAKE_UPLOAD_ATTEMPTS = 7;
-static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt
+using namespace LLAvatarAppearanceDefines;
 
 // runway consolidate
 extern std::string self_av_string();
@@ -68,7 +61,7 @@ class LLTexLayerInfo
 	~LLTexLayerInfo();
 
 	BOOL parseXml(LLXmlTreeNode* node);
-	BOOL createVisualParams(LLVOAvatar *avatar);
+	BOOL createVisualParams(LLAvatarAppearance *appearance);
 	BOOL isUserSettable() { return mLocalTexture != -1;	}
 	S32  getLocalTexture() const { return mLocalTexture; }
 	BOOL getOnlyAlpha() const { return mUseLocalTextureAlphaOnly; }
@@ -95,126 +88,18 @@ class LLTexLayerInfo
 	param_alpha_info_list_t		mParamAlphaInfoList;
 };
 
-//-----------------------------------------------------------------------------
-// LLBakedUploadData()
-//-----------------------------------------------------------------------------
-LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar,
-									 LLTexLayerSet* layerset,
-									 const LLUUID& id,
-									 bool highest_res) :
-	mAvatar(avatar),
-	mTexLayerSet(layerset),
-	mID(id),
-	mStartTime(LLFrameTimer::getTotalTime()),		// Record starting time
-	mIsHighestRes(highest_res)
-{ 
-}
-
 //-----------------------------------------------------------------------------
 // LLTexLayerSetBuffer
-// The composite image that a LLTexLayerSet writes to.  Each LLTexLayerSet has one.
+// The composite image that a LLViewerTexLayerSet writes to.  Each LLViewerTexLayerSet has one.
 //-----------------------------------------------------------------------------
 
-// static
-S32 LLTexLayerSetBuffer::sGLByteCount = 0;
-
-LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner, 
-										 S32 width, S32 height) :
-	// ORDER_LAST => must render these after the hints are created.
-	LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), 
-	mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
-	mNeedsUpload(FALSE),
-	mNumLowresUploads(0),
-	mUploadFailCount(0),
-	mNeedsUpdate(TRUE),
-	mNumLowresUpdates(0),
+LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner) :
 	mTexLayerSet(owner)
 {
-	LLTexLayerSetBuffer::sGLByteCount += getSize();
-	mNeedsUploadTimer.start();
-	mNeedsUpdateTimer.start();
 }
 
 LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
 {
-	LLTexLayerSetBuffer::sGLByteCount -= getSize();
-	destroyGLTexture();
-	for( S32 order = 0; order < ORDER_COUNT; order++ )
-	{
-		LLViewerDynamicTexture::sInstances[order].erase(this);  // will fail in all but one case.
-	}
-}
-
-//virtual 
-S8 LLTexLayerSetBuffer::getType() const 
-{
-	return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ;
-}
-
-//virtual 
-void LLTexLayerSetBuffer::restoreGLTexture() 
-{	
-	LLViewerDynamicTexture::restoreGLTexture() ;
-}
-
-//virtual 
-void LLTexLayerSetBuffer::destroyGLTexture() 
-{
-	LLViewerDynamicTexture::destroyGLTexture() ;
-}
-
-// static
-void LLTexLayerSetBuffer::dumpTotalByteCount()
-{
-	llinfos << "Composite System GL Buffers: " << (LLTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl;
-}
-
-void LLTexLayerSetBuffer::requestUpdate()
-{
-	restartUpdateTimer();
-	mNeedsUpdate = TRUE;
-	mNumLowresUpdates = 0;
-	// If we're in the middle of uploading a baked texture, we don't care about it any more.
-	// When it's downloaded, ignore it.
-	mUploadID.setNull();
-}
-
-void LLTexLayerSetBuffer::requestUpload()
-{
-	conditionalRestartUploadTimer();
-	mNeedsUpload = TRUE;
-	mNumLowresUploads = 0;
-	mUploadPending = TRUE;
-}
-
-void LLTexLayerSetBuffer::conditionalRestartUploadTimer()
-{
-	// If we requested a new upload but haven't even uploaded
-	// a low res version of our last upload request, then
-	// keep the timer ticking instead of resetting it.
-	if (mNeedsUpload && (mNumLowresUploads == 0))
-	{
-		mNeedsUploadTimer.unpause();
-	}
-	else
-	{
-		mNeedsUploadTimer.reset();
-		mNeedsUploadTimer.start();
-	}
-}
-
-void LLTexLayerSetBuffer::restartUpdateTimer()
-{
-	mNeedsUpdateTimer.reset();
-	mNeedsUpdateTimer.start();
-}
-
-void LLTexLayerSetBuffer::cancelUpload()
-{
-	mNeedsUpload = FALSE;
-	mUploadPending = FALSE;
-	mNeedsUploadTimer.pause();
-	mUploadRetryTimer.reset();
 }
 
 void LLTexLayerSetBuffer::pushProjection() const
@@ -222,7 +107,7 @@ void LLTexLayerSetBuffer::pushProjection() const
 	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.pushMatrix();
 	gGL.loadIdentity();
-	gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
+	gGL.ortho(0.0f, getCompositeWidth(), 0.0f, getCompositeHeight(), -1.0f, 1.0f);
 
 	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
@@ -238,64 +123,24 @@ void LLTexLayerSetBuffer::popProjection() const
 	gGL.popMatrix();
 }
 
-BOOL LLTexLayerSetBuffer::needsRender()
-{
-	llassert(mTexLayerSet->getAvatar() == gAgentAvatarp);
-	if (!isAgentAvatarValid()) return FALSE;
-
-	const BOOL upload_now = mNeedsUpload && isReadyToUpload();
-	const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
-
-	// Don't render if we don't want to (or aren't ready to) upload or update.
-	if (!(update_now || upload_now))
-	{
-		return FALSE;
-	}
-
-	// Don't render if we're animating our appearance.
-	if (gAgentAvatarp->getIsAppearanceAnimating())
-	{
-		return FALSE;
-	}
-
-	// Don't render if we are trying to create a shirt texture but aren't wearing a skirt.
-	if (gAgentAvatarp->getBakedTE(mTexLayerSet) == LLVOAvatarDefines::TEX_SKIRT_BAKED && 
-		!gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
-	{
-		cancelUpload();
-		return FALSE;
-	}
-
-	// Render if we have at least minimal level of detail for each local texture.
-	return mTexLayerSet->isLocalTextureDataAvailable();
-}
-
-void LLTexLayerSetBuffer::preRender(BOOL clear_depth)
+// virtual
+void LLTexLayerSetBuffer::preRenderTexLayerSet()
 {
 	// Set up an ortho projection
 	pushProjection();
-	
-	// keep depth buffer, we don't need to clear it
-	LLViewerDynamicTexture::preRender(FALSE);
 }
 
-void LLTexLayerSetBuffer::postRender(BOOL success)
+// virtual
+void LLTexLayerSetBuffer::postRenderTexLayerSet(BOOL success)
 {
 	popProjection();
-
-	LLViewerDynamicTexture::postRender(success);
 }
 
-BOOL LLTexLayerSetBuffer::render()
+BOOL LLTexLayerSetBuffer::renderTexLayerSet()
 {
 	// Default color mask for tex layer render
 	gGL.setColorMask(true, true);
 
-	// do we need to upload, and do we have sufficient data to create an uploadable composite?
-	// TODO: When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
-	const BOOL upload_now = mNeedsUpload && isReadyToUpload();
-	const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
-	
 	BOOL success = TRUE;
 	
 	bool use_shaders = LLGLSLShader::sNoFixedFunction;
@@ -305,42 +150,20 @@ BOOL LLTexLayerSetBuffer::render()
 		gAlphaMaskProgram.bind();
 		gAlphaMaskProgram.setMinimumAlpha(0.004f);
 	}
+	else
+	{
+		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.00f);
+	}
 
 	LLVertexBuffer::unbind();
 
 	// Composite the color data
 	LLGLSUIDefault gls_ui;
-	success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight );
+	success &= mTexLayerSet->render( getCompositeOriginX(), getCompositeOriginY(), 
+									 getCompositeWidth(), getCompositeHeight() );
 	gGL.flush();
 
-	if(upload_now)
-	{
-		if (!success)
-		{
-			llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegionName() << llendl;
-			mUploadPending = FALSE;
-		}
-		else
-		{
-			if (mTexLayerSet->isVisible())
-			{
-				mTexLayerSet->getAvatar()->debugBakedTextureUpload(mTexLayerSet->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish.
-				doUpload();
-			}
-			else
-			{
-				mUploadPending = FALSE;
-				mNeedsUpload = FALSE;
-				mNeedsUploadTimer.pause();
-				mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getBakedTexIndex(),IMG_INVISIBLE);
-			}
-		}
-	}
-	
-	if (update_now)
-	{
-		doUpdate();
-	}
+	midRenderTexLayerSet(success);
 
 	if (use_shaders)
 	{
@@ -353,374 +176,11 @@ BOOL LLTexLayerSetBuffer::render()
 	gGL.setColorMask(true, true);
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
-	// we have valid texture data now
-	mGLTexturep->setGLTextureCreated(true);
-
 	return success;
 }
 
-BOOL LLTexLayerSetBuffer::isInitialized(void) const
-{
-	return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
-}
-
-BOOL LLTexLayerSetBuffer::uploadPending() const
-{
-	return mUploadPending;
-}
-
-BOOL LLTexLayerSetBuffer::uploadNeeded() const
-{
-	return mNeedsUpload;
-}
-
-BOOL LLTexLayerSetBuffer::uploadInProgress() const
-{
-	return !mUploadID.isNull();
-}
-
-BOOL LLTexLayerSetBuffer::isReadyToUpload() const
-{
-	if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries.
-	if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) return FALSE; // Don't upload if avatar is using composites.
-
-	BOOL ready = FALSE;
-	if (mTexLayerSet->isLocalTextureDataFinal())
-	{
-		// If we requested an upload and have the final LOD ready, upload (or wait a while if this is a retry)
-		if (mUploadFailCount == 0)
-		{
-			ready = TRUE;
-		}
-		else
-		{
-			ready = mUploadRetryTimer.getElapsedTimeF32() >= BAKE_UPLOAD_RETRY_DELAY * (1 << (mUploadFailCount - 1));
-		}
-	}
-	else
-	{
-		// Upload if we've hit a timeout.  Upload is a pretty expensive process so we need to make sure
-		// we aren't doing uploads too frequently.
-		const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout");
-		if (texture_timeout != 0)
-		{
-			// The timeout period increases exponentially between every lowres upload in order to prevent
-			// spamming the server with frequent uploads.
-			const U32 texture_timeout_threshold = texture_timeout*(1 << mNumLowresUploads);
-
-			// If we hit our timeout and have textures available at even lower resolution, then upload.
-			const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout_threshold;
-			const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
-			ready = has_lower_lod && is_upload_textures_timeout;
-		}
-	}
-
-	return ready;
-}
-
-BOOL LLTexLayerSetBuffer::isReadyToUpdate() const
-{
-	// If we requested an update and have the final LOD ready, then update.
-	if (mTexLayerSet->isLocalTextureDataFinal()) return TRUE;
-
-	// If we haven't done an update yet, then just do one now regardless of state of textures.
-	if (mNumLowresUpdates == 0) return TRUE;
-
-	// Update if we've hit a timeout.  Unlike for uploads, we can make this timeout fairly small
-	// since render unnecessarily doesn't cost much.
-	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout");
-	if (texture_timeout != 0)
-	{
-		// If we hit our timeout and have textures available at even lower resolution, then update.
-		const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout;
-		const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
-		if (has_lower_lod && is_update_textures_timeout) return TRUE; 
-	}
-
-	return FALSE;
-}
-
-BOOL LLTexLayerSetBuffer::requestUpdateImmediate()
-{
-	mNeedsUpdate = TRUE;
-	BOOL result = FALSE;
-
-	if (needsRender())
-	{
-		preRender(FALSE);
-		result = render();
-		postRender(result);
-	}
-
-	return result;
-}
-
-// Create the baked texture, send it out to the server, then wait for it to come
-// back so we can switch to using it.
-void LLTexLayerSetBuffer::doUpload()
-{
-	llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl;
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
-
-	// Don't need caches since we're baked now.  (note: we won't *really* be baked 
-	// until this image is sent to the server and the Avatar Appearance message is received.)
-	mTexLayerSet->deleteCaches();
-
-	// Get the COLOR information from our texture
-	U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ];
-	glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
-	stop_glerror();
-
-	// Get the MASK information from our texture
-	LLGLSUIDefault gls_ui;
-	LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 );
-	U8* baked_mask_data = baked_mask_image->getData(); 
-	mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mFullWidth, mFullHeight);
-
-
-	// Create the baked image from our color and mask information
-	const S32 baked_image_components = 5; // red green blue [bump] clothing
-	LLPointer<LLImageRaw> baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components );
-	U8* baked_image_data = baked_image->getData();
-	S32 i = 0;
-	for (S32 u=0; u < mFullWidth; u++)
-	{
-		for (S32 v=0; v < mFullHeight; v++)
-		{
-			baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
-			baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
-			baked_image_data[5*i + 2] = baked_color_data[4*i + 2];
-			baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes.
-			baked_image_data[5*i + 4] = baked_mask_data[i];
-			i++;
-		}
-	}
-	
-	LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C;
-	const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)
-	if (compressedImage->encode(baked_image, comment_text))
-	{
-		LLTransactionID tid;
-		tid.generate();
-		const LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-		if (LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(),
-							   gVFS, asset_id, LLAssetType::AT_TEXTURE))
-		{
-			// Read back the file and validate.
-			BOOL valid = FALSE;
-			LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
-			S32 file_size = 0;
-			
-			//data buffer MUST be allocated using LLImageBase
-			LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE);
-			file_size = file.getSize();
-			U8* data = integrity_test->allocateData(file_size);
-			file.read(data, file_size);
-			
-			if (data)
-			{
-				valid = integrity_test->validate(data, file_size); // integrity_test will delete 'data'
-			}
-			else
-			{
-				integrity_test->setLastError("Unable to read entire file");
-			}
-			
-			if (valid)
-			{
-				const bool highest_lod = mTexLayerSet->isLocalTextureDataFinal();
-				// Baked_upload_data is owned by the responder and deleted after the request completes.
-				LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, 
-																			 this->mTexLayerSet, 
-																			 asset_id,
-																			 highest_lod);
-				// upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.
-				mUploadID = asset_id;
-
-				// Upload the image
-				const std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture");
-				if(!url.empty()
-					&& !LLPipeline::sForceOldBakedUpload // toggle debug setting UploadBakedTexOld to change between the new caps method and old method
-					&& (mUploadFailCount < (BAKE_UPLOAD_ATTEMPTS - 1))) // Try last ditch attempt via asset store if cap upload is failing.
-				{
-					LLSD body = LLSD::emptyMap();
-					// The responder will call LLTexLayerSetBuffer::onTextureUploadComplete()
-					LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data));
-					llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl;
-				} 
-				else
-				{
-					gAssetStorage->storeAssetData(tid,
-												  LLAssetType::AT_TEXTURE,
-												  LLTexLayerSetBuffer::onTextureUploadComplete,
-												  baked_upload_data,
-												  TRUE,		// temp_file
-												  TRUE,		// is_priority
-												  TRUE);	// store_local
-					llinfos << "Baked texture upload via Asset Store." <<  llendl;
-				}
-
-				if (highest_lod)
-				{
-					// Sending the final LOD for the baked texture.  All done, pause 
-					// the upload timer so we know how long it took.
-					mNeedsUpload = FALSE;
-					mNeedsUploadTimer.pause();
-				}
-				else
-				{
-					// Sending a lower level LOD for the baked texture.  Restart the upload timer.
-					mNumLowresUploads++;
-					mNeedsUploadTimer.unpause();
-					mNeedsUploadTimer.reset();
-				}
-
-				// Print out notification that we uploaded this texture.
-				if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
-				{
-					const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
-					LLSD args;
-					args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());
-					args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32());
-					args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
-					args["RESOLUTION"] = lod_str;
-					LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args);
-					LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
-				}
-			}
-			else
-			{
-				// The read back and validate operation failed.  Remove the uploaded file.
-				mUploadPending = FALSE;
-				LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE, LLVFile::WRITE);
-				file.remove();
-				llinfos << "Unable to create baked upload file (reason: corrupted)." << llendl;
-			}
-		}
-	}
-	else
-	{
-		// The VFS write file operation failed.
-		mUploadPending = FALSE;
-		llinfos << "Unable to create baked upload file (reason: failed to write file)" << llendl;
-	}
-
-	delete [] baked_color_data;
-}
-
-// Mostly bookkeeping; don't need to actually "do" anything since
-// render() will actually do the update.
-void LLTexLayerSetBuffer::doUpdate()
-{
-	const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
-	if (highest_lod)
-	{
-		mNeedsUpdate = FALSE;
-	}
-	else
-	{
-		mNumLowresUpdates++;
-	}
-
-	restartUpdateTimer();
-
-	// need to swtich to using this layerset if this is the first update
-	// after getting the lowest LOD
-	mTexLayerSet->getAvatar()->updateMeshTextures();
-	
-	// Print out notification that we uploaded this texture.
-	if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
-	{
-		const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
-		const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
-		LLSD args;
-		args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());
-		args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32());
-		args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
-		args["RESOLUTION"] = lod_str;
-		LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args);
-		LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
-	}
-}
-
-// static
-void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
-												  void* userdata,
-												  S32 result,
-												  LLExtStat ext_status) // StoreAssetData callback (not fixed)
-{
-	LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata;
-
-	if (isAgentAvatarValid() &&
-		!gAgentAvatarp->isDead() &&
-		(baked_upload_data->mAvatar == gAgentAvatarp) && // Sanity check: only the user's avatar should be uploading textures.
-		(baked_upload_data->mTexLayerSet->hasComposite()))
-	{
-		LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getComposite();
-		S32 failures = layerset_buffer->mUploadFailCount;
-		layerset_buffer->mUploadFailCount = 0;
-
-		if (layerset_buffer->mUploadID.isNull())
-		{
-			// The upload got canceled, we should be in the
-			// process of baking a new texture so request an
-			// upload with the new data
-
-			// BAP: does this really belong in this callback, as
-			// opposed to where the cancellation takes place?
-			// suspect this does nothing.
-			layerset_buffer->requestUpload();
-		}
-		else if (baked_upload_data->mID == layerset_buffer->mUploadID)
-		{
-			// This is the upload we're currently waiting for.
-			layerset_buffer->mUploadID.setNull();
-			const std::string name(baked_upload_data->mTexLayerSet->getBodyRegionName());
-			const std::string resolution = baked_upload_data->mIsHighestRes ? " full res " : " low res ";
-			if (result >= 0)
-			{
-				layerset_buffer->mUploadPending = FALSE; // Allows sending of AgentSetAppearance later
-				LLVOAvatarDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->mTexLayerSet);
-				// Update baked texture info with the new UUID
-				U64 now = LLFrameTimer::getTotalTime();		// Record starting time
-				llinfos << "Baked" << resolution << "texture upload for " << name << " took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl;
-				gAgentAvatarp->setNewBakedTexture(baked_te, uuid);
-			}
-			else
-			{	
-				++failures;
-				S32 max_attempts = baked_upload_data->mIsHighestRes ? BAKE_UPLOAD_ATTEMPTS : 1; // only retry final bakes
-				llwarns << "Baked" << resolution << "texture upload for " << name << " failed (attempt " << failures << "/" << max_attempts << ")" << llendl;
-				if (failures < max_attempts)
-				{
-					layerset_buffer->mUploadFailCount = failures;
-					layerset_buffer->mUploadRetryTimer.start();
-					layerset_buffer->requestUpload();
-				}
-			}
-		}
-		else
-		{
-			llinfos << "Received baked texture out of date, ignored." << llendl;
-		}
-
-		gAgentAvatarp->dirtyMesh();
-	}
-	else
-	{
-		// Baked texture failed to upload (in which case since we
-		// didn't set the new baked texture, it means that they'll try
-		// and rebake it at some point in the future (after login?)),
-		// or this response to upload is out of date, in which case a
-		// current response should be on the way or already processed.
-		llwarns << "Baked upload failed" << llendl;
-	}
-
-	delete baked_upload_data;
-}
-
 //-----------------------------------------------------------------------------
-// LLTexLayerSet
+// LLTexLayerSetInfo
 // An ordered set of texture layers that get composited into a single texture.
 //-----------------------------------------------------------------------------
 
@@ -790,7 +250,7 @@ BOOL LLTexLayerSetInfo::parseXml(LLXmlTreeNode* node)
 }
 
 // creates visual params without generating layersets or layers
-void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar)
+void LLTexLayerSetInfo::createVisualParams(LLAvatarAppearance *appearance)
 {
 	//layer_info_list_t		mLayerInfoList;
 	for (layer_info_list_t::iterator layer_iter = mLayerInfoList.begin();
@@ -798,7 +258,7 @@ void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar)
 		 layer_iter++)
 	{
 		LLTexLayerInfo *layer_info = *layer_iter;
-		layer_info->createVisualParams(avatar);
+		layer_info->createVisualParams(appearance);
 	}
 }
 
@@ -809,16 +269,15 @@ void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar)
 
 BOOL LLTexLayerSet::sHasCaches = FALSE;
 
-LLTexLayerSet::LLTexLayerSet(LLVOAvatarSelf* const avatar) :
-	mComposite( NULL ),
-	mAvatar( avatar ),
-	mUpdatesEnabled( FALSE ),
+LLTexLayerSet::LLTexLayerSet(LLAvatarAppearance* const appearance) :
+	mAvatarAppearance( appearance ),
 	mIsVisible( TRUE ),
-	mBakedTexIndex(LLVOAvatarDefines::BAKED_HEAD),
+	mBakedTexIndex(LLAvatarAppearanceDefines::BAKED_HEAD),
 	mInfo( NULL )
 {
 }
 
+// virtual
 LLTexLayerSet::~LLTexLayerSet()
 {
 	deleteCaches();
@@ -844,13 +303,13 @@ BOOL LLTexLayerSet::setInfo(const LLTexLayerSetInfo *info)
 		LLTexLayerInterface *layer = NULL;
 		if ( (*iter)->isUserSettable() )
 		{
-			layer = new LLTexLayerTemplate( this );
+			layer = new LLTexLayerTemplate( this, getAvatarAppearance() );
 		}
 		else
 		{
 			layer = new LLTexLayer(this);
 		}
-		// this is the first time this layer (of either type) is being created - make sure you add the parameters to the avatar
+		// this is the first time this layer (of either type) is being created - make sure you add the parameters to the avatar appearance
 		if (!layer->setInfo(*iter, NULL))
 		{
 			mInfo = NULL;
@@ -910,21 +369,6 @@ void LLTexLayerSet::deleteCaches()
 	}
 }
 
-// Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on.
-BOOL LLTexLayerSet::isLocalTextureDataAvailable() const
-{
-	if (!mAvatar->isSelf()) return FALSE;
-	return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataAvailable(this);
-}
-
-
-// Returns TRUE if all of the data for the textures that this layerset depends on have arrived.
-BOOL LLTexLayerSet::isLocalTextureDataFinal() const
-{
-	if (!mAvatar->isSelf()) return FALSE;
-	return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataFinal(this);
-}
-
 
 BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
 {
@@ -1025,43 +469,31 @@ const std::string LLTexLayerSet::getBodyRegionName() const
 	return mInfo->mBodyRegion; 
 }
 
-void LLTexLayerSet::requestUpdate()
-{
-	if( mUpdatesEnabled )
-	{
-		createComposite();
-		mComposite->requestUpdate(); 
-	}
-}
-
-void LLTexLayerSet::requestUpload()
-{
-	createComposite();
-	mComposite->requestUpload();
-}
 
-void LLTexLayerSet::cancelUpload()
+// virtual
+void LLTexLayerSet::asLLSD(LLSD& sd) const
 {
-	if(mComposite)
+	sd["visible"] = LLSD::Boolean(isVisible());
+	LLSD layer_list_sd;
+	layer_list_t::const_iterator layer_iter = mLayerList.begin();
+	layer_list_t::const_iterator layer_end  = mLayerList.end();
+	for(; layer_iter != layer_end; ++layer_iter);
 	{
-		mComposite->cancelUpload();
+		LLSD layer_sd;
+		//LLTexLayerInterface* layer = (*layer_iter);
+		//if (layer)
+		//{
+		//	layer->asLLSD(layer_sd);
+		//}
+		layer_list_sd.append(layer_sd);
 	}
+	LLSD mask_list_sd;
+	LLSD info_sd;
+	sd["layers"] = layer_list_sd;
+	sd["masks"] = mask_list_sd;
+	sd["info"] = info_sd;
 }
 
-void LLTexLayerSet::createComposite()
-{
-	if(!mComposite)
-	{
-		S32 width = mInfo->mWidth;
-		S32 height = mInfo->mHeight;
-		// Composite other avatars at reduced resolution
-		if( !mAvatar->isSelf() )
-		{
-			llerrs << "composites should not be created for non-self avatars!" << llendl;
-		}
-		mComposite = new LLTexLayerSetBuffer( this, width, height );
-	}
-}
 
 void LLTexLayerSet::destroyComposite()
 {
@@ -1071,18 +503,6 @@ void LLTexLayerSet::destroyComposite()
 	}
 }
 
-void LLTexLayerSet::setUpdatesEnabled( BOOL b )
-{
-	mUpdatesEnabled = b; 
-}
-
-
-void LLTexLayerSet::updateComposite()
-{
-	createComposite();
-	mComposite->requestUpdateImmediate();
-}
-
 LLTexLayerSetBuffer* LLTexLayerSet::getComposite()
 {
 	if (!mComposite)
@@ -1097,22 +517,26 @@ const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const
 	return mComposite;
 }
 
-void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 width, S32 height)
+static LLFastTimer::DeclareTimer FTM_GATHER_MORPH_MASK_ALPHA("gatherMorphMaskAlpha");
+void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height)
 {
+	LLFastTimer t(FTM_GATHER_MORPH_MASK_ALPHA);
 	memset(data, 255, width * height);
 
 	for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
 	{
 		LLTexLayerInterface* layer = *iter;
-		layer->gatherAlphaMasks(data, mComposite->getOriginX(),mComposite->getOriginY(), width, height);
+		layer->gatherAlphaMasks(data, origin_x, origin_y, width, height);
 	}
 	
 	// Set alpha back to that of our alpha masks.
-	renderAlphaMaskTextures(mComposite->getOriginX(), mComposite->getOriginY(), width, height, true);
+	renderAlphaMaskTextures(origin_x, origin_y, width, height, true);
 }
 
+static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK_TEXTURES("renderAlphaMaskTextures");
 void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear)
 {
+	LLFastTimer t(FTM_RENDER_ALPHA_MASK_TEXTURES);
 	const LLTexLayerSetInfo *info = getInfo();
 	
 	bool use_shaders = LLGLSLShader::sNoFixedFunction;
@@ -1125,7 +549,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
 	{
 		gGL.flush();
 		{
-			LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE);
+			LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE);
 			if( tex )
 			{
 				LLGLSUIDefault gls_ui;
@@ -1182,7 +606,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
 
 void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components)
 {
-	mAvatar->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex);
+	mAvatarAppearance->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex);
 }
 
 BOOL LLTexLayerSet::isMorphValid() const
@@ -1297,11 +721,11 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
 			/* if ("upper_shirt" == local_texture_name)
 				mLocalTexture = TEX_UPPER_SHIRT; */
 			mLocalTexture = TEX_NUM_INDICES;
-			for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-				 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+			for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+				 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 				 iter++)
 			{
-				const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+				const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 				if (local_texture_name == texture_dict->mName)
 			{
 					mLocalTexture = iter->first;
@@ -1368,7 +792,7 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
 	return TRUE;
 }
 
-BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar)
+BOOL LLTexLayerInfo::createVisualParams(LLAvatarAppearance *appearance)
 {
 	BOOL success = TRUE;
 	for (param_color_info_list_t::iterator color_info_iter = mParamColorInfoList.begin();
@@ -1376,7 +800,7 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar)
 		 color_info_iter++)
 	{
 		LLTexLayerParamColorInfo * color_info = *color_info_iter;
-		LLTexLayerParamColor* param_color = new LLTexLayerParamColor(avatar);
+		LLTexLayerParamColor* param_color = new LLTexLayerParamColor(appearance);
 		if (!param_color->setInfo(color_info, TRUE))
 		{
 			llwarns << "NULL TexLayer Color Param could not be added to visual param list. Deleting." << llendl;
@@ -1390,7 +814,7 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar)
 		 alpha_info_iter++)
 	{
 		LLTexLayerParamAlphaInfo * alpha_info = *alpha_info_iter;
-		LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha(avatar);
+		LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha(appearance);
 		if (!param_alpha->setInfo(alpha_info, TRUE))
 		{
 			llwarns << "NULL TexLayer Alpha Param could not be added to visual param list. Deleting." << llendl;
@@ -1498,6 +922,59 @@ const std::string& LLTexLayerInterface::getName() const
 	return mInfo->mName; 
 }
 
+ETextureIndex LLTexLayerInterface::getLocalTextureIndex() const
+{
+	return (ETextureIndex) mInfo->mLocalTexture;
+}
+
+LLWearableType::EType LLTexLayerInterface::getWearableType() const
+{
+	ETextureIndex te = getLocalTextureIndex();
+	if (TEX_INVALID == te)
+	{
+		LLWearableType::EType type = LLWearableType::WT_INVALID;
+		param_color_list_t::const_iterator color_iter = mParamColorList.begin();
+		param_alpha_list_t::const_iterator alpha_iter = mParamAlphaList.begin();
+
+		for (; color_iter != mParamColorList.end(); color_iter++)
+		{
+			LLTexLayerParamColor* param = *color_iter;
+			if (param) 
+			{
+				LLWearableType::EType new_type = (LLWearableType::EType)param->getWearableType();
+				if (new_type != LLWearableType::WT_INVALID && new_type != type) 
+				{
+					if (type != LLWearableType::WT_INVALID) 
+					{
+						return LLWearableType::WT_INVALID;
+					}
+					type = new_type;
+				}
+			}
+		}
+
+		for (; alpha_iter != mParamAlphaList.end(); alpha_iter++)
+		{
+			LLTexLayerParamAlpha* param = *alpha_iter;
+			if (param) 
+			{
+				LLWearableType::EType new_type = (LLWearableType::EType)param->getWearableType();
+				if (new_type != LLWearableType::WT_INVALID && new_type != type) 
+				{
+					if (type != LLWearableType::WT_INVALID) 
+					{
+						return LLWearableType::WT_INVALID;
+					}
+					type = new_type;
+				}
+			}
+		}
+
+		return type;
+	}
+	return LLAvatarAppearanceDictionary::getTEWearableType(te);
+}
+
 LLTexLayerInterface::ERenderPass LLTexLayerInterface::getRenderPass() const
 {
 	return mInfo->mRenderPass; 
@@ -1586,6 +1063,12 @@ LLTexLayer::~LLTexLayer()
 
 }
 
+void LLTexLayer::asLLSD(LLSD& sd) const
+{
+	// *TODO: Finish
+	sd["id"] = getUUID();
+}
+
 //-----------------------------------------------------------------------------
 // setInfo
 //-----------------------------------------------------------------------------
@@ -1637,17 +1120,21 @@ void LLTexLayer::calculateTexLayerColor(const param_color_list_t &param_list, LL
 BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 {
 	LLGLEnable color_mat(GL_COLOR_MATERIAL);
-	gPipeline.disableLights();
+	// *TODO: Is this correct?
+	//gPipeline.disableLights();
+	stop_glerror();
+	glDisable(GL_LIGHTING);
+	stop_glerror();
 
 	bool use_shaders = LLGLSLShader::sNoFixedFunction;
 
 	LLColor4 net_color;
 	BOOL color_specified = findNetColor(&net_color);
 	
-	if (mTexLayerSet->getAvatar()->mIsDummy)
+	if (mTexLayerSet->getAvatarAppearance()->mIsDummy)
 	{
 		color_specified = true;
-		net_color = LLVOAvatar::getDummyColor();
+		net_color = LLAvatarAppearance::getDummyColor();
 	}
 
 	BOOL success = TRUE;
@@ -1687,7 +1174,8 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 			}
 		}//*/
 
-		renderMorphMasks(x, y, width, height, net_color);
+		const bool force_render = true;
+		renderMorphMasks(x, y, width, height, net_color, force_render);
 		alpha_mask_specified = TRUE;
 		gGL.flush();
 		gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA);
@@ -1704,7 +1192,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 	if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly )
 	{
 		{
-			LLViewerTexture* tex = NULL;
+			LLGLTexture* tex = NULL;
 			if (mLocalTextureObject && mLocalTextureObject->getImage())
 			{
 				tex = mLocalTextureObject->getImage();
@@ -1717,15 +1205,18 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 			{
 				llinfos << "lto not defined or image not defined: " << getInfo()->getLocalTexture() << " lto: " << mLocalTextureObject << llendl;
 			}
-//			if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )
+//			if( mTexLayerSet->getAvatarAppearance()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )
 			{
 				if( tex )
 				{
 					bool no_alpha_test = getInfo()->mWriteAllChannels;
 					LLGLDisable alpha_test(no_alpha_test ? GL_ALPHA_TEST : 0);
-					if (use_shaders && no_alpha_test)
+					if (no_alpha_test)
 					{
-						gAlphaMaskProgram.setMinimumAlpha(0.f);
+						if (use_shaders)
+						{
+							gAlphaMaskProgram.setMinimumAlpha(0.f);
+						}
 					}
 					
 					LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
@@ -1737,11 +1228,13 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 
 					gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
 					gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-					if (use_shaders && no_alpha_test)
+					if (no_alpha_test)
 					{
-						gAlphaMaskProgram.setMinimumAlpha(0.004f);
+						if (use_shaders)
+						{
+							gAlphaMaskProgram.setMinimumAlpha(0.004f);
+						}
 					}
-					
 				}
 			}
 //			else
@@ -1754,7 +1247,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 	if( !getInfo()->mStaticImageFileName.empty() )
 	{
 		{
-			LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+			LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
 			if( tex )
 			{
 				gGL.getTexUnit(0)->bind(tex, TRUE);
@@ -1776,8 +1269,9 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 		LLGLDisable no_alpha(GL_ALPHA_TEST);
 		if (use_shaders)
 		{
-			gAlphaMaskProgram.setMinimumAlpha(0.f);
+			gAlphaMaskProgram.setMinimumAlpha(0.000f);
 		}
+
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4fv( net_color.mV );
 		gl_rect_2d_simple( width, height );
@@ -1834,7 +1328,7 @@ BOOL LLTexLayer::findNetColor(LLColor4* net_color) const
 	{
 		if( !getGlobalColor().empty() )
 		{
-			net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getInfo()->mGlobalColor ) );
+			net_color->setVec( mTexLayerSet->getAvatarAppearance()->getGlobalColor( getInfo()->mGlobalColor ) );
 		}
 		else if (getInfo()->mFixedColor.mV[VW])
 		{
@@ -1851,7 +1345,7 @@ BOOL LLTexLayer::findNetColor(LLColor4* net_color) const
 
 	if( !getGlobalColor().empty() )
 	{
-		net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getGlobalColor() ) );
+		net_color->setVec( mTexLayerSet->getAvatarAppearance()->getGlobalColor( getGlobalColor() ) );
 		return TRUE;
 	}
 
@@ -1876,7 +1370,7 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
 
 	if( !getInfo()->mStaticImageFileName.empty() )
 	{
-		LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
+		LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
 		if( tex )
 		{
 			LLGLSNoAlphaTest gls_no_alpha_test;
@@ -1901,7 +1395,7 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
 	{
 		if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES)
 		{
-			LLViewerTexture* tex = mLocalTextureObject->getImage();
+			LLGLTexture* tex = mLocalTextureObject->getImage();
 			if (tex)
 			{
 				LLGLSNoAlphaTest gls_no_alpha_test;
@@ -1929,8 +1423,15 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
 	addAlphaMask(data, originX, originY, width, height);
 }
 
-BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color)
+static LLFastTimer::DeclareTimer FTM_RENDER_MORPH_MASKS("renderMorphMasks");
+void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render)
 {
+	if (!force_render && !hasMorph())
+	{
+		lldebugs << "skipping renderMorphMasks for " << getUUID() << llendl;
+		return;
+	}
+	LLFastTimer t(FTM_RENDER_MORPH_MASKS);
 	BOOL success = TRUE;
 
 	llassert( !mParamAlphaList.empty() );
@@ -1966,6 +1467,11 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 	{
 		LLTexLayerParamAlpha* param = *iter;
 		success &= param->render( x, y, width, height );
+		if (!success && !force_render)
+		{
+			lldebugs << "Failed to render param " << param->getID() << " ; skipping morph mask." << llendl;
+			return;
+		}
 	}
 
 	// Approximates a min() function
@@ -1975,7 +1481,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 	// Accumulate the alpha component of the texture
 	if( getInfo()->mLocalTexture != -1 )
 	{
-		LLViewerTexture* tex = mLocalTextureObject->getImage();
+		LLGLTexture* tex = mLocalTextureObject->getImage();
 		if( tex && (tex->getComponents() == 4) )
 		{
 			LLGLSNoAlphaTest gls_no_alpha_test;
@@ -1991,25 +1497,29 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 		}
 	}
 
-	if( !getInfo()->mStaticImageFileName.empty() )
+	if( !getInfo()->mStaticImageFileName.empty() && getInfo()->mStaticImageIsMask )
 	{
-		LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+		LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
 		if( tex )
 		{
-			if(	(tex->getComponents() == 4) ||
-				( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
+			if(	(tex->getComponents() == 4) || (tex->getComponents() == 1) )
 			{
 				LLGLSNoAlphaTest gls_no_alpha_test;
 				gGL.getTexUnit(0)->bind(tex, TRUE);
 				gl_rect_2d_simple_tex( width, height );
 				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			}
+			else
+			{
+				llwarns << "Skipping rendering of " << getInfo()->mStaticImageFileName 
+						<< "; expected 1 or 4 components." << llendl;
+			}
 		}
 	}
 
 	// Draw a rectangle with the layer color to multiply the alpha by that color's alpha.
 	// Note: we're still using gGL.blendFunc( GL_DST_ALPHA, GL_ZERO );
-	if (layer_color.mV[VW] != 1.f)
+	if ( !is_approx_equal(layer_color.mV[VW], 1.f) )
 	{
 		LLGLDisable no_alpha(GL_ALPHA_TEST);
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -2044,7 +1554,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 		if (!alpha_data)
 		{
 			// clear out a slot if we have filled our cache
-			S32 max_cache_entries = getTexLayerSet()->getAvatar()->isSelf() ? 4 : 1;
+			S32 max_cache_entries = getTexLayerSet()->getAvatarAppearance()->isSelf() ? 4 : 1;
 			while ((S32)mAlphaCache.size() >= max_cache_entries)
 			{
 				alpha_cache_t::iterator iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry
@@ -2057,17 +1567,17 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 			glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data);
 		}
 		
-		getTexLayerSet()->getAvatar()->dirtyMesh();
+		getTexLayerSet()->getAvatarAppearance()->dirtyMesh();
 
 		mMorphMasksValid = TRUE;
 		getTexLayerSet()->applyMorphMask(alpha_data, width, height, 1);
 	}
-
-	return success;
 }
 
+static LLFastTimer::DeclareTimer FTM_ADD_ALPHA_MASK("addAlphaMask");
 void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
 {
+	LLFastTimer t(FTM_ADD_ALPHA_MASK);
 	S32 size = width * height;
 	const U8* alphaData = getAlphaData();
 	if (!alphaData && hasAlphaParams())
@@ -2076,7 +1586,8 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32
 		findNetColor( &net_color );
 		// TODO: eliminate need for layer morph mask valid flag
 		invalidateMorphMasks();
-		renderMorphMasks(originX, originY, width, height, net_color);
+		const bool force_render = false;
+		renderMorphMasks(originX, originY, width, height, net_color, force_render);
 		alphaData = getAlphaData();
 	}
 	if (alphaData)
@@ -2085,7 +1596,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32
 		{
 			U8 curAlpha = data[i];
 			U16 resultAlpha = curAlpha;
-			resultAlpha *= (alphaData[i] + 1);
+			resultAlpha *= ( ((U16)alphaData[i]) + 1);
 			resultAlpha = resultAlpha >> 8;
 			data[i] = (U8)resultAlpha;
 		}
@@ -2110,7 +1621,7 @@ LLUUID LLTexLayer::getUUID() const
 	LLUUID uuid;
 	if( getInfo()->mLocalTexture != -1 )
 	{
-			LLViewerTexture* tex = mLocalTextureObject->getImage();
+			LLGLTexture* tex = mLocalTextureObject->getImage();
 			if (tex)
 			{
 				uuid = mLocalTextureObject->getID();
@@ -2118,7 +1629,7 @@ LLUUID LLTexLayer::getUUID() const
 	}
 	if( !getInfo()->mStaticImageFileName.empty() )
 	{
-			LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+			LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
 			if( tex )
 			{
 				uuid = tex->getID();
@@ -2141,13 +1652,15 @@ LLUUID LLTexLayer::getUUID() const
 //			* a texture entry index (TE)
 //		* (optional) one or more alpha parameters (weighted alpha textures)
 //-----------------------------------------------------------------------------
-LLTexLayerTemplate::LLTexLayerTemplate(LLTexLayerSet* layer_set) :
-	LLTexLayerInterface(layer_set)
+LLTexLayerTemplate::LLTexLayerTemplate(LLTexLayerSet* layer_set, LLAvatarAppearance* const appearance) :
+	LLTexLayerInterface(layer_set),
+	mAvatarAppearance( appearance )
 {
 }
 
 LLTexLayerTemplate::LLTexLayerTemplate(const LLTexLayerTemplate &layer) :
-	LLTexLayerInterface(layer)
+	LLTexLayerInterface(layer),
+	mAvatarAppearance(layer.getAvatarAppearance())
 {
 }
 
@@ -2168,18 +1681,17 @@ U32 LLTexLayerTemplate::updateWearableCache() const
 {
 	mWearableCache.clear();
 
-	S32 te = mInfo->mLocalTexture;
-	if (te == -1)
+	LLWearableType::EType wearable_type = getWearableType();
+	if (LLWearableType::WT_INVALID == wearable_type)
 	{
 		//this isn't a cloneable layer 
 		return 0;
 	}
-	LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te);
-	U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
+	U32 num_wearables = getAvatarAppearance()->getWearableData()->getWearableCount(wearable_type);
 	U32 added = 0;
 	for (U32 i = 0; i < num_wearables; i++)
 	{
-		LLWearable*  wearable = gAgentWearables.getWearable(wearable_type, i);
+		LLWearable*  wearable = getAvatarAppearance()->getWearableData()->getWearable(wearable_type, i);
 		if (!wearable)
 		{
 			continue;
@@ -2234,7 +1746,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const
 		}
 		if (layer)
 		{
-			wearable->writeToAvatar();
+			wearable->writeToAvatar(mAvatarAppearance);
 			layer->setLTO(lto);
 			success &= layer->render(x,y,width,height);
 		}
@@ -2341,7 +1853,7 @@ LLTexLayerInterface*  LLTexLayerSet::findLayerByName(const std::string& name)
 	return NULL;
 }
 
-void LLTexLayerSet::cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable *wearable)
+void LLTexLayerSet::cloneTemplates(LLLocalTextureObject *lto, LLAvatarAppearanceDefines::ETextureIndex tex_index, LLWearable *wearable)
 {
 	// initialize all texlayers with this texture type for this LTO
 	for( LLTexLayerSet::layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
@@ -2408,8 +1920,10 @@ void LLTexLayerStaticImageList::deleteCachedImages()
 
 // Returns an LLImageTGA that contains the encoded data from a tga file named file_name.
 // Caches the result to speed identical subsequent requests.
+static LLFastTimer::DeclareTimer FTM_LOAD_STATIC_TGA("getImageTGA");
 LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name)
 {
+	LLFastTimer t(FTM_LOAD_STATIC_TGA);
 	const char *namekey = mImageNames.addString(file_name);
 	image_tga_map_t::const_iterator iter = mStaticImageListTGA.find(namekey);
 	if( iter != mStaticImageListTGA.end() )
@@ -2436,9 +1950,11 @@ LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name)
 
 // Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name.
 // Caches the result to speed identical subsequent requests.
-LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask)
+static LLFastTimer::DeclareTimer FTM_LOAD_STATIC_TEXTURE("getTexture");
+LLGLTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask)
 {
-	LLPointer<LLViewerTexture> tex;
+	LLFastTimer t(FTM_LOAD_STATIC_TEXTURE);
+	LLPointer<LLGLTexture> tex;
 	const char *namekey = mImageNames.addString(file_name);
 
 	texture_map_t::const_iterator iter = mStaticImageList.find(namekey);
@@ -2448,17 +1964,24 @@ LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_n
 	}
 	else
 	{
-		tex = LLViewerTextureManager::getLocalTexture( FALSE );
+		llassert(gTextureManagerBridgep);
+		tex = gTextureManagerBridgep->getLocalTexture( FALSE );
 		LLPointer<LLImageRaw> image_raw = new LLImageRaw;
 		if( loadImageRaw( file_name, image_raw ) )
 		{
 			if( (image_raw->getComponents() == 1) && is_mask )
 			{
-				// Note: these are static, unchanging images so it's ok to assume
-				// that once an image is a mask it's always a mask.
-				tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
+				// Convert grayscale alpha masks from single channel into RGBA.
+				// Fill RGB with black to allow fixed function gl calls
+				// to match shader implementation.
+				LLPointer<LLImageRaw> alpha_image_raw = image_raw;
+				image_raw = new LLImageRaw(image_raw->getWidth(),
+										   image_raw->getHeight(),
+										   4);
+
+				image_raw->copyUnscaledAlphaMask(alpha_image_raw, LLColor4U::black);
 			}
-			tex->createGLTexture(0, image_raw, 0, TRUE, LLViewerTexture::LOCAL);
+			tex->createGLTexture(0, image_raw, 0, TRUE, LLGLTexture::LOCAL);
 
 			gGL.getTexUnit(0)->bind(tex);
 			tex->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -2477,8 +2000,10 @@ LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_n
 
 // Reads a .tga file, decodes it, and puts the decoded data in image_raw.
 // Returns TRUE if successful.
+static LLFastTimer::DeclareTimer FTM_LOAD_IMAGE_RAW("loadImageRaw");
 BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLImageRaw* image_raw)
 {
+	LLFastTimer t(FTM_LOAD_IMAGE_RAW);
 	BOOL success = FALSE;
 	std::string path;
 	path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,file_name);
@@ -2492,23 +2017,3 @@ BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLIma
 	return success;
 }
 
-const std::string LLTexLayerSetBuffer::dumpTextureInfo() const
-{
-	if (!isAgentAvatarValid()) return "";
-
-	const BOOL is_high_res = !mNeedsUpload;
-	const U32 num_low_res = mNumLowresUploads;
-	const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32();
-	const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(mTexLayerSet);
-
-	std::string status 				= "CREATING ";
-	if (!uploadNeeded()) status 	= "DONE     ";
-	if (uploadInProgress()) status 	= "UPLOADING";
-
-	std::string text = llformat("[%s] [HiRes:%d LoRes:%d] [Elapsed:%d] %s",
-								status.c_str(),
-								is_high_res, num_low_res,
-								upload_time, 
-								local_texture_info.c_str());
-	return text;
-}
diff --git a/indra/newview/lltexlayer.h b/indra/llappearance/lltexlayer.h
similarity index 65%
rename from indra/newview/lltexlayer.h
rename to indra/llappearance/lltexlayer.h
index 4f43547dae5034117610fe9bd6274de7b1cc9a67..959d6e499abfb348bf8709e2b4c6b618871a9e3c 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/llappearance/lltexlayer.h
@@ -28,14 +28,15 @@
 #define LL_LLTEXLAYER_H
 
 #include <deque>
-#include "lldynamictexture.h"
-#include "llvoavatardefines.h"
+#include "llglslshader.h"
+#include "llgltexture.h"
+#include "llavatarappearancedefines.h"
 #include "lltexlayerparams.h"
 
-class LLVOAvatar;
-class LLVOAvatarSelf;
+class LLAvatarAppearance;
 class LLImageTGA;
 class LLImageRaw;
+class LLLocalTextureObject;
 class LLXmlTreeNode;
 class LLTexLayerSet;
 class LLTexLayerSetInfo;
@@ -71,6 +72,8 @@ class LLTexLayerInterface
 
 	const LLTexLayerInfo* 	getInfo() const 			{ return mInfo; }
 	virtual BOOL			setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // sets mInfo, calls initialization functions
+	LLWearableType::EType	getWearableType() const;
+	LLAvatarAppearanceDefines::ETextureIndex	getLocalTextureIndex() const;
 
 	const std::string&		getName() const;
 	const LLTexLayerSet* const getTexLayerSet() const 	{ return mTexLayerSet; }
@@ -88,6 +91,8 @@ class LLTexLayerInterface
 	ERenderPass				getRenderPass() const;
 	BOOL					isVisibilityMask() const;
 
+	virtual void			asLLSD(LLSD& sd) const {}
+
 protected:
 	const std::string&		getGlobalColor() const;
 	LLViewerVisualParam*	getVisualParamPtr(S32 index) const;
@@ -113,7 +118,7 @@ class LLTexLayerInterface
 class LLTexLayerTemplate : public LLTexLayerInterface
 {
 public:
-	LLTexLayerTemplate(LLTexLayerSet* const layer_set);
+	LLTexLayerTemplate(LLTexLayerSet* const layer_set, LLAvatarAppearance* const appearance);
 	LLTexLayerTemplate(const LLTexLayerTemplate &layer);
 	/*virtual*/ ~LLTexLayerTemplate();
 	/*virtual*/ BOOL		render(S32 x, S32 y, S32 width, S32 height);
@@ -126,7 +131,9 @@ class LLTexLayerTemplate : public LLTexLayerInterface
 protected:
 	U32 					updateWearableCache() const;
 	LLTexLayer* 			getLayer(U32 i) const;
+	LLAvatarAppearance*		getAvatarAppearance()	const		{ return mAvatarAppearance; }
 private:
+	LLAvatarAppearance*	const	mAvatarAppearance; // note: backlink only; don't make this an LLPointer.
 	typedef std::vector<LLWearable*> wearable_cache_t;
 	mutable wearable_cache_t mWearableCache; // mutable b/c most get- require updating this cache
 };
@@ -153,17 +160,18 @@ class LLTexLayer : public LLTexLayerInterface
 	BOOL					findNetColor(LLColor4* color) const;
 	/*virtual*/ BOOL		blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
 	/*virtual*/ void		gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
-	BOOL					renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color);
+	void					renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render);
 	void					addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
 	/*virtual*/ BOOL		isInvisibleAlphaMask() const;
 
 	void					setLTO(LLLocalTextureObject *lto) 	{ mLocalTextureObject = lto; }
 	LLLocalTextureObject* 	getLTO() 							{ return mLocalTextureObject; }
 
+	/*virtual*/ void		asLLSD(LLSD& sd) const;
+
 	static void 			calculateTexLayerColor(const param_color_list_t &param_list, LLColor4 &net_color);
 protected:
 	LLUUID					getUUID() const;
-private:
 	typedef std::map<U32, U8*> alpha_cache_t;
 	alpha_cache_t			mAlphaCache;
 	LLLocalTextureObject* 	mLocalTextureObject;
@@ -179,8 +187,14 @@ class LLTexLayerSet
 {
 	friend class LLTexLayerSetBuffer;
 public:
-	LLTexLayerSet(LLVOAvatarSelf* const avatar);
-	~LLTexLayerSet();
+	LLTexLayerSet(LLAvatarAppearance* const appearance);
+	virtual ~LLTexLayerSet();
+
+	LLTexLayerSetBuffer*		getComposite();
+	const LLTexLayerSetBuffer* 	getComposite() const; // Do not create one if it doesn't exist.
+	virtual void				createComposite() = 0;
+	void						destroyComposite();
+	void						gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height);
 
 	const LLTexLayerSetInfo* 	getInfo() const 			{ return mInfo; }
 	BOOL						setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions
@@ -189,45 +203,34 @@ class LLTexLayerSet
 	void						renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false);
 
 	BOOL						isBodyRegion(const std::string& region) const;
-	LLTexLayerSetBuffer*		getComposite();
-	const LLTexLayerSetBuffer* 	getComposite() const; // Do not create one if it doesn't exist.
-	void						requestUpdate();
-	void						requestUpload();
-	void						cancelUpload();
-	void						updateComposite();
-	BOOL						isLocalTextureDataAvailable() const;
-	BOOL						isLocalTextureDataFinal() const;
-	void						createComposite();
-	void						destroyComposite();
-	void						setUpdatesEnabled(BOOL b);
-	BOOL						getUpdatesEnabled()	const 	{ return mUpdatesEnabled; }
-	void						deleteCaches();
-	void						gatherMorphMaskAlpha(U8 *data, S32 width, S32 height);
 	void						applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
 	BOOL						isMorphValid() const;
+	virtual void				requestUpdate() = 0;
 	void						invalidateMorphMasks();
+	void						deleteCaches();
 	LLTexLayerInterface*		findLayerByName(const std::string& name);
-	void						cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable);
+	void						cloneTemplates(LLLocalTextureObject *lto, LLAvatarAppearanceDefines::ETextureIndex tex_index, LLWearable* wearable);
 	
-	LLVOAvatarSelf*		    	getAvatar()	const 			{ return mAvatar; }
+	LLAvatarAppearance*			getAvatarAppearance()	const		{ return mAvatarAppearance; }
 	const std::string			getBodyRegionName() const;
 	BOOL						hasComposite() const 		{ return (mComposite.notNull()); }
-	LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
-	void						setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
+	LLAvatarAppearanceDefines::EBakedTextureIndex getBakedTexIndex() const { return mBakedTexIndex; }
+	void						setBakedTexIndex(LLAvatarAppearanceDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
 	BOOL						isVisible() const 			{ return mIsVisible; }
 
 	static BOOL					sHasCaches;
 
-private:
+	virtual void				asLLSD(LLSD& sd) const;
+
+protected:
 	typedef std::vector<LLTexLayerInterface *> layer_list_t;
 	layer_list_t				mLayerList;
 	layer_list_t				mMaskLayerList;
 	LLPointer<LLTexLayerSetBuffer>	mComposite;
-	LLVOAvatarSelf*	const		mAvatar; // note: backlink only; don't make this an LLPointer.
-	BOOL						mUpdatesEnabled;
+	LLAvatarAppearance*	const	mAvatarAppearance; // note: backlink only; don't make this an LLPointer.
 	BOOL						mIsVisible;
 
-	LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex;
+	LLAvatarAppearanceDefines::EBakedTextureIndex mBakedTexIndex;
 	const LLTexLayerSetInfo* 	mInfo;
 };
 
@@ -243,8 +246,10 @@ class LLTexLayerSetInfo
 	LLTexLayerSetInfo();
 	~LLTexLayerSetInfo();
 	BOOL parseXml(LLXmlTreeNode* node);
-	void createVisualParams(LLVOAvatar *avatar);
-private:
+	void createVisualParams(LLAvatarAppearance *appearance);
+	S32 getWidth() const { return mWidth; }
+	S32 getHeight() const { return mHeight; }
+protected:
 	std::string				mBodyRegion;
 	S32						mWidth;
 	S32						mHeight;
@@ -259,78 +264,27 @@ class LLTexLayerSetInfo
 //
 // The composite image that a LLTexLayerSet writes to.  Each LLTexLayerSet has one.
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerSetBuffer : public LLViewerDynamicTexture
+class LLTexLayerSetBuffer : public virtual LLRefCount
 {
 	LOG_CLASS(LLTexLayerSetBuffer);
 
 public:
-	LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
+	LLTexLayerSetBuffer(LLTexLayerSet* const owner);
 	virtual ~LLTexLayerSetBuffer();
 
-public:
-	/*virtual*/ S8          getType() const;
-	BOOL					isInitialized(void) const;
-	static void				dumpTotalByteCount();
-	const std::string		dumpTextureInfo() const;
-	virtual void 			restoreGLTexture();
-	virtual void 			destroyGLTexture();
 protected:
 	void					pushProjection() const;
 	void					popProjection() const;
-private:
-	LLTexLayerSet* const    mTexLayerSet;
-	static S32				sGLByteCount;
+	virtual void			preRenderTexLayerSet();
+	virtual void			midRenderTexLayerSet(BOOL success) {}
+	virtual void			postRenderTexLayerSet(BOOL success);
+	virtual S32				getCompositeOriginX() const = 0;
+	virtual S32				getCompositeOriginY() const = 0;
+	virtual S32				getCompositeWidth() const = 0;
+	virtual S32				getCompositeHeight() const = 0;
+	BOOL					renderTexLayerSet();
 
-	//--------------------------------------------------------------------
-	// Render
-	//--------------------------------------------------------------------
-public:
-	/*virtual*/ BOOL		needsRender();
-protected:
-	BOOL					render(S32 x, S32 y, S32 width, S32 height);
-	virtual void			preRender(BOOL clear_depth);
-	virtual void			postRender(BOOL success);
-	virtual BOOL			render();	
-	
-	//--------------------------------------------------------------------
-	// Uploads
-	//--------------------------------------------------------------------
-public:
-	void					requestUpload();
-	void					cancelUpload();
-	BOOL					uploadNeeded() const; 			// We need to upload a new texture
-	BOOL					uploadInProgress() const; 		// We have started uploading a new texture and are awaiting the result
-	BOOL					uploadPending() const; 			// We are expecting a new texture to be uploaded at some point
-	static void				onTextureUploadComplete(const LLUUID& uuid,
-													void* userdata,
-													S32 result, LLExtStat ext_status);
-protected:
-	BOOL					isReadyToUpload() const;
-	void					doUpload(); 					// Does a read back and upload.
-	void					conditionalRestartUploadTimer();
-private:
-	BOOL					mNeedsUpload; 					// Whether we need to send our baked textures to the server
-	U32						mNumLowresUploads; 				// Number of times we've sent a lowres version of our baked textures to the server
-	BOOL					mUploadPending; 				// Whether we have received back the new baked textures
-	LLUUID					mUploadID; 						// The current upload process (null if none).
-	LLFrameTimer    		mNeedsUploadTimer; 				// Tracks time since upload was requested and performed.
-	S32						mUploadFailCount;				// Number of consecutive upload failures
-	LLFrameTimer    		mUploadRetryTimer; 				// Tracks time since last upload failure.
-
-	//--------------------------------------------------------------------
-	// Updates
-	//--------------------------------------------------------------------
-public:
-	void					requestUpdate();
-	BOOL					requestUpdateImmediate();
-protected:
-	BOOL					isReadyToUpdate() const;
-	void					doUpdate();
-	void					restartUpdateTimer();
-private:
-	BOOL					mNeedsUpdate; 					// Whether we need to locally update our baked textures
-	U32						mNumLowresUpdates; 				// Number of times we've locally updated with lowres version of our baked textures
-	LLFrameTimer    		mNeedsUpdateTimer; 				// Tracks time since update was requested and performed.
+	LLTexLayerSet* const	mTexLayerSet;
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -342,7 +296,7 @@ class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
 public:
 	LLTexLayerStaticImageList();
 	~LLTexLayerStaticImageList();
-	LLViewerTexture*	getTexture(const std::string& file_name, BOOL is_mask);
+	LLGLTexture*		getTexture(const std::string& file_name, BOOL is_mask);
 	LLImageTGA*			getImageTGA(const std::string& file_name);
 	void				deleteCachedImages();
 	void				dumpByteCount() const;
@@ -350,7 +304,7 @@ class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
 	BOOL				loadImageRaw(const std::string& file_name, LLImageRaw* image_raw);
 private:
 	LLStringTable 		mImageNames;
-	typedef std::map<const char*, LLPointer<LLViewerTexture> > texture_map_t;
+	typedef std::map<const char*, LLPointer<LLGLTexture> > texture_map_t;
 	texture_map_t 		mStaticImageList;
 	typedef std::map<const char*, LLPointer<LLImageTGA> > image_tga_map_t;
 	image_tga_map_t 	mStaticImageListTGA;
@@ -358,23 +312,4 @@ class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
 	S32 				mTGABytes;
 };
 
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLBakedUploadData
-//
-// Used by LLTexLayerSetBuffer for a callback.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-struct LLBakedUploadData
-{
-	LLBakedUploadData(const LLVOAvatarSelf* avatar, 
-					  LLTexLayerSet* layerset, 
-					  const LLUUID& id,
-					  bool highest_res);
-	~LLBakedUploadData() {}
-	const LLUUID				mID;
-	const LLVOAvatarSelf*		mAvatar; // note: backlink only; don't LLPointer 
-	LLTexLayerSet*				mTexLayerSet;
-   	const U64					mStartTime;	// for measuring baked texture upload time
-   	const bool					mIsHighestRes; // whether this is a "final" bake, or intermediate low res
-};
-
 #endif  // LL_LLTEXLAYER_H
diff --git a/indra/newview/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp
similarity index 85%
rename from indra/newview/lltexlayerparams.cpp
rename to indra/llappearance/lltexlayerparams.cpp
index 8972827effb513b90dbd7a951f1776266d88cd9c..6aae9a8cc11ce032266c3bbcfec8027f810d1b03 100644
--- a/indra/newview/lltexlayerparams.cpp
+++ b/indra/llappearance/lltexlayerparams.cpp
@@ -24,27 +24,28 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 
 #include "lltexlayerparams.h"
 
-#include "llagentcamera.h"
+#include "llavatarappearance.h"
 #include "llimagetga.h"
+#include "llquantize.h"
 #include "lltexlayer.h"
-#include "llvoavatarself.h"
+#include "lltexturemanagerbridge.h"
+#include "../llui/llui.h"
 #include "llwearable.h"
-#include "llui.h"
 
 //-----------------------------------------------------------------------------
 // LLTexLayerParam
 //-----------------------------------------------------------------------------
 LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) :
 	mTexLayer(layer),
-	mAvatar(NULL)
+	mAvatarAppearance(NULL)
 {
 	if (mTexLayer != NULL)
 	{
-		mAvatar = mTexLayer->getTexLayerSet()->getAvatar();
+		mAvatarAppearance = mTexLayer->getTexLayerSet()->getAvatarAppearance();
 	}
 	else
 	{
@@ -52,20 +53,21 @@ LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) :
 	}
 }
 
-LLTexLayerParam::LLTexLayerParam(LLVOAvatar *avatar) :
-	mTexLayer(NULL)
+LLTexLayerParam::LLTexLayerParam(LLAvatarAppearance *appearance) :
+	mTexLayer(NULL),
+	mAvatarAppearance(appearance)
 {
-	mAvatar = avatar;
 }
 
 
-BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar  )
-{	
+BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance)
+{
 	LLViewerVisualParam::setInfo(info);
 
-	if (add_to_avatar)
+	if (add_to_appearance)
 	{
-		mAvatar->addVisualParam( this);
+		mAvatarAppearance->addVisualParam( this);
+		this->setParamLocation(mAvatarAppearance->isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
 	}
 
 	return TRUE;
@@ -96,7 +98,7 @@ void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes)
 		 iter != sInstances.end(); iter++)
 	{
 		LLTexLayerParamAlpha* instance = *iter;
-		LLViewerTexture* tex = instance->mCachedProcessedTexture;
+		LLGLTexture* tex = instance->mCachedProcessedTexture;
 		if (tex)
 		{
 			S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
@@ -120,8 +122,8 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) :
 	sInstances.push_front(this);
 }
 
-LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLVOAvatar* avatar) :
-	LLTexLayerParam(avatar),
+LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLAvatarAppearance* appearance) :
+	LLTexLayerParam(appearance),
 	mCachedProcessedTexture(NULL),
 	mNeedsCreateTexture(FALSE),
 	mStaticImageInvalid(FALSE),
@@ -173,13 +175,10 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake)
 	{
 		mCurWeight = new_weight;
 
-		if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
+		if ((mAvatarAppearance->getSex() & getSex()) &&
+			(mAvatarAppearance->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
 		{
-			if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
-			{
-				upload_bake = FALSE;
-			}
-			mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
+			mAvatarAppearance->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
 			mTexLayer->invalidateMorphMasks();
 		}
 	}
@@ -218,11 +217,11 @@ BOOL LLTexLayerParamAlpha::getSkip() const
 		return TRUE;
 	}
 
-	const LLVOAvatar *avatar = mTexLayer->getTexLayerSet()->getAvatar();
+	const LLAvatarAppearance *appearance = mTexLayer->getTexLayerSet()->getAvatarAppearance();
 
 	if (((LLTexLayerParamAlphaInfo *)getInfo())->mSkipIfZeroWeight)
 	{
-		F32 effective_weight = (avatar->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
+		F32 effective_weight = (appearance->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
 		if (is_approx_zero(effective_weight)) 
 		{
 			return TRUE;
@@ -230,7 +229,7 @@ BOOL LLTexLayerParamAlpha::getSkip() const
 	}
 
 	LLWearableType::EType type = (LLWearableType::EType)getWearableType();
-	if ((type != LLWearableType::WT_INVALID) && !avatar->isWearingWearableType(type))
+	if ((type != LLWearableType::WT_INVALID) && !appearance->isWearingWearableType(type))
 	{
 		return TRUE;
 	}
@@ -239,8 +238,10 @@ BOOL LLTexLayerParamAlpha::getSkip() const
 }
 
 
+static LLFastTimer::DeclareTimer FTM_TEX_LAYER_PARAM_ALPHA("alpha render");
 BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
 {
+	LLFastTimer t(FTM_TEX_LAYER_PARAM_ALPHA);
 	BOOL success = TRUE;
 
 	if (!mTexLayer)
@@ -248,7 +249,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
 		return success;
 	}
 
-	F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatar()->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
+	F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatarAppearance()->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
 	BOOL weight_changed = effective_weight != mCachedEffectiveWeight;
 	if (getSkip())
 	{
@@ -290,12 +291,12 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
 			(mCachedProcessedTexture->getHeight() != image_tga_height) ||
 			(weight_changed))
 		{
-//			llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl;
 			mCachedEffectiveWeight = effective_weight;
 
 			if (!mCachedProcessedTexture)
 			{
-				mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture(image_tga_width, image_tga_height, 1, FALSE);
+				llassert(gTextureManagerBridgep);
+				mCachedProcessedTexture = gTextureManagerBridgep->getLocalTexture(image_tga_width, image_tga_height, 1, FALSE);
 
 				// We now have something in one of our caches
 				LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE;
@@ -308,6 +309,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
 			mStaticImageRaw = new LLImageRaw;
 			mStaticImageTGA->decodeAndProcess(mStaticImageRaw, info->mDomain, effective_weight);
 			mNeedsCreateTexture = TRUE;			
+			lldebugs << "Built Cached Alpha: " << info->mStaticImageFileName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << "Domain: " << info->mDomain << " Weight: " << effective_weight << llendl;
 		}
 
 		if (mCachedProcessedTexture)
@@ -332,7 +334,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
 
 		// Don't keep the cache for other people's avatars
 		// (It's not really a "cache" in that case, but the logic is the same)
-		if (!mAvatar->isSelf())
+		if (!mAvatarAppearance->isSelf())
 		{
 			mCachedProcessedTexture = NULL;
 		}
@@ -402,8 +404,8 @@ LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer) :
 {
 }
 
-LLTexLayerParamColor::LLTexLayerParamColor(LLVOAvatar *avatar) :
-	LLTexLayerParam(avatar),
+LLTexLayerParamColor::LLTexLayerParamColor(LLAvatarAppearance *appearance) :
+	LLTexLayerParam(appearance),
 	mAvgDistortionVec(1.f, 1.f, 1.f)
 {
 }
@@ -425,7 +427,7 @@ LLColor4 LLTexLayerParamColor::getNetColor() const
 	
 	llassert(info->mNumColors >= 1);
 
-	F32 effective_weight = (mAvatar && (mAvatar->getSex() & getSex())) ? mCurWeight : getDefaultWeight();
+	F32 effective_weight = (mAvatarAppearance && (mAvatarAppearance->getSex() & getSex())) ? mCurWeight : getDefaultWeight();
 
 	S32 index_last = info->mNumColors - 1;
 	F32 scaled_weight = effective_weight * index_last;
@@ -470,12 +472,12 @@ void LLTexLayerParamColor::setWeight(F32 weight, BOOL upload_bake)
 			return;
 		}
 
-		if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
+		if ((mAvatarAppearance->getSex() & getSex()) && (mAvatarAppearance->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
 		{
 			onGlobalColorChanged(upload_bake);
 			if (mTexLayer)
 			{
-				mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
+				mAvatarAppearance->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
 			}
 		}
 
diff --git a/indra/newview/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h
similarity index 95%
rename from indra/newview/lltexlayerparams.h
rename to indra/llappearance/lltexlayerparams.h
index c812199796f91a839a1c3e575248fbc5506a99c6..b38d28d3ebb4d666265747e5696c263fc6c7f715 100644
--- a/indra/newview/lltexlayerparams.h
+++ b/indra/llappearance/lltexlayerparams.h
@@ -27,14 +27,16 @@
 #ifndef LL_LLTEXLAYERPARAMS_H
 #define LL_LLTEXLAYERPARAMS_H
 
+#include "llpointer.h"
+#include "v4color.h"
 #include "llviewervisualparam.h"
 
+class LLAvatarAppearance;
 class LLImageRaw;
 class LLImageTGA;
 class LLTexLayer;
 class LLTexLayerInterface;
-class LLViewerTexture;
-class LLVOAvatar;
+class LLGLTexture;
 class LLWearable;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -45,13 +47,13 @@ class LLTexLayerParam : public LLViewerVisualParam
 {
 public: 
 	LLTexLayerParam(LLTexLayerInterface *layer);
-	LLTexLayerParam(LLVOAvatar *avatar);
-	/*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar  );
+	LLTexLayerParam(LLAvatarAppearance *appearance);
+	/*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance);
 	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
 
 protected:
 	LLTexLayerInterface*	mTexLayer;
-	LLVOAvatar*             mAvatar;
+	LLAvatarAppearance*		mAvatarAppearance;
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -63,7 +65,7 @@ class LLTexLayerParamAlpha : public LLTexLayerParam
 {
 public:
 	LLTexLayerParamAlpha( LLTexLayerInterface* layer );
-	LLTexLayerParamAlpha( LLVOAvatar* avatar );
+	LLTexLayerParamAlpha( LLAvatarAppearance* appearance );
 	/*virtual*/ ~LLTexLayerParamAlpha();
 
 	void* operator new(size_t size)
@@ -100,7 +102,7 @@ class LLTexLayerParamAlpha : public LLTexLayerParam
 	BOOL					getMultiplyBlend() const;
 
 private:
-	LLPointer<LLViewerTexture>	mCachedProcessedTexture;
+	LLPointer<LLGLTexture>	mCachedProcessedTexture;
 	LLPointer<LLImageTGA>	mStaticImageTGA;
 	LLPointer<LLImageRaw>	mStaticImageRaw;
 	BOOL					mNeedsCreateTexture;
@@ -153,7 +155,7 @@ class LLTexLayerParamColor : public LLTexLayerParam
 	};
 
 	LLTexLayerParamColor( LLTexLayerInterface* layer );
-	LLTexLayerParamColor( LLVOAvatar* avatar );
+	LLTexLayerParamColor( LLAvatarAppearance* appearance );
 
 	void* operator new(size_t size)
 	{
diff --git a/indra/llappearance/lltexturemanagerbridge.cpp b/indra/llappearance/lltexturemanagerbridge.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..33f2185e4fad5cb942661dd5421e7722b63a6a4e
--- /dev/null
+++ b/indra/llappearance/lltexturemanagerbridge.cpp
@@ -0,0 +1,32 @@
+ /** 
+ * @file lltexturemanagerbridge.cpp
+ * @brief Defined a null texture manager bridge.  Applications must provide their own bridge implementaton.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "lltexturemanagerbridge.h"
+
+// Define a null texture manager bridge.  Applications must provide their own bridge implementaton.
+LLTextureManagerBridge* gTextureManagerBridgep = NULL;
+
+
diff --git a/indra/llappearance/lltexturemanagerbridge.h b/indra/llappearance/lltexturemanagerbridge.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b814b522dd49ff23dff72fc6da4ab36f7c26e75
--- /dev/null
+++ b/indra/llappearance/lltexturemanagerbridge.h
@@ -0,0 +1,46 @@
+/** 
+ * @file lltexturemanagerbridge.h
+ * @brief Bridge to an application-specific texture manager.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_TEXTUREMANAGERBRIDGE_H
+#define LL_TEXTUREMANAGERBRIDGE_H
+
+#include "llavatarappearancedefines.h"
+#include "llpointer.h"
+#include "llgltexture.h"
+
+// Abstract bridge interface
+class LLTextureManagerBridge
+{
+public:
+	virtual LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) = 0;
+	virtual LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) = 0;
+	virtual LLGLTexture* getFetchedTexture(const LLUUID &image_id) = 0;
+};
+
+extern LLTextureManagerBridge* gTextureManagerBridgep;
+
+#endif // LL_TEXTUREMANAGERBRIDGE_H
+
diff --git a/indra/newview/llviewervisualparam.cpp b/indra/llappearance/llviewervisualparam.cpp
similarity index 98%
rename from indra/newview/llviewervisualparam.cpp
rename to indra/llappearance/llviewervisualparam.cpp
index f0cf9b7692ef9e492d13c5dc65168f46863dd10a..cc81bcf118a2a964d9a40feb556c400eed2cdf99 100644
--- a/indra/newview/llviewervisualparam.cpp
+++ b/indra/llappearance/llviewervisualparam.cpp
@@ -27,11 +27,10 @@
 //-----------------------------------------------------------------------------
 // Header Files
 //-----------------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 
 #include "llviewervisualparam.h"
 #include "llxmltree.h"
-#include "llui.h"
 #include "llwearable.h"
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llviewervisualparam.h b/indra/llappearance/llviewervisualparam.h
similarity index 100%
rename from indra/newview/llviewervisualparam.h
rename to indra/llappearance/llviewervisualparam.h
diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d86a460511fba4cb052b8d40029dae735488e08b
--- /dev/null
+++ b/indra/llappearance/llwearable.cpp
@@ -0,0 +1,781 @@
+/** 
+ * @file llwearable.cpp
+ * @brief LLWearable class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llavatarappearance.h"
+#include "lllocaltextureobject.h"
+#include "lltexlayer.h"
+#include "lltexturemanagerbridge.h"
+#include "llvisualparam.h"
+#include "llavatarappearancedefines.h"
+#include "llwearable.h"
+
+using namespace LLAvatarAppearanceDefines;
+
+// static
+S32 LLWearable::sCurrentDefinitionVersion = 1;
+
+// Private local functions
+static std::string terse_F32_to_string(F32 f);
+
+// virtual
+LLWearable::~LLWearable()
+{
+}
+
+const std::string& LLWearable::getTypeLabel() const
+{
+	return LLWearableType::getTypeLabel(mType);
+}
+
+const std::string& LLWearable::getTypeName() const
+{
+	return LLWearableType::getTypeName(mType);
+}
+
+LLAssetType::EType LLWearable::getAssetType() const
+{
+	return LLWearableType::getAssetType(mType);
+}
+
+BOOL LLWearable::exportFile(LLFILE* fp) const
+{
+	llofstream ofs(fp);
+	return exportStream(ofs);
+}
+
+// virtual
+BOOL LLWearable::exportStream( std::ostream& output_stream ) const
+{
+	if (!output_stream.good()) return FALSE;
+
+	// header and version
+	output_stream << "LLWearable version " << mDefinitionVersion  << "\n";
+	// name
+	output_stream << mName << "\n";
+	// description
+	output_stream << mDescription << "\n";
+
+	// permissions
+	if( !mPermissions.exportLegacyStream( output_stream ) )
+	{
+		return FALSE;
+	}
+
+	// sale info
+	if( !mSaleInfo.exportLegacyStream( output_stream ) )
+	{
+		return FALSE;
+	}
+
+	// wearable type
+	output_stream << "type " << (S32) getType() << "\n";
+
+	// parameters
+	output_stream << "parameters " << mVisualParamIndexMap.size() << "\n";
+
+	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
+		 iter != mVisualParamIndexMap.end(); 
+		 ++iter)
+	{
+		S32 param_id = iter->first;
+		const LLVisualParam* param = iter->second;
+		F32 param_weight = param->getWeight();
+		output_stream << param_id << " " << terse_F32_to_string( param_weight ) << "\n";
+	}
+
+	// texture entries
+	output_stream << "textures " << mTEMap.size() << "\n";
+
+	for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
+	{
+			S32 te = iter->first;
+			const LLUUID& image_id = iter->second->getID();
+			output_stream << te << " " << image_id << "\n";
+	}
+	return TRUE;
+}
+
+void LLWearable::createVisualParams(LLAvatarAppearance *avatarp)
+{
+	for (LLViewerVisualParam* param = (LLViewerVisualParam*) avatarp->getFirstVisualParam(); 
+		 param;
+		 param = (LLViewerVisualParam*) avatarp->getNextVisualParam())
+	{
+		if (param->getWearableType() == mType)
+		{
+			LLVisualParam *clone_param = param->cloneParam(this);
+			clone_param->setParamLocation(LOC_UNKNOWN);
+			clone_param->setParamLocation(LOC_WEARABLE);
+			addVisualParam(clone_param);
+		}
+	}
+
+	// resync driver parameters to point to the newly cloned driven parameters
+	for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin(); 
+		 param_iter != mVisualParamIndexMap.end(); 
+		 ++param_iter)
+	{
+		LLVisualParam* param = param_iter->second;
+		LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam; 
+		// need this line to disambiguate between versions of LLCharacter::getVisualParam()
+		LLVisualParam*(LLAvatarAppearance::*param_function)(S32)const = &LLAvatarAppearance::getVisualParam; 
+		param->resetDrivenParams();
+		if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false))
+		{
+			if( !param->linkDrivenParams(boost::bind(param_function,avatarp,_1 ), true))
+			{
+				llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl;
+				continue;
+			}
+		}
+	}
+}
+
+void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
+{
+	LLTexLayerSet *layer_set = NULL;
+	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
+	if (texture_dict->mIsUsedByBakedTexture)
+	{
+		const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+		
+		 layer_set = avatarp->getAvatarLayerSet(baked_index);
+	}
+
+	if (layer_set)
+	{
+		   layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
+	}
+	else
+	{
+		   llerrs << "could not find layerset for LTO in wearable!" << llendl;
+	}
+}
+
+LLWearable::EImportResult LLWearable::importFile(LLFILE* fp, LLAvatarAppearance* avatarp )
+{
+	llifstream ifs(fp);
+	return importStream(ifs, avatarp);
+}
+
+// virtual
+LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
+{
+	// *NOTE: changing the type or size of this buffer will require
+	// changes in the fscanf() code below.
+	// We are using a local max buffer size here to avoid issues
+	// if MAX_STRING size changes.
+	const U32 PARSE_BUFFER_SIZE = 2048;
+	char buffer[PARSE_BUFFER_SIZE];		/* Flawfinder: ignore */
+	char uuid_buffer[37];	/* Flawfinder: ignore */
+
+	// This data is being generated on the viewer.
+	// Impose some sane limits on parameter and texture counts.
+	const S32 MAX_WEARABLE_ASSET_TEXTURES = 100;
+	const S32 MAX_WEARABLE_ASSET_PARAMETERS = 1000;
+
+	if(!avatarp)
+	{
+		return LLWearable::FAILURE;
+	}
+
+	// read header and version 
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Failed to read wearable asset input stream." << llendl;
+		return LLWearable::FAILURE;
+	}
+	if ( 1 != sscanf( /* Flawfinder: ignore */
+				buffer,
+				"LLWearable version %d\n",
+				&mDefinitionVersion ) )
+	{
+		return LLWearable::BAD_HEADER;
+	}
+
+	// Hack to allow wearables with definition version 24 to still load.
+	// This should only affect lindens and NDA'd testers who have saved wearables in 2.0
+	// the extra check for version == 24 can be removed before release, once internal testers
+	// have loaded these wearables again. See hack pt 2 at bottom of function to ensure that
+	// these wearables get re-saved with version definition 22.
+	if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 )
+	{
+		llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
+		return LLWearable::FAILURE;
+	}
+
+	// name may be empty
+    if (!input_stream.good())
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading name" << llendl;
+		return LLWearable::FAILURE;
+	}
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+	mName = buffer;
+
+	// description may be empty
+	if (!input_stream.good())
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading description" << llendl;
+		return LLWearable::FAILURE;
+	}
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+	mDescription = buffer;
+
+	// permissions may have extra empty lines before the correct line
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading permissions" << llendl;
+		return LLWearable::FAILURE;
+	}
+	S32 perm_version = -1;
+	if ( 1 != sscanf( buffer, " permissions %d\n", &perm_version ) ||
+		 perm_version != 0 )
+	{
+		llwarns << "Bad Wearable asset: missing valid permissions" << llendl;
+		return LLWearable::FAILURE;
+	}
+	if( !mPermissions.importLegacyStream( input_stream ) )
+	{
+		return LLWearable::FAILURE;
+	}
+
+	// sale info
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading sale info" << llendl;
+		return LLWearable::FAILURE;
+	}
+	S32 sale_info_version = -1;
+	if ( 1 != sscanf( buffer, " sale_info %d\n", &sale_info_version ) ||
+		sale_info_version != 0 )
+	{
+		llwarns << "Bad Wearable asset: missing valid sale_info" << llendl;
+		return LLWearable::FAILURE;
+	}
+	// Sale info used to contain next owner perm. It is now in the
+	// permissions. Thus, we read that out, and fix legacy
+	// objects. It's possible this op would fail, but it should pick
+	// up the vast majority of the tasks.
+	BOOL has_perm_mask = FALSE;
+	U32 perm_mask = 0;
+	if( !mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask) )
+	{
+		return LLWearable::FAILURE;
+	}
+	if(has_perm_mask)
+	{
+		// fair use fix.
+		if(!(perm_mask & PERM_COPY))
+		{
+			perm_mask |= PERM_TRANSFER;
+		}
+		mPermissions.setMaskNext(perm_mask);
+	}
+
+	// wearable type
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading type" << llendl;
+		return LLWearable::FAILURE;
+	}
+	S32 type = -1;
+	if ( 1 != sscanf( buffer, "type %d\n", &type ) )
+	{
+		llwarns << "Bad Wearable asset: bad type" << llendl;
+		return LLWearable::FAILURE;
+	}
+	if( 0 <= type && type < LLWearableType::WT_COUNT )
+	{
+		setType((LLWearableType::EType)type, avatarp);
+	}
+	else
+	{
+		mType = LLWearableType::WT_COUNT;
+		llwarns << "Bad Wearable asset: bad type #" << type <<  llendl;
+		return LLWearable::FAILURE;
+	}
+
+	// parameters header
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading parameters header" << llendl;
+		return LLWearable::FAILURE;
+	}
+	S32 num_parameters = -1;
+	if ( 1 != sscanf( buffer, "parameters %d\n", &num_parameters ) )
+	{
+		llwarns << "Bad Wearable asset: missing parameters block" << llendl;
+		return LLWearable::FAILURE;
+	}
+	if ( num_parameters > MAX_WEARABLE_ASSET_PARAMETERS )
+	{
+		llwarns << "Bad Wearable asset: too many parameters, "
+				<< num_parameters << llendl;
+		return LLWearable::FAILURE;
+	}
+	if( num_parameters != mVisualParamIndexMap.size() )
+	{
+		llwarns << "Wearable parameter mismatch. Reading in " 
+				<< num_parameters << " from file, but created " 
+				<< mVisualParamIndexMap.size() 
+				<< " from avatar parameters. type: " 
+				<<  getType() << llendl;
+	}
+
+	// parameters
+	S32 i;
+	for( i = 0; i < num_parameters; i++ )
+	{
+		if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+		{
+			llwarns << "Bad Wearable asset: early end of input stream " 
+					<< "while reading parameter #" << i << llendl;
+			return LLWearable::FAILURE;
+		}
+		S32 param_id = 0;
+		F32 param_weight = 0.f;
+		if ( 2 != sscanf( buffer, "%d %f\n", &param_id, &param_weight ) )
+		{
+			llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
+			return LLWearable::FAILURE;
+		}
+		mSavedVisualParamMap[param_id] = param_weight;
+	}
+
+	// textures header
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading textures header" << i << llendl;
+		return LLWearable::FAILURE;
+	}
+	S32 num_textures = -1;
+	if ( 1 != sscanf( buffer, "textures %d\n", &num_textures) )
+	{
+		llwarns << "Bad Wearable asset: missing textures block" << llendl;
+		return LLWearable::FAILURE;
+	}
+	if ( num_textures > MAX_WEARABLE_ASSET_TEXTURES )
+	{
+		llwarns << "Bad Wearable asset: too many textures, "
+				<< num_textures << llendl;
+		return LLWearable::FAILURE;
+	}
+
+	// textures
+	for( i = 0; i < num_textures; i++ )
+	{
+		if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+		{
+			llwarns << "Bad Wearable asset: early end of input stream " 
+					<< "while reading textures #" << i << llendl;
+			return LLWearable::FAILURE;
+		}
+		S32 te = 0;
+		if ( 2 != sscanf(   /* Flawfinder: ignore */
+				buffer,
+				"%d %36s\n",
+				&te, uuid_buffer) )
+		{
+				llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
+				return LLWearable::FAILURE;
+		}
+	
+		if( !LLUUID::validate( uuid_buffer ) )
+		{
+				llwarns << "Bad Wearable asset: bad texture uuid: " 
+						<< uuid_buffer << llendl;
+				return LLWearable::FAILURE;
+		}
+		LLUUID id = LLUUID(uuid_buffer);
+		LLGLTexture* image = gTextureManagerBridgep->getFetchedTexture( id );
+		if( mTEMap.find(te) != mTEMap.end() )
+		{
+				delete mTEMap[te];
+		}
+		if( mSavedTEMap.find(te) != mSavedTEMap.end() )
+		{
+				delete mSavedTEMap[te];
+		}
+	
+		LLUUID textureid(uuid_buffer);
+		mTEMap[te] = new LLLocalTextureObject(image, textureid);
+		mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
+		createLayers(te, avatarp);
+	}
+
+	// copy all saved param values to working params
+	revertValues();
+
+	return LLWearable::SUCCESS;
+}
+
+BOOL LLWearable::getNextPopulatedLine(std::istream& input_stream, char* buffer, U32 buffer_size)
+{
+	if (!input_stream.good())
+	{
+		return FALSE;
+	}
+
+	do 
+	{
+		input_stream.getline(buffer, buffer_size);
+	}
+	while (input_stream.good() && buffer[0]=='\0');
+
+	return (buffer[0] != '\0'); 
+}
+
+
+void LLWearable::setType(LLWearableType::EType type, LLAvatarAppearance *avatarp) 
+{ 
+	mType = type; 
+	createVisualParams(avatarp);
+}
+
+
+LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index)
+{
+	te_map_t::iterator iter = mTEMap.find(index);
+	if( iter != mTEMap.end() )
+	{
+		LLLocalTextureObject* lto = iter->second;
+		return lto;
+	}
+	return NULL;
+}
+
+const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const
+{
+	te_map_t::const_iterator iter = mTEMap.find(index);
+	if( iter != mTEMap.end() )
+	{
+		const LLLocalTextureObject* lto = iter->second;
+		return lto;
+	}
+	return NULL;
+}
+
+std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq()
+{
+	std::vector<LLLocalTextureObject*> result;
+
+	for(te_map_t::const_iterator iter = mTEMap.begin();
+		iter != mTEMap.end(); iter++)
+	{
+		LLLocalTextureObject* lto = iter->second;
+		result.push_back(lto);
+	}
+
+	return result;
+}
+
+void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
+{
+	if( mTEMap.find(index) != mTEMap.end() )
+	{
+		mTEMap.erase(index);
+	}
+	mTEMap[index] = new LLLocalTextureObject(lto);
+}
+
+void LLWearable::revertValues()
+{
+	// FIXME DRANO - this triggers changes to driven params on avatar, potentially clobbering baked appearance.
+
+	//update saved settings so wearable is no longer dirty
+	// non-driver params first
+	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+	{
+		S32 id = iter->first;
+		F32 value = iter->second;
+		LLVisualParam *param = getVisualParam(id);
+		if(param &&  !dynamic_cast<LLDriverParam*>(param) )
+		{
+			setVisualParamWeight(id, value, TRUE);
+		}
+	}
+
+	//then driver params
+	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+	{
+		S32 id = iter->first;
+		F32 value = iter->second;
+		LLVisualParam *param = getVisualParam(id);
+		if(param &&  dynamic_cast<LLDriverParam*>(param) )
+		{
+			setVisualParamWeight(id, value, TRUE);
+		}
+	}
+
+	// make sure that saved values are sane
+	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+	{
+		S32 id = iter->first;
+		LLVisualParam *param = getVisualParam(id);
+		if( param )
+		{
+			mSavedVisualParamMap[id] = param->getWeight();
+		}
+	}
+
+	syncImages(mSavedTEMap, mTEMap);
+}
+
+void LLWearable::saveValues()
+{
+	//update saved settings so wearable is no longer dirty
+	mSavedVisualParamMap.clear();
+	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
+	{
+		S32 id = iter->first;
+		LLVisualParam *wearable_param = iter->second;
+		F32 value = wearable_param->getWeight();
+		mSavedVisualParamMap[id] = value;
+	}
+
+	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
+	syncImages(mTEMap, mSavedTEMap);
+}
+
+void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
+{
+	// Deep copy of src (copies only those tes that are current, filling in defaults where needed)
+	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			te_map_t::const_iterator iter = src.find(te);
+			LLUUID image_id;
+			LLGLTexture *image = NULL;
+			LLLocalTextureObject *lto = NULL;
+			if(iter != src.end())
+			{
+				// there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map.
+				lto = iter->second;
+				image = lto->getImage();
+				image_id = lto->getID();
+			}
+			else
+			{
+				// there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map.
+				image_id = getDefaultTextureImageID((ETextureIndex) te);
+				image = gTextureManagerBridgep->getFetchedTexture( image_id );
+			}
+
+			if( dst.find(te) != dst.end() )
+			{
+				// there's already an entry in the destination map for the texture. Just update its values.
+				dst[te]->setImage(image);
+				dst[te]->setID(image_id);
+			}
+			else
+			{
+				// no entry found in the destination map, we need to create a new Local Texture Object
+				dst[te] = new LLLocalTextureObject(image, image_id);
+			}
+
+			if( lto )
+			{
+				// If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map.
+				dst[te]->setBakedReady(lto->getBakedReady());
+				dst[te]->setDiscard(lto->getDiscard());
+			}
+		}
+	}
+}
+
+void LLWearable::destroyTextures()
+{
+	for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
+	{
+		LLLocalTextureObject *lto = iter->second;
+		delete lto;
+	}
+	mTEMap.clear();
+	for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
+	{
+		LLLocalTextureObject *lto = iter->second;
+		delete lto;
+	}
+	mSavedTEMap.clear();
+}
+
+void LLWearable::addVisualParam(LLVisualParam *param)
+{
+	if( mVisualParamIndexMap[param->getID()] )
+	{
+		delete mVisualParamIndexMap[param->getID()];
+	}
+	param->setIsDummy(FALSE);
+	param->setParamLocation(LOC_WEARABLE);
+	mVisualParamIndexMap[param->getID()] = param;
+	mSavedVisualParamMap[param->getID()] = param->getDefaultWeight();
+}
+
+
+void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake)
+{
+	if( is_in_map(mVisualParamIndexMap, param_index ) )
+	{
+		LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
+		wearable_param->setWeight(value, upload_bake);
+	}
+	else
+	{
+		llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
+	}
+}
+
+F32 LLWearable::getVisualParamWeight(S32 param_index) const
+{
+	if( is_in_map(mVisualParamIndexMap, param_index ) )
+	{
+		const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second;
+		return wearable_param->getWeight();
+	}
+	else
+	{
+		llwarns << "LLWerable::getVisualParam passed invalid parameter index: "  << param_index << " for wearable type: " << this->getName() << llendl;
+	}
+	return (F32)-1.0;
+}
+
+LLVisualParam* LLWearable::getVisualParam(S32 index) const
+{
+	visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index);
+	return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second;
+}
+
+
+void LLWearable::getVisualParams(visual_param_vec_t &list)
+{
+	visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
+	visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
+
+	// add all visual params to the passed-in vector
+	for( ; iter != end; ++iter )
+	{
+		list.push_back(iter->second);
+	}
+}
+
+void LLWearable::animateParams(F32 delta, BOOL upload_bake)
+{
+	for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
+		 iter != mVisualParamIndexMap.end();
+		 ++iter)
+	{
+		LLVisualParam *param = (LLVisualParam*) iter->second;
+		param->animate(delta, upload_bake);
+	}
+}
+
+LLColor4 LLWearable::getClothesColor(S32 te) const
+{
+	LLColor4 color;
+	U32 param_name[3];
+	if( LLAvatarAppearance::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) )
+	{
+		for( U8 index = 0; index < 3; index++ )
+		{
+			color.mV[index] = getVisualParamWeight(param_name[index]);
+		}
+	}
+	return color;
+}
+
+void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake )
+{
+	U32 param_name[3];
+	if( LLAvatarAppearance::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) )
+	{
+		for( U8 index = 0; index < 3; index++ )
+		{
+			setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake);
+		}
+	}
+}
+
+void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
+{
+	if (!avatarp) return;
+
+	// Pull params
+	for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
+	{
+		// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
+		// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
+		if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) )
+		{
+			S32 param_id = param->getID();
+			F32 weight = getVisualParamWeight(param_id);
+
+			avatarp->setVisualParamWeight( param_id, weight, FALSE );
+		}
+	}
+}
+
+
+std::string terse_F32_to_string(F32 f)
+{
+	std::string r = llformat("%.2f", f);
+	S32 len = r.length();
+
+    // "1.20"  -> "1.2"
+    // "24.00" -> "24."
+	while (len > 0 && ('0' == r[len - 1]))
+	{
+		r.erase(len-1, 1);
+		len--;
+	}
+	if ('.' == r[len - 1])
+	{
+		// "24." -> "24"
+		r.erase(len-1, 1);
+	}
+	else if (('-' == r[0]) && ('0' == r[1]))
+	{
+		// "-0.59" -> "-.59"
+		r.erase(1, 1);
+	}
+	else if ('0' == r[0])
+	{
+		// "0.59" -> ".59"
+		r.erase(0, 1);
+	}
+	return r;
+}
+
diff --git a/indra/newview/llwearable.h b/indra/llappearance/llwearable.h
similarity index 68%
rename from indra/newview/llwearable.h
rename to indra/llappearance/llwearable.h
index 3d8c53a755c3a17efe810d10d272b224f0d750f8..6f5a1e14e8ab82ae5e3dec1c1e8b6e24448477a7 100644
--- a/indra/newview/llwearable.h
+++ b/indra/llappearance/llwearable.h
@@ -27,31 +27,25 @@
 #ifndef LL_LLWEARABLE_H
 #define LL_LLWEARABLE_H
 
-#include "lluuid.h"
-#include "llstring.h"
+#include "llavatarappearancedefines.h"
+#include "llextendedstatus.h"
 #include "llpermissions.h"
 #include "llsaleinfo.h"
-#include "llassetstorage.h"
 #include "llwearabletype.h"
-#include "llfile.h"
 #include "lllocaltextureobject.h"
 
-class LLViewerInventoryItem;
+class LLMD5;
 class LLVisualParam;
 class LLTexGlobalColorInfo;
 class LLTexGlobalColor;
+class LLAvatarAppearance;
 
+// Abstract class.
 class LLWearable
 {
-	friend class LLWearableList;
-
 	//--------------------------------------------------------------------
 	// Constructors and destructors
 	//--------------------------------------------------------------------
-private:
-	// Private constructors used by LLWearableList
-	LLWearable(const LLTransactionID& transactionID);
-	LLWearable(const LLAssetID& assetID);
 public:
 	virtual ~LLWearable();
 
@@ -59,11 +53,8 @@ class LLWearable
 	// Accessors
 	//--------------------------------------------------------------------
 public:
-	const LLUUID&				getItemID() const;
-	const LLAssetID&			getAssetID() const { return mAssetID; }
-	const LLTransactionID&		getTransactionID() const { return mTransactionID; }
-	LLWearableType::EType				getType() const	{ return mType; }
-	void						setType(LLWearableType::EType type);
+	LLWearableType::EType		getType() const	{ return mType; }
+	void						setType(LLWearableType::EType type, LLAvatarAppearance *avatarp);
 	const std::string&			getName() const	{ return mName; }
 	void						setName(const std::string& name) { mName = name; }
 	const std::string&			getDescription() const { return mDescription; }
@@ -77,32 +68,26 @@ class LLWearable
 	LLAssetType::EType			getAssetType() const;
 	S32							getDefinitionVersion() const { return mDefinitionVersion; }
 	void						setDefinitionVersion( S32 new_version ) { mDefinitionVersion = new_version; }
+	static S32					getCurrentDefinitionVersion() { return LLWearable::sCurrentDefinitionVersion; }
 
 public:
 	typedef std::vector<LLVisualParam*> visual_param_vec_t;
 
-	BOOL				isDirty() const;
-	BOOL				isOldVersion() const;
-
-	void				writeToAvatar();
-	void				removeFromAvatar( BOOL upload_bake )	{ LLWearable::removeFromAvatar( mType, upload_bake ); }
-	static void			removeFromAvatar( LLWearableType::EType type, BOOL upload_bake ); 
+	virtual void	writeToAvatar(LLAvatarAppearance* avatarp);
 
+	enum EImportResult
+	{
+		FAILURE = 0,
+		SUCCESS,
+		BAD_HEADER
+	};
 	BOOL				exportFile(LLFILE* file) const;
-	BOOL				importFile(LLFILE* file);
-	
-	void				setParamsToDefaults();
-	void				setTexturesToDefaults();
-
-	void				saveNewAsset() const;
-	static void			onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status );
-
-	void				copyDataFrom(const LLWearable* src);
+	EImportResult		importFile(LLFILE* file, LLAvatarAppearance* avatarp );
+	virtual BOOL				exportStream( std::ostream& output_stream ) const;
+	virtual EImportResult		importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
 
 	static void			setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; }
-
-	friend std::ostream& operator<<(std::ostream &s, const LLWearable &w);
-	void				setItemID(const LLUUID& item_id);
+	virtual LLUUID		getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const = 0;
 
 	LLLocalTextureObject* getLocalTextureObject(S32 index);
 	const LLLocalTextureObject* getLocalTextureObject(S32 index) const;
@@ -110,7 +95,6 @@ class LLWearable
 
 	void				setLocalTextureObject(S32 index, LLLocalTextureObject &lto);
 	void				addVisualParam(LLVisualParam *param);
-	void				setVisualParams();
 	void 				setVisualParamWeight(S32 index, F32 value, BOOL upload_bake);
 	F32					getVisualParamWeight(S32 index) const;
 	LLVisualParam*		getVisualParam(S32 index) const;
@@ -120,27 +104,22 @@ class LLWearable
 	LLColor4			getClothesColor(S32 te) const;
 	void 				setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake );
 
-	void				revertValues();
-	void				saveValues();
-	void				pullCrossWearableValues();		
+	virtual void		revertValues();
+	virtual void		saveValues();
 
-	BOOL				isOnTop() const;
+	// Something happened that requires the wearable to be updated (e.g. worn/unworn).
+	virtual void		setUpdated() const = 0;
 
-	// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
-	void				setLabelUpdated() const;
+	// Update the baked texture hash.
+	virtual void		addToBakedTextureHash(LLMD5& hash) const = 0;
 
-	// the wearable was worn. make sure the name of the wearable object matches the LLViewerInventoryItem,
-	// not the wearable asset itself.
-	void				refreshName();
-
-private:
+protected:
 	typedef std::map<S32, LLLocalTextureObject*> te_map_t;
-	typedef std::map<S32, LLVisualParam *>    visual_param_index_map_t;
-
-	void 				createLayers(S32 te);
-	void 				createVisualParams();
 	void				syncImages(te_map_t &src, te_map_t &dst);
-	void				destroyTextures();	
+	void				destroyTextures();
+	void			 	createVisualParams(LLAvatarAppearance *avatarp);
+	void 				createLayers(S32 te, LLAvatarAppearance *avatarp);
+	BOOL				getNextPopulatedLine(std::istream& input_stream, char* buffer, U32 buffer_size);
 
 	static S32			sCurrentDefinitionVersion;	// Depends on the current state of the avatar_lad.xml.
 	S32					mDefinitionVersion;			// Depends on the state of the avatar_lad.xml when this asset was created.
@@ -148,18 +127,16 @@ class LLWearable
 	std::string			mDescription;
 	LLPermissions		mPermissions;
 	LLSaleInfo			mSaleInfo;
-	LLAssetID mAssetID;
-	LLTransactionID		mTransactionID;
 	LLWearableType::EType		mType;
 
 	typedef std::map<S32, F32> param_map_t;
 	param_map_t mSavedVisualParamMap; // last saved version of visual params
 
+	typedef std::map<S32, LLVisualParam *>    visual_param_index_map_t;
 	visual_param_index_map_t mVisualParamIndexMap;
 
 	te_map_t mTEMap;				// maps TE to LocalTextureObject
 	te_map_t mSavedTEMap;			// last saved version of TEMap
-	LLUUID				mItemID;  // ID of the inventory item in the agent's inventory	
 };
 
 #endif  // LL_LLWEARABLE_H
diff --git a/indra/llappearance/llwearabledata.cpp b/indra/llappearance/llwearabledata.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..68fdcca78214dc7030de849e35e9280838cbd1c2
--- /dev/null
+++ b/indra/llappearance/llwearabledata.cpp
@@ -0,0 +1,360 @@
+/** 
+ * @file llwearabledata.cpp
+ * @brief LLWearableData class implementation
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llwearabledata.h"
+
+#include "llavatarappearance.h"
+#include "llavatarappearancedefines.h"
+#include "lldriverparam.h"
+#include "llmd5.h"
+
+LLWearableData::LLWearableData() :
+	mAvatarAppearance(NULL)
+{
+}
+
+// virtual
+LLWearableData::~LLWearableData()
+{
+}
+
+using namespace LLAvatarAppearanceDefines;
+
+LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index)
+{
+	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		return NULL;
+	}
+	wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	if (index>=wearable_vec.size())
+	{
+		return NULL;
+	}
+	else
+	{
+		return wearable_vec[index];
+	}
+}
+
+void LLWearableData::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable)
+{
+	LLWearable *old_wearable = getWearable(type,index);
+	if (!old_wearable)
+	{
+		pushWearable(type,wearable);
+		return;
+	}
+	
+	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		llwarns << "invalid type, type " << type << " index " << index << llendl; 
+		return;
+	}
+	wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	if (index>=wearable_vec.size())
+	{
+		llwarns << "invalid index, type " << type << " index " << index << llendl; 
+	}
+	else
+	{
+		wearable_vec[index] = wearable;
+		old_wearable->setUpdated();
+		const BOOL removed = FALSE;
+		wearableUpdated(wearable, removed);
+	}
+}
+
+U32 LLWearableData::pushWearable(const LLWearableType::EType type, 
+								   LLWearable *wearable,
+								   bool trigger_updated /* = true */)
+{
+	if (wearable == NULL)
+	{
+		// no null wearables please!
+		llwarns << "Null wearable sent for type " << type << llendl;
+		return MAX_CLOTHING_PER_TYPE;
+	}
+	if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
+	{
+		mWearableDatas[type].push_back(wearable);
+		if (trigger_updated)
+		{
+			const BOOL removed = FALSE;
+			wearableUpdated(wearable, removed);
+		}
+		return mWearableDatas[type].size()-1;
+	}
+	return MAX_CLOTHING_PER_TYPE;
+}
+
+// virtual
+void LLWearableData::wearableUpdated(LLWearable *wearable, BOOL removed)
+{
+	wearable->setUpdated();
+	// FIXME DRANO avoid updating params via wearables when rendering server-baked appearance.
+#if 0
+	if (mAvatarAppearance->isUsingServerBakes() && !mAvatarAppearance->isUsingLocalAppearance())
+	{
+		return;
+	}
+#endif
+	if (!removed)
+	{
+		pullCrossWearableValues(wearable->getType());
+	}
+}
+
+void LLWearableData::popWearable(LLWearable *wearable)
+{
+	if (wearable == NULL)
+	{
+		// nothing to do here. move along.
+		return;
+	}
+
+	U32 index = getWearableIndex(wearable);
+	const LLWearableType::EType type = wearable->getType();
+
+	if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type))
+	{
+		popWearable(type, index);
+	}
+}
+
+void LLWearableData::popWearable(const LLWearableType::EType type, U32 index)
+{
+	LLWearable *wearable = getWearable(type, index);
+	if (wearable)
+	{
+		mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
+		const BOOL removed = TRUE;
+		wearableUpdated(wearable, removed);
+	}
+}
+
+void LLWearableData::clearWearableType(const LLWearableType::EType type)
+{
+	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		return;
+	}
+	wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	wearable_vec.clear();
+}
+
+bool LLWearableData::swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b)
+{
+	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		return false;
+	}
+
+	wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	if (0 > index_a || index_a >= wearable_vec.size()) return false;
+	if (0 > index_b || index_b >= wearable_vec.size()) return false;
+
+	LLWearable* wearable = wearable_vec[index_a];
+	wearable_vec[index_a] = wearable_vec[index_b];
+	wearable_vec[index_b] = wearable;
+	return true;
+}
+
+void LLWearableData::pullCrossWearableValues(const LLWearableType::EType type)
+{
+	llassert(mAvatarAppearance);
+	// scan through all of the avatar's visual parameters
+	for (LLViewerVisualParam* param = (LLViewerVisualParam*) mAvatarAppearance->getFirstVisualParam(); 
+		 param;
+		 param = (LLViewerVisualParam*) mAvatarAppearance->getNextVisualParam())
+	{
+		if( param )
+		{
+			LLDriverParam *driver_param = dynamic_cast<LLDriverParam*>(param);
+			if(driver_param)
+			{
+				// parameter is a driver parameter, have it update its cross-driven params
+				driver_param->updateCrossDrivenParams(type);
+			}
+		}
+	}
+}
+
+
+U32	LLWearableData::getWearableIndex(const LLWearable *wearable) const
+{
+	if (wearable == NULL)
+	{
+		return MAX_CLOTHING_PER_TYPE;
+	}
+
+	const LLWearableType::EType type = wearable->getType();
+	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		llwarns << "tried to get wearable index with an invalid type!" << llendl;
+		return MAX_CLOTHING_PER_TYPE;
+	}
+	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	for(U32 index = 0; index < wearable_vec.size(); index++)
+	{
+		if (wearable_vec[index] == wearable)
+		{
+			return index;
+		}
+	}
+
+	return MAX_CLOTHING_PER_TYPE;
+}
+
+BOOL LLWearableData::isOnTop(LLWearable* wearable) const
+{
+	if (!wearable) return FALSE;
+	const LLWearableType::EType type = wearable->getType();
+	return ( getTopWearable(type) == wearable );
+}
+
+const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) const
+{
+	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		return NULL;
+	}
+	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	if (index>=wearable_vec.size())
+	{
+		return NULL;
+	}
+	else
+	{
+		return wearable_vec[index];
+	}
+}
+
+LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type)
+{
+	U32 count = getWearableCount(type);
+	if ( count == 0)
+	{
+		return NULL;
+	}
+
+	return getWearable(type, count-1);
+}
+
+const LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) const
+{
+	U32 count = getWearableCount(type);
+	if ( count == 0)
+	{
+		return NULL;
+	}
+
+	return getWearable(type, count-1);
+}
+
+LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type)
+{
+	if (getWearableCount(type) == 0)
+	{
+		return NULL;
+	}
+
+	return getWearable(type, 0);
+}
+
+const LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) const
+{
+	if (getWearableCount(type) == 0)
+	{
+		return NULL;
+	}
+
+	return getWearable(type, 0);
+}
+
+U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const
+{
+	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		return 0;
+	}
+	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	return wearable_vec.size();
+}
+
+U32 LLWearableData::getWearableCount(const U32 tex_index) const
+{
+	const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)tex_index);
+	return getWearableCount(wearable_type);
+}
+
+LLUUID LLWearableData::computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index,
+												 BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
+{
+	LLUUID hash_id;
+	bool hash_computed = false;
+	LLMD5 hash;
+	const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index);
+
+	for (U8 i=0; i < baked_dict->mWearables.size(); i++)
+	{
+		const LLWearableType::EType baked_type = baked_dict->mWearables[i];
+		const U32 num_wearables = getWearableCount(baked_type);
+		for (U32 index = 0; index < num_wearables; ++index)
+		{
+			const LLWearable* wearable = getWearable(baked_type,index);
+			if (wearable)
+			{
+				wearable->addToBakedTextureHash(hash);
+				hash_computed = true;
+			}
+		}
+	}
+	if (hash_computed)
+	{
+		hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
+
+		if (!generate_valid_hash)
+		{
+			invalidateBakedTextureHash(hash);
+		}
+		hash.finalize();
+		hash.raw_digest(hash_id.mData);
+	}
+
+	return hash_id;
+}
+
+
diff --git a/indra/llappearance/llwearabledata.h b/indra/llappearance/llwearabledata.h
new file mode 100644
index 0000000000000000000000000000000000000000..03bd179f258812a1fdac747fd5404f41f7d2cd2a
--- /dev/null
+++ b/indra/llappearance/llwearabledata.h
@@ -0,0 +1,109 @@
+/** 
+ * @file llwearabledata.h
+ * @brief LLWearableData class header file
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_WEARABLEDATA_H
+#define LL_WEARABLEDATA_H
+
+#include "llavatarappearancedefines.h"
+#include "llwearable.h"
+#include "llerror.h"
+
+class LLAvatarAppearance;
+
+class LLWearableData
+{
+	// *TODO: Figure out why this is causing compile error.
+	//LOG_CLASS(LLWearableData);
+
+	//--------------------------------------------------------------------
+	// Constructors / destructors / Initializers
+	//--------------------------------------------------------------------
+public:
+	LLWearableData();
+	virtual ~LLWearableData();
+
+	void setAvatarAppearance(LLAvatarAppearance* appearance) { mAvatarAppearance = appearance; }
+
+protected:
+	//--------------------------------------------------------------------
+	// Accessors
+	//--------------------------------------------------------------------
+public:
+	LLWearable*			getWearable(const LLWearableType::EType type, U32 index /*= 0*/); 
+	const LLWearable* 	getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
+	LLWearable*			getTopWearable(const LLWearableType::EType type);
+	const LLWearable*	getTopWearable(const LLWearableType::EType type) const;
+	LLWearable*			getBottomWearable(const LLWearableType::EType type);
+	const LLWearable*	getBottomWearable(const LLWearableType::EType type) const;
+	U32				getWearableCount(const LLWearableType::EType type) const;
+	U32				getWearableCount(const U32 tex_index) const;
+	U32				getWearableIndex(const LLWearable *wearable) const;
+
+	BOOL			isOnTop(LLWearable* wearable) const;
+
+	static const U32 MAX_CLOTHING_PER_TYPE = 5; 
+
+	//--------------------------------------------------------------------
+	// Setters
+	//--------------------------------------------------------------------
+protected:
+	// Low-level data structure setter - public access is via setWearableItem, etc.
+	void 			setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable);
+	U32 			pushWearable(const LLWearableType::EType type, LLWearable *wearable, 
+								 bool trigger_updated = true);
+	virtual void	wearableUpdated(LLWearable *wearable, BOOL removed);
+	void 			popWearable(LLWearable *wearable);
+	void			popWearable(const LLWearableType::EType type, U32 index);
+	void			clearWearableType(const LLWearableType::EType type);
+	bool			swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b);
+
+private:
+	void			pullCrossWearableValues(const LLWearableType::EType type);
+
+	//--------------------------------------------------------------------
+	// Server Communication
+	//--------------------------------------------------------------------
+public:
+	LLUUID			computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index,
+											BOOL generate_valid_hash = TRUE);
+protected:
+	virtual void	invalidateBakedTextureHash(LLMD5& hash) const {}
+
+	//--------------------------------------------------------------------
+	// Member variables
+	//--------------------------------------------------------------------
+protected:
+	LLAvatarAppearance* mAvatarAppearance;
+	typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
+	typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t;	// wearable "categories" arranged by wearable type
+	wearableentry_map_t mWearableDatas;
+
+};
+
+
+
+#endif // LL_WEARABLEDATA_H
+
diff --git a/indra/newview/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp
similarity index 83%
rename from indra/newview/llwearabletype.cpp
rename to indra/llappearance/llwearabletype.cpp
index c090ab5c3dedeef17ec052b3c85eb810a54204f6..618e2a1941bc8768765a0d91c61159bf87fd0e02 100644
--- a/indra/newview/llwearabletype.cpp
+++ b/indra/llappearance/llwearabletype.cpp
@@ -24,23 +24,35 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 #include "llwearabletype.h"
-#include "llinventoryfunctions.h"
-#include "lltrans.h"
+#include "llinventorytype.h"
+
+static LLTranslationBridge* sTrans = NULL;
+
+// static
+void LLWearableType::initClass(LLTranslationBridge* trans)
+{
+	sTrans = trans;
+}
+
+void LLWearableType::cleanupClass()
+{
+	delete sTrans;
+}
 
 struct WearableEntry : public LLDictionaryEntry
 {
 	WearableEntry(const std::string &name,
 				  const std::string& default_new_name,
 				  LLAssetType::EType assetType,
-				  LLInventoryIcon::EIconName iconName,
+				  LLInventoryType::EIconName iconName,
 				  BOOL disable_camera_switch = FALSE,
 				  BOOL allow_multiwear = TRUE) :
 		LLDictionaryEntry(name),
 		mAssetType(assetType),
 		mDefaultNewName(default_new_name),
-		mLabel(LLTrans::getString(name)),
+		mLabel(sTrans->getString(name)),
 		mIconName(iconName),
 		mDisableCameraSwitch(disable_camera_switch),
 		mAllowMultiwear(allow_multiwear)
@@ -50,7 +62,7 @@ struct WearableEntry : public LLDictionaryEntry
 	const LLAssetType::EType mAssetType;
 	const std::string mLabel;
 	const std::string mDefaultNewName; //keep mLabel for backward compatibility
-	LLInventoryIcon::EIconName mIconName;
+	LLInventoryType::EIconName mIconName;
 	BOOL mDisableCameraSwitch;
 	BOOL mAllowMultiwear;
 };
@@ -64,26 +76,26 @@ class LLWearableDictionary : public LLSingleton<LLWearableDictionary>,
 
 LLWearableDictionary::LLWearableDictionary()
 {
-	addEntry(LLWearableType::WT_SHAPE,        new WearableEntry("shape",       "New Shape",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_SHAPE, FALSE, FALSE));
-	addEntry(LLWearableType::WT_SKIN,         new WearableEntry("skin",        "New Skin",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_SKIN, FALSE, FALSE));
-	addEntry(LLWearableType::WT_HAIR,         new WearableEntry("hair",        "New Hair",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_HAIR, FALSE, FALSE));
-	addEntry(LLWearableType::WT_EYES,         new WearableEntry("eyes",        "New Eyes",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_EYES, FALSE, FALSE));
-	addEntry(LLWearableType::WT_SHIRT,        new WearableEntry("shirt",       "New Shirt",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE));
-	addEntry(LLWearableType::WT_PANTS,        new WearableEntry("pants",       "New Pants",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_PANTS, FALSE, TRUE));
-	addEntry(LLWearableType::WT_SHOES,        new WearableEntry("shoes",       "New Shoes",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SHOES, FALSE, TRUE));
-	addEntry(LLWearableType::WT_SOCKS,        new WearableEntry("socks",       "New Socks",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE));
-	addEntry(LLWearableType::WT_JACKET,       new WearableEntry("jacket",      "New Jacket",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_JACKET, FALSE, TRUE));
-	addEntry(LLWearableType::WT_GLOVES,       new WearableEntry("gloves",      "New Gloves",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE));
-	addEntry(LLWearableType::WT_UNDERSHIRT,   new WearableEntry("undershirt",  "New Undershirt",	LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE));
-	addEntry(LLWearableType::WT_UNDERPANTS,   new WearableEntry("underpants",  "New Underpants",	LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE));
-	addEntry(LLWearableType::WT_SKIRT,        new WearableEntry("skirt",       "New Skirt",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE));
-	addEntry(LLWearableType::WT_ALPHA,        new WearableEntry("alpha",       "New Alpha",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
-	addEntry(LLWearableType::WT_TATTOO,       new WearableEntry("tattoo",      "New Tattoo",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
-
-	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
-
-	addEntry(LLWearableType::WT_INVALID,      new WearableEntry("invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE));
-	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry("none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE));
+	addEntry(LLWearableType::WT_SHAPE,        new WearableEntry("shape",       "New Shape",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_SHAPE, FALSE, FALSE));
+	addEntry(LLWearableType::WT_SKIN,         new WearableEntry("skin",        "New Skin",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_SKIN, FALSE, FALSE));
+	addEntry(LLWearableType::WT_HAIR,         new WearableEntry("hair",        "New Hair",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_HAIR, FALSE, FALSE));
+	addEntry(LLWearableType::WT_EYES,         new WearableEntry("eyes",        "New Eyes",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_EYES, FALSE, FALSE));
+	addEntry(LLWearableType::WT_SHIRT,        new WearableEntry("shirt",       "New Shirt",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE));
+	addEntry(LLWearableType::WT_PANTS,        new WearableEntry("pants",       "New Pants",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PANTS, FALSE, TRUE));
+	addEntry(LLWearableType::WT_SHOES,        new WearableEntry("shoes",       "New Shoes",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SHOES, FALSE, TRUE));
+	addEntry(LLWearableType::WT_SOCKS,        new WearableEntry("socks",       "New Socks",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE));
+	addEntry(LLWearableType::WT_JACKET,       new WearableEntry("jacket",      "New Jacket",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_JACKET, FALSE, TRUE));
+	addEntry(LLWearableType::WT_GLOVES,       new WearableEntry("gloves",      "New Gloves",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE));
+	addEntry(LLWearableType::WT_UNDERSHIRT,   new WearableEntry("undershirt",  "New Undershirt",	LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE));
+	addEntry(LLWearableType::WT_UNDERPANTS,   new WearableEntry("underpants",  "New Underpants",	LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE));
+	addEntry(LLWearableType::WT_SKIRT,        new WearableEntry("skirt",       "New Skirt",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE));
+	addEntry(LLWearableType::WT_ALPHA,        new WearableEntry("alpha",       "New Alpha",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
+	addEntry(LLWearableType::WT_TATTOO,       new WearableEntry("tattoo",      "New Tattoo",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
+
+	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
+
+	addEntry(LLWearableType::WT_INVALID,      new WearableEntry("invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
+	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry("none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
 }
 
 // static
@@ -131,7 +143,7 @@ LLAssetType::EType LLWearableType::getAssetType(LLWearableType::EType type)
 }
 
 // static 
-LLInventoryIcon::EIconName LLWearableType::getIconName(LLWearableType::EType type)
+LLInventoryType::EIconName LLWearableType::getIconName(LLWearableType::EType type)
 {
 	const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
 	const WearableEntry *entry = dict->lookup(type);
diff --git a/indra/newview/llwearabletype.h b/indra/llappearance/llwearabletype.h
similarity index 85%
rename from indra/newview/llwearabletype.h
rename to indra/llappearance/llwearabletype.h
index d633b4807ece113c630fca0250318a5d86a338fe..e51e6731d38880e82896fd9b4d8c3da4f3650e37 100644
--- a/indra/newview/llwearabletype.h
+++ b/indra/llappearance/llwearabletype.h
@@ -29,9 +29,16 @@
 
 #include "llassettype.h"
 #include "lldictionary.h"
-#include "llinventoryicon.h"
+#include "llinventorytype.h"
 #include "llsingleton.h"
 
+class LLTranslationBridge
+{
+public:
+	virtual std::string getString(const std::string &xml_desc) = 0;
+};
+
+
 class LLWearableType
 {
 public: 
@@ -59,12 +66,15 @@ class LLWearableType
 		WT_NONE		  = -1,
 	};
 
+	static void			initClass(LLTranslationBridge* trans); // initializes static members
+	static void			cleanupClass(); // initializes static members
+
 	static const std::string& 			getTypeName(EType type);
 	static const std::string& 			getTypeDefaultNewName(EType type);
 	static const std::string& 			getTypeLabel(EType type);
 	static LLAssetType::EType 			getAssetType(EType type);
 	static EType 						typeNameToType(const std::string& type_name);
-	static LLInventoryIcon::EIconName 	getIconName(EType type);
+	static LLInventoryType::EIconName 	getIconName(EType type);
 	static BOOL 						getDisableCameraSwitch(EType type);
 	static BOOL 						getAllowMultiwear(EType type);
 
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt
index 632e5d46e3338b45d644191c5a5eb0bc94f68b86..24d25311065c5db5772b21019d52390bd366a6cc 100644
--- a/indra/llaudio/CMakeLists.txt
+++ b/indra/llaudio/CMakeLists.txt
@@ -88,6 +88,10 @@ list(APPEND llaudio_SOURCE_FILES ${llaudio_HEADER_FILES})
 add_library (llaudio ${llaudio_SOURCE_FILES})
 target_link_libraries(
     llaudio
+    ${LLCOMMON_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLMESSAGE_LIBRARIES}
+    ${LLVFS_LIBRARIES}
     ${VORBISENC_LIBRARIES}
     ${VORBISFILE_LIBRARIES}
     ${VORBIS_LIBRARIES}
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt
index a1712699eb25266c863aeb6234336bbb983b58d5..2573417b260536371d7a93c87e459514b597db37 100644
--- a/indra/llcharacter/CMakeLists.txt
+++ b/indra/llcharacter/CMakeLists.txt
@@ -16,6 +16,10 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llcharacter_SOURCE_FILES
     llanimationstates.cpp
@@ -76,6 +80,15 @@ list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES})
 
 add_library (llcharacter ${llcharacter_SOURCE_FILES})
 
+target_link_libraries(
+    llcharacter
+    ${LLCOMMON_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLMESSAGE_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    )
+
 
 # Add tests
 if (LL_TESTS)
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index 0a6a8f9fa6b4a095d404085ed4900264c0aa32d1..85cf1cd3f5eac08db7e89efd7d25d90fe313a227 100644
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -286,7 +286,7 @@ void LLCharacter::removeAnimationData(std::string name)
 //-----------------------------------------------------------------------------
 // setVisualParamWeight()
 //-----------------------------------------------------------------------------
-BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL upload_bake)
+BOOL LLCharacter::setVisualParamWeight(const LLVisualParam* which_param, F32 weight, BOOL upload_bake)
 {
 	S32 index = which_param->getID();
 	visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index);
diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h
index 3ebb2bffb04ec47b8b5a44d856fbd03f0b2452a4..5740dbce77274089b2a4a0d60ea9c6b8c57c50bd 100644
--- a/indra/llcharacter/llcharacter.h
+++ b/indra/llcharacter/llcharacter.h
@@ -93,13 +93,6 @@ class LLCharacter
 	// get the height & normal of the ground under a point
 	virtual void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm) = 0;
 
-	// allocate an array of joints for the character skeleton
-	// this must be overloaded to support joint subclasses,
-	// and is called implicitly from buildSkeleton().
-	// Note this must handle reallocation as it will be called
-	// each time buildSkeleton() is called.
-	virtual BOOL allocateCharacterJoints( U32 num ) = 0;
-
 	// skeleton joint accessor to support joint subclasses
 	virtual LLJoint *getCharacterJoint( U32 i ) = 0;
 
@@ -197,7 +190,7 @@ class LLCharacter
 	void addVisualParam(LLVisualParam *param);
 	void addSharedVisualParam(LLVisualParam *param);
 
-	virtual BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
+	virtual BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
 	virtual BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );
 	virtual BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );
 
diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp
index 19907933cb4c5cab89f20eb329be4f262351182e..09a7c11a22d972a007c22407aac3a2802463a3eb 100644
--- a/indra/llcharacter/lljoint.cpp
+++ b/indra/llcharacter/lljoint.cpp
@@ -40,7 +40,9 @@ S32 LLJoint::sNumTouches = 0;
 // LLJoint()
 // Class Constructor
 //-----------------------------------------------------------------------------
-LLJoint::LLJoint()
+
+
+void LLJoint::init()
 {
 	mName = "unnamed";
 	mParent = NULL;
@@ -48,7 +50,20 @@ LLJoint::LLJoint()
 	mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
 	mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
 	mUpdateXform = TRUE;
-	mJointNum = -1;
+}
+
+LLJoint::LLJoint() :
+	mJointNum(-1)
+{
+	init();
+	touch();
+	mResetAfterRestoreOldXform = false;
+}
+
+LLJoint::LLJoint(S32 joint_num) :
+	mJointNum(joint_num)
+{
+	init();
 	touch();
 	mResetAfterRestoreOldXform = false;
 }
@@ -58,15 +73,12 @@ LLJoint::LLJoint()
 // LLJoint()
 // Class Constructor
 //-----------------------------------------------------------------------------
-LLJoint::LLJoint(const std::string &name, LLJoint *parent)
+LLJoint::LLJoint(const std::string &name, LLJoint *parent) :
+	mJointNum(0)
 {
-	mName = "unnamed";
-	mParent = NULL;
-	mXform.setScaleChildOffset(TRUE);
-	mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
-	mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
+	init();
 	mUpdateXform = FALSE;
-	mJointNum = 0;
+	// *TODO: mResetAfterRestoreOldXform is not initialized!!!
 
 	setName(name);
 	if (parent)
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index dc3c58cf645204c6667dfe62d403ba41e4a0c8b3..2b1e2005c62022910497ea8bbd8dbbd6ce7f8c31 100644
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -105,10 +105,15 @@ class LLJoint
 
 public:
 	LLJoint();
+	LLJoint(S32 joint_num);
+	// *TODO: Only used for LLVOAvatarSelf::mScreenp.  *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
 	LLJoint( const std::string &name, LLJoint *parent=NULL );
-
 	virtual ~LLJoint();
 
+private:
+	void init();
+
+public:
 	// set name and parent
 	void setup( const std::string &name, LLJoint *parent=NULL );
 
@@ -178,7 +183,6 @@ class LLJoint
 	virtual BOOL isAnimatable() const { return TRUE; }
 
 	S32 getJointNum() const { return mJointNum; }
-	void setJointNum(S32 joint_num) { mJointNum = joint_num; }
 	
 	void restoreOldXform( void );
 	void restoreToDefaultXform( void );
diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp
index 809b312abe29241a0c7b1153a57792f8d234d5c2..f7cb0f76b717f9a83b42d91d96b64219b527a9ff 100644
--- a/indra/llcharacter/llvisualparam.cpp
+++ b/indra/llcharacter/llvisualparam.cpp
@@ -168,7 +168,8 @@ LLVisualParam::LLVisualParam()
 	mIsAnimating( FALSE ),
 	mID( -1 ),
 	mInfo( 0 ),
-	mIsDummy(FALSE)
+	mIsDummy(FALSE),
+	mParamLocation(LOC_UNKNOWN)
 {
 }
 
@@ -250,6 +251,7 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL upload_bake)
 	if (mIsDummy)
 	{
 		setWeight(target_value, upload_bake);
+		mTargetWeight = mCurWeight;
 		return;
 	}
 
@@ -319,3 +321,32 @@ void LLVisualParam::resetDrivenParams()
 	// nothing to do for non-driver parameters
 	return;
 }
+
+const std::string param_location_name(const EParamLocation& loc)
+{
+	switch (loc)
+	{
+		case LOC_UNKNOWN: return "unknown";
+		case LOC_AV_SELF: return "self";
+		case LOC_AV_OTHER: return "other";
+		case LOC_WEARABLE: return "wearable";
+		default: return "error";
+	}
+}
+
+void LLVisualParam::setParamLocation(EParamLocation loc)
+{
+	if (mParamLocation == LOC_UNKNOWN || loc == LOC_UNKNOWN)
+	{
+		mParamLocation = loc;
+	}
+	else if (mParamLocation == loc)
+	{
+		// no action
+	}
+	else
+	{
+		lldebugs << "param location is already " << mParamLocation << ", not slamming to " << loc << llendl;
+	}
+}
+
diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h
index 281fb147810203bcb09f412bc5c3d23501c3056e..60ea7a369a8aecfc6c0a1c96a9d8b32c33b7eec7 100644
--- a/indra/llcharacter/llvisualparam.h
+++ b/indra/llcharacter/llvisualparam.h
@@ -50,6 +50,16 @@ enum EVisualParamGroup
 	NUM_VISUAL_PARAM_GROUPS
 };
 
+enum EParamLocation
+{
+	LOC_UNKNOWN,
+	LOC_AV_SELF,
+	LOC_AV_OTHER,
+	LOC_WEARABLE
+};
+
+const std::string param_location_name(const EParamLocation& loc);
+
 const S32 MAX_TRANSMITTED_VISUAL_PARAMS = 255;
 
 //-----------------------------------------------------------------------------
@@ -150,6 +160,9 @@ class LLVisualParam
 
 	void					setIsDummy(BOOL is_dummy) { mIsDummy = is_dummy; }
 
+	void					setParamLocation(EParamLocation loc);
+	EParamLocation			getParamLocation() const { return mParamLocation; }
+
 protected:
 	F32					mCurWeight;			// current weight
 	F32					mLastWeight;		// last weight
@@ -161,6 +174,7 @@ class LLVisualParam
 
 	S32					mID;				// id for storing weight/morphtarget compares compactly
 	LLVisualParamInfo	*mInfo;
+	EParamLocation		mParamLocation;		// where does this visual param live?
 } LL_ALIGN_POSTFIX(16);
 
 #endif // LL_LLVisualParam_H
diff --git a/indra/llcharacter/tests/lljoint_test.cpp b/indra/llcharacter/tests/lljoint_test.cpp
index e92aa832d66f820c46524920d3b1db27b6919432..da151808f21c660f6e57c922d848af356f4889c8 100644
--- a/indra/llcharacter/tests/lljoint_test.cpp
+++ b/indra/llcharacter/tests/lljoint_test.cpp
@@ -150,11 +150,11 @@ namespace tut
 	template<> template<>
 	void lljoint_object::test<11>()
 	{
-		LLJoint lljoint("parent");
 		S32 joint_num = 12;
-		lljoint.setJointNum(joint_num);
+		LLJoint lljoint(joint_num);
+		lljoint.setName("parent");
 		S32 jointNum = 	lljoint.getJointNum();
-		ensure("setJointNum()/getJointNum failed ", (jointNum == joint_num));
+		ensure("getJointNum failed ", (jointNum == joint_num));
 	}
 
 	template<> template<>
diff --git a/indra/llcommon/imageids.cpp b/indra/llcommon/imageids.cpp
index fe11465221075cd82ee66ae9cee50a46f1944665..7d647e5c364f4dae5a76bc817c50e2f1c48d699c 100644
--- a/indra/llcommon/imageids.cpp
+++ b/indra/llcommon/imageids.cpp
@@ -68,3 +68,6 @@ const LLUUID TERRAIN_MOUNTAIN_DETAIL	("303cd381-8560-7579-23f1-f0a880799740"); /
 const LLUUID TERRAIN_ROCK_DETAIL		("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER
 
 const LLUUID DEFAULT_WATER_NORMAL		("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER
+
+const LLUUID IMG_CHECKERBOARD_RGBA     ("2585a0f3-4163-6dd1-0f34-ad48cb909e25"); // dataserver
+
diff --git a/indra/llcommon/imageids.h b/indra/llcommon/imageids.h
index e0c2683fdc33542a896a95559d5dafa10ad7c42c..18c8ecb0743765b06857558504cdd1bb16722376 100644
--- a/indra/llcommon/imageids.h
+++ b/indra/llcommon/imageids.h
@@ -66,4 +66,5 @@ LL_COMMON_API extern const LLUUID TERRAIN_ROCK_DETAIL;
 
 LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL;
 
+LL_COMMON_API extern const LLUUID IMG_CHECKERBOARD_RGBA;
 #endif
diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp
index 95ecce509bbd33e475594f44baf64a97d5852b00..642bd82e90947978b33eacbe8eb884d330f8b14c 100644
--- a/indra/llcommon/llavatarname.cpp
+++ b/indra/llcommon/llavatarname.cpp
@@ -178,6 +178,21 @@ std::string LLAvatarName::getCompleteName() const
 	return name;
 }
 
+std::string LLAvatarName::getLegacyName() const
+{
+	if (mLegacyFirstName.empty() && mLegacyLastName.empty()) // display names disabled?
+	{
+		return mDisplayName;
+	}
+
+	std::string name;
+	name.reserve( mLegacyFirstName.size() + 1 + mLegacyLastName.size() );
+	name = mLegacyFirstName;
+	name += " ";
+	name += mLegacyLastName;
+	return name;
+}
+
 std::string LLAvatarName::getDisplayName() const
 {
 	if (sUseDisplayNames)
diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h
index 4827353018ef15b0cda7974ed5c5bfd5c1eab926..7542a8dece0918da062061d0b10d1441a3198a1d 100644
--- a/indra/llcommon/llavatarname.h
+++ b/indra/llcommon/llavatarname.h
@@ -63,6 +63,11 @@ class LL_COMMON_API LLAvatarName
 	// For normal names, returns "James Linden (james.linden)"
 	// When display names are disabled returns just "James Linden"
 	std::string getCompleteName() const;
+
+	// Returns "James Linden" or "bobsmith123 Resident" for backwards
+	// compatibility with systems like voice and muting
+	// *TODO: Eliminate this in favor of username only
+	std::string getLegacyName() const;
 	
 	// "José Sanchez" or "James Linden", UTF-8 encoded Unicode
 	// Takes the display name preference into account. This is truly the name that should 
diff --git a/indra/llcommon/lldictionary.h b/indra/llcommon/lldictionary.h
index bc3bc3e74ac1cca5601a425a53891175c3e18555..c752859a3661f1116f8bc41ec43a36282dfc40ad 100644
--- a/indra/llcommon/lldictionary.h
+++ b/indra/llcommon/lldictionary.h
@@ -30,6 +30,8 @@
 #include <map>
 #include <string>
 
+#include "llerror.h"
+
 struct LL_COMMON_API LLDictionaryEntry
 {
 	LLDictionaryEntry(const std::string &name);
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 6970c290924e045eb8296f398028763b9fc71a68..9b15804e97b65998f8457a2e0f9625ae3b8edbe4 100644
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -561,6 +561,12 @@ std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren()
 	return mChildren;
 }
 
+// static
+LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer()
+{
+        return *NamedTimerFactory::instance().getRootTimer();
+}
+
 //static
 void LLFastTimer::nextFrame()
 {
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index e42e549df58c6579de25f0f271a1225da74a93fd..81c4b78775574c931f8f7cb28bfef12b8725926b 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -91,6 +91,8 @@ class LL_COMMON_API LLFastTimer
 		U32 getHistoricalCount(S32 history_index = 0) const;
 		U32 getHistoricalCalls(S32 history_index = 0) const;
 
+		static NamedTimer& getRootNamedTimer();
+
 		void setFrameState(FrameState* state) { mFrameState = state; state->setNamedTimer(this); }
 		FrameState& getFrameState() const;
 
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index c51d042a3d312d908d5c8b56cd47341ee43dad51..bc615ed39ec593de0cda0d2bd3caa1639d7dad06 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -56,6 +56,8 @@ std::string strerr(int errn)
 	return buffer;
 }
 
+typedef std::basic_ios<char,std::char_traits < char > > _Myios;
+
 #else
 // On Posix we want to call strerror_r(), but alarmingly, there are two
 // different variants. The one that returns int always populates the passed
@@ -324,9 +326,10 @@ const char *LLFile::tmpdir()
 
 /***************** Modified file stream created to overcome the incorrect behaviour of posix fopen in windows *******************/
 
-#if USE_LLFILESTREAMS
+#if LL_WINDOWS
 
-LLFILE *	LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,int)	// protection currently unused
+LLFILE *	LLFile::_Fiopen(const std::string& filename, 
+		std::ios::openmode mode)
 {	// open a file
 	static const char *mods[] =
 	{	// fopen mode strings corresponding to valid[i]
@@ -385,117 +388,681 @@ LLFILE *	LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,in
 	return (0);
 }
 
-/************** input file stream ********************************/
+#endif /* LL_WINDOWS */
 
-void llifstream::close()
-{	// close the C stream
-	if (_Filebuffer && _Filebuffer->close() == 0)
+/************** llstdio file buffer ********************************/
+
+
+//llstdio_filebuf* llstdio_filebuf::open(const char *_Filename,
+//	ios_base::openmode _Mode)
+//{
+//#if LL_WINDOWS
+//	_Filet *_File;
+//	if (is_open() || (_File = LLFILE::_Fiopen(_Filename, _Mode)) == 0)
+//		return (0);	// open failed
+//
+//	_Init(_File, _Openfl);
+//	_Initcvt(&_USE(_Mysb::getloc(), _Cvt));
+//	return (this);	// open succeeded
+//#else
+//	std::filebuf* _file = std::filebuf::open(_Filename, _Mode);
+//	if (NULL == _file) return NULL;
+//	return this;
+//#endif
+//}
+
+
+// *TODO: Seek the underlying c stream for better cross-platform compatibility?
+#if !LL_WINDOWS
+llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __c)
+{
+	int_type __ret = traits_type::eof();
+	const bool __testeof = traits_type::eq_int_type(__c, __ret);
+	const bool __testout = _M_mode & ios_base::out;
+	if (__testout && !_M_reading)
 	{
-		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
+		if (this->pbase() < this->pptr())
+		{
+			// If appropriate, append the overflow char.
+			if (!__testeof)
+			{
+				*this->pptr() = traits_type::to_char_type(__c);
+				this->pbump(1);
+			}
+
+			// Convert pending sequence to external representation,
+			// and output.
+			if (_convert_to_external(this->pbase(),
+					 this->pptr() - this->pbase()))
+			{
+				_M_set_buffer(0);
+				__ret = traits_type::not_eof(__c);
+			}
+		}
+		else if (_M_buf_size > 1)
+		{
+			// Overflow in 'uncommitted' mode: set _M_writing, set
+			// the buffer to the initial 'write' mode, and put __c
+			// into the buffer.
+			_M_set_buffer(0);
+			_M_writing = true;
+			if (!__testeof)
+			{
+				*this->pptr() = traits_type::to_char_type(__c);
+				this->pbump(1);
+			}
+			__ret = traits_type::not_eof(__c);
+		}
+		else
+		{
+			// Unbuffered.
+			char_type __conv = traits_type::to_char_type(__c);
+			if (__testeof || _convert_to_external(&__conv, 1))
+			{
+				_M_writing = true;
+				__ret = traits_type::not_eof(__c);
+			}
+		}
 	}
+	return __ret;
 }
 
-void llifstream::open(const std::string& _Filename,	/* Flawfinder: ignore */
-	ios_base::openmode _Mode,
-	int _Prot)
-{	// open a C stream with specified mode
+bool llstdio_filebuf::_convert_to_external(char_type* __ibuf,
+						std::streamsize __ilen)
+{
+	// Sizes of external and pending output.
+	streamsize __elen;
+	streamsize __plen;
+	if (__check_facet(_M_codecvt).always_noconv())
+	{
+		//__elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
+		__elen = fwrite(reinterpret_cast<void*>(__ibuf), 1,
+						__ilen, _M_file.file());
+		__plen = __ilen;
+	}
+	else
+	{
+		// Worst-case number of external bytes needed.
+		// XXX Not done encoding() == -1.
+		streamsize __blen = __ilen * _M_codecvt->max_length();
+		char* __buf = static_cast<char*>(__builtin_alloca(__blen));
 
-	LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::in, _Prot);
-	if(filep == NULL)
+		char* __bend;
+		const char_type* __iend;
+		codecvt_base::result __r;
+		__r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
+				__iend, __buf, __buf + __blen, __bend);
+
+		if (__r == codecvt_base::ok || __r == codecvt_base::partial)
+			__blen = __bend - __buf;
+		else if (__r == codecvt_base::noconv)
+		{
+			// Same as the always_noconv case above.
+			__buf = reinterpret_cast<char*>(__ibuf);
+			__blen = __ilen;
+		}
+		else
+			__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
+									"conversion error"));
+  
+		//__elen = _M_file.xsputn(__buf, __blen);
+		__elen = fwrite(__buf, 1, __blen, _M_file.file());
+		__plen = __blen;
+
+		// Try once more for partial conversions.
+		if (__r == codecvt_base::partial && __elen == __plen)
+		{
+			const char_type* __iresume = __iend;
+			streamsize __rlen = this->pptr() - __iend;
+			__r = _M_codecvt->out(_M_state_cur, __iresume,
+					__iresume + __rlen, __iend, __buf,
+					__buf + __blen, __bend);
+			if (__r != codecvt_base::error)
+			{
+				__rlen = __bend - __buf;
+				//__elen = _M_file.xsputn(__buf, __rlen);
+				__elen = fwrite(__buf, 1, __rlen, _M_file.file());
+				__plen = __rlen;
+			}
+			else
+			{
+				__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
+										"conversion error"));
+			}
+		}
+	}
+	return __elen == __plen;
+}
+
+llstdio_filebuf::int_type llstdio_filebuf::underflow()
+{
+	int_type __ret = traits_type::eof();
+	const bool __testin = _M_mode & ios_base::in;
+	if (__testin)
 	{
-		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
-		return;
+		if (_M_writing)
+		{
+			if (overflow() == traits_type::eof())
+			return __ret;
+			//_M_set_buffer(-1);
+			//_M_writing = false;
+		}
+		// Check for pback madness, and if so switch back to the
+		// normal buffers and jet outta here before expensive
+		// fileops happen...
+		_M_destroy_pback();
+
+		if (this->gptr() < this->egptr())
+			return traits_type::to_int_type(*this->gptr());
+
+		// Get and convert input sequence.
+		const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
+
+		// Will be set to true if ::fread() returns 0 indicating EOF.
+		bool __got_eof = false;
+		// Number of internal characters produced.
+		streamsize __ilen = 0;
+		codecvt_base::result __r = codecvt_base::ok;
+		if (__check_facet(_M_codecvt).always_noconv())
+		{
+			//__ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
+			//			__buflen);
+			__ilen = fread(reinterpret_cast<void*>(this->eback()), 1,
+						__buflen, _M_file.file());
+			if (__ilen == 0)
+				__got_eof = true;
+		}
+		else
+	    {
+			// Worst-case number of external bytes.
+			// XXX Not done encoding() == -1.
+			const int __enc = _M_codecvt->encoding();
+			streamsize __blen; // Minimum buffer size.
+			streamsize __rlen; // Number of chars to read.
+			if (__enc > 0)
+				__blen = __rlen = __buflen * __enc;
+			else
+			{
+				__blen = __buflen + _M_codecvt->max_length() - 1;
+				__rlen = __buflen;
+			}
+			const streamsize __remainder = _M_ext_end - _M_ext_next;
+			__rlen = __rlen > __remainder ? __rlen - __remainder : 0;
+
+			// An imbue in 'read' mode implies first converting the external
+			// chars already present.
+			if (_M_reading && this->egptr() == this->eback() && __remainder)
+				__rlen = 0;
+
+			// Allocate buffer if necessary and move unconverted
+			// bytes to front.
+			if (_M_ext_buf_size < __blen)
+			{
+				char* __buf = new char[__blen];
+				if (__remainder)
+					__builtin_memcpy(__buf, _M_ext_next, __remainder);
+
+				delete [] _M_ext_buf;
+				_M_ext_buf = __buf;
+				_M_ext_buf_size = __blen;
+			}
+			else if (__remainder)
+				__builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
+
+			_M_ext_next = _M_ext_buf;
+			_M_ext_end = _M_ext_buf + __remainder;
+			_M_state_last = _M_state_cur;
+
+			do
+			{
+				if (__rlen > 0)
+				{
+					// Sanity check!
+					// This may fail if the return value of
+					// codecvt::max_length() is bogus.
+					if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
+					{
+						__throw_ios_failure(__N("llstdio_filebuf::underflow "
+							"codecvt::max_length() "
+							"is not valid"));
+					}
+					//streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
+					streamsize __elen = fread(_M_ext_end, 1,
+						__rlen, _M_file.file());
+					if (__elen == 0)
+						__got_eof = true;
+					else if (__elen == -1)
+					break;
+					//_M_ext_end += __elen;
+				}
+
+				char_type* __iend = this->eback();
+				if (_M_ext_next < _M_ext_end)
+				{
+					__r = _M_codecvt->in(_M_state_cur, _M_ext_next,
+							_M_ext_end, _M_ext_next,
+							this->eback(),
+							this->eback() + __buflen, __iend);
+				}
+				if (__r == codecvt_base::noconv)
+				{
+					size_t __avail = _M_ext_end - _M_ext_buf;
+					__ilen = std::min(__avail, __buflen);
+					traits_type::copy(this->eback(),
+						reinterpret_cast<char_type*>
+						(_M_ext_buf), __ilen);
+					_M_ext_next = _M_ext_buf + __ilen;
+				}
+				else
+					__ilen = __iend - this->eback();
+
+				// _M_codecvt->in may return error while __ilen > 0: this is
+				// ok, and actually occurs in case of mixed encodings (e.g.,
+				// XML files).
+				if (__r == codecvt_base::error)
+					break;
+
+				__rlen = 1;
+			} while (__ilen == 0 && !__got_eof);
+		}
+
+		if (__ilen > 0)
+		{
+			_M_set_buffer(__ilen);
+			_M_reading = true;
+			__ret = traits_type::to_int_type(*this->gptr());
+		}
+		else if (__got_eof)
+		{
+			// If the actual end of file is reached, set 'uncommitted'
+			// mode, thus allowing an immediate write without an
+			// intervening seek.
+			_M_set_buffer(-1);
+			_M_reading = false;
+			// However, reaching it while looping on partial means that
+			// the file has got an incomplete character.
+			if (__r == codecvt_base::partial)
+				__throw_ios_failure(__N("llstdio_filebuf::underflow "
+					"incomplete character in file"));
+		}
+		else if (__r == codecvt_base::error)
+			__throw_ios_failure(__N("llstdio_filebuf::underflow "
+					"invalid byte sequence in file"));
+		else
+			__throw_ios_failure(__N("llstdio_filebuf::underflow "
+					"error reading the file"));
 	}
-	llassert(_Filebuffer == NULL);
-	_Filebuffer = new _Myfb(filep);
-	_ShouldClose = true;
-	_Myios::init(_Filebuffer);
+	return __ret;
 }
 
-bool llifstream::is_open() const
-{	// test if C stream has been opened
-	if(_Filebuffer)
-		return (_Filebuffer->is_open());
-	return false;
+std::streamsize llstdio_filebuf::xsgetn(char_type* __s, std::streamsize __n)
+{
+	// Clear out pback buffer before going on to the real deal...
+	streamsize __ret = 0;
+	if (_M_pback_init)
+	{
+		if (__n > 0 && this->gptr() == this->eback())
+		{
+			*__s++ = *this->gptr();
+			this->gbump(1);
+			__ret = 1;
+			--__n;
+		}
+		_M_destroy_pback();
+	}
+       
+	// Optimization in the always_noconv() case, to be generalized in the
+	// future: when __n > __buflen we read directly instead of using the
+	// buffer repeatedly.
+	const bool __testin = _M_mode & ios_base::in;
+	const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
+
+	if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
+		&& __testin && !_M_writing)
+	{
+		// First, copy the chars already present in the buffer.
+		const streamsize __avail = this->egptr() - this->gptr();
+		if (__avail != 0)
+		{
+			if (__avail == 1)
+				*__s = *this->gptr();
+			else
+				traits_type::copy(__s, this->gptr(), __avail);
+			__s += __avail;
+			this->gbump(__avail);
+			__ret += __avail;
+			__n -= __avail;
+		}
+
+		// Need to loop in case of short reads (relatively common
+		// with pipes).
+		streamsize __len;
+		for (;;)
+		{
+			//__len = _M_file.xsgetn(reinterpret_cast<char*>(__s), __n);
+			__len = fread(reinterpret_cast<void*>(__s), 1, 
+						__n, _M_file.file());
+			if (__len == -1)
+				__throw_ios_failure(__N("llstdio_filebuf::xsgetn "
+										"error reading the file"));
+			if (__len == 0)
+				break;
+
+			__n -= __len;
+			__ret += __len;
+			if (__n == 0)
+				break;
+
+			__s += __len;
+		}
+
+		if (__n == 0)
+		{
+			_M_set_buffer(0);
+			_M_reading = true;
+		}
+		else if (__len == 0)
+		{
+			// If end of file is reached, set 'uncommitted'
+			// mode, thus allowing an immediate write without
+			// an intervening seek.
+			_M_set_buffer(-1);
+			_M_reading = false;
+		}
+	}
+	else
+		__ret += __streambuf_type::xsgetn(__s, __n);
+
+	return __ret;
 }
-llifstream::~llifstream()
+
+std::streamsize llstdio_filebuf::xsputn(char_type* __s, std::streamsize __n)
 {
-	if (_ShouldClose)
+	// Optimization in the always_noconv() case, to be generalized in the
+	// future: when __n is sufficiently large we write directly instead of
+	// using the buffer.
+	streamsize __ret = 0;
+	const bool __testout = _M_mode & ios_base::out;
+	if (__check_facet(_M_codecvt).always_noconv()
+		&& __testout && !_M_reading)
 	{
-		close();
+		// Measurement would reveal the best choice.
+		const streamsize __chunk = 1ul << 10;
+		streamsize __bufavail = this->epptr() - this->pptr();
+
+		// Don't mistake 'uncommitted' mode buffered with unbuffered.
+		if (!_M_writing && _M_buf_size > 1)
+			__bufavail = _M_buf_size - 1;
+
+		const streamsize __limit = std::min(__chunk, __bufavail);
+		if (__n >= __limit)
+		{
+			const streamsize __buffill = this->pptr() - this->pbase();
+			const char* __buf = reinterpret_cast<const char*>(this->pbase());
+			//__ret = _M_file.xsputn_2(__buf, __buffill,
+			//			reinterpret_cast<const char*>(__s), __n);
+			if (__buffill)
+			{
+				__ret = fwrite(__buf, 1, __buffill, _M_file.file());
+			}
+			if (__ret == __buffill)
+			{
+				__ret += fwrite(reinterpret_cast<const char*>(__s), 1,
+								__n, _M_file.file());
+			}
+			if (__ret == __buffill + __n)
+			{
+				_M_set_buffer(0);
+				_M_writing = true;
+			}
+			if (__ret > __buffill)
+				__ret -= __buffill;
+			else
+				__ret = 0;
+		}
+		else
+			__ret = __streambuf_type::xsputn(__s, __n);
 	}
-	delete _Filebuffer;
+	else
+		__ret = __streambuf_type::xsputn(__s, __n);
+    return __ret;
 }
 
-llifstream::llifstream(const std::string& _Filename,
-	ios_base::openmode _Mode,
-	int _Prot)
-	: std::basic_istream< char , std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
+int llstdio_filebuf::sync()
+{
+	return (_M_file.sync() == 0 ? 0 : -1);
+}
+#endif
+
+/************** input file stream ********************************/
 
-{	// construct with named file and specified mode
-	open(_Filename, _Mode | ios_base::in, _Prot);	/* Flawfinder: ignore */
+
+llifstream::llifstream() : _M_filebuf(),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf) {}
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+// explicit
+llifstream::llifstream(const std::string& _Filename, 
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::in) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
 }
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename.c_str(), _Mode | ios_base::in);
+}
+#endif
 
+// explicit
+llifstream::llifstream(const char* _Filename, 
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+}
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename, _Mode | ios_base::in);
+}
+#endif
 
-/************** output file stream ********************************/
 
-bool llofstream::is_open() const
+// explicit
+llifstream::llifstream(_Filet *_File,
+		ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(_File, _Mode, _Size),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf) {}
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+#if !LL_WINDOWS
+// explicit
+llifstream::llifstream(int __fd,
+		ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(__fd, _Mode, _Size),
+	std::istream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+bool llifstream::is_open() const
 {	// test if C stream has been opened
-	if(_Filebuffer)
-		return (_Filebuffer->is_open());
-	return false;
+	return _M_filebuf.is_open();
 }
 
-void llofstream::open(const std::string& _Filename,	/* Flawfinder: ignore */
-	ios_base::openmode _Mode,
-	int _Prot)
+void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
 {	// open a C stream with specified mode
-
-	LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::out, _Prot);
-	if(filep == NULL)
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+#if LL_WINDOWS
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+	else
 	{
-		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
-		return;
+		_Myios::clear();
 	}
-	llassert(_Filebuffer==NULL);
-	_Filebuffer = new _Myfb(filep);
-	_ShouldClose = true;
-	_Myios::init(_Filebuffer);
+#else
+	{
+		this->setstate(ios_base::failbit);
+	}
+	else
+	{
+		this->clear();
+	}
+#endif
 }
 
-void llofstream::close()
+void llifstream::close()
 {	// close the C stream
-	if(is_open())
+	if (_M_filebuf.close() == 0)
 	{
-		if (_Filebuffer->close() == 0)
-		{
-			_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
-		}
-		delete _Filebuffer;
-		_Filebuffer = NULL;
-		_ShouldClose = false;
+#if LL_WINDOWS
+		_Myios::setstate(ios_base::failbit);
+#else
+		this->setstate(ios_base::failbit);
+#endif
 	}
 }
 
+
+/************** output file stream ********************************/
+
+
+llofstream::llofstream() : _M_filebuf(),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf) {}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+// explicit
 llofstream::llofstream(const std::string& _Filename,
-	std::ios_base::openmode _Mode,
-	int _Prot)
-		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
-{	// construct with named file and specified mode
-	open(_Filename, _Mode , _Prot);	/* Flawfinder: ignore */
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::out) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename.c_str(), _Mode | ios_base::out);
+}
+#endif
+
+// explicit
+llofstream::llofstream(const char* _Filename,
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename, _Mode | ios_base::out);
+}
+#endif
+
+// explicit
+llofstream::llofstream(_Filet *_File,
+			ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(_File, _Mode, _Size),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf) {}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
 }
+#endif
 
-llofstream::~llofstream()
+#if !LL_WINDOWS
+// explicit
+llofstream::llofstream(int __fd,
+			ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(__fd, _Mode, _Size),
+	std::ostream()
 {
-	// destroy the object
-	if (_ShouldClose)
+	this->init(&_M_filebuf);
+}
+#endif
+
+bool llofstream::is_open() const
+{	// test if C stream has been opened
+	return _M_filebuf.is_open();
+}
+
+void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
+{	// open a C stream with specified mode
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
+#if LL_WINDOWS
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+	else
 	{
-		close();
+		_Myios::clear();
 	}
-	delete _Filebuffer;
+#else
+	{
+		this->setstate(ios_base::failbit);
+	}
+	else
+	{
+		this->clear();
+	}
+#endif
 }
 
-#endif // #if USE_LLFILESTREAMS
+void llofstream::close()
+{	// close the C stream
+	if (_M_filebuf.close() == 0)
+	{
+#if LL_WINDOWS
+		_Myios::setstate(ios_base::failbit);
+#else
+		this->setstate(ios_base::failbit);
+#endif
+	}
+}
 
 /************** helper functions ********************************/
 
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index dd7d36513a06d13c81638c1d7eafbdac2e60ab9e..9d70db96ea83852d4365cf9f0096454bc2e41cec 100644
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -35,16 +35,9 @@
  * Attempts to mostly mirror the POSIX style IO functions.
  */
 
-typedef FILE	LLFILE;
+typedef FILE LLFILE;
 
 #include <fstream>
-
-#ifdef LL_WINDOWS
-#define	USE_LLFILESTREAMS	1
-#else
-#define	USE_LLFILESTREAMS	0
-#endif
-
 #include <sys/stat.h>
 
 #if LL_WINDOWS
@@ -52,6 +45,8 @@ typedef FILE	LLFILE;
 typedef struct _stat	llstat;
 #else
 typedef struct stat		llstat;
+#include <ext/stdio_filebuf.h>
+#include <bits/postypes.h>
 #endif
 
 #ifndef S_ISREG
@@ -83,142 +78,342 @@ class LL_COMMON_API LLFile
 	static	int		stat(const std::string&	filename,llstat*	file_status);
 	static	bool	isdir(const std::string&	filename);
 	static	bool	isfile(const std::string&	filename);
-	static	LLFILE *	_Fiopen(const std::string& filename, std::ios::openmode mode,int);	// protection currently unused
+	static	LLFILE *	_Fiopen(const std::string& filename, 
+			std::ios::openmode mode);
 
 	static  const char * tmpdir();
 };
 
+/**
+ *  @brief Provides a layer of compatibility for C/POSIX.
+ *
+ *  This is taken from both the GNU __gnu_cxx::stdio_filebuf extension and 
+ *  VC's basic_filebuf implementation.
+ *  This file buffer provides extensions for working with standard C FILE*'s 
+ *  and POSIX file descriptors for platforms that support this.
+*/
+namespace
+{
+#if LL_WINDOWS
+typedef std::filebuf						_Myfb;
+#else
+typedef  __gnu_cxx::stdio_filebuf< char >	_Myfb;
+typedef std::__c_file						_Filet;
+#endif /* LL_WINDOWS */
+}
 
-#if USE_LLFILESTREAMS
-
-class LL_COMMON_API llifstream	:	public	std::basic_istream < char , std::char_traits < char > >
+class LL_COMMON_API llstdio_filebuf : public _Myfb
 {
-	// input stream associated with a C stream
 public:
-	typedef std::basic_ifstream<char,std::char_traits < char > > _Myt;
-	typedef std::basic_filebuf<char,std::char_traits< char > > _Myfb;
-	typedef std::basic_ios<char,std::char_traits< char > > _Myios;
-
-	llifstream()
-		: std::basic_istream<char,std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
-	{	// construct unopened
-	}
+	/**
+	 * deferred initialization / destruction
+	*/
+	llstdio_filebuf() : _Myfb() {}
+	virtual ~llstdio_filebuf() {} 
+
+	/**
+	 *  @param  f  An open @c FILE*.
+	 *  @param  mode  Same meaning as in a standard filebuf.
+	 *  @param  size  Optimal or preferred size of internal buffer, in chars.
+	 *                Defaults to system's @c BUFSIZ.
+	 *
+	 *  This constructor associates a file stream buffer with an open
+	 *  C @c FILE*.  The @c FILE* will not be automatically closed when the
+	 *  stdio_filebuf is closed/destroyed.
+	*/
+	llstdio_filebuf(_Filet* __f, std::ios_base::openmode __mode,
+		    //size_t __size = static_cast<size_t>(BUFSIZ)) :
+		    size_t __size = static_cast<size_t>(1)) :
+#if LL_WINDOWS
+		_Myfb(__f) {}
+#else
+		_Myfb(__f, __mode, __size) {}
+#endif
 
-	explicit llifstream(const std::string& _Filename,
-		ios_base::openmode _Mode = ios_base::in,
-		int _Prot = (int)ios_base::_Openprot);
-
-	explicit llifstream(_Filet *_File)
-		: std::basic_istream<char,std::char_traits< char > >(NULL,true),
-			_Filebuffer(new _Myfb(_File)),
-			_ShouldClose(false)
-	{	// construct with specified C stream
-	}
-	virtual ~llifstream();
-
-	_Myfb *rdbuf() const
-	{	// return pointer to file buffer
-		return _Filebuffer;
-	}
-	bool is_open() const;
-	void open(const std::string& _Filename,	/* Flawfinder: ignore */
-		ios_base::openmode _Mode = ios_base::in,
-		int _Prot = (int)ios_base::_Openprot);	
-	void close();
+	/**
+	 *  @brief  Opens an external file.
+	 *  @param  s  The name of the file.
+	 *  @param  mode  The open mode flags.
+	 *  @return  @c this on success, NULL on failure
+	 *
+	 *  If a file is already open, this function immediately fails.
+	 *  Otherwise it tries to open the file named @a s using the flags
+	 *  given in @a mode.
+	*/
+	//llstdio_filebuf* open(const char *_Filename,
+	//		std::ios_base::openmode _Mode);
+
+	/**
+	 *  @param  fd  An open file descriptor.
+	 *  @param  mode  Same meaning as in a standard filebuf.
+	 *  @param  size  Optimal or preferred size of internal buffer, in chars.
+	 *
+	 *  This constructor associates a file stream buffer with an open
+	 *  POSIX file descriptor. The file descriptor will be automatically
+	 *  closed when the stdio_filebuf is closed/destroyed.
+	*/
+#if !LL_WINDOWS
+	llstdio_filebuf(int __fd, std::ios_base::openmode __mode,
+		//size_t __size = static_cast<size_t>(BUFSIZ)) :
+		size_t __size = static_cast<size_t>(1)) :
+		_Myfb(__fd, __mode, __size) {}
+#endif
 
-private:
-	_Myfb* _Filebuffer;	// the file buffer
-	bool _ShouldClose;
+// *TODO: Seek the underlying c stream for better cross-platform compatibility?
+#if !LL_WINDOWS
+protected:
+	/** underflow() and uflow() functions are called to get the next
+	 *  character from the real input source when the buffer is empty.
+	 *  Buffered input uses underflow()
+	*/
+	/*virtual*/ int_type underflow();
+
+	/*  Convert internal byte sequence to external, char-based
+	 * sequence via codecvt.
+	*/
+	bool _convert_to_external(char_type*, std::streamsize);
+
+	/** The overflow() function is called to transfer characters to the
+	 *  real output destination when the buffer is full. A call to
+	 *  overflow(c) outputs the contents of the buffer plus the
+	 *  character c.
+	 *  Consume some sequence of the characters in the pending sequence.
+	*/
+	/*virtual*/ int_type overflow(int_type __c = traits_type::eof());
+
+	/** sync() flushes the underlying @c FILE* stream.
+	*/
+	/*virtual*/ int sync();
+
+	std::streamsize xsgetn(char_type*, std::streamsize);
+	std::streamsize xsputn(char_type*, std::streamsize);
+#endif
 };
 
 
-class LL_COMMON_API llofstream	:	public	std::basic_ostream< char , std::char_traits < char > >
+/**
+ *  @brief  Controlling input for files.
+ *
+ *  This class supports reading from named files, using the inherited
+ *  functions from std::basic_istream.  To control the associated
+ *  sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
+ *  which allows construction using a pre-exisintg file stream buffer. 
+ *  We refer to this std::basic_filebuf (or derivative) as @c sb.
+*/
+class LL_COMMON_API llifstream	:	public	std::istream
 {
+	// input stream associated with a C stream
 public:
-	typedef std::basic_ostream< char , std::char_traits < char > > _Myt;
-	typedef std::basic_filebuf< char , std::char_traits < char > > _Myfb;
-	typedef std::basic_ios<char,std::char_traits < char > > _Myios;
-
-	llofstream()
-		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
-	{	// construct unopened
-	}
-
-	explicit llofstream(const std::string& _Filename,
-		std::ios_base::openmode _Mode = ios_base::out,
-		int _Prot = (int)std::ios_base::_Openprot);
-	
-
-	explicit llofstream(_Filet *_File)
-		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),
-			_Filebuffer(new _Myfb(_File)),//_File)
-			_ShouldClose(false)
-	{	// construct with specified C stream
-	}
-
-	virtual ~llofstream();
-
-	_Myfb *rdbuf() const
-	{	// return pointer to file buffer
-		return _Filebuffer;
-	}
+	// Constructors:
+	/**
+	 *  @brief  Default constructor.
+	 *
+	 *  Initializes @c sb using its default constructor, and passes
+	 *  @c &sb to the base class initializer.  Does not open any files
+	 *  (you haven't given it a filename to open).
+	*/
+	llifstream();
+
+	/**
+	 *  @brief  Create an input file stream.
+	 *  @param  Filename  String specifying the filename.
+	 *  @param  Mode  Open file in specified mode (see std::ios_base).
+	 *
+     *  @c ios_base::in is automatically included in @a mode.
+	*/
+	explicit llifstream(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::in);
+	explicit llifstream(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::in);
+
+	/**
+	 *  @brief  Create a stream using an open c file stream.
+	 *  @param  File  An open @c FILE*.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+	explicit llifstream(_Filet *_File,
+			ios_base::openmode _Mode = ios_base::in,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+
+	/**
+	 *  @brief  Create a stream using an open file descriptor.
+	 *  @param  fd    An open file descriptor.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+#if !LL_WINDOWS
+	explicit llifstream(int __fd,
+			ios_base::openmode _Mode = ios_base::in,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+#endif
 
+	/**
+	 *  @brief  The destructor does nothing.
+	 *
+	 *  The file is closed by the filebuf object, not the formatting
+	 *  stream.
+	*/
+	virtual ~llifstream() {}
+
+	// Members:
+	/**
+	 *  @brief  Accessing the underlying buffer.
+	 *  @return  The current basic_filebuf buffer.
+	 *
+	 *  This hides both signatures of std::basic_ios::rdbuf().
+	*/
+	llstdio_filebuf* rdbuf() const
+	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); }
+
+	/**
+	 *  @brief  Wrapper to test for an open file.
+	 *  @return  @c rdbuf()->is_open()
+	*/
 	bool is_open() const;
 
-	void open(const std::string& _Filename,ios_base::openmode _Mode = ios_base::out,int _Prot = (int)ios_base::_Openprot);	/* Flawfinder: ignore */
-
+	/**
+	 *  @brief  Opens an external file.
+	 *  @param  Filename  The name of the file.
+	 *  @param  Node  The open mode flags.
+	 *
+	 *  Calls @c llstdio_filebuf::open(s,mode|in).  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
+	void open(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::in)
+	{ open(_Filename.c_str(), _Mode); }
+	void open(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::in);
+
+	/**
+	 *  @brief  Close the file.
+	 *
+	 *  Calls @c llstdio_filebuf::close().  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
 	void close();
 
 private:
-	_Myfb *_Filebuffer;	// the file buffer
-	bool _ShouldClose;
-};
-
-
-
-#else
-//Use standard file streams on non windows platforms
-//#define	llifstream	std::ifstream
-//#define	llofstream	std::ofstream
-
-class LL_COMMON_API llifstream	:	public	std::ifstream
-{
-public:
-	llifstream() : std::ifstream()
-	{
-	}
-
-	explicit llifstream(const std::string& _Filename, std::_Ios_Openmode _Mode = in)
-		: std::ifstream(_Filename.c_str(), _Mode)
-	{
-	}
-	void open(const std::string& _Filename, std::_Ios_Openmode _Mode = in)	/* Flawfinder: ignore */
-	{
-		std::ifstream::open(_Filename.c_str(), _Mode);
-	}
+	llstdio_filebuf _M_filebuf;
 };
 
 
-class LL_COMMON_API llofstream	:	public	std::ofstream
+/**
+ *  @brief  Controlling output for files.
+ *
+ *  This class supports writing to named files, using the inherited
+ *  functions from std::basic_ostream.  To control the associated
+ *  sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
+ *  which allows construction using a pre-exisintg file stream buffer. 
+ *  We refer to this std::basic_filebuf (or derivative) as @c sb.
+*/
+class LL_COMMON_API llofstream	:	public	std::ostream
 {
 public:
-	llofstream() : std::ofstream()
-	{
-	}
+	// Constructors:
+	/**
+	 *  @brief  Default constructor.
+	 *
+	 *  Initializes @c sb using its default constructor, and passes
+	 *  @c &sb to the base class initializer.  Does not open any files
+	 *  (you haven't given it a filename to open).
+	*/
+	llofstream();
+
+	/**
+	 *  @brief  Create an output file stream.
+	 *  @param  Filename  String specifying the filename.
+	 *  @param  Mode  Open file in specified mode (see std::ios_base).
+	 *
+	 *  @c ios_base::out|ios_base::trunc is automatically included in
+	 *  @a mode.
+	*/
+	explicit llofstream(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+	explicit llofstream(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+
+	/**
+	 *  @brief  Create a stream using an open c file stream.
+	 *  @param  File  An open @c FILE*.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+	explicit llofstream(_Filet *_File,
+			ios_base::openmode _Mode = ios_base::out,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+
+	/**
+	 *  @brief  Create a stream using an open file descriptor.
+	 *  @param  fd    An open file descriptor.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+#if !LL_WINDOWS
+	explicit llofstream(int __fd,
+			ios_base::openmode _Mode = ios_base::out,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+#endif
 
-	explicit llofstream(const std::string& _Filename, std::_Ios_Openmode _Mode = out)
-		: std::ofstream(_Filename.c_str(), _Mode)
-	{
-	}
+	/**
+	 *  @brief  The destructor does nothing.
+	 *
+	 *  The file is closed by the filebuf object, not the formatting
+	 *  stream.
+	*/
+	virtual ~llofstream() {}
+
+	// Members:
+	/**
+	 *  @brief  Accessing the underlying buffer.
+	 *  @return  The current basic_filebuf buffer.
+	 *
+	 *  This hides both signatures of std::basic_ios::rdbuf().
+	*/
+	llstdio_filebuf* rdbuf() const
+	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); }
+
+	/**
+	 *  @brief  Wrapper to test for an open file.
+	 *  @return  @c rdbuf()->is_open()
+	*/
+	bool is_open() const;
 
-	void open(const std::string& _Filename, std::_Ios_Openmode _Mode = out)	/* Flawfinder: ignore */
-	{
-		std::ofstream::open(_Filename.c_str(), _Mode);
-	}
+	/**
+	 *  @brief  Opens an external file.
+	 *  @param  Filename  The name of the file.
+	 *  @param  Node  The open mode flags.
+	 *
+	 *  Calls @c llstdio_filebuf::open(s,mode|out).  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
+	void open(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc)
+	{ open(_Filename.c_str(), _Mode); }
+	void open(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+
+	/**
+	 *  @brief  Close the file.
+	 *
+	 *  Calls @c llstdio_filebuf::close().  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
+	void close();
 
+private:
+	llstdio_filebuf _M_filebuf;
 };
 
-#endif
 
 /**
  * @breif filesize helpers.
diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp
index 41d3eb0bf369881da267876ef9224e7bcfaf9446..731e58bd20e5af682a31611f5f8bbee5080b9ef1 100644
--- a/indra/llcommon/llmetricperformancetester.cpp
+++ b/indra/llcommon/llmetricperformancetester.cpp
@@ -100,7 +100,7 @@ LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& i
 	LLSD ret;
 	LLSD cur;
 	
-	while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+	while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
 	{
 		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
 		{
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 6b549e4b6f9655116d5fb76fedd6a0aea390ad42..ad4fce6f359b8dbb6277402ed615394c98de118a 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -1453,8 +1453,8 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
 	case LLSD::TypeUUID:
 	{
 		ostr.put('u');
-		LLSD::UUID value = data.asUUID();
-		ostr.write((const char*)(&value.mData), UUID_BYTES);
+		LLUUID temp = data.asUUID();
+		ostr.write((const char*)(&(temp.mData)), UUID_BYTES);
 		break;
 	}
 
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index 86e3fc864c065a694e8003dcc6a8d272b2f4b43b..e7a5507385c07bd0c05b42d2477336e04d6d3c1d 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -300,7 +300,7 @@ class LL_COMMON_API LLSDXMLParser : public LLSDParser
 	/** 
 	 * @brief Constructor
 	 */
-	LLSDXMLParser();
+	LLSDXMLParser(bool emit_errors=true);
 
 protected:
 	/** 
@@ -747,25 +747,25 @@ class LL_COMMON_API LLSDSerialize
 		return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY);
 	}
 
-	static S32 fromXMLEmbedded(LLSD& sd, std::istream& str)
+	static S32 fromXMLEmbedded(LLSD& sd, std::istream& str, bool emit_errors=true)
 	{
 		// no need for max_bytes since xml formatting is not
 		// subvertable by bad sizes.
-		LLPointer<LLSDXMLParser> p = new LLSDXMLParser;
+		LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);
 		return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED);
 	}
 	// Line oriented parser, 30% faster than fromXML(), but can
 	// only be used when you know you have the complete XML
 	// document available in the stream.
-	static S32 fromXMLDocument(LLSD& sd, std::istream& str)
+	static S32 fromXMLDocument(LLSD& sd, std::istream& str, bool emit_errors=true)
 	{
-		LLPointer<LLSDXMLParser> p = new LLSDXMLParser();
+		LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);
 		return p->parseLines(str, sd);
 	}
-	static S32 fromXML(LLSD& sd, std::istream& str)
+	static S32 fromXML(LLSD& sd, std::istream& str, bool emit_errors=true)
 	{
-		return fromXMLEmbedded(sd, str);
-//		return fromXMLDocument(sd, str);
+		return fromXMLEmbedded(sd, str, emit_errors);
+//		return fromXMLDocument(sd, str, emit_errors);
 	}
 
 	/*
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 34b3dbb99a3ff05dd5de91a06879b69ce5bcc5a6..cef743a7beab012a31a2b42233da8f33db9588b6 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -250,7 +250,7 @@ std::string LLSDXMLFormatter::escapeString(const std::string& in)
 class LLSDXMLParser::Impl
 {
 public:
-	Impl();
+	Impl(bool emit_errors);
 	~Impl();
 	
 	S32 parse(std::istream& input, LLSD& data);
@@ -294,6 +294,7 @@ class LLSDXMLParser::Impl
 	
 	static const XML_Char* findAttribute(const XML_Char* name, const XML_Char** pairs);
 	
+	bool mEmitErrors;
 
 	XML_Parser	mParser;
 
@@ -315,7 +316,8 @@ class LLSDXMLParser::Impl
 };
 
 
-LLSDXMLParser::Impl::Impl()
+LLSDXMLParser::Impl::Impl(bool emit_errors)
+	: mEmitErrors(emit_errors)
 {
 	mParser = XML_ParserCreate(NULL);
 	reset();
@@ -402,7 +404,10 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
 		{
 			((char*) buffer)[count ? count - 1 : 0] = '\0';
 		}
-		llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
+		if (mEmitErrors)
+		{
+			llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
+		}
 		data = LLSD();
 		return LLSDParser::PARSE_FAILURE;
 	}
@@ -480,7 +485,10 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data)
 	if (status == XML_STATUS_ERROR  
 		&& !mGracefullStop)
 	{
-		llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
+		if (mEmitErrors)
+		{
+			llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
+		}
 		return LLSDParser::PARSE_FAILURE;
 	}
 
@@ -897,7 +905,7 @@ LLSDXMLParser::Impl::Element LLSDXMLParser::Impl::readElement(const XML_Char* na
 /**
  * LLSDXMLParser
  */
-LLSDXMLParser::LLSDXMLParser() : impl(* new Impl)
+LLSDXMLParser::LLSDXMLParser(bool emit_errors /* = true */) : impl(* new Impl(emit_errors))
 {
 }
 
diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h
index b19ba3bf7407eddf5d34dd1ace14e527e1cddc79..ef68a0eaf5cbd4b9272f8b35d70ed17b51c8f42c 100644
--- a/indra/llcommon/llversionserver.h
+++ b/indra/llcommon/llversionserver.h
@@ -30,7 +30,7 @@
 const S32 LL_VERSION_MAJOR = 2;
 const S32 LL_VERSION_MINOR = 1;
 const S32 LL_VERSION_PATCH = 0;
-const S32 LL_VERSION_BUILD = 13828;
+const S32 LL_VERSION_BUILD = 264760;
 
 const char * const LL_CHANNEL = "Second Life Server";
 
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index 0b0c74b3d359e6a939153f38e0779187c72e96fa..ae5e3ecade2d9c1cac2650437fdb55164b58ae35 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -30,7 +30,7 @@
 const S32 LL_VERSION_MAJOR = 3;
 const S32 LL_VERSION_MINOR = 5;
 const S32 LL_VERSION_PATCH = 1;
-const S32 LL_VERSION_BUILD = 0;
+const S32 LL_VERSION_BUILD = 264760;
 
 const char * const LL_CHANNEL = "Second Life Developer";
 
diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp
index 4c3bc674af9d5e9a971684e6b3d4d559814169d3..afc0c18cd01ad7b6de21b547e1407e02bb4ba442 100644
--- a/indra/llcommon/tests/bitpack_test.cpp
+++ b/indra/llcommon/tests/bitpack_test.cpp
@@ -71,7 +71,6 @@ namespace tut
 		U8 packbuffer[255];
 		U8 unpackbuffer[255];
 		int pack_bufsize = 0;
-		int unpack_bufsize = 0;
 
 		LLBitPack bitpack(packbuffer, 255);
 
@@ -81,21 +80,20 @@ namespace tut
 		pack_bufsize = bitpack.flushBitPack();
 
 		LLBitPack bitunpack(packbuffer, pack_bufsize*8);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 0", unpackbuffer[0] == (U8) str[0]);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 1", unpackbuffer[0] == (U8) str[1]);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 2", unpackbuffer[0] == (U8) str[2]);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 3", unpackbuffer[0] == (U8) str[3]);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 4", unpackbuffer[0] == (U8) str[4]);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 5", unpackbuffer[0] == (U8) str[5]);
-		unpack_bufsize = bitunpack.bitUnpack(unpackbuffer, 8*4); // Life
+		bitunpack.bitUnpack(unpackbuffer, 8*4); // Life
 		ensure_memory_matches("bitPack: 4 bytes unpack:", unpackbuffer, 4, str+6, 4);
-		ensure("keep compiler quiet", unpack_bufsize == unpack_bufsize);
 	}
 
 	// U32 packing
diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
index 454695ff9f2593d5954d80e7d2d6b5fa70de7def..e769c3e22c77c38298a7f704c40c0bc2dc75a602 100644
--- a/indra/llcommon/tests/llinstancetracker_test.cpp
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
@@ -267,7 +267,6 @@ namespace tut
         {
             existing.insert(&*uki);
         }
-        Unkeyed* puk = NULL;
         try
         {
             // We don't expect the assignment to take place because we expect
@@ -280,7 +279,7 @@ namespace tut
             // realize we're testing the C++ implementation more than
             // Unkeyed's implementation, but this seems an important point to
             // nail down.
-            puk = new Unkeyed("throw");
+            new Unkeyed("throw");
         }
         catch (const Badness&)
         {
diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt
index b2639aec304d5997fffd880c72896878f0938119..12986de8b2c3cf2b94b6c9e90a87ed9eaaeb07fa 100644
--- a/indra/llcrashlogger/CMakeLists.txt
+++ b/indra/llcrashlogger/CMakeLists.txt
@@ -16,6 +16,10 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llcrashlogger_SOURCE_FILES
     llcrashlogger.cpp
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 34e25a8a715a2ac6fb695b9ae40cca427fa85e93..fb2d43e3b0d6c25af71214e8cf3f1bbe255198fd 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -147,7 +147,7 @@ void LLCrashLogger::gatherFiles()
 
 	// Look for it in the debug_info.log file
 	if (debug_log_file.is_open())
-	{		
+	{
 		LLSDSerialize::fromXML(mDebugLog, debug_log_file);
 
 		mCrashInPreviousExec = mDebugLog["CrashNotHandled"].asBoolean();
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index ea8c1a1107eef6c7f3b2be9cdbad5dce5d45c54c..e837b0cac2cbb25bc5d2587a7c1428d4866ec37c 100644
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -7,12 +7,15 @@ include(LLCommon)
 include(LLImage)
 include(LLMath)
 include(LLVFS)
+include(LLKDU)
+include(LLImageJ2COJ)
 include(ZLIB)
 include(LLAddBuildTest)
 include(Tut)
 
 include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
     ${LLMATH_INCLUDE_DIRS}
     ${LLVFS_INCLUDE_DIRS}
     ${PNG_INCLUDE_DIRS}
@@ -56,8 +59,16 @@ list(APPEND llimage_SOURCE_FILES ${llimage_HEADER_FILES})
 add_library (llimage ${llimage_SOURCE_FILES})
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
+if (USE_KDU)
+    target_link_libraries(llimage ${LLKDU_LIBRARIES})
+else (USE_KDU)
+    target_link_libraries(llimage ${LLIMAGEJ2COJ_LIBRARIES})
+endif (USE_KDU)
+
 target_link_libraries(llimage
-    llcommon
+    ${LLVFS_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLCOMMON_LIBRARIES}
     ${JPEG_LIBRARIES}
     ${PNG_LIBRARIES}
     ${ZLIB_LIBRARIES}
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index a88ac148efa306f98cbc2689d0c57bc971bdbeec..1c25256e9521894a04c7e0b0230932d201f7c84b 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -640,6 +640,29 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
 	}
 }
 
+void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
+{
+	LLImageRaw* dst = this;  // Just for clarity.
+
+	llassert( 1 == src->getComponents() );
+	llassert( 4 == dst->getComponents() );
+	llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+
+	S32 pixels = getWidth() * getHeight();
+	U8* src_data = src->getData();
+	U8* dst_data = dst->getData();
+	for ( S32 i = 0; i < pixels; i++ )
+	{
+		dst_data[0] = fill.mV[0];
+		dst_data[1] = fill.mV[1];
+		dst_data[2] = fill.mV[2];
+		dst_data[3] = src_data[0];
+		src_data += 1;
+		dst_data += 4;
+	}
+}
+
+
 // Fill the buffer with a constant color
 void LLImageRaw::fill( const LLColor4U& color )
 {
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 6cb1226da09748e93d5a77c94f854767d733aba5..4fc40ecff7703364b950cd7c8cdadd18266c5f3d 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -226,6 +226,11 @@ class LLImageRaw : public LLImageBase
 	// Src and dst are same size.  Src has 3 components.  Dst has 4 components.
 	void copyUnscaled3onto4( LLImageRaw* src );
 
+	// Src and dst are same size.  Src has 1 component.  Dst has 4 components.
+	// Alpha component is set to source alpha mask component.
+	// RGB components are set to fill color.
+	void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill);
+
 	// Src and dst can be any size.  Src and dst have same number of components.
 	void copyScaled( LLImageRaw* src );
 
diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp
index 58426d31fa6837c174f6f389d28047bc28cc75a9..920ae2891f6caefa99b37ed30935047c34f21fe8 100644
--- a/indra/llimage/llimagetga.cpp
+++ b/indra/llimage/llimagetga.cpp
@@ -132,12 +132,12 @@ BOOL LLImageTGA::updateData()
 	**	  FIELD 2 :	COLOR MAP TYPE (1 BYTES)			
 	**	  FIELD 3 :	IMAGE TYPE CODE (1 BYTES)			
 	**					= 0	NO IMAGE DATA INCLUDED		
-	**					= 1	UNCOMPRESSED, COLOR-MAPPED IMAGE
-	**					= 2	UNCOMPRESSED, TRUE-COLOR IMAGE	
-	**					= 3	UNCOMPRESSED, BLACK AND WHITE IMAGE
-	**					= 9	RUN-LENGTH ENCODED COLOR-MAPPED IMAGE
-	**					= 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE
-	**					= 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE
+	**					= (0001) 1	UNCOMPRESSED, COLOR-MAPPED IMAGE
+	**					= (0010) 2	UNCOMPRESSED, TRUE-COLOR IMAGE	
+	**					= (0011) 3	UNCOMPRESSED, BLACK AND WHITE IMAGE
+	**					= (1001) 9	RUN-LENGTH ENCODED COLOR-MAPPED IMAGE
+	**					= (1010) 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE
+	**					= (1011) 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE
 	**	  FIELD 4 :	COLOR MAP SPECIFICATION	(5 BYTES)		
 	**				4.1 : COLOR MAP ORIGIN (2 BYTES)	
 	**				4.2 : COLOR MAP LENGTH (2 BYTES)	
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index a80ae73dca3c5434ca6e3caa2ae0137af116cb24..41d58c6deb5b2c476012deb32bccefe661a13b3e 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -288,7 +288,15 @@ void LLInventoryObject::setCreationDate(time_t creation_date_utc)
 }
 
 
+const std::string& LLInventoryItem::getDescription() const
+{
+	return mDescription;
+}
 
+const std::string& LLInventoryItem::getActualDescription() const
+{
+	return mDescription;
+}
 
 ///----------------------------------------------------------------------------
 /// Class LLInventoryItem
@@ -389,11 +397,6 @@ void LLInventoryItem::setAssetUUID(const LLUUID& asset_id)
 }
 
 
-const std::string& LLInventoryItem::getDescription() const
-{
-	return mDescription;
-}
-
 U32 LLInventoryItem::getCRC32() const
 {
 	// *FIX: Not a real crc - more of a checksum.
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index 4516e548df1c41b1edbc745b1e30175278ac7ea6..99716ed7be6d13290756c80b191385eed8c25d73 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -160,6 +160,7 @@ class LLInventoryItem : public LLInventoryObject
 	virtual const LLUUID& getCreatorUUID() const;
 	virtual const LLUUID& getAssetUUID() const;
 	virtual const std::string& getDescription() const;
+	virtual const std::string& getActualDescription() const; // Does not follow links
 	virtual const LLSaleInfo& getSaleInfo() const;
 	virtual LLInventoryType::EType getInventoryType() const;
 	virtual U32 getFlags() const;
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index 645ebab23400fb6fc9ad5e7ab6169020da09cbab..fc3c78cf5062c7c0333a68585733ab2aa1320c1e 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -69,6 +69,53 @@ class LLInventoryType
 		IT_NONE = -1
 	};
 
+	enum EIconName
+	{
+		ICONNAME_TEXTURE,
+		ICONNAME_SOUND,
+		ICONNAME_CALLINGCARD_ONLINE,
+		ICONNAME_CALLINGCARD_OFFLINE,
+		ICONNAME_LANDMARK,
+		ICONNAME_LANDMARK_VISITED,
+		ICONNAME_SCRIPT,
+		ICONNAME_CLOTHING,
+		ICONNAME_OBJECT,
+		ICONNAME_OBJECT_MULTI,
+		ICONNAME_NOTECARD,
+		ICONNAME_BODYPART,
+		ICONNAME_SNAPSHOT,
+		
+		ICONNAME_BODYPART_SHAPE,
+		ICONNAME_BODYPART_SKIN,
+		ICONNAME_BODYPART_HAIR,
+		ICONNAME_BODYPART_EYES,
+		ICONNAME_CLOTHING_SHIRT,
+		ICONNAME_CLOTHING_PANTS,
+		ICONNAME_CLOTHING_SHOES,
+		ICONNAME_CLOTHING_SOCKS,
+		ICONNAME_CLOTHING_JACKET,
+		ICONNAME_CLOTHING_GLOVES,
+		ICONNAME_CLOTHING_UNDERSHIRT,
+		ICONNAME_CLOTHING_UNDERPANTS,
+		ICONNAME_CLOTHING_SKIRT,
+		ICONNAME_CLOTHING_ALPHA,
+		ICONNAME_CLOTHING_TATTOO,
+
+		ICONNAME_ANIMATION,
+		ICONNAME_GESTURE,
+
+		ICONNAME_CLOTHING_PHYSICS,
+		
+		ICONNAME_LINKITEM,
+		ICONNAME_LINKFOLDER,
+		ICONNAME_MESH,
+
+		ICONNAME_INVALID,
+		ICONNAME_COUNT,
+		ICONNAME_NONE = -1
+	};
+
+
 	// machine transation between type and strings
 	static EType lookup(const std::string& name);
 	static const std::string &lookup(EType type);
diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt
index bdac2eded7ec3d1723d147072fea27f1c0571335..b8f8b420c329cc8bc0c448c900f4d3ca34bfed41 100644
--- a/indra/llkdu/CMakeLists.txt
+++ b/indra/llkdu/CMakeLists.txt
@@ -41,7 +41,10 @@ set_source_files_properties(${llkdu_HEADER_FILES}
 list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES})
 
 if (USE_KDU)
-  add_library (${LLKDU_LIBRARIES} ${llkdu_SOURCE_FILES})
+  add_library (llkdu ${llkdu_SOURCE_FILES})
+
+  target_link_libraries(llkdu
+    ${KDU_LIBRARY})
   
   # Add tests
   if (LL_TESTS)
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 5865ae030c2cac900207fc5e221036488e3ee351..0614fd92ef60f1bfaf8f1de1a52aca92ae888ae2 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -7,6 +7,7 @@ include(LLCommon)
 
 include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
     )
 
 set(llmath_SOURCE_FILES
@@ -99,6 +100,10 @@ list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES})
 
 add_library (llmath ${llmath_SOURCE_FILES})
 
+target_link_libraries(llmath
+    ${LLCOMMON_LIBRARIES}
+    )
+
 # Add tests
 if (LL_TESTS)
   include(LLAddBuildTest)
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 02c8d2b86f090f5150bdd8574338ceb3d0d1f6f6..3f06e6b99ed38d493f05416c2354185a1ebf20c4 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -6066,12 +6066,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
 	S32 max_t = volume->getPath().mPath.size();
 
 	// S32 i;
-	S32 num_vertices = 0, num_indices = 0;
 	S32	grid_size = (profile.size()-1)/4;
-	S32	quad_count = (grid_size * grid_size);
-
-	num_vertices = (grid_size+1)*(grid_size+1);
-	num_indices = quad_count * 4;
 
 	LLVector4a& min = mExtents[0];
 	LLVector4a& max = mExtents[1];
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index d98781e9e62ba8ff79e689345f3975d3cec98d39..1a90c32fe4fd0ee38433164a7e7a0d59ddfb885a 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -218,6 +218,9 @@ add_library (llmessage ${llmessage_SOURCE_FILES})
 target_link_libraries(
   llmessage
   ${CURL_LIBRARIES}
+  ${LLCOMMON_LIBRARIES}
+  ${LLVFS_LIBRARES}
+  ${LLMATH_LIBRARIES}
   ${CARES_LIBRARIES}
   ${OPENSSL_LIBRARIES}
   ${CRYPTO_LIBRARIES}
@@ -243,7 +246,7 @@ if (LL_TESTS)
     ${LLVFS_LIBRARIES}
     ${LLMATH_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
-      ${GOOGLEMOCK_LIBRARIES}
+    ${GOOGLEMOCK_LIBRARIES}
     )
 
   LL_ADD_INTEGRATION_TEST(
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index 8f91d2a23fc8aadb5789df36f654c9e73df94c50..9a68093427d241b8c8000edfdc18920598333b18 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -435,8 +435,10 @@ void LLAvatarNameCache::cleanupClass()
 void LLAvatarNameCache::importFile(std::istream& istr)
 {
 	LLSD data;
-	S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr);
-	if (parse_count < 1) return;
+	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr))
+	{
+		return;
+	}
 
 	// by convention LLSD storage is a map
 	// we only store one entry in the map
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 3fb36eecf09cb7e771d379ac1f4475ec73a96028..267c48e1d2d5d692cc36c0792b0854eaa7ef0587 100644
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -308,8 +308,10 @@ boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback&
 bool LLCacheName::importFile(std::istream& istr)
 {
 	LLSD data;
-	if(LLSDSerialize::fromXMLDocument(data, istr) < 1)
+	if(LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr))
+	{
 		return false;
+	}
 
 	// We'll expire entries more than a week old
 	U32 now = (U32)time(NULL);
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 8ffa8e4271120ba59a81efe9be0066547d0c1575..47041a2880710e50e201cca400a3e35f44511b0d 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -175,9 +175,11 @@ void LLCurl::Responder::completedRaw(
 {
 	LLSD content;
 	LLBufferStream istr(channels, buffer.get());
-	if (!LLSDSerialize::fromXML(content, istr))
+	const bool emit_errors = false;
+	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(content, istr, emit_errors))
 	{
 		llinfos << "Failed to deserialize LLSD. " << mURL << " [" << status << "]: " << reason << llendl;
+		content["reason"] = reason;
 	}
 
 	completed(status, reason, content);
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index d6ed08055e7764052586b9181ec1072649217883..7dcf160c9ba9c3ccb8d88a4b84d09cdbbac7d01f 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -747,9 +747,9 @@ LLAssetRequest* LLHTTPAssetStorage::findNextRequest(LLAssetStorage::request_list
 	request_list_t::iterator running_end   = running.end();
 
 	request_list_t::iterator pending_iter = pending.begin();
-	request_list_t::iterator pending_end  = pending.end();
+
 	// Loop over all pending requests until we miss finding it in the running list.
-	for (; pending_iter != pending_end; ++pending_iter)
+	for (; pending_iter != pending.end(); ++pending_iter)
 	{
 		LLAssetRequest* req = *pending_iter;
 		// Look for this pending request in the running list.
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
old mode 100644
new mode 100755
index 0c325a68aaed740a04a71019a4163b86b64ad999..3561459bb40f28da675fed5bb755aa4d3eb83af9
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -222,7 +222,11 @@ static void request(
 {
 	if (!LLHTTPClient::hasPump())
 	{
-		responder->completed(U32_MAX, "No pump", LLSD());
+		if (responder)
+		{
+			responder->completed(U32_MAX, "No pump", LLSD());
+		}
+		delete body_injector;
 		return;
 	}
 	LLPumpIO::chain_t chain;
@@ -230,8 +234,13 @@ static void request(
 	LLURLRequest* req = new LLURLRequest(method, url);
 	if(!req->isValid())//failed
 	{
-		delete req ;
-		return ;
+		if (responder)
+		{
+			responder->completed(498, "Internal Error - curl failure", LLSD());
+		}
+		delete req;
+		delete body_injector;
+		return;
 	}
 
 	req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp
index f5d7a9abb6019442ad932e66237b39342fe788d1..0b59209af1b6d1efea5e01150b4d92fcd29ac6bf 100644
--- a/indra/llmessage/llhttpclientadapter.cpp
+++ b/indra/llmessage/llhttpclientadapter.cpp
@@ -43,8 +43,11 @@ void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr respo
 void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) 
 {
 	LLSD empty_pragma_header = headers;
-	// as above
-	empty_pragma_header["Pragma"] = " ";
+	if (!empty_pragma_header.has("Pragma"))
+	{
+		// as above
+		empty_pragma_header["Pragma"] = " ";
+	}
 	LLHTTPClient::get(url, responder, empty_pragma_header);
 }
 
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index 0287026659a1b4406356a4cecfd5592a0e2e31b9..2043bae5e7c0b6c8d42d0d5e9f7d75826577e6be 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -592,6 +592,15 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
 	PUMP_DEBUG;
 	apr_pool_t* new_pool = NULL;
 	apr_status_t status = apr_pool_create(&new_pool, mPool);
+	if(ll_apr_warn_status(status))
+	{
+		if(new_pool)
+		{	
+			apr_pool_destroy(new_pool);
+		}
+		return STATUS_ERROR;
+	}
+
 	apr_socket_t* socket = NULL;
 	status = apr_socket_accept(
 		&socket,
diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h
index 7b796a0fa875f92785ac0f0c376338c453188f97..1cf940918b72ff4b8aaa0a89977d8714b7f58080 100644
--- a/indra/llmessage/llregionflags.h
+++ b/indra/llmessage/llregionflags.h
@@ -28,95 +28,98 @@
 #define LL_LLREGIONFLAGS_H
 
 // Can you be hurt here? Should health be on?
-const U32 REGION_FLAGS_ALLOW_DAMAGE				= (1 << 0);
+const U64 REGION_FLAGS_ALLOW_DAMAGE				= (1 << 0);
 
 // Can you make landmarks here?
-const U32 REGION_FLAGS_ALLOW_LANDMARK			= (1 << 1);
+const U64 REGION_FLAGS_ALLOW_LANDMARK			= (1 << 1);
 
 // Do we reset the home position when someone teleports away from here?
-const U32 REGION_FLAGS_ALLOW_SET_HOME			= (1 << 2);
+const U64 REGION_FLAGS_ALLOW_SET_HOME			= (1 << 2);
 
 // Do we reset the home position when someone teleports away from here?
-const U32 REGION_FLAGS_RESET_HOME_ON_TELEPORT	= (1 << 3);
+const U64 REGION_FLAGS_RESET_HOME_ON_TELEPORT	= (1 << 3);
 
 // Does the sun move?
-const U32 REGION_FLAGS_SUN_FIXED				= (1 << 4);
+const U64 REGION_FLAGS_SUN_FIXED				= (1 << 4);
 
 // Can't change the terrain heightfield, even on owned parcels,
 // but can plant trees and grass.
-const U32 REGION_FLAGS_BLOCK_TERRAFORM			= (1 << 6);
+const U64 REGION_FLAGS_BLOCK_TERRAFORM			= (1 << 6);
 
 // Can't release, sell, or buy land.
-const U32 REGION_FLAGS_BLOCK_LAND_RESELL		= (1 << 7);
+const U64 REGION_FLAGS_BLOCK_LAND_RESELL		= (1 << 7);
 
 // All content wiped once per night
-const U32 REGION_FLAGS_SANDBOX					= (1 << 8);
-const U32 REGION_FLAGS_SKIP_COLLISIONS			= (1 << 12); // Pin all non agent rigid bodies
-const U32 REGION_FLAGS_SKIP_SCRIPTS				= (1 << 13);
-const U32 REGION_FLAGS_SKIP_PHYSICS				= (1 << 14); // Skip all physics
-const U32 REGION_FLAGS_EXTERNALLY_VISIBLE		= (1 << 15);
-const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16);
-const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17);
-const U32 REGION_FLAGS_BLOCK_DWELL				= (1 << 18);
+const U64 REGION_FLAGS_SANDBOX					= (1 << 8);
+const U64 REGION_FLAGS_SKIP_COLLISIONS			= (1 << 12); // Pin all non agent rigid bodies
+const U64 REGION_FLAGS_SKIP_SCRIPTS				= (1 << 13);
+const U64 REGION_FLAGS_SKIP_PHYSICS				= (1 << 14); // Skip all physics
+const U64 REGION_FLAGS_EXTERNALLY_VISIBLE		= (1 << 15);
+const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16);
+const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17);
+const U64 REGION_FLAGS_BLOCK_DWELL				= (1 << 18);
 
 // Is flight allowed?
-const U32 REGION_FLAGS_BLOCK_FLY				= (1 << 19);	
+const U64 REGION_FLAGS_BLOCK_FLY				= (1 << 19);	
 
 // Is direct teleport (p2p) allowed?
-const U32 REGION_FLAGS_ALLOW_DIRECT_TELEPORT	= (1 << 20);
+const U64 REGION_FLAGS_ALLOW_DIRECT_TELEPORT	= (1 << 20);
 
 // Is there an administrative override on scripts in the region at the
 // moment. This is the similar skip scripts, except this flag is
 // presisted in the database on an estate level.
-const U32 REGION_FLAGS_ESTATE_SKIP_SCRIPTS		= (1 << 21);
+const U64 REGION_FLAGS_ESTATE_SKIP_SCRIPTS		= (1 << 21);
 
-const U32 REGION_FLAGS_RESTRICT_PUSHOBJECT		= (1 << 22);
+const U64 REGION_FLAGS_RESTRICT_PUSHOBJECT		= (1 << 22);
 
-const U32 REGION_FLAGS_DENY_ANONYMOUS			= (1 << 23);
+const U64 REGION_FLAGS_DENY_ANONYMOUS			= (1 << 23);
 
-const U32 REGION_FLAGS_ALLOW_PARCEL_CHANGES		= (1 << 26);
+const U64 REGION_FLAGS_ALLOW_PARCEL_CHANGES		= (1 << 26);
 
-const U32 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
+const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
 
-const U32 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);
-const U32 REGION_FLAGS_DENY_AGEUNVERIFIED	= (1 << 30);
+const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);
+const U64 REGION_FLAGS_DENY_AGEUNVERIFIED	= (1 << 30);
 
-const U32 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |
+const U64 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |
 								 REGION_FLAGS_ALLOW_SET_HOME |
                                  REGION_FLAGS_ALLOW_PARCEL_CHANGES |
                                  REGION_FLAGS_ALLOW_VOICE;
 
 
-const U32 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT;
-const U32 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK 
+const U64 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT;
+const U64 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK 
 									   | REGION_FLAGS_ALLOW_SET_HOME;
 
-const U32 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE
+const U64 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE
 									 | REGION_FLAGS_SUN_FIXED
 									 | REGION_FLAGS_DENY_ANONYMOUS
 									 | REGION_FLAGS_DENY_AGEUNVERIFIED;
 
-inline BOOL is_prelude( U32 flags )
+inline BOOL is_prelude( U64 flags )
 {
 	// definition of prelude does not depend on fixed-sun
 	return 0 == (flags & REGION_FLAGS_PRELUDE_UNSET)
 		   && 0 != (flags & REGION_FLAGS_PRELUDE_SET);
 }
 
-inline U32 set_prelude_flags(U32 flags)
+inline U64 set_prelude_flags(U64 flags)
 {
 	// also set the sun-fixed flag
 	return ((flags & ~REGION_FLAGS_PRELUDE_UNSET)
 			| (REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED));
 }
 
-inline U32 unset_prelude_flags(U32 flags)
+inline U64 unset_prelude_flags(U64 flags)
 {
 	// also unset the fixed-sun flag
 	return ((flags | REGION_FLAGS_PRELUDE_UNSET) 
 			& ~(REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED));
 }
 
+// Region protocols
+const U64 REGION_PROTOCOLS_AGENT_APPEARANCE_SERVICE = (1 << 0);
+
 // estate constants. Need to match first few etries in indra.estate table.
 const U32 ESTATE_ALL = 0; // will not match in db, reserved key for logic
 const U32 ESTATE_MAINLAND = 1;
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index 227efdb07af27b33dc6574336367ebae5b560cc7..627d5918392f94b9d307890d6e225d57dbbbab00 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -174,6 +174,10 @@ LLURLRequest::~LLURLRequest()
 void LLURLRequest::setURL(const std::string& url)
 {
 	mDetail->mURL = url;
+	if (url.empty())
+	{
+		llwarns << "empty URL specified" << llendl;
+	}
 }
 
 std::string LLURLRequest::getURL() const
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index d7658862da4f3eb2f83816d55587bfaff43ccd64..39cfb6019e5af4cfdaf2b88e8e3a55a4401571e4 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -279,6 +279,8 @@ char const* const _PREHASH_GrabOffset = LLMessageStringTable::getInstance()->get
 char const* const _PREHASH_SimPort = LLMessageStringTable::getInstance()->getString("SimPort");
 char const* const _PREHASH_PricePerMeter = LLMessageStringTable::getInstance()->getString("PricePerMeter");
 char const* const _PREHASH_RegionFlags = LLMessageStringTable::getInstance()->getString("RegionFlags");
+char const* const _PREHASH_RegionFlagsExtended = LLMessageStringTable::getInstance()->getString("RegionFlagsExtended");
+char const* const _PREHASH_RegionProtocols = LLMessageStringTable::getInstance()->getString("RegionProtocols");
 char const* const _PREHASH_VoteResult = LLMessageStringTable::getInstance()->getString("VoteResult");
 char const* const _PREHASH_ParcelDirFeeEstimate = LLMessageStringTable::getInstance()->getString("ParcelDirFeeEstimate");
 char const* const _PREHASH_ModifyBlock = LLMessageStringTable::getInstance()->getString("ModifyBlock");
@@ -305,6 +307,8 @@ char const* const _PREHASH_ViewerStartAuction = LLMessageStringTable::getInstanc
 char const* const _PREHASH_StartAuction = LLMessageStringTable::getInstance()->getString("StartAuction");
 char const* const _PREHASH_DuplicateFlags = LLMessageStringTable::getInstance()->getString("DuplicateFlags");
 char const* const _PREHASH_RegionInfo2 = LLMessageStringTable::getInstance()->getString("RegionInfo2");
+char const* const _PREHASH_RegionInfo3 = LLMessageStringTable::getInstance()->getString("RegionInfo3");
+char const* const _PREHASH_RegionInfo4 = LLMessageStringTable::getInstance()->getString("RegionInfo4");
 char const* const _PREHASH_TextColor = LLMessageStringTable::getInstance()->getString("TextColor");
 char const* const _PREHASH_SlaveID = LLMessageStringTable::getInstance()->getString("SlaveID");
 char const* const _PREHASH_Charter = LLMessageStringTable::getInstance()->getString("Charter");
@@ -1376,3 +1380,6 @@ char const* const _PREHASH_ProductSKU = LLMessageStringTable::getInstance()->get
 char const* const _PREHASH_SeeAVs = LLMessageStringTable::getInstance()->getString("SeeAVs");
 char const* const _PREHASH_AnyAVSounds = LLMessageStringTable::getInstance()->getString("AnyAVSounds");
 char const* const _PREHASH_GroupAVSounds = LLMessageStringTable::getInstance()->getString("GroupAVSounds");
+char const* const _PREHASH_AppearanceData = LLMessageStringTable::getInstance()->getString("AppearanceData");
+char const* const _PREHASH_AppearanceVersion = LLMessageStringTable::getInstance()->getString("AppearanceVersion");
+char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index da2b613f539022bc58bfaa2013d7b77272e365d1..573e10dc0bc2dc630d5a1153693e79e2434ece7b 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -279,6 +279,8 @@ extern char const* const _PREHASH_GrabOffset;
 extern char const* const _PREHASH_SimPort;
 extern char const* const _PREHASH_PricePerMeter;
 extern char const* const _PREHASH_RegionFlags;
+extern char const* const _PREHASH_RegionFlagsExtended;
+extern char const* const _PREHASH_RegionProtocols;
 extern char const* const _PREHASH_VoteResult;
 extern char const* const _PREHASH_ParcelDirFeeEstimate;
 extern char const* const _PREHASH_ModifyBlock;
@@ -305,6 +307,8 @@ extern char const* const _PREHASH_ViewerStartAuction;
 extern char const* const _PREHASH_StartAuction;
 extern char const* const _PREHASH_DuplicateFlags;
 extern char const* const _PREHASH_RegionInfo2;
+extern char const* const _PREHASH_RegionInfo3;
+extern char const* const _PREHASH_RegionInfo4;
 extern char const* const _PREHASH_TextColor;
 extern char const* const _PREHASH_SlaveID;
 extern char const* const _PREHASH_Charter;
@@ -1376,4 +1380,7 @@ extern char const* const _PREHASH_ProductSKU;
 extern char const* const _PREHASH_SeeAVs;
 extern char const* const _PREHASH_AnyAVSounds;
 extern char const* const _PREHASH_GroupAVSounds;
+extern char const* const _PREHASH_AppearanceData;
+extern char const* const _PREHASH_AppearanceVersion;
+extern char const* const _PREHASH_CofVersion;
 #endif
diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp
index 7c3def6024e6a3abbd3ae474b13a3460dc120098..87cbafa404c441e83a481e0302fbfe021c7096bf 100644
--- a/indra/llmessage/tests/llhttpclient_test.cpp
+++ b/indra/llmessage/tests/llhttpclient_test.cpp
@@ -47,37 +47,6 @@
 
 namespace tut
 {
-	LLSD storage;
-
-	class LLSDStorageNode : public LLHTTPNode
-	{
-	public:
-		LLSD simpleGet() const					{ return storage; }
-		LLSD simplePut(const LLSD& value) const	{ storage = value; return LLSD(); }
-	};
-
-	class ErrorNode : public LLHTTPNode
-	{
-	public:
-		void get(ResponsePtr r, const LLSD& context) const
-			{ r->status(599, "Intentional error"); }
-		void post(ResponsePtr r, const LLSD& context, const LLSD& input) const
-			{ r->status(input["status"], input["reason"]); }
-	};
-
-	class TimeOutNode : public LLHTTPNode
-	{
-	public:
-		void get(ResponsePtr r, const LLSD& context) const
-		{
-            /* do nothing, the request will eventually time out */ 
-		}
-	};
-
-	LLHTTPRegistration<LLSDStorageNode> gStorageNode("/test/storage");
-	LLHTTPRegistration<ErrorNode>		gErrorNode("/test/error");
-	LLHTTPRegistration<TimeOutNode>		gTimeOutNode("/test/timeout");
-
 	struct HTTPClientTestData
 	{
 	public:
@@ -91,7 +60,6 @@ namespace tut
 			ensure("Set environment variable PORT to local test server port", PORT);
 			apr_pool_create(&mPool, NULL);
 			LLCurl::initClass(false);
-			mServerPump = new LLPumpIO(mPool);
 			mClientPump = new LLPumpIO(mPool);
 
 			LLHTTPClient::setPump(*mClientPump);
@@ -99,20 +67,11 @@ namespace tut
 
 		~HTTPClientTestData()
 		{
-			delete mServerPump;
 			delete mClientPump;
 			LLProxy::cleanupClass();
 			apr_pool_destroy(mPool);
 		}
 
-		void setupTheServer()
-		{
-			LLHTTPNode& root = LLIOHTTPServer::create(mPool, *mServerPump, 8888);
-
-			LLHTTPStandardServices::useServices();
-			LLHTTPRegistrar::buildAllServices(root);
-		}
-
 		void runThePump(float timeout = 100.0f)
 		{
 			LLTimer timer;
@@ -120,11 +79,7 @@ namespace tut
 
 			while(!mSawCompleted && !mSawCompletedHeader && !timer.hasExpired())
 			{
-				if (mServerPump)
-				{
-					mServerPump->pump();
-					mServerPump->callback();
-				}
+				LLFrameTimer::updateFrameTime();
 				if (mClientPump)
 				{
 					mClientPump->pump();
@@ -133,18 +88,11 @@ namespace tut
 			}
 		}
 
-		void killServer()
-		{
-			delete mServerPump;
-			mServerPump = NULL;
-		}
-
 		const char* const PORT;
 		const std::string local_server;
 
 	private:
 		apr_pool_t* mPool;
-		LLPumpIO* mServerPump;
 		LLPumpIO* mClientPump;
 
 	protected:
@@ -288,14 +236,12 @@ namespace tut
 		sd["list"][1]["three"] = 3;
 		sd["list"][1]["four"] = 4;
 		
-		setupTheServer();
-
-		LLHTTPClient::post("http://localhost:8888/web/echo", sd, newResult());
+		LLHTTPClient::post(local_server + "web/echo", sd, newResult());
 		runThePump();
 		ensureStatusOK();
 		ensure_equals("echoed result matches", getResult(), sd);
 	}
-
+		
 	template<> template<>
 		void HTTPClientTestObject::test<4>()
 	{
@@ -303,12 +249,11 @@ namespace tut
 
 		sd["message"] = "This is my test message.";
 
-		setupTheServer();
-		LLHTTPClient::put("http://localhost:8888/test/storage", sd, newResult());
+		LLHTTPClient::put(local_server + "test/storage", sd, newResult());
 		runThePump();
 		ensureStatusOK();
 
-		LLHTTPClient::get("http://localhost:8888/test/storage", newResult());
+		LLHTTPClient::get(local_server + "test/storage", newResult());
 		runThePump();
 		ensureStatusOK();
 		ensure_equals("echoed result matches", getResult(), sd);
@@ -322,9 +267,7 @@ namespace tut
 		sd["status"] = 543;
 		sd["reason"] = "error for testing";
 
-		setupTheServer();
-
-		LLHTTPClient::post("http://localhost:8888/test/error", sd, newResult());
+		LLHTTPClient::post(local_server + "test/error", sd, newResult());
 		runThePump();
 		ensureStatusError();
 		ensure_contains("reason", mReason, sd["reason"]);
@@ -333,23 +276,16 @@ namespace tut
 	template<> template<>
 		void HTTPClientTestObject::test<6>()
 	{
-		setupTheServer();
-
-		LLHTTPClient::get("http://localhost:8888/test/timeout", newResult());
-		runThePump(1.0f);
-		killServer();
-		runThePump();
+		const F32 timeout = 1.0f;
+		LLHTTPClient::get(local_server + "test/timeout", newResult(), LLSD(), timeout);
+		runThePump(timeout * 5.0f);
 		ensureStatusError();
-		ensure_equals("reason", mReason, "STATUS_ERROR");
+		ensure_equals("reason", mReason, "STATUS_EXPIRED");
 	}
 
 	template<> template<>
 		void HTTPClientTestObject::test<7>()
 	{
-		// Can not use the little mini server.  The blocking request
-		// won't ever let it run.  Instead get from a known LLSD
-		// source and compare results with the non-blocking get which
-		// is tested against the mini server earlier.
 		LLHTTPClient::get(local_server, newResult());
 		runThePump();
 		ensureStatusOK();
diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py
index fe4f3a8c011b095ab7b020f5b6d01c1216bc30a7..e45249b1cba1ca41b539b2dfa1d2aff1034409fe 100644
--- a/indra/llmessage/tests/test_llsdmessage_peer.py
+++ b/indra/llmessage/tests/test_llsdmessage_peer.py
@@ -39,6 +39,9 @@
 from indra.util.fastest_elementtree import parse as xml_parse
 from indra.base import llsd
 from testrunner import freeport, run, debug, VERBOSE
+import time
+
+_storage=None
 
 class TestHTTPRequestHandler(BaseHTTPRequestHandler):
     """This subclass of BaseHTTPRequestHandler is to receive and echo
@@ -90,21 +93,14 @@ def do_POST(self):
         # Read the provided POST data.
         self.answer(self.read_xml())
 
+    def do_PUT(self):
+        # Read the provided PUT data.
+        self.answer(self.read_xml())
+
     def answer(self, data, withdata=True):
+        global _storage
         debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path)
-        if "fail" not in self.path:
-            data = data.copy()          # we're going to modify
-            # Ensure there's a "reply" key in data, even if there wasn't before
-            data["reply"] = data.get("reply", llsd.LLSD("success"))
-            response = llsd.format_xml(data)
-            debug("success: %s", response)
-            self.send_response(200)
-            self.send_header("Content-type", "application/llsd+xml")
-            self.send_header("Content-Length", str(len(response)))
-            self.end_headers()
-            if withdata:
-                self.wfile.write(response)
-        else:                           # fail requested
+        if "fail" in self.path or "test/error" in self.path: # fail requested
             status = data.get("status", 500)
             # self.responses maps an int status to a (short, long) pair of
             # strings. We want the longer string. That's why we pass a string
@@ -117,6 +113,30 @@ def answer(self, data, withdata=True):
                                                    "without providing a reason" % status))[1])
             debug("fail requested: %s: %r", status, reason)
             self.send_error(status, reason)
+        else:
+            if "web/echo" in self.path:
+                pass
+            elif "test/timeout" in self.path:
+                time.sleep(5.0)
+                return
+            elif "test/storage" in self.path:
+                if "GET" == self.command:
+                    data = _storage
+                else:
+                    _storage = data
+                    data = "ok"
+            else:
+                data = data.copy()          # we're going to modify
+                # Ensure there's a "reply" key in data, even if there wasn't before
+                data["reply"] = data.get("reply", llsd.LLSD("success"))
+            response = llsd.format_xml(data)
+            debug("success: %s", response)
+            self.send_response(200)
+            self.send_header("Content-type", "application/llsd+xml")
+            self.send_header("Content-Length", str(len(response)))
+            self.end_headers()
+            if withdata:
+                self.wfile.write(response)
 
     if not VERBOSE:
         # When VERBOSE is set, skip both these overrides because they exist to
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 1353b7a4587161b2abbed44697bebdf99d9b46f2..75d89aac785d4c44f0d28210951a65ea3b104d5b 100644
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -22,6 +22,10 @@ include_directories(
     ${LLWINDOW_INCLUDE_DIRS}
     ${LLQTWEBKIT_INCLUDE_DIR}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llplugin_SOURCE_FILES
     llpluginclassmedia.cpp
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 71a6145b581b519fd02e70a8fb3c58be04a07653..a4da7674d593f2f44965b6d92798f114a6fab984 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -31,6 +31,7 @@
 #include "llpluginprocessparent.h"
 #include "llpluginmessagepipe.h"
 #include "llpluginmessageclasses.h"
+#include "llsdserialize.h"
 #include "stringize.h"
 
 #include "llapr.h"
@@ -836,7 +837,7 @@ void LLPluginProcessParent::receiveMessageRaw(const std::string &message)
 	LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL;
 	
 	LLPluginMessage parsed;
-	if(parsed.parse(message) != -1)
+	if(LLSDParser::PARSE_FAILURE != parsed.parse(message))
 	{
 		if(parsed.hasValue("blocking_request"))
 		{
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 8183467dc5bcdaa8ae57521a8bca8f4075a8b583..03412d95d528d5ef79e8ba88505c562c7c5940ae 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -12,6 +12,9 @@ include_directories(
     ${LLMESSAGE_INCLUDE_DIRS}
     ${LLCOMMON_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 if (DARWIN)
     include(CMakeFindFrameworks)
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index e4d9de7eb64cea94020c14ecaa08f66bebb9aa52..1768a06a279f316eb66ae62ecd0db086fd105ca9 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -14,10 +14,14 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LLMESSAGE_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
-    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
     ${LIBS_PREBUILT_DIR}/include/collada
     ${LIBS_PREBUILT_DIR}/include/collada/1.4
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
+    )
 
 set(llprimitive_SOURCE_FILES
     llmaterialtable.cpp
@@ -59,6 +63,15 @@ list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})
 
 add_library (llprimitive ${llprimitive_SOURCE_FILES})
 
+target_link_libraries(llprimitive
+    ${LLCOMMON_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLMESSAGE_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    ${LLPHYSICSEXTENSIONS_LIBRARIES}
+    )
+
+
 #add unit tests
 if (LL_TESTS)
     INCLUDE(LLAddBuildTest)
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 946251f38399a24933a46b61843de41c80e1c130..c340fc2d353af999925b9768faa888341b83bb03 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -38,6 +38,7 @@
 #include "lldatapacker.h"
 #include "llsdutil_math.h"
 #include "llprimtexturelist.h"
+#include "imageids.h"
 
 /**
  * exported constants
@@ -1230,94 +1231,78 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
 	return FALSE;
 }
 
-S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name)
+S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec)
 {
-	return(unpackTEMessage(mesgsys,block_name,-1));
-}
-
-S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num)
-{
-	// use a negative block_num to indicate a single-block read (a non-variable block)
 	S32 retval = 0;
-	const U32 MAX_TES = 32;
-
-	// Avoid construction of 32 UUIDs per call. JC
-
-	U8     image_data[MAX_TES*16];
-	U8	  colors[MAX_TES*4];
-	F32    scale_s[MAX_TES];
-	F32    scale_t[MAX_TES];
-	S16    offset_s[MAX_TES];
-	S16    offset_t[MAX_TES];
-	S16    image_rot[MAX_TES];
-	U8	   bump[MAX_TES];
-	U8	   media_flags[MAX_TES];
-    U8     glow[MAX_TES];
-	
-	const U32 MAX_TE_BUFFER = 4096;
-	U8 packed_buffer[MAX_TE_BUFFER];
-	U8 *cur_ptr = packed_buffer;
-
-	U32 size;
-	U32 face_count = 0;
 
 	if (block_num < 0)
 	{
-		size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
+		tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
 	}
 	else
 	{
-		size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
+		tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
 	}
 
-	if (size == 0)
+	if (tec.size == 0)
 	{
+		tec.face_count = 0;
 		return retval;
 	}
 
 	if (block_num < 0)
 	{
-		mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, 0, MAX_TE_BUFFER);
+		mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, 0, LLTEContents::MAX_TE_BUFFER);
 	}
 	else
 	{
-		mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, block_num, MAX_TE_BUFFER);
+		mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER);
 	}
 
-	face_count = getNumTEs();
+	tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES);
 
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID);
+	U8 *cur_ptr = tec.packed_buffer;
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.colors, 4, tec.face_count, MVT_U8);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_s, 4, tec.face_count, MVT_F32);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_t, 4, tec.face_count, MVT_F32);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_s, 2, tec.face_count, MVT_S16Array);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_t, 2, tec.face_count, MVT_S16Array);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_rot, 2, tec.face_count, MVT_S16Array);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.bump, 1, tec.face_count, MVT_U8);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.media_flags, 1, tec.face_count, MVT_U8);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
-	
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8);
+
+	retval = 1;
+	return retval;
+}
+
+S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)
+{
+	S32 retval = 0;
+
 	LLColor4 color;
 	LLColor4U coloru;
-	for (U32 i = 0; i < face_count; i++)
-	{
-		retval |= setTETexture(i, ((LLUUID*)image_data)[i]);
-		retval |= setTEScale(i, scale_s[i], scale_t[i]);
-		retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);
-		retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
-		retval |= setTEBumpShinyFullbright(i, bump[i]);
-		retval |= setTEMediaTexGen(i, media_flags[i]);
-		retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
-		coloru = LLColor4U(colors + 4*i);
+	for (U32 i = 0; i < tec.face_count; i++)
+	{
+		LLUUID& req_id = ((LLUUID*)tec.image_data)[i];
+		retval |= setTETexture(i, req_id);
+		retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]);
+		retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF);
+		retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
+		retval |= setTEBumpShinyFullbright(i, tec.bump[i]);
+		retval |= setTEMediaTexGen(i, tec.media_flags[i]);
+		retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF);
+		coloru = LLColor4U(tec.colors + 4*i);
 
 		// Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
 		// as all zeros.  However, the subtraction and addition must be done in unsigned
@@ -1334,6 +1319,15 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam
 	return retval;
 }
 
+S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num)
+{
+	LLTEContents tec;
+	S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec);
+	if (!retval)
+		return retval;
+	return applyParsedTEMessage(tec);
+}
+
 S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
 {
 	// use a negative block_num to indicate a single-block read (a non-variable block)
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 8dcaa8c740b58c47f742e0c340c099de627a79eb..6a8b59c81cce09cd03587168227b60d950f07011 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -289,6 +289,34 @@ class LLLightImageParams : public LLNetworkData
 };
 
 
+// This code is not naming-standards compliant. Leaving it like this for
+// now to make the connection to code in
+// 	BOOL packTEMessage(LLDataPacker &dp) const;
+// more obvious. This should be refactored to remove the duplication, at which
+// point we can fix the names as well.
+// - Vir
+struct LLTEContents
+{
+	static const U32 MAX_TES = 32;
+
+	U8     image_data[MAX_TES*16];
+	U8	  colors[MAX_TES*4];
+	F32    scale_s[MAX_TES];
+	F32    scale_t[MAX_TES];
+	S16    offset_s[MAX_TES];
+	S16    offset_t[MAX_TES];
+	S16    image_rot[MAX_TES];
+	U8	   bump[MAX_TES];
+	U8	   media_flags[MAX_TES];
+    U8     glow[MAX_TES];
+	
+	static const U32 MAX_TE_BUFFER = 4096;
+	U8 packed_buffer[MAX_TE_BUFFER];
+
+	U32 size;
+	U32 face_count;
+};
+
 class LLPrimitive : public LLXform
 {
 public:
@@ -360,9 +388,10 @@ class LLPrimitive : public LLXform
 	S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type);
 	BOOL packTEMessage(LLMessageSystem *mesgsys) const;
 	BOOL packTEMessage(LLDataPacker &dp) const;
-	S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name);
 	S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks
 	BOOL unpackTEMessage(LLDataPacker &dp);
+	S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec);
+	S32 applyParsedTEMessage(LLTEContents& tec);
 	
 #ifdef CHECK_FOR_FINITE
 	inline void setPosition(const LLVector3& pos);
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 516af933165621055fac01849732f0ad7114167c..669b70aa433a25bc131b9d78f1d2573aed4cd6ee 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -3,7 +3,7 @@
 project(llrender)
 
 include(00-Common)
-include(FindOpenGL)
+include(OpenGL)
 include(FreeType)
 include(LLCommon)
 include(LLImage)
@@ -25,21 +25,31 @@ include_directories(
     ${LLXML_INCLUDE_DIRS}
     ${LLVFS_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llrender_SOURCE_FILES
     llcubemap.cpp
+    llfontbitmapcache.cpp
     llfontfreetype.cpp
     llfontgl.cpp
-    llfontbitmapcache.cpp
     llfontregistry.cpp
+    llgl.cpp
     llgldbg.cpp
     llglslshader.cpp
+    llgltexture.cpp
     llimagegl.cpp
     llpostprocess.cpp
+    llrender.cpp
+    llrender2dutils.cpp
     llrendernavprim.cpp
     llrendersphere.cpp
+    llrendertarget.cpp
     llshadermgr.cpp
     lltexture.cpp
+    lluiimage.cpp
     llvertexbuffer.cpp
     )
     
@@ -56,14 +66,17 @@ set(llrender_HEADER_FILES
     llglheaders.h
     llglslshader.h
     llglstates.h
+    llgltexture.h
     llgltypes.h
     llimagegl.h
     llpostprocess.h
     llrender.h
+    llrender2dutils.h
     llrendernavprim.h
     llrendersphere.h
     llshadermgr.h
     lltexture.h
+    lluiimage.h
     llvertexbuffer.h
     )
 
@@ -72,33 +85,47 @@ set_source_files_properties(${llrender_HEADER_FILES}
 
 list(APPEND llrender_SOURCE_FILES ${llrender_HEADER_FILES})
 
-if (SERVER AND NOT WINDOWS AND NOT DARWIN)
-  copy_server_sources(
-      llgl
-      llrender
-      )
-
-
-  set_source_files_properties(
-    ${server_SOURCE_FILES}
-    PROPERTIES
-    COMPILE_FLAGS "-DLL_MESA=1 -DLL_MESA_HEADLESS=1"
-    )
+if (BUILD_HEADLESS)
   add_library (llrenderheadless
     ${llrender_SOURCE_FILES}
-    ${server_SOURCE_FILES}
     )
-else (SERVER AND NOT WINDOWS AND NOT DARWIN)
-  list(APPEND llrender_SOURCE_FILES
-      llgl.cpp
-      llrender.cpp
-      llrendertarget.cpp
-      )
-endif (SERVER AND NOT WINDOWS AND NOT DARWIN)
+
+  set_property(TARGET llrenderheadless
+    PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
+    )
+
+  target_link_libraries(llrenderheadless
+    ${LLCOMMON_LIBRARIES}
+    ${LLIMAGE_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLRENDER_HEADLESS_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLWINDOW_HEADLESS_LIBRARIES}
+    ${OPENGL_HEADLESS_LIBRARIES})
+
+endif (BUILD_HEADLESS)
+
 add_library (llrender ${llrender_SOURCE_FILES})
+
+if (SDL_FOUND)
+  set_property(TARGET llrender
+    PROPERTY COMPILE_DEFINITIONS LL_SDL=1
+    )
+endif (SDL_FOUND)
+
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 target_link_libraries(llrender 
-    llimage 
+    ${LLCOMMON_LIBRARIES}
+    ${LLIMAGE_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLRENDER_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLWINDOW_LIBRARIES}
     ${FREETYPE_LIBRARIES}
     ${OPENGL_LIBRARIES})
+
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 66d4ad2d87dc57013039f769abd67a4cf1bbafeb..058bef43a566079881309508da4a20244ff874b0 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -485,14 +485,11 @@ void LLFontFreetype::renderGlyph(U32 glyph_index) const
 	if (mFTFace == NULL)
 		return;
 
-	int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT );
-	llassert(!error);
+	llassert_always(! FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT) );
 
-	error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode);
+	llassert_always(! FT_Render_Glyph(mFTFace->glyph, gFontRenderMode) );
 
 	mRenderGlyphCount++;
-	
-	llassert(!error);
 }
 
 void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 8772779645a693dbb3393e5b3996c431a66eedd9..c4f36cabd049bf615a59b929723e66ab21280010 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -541,7 +541,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
 	
 	BOOL clip = FALSE;
 	F32 cur_x = 0;
-	F32 drawn_x = 0;
 
 	S32 start_of_last_word = 0;
 	BOOL in_word = FALSE;
@@ -629,7 +628,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
 
 		// Round after kerning.
 		cur_x = (F32)llround(cur_x);
-		drawn_x = cur_x;
 	}
 
 	if( clip )
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index b5bdba996ffeb4ea2a558c3574a5fe99cfd528f4..f5ca8d5b04c82b7848b5bac7c828dad7bf2523b4 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -223,7 +223,7 @@ std::string currentOsName()
 	return "Windows";
 #elif LL_DARWIN
 	return "Mac";
-#elif LL_SDL
+#elif LL_SDL || LL_MESA_HEADLESS
 	return "Linux";
 #else
 	return "";
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index c8cf3713abaf4ac9c26cbb2a7c8de5a3ccffc626..c8a8e9fcf7c052ffd854ee5dbe7e5df132370731 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -1485,6 +1485,7 @@ void assert_glerror()
 void clear_glerror()
 {
 	glGetError();
+	glGetError();
 }
 
 ///////////////////////////////////////////////////////////////
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 5c68cb46eb3b79a9811bc16a9cb146af902a6dc5..cf21101e35a2b064d9d121e826589b7f2a4435c9 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -159,6 +159,8 @@ class LLGLSLShader
 extern LLGLSLShader			gUIProgram;
 //output vec4(color.rgb,color.a*tex0[tc0].a)
 extern LLGLSLShader			gSolidColorProgram;
+//Alpha mask shader (declared here so llappearance can access properly)
+extern LLGLSLShader			gAlphaMaskProgram;
 
 
 #endif
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d06ed5e57bf4229bf1e6e4d4bf8a2e7d66915336
--- /dev/null
+++ b/indra/llrender/llgltexture.cpp
@@ -0,0 +1,396 @@
+/** 
+ * @file llgltexture.cpp
+ * @brief Opengl texture implementation
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+#include "llgltexture.h"
+
+
+// static
+S32 LLGLTexture::getTotalNumOfCategories() 
+{
+	return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ;
+}
+
+// static
+//index starts from zero.
+S32 LLGLTexture::getIndexFromCategory(S32 category) 
+{
+	return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ;
+}
+
+//static 
+S32 LLGLTexture::getCategoryFromIndex(S32 index)
+{
+	return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ;
+}
+
+LLGLTexture::LLGLTexture(BOOL usemipmaps)
+{
+	init();
+	mUseMipMaps = usemipmaps;
+}
+
+LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)
+{
+	init();
+	mFullWidth = width ;
+	mFullHeight = height ;
+	mUseMipMaps = usemipmaps;
+	mComponents = components ;
+	setTexelsPerImage();
+}
+
+LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps)
+{
+	init();
+	mUseMipMaps = usemipmaps ;
+	// Create an empty image of the specified size and width
+	mGLTexturep = new LLImageGL(raw, usemipmaps) ;
+}
+
+LLGLTexture::~LLGLTexture()
+{
+	cleanup();
+}
+
+void LLGLTexture::init()
+{
+	mBoostLevel = LLGLTexture::BOOST_NONE;
+
+	mFullWidth = 0;
+	mFullHeight = 0;
+	mTexelsPerImage = 0 ;
+	mUseMipMaps = FALSE ;
+	mComponents = 0 ;
+
+	mTextureState = NO_DELETE ;
+	mDontDiscard = FALSE;
+	mNeedsGLTexture = FALSE ;
+}
+
+void LLGLTexture::cleanup()
+{
+	if(mGLTexturep)
+	{
+		mGLTexturep->cleanup();
+	}
+}
+
+// virtual
+void LLGLTexture::dump()
+{
+	if(mGLTexturep)
+	{
+		mGLTexturep->dump();
+	}
+}
+
+void LLGLTexture::setBoostLevel(S32 level)
+{
+	if(mBoostLevel != level)
+	{
+		mBoostLevel = level ;
+		if(mBoostLevel != LLGLTexture::BOOST_NONE)
+		{
+			setNoDelete() ;		
+		}
+	}
+}
+
+void LLGLTexture::forceActive()
+{
+	mTextureState = ACTIVE ; 
+}
+
+void LLGLTexture::setActive() 
+{ 
+	if(mTextureState != NO_DELETE)
+	{
+		mTextureState = ACTIVE ; 
+	}
+}
+
+//set the texture to stay in memory
+void LLGLTexture::setNoDelete() 
+{ 
+	mTextureState = NO_DELETE ;
+}
+
+void LLGLTexture::generateGLTexture() 
+{	
+	if(mGLTexturep.isNull())
+	{
+		mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
+	}
+}
+
+LLImageGL* LLGLTexture::getGLTexture() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep ;
+}
+
+BOOL LLGLTexture::createGLTexture() 
+{
+	if(mGLTexturep.isNull())
+	{
+		generateGLTexture() ;
+	}
+
+	return mGLTexturep->createGLTexture() ;
+}
+
+BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category)
+{
+	llassert(mGLTexturep.notNull()) ;	
+
+	BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ;
+
+	if(ret)
+	{
+		mFullWidth = mGLTexturep->getCurrentWidth() ;
+		mFullHeight = mGLTexturep->getCurrentHeight() ; 
+		mComponents = mGLTexturep->getComponents() ;	
+		setTexelsPerImage();
+	}
+
+	return ret ;
+}
+
+void LLGLTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
+{
+	llassert(mGLTexturep.notNull()) ;
+	
+	mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ;
+}
+void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode)
+{
+	llassert(mGLTexturep.notNull()) ;
+	mGLTexturep->setAddressMode(mode) ;
+}
+void LLGLTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
+{
+	llassert(mGLTexturep.notNull()) ;
+	mGLTexturep->setFilteringOption(option) ;
+}
+
+//virtual
+S32	LLGLTexture::getWidth(S32 discard_level) const
+{
+	llassert(mGLTexturep.notNull()) ;
+	return mGLTexturep->getWidth(discard_level) ;
+}
+
+//virtual
+S32	LLGLTexture::getHeight(S32 discard_level) const
+{
+	llassert(mGLTexturep.notNull()) ;
+	return mGLTexturep->getHeight(discard_level) ;
+}
+
+S32 LLGLTexture::getMaxDiscardLevel() const
+{
+	llassert(mGLTexturep.notNull()) ;
+	return mGLTexturep->getMaxDiscardLevel() ;
+}
+S32 LLGLTexture::getDiscardLevel() const
+{
+	llassert(mGLTexturep.notNull()) ;
+	return mGLTexturep->getDiscardLevel() ;
+}
+S8  LLGLTexture::getComponents() const 
+{ 
+	llassert(mGLTexturep.notNull()) ;
+	
+	return mGLTexturep->getComponents() ;
+}
+
+LLGLuint LLGLTexture::getTexName() const 
+{ 
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getTexName() ; 
+}
+
+BOOL LLGLTexture::hasGLTexture() const 
+{
+	if(mGLTexturep.notNull())
+	{
+		return mGLTexturep->getHasGLTexture() ;
+	}
+	return FALSE ;
+}
+
+BOOL LLGLTexture::getBoundRecently() const
+{
+	if(mGLTexturep.notNull())
+	{
+		return mGLTexturep->getBoundRecently() ;
+	}
+	return FALSE ;
+}
+
+LLTexUnit::eTextureType LLGLTexture::getTarget(void) const
+{
+	llassert(mGLTexturep.notNull()) ;
+	return mGLTexturep->getTarget() ;
+}
+
+BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
+}
+
+BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
+}
+
+void LLGLTexture::setGLTextureCreated (bool initialized)
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	mGLTexturep->setGLTextureCreated (initialized) ;
+}
+
+void  LLGLTexture::setCategory(S32 category) 
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	mGLTexturep->setCategory(category) ;
+}
+
+LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getAddressMode() ;
+}
+
+S32 LLGLTexture::getTextureMemory() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->mTextureMemory ;
+}
+
+LLGLenum LLGLTexture::getPrimaryFormat() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getPrimaryFormat() ;
+}
+
+BOOL LLGLTexture::getIsAlphaMask() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getIsAlphaMask() ;
+}
+
+BOOL LLGLTexture::getMask(const LLVector2 &tc)
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getMask(tc) ;
+}
+
+F32 LLGLTexture::getTimePassedSinceLastBound()
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getTimePassedSinceLastBound() ;
+}
+BOOL LLGLTexture::getMissed() const 
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getMissed() ;
+}
+
+BOOL LLGLTexture::isJustBound() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->isJustBound() ;
+}
+
+void LLGLTexture::forceUpdateBindStats(void) const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->forceUpdateBindStats() ;
+}
+
+U32 LLGLTexture::getTexelsInAtlas() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getTexelsInAtlas() ;
+}
+
+U32 LLGLTexture::getTexelsInGLTexture() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getTexelsInGLTexture() ;
+}
+
+BOOL LLGLTexture::isGLTextureCreated() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->isGLTextureCreated() ;
+}
+
+S32  LLGLTexture::getDiscardLevelInAtlas() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getDiscardLevelInAtlas() ;
+}
+
+void LLGLTexture::destroyGLTexture() 
+{
+	if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
+	{
+		mGLTexturep->destroyGLTexture() ;
+		mTextureState = DELETED ;
+	}
+}
+
+void LLGLTexture::setTexelsPerImage()
+{
+	S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
+	S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
+	mTexelsPerImage = (F32)fullwidth * fullheight;
+}
+
+
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
new file mode 100644
index 0000000000000000000000000000000000000000..e69b322d6059aa5a047f7e6b59184f6215c5327c
--- /dev/null
+++ b/indra/llrender/llgltexture.h
@@ -0,0 +1,199 @@
+/** 
+ * @file llglviewertexture.h
+ * @brief Object for managing opengl textures
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_GL_TEXTURE_H
+#define LL_GL_TEXTURE_H
+
+#include "lltexture.h"
+#include "llgl.h"
+
+class LLImageRaw;
+
+//
+//this the parent for the class LLViewerTexture
+//through the following virtual functions, the class LLViewerTexture can be reached from /llrender.
+//
+class LLGLTexture : public LLTexture
+{
+public:
+	enum
+	{
+		MAX_IMAGE_SIZE_DEFAULT = 1024,
+		INVALID_DISCARD_LEVEL = 0x7fff
+	};
+
+	enum EBoostLevel
+	{
+		BOOST_NONE 			= 0,
+		BOOST_AVATAR_BAKED	,
+		BOOST_AVATAR		,
+		BOOST_CLOUDS		,
+		BOOST_SCULPTED      ,
+		
+		BOOST_HIGH 			= 10,
+		BOOST_BUMP          ,
+		BOOST_TERRAIN		, // has to be high priority for minimap / low detail
+		BOOST_SELECTED		,		
+		BOOST_AVATAR_BAKED_SELF	,
+		BOOST_AVATAR_SELF	, // needed for baking avatar
+		BOOST_SUPER_HIGH    , //textures higher than this need to be downloaded at the required resolution without delay.
+		BOOST_HUD			,
+		BOOST_ICON			,
+		BOOST_UI			,
+		BOOST_PREVIEW		,
+		BOOST_MAP			,
+		BOOST_MAP_VISIBLE	,		
+		BOOST_MAX_LEVEL,
+
+		//other texture Categories
+		LOCAL = BOOST_MAX_LEVEL,
+		AVATAR_SCRATCH_TEX,
+		DYNAMIC_TEX,
+		MEDIA,
+		ATLAS,
+		OTHER,
+		MAX_GL_IMAGE_CATEGORY
+	};
+
+	typedef enum 
+	{
+		DELETED = 0,         //removed from memory
+		DELETION_CANDIDATE,  //ready to be removed from memory
+		INACTIVE,            //not be used for the last certain period (i.e., 30 seconds).
+		ACTIVE,              //just being used, can become inactive if not being used for a certain time (10 seconds).
+		NO_DELETE = 99       //stay in memory, can not be removed.
+	} LLGLTextureState;
+
+	static S32 getTotalNumOfCategories() ;
+	static S32 getIndexFromCategory(S32 category) ;
+	static S32 getCategoryFromIndex(S32 index) ;
+
+protected:
+	virtual ~LLGLTexture();
+	LOG_CLASS(LLGLTexture);
+
+public:
+	LLGLTexture(BOOL usemipmaps = TRUE);
+	LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
+	LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ;
+
+	virtual void dump();	// debug info to llinfos
+
+	virtual const LLUUID& getID() const = 0;
+
+	void setBoostLevel(S32 level);
+	S32  getBoostLevel() { return mBoostLevel; }
+
+	S32 getFullWidth() const { return mFullWidth; }
+	S32 getFullHeight() const { return mFullHeight; }	
+
+	void generateGLTexture() ;
+	void destroyGLTexture() ;
+
+	//---------------------------------------------------------------------------------------------
+	//functions to access LLImageGL
+	//---------------------------------------------------------------------------------------------
+	/*virtual*/S32	       getWidth(S32 discard_level = -1) const;
+	/*virtual*/S32	       getHeight(S32 discard_level = -1) const;
+
+	BOOL       hasGLTexture() const ;
+	LLGLuint   getTexName() const ;		
+	BOOL       createGLTexture() ;
+	BOOL       createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER);
+
+	void       setFilteringOption(LLTexUnit::eTextureFilterOptions option);
+	void       setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
+	void       setAddressMode(LLTexUnit::eTextureAddressMode mode);
+	BOOL       setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
+	BOOL       setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
+	void       setGLTextureCreated (bool initialized);
+	void       setCategory(S32 category) ;
+
+	LLTexUnit::eTextureAddressMode getAddressMode(void) const ;
+	S32        getMaxDiscardLevel() const;
+	S32        getDiscardLevel() const;
+	S8         getComponents() const;
+	BOOL       getBoundRecently() const;
+	S32        getTextureMemory() const ;
+	LLGLenum   getPrimaryFormat() const;
+	BOOL       getIsAlphaMask() const ;
+	LLTexUnit::eTextureType getTarget(void) const ;
+	BOOL       getMask(const LLVector2 &tc);
+	F32        getTimePassedSinceLastBound();
+	BOOL       getMissed() const ;
+	BOOL       isJustBound()const ;
+	void       forceUpdateBindStats(void) const;
+
+	U32        getTexelsInAtlas() const ;
+	U32        getTexelsInGLTexture() const ;
+	BOOL       isGLTextureCreated() const ;
+	S32        getDiscardLevelInAtlas() const ;
+	LLGLTextureState getTextureState() const { return mTextureState; }
+	
+	//---------------------------------------------------------------------------------------------
+	//end of functions to access LLImageGL
+	//---------------------------------------------------------------------------------------------
+
+	//-----------------
+	/*virtual*/ void setActive() ;
+	void forceActive() ;
+	void setNoDelete() ;
+	void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
+	BOOL getDontDiscard() const { return mDontDiscard; }
+	//-----------------	
+
+private:
+	void cleanup();
+	void init();
+
+protected:
+	void setTexelsPerImage();
+
+	//note: do not make this function public.
+	/*virtual*/ LLImageGL* getGLTexture() const ;
+
+protected:
+	S32 mBoostLevel;				// enum describing priority level
+	S32 mFullWidth;
+	S32 mFullHeight;
+	BOOL mUseMipMaps;
+	S8  mComponents;
+	F32 mTexelsPerImage;			// Texels per image.
+	mutable S8  mNeedsGLTexture;
+
+	//GL texture
+	LLPointer<LLImageGL> mGLTexturep ;
+	S8 mDontDiscard;			// Keep full res version of this image (for UI, etc)
+
+protected:
+	LLGLTextureState  mTextureState ;
+
+
+};
+
+#endif // LL_GL_TEXTURE_H
+
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index a4d7872ec25e0091152a4da7de8e60f2df09e5ed..249b8da880e2b79e9ccc078de7f89a81c61cc986 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -74,6 +74,9 @@ S32 LLImageGL::sCurTexSizeBar = -1 ;
 S32 LLImageGL::sCurTexPickSize = -1 ;
 S32 LLImageGL::sMaxCategories = 1 ;
 
+//optimization for when we don't need to calculate mIsMask
+BOOL LLImageGL::sSkipAnalyzeAlpha;
+
 //------------------------
 //****************************************************************************************************
 //End for texture auditing use only
@@ -169,8 +172,9 @@ BOOL is_little_endian()
 	return (*c == 0x78) ;
 }
 //static 
-void LLImageGL::initClass(S32 num_catagories) 
+void LLImageGL::initClass(S32 num_catagories, BOOL skip_analyze_alpha /* = false */)
 {
+	sSkipAnalyzeAlpha = skip_analyze_alpha;
 }
 
 //static 
@@ -611,14 +615,16 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
 	setImage(rawdata, FALSE);
 }
 
+static LLFastTimer::DeclareTimer FTM_SET_IMAGE("setImage");
 void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 {
+	LLFastTimer t(FTM_SET_IMAGE);
 	bool is_compressed = false;
 	if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
 	{
 		is_compressed = true;
 	}
-
+	
 	
 	
 	if (mUseMipMaps)
@@ -738,8 +744,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 				S32 w = width, h = height;
 				const U8* prev_mip_data = 0;
 				const U8* cur_mip_data = 0;
-				S32 prev_mip_size = 0;
+#ifdef SHOW_ASSERT
 				S32 cur_mip_size = 0;
+#endif
 				
 				mMipLevels = nummips;
 
@@ -748,18 +755,24 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 					if (m==0)
 					{
 						cur_mip_data = data_in;
+#ifdef SHOW_ASSERT
 						cur_mip_size = width * height * mComponents; 
+#endif
 					}
 					else
 					{
 						S32 bytes = w * h * mComponents;
+#ifdef SHOW_ASSERT
 						llassert(prev_mip_data);
-						llassert(prev_mip_size == bytes*4);
+						llassert(cur_mip_size == bytes*4);
+#endif
 						U8* new_data = new U8[bytes];
 						llassert_always(new_data);
 						LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
 						cur_mip_data = new_data;
+#ifdef SHOW_ASSERT
 						cur_mip_size = bytes; 
+#endif
 					}
 					llassert(w > 0 && h > 0 && cur_mip_data);
 					{
@@ -792,7 +805,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 						delete[] prev_mip_data;
 					}
 					prev_mip_data = cur_mip_data;
-					prev_mip_size = cur_mip_size;
 					w >>= 1;
 					h >>= 1;
 				}
@@ -1053,8 +1065,10 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
 }
 
 // static
+static LLFastTimer::DeclareTimer FTM_GENERATE_TEXTURES("generate textures");
 void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures)
 {
+	LLFastTimer t(FTM_GENERATE_TEXTURES);
 	bool empty = true;
 
 	dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);
@@ -1115,8 +1129,10 @@ void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip
 }
 
 // static
+static LLFastTimer::DeclareTimer FTM_SET_MANUAL_IMAGE("setManualImage");
 void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)
 {
+	LLFastTimer t(FTM_SET_MANUAL_IMAGE);
 	bool use_scratch = false;
 	U32* scratch = NULL;
 	if (LLRender::sGLCoreProfile)
@@ -1220,9 +1236,10 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
 
 //create an empty GL texture: just create a texture name
 //the texture is assiciate with some image by calling glTexImage outside LLImageGL
+static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE1("createGLTexture()");
 BOOL LLImageGL::createGLTexture()
 {
-	if (gHeadlessClient) return FALSE;
+	LLFastTimer t(FTM_CREATE_GL_TEXTURE1);
 	if (gGLManager.mIsDisabled)
 	{
 		llwarns << "Trying to create a texture while GL is disabled!" << llendl;
@@ -1250,9 +1267,10 @@ BOOL LLImageGL::createGLTexture()
 	return TRUE ;
 }
 
+static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE2("createGLTexture(raw)");
 BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
 {
-	if (gHeadlessClient) return FALSE;
+	LLFastTimer t(FTM_CREATE_GL_TEXTURE2);
 	if (gGLManager.mIsDisabled)
 	{
 		llwarns << "Trying to create a texture while GL is disabled!" << llendl;
@@ -1324,8 +1342,10 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
 	return createGLTexture(discard_level, rawdata, FALSE, usename);
 }
 
+static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE3("createGLTexture3(data)");
 BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
 {
+	LLFastTimer t(FTM_CREATE_GL_TEXTURE3);
 	llassert(data_in);
 	stop_glerror();
 
@@ -1702,6 +1722,12 @@ BOOL LLImageGL::getBoundRecently() const
 	return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
 }
 
+BOOL LLImageGL::getIsAlphaMask() const
+{
+	llassert_always(!sSkipAnalyzeAlpha);
+	return mIsMask;
+}
+
 void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)
 {
 	mTarget = target;
@@ -1799,7 +1825,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
 
 void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
 {
-	if(!mNeedsAlphaAndPickMask)
+	if(sSkipAnalyzeAlpha || !mNeedsAlphaAndPickMask)
 	{
 		return ;
 	}
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index cf3c484c79df58a4bbeb17e2b84dd2ffab4a7e4d..57a052b25888ae370519dd4cf638cb8e6697f273 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -142,7 +142,7 @@ class LLImageGL : public LLRefCount
 	BOOL getHasGLTexture() const { return mTexName != 0; }
 	LLGLuint getTexName() const { return mTexName; }
 
-	BOOL getIsAlphaMask() const { return mIsMask; }
+	BOOL getIsAlphaMask() const;
 
 	BOOL getIsResident(BOOL test_now = FALSE); // not const
 
@@ -262,11 +262,12 @@ class LLImageGL : public LLRefCount
 #endif
 
 public:
-	static void initClass(S32 num_catagories) ;
+	static void initClass(S32 num_catagories, BOOL skip_analyze_alpha = false); 
 	static void cleanupClass() ;
 
 private:
 	static S32 sMaxCategories;
+	static BOOL sSkipAnalyzeAlpha;
 	
 	//the flag to allow to call readBackRaw(...).
 	//can be removed if we do not use that function at all.
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 4597d0626065b40af486b541f45390dd4090f62c..c60eb8d9d9169271dad585f042c302e52f65e970 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -357,7 +357,6 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
 }
 
 // LLRenderTarget is unavailible on the mapserver since it uses FBOs.
-#if !LL_MESA_HEADLESS
 bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
 {
 	if (mIndex < 0) return false;
@@ -380,7 +379,6 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
 
 	return true;
 }
-#endif // LL_MESA_HEADLESS
 
 bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
 {
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d3cfbaf03a7bb05046ac2265e36fdf45384c5732
--- /dev/null
+++ b/indra/llrender/llrender2dutils.cpp
@@ -0,0 +1,1608 @@
+/** 
+ * @file llrender2dutils.cpp
+ * @brief GL function implementations for immediate-mode gl drawing.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+// Linden library includes
+#include "v2math.h"
+#include "m3math.h"
+#include "v4color.h"
+#include "llfontgl.h"
+#include "llrender.h"
+#include "llrect.h"
+#include "llgl.h"
+#include "lltexture.h"
+
+// Project includes
+#include "llrender2dutils.h"
+#include "lluiimage.h"
+
+
+//
+// Globals
+//
+const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
+/*static*/ LLVector2		LLRender2D::sGLScaleFactor(1.f, 1.f);
+/*static*/ LLImageProviderInterface* LLRender2D::sImageProvider = NULL;
+
+//
+// Functions
+//
+
+BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
+{
+	if (x < left || right < x) return FALSE;
+	if (y < bottom || top < y) return FALSE;
+	return TRUE;
+}
+
+
+// Puts GL into 2D drawing mode by turning off lighting, setting to an
+// orthographic projection, etc.
+void gl_state_for_2d(S32 width, S32 height)
+{
+	stop_glerror();
+	F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
+	F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
+
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.loadIdentity();
+	gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.loadIdentity();
+	stop_glerror();
+}
+
+
+void gl_draw_x(const LLRect& rect, const LLColor4& color)
+{
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.color4fv( color.mV );
+
+	gGL.begin( LLRender::LINES );
+		gGL.vertex2i( rect.mLeft,		rect.mTop );
+		gGL.vertex2i( rect.mRight,	rect.mBottom );
+		gGL.vertex2i( rect.mLeft,		rect.mBottom );
+		gGL.vertex2i( rect.mRight,	rect.mTop );
+	gGL.end();
+}
+
+
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled)
+{
+	gGL.color4fv(color.mV);
+	gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
+}
+
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
+{
+	gGL.pushUIMatrix();
+	left += LLFontGL::sCurOrigin.mX;
+	right += LLFontGL::sCurOrigin.mX;
+	bottom += LLFontGL::sCurOrigin.mY;
+	top += LLFontGL::sCurOrigin.mY;
+
+	gGL.loadUIIdentity();
+	gl_rect_2d(llfloor((F32)left * LLRender2D::sGLScaleFactor.mV[VX]) - pixel_offset,
+				llfloor((F32)top * LLRender2D::sGLScaleFactor.mV[VY]) + pixel_offset,
+				llfloor((F32)right * LLRender2D::sGLScaleFactor.mV[VX]) + pixel_offset,
+				llfloor((F32)bottom * LLRender2D::sGLScaleFactor.mV[VY]) - pixel_offset,
+				filled);
+	gGL.popUIMatrix();
+}
+
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
+{
+	stop_glerror();
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	// Counterclockwise quad will face the viewer
+	if( filled )
+	{ 
+		gGL.begin( LLRender::QUADS );
+			gGL.vertex2i(left, top);
+			gGL.vertex2i(left, bottom);
+			gGL.vertex2i(right, bottom);
+			gGL.vertex2i(right, top);
+		gGL.end();
+	}
+	else
+	{
+		if( gGLManager.mATIOffsetVerticalLines )
+		{
+			// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+			gGL.begin( LLRender::LINES );
+
+				// Verticals 
+				gGL.vertex2i(left + 1, top);
+				gGL.vertex2i(left + 1, bottom);
+
+				gGL.vertex2i(right, bottom);
+				gGL.vertex2i(right, top);
+
+				// Horizontals
+				top--;
+				right--;
+				gGL.vertex2i(left, bottom);
+				gGL.vertex2i(right, bottom);
+
+				gGL.vertex2i(left, top);
+				gGL.vertex2i(right, top);
+			gGL.end();
+		}
+		else
+		{
+			top--;
+			right--;
+			gGL.begin( LLRender::LINE_STRIP );
+				gGL.vertex2i(left, top);
+				gGL.vertex2i(left, bottom);
+				gGL.vertex2i(right, bottom);
+				gGL.vertex2i(right, top);
+				gGL.vertex2i(left, top);
+			gGL.end();
+		}
+	}
+	stop_glerror();
+}
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
+{
+	gGL.color4fv( color.mV );
+	gl_rect_2d( left, top, right, bottom, filled );
+}
+
+
+void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
+{
+	gGL.color4fv( color.mV );
+	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
+}
+
+// Given a rectangle on the screen, draws a drop shadow _outside_
+// the right and bottom edges of it.  Along the right it has width "lines"
+// and along the bottom it has height "lines".
+void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines)
+{
+	stop_glerror();
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	
+	// HACK: Overlap with the rectangle by a single pixel.
+	right--;
+	bottom++;
+	lines++;
+
+	LLColor4 end_color = start_color;
+	end_color.mV[VALPHA] = 0.f;
+
+	gGL.begin(LLRender::QUADS);
+
+	// Right edge, CCW faces screen
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(right,		top-lines);
+	gGL.vertex2i(right,		bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(right+lines, bottom);
+	gGL.vertex2i(right+lines, top-lines);
+
+	// Bottom edge, CCW faces screen
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(right,		bottom);
+	gGL.vertex2i(left+lines,	bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(left+lines,	bottom-lines);
+	gGL.vertex2i(right,		bottom-lines);
+
+	// bottom left Corner
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(left+lines,	bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(left,		bottom);
+	// make the bottom left corner not sharp
+	gGL.vertex2i(left+1,		bottom-lines+1);
+	gGL.vertex2i(left+lines,	bottom-lines);
+
+	// bottom right corner
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(right,		bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(right,		bottom-lines);
+	// make the rightmost corner not sharp
+	gGL.vertex2i(right+lines-1,	bottom-lines+1);
+	gGL.vertex2i(right+lines,	bottom);
+
+	// top right corner
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i( right,			top-lines );
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i( right+lines,	top-lines );
+	// make the corner not sharp
+	gGL.vertex2i( right+lines-1,	top-1 );
+	gGL.vertex2i( right,			top );
+
+	gGL.end();
+	stop_glerror();
+}
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
+{
+	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
+	{
+		x1++;
+		x2++;
+		y1++;
+		y2++;
+	}
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	
+	gGL.begin(LLRender::LINES);
+		gGL.vertex2i(x1, y1);
+		gGL.vertex2i(x2, y2);
+	gGL.end();
+}
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
+{
+	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
+	{
+		x1++;
+		x2++;
+		y1++;
+		y2++;
+	}
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.color4fv( color.mV );
+
+	gGL.begin(LLRender::LINES);
+		gGL.vertex2i(x1, y1);
+		gGL.vertex2i(x2, y2);
+	gGL.end();
+}
+
+void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
+{
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.color4fv(color.mV);
+
+	if (filled)
+	{
+		gGL.begin(LLRender::TRIANGLES);
+	}
+	else
+	{
+		gGL.begin(LLRender::LINE_LOOP);
+	}
+	gGL.vertex2i(x1, y1);
+	gGL.vertex2i(x2, y2);
+	gGL.vertex2i(x3, y3);
+	gGL.end();
+}
+
+void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac)
+{
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	length = llmin((S32)(max_frac*(right - left)), length);
+	length = llmin((S32)(max_frac*(top - bottom)), length);
+	gGL.begin(LLRender::LINES);
+	gGL.vertex2i(left, top);
+	gGL.vertex2i(left + length, top);
+	
+	gGL.vertex2i(left, top);
+	gGL.vertex2i(left, top - length);
+
+	gGL.vertex2i(left, bottom);
+	gGL.vertex2i(left + length, bottom);
+	
+	gGL.vertex2i(left, bottom);
+	gGL.vertex2i(left, bottom + length);
+
+	gGL.vertex2i(right, top);
+	gGL.vertex2i(right - length, top);
+
+	gGL.vertex2i(right, top);
+	gGL.vertex2i(right, top - length);
+
+	gGL.vertex2i(right, bottom);
+	gGL.vertex2i(right - length, bottom);
+
+	gGL.vertex2i(right, bottom);
+	gGL.vertex2i(right, bottom + length);
+	gGL.end();
+}
+
+
+void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect )
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
+}
+
+void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+	gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
+}
+
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect)
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+
+	// scale screen size of borders down
+	F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0);
+	F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
+
+	LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
+	gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
+}
+
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect)
+{
+	stop_glerror();
+
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+
+	// add in offset of current image to current UI translation
+	const LLVector3 ui_scale = gGL.getUIScale();
+	const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
+
+	F32 uv_width = uv_outer_rect.getWidth();
+	F32 uv_height = uv_outer_rect.getHeight();
+
+	// shrink scaling region to be proportional to clipped image region
+	LLRectf uv_center_rect(
+		uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
+		uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
+		uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
+		uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
+
+	F32 image_width = image->getWidth(0);
+	F32 image_height = image->getHeight(0);
+
+	S32 image_natural_width = llround(image_width * uv_width);
+	S32 image_natural_height = llround(image_height * uv_height);
+
+	LLRectf draw_center_rect(	uv_center_rect.mLeft * image_width,
+								uv_center_rect.mTop * image_height,
+								uv_center_rect.mRight * image_width,
+								uv_center_rect.mBottom * image_height);
+
+	{	// scale fixed region of image to drawn region
+		draw_center_rect.mRight += width - image_natural_width;
+		draw_center_rect.mTop += height - image_natural_height;
+
+		F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
+		F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
+
+		F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
+		F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
+
+		F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
+
+		draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]);
+		draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]);
+		draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]);
+		draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]);
+	}
+
+	LLRectf draw_outer_rect(ui_translation.mV[VX], 
+							ui_translation.mV[VY] + height * ui_scale.mV[VY], 
+							ui_translation.mV[VX] + width * ui_scale.mV[VX], 
+							ui_translation.mV[VY]);
+
+	LLGLSUIDefault gls_ui;
+	
+	if (solid_color)
+	{
+		if (LLGLSLShader::sNoFixedFunction)
+		{
+			gSolidColorProgram.bind();
+		}
+		else
+		{
+			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
+			gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
+		}
+	}
+
+	gGL.getTexUnit(0)->bind(image, true);
+
+	gGL.color4fv(color.mV);
+	
+	const S32 NUM_VERTICES = 9 * 4; // 9 quads
+	LLVector2 uv[NUM_VERTICES];
+	LLVector3 pos[NUM_VERTICES];
+
+	S32 index = 0;
+
+	gGL.begin(LLRender::QUADS);
+	{
+		// draw bottom left
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		// draw bottom middle
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		// draw bottom right
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		// draw left 
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		// draw middle
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		// draw right 
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		// draw top left
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		// draw top middle
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		// draw top right
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
+	}
+	gGL.end();
+
+	if (solid_color)
+	{
+		if (LLGLSLShader::sNoFixedFunction)
+		{
+			gUIProgram.bind();
+		}
+		else
+		{
+			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+		}
+	}
+}
+
+void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+{
+	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
+}
+
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+
+	LLGLSUIDefault gls_ui;
+
+
+	gGL.getTexUnit(0)->bind(image, true);
+
+	gGL.color4fv(color.mV);
+
+	if (degrees == 0.f)
+	{
+		const S32 NUM_VERTICES = 4; // 9 quads
+		LLVector2 uv[NUM_VERTICES];
+		LLVector3 pos[NUM_VERTICES];
+
+		gGL.begin(LLRender::QUADS);
+		{
+			LLVector3 ui_scale = gGL.getUIScale();
+			LLVector3 ui_translation = gGL.getUITranslation();
+			ui_translation.mV[VX] += x;
+			ui_translation.mV[VY] += y;
+			ui_translation.scaleVec(ui_scale);
+			S32 index = 0;
+			S32 scaled_width = llround(width * ui_scale.mV[VX]);
+			S32 scaled_height = llround(height * ui_scale.mV[VY]);
+
+			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
+			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
+			index++;
+
+			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
+			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
+			index++;
+
+			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
+			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
+			index++;
+
+			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
+			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
+			index++;
+
+			gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
+		}
+		gGL.end();
+	}
+	else
+	{
+		gGL.pushUIMatrix();
+		gGL.translateUI((F32)x, (F32)y, 0.f);
+	
+		F32 offset_x = F32(width/2);
+		F32 offset_y = F32(height/2);
+
+		gGL.translateUI(offset_x, offset_y, 0.f);
+
+		LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
+		
+		gGL.getTexUnit(0)->bind(image, true);
+
+		gGL.color4fv(color.mV);
+		
+		gGL.begin(LLRender::QUADS);
+		{
+			LLVector3 v;
+
+			v = LLVector3(offset_x, offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+
+			v = LLVector3(-offset_x, offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+
+			v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+
+			v = LLVector3(offset_x, -offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+		}
+		gGL.end();
+		gGL.popUIMatrix();
+	}
+}
+
+
+void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
+{
+	phase = fmod(phase, 1.f);
+
+	S32 shift = S32(phase * 4.f) % 4;
+
+	// Stippled line
+	LLGLEnable stipple(GL_LINE_STIPPLE);
+	
+	gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
+
+	gGL.flush();
+	glLineWidth(2.5f);
+
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		glLineStipple(2, 0x3333 << shift);
+	}
+
+	gGL.begin(LLRender::LINES);
+	{
+		gGL.vertex3fv( start.mV );
+		gGL.vertex3fv( end.mV );
+	}
+	gGL.end();
+
+	LLRender2D::setLineWidth(1.f);
+}
+
+void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
+{
+	if (end_angle < start_angle)
+	{
+		end_angle += F_TWO_PI;
+	}
+
+	gGL.pushUIMatrix();
+	{
+		gGL.translateUI(center_x, center_y, 0.f);
+
+		// Inexact, but reasonably fast.
+		F32 delta = (end_angle - start_angle) / steps;
+		F32 sin_delta = sin( delta );
+		F32 cos_delta = cos( delta );
+		F32 x = cosf(start_angle) * radius;
+		F32 y = sinf(start_angle) * radius;
+
+		if (filled)
+		{
+			gGL.begin(LLRender::TRIANGLE_FAN);
+			gGL.vertex2f(0.f, 0.f);
+			// make sure circle is complete
+			steps += 1;
+		}
+		else
+		{
+			gGL.begin(LLRender::LINE_STRIP);
+		}
+
+		while( steps-- )
+		{
+			// Successive rotations
+			gGL.vertex2f( x, y );
+			F32 x_new = x * cos_delta - y * sin_delta;
+			y = x * sin_delta +  y * cos_delta;
+			x = x_new;
+		}
+		gGL.end();
+	}
+	gGL.popUIMatrix();
+}
+
+void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
+{
+	gGL.pushUIMatrix();
+	{
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		gGL.translateUI(center_x, center_y, 0.f);
+
+		// Inexact, but reasonably fast.
+		F32 delta = F_TWO_PI / steps;
+		F32 sin_delta = sin( delta );
+		F32 cos_delta = cos( delta );
+		F32 x = radius;
+		F32 y = 0.f;
+
+		if (filled)
+		{
+			gGL.begin(LLRender::TRIANGLE_FAN);
+			gGL.vertex2f(0.f, 0.f);
+			// make sure circle is complete
+			steps += 1;
+		}
+		else
+		{
+			gGL.begin(LLRender::LINE_LOOP);
+		}
+
+		while( steps-- )
+		{
+			// Successive rotations
+			gGL.vertex2f( x, y );
+			F32 x_new = x * cos_delta - y * sin_delta;
+			y = x * sin_delta +  y * cos_delta;
+			x = x_new;
+		}
+		gGL.end();
+	}
+	gGL.popUIMatrix();
+}
+
+// Renders a ring with sides (tube shape)
+void gl_deep_circle( F32 radius, F32 depth, S32 steps )
+{
+	F32 x = radius;
+	F32 y = 0.f;
+	F32 angle_delta = F_TWO_PI / (F32)steps;
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
+	{
+		S32 step = steps + 1; // An extra step to close the circle.
+		while( step-- )
+		{
+			gGL.vertex3f( x, y, depth );
+			gGL.vertex3f( x, y, 0.f );
+
+			F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta);
+			y = x * sinf(angle_delta) +  y * cosf(angle_delta);
+			x = x_new;
+		}
+	}
+	gGL.end();
+}
+
+void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
+{
+	gGL.pushUIMatrix();
+	{
+		gGL.translateUI(0.f, 0.f, -width / 2);
+		if( render_center )
+		{
+			gGL.color4fv(center_color.mV);
+			gGL.diffuseColor4fv(center_color.mV);
+			gl_deep_circle( radius, width, steps );
+		}
+		else
+		{
+			gGL.diffuseColor4fv(side_color.mV);
+			gl_washer_2d(radius, radius - width, steps, side_color, side_color);
+			gGL.translateUI(0.f, 0.f, width);
+			gl_washer_2d(radius - width, radius, steps, side_color, side_color);
+		}
+	}
+	gGL.popUIMatrix();
+}
+
+// Draw gray and white checkerboard with black border
+void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
+{
+	if (!LLGLSLShader::sNoFixedFunction)
+	{ 
+	// Initialize the first time this is called.
+	const S32 PIXELS = 32;
+	static GLubyte checkerboard[PIXELS * PIXELS];
+	static BOOL first = TRUE;
+	if( first )
+	{
+		for( S32 i = 0; i < PIXELS; i++ )
+		{
+			for( S32 j = 0; j < PIXELS; j++ )
+			{
+				checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
+			}
+		}
+		first = FALSE;
+	}
+	
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	// ...white squares
+	gGL.color4f( 1.f, 1.f, 1.f, alpha );
+	gl_rect_2d(rect);
+
+	// ...gray squares
+	gGL.color4f( .7f, .7f, .7f, alpha );
+	gGL.flush();
+
+		glPolygonStipple( checkerboard );
+
+		LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
+		gl_rect_2d(rect);
+	}
+	else
+	{ //polygon stipple is deprecated, use "Checker" texture
+		LLPointer<LLUIImage> img = LLRender2D::getUIImage("Checker");
+		gGL.getTexUnit(0)->bind(img->getImage());
+		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+
+		LLColor4 color(1.f, 1.f, 1.f, alpha);
+		LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
+
+		gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(),
+			img->getImage(), color, uv_rect);
+	}
+	
+	gGL.flush();
+}
+
+
+// Draws the area between two concentric circles, like
+// a doughnut or washer.
+void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
+{
+	const F32 DELTA = F_TWO_PI / steps;
+	const F32 SIN_DELTA = sin( DELTA );
+	const F32 COS_DELTA = cos( DELTA );
+
+	F32 x1 = outer_radius;
+	F32 y1 = 0.f;
+	F32 x2 = inner_radius;
+	F32 y2 = 0.f;
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
+	{
+		steps += 1; // An extra step to close the circle.
+		while( steps-- )
+		{
+			gGL.color4fv(outer_color.mV);
+			gGL.vertex2f( x1, y1 );
+			gGL.color4fv(inner_color.mV);
+			gGL.vertex2f( x2, y2 );
+
+			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
+			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
+			x1 = x1_new;
+
+			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
+			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
+			x2 = x2_new;
+		}
+	}
+	gGL.end();
+}
+
+// Draws the area between two concentric circles, like
+// a doughnut or washer.
+void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
+{
+	const F32 DELTA = (end_radians - start_radians) / steps;
+	const F32 SIN_DELTA = sin( DELTA );
+	const F32 COS_DELTA = cos( DELTA );
+
+	F32 x1 = outer_radius * cos( start_radians );
+	F32 y1 = outer_radius * sin( start_radians );
+	F32 x2 = inner_radius * cos( start_radians );
+	F32 y2 = inner_radius * sin( start_radians );
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
+	{
+		steps += 1; // An extra step to close the circle.
+		while( steps-- )
+		{
+			gGL.color4fv(outer_color.mV);
+			gGL.vertex2f( x1, y1 );
+			gGL.color4fv(inner_color.mV);
+			gGL.vertex2f( x2, y2 );
+
+			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
+			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
+			x1 = x1_new;
+
+			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
+			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
+			x2 = x2_new;
+		}
+	}
+	gGL.end();
+}
+
+void gl_rect_2d_simple_tex( S32 width, S32 height )
+{
+	gGL.begin( LLRender::QUADS );
+
+		gGL.texCoord2f(1.f, 1.f);
+		gGL.vertex2i(width, height);
+
+		gGL.texCoord2f(0.f, 1.f);
+		gGL.vertex2i(0, height);
+
+		gGL.texCoord2f(0.f, 0.f);
+		gGL.vertex2i(0, 0);
+
+		gGL.texCoord2f(1.f, 0.f);
+		gGL.vertex2i(width, 0);
+	
+	gGL.end();
+}
+
+void gl_rect_2d_simple( S32 width, S32 height )
+{
+	gGL.begin( LLRender::QUADS );
+		gGL.vertex2i(width, height);
+		gGL.vertex2i(0, height);
+		gGL.vertex2i(0, 0);
+		gGL.vertex2i(width, 0);
+	gGL.end();
+}
+
+void gl_segmented_rect_2d_tex(const S32 left, 
+							  const S32 top, 
+							  const S32 right, 
+							  const S32 bottom, 
+							  const S32 texture_width, 
+							  const S32 texture_height, 
+							  const S32 border_size, 
+							  const U32 edges)
+{
+	S32 width = llabs(right - left);
+	S32 height = llabs(top - bottom);
+
+	gGL.pushUIMatrix();
+
+	gGL.translateUI((F32)left, (F32)bottom, 0.f);
+	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
+
+	if (border_uv_scale.mV[VX] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
+	}
+	if (border_uv_scale.mV[VY] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
+	}
+
+	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
+	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 width_vec((F32)width, 0.f);
+	LLVector2 height_vec(0.f, (F32)height);
+
+	gGL.begin(LLRender::QUADS);
+	{
+		// draw bottom left
+		gGL.texCoord2f(0.f, 0.f);
+		gGL.vertex2f(0.f, 0.f);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv(border_width_left.mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv(border_height_bottom.mV);
+
+		// draw bottom middle
+		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv(border_width_left.mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv((width_vec - border_width_right).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		// draw bottom right
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv((width_vec - border_width_right).mV);
+
+		gGL.texCoord2f(1.f, 0.f);
+		gGL.vertex2fv(width_vec.mV);
+
+		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		// draw left 
+		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv(border_height_bottom.mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((height_vec - border_height_top).mV);
+
+		// draw middle
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		// draw right 
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		// draw top left
+		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((border_width_left + height_vec).mV);
+
+		gGL.texCoord2f(0.f, 1.f);
+		gGL.vertex2fv((height_vec).mV);
+
+		// draw top middle
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((border_width_left + height_vec).mV);
+
+		// draw top right
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f, 1.f);
+		gGL.vertex2fv((width_vec + height_vec).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+	}
+	gGL.end();
+
+	gGL.popUIMatrix();
+}
+
+//FIXME: rewrite to use scissor?
+void gl_segmented_rect_2d_fragment_tex(const S32 left, 
+									   const S32 top, 
+									   const S32 right, 
+									   const S32 bottom, 
+									   const S32 texture_width, 
+									   const S32 texture_height, 
+									   const S32 border_size, 
+									   const F32 start_fragment, 
+									   const F32 end_fragment, 
+									   const U32 edges)
+{
+	S32 width = llabs(right - left);
+	S32 height = llabs(top - bottom);
+
+	gGL.pushUIMatrix();
+
+	gGL.translateUI((F32)left, (F32)bottom, 0.f);
+	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
+
+	if (border_uv_scale.mV[VX] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
+	}
+	if (border_uv_scale.mV[VY] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
+	}
+
+	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
+	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 width_vec((F32)width, 0.f);
+	LLVector2 height_vec(0.f, (F32)height);
+
+	F32 middle_start = border_scale / (F32)width;
+	F32 middle_end = 1.f - middle_start;
+
+	F32 u_min;
+	F32 u_max;
+	LLVector2 x_min;
+	LLVector2 x_max;
+
+	gGL.begin(LLRender::QUADS);
+	{
+		if (start_fragment < middle_start)
+		{
+			u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
+			u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
+			x_min = (start_fragment / middle_start) * border_width_left;
+			x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
+
+			// draw bottom left
+			gGL.texCoord2f(u_min, 0.f);
+			gGL.vertex2fv(x_min.mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+			gGL.vertex2fv(x_max.mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			// draw left 
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+			
+			// draw top left
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f);
+			gGL.vertex2fv((x_max + height_vec).mV);
+
+			gGL.texCoord2f(u_min, 1.f);
+			gGL.vertex2fv((x_min + height_vec).mV);
+		}
+
+		if (end_fragment > middle_start || start_fragment < middle_end)
+		{
+			x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec;
+			x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec;
+
+			// draw bottom middle
+			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+			gGL.vertex2fv(x_min.mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+			gGL.vertex2fv((x_max).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			// draw middle
+			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			// draw top middle
+			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+			gGL.vertex2fv((x_max + height_vec).mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+			gGL.vertex2fv((x_min + height_vec).mV);
+		}
+
+		if (end_fragment > middle_end)
+		{
+			u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
+			u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX];
+			x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right);
+			x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
+
+			// draw bottom right
+			gGL.texCoord2f(u_min, 0.f);
+			gGL.vertex2fv((x_min).mV);
+
+			gGL.texCoord2f(u_max, 0.f);
+			gGL.vertex2fv(x_max.mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			// draw right 
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			// draw top right
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f);
+			gGL.vertex2fv((x_max + height_vec).mV);
+
+			gGL.texCoord2f(u_min, 1.f);
+			gGL.vertex2fv((x_min + height_vec).mV);
+		}
+	}
+	gGL.end();
+
+	gGL.popUIMatrix();
+}
+
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, 
+							 const LLVector3& width_vec, const LLVector3& height_vec)
+{
+	gGL.begin(LLRender::QUADS);
+	{
+		// draw bottom left
+		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
+		gGL.vertex3f(0.f, 0.f, 0.f);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
+
+		// draw bottom middle
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		// draw bottom right
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom);
+		gGL.vertex3fv(width_vec.mV);
+
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		// draw left 
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
+
+		// draw middle
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		// draw right 
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		// draw top left
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);
+		gGL.vertex3fv((height_vec).mV);
+
+		// draw top middle
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
+
+		// draw top right
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
+		gGL.vertex3fv((width_vec + height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
+	}
+	gGL.end();
+
+}
+
+// static
+void LLRender2D::initClass(LLImageProviderInterface* image_provider,
+						   const LLVector2* scale_factor)
+{
+	sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
+	sImageProvider = image_provider;
+}
+
+// static
+void LLRender2D::cleanupClass()
+{
+	if(sImageProvider)
+	{
+		sImageProvider->cleanUp();
+	}
+}
+
+
+//static
+void LLRender2D::translate(F32 x, F32 y, F32 z)
+{
+	gGL.translateUI(x,y,z);
+	LLFontGL::sCurOrigin.mX += (S32) x;
+	LLFontGL::sCurOrigin.mY += (S32) y;
+	LLFontGL::sCurDepth += z;
+}
+
+//static
+void LLRender2D::pushMatrix()
+{
+	gGL.pushUIMatrix();
+	LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
+}
+
+//static
+void LLRender2D::popMatrix()
+{
+	gGL.popUIMatrix();
+	LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
+	LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
+	LLFontGL::sOriginStack.pop_back();
+}
+
+//static 
+void LLRender2D::loadIdentity()
+{
+	gGL.loadUIIdentity(); 
+	LLFontGL::sCurOrigin.mX = 0;
+	LLFontGL::sCurOrigin.mY = 0;
+	LLFontGL::sCurDepth = 0.f;
+}
+
+//static
+void LLRender2D::setScaleFactor(const LLVector2 &scale_factor)
+{
+	sGLScaleFactor = scale_factor;
+}
+
+//static
+void LLRender2D::setLineWidth(F32 width)
+{
+	gGL.flush();
+	glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f));
+}
+
+//static
+LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)
+{
+	if (sImageProvider)
+	{
+		return sImageProvider->getUIImageByID(image_id, priority);
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+//static 
+LLPointer<LLUIImage> LLRender2D::getUIImage(const std::string& name, S32 priority)
+{
+	if (!name.empty() && sImageProvider)
+		return sImageProvider->getUIImage(name, priority);
+	else
+		return NULL;
+}
+
diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h
new file mode 100644
index 0000000000000000000000000000000000000000..4884422c58057df9baad42e9e01ecaef598df9c9
--- /dev/null
+++ b/indra/llrender/llrender2dutils.h
@@ -0,0 +1,163 @@
+/** 
+ * @file llrender2dutils.h
+ * @brief GL function declarations for immediate-mode gl drawing.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+// All immediate-mode gl drawing should happen here.
+
+
+#ifndef LL_RENDER2DUTILS_H
+#define LL_RENDER2DUTILS_H
+
+#include "llpointer.h"		// LLPointer<>
+#include "llrect.h"
+#include "llglslshader.h"
+
+class LLColor4; 
+class LLVector3;
+class LLVector2;
+class LLUIImage;
+class LLUUID;
+
+extern const LLColor4 UI_VERTEX_COLOR;
+
+BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
+void gl_state_for_2d(S32 width, S32 height);
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
+void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
+void gl_rect_2d_simple( S32 width, S32 height );
+
+void gl_draw_x(const LLRect& rect, const LLColor4& color);
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
+void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
+void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
+void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
+
+void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
+
+void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
+void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
+void gl_deep_circle( F32 radius, F32 depth );
+void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
+void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
+void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
+void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
+
+void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+
+void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); 
+
+void gl_rect_2d_simple_tex( S32 width, S32 height );
+
+// segmented rectangles
+
+/*
+   TL |______TOP_________| TR 
+     /|                  |\  
+   _/_|__________________|_\_
+   L| |    MIDDLE        | |R
+   _|_|__________________|_|_
+    \ |    BOTTOM        | /  
+   BL\|__________________|/ BR
+      |                  |    
+*/
+
+typedef enum e_rounded_edge
+{
+	ROUNDED_RECT_LEFT	= 0x1, 
+	ROUNDED_RECT_TOP	= 0x2, 
+	ROUNDED_RECT_RIGHT	= 0x4, 
+	ROUNDED_RECT_BOTTOM	= 0x8,
+	ROUNDED_RECT_ALL	= 0xf
+}ERoundedEdge;
+
+
+void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
+void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec);
+
+inline void gl_rect_2d( const LLRect& rect, BOOL filled )
+{
+	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
+}
+
+inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
+{
+	gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
+}
+
+class LLImageProviderInterface;
+
+class LLRender2D
+{
+	LOG_CLASS(LLRender2D);
+public:
+	static void initClass(LLImageProviderInterface* image_provider,
+						  const LLVector2* scale_factor);
+	static void cleanupClass();
+
+	static void pushMatrix();
+	static void popMatrix();
+	static void loadIdentity();
+	static void translate(F32 x, F32 y, F32 z = 0.0f);
+
+	static void setLineWidth(F32 width);
+	static void setScaleFactor(const LLVector2& scale_factor);
+
+	static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
+	static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
+
+	static LLVector2		sGLScaleFactor;
+private:
+	static LLImageProviderInterface* sImageProvider;
+};
+
+class LLImageProviderInterface
+{
+protected:
+	LLImageProviderInterface() {};
+	virtual ~LLImageProviderInterface() {};
+public:
+	virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
+	virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
+	virtual void cleanUp() = 0;
+};
+
+
+extern LLGLSLShader gSolidColorProgram;
+extern LLGLSLShader gUIProgram;
+
+#endif // LL_RENDER2DUTILS_H
+
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index c1b96a43da4439b5cc47a796174db2e215d9981f..5fb4fc8e520b3b26bf549c62d4e8351c734eb9f4 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -579,3 +579,5 @@ void LLRenderTarget::getViewport(S32* viewport)
 	viewport[3] = mResY;
 }
 
+
+
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index cf15f66d318c8902bff8d4fd74cd33736d8c591c..765a727b5b9ea358403491e9ac6bebec8e185fc3 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -28,7 +28,6 @@
 #define LL_LLRENDERTARGET_H
 
 // LLRenderTarget is unavailible on the mapserver since it uses FBOs.
-#if !LL_MESA_HEADLESS
 
 #include "llgl.h"
 #include "llrender.h"
@@ -156,7 +155,5 @@ class LLRenderTarget
 	static LLRenderTarget* sBoundTarget;
 };
 
-#endif //!LL_MESA_HEADLESS
-
 #endif
 
diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
index 569a65c2e0862f4c2b1c1e1a051642f9fe4b9175..093bac20d14c9457f06af0075b205b00850d28c0 100644
--- a/indra/llrender/lltexture.h
+++ b/indra/llrender/lltexture.h
@@ -38,10 +38,9 @@ class LLTexUnit ;
 class LLFontGL ;
 
 //
-//this is an abstract class as the parent for the class LLViewerTexture
-//through the following virtual functions, the class LLViewerTexture can be reached from /llrender.
+//this is an abstract class as the parent for the class LLGLTexture
 //
-class LLTexture : public LLRefCount
+class LLTexture : public virtual LLRefCount
 {
 	friend class LLTexUnit ;
 	friend class LLFontGL ;
@@ -53,7 +52,7 @@ class LLTexture : public LLRefCount
 	LLTexture(){}
 
 	//
-	//interfaces to access LLViewerTexture
+	//interfaces to access LLGLTexture
 	//
 	virtual S8         getType() const = 0 ;
 	virtual void       setKnownDrawSize(S32 width, S32 height) = 0 ;
diff --git a/indra/llui/lluiimage.cpp b/indra/llrender/lluiimage.cpp
similarity index 97%
rename from indra/llui/lluiimage.cpp
rename to indra/llrender/lluiimage.cpp
index 9ed98f941f6a0bf890c70f6bc33cca8e242a6508..b954b66350c9a4c771f1de2a07b587c5e5cb9e73 100644
--- a/indra/llui/lluiimage.cpp
+++ b/indra/llrender/lluiimage.cpp
@@ -31,7 +31,7 @@
 
 // Project includes
 #include "lluiimage.h"
-#include "llui.h"
+#include "llrender2dutils.h"
 
 LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
 :	mName(name),
@@ -130,10 +130,10 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c
 		 }
 	}
 
-	LLUI::pushMatrix();
+	LLRender2D::pushMatrix();
 	{ 
 		LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis); 
-		LLUI::translate(rect_origin.mV[VX],
+		LLRender2D::translate(rect_origin.mV[VX],
 						rect_origin.mV[VY], 
 						rect_origin.mV[VZ]);
 		gGL.getTexUnit(0)->bind(getImage());
@@ -152,7 +152,7 @@ void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, c
 								rect.getWidth() * x_axis, 
 								rect.getHeight() * y_axis);
 		
-	} LLUI::popMatrix();
+	} LLRender2D::popMatrix();
 }
 
 
@@ -209,7 +209,7 @@ namespace LLInitParam
 			return;
 		}
 
-		LLUIImage* imagep =  LLUI::getUIImage(name());
+		LLUIImage* imagep =  LLRender2D::getUIImage(name());
 		if (imagep)
 		{
 			updateValue(imagep);
diff --git a/indra/llui/lluiimage.h b/indra/llrender/lluiimage.h
similarity index 100%
rename from indra/llui/lluiimage.h
rename to indra/llrender/lluiimage.h
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index dfbd8cd4eed705dfaacba315bb56114ff03a1593..4909b43e8aa126be2975054d6eec33fc08c8d4f0 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -402,7 +402,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 {
 	if (sLastMask != data_mask)
 	{
-		bool error = false;
 
 		if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 30)
 		{
@@ -469,7 +468,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 						{
 							if (gDebugSession)
 							{
-								error = true;
 								gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
 							}
 							else
@@ -489,7 +487,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 					{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
 						if (gDebugSession)
 						{
-							error = true;
 							gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
 						}
 						else
@@ -548,8 +545,10 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 }
 
 //static
+static LLFastTimer::DeclareTimer FTM_VB_DRAW_ARRAYS("drawArrays");
 void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
 {
+	LLFastTimer t(FTM_VB_DRAW_ARRAYS);
 	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
 	gGL.syncMatrices();
 
@@ -784,6 +783,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 	placeFence();
 }
 
+static LLFastTimer::DeclareTimer FTM_GL_DRAW_ARRAYS("GL draw arrays");
 void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 {
 	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
@@ -818,8 +818,11 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 		return;
 	}
 
-	stop_glerror();
-	glDrawArrays(sGLMode[mode], first, count);
+	{
+		LLFastTimer t2(FTM_GL_DRAW_ARRAYS);
+		stop_glerror();
+		glDrawArrays(sGLMode[mode], first, count);
+	}
 	stop_glerror();
 	placeFence();
 }
@@ -1565,8 +1568,10 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
 				{
 					if (map_range)
 					{
+#ifndef LL_MESA_HEADLESS
 						glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
 						glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+#endif
 						src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
 					}
 					else
@@ -1740,8 +1745,10 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
 				{
 					if (map_range)
 					{
+#ifndef LL_MESA_HEADLESS
 						glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
 						glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+#endif
 						src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
 					}
 					else
@@ -1868,7 +1875,9 @@ void LLVertexBuffer::unmapBuffer()
 						}
 						else if (gGLManager.mHasFlushBufferRange)
 						{
+#ifndef LL_MESA_HEADLESS
 							glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length);
+#endif
 						}
 						stop_glerror();
 					}
@@ -1934,7 +1943,9 @@ void LLVertexBuffer::unmapBuffer()
 						else if (gGLManager.mHasFlushBufferRange)
 						{
 #ifdef GL_APPLE_flush_buffer_range
+#ifndef LL_MESA_HEADLESS
 							glFlushMappedBufferRangeAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
+#endif
 #endif
 						}
 						stop_glerror();
@@ -2209,7 +2220,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 			setup = setup || bindBuffer || bindIndices;
 		}
 
-		bool error = false;
 		if (gDebugGL && !mGLArray)
 		{
 			GLint buff;
@@ -2218,7 +2228,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 			{
 				if (gDebugSession)
 				{
-					error = true;
 					gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
 				}
 				else
@@ -2234,7 +2243,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 				{
 					if (gDebugSession)
 					{
-						error = true;
 						gFailLog << "Invalid GL index buffer bound: " << buff <<  std::endl;
 					}
 					else
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 9c961d67d6f16f0558100a81f0b90d2095f92a56..34a08603fabdb165486892b21c9cc69b2faf6923 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -25,6 +25,10 @@ include_directories(
     ${LLXML_INCLUDE_DIRS}
     ${LIBS_PREBUILD_DIR}/include/hunspell
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llui_SOURCE_FILES
     llaccordionctrl.cpp
@@ -113,7 +117,6 @@ set(llui_SOURCE_FILES
     lluicolortable.cpp
     lluictrl.cpp
     lluictrlfactory.cpp
-    lluiimage.cpp
     lluistring.cpp
     llundo.cpp
     llurlaction.cpp
@@ -227,7 +230,6 @@ set(llui_HEADER_FILES
     lluifwd.h
     llui.h
     lluicolor.h
-    lluiimage.h
     lluistring.h
     llundo.h
     llurlaction.h
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 41e5d74042f112f8eae50ea0af3c250442d21e5c..d4e14d94190bcaa4d5d8c4867b8f8737d94cfc8c 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -551,7 +551,7 @@ void LLComboBox::showList()
 	LLCoordWindow window_size;
 	getWindow()->getSize(&window_size);
 	//HACK: shouldn't have to know about scale here
-	mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 );
+	mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::getScaleFactor().mV[VY]) - 50 );
 
 	// Make sure that we can see the whole list
 	LLRect root_view_local;
diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp
index 161496b1f5a36b9a37bb8875e4c9d64c8e6c0396..c216d593a249693700ab7e2f01c3da3f77a0a5d4 100644
--- a/indra/llui/llconsole.cpp
+++ b/indra/llui/llconsole.cpp
@@ -243,7 +243,6 @@ void LLConsole::draw()
 void LLConsole::Paragraph::makeParagraphColorSegments (const LLColor4 &color) 
 {
 	LLSD paragraph_color_segments;
-	LLColor4 lcolor=color;
 	
 	paragraph_color_segments[0]["text"] =wstring_to_utf8str(mParagraphText);
 	LLSD color_sd = color.getValue();
diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index 8feaf654f05e63c7a7d6dc5fdeca095a6f43ef47..8aa1eb7cd59b68196cd660c169914ce8b3f30a47 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1055,12 +1055,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 		LLMenuGL::sMenuContainer->hideMenus();
 	}
 
-	LLView *item = NULL;
-	if (getChildCount() > 0)
-	{
-		item = *(getChildList()->begin());
-	}
-
 	switch( key )
 	{
 	case KEY_F2:
diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h
index 899cc3a326304e7aecd40c4e5dcd21b0ba59fe78..beac21244192a1dcd9637237693db331eeb381c0 100644
--- a/indra/llui/llfunctorregistry.h
+++ b/indra/llui/llfunctorregistry.h
@@ -69,7 +69,6 @@ class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> >
 	bool registerFunctor(const std::string& name, ResponseFunctor f)
 	{
 		bool retval = true;
-		typename FunctorMap::iterator it = mMap.find(name);
 		if (mMap.count(name) == 0)
 		{
 			mMap[name] = f;
@@ -96,7 +95,6 @@ class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> >
 
 	FUNCTOR_TYPE getFunctor(const std::string& name)
 	{
-		typename FunctorMap::iterator it = mMap.find(name);
 		if (mMap.count(name) != 0)
 		{
 			return mMap[name];
diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp
index c1cd04186bda56afc329e0a255bc46269f56408f..795dacdbb069702ee69888eba6cd72200847c316 100644
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -367,7 +367,6 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
 
 	const llwchar* base = wtext.c_str();
 	const llwchar* cur = base;
-	const llwchar* line = NULL;
 
 	while( *cur )
 	{
@@ -385,9 +384,6 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
 				}
 			}
 
-			// Start of a new line
-			line = cur;
-
 			// Skip white space
 			while( *cur && isspace(*cur) && (*cur != '\n')  )
 			{
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index e64288399133a970e51946e4475ec92691974ef0..e33ac1d5c263bbd4e6d441db4d2a442af83d87c9 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -476,7 +476,6 @@ void LLLayoutStack::createResizeBar(LLLayoutPanel* panelp)
 		if (lp->mResizeBar == NULL)
 		{
 			LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
-			LLRect resize_bar_rect = getRect();
 
 			LLResizeBar::Params resize_params;
 			resize_params.name("resize");
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 6976b06a924b2b4c7317382dffeca88f8dafa3b8..5478e85e13a01842bb4f359d95e2167d398491b5 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -2023,8 +2023,8 @@ void LLLineEditor::draw()
 				LLRect screen_pos = calcScreenRect();
 				LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - lineeditor_v_pad );
 
-				ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
-				ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
+				ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
+				ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
 				getWindow()->setLanguageTextInput( ime_pos );
 			}
 		}
@@ -2571,7 +2571,7 @@ void LLLineEditor::markAsPreedit(S32 position, S32 length)
 
 S32 LLLineEditor::getPreeditFontSize() const
 {
-	return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+	return llround(mGLFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);
 }
 
 void LLLineEditor::setReplaceNewlinesWithSpaces(BOOL replace)
diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp
index 6841301219427752c66f74675a2f5201d15a7fae..0620e0f52d972af82466c07e3fea403801a930ab 100644
--- a/indra/llui/lllocalcliprect.cpp
+++ b/indra/llui/lllocalcliprect.cpp
@@ -33,7 +33,7 @@
 
 
 LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled)
-:	mScissorState(GL_SCISSOR_TEST),
+	:	mScissorState(GL_SCISSOR_TEST),
 	mEnabled(enabled)
 {
 	if (mEnabled)
@@ -88,10 +88,10 @@ void LLScreenClipRect::updateScissorRegion()
 	LLRect rect = sClipRectStack.top();
 	stop_glerror();
 	S32 x,y,w,h;
-	x = llfloor(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]);
-	y = llfloor(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]);
-	w = llmax(0, llceil(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX])) + 1;
-	h = llmax(0, llceil(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY])) + 1;
+	x = llfloor(rect.mLeft * LLUI::getScaleFactor().mV[VX]);
+	y = llfloor(rect.mBottom * LLUI::getScaleFactor().mV[VY]);
+	w = llmax(0, llceil(rect.getWidth() * LLUI::getScaleFactor().mV[VX])) + 1;
+	h = llmax(0, llceil(rect.getHeight() * LLUI::getScaleFactor().mV[VY])) + 1;
 	glScissor( x,y,w,h );
 	stop_glerror();
 }
@@ -100,10 +100,10 @@ void LLScreenClipRect::updateScissorRegion()
 // LLLocalClipRect
 //---------------------------------------------------------------------------
 LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */)
-:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX, 
-					rect.mTop + LLFontGL::sCurOrigin.mY, 
-					rect.mRight + LLFontGL::sCurOrigin.mX, 
-					rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)
+	:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX, 
+	rect.mTop + LLFontGL::sCurOrigin.mY, 
+	rect.mRight + LLFontGL::sCurOrigin.mX, 
+	rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)
 {}
 
 LLLocalClipRect::~LLLocalClipRect()
diff --git a/indra/llui/llspellcheck.cpp b/indra/llui/llspellcheck.cpp
index a189375fbea58d3c2f9a4469c09c8bf0c7bccbf9..250372da5ba461823ffb2b0902f9e3edd6a1163e 100644
--- a/indra/llui/llspellcheck.cpp
+++ b/indra/llui/llspellcheck.cpp
@@ -145,10 +145,14 @@ void LLSpellChecker::refreshDictionaryMap()
 
 	// Load dictionary information (file name, friendly name, ...)
 	llifstream user_file(user_path + DICT_FILE_MAIN, std::ios::binary);
-	if ( (!user_file.is_open()) || (0 == LLSDSerialize::fromXMLDocument(sDictMap, user_file)) || (0 == sDictMap.size()) )
+	if ( (!user_file.is_open()) 
+		|| (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(sDictMap, user_file)) 
+		|| (0 == sDictMap.size()) )
 	{
 		llifstream app_file(app_path + DICT_FILE_MAIN, std::ios::binary);
-		if ( (!app_file.is_open()) || (0 == LLSDSerialize::fromXMLDocument(sDictMap, app_file)) || (0 == sDictMap.size()) )
+		if ( (!app_file.is_open()) 
+			|| (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(sDictMap, app_file)) 
+			|| (0 == sDictMap.size()) )
 		{
 			return;
 		}
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 6f895ed939a54dc369d2be2a400127f1d0a5c6d4..fd981557047697b291af17e4791b04de1d723234 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -1215,9 +1215,11 @@ void LLTabContainer::removeTabPanel(LLPanel* child)
 				removeChild( tuple->mButton );
 			}
  			delete tuple->mButton;
+            tuple->mButton = NULL;
 
  			removeChild( tuple->mTabPanel );
 // 			delete tuple->mTabPanel;
+            tuple->mTabPanel = NULL;
 			
 			mTabList.erase( iter );
 			delete tuple;
@@ -1279,9 +1281,11 @@ void LLTabContainer::deleteAllTabs()
 
 		removeChild( tuple->mButton );
 		delete tuple->mButton;
+        tuple->mButton = NULL;
 
  		removeChild( tuple->mTabPanel );
 // 		delete tuple->mTabPanel;
+        tuple->mTabPanel = NULL;
 	}
 
 	// Actually delete the tuples themselves
@@ -1484,9 +1488,8 @@ BOOL LLTabContainer::setTab(S32 which)
 		{
 			LLTabTuple* tuple = *iter;
 			BOOL is_selected = ( tuple == selected_tuple );
-            
             // Although the selected tab must be complete, we may have hollow LLTabTuple tucked in the list
-            if (tuple->mButton)
+            if (tuple && tuple->mButton)
             {
                 tuple->mButton->setUseEllipses(mUseTabEllipses);
                 tuple->mButton->setHAlign(mFontHalign);
@@ -1494,7 +1497,7 @@ BOOL LLTabContainer::setTab(S32 which)
                 // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs
                 tuple->mButton->setTabStop( is_selected );
             }
-            if (tuple->mTabPanel)
+            if (tuple && tuple->mTabPanel)
             {
                 tuple->mTabPanel->setVisible( is_selected );
                 //tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here.
@@ -1525,7 +1528,7 @@ BOOL LLTabContainer::setTab(S32 which)
 					else
 					{
 						S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size  + tabcntr_arrow_btn_size + 1);
-						S32 running_tab_width = tuple->mButton->getRect().getWidth();
+						S32 running_tab_width = (tuple && tuple->mButton ? tuple->mButton->getRect().getWidth() : 0);
 						S32 j = i - 1;
 						S32 min_scroll_pos = i;
 						if (running_tab_width < available_width_with_arrows)
@@ -1533,7 +1536,7 @@ BOOL LLTabContainer::setTab(S32 which)
 							while (j >= 0)
 							{
 								LLTabTuple* other_tuple = getTab(j);
-								running_tab_width += other_tuple->mButton->getRect().getWidth();
+								running_tab_width += (other_tuple && other_tuple->mButton ? other_tuple->mButton->getRect().getWidth() : 0);
 								if (running_tab_width > available_width_with_arrows)
 								{
 									break;
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index a815cfc1767a6c80efff704a8b6f26267af45619..e70992129a6fd9a754422365ec9e846e51f8a128 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -443,6 +443,7 @@ void LLTextBase::drawSelectionBackground()
 			++rect_it)
 		{
 			LLRect selection_rect = *rect_it;
+			selection_rect = *rect_it;
 			selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
 			gl_rect_2d(selection_rect, selection_color);
 		}
@@ -520,8 +521,8 @@ void LLTextBase::drawCursor()
 			LLRect screen_pos = calcScreenRect();
 			LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_rect.mLeft), screen_pos.mBottom + llfloor(cursor_rect.mTop) );
 
-			ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
-			ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
+			ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
+			ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
 			getWindow()->setLanguageTextInput( ime_pos );
 		}
 	}
@@ -1917,7 +1918,6 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
 	registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, url));
 	registrar.add("Url.Teleport", boost::bind(&LLUrlAction::teleportToLocation, url));
 	registrar.add("Url.ShowProfile", boost::bind(&LLUrlAction::showProfile, url));
-	registrar.add("Url.SendIM", boost::bind(&LLUrlAction::sendIM, url));
 	registrar.add("Url.AddFriend", boost::bind(&LLUrlAction::addFriend, url));
 	registrar.add("Url.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
 	registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index b8bdea48b50a3becfb6966c706c3417547b36725..834f21309707f71d92f85d9cd2978d62b394fb17 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -2917,7 +2917,7 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length)
 
 S32 LLTextEditor::getPreeditFontSize() const
 {
-	return llround((F32)mFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+	return llround((F32)mFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);
 }
 
 BOOL LLTextEditor::isDirty() const
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 1c74395c666b6812a0f79e9fe3733f664a83fce9..3d9f5cbbc232822be501c93860ec10342c2a0a15 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -653,7 +653,6 @@ void LLToolBar::updateLayoutAsNeeded()
 	S32 max_row_length = 0;
 
 	S32 max_length;
-	S32 max_total_girth;
 	S32 cur_start;
 	S32 cur_row ;
 	S32 row_pad_start;
@@ -664,7 +663,6 @@ void LLToolBar::updateLayoutAsNeeded()
 	if (orientation == LLLayoutStack::HORIZONTAL)
 	{
 		max_length = getRect().getWidth() - mPadLeft - mPadRight;
-		max_total_girth = getRect().getHeight() - mPadTop - mPadBottom;
 		row_pad_start = mPadLeft;
 		row_pad_end = mPadRight;
 		cur_row = mPadTop;
@@ -673,7 +671,6 @@ void LLToolBar::updateLayoutAsNeeded()
 	else // VERTICAL
 	{
 		max_length = getRect().getHeight() - mPadTop - mPadBottom;
-		max_total_girth = getRect().getWidth() - mPadLeft - mPadRight;
 		row_pad_start = mPadTop;
 		row_pad_end = mPadBottom;
 		cur_row = mPadLeft;
@@ -841,7 +838,6 @@ void LLToolBar::draw()
 	if (mDragAndDropTarget && !mButtonCommands.empty())
 	{
 		LLRect caret_rect = caret->getRect();
-		LLRect toolbar_rect = getRect();
 		if (getOrientation(mSideType) == LLLayoutStack::HORIZONTAL)
 		{
 			caret->setRect(LLRect(mDragx-caret_rect.getWidth()/2+1,
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 2a774d54a3a0ab044bddfda8f698d6e812c77422..0ddb14973831628f9fc1922909aaafc6e7dd11a6 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -39,6 +39,7 @@
 #include "llrect.h"
 #include "lldir.h"
 #include "llgl.h"
+#include "llsd.h"
 
 // Project includes
 #include "llcommandmanager.h"
@@ -69,16 +70,13 @@
 //
 // Globals
 //
-const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
 
 // Language for UI construction
 std::map<std::string, std::string> gTranslation;
 std::list<std::string> gUntranslated;
 /*static*/ LLUI::settings_map_t LLUI::sSettingGroups;
-/*static*/ LLImageProviderInterface* LLUI::sImageProvider = NULL;
 /*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
 /*static*/ LLUIAudioCallback LLUI::sDeferredAudioCallback = NULL;
-/*static*/ LLVector2		LLUI::sGLScaleFactor(1.f, 1.f);
 /*static*/ LLWindow*		LLUI::sWindow = NULL;
 /*static*/ LLView*			LLUI::sRootView = NULL;
 /*static*/ BOOL                         LLUI::sDirty = FALSE;
@@ -158,1474 +156,6 @@ void make_ui_sound_deferred(const char* namep)
 	}
 }
 
-BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
-{
-	if (x < left || right < x) return FALSE;
-	if (y < bottom || top < y) return FALSE;
-	return TRUE;
-}
-
-
-// Puts GL into 2D drawing mode by turning off lighting, setting to an
-// orthographic projection, etc.
-void gl_state_for_2d(S32 width, S32 height)
-{
-	stop_glerror();
-	F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
-	F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
-
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.loadIdentity();
-	gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.loadIdentity();
-	stop_glerror();
-}
-
-
-void gl_draw_x(const LLRect& rect, const LLColor4& color)
-{
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.color4fv( color.mV );
-
-	gGL.begin( LLRender::LINES );
-		gGL.vertex2i( rect.mLeft,		rect.mTop );
-		gGL.vertex2i( rect.mRight,	rect.mBottom );
-		gGL.vertex2i( rect.mLeft,		rect.mBottom );
-		gGL.vertex2i( rect.mRight,	rect.mTop );
-	gGL.end();
-}
-
-
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled)
-{
-	gGL.color4fv(color.mV);
-	gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
-}
-
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
-{
-	gGL.pushUIMatrix();
-	left += LLFontGL::sCurOrigin.mX;
-	right += LLFontGL::sCurOrigin.mX;
-	bottom += LLFontGL::sCurOrigin.mY;
-	top += LLFontGL::sCurOrigin.mY;
-
-	gGL.loadUIIdentity();
-	gl_rect_2d(llfloor((F32)left * LLUI::sGLScaleFactor.mV[VX]) - pixel_offset,
-				llfloor((F32)top * LLUI::sGLScaleFactor.mV[VY]) + pixel_offset,
-				llfloor((F32)right * LLUI::sGLScaleFactor.mV[VX]) + pixel_offset,
-				llfloor((F32)bottom * LLUI::sGLScaleFactor.mV[VY]) - pixel_offset,
-				filled);
-	gGL.popUIMatrix();
-}
-
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
-{
-	stop_glerror();
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	// Counterclockwise quad will face the viewer
-	if( filled )
-	{ 
-		gGL.begin( LLRender::QUADS );
-			gGL.vertex2i(left, top);
-			gGL.vertex2i(left, bottom);
-			gGL.vertex2i(right, bottom);
-			gGL.vertex2i(right, top);
-		gGL.end();
-	}
-	else
-	{
-		if( gGLManager.mATIOffsetVerticalLines )
-		{
-			// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
-			gGL.begin( LLRender::LINES );
-
-				// Verticals 
-				gGL.vertex2i(left + 1, top);
-				gGL.vertex2i(left + 1, bottom);
-
-				gGL.vertex2i(right, bottom);
-				gGL.vertex2i(right, top);
-
-				// Horizontals
-				top--;
-				right--;
-				gGL.vertex2i(left, bottom);
-				gGL.vertex2i(right, bottom);
-
-				gGL.vertex2i(left, top);
-				gGL.vertex2i(right, top);
-			gGL.end();
-		}
-		else
-		{
-			top--;
-			right--;
-			gGL.begin( LLRender::LINE_STRIP );
-				gGL.vertex2i(left, top);
-				gGL.vertex2i(left, bottom);
-				gGL.vertex2i(right, bottom);
-				gGL.vertex2i(right, top);
-				gGL.vertex2i(left, top);
-			gGL.end();
-		}
-	}
-	stop_glerror();
-}
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
-{
-	gGL.color4fv( color.mV );
-	gl_rect_2d( left, top, right, bottom, filled );
-}
-
-
-void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
-{
-	gGL.color4fv( color.mV );
-	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
-}
-
-// Given a rectangle on the screen, draws a drop shadow _outside_
-// the right and bottom edges of it.  Along the right it has width "lines"
-// and along the bottom it has height "lines".
-void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines)
-{
-	stop_glerror();
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	
-	// HACK: Overlap with the rectangle by a single pixel.
-	right--;
-	bottom++;
-	lines++;
-
-	LLColor4 end_color = start_color;
-	end_color.mV[VALPHA] = 0.f;
-
-	gGL.begin(LLRender::QUADS);
-
-	// Right edge, CCW faces screen
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(right,		top-lines);
-	gGL.vertex2i(right,		bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(right+lines, bottom);
-	gGL.vertex2i(right+lines, top-lines);
-
-	// Bottom edge, CCW faces screen
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(right,		bottom);
-	gGL.vertex2i(left+lines,	bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(left+lines,	bottom-lines);
-	gGL.vertex2i(right,		bottom-lines);
-
-	// bottom left Corner
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(left+lines,	bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(left,		bottom);
-	// make the bottom left corner not sharp
-	gGL.vertex2i(left+1,		bottom-lines+1);
-	gGL.vertex2i(left+lines,	bottom-lines);
-
-	// bottom right corner
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(right,		bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(right,		bottom-lines);
-	// make the rightmost corner not sharp
-	gGL.vertex2i(right+lines-1,	bottom-lines+1);
-	gGL.vertex2i(right+lines,	bottom);
-
-	// top right corner
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i( right,			top-lines );
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i( right+lines,	top-lines );
-	// make the corner not sharp
-	gGL.vertex2i( right+lines-1,	top-1 );
-	gGL.vertex2i( right,			top );
-
-	gGL.end();
-	stop_glerror();
-}
-
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
-{
-	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
-	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
-	{
-		x1++;
-		x2++;
-		y1++;
-		y2++;
-	}
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	
-	gGL.begin(LLRender::LINES);
-		gGL.vertex2i(x1, y1);
-		gGL.vertex2i(x2, y2);
-	gGL.end();
-}
-
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
-{
-	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
-	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
-	{
-		x1++;
-		x2++;
-		y1++;
-		y2++;
-	}
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.color4fv( color.mV );
-
-	gGL.begin(LLRender::LINES);
-		gGL.vertex2i(x1, y1);
-		gGL.vertex2i(x2, y2);
-	gGL.end();
-}
-
-void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
-{
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.color4fv(color.mV);
-
-	if (filled)
-	{
-		gGL.begin(LLRender::TRIANGLES);
-	}
-	else
-	{
-		gGL.begin(LLRender::LINE_LOOP);
-	}
-	gGL.vertex2i(x1, y1);
-	gGL.vertex2i(x2, y2);
-	gGL.vertex2i(x3, y3);
-	gGL.end();
-}
-
-void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac)
-{
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	length = llmin((S32)(max_frac*(right - left)), length);
-	length = llmin((S32)(max_frac*(top - bottom)), length);
-	gGL.begin(LLRender::LINES);
-	gGL.vertex2i(left, top);
-	gGL.vertex2i(left + length, top);
-	
-	gGL.vertex2i(left, top);
-	gGL.vertex2i(left, top - length);
-
-	gGL.vertex2i(left, bottom);
-	gGL.vertex2i(left + length, bottom);
-	
-	gGL.vertex2i(left, bottom);
-	gGL.vertex2i(left, bottom + length);
-
-	gGL.vertex2i(right, top);
-	gGL.vertex2i(right - length, top);
-
-	gGL.vertex2i(right, top);
-	gGL.vertex2i(right, top - length);
-
-	gGL.vertex2i(right, bottom);
-	gGL.vertex2i(right - length, bottom);
-
-	gGL.vertex2i(right, bottom);
-	gGL.vertex2i(right, bottom + length);
-	gGL.end();
-}
-
-
-void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect )
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
-}
-
-void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-	gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
-}
-
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect)
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-
-	// scale screen size of borders down
-	F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0);
-	F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
-
-	LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
-	gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
-}
-
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect)
-{
-	stop_glerror();
-
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-
-	// add in offset of current image to current UI translation
-	const LLVector3 ui_scale = gGL.getUIScale();
-	const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
-
-	F32 uv_width = uv_outer_rect.getWidth();
-	F32 uv_height = uv_outer_rect.getHeight();
-
-	// shrink scaling region to be proportional to clipped image region
-	LLRectf uv_center_rect(
-		uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
-		uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
-		uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
-		uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
-
-	F32 image_width = image->getWidth(0);
-	F32 image_height = image->getHeight(0);
-
-	S32 image_natural_width = llround(image_width * uv_width);
-	S32 image_natural_height = llround(image_height * uv_height);
-
-	LLRectf draw_center_rect(	uv_center_rect.mLeft * image_width,
-								uv_center_rect.mTop * image_height,
-								uv_center_rect.mRight * image_width,
-								uv_center_rect.mBottom * image_height);
-
-	{	// scale fixed region of image to drawn region
-		draw_center_rect.mRight += width - image_natural_width;
-		draw_center_rect.mTop += height - image_natural_height;
-
-		F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
-		F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
-
-		F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
-		F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
-
-		F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
-
-		draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]);
-		draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]);
-		draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]);
-		draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]);
-	}
-
-	LLRectf draw_outer_rect(ui_translation.mV[VX], 
-							ui_translation.mV[VY] + height * ui_scale.mV[VY], 
-							ui_translation.mV[VX] + width * ui_scale.mV[VX], 
-							ui_translation.mV[VY]);
-
-	LLGLSUIDefault gls_ui;
-	
-	if (solid_color)
-	{
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gSolidColorProgram.bind();
-		}
-		else
-		{
-			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
-			gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
-		}
-	}
-
-	gGL.getTexUnit(0)->bind(image, true);
-
-	gGL.color4fv(color.mV);
-	
-	const S32 NUM_VERTICES = 9 * 4; // 9 quads
-	LLVector2 uv[NUM_VERTICES];
-	LLVector3 pos[NUM_VERTICES];
-
-	S32 index = 0;
-
-	gGL.begin(LLRender::QUADS);
-	{
-		// draw bottom left
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		// draw bottom middle
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		// draw bottom right
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		// draw left 
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		// draw middle
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		// draw right 
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		// draw top left
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		// draw top middle
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		// draw top right
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
-	}
-	gGL.end();
-
-	if (solid_color)
-	{
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gUIProgram.bind();
-		}
-		else
-		{
-			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-		}
-	}
-}
-
-void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
-	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
-}
-
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-
-	LLGLSUIDefault gls_ui;
-
-
-	gGL.getTexUnit(0)->bind(image, true);
-
-	gGL.color4fv(color.mV);
-
-	if (degrees == 0.f)
-	{
-		const S32 NUM_VERTICES = 4; // 9 quads
-		LLVector2 uv[NUM_VERTICES];
-		LLVector3 pos[NUM_VERTICES];
-
-		gGL.begin(LLRender::QUADS);
-		{
-			LLVector3 ui_scale = gGL.getUIScale();
-			LLVector3 ui_translation = gGL.getUITranslation();
-			ui_translation.mV[VX] += x;
-			ui_translation.mV[VY] += y;
-			ui_translation.scaleVec(ui_scale);
-			S32 index = 0;
-			S32 scaled_width = llround(width * ui_scale.mV[VX]);
-			S32 scaled_height = llround(height * ui_scale.mV[VY]);
-
-			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
-			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
-			index++;
-
-			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
-			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
-			index++;
-
-			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
-			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
-			index++;
-
-			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
-			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
-			index++;
-
-			gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
-		}
-		gGL.end();
-	}
-	else
-	{
-		gGL.pushUIMatrix();
-		gGL.translateUI((F32)x, (F32)y, 0.f);
-	
-		F32 offset_x = F32(width/2);
-		F32 offset_y = F32(height/2);
-
-		gGL.translateUI(offset_x, offset_y, 0.f);
-
-		LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
-		
-		gGL.getTexUnit(0)->bind(image, true);
-
-		gGL.color4fv(color.mV);
-		
-		gGL.begin(LLRender::QUADS);
-		{
-			LLVector3 v;
-
-			v = LLVector3(offset_x, offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-
-			v = LLVector3(-offset_x, offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-
-			v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-
-			v = LLVector3(offset_x, -offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-		}
-		gGL.end();
-		gGL.popUIMatrix();
-	}
-}
-
-
-void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
-{
-	phase = fmod(phase, 1.f);
-
-	S32 shift = S32(phase * 4.f) % 4;
-
-	// Stippled line
-	LLGLEnable stipple(GL_LINE_STIPPLE);
-	
-	gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
-
-	gGL.flush();
-	glLineWidth(2.5f);
-
-	if (!LLGLSLShader::sNoFixedFunction)
-	{
-		glLineStipple(2, 0x3333 << shift);
-	}
-
-	gGL.begin(LLRender::LINES);
-	{
-		gGL.vertex3fv( start.mV );
-		gGL.vertex3fv( end.mV );
-	}
-	gGL.end();
-
-	LLUI::setLineWidth(1.f);
-}
-
-void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
-{
-	if (end_angle < start_angle)
-	{
-		end_angle += F_TWO_PI;
-	}
-
-	gGL.pushUIMatrix();
-	{
-		gGL.translateUI(center_x, center_y, 0.f);
-
-		// Inexact, but reasonably fast.
-		F32 delta = (end_angle - start_angle) / steps;
-		F32 sin_delta = sin( delta );
-		F32 cos_delta = cos( delta );
-		F32 x = cosf(start_angle) * radius;
-		F32 y = sinf(start_angle) * radius;
-
-		if (filled)
-		{
-			gGL.begin(LLRender::TRIANGLE_FAN);
-			gGL.vertex2f(0.f, 0.f);
-			// make sure circle is complete
-			steps += 1;
-		}
-		else
-		{
-			gGL.begin(LLRender::LINE_STRIP);
-		}
-
-		while( steps-- )
-		{
-			// Successive rotations
-			gGL.vertex2f( x, y );
-			F32 x_new = x * cos_delta - y * sin_delta;
-			y = x * sin_delta +  y * cos_delta;
-			x = x_new;
-		}
-		gGL.end();
-	}
-	gGL.popUIMatrix();
-}
-
-void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
-{
-	gGL.pushUIMatrix();
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		gGL.translateUI(center_x, center_y, 0.f);
-
-		// Inexact, but reasonably fast.
-		F32 delta = F_TWO_PI / steps;
-		F32 sin_delta = sin( delta );
-		F32 cos_delta = cos( delta );
-		F32 x = radius;
-		F32 y = 0.f;
-
-		if (filled)
-		{
-			gGL.begin(LLRender::TRIANGLE_FAN);
-			gGL.vertex2f(0.f, 0.f);
-			// make sure circle is complete
-			steps += 1;
-		}
-		else
-		{
-			gGL.begin(LLRender::LINE_LOOP);
-		}
-
-		while( steps-- )
-		{
-			// Successive rotations
-			gGL.vertex2f( x, y );
-			F32 x_new = x * cos_delta - y * sin_delta;
-			y = x * sin_delta +  y * cos_delta;
-			x = x_new;
-		}
-		gGL.end();
-	}
-	gGL.popUIMatrix();
-}
-
-// Renders a ring with sides (tube shape)
-void gl_deep_circle( F32 radius, F32 depth, S32 steps )
-{
-	F32 x = radius;
-	F32 y = 0.f;
-	F32 angle_delta = F_TWO_PI / (F32)steps;
-	gGL.begin( LLRender::TRIANGLE_STRIP  );
-	{
-		S32 step = steps + 1; // An extra step to close the circle.
-		while( step-- )
-		{
-			gGL.vertex3f( x, y, depth );
-			gGL.vertex3f( x, y, 0.f );
-
-			F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta);
-			y = x * sinf(angle_delta) +  y * cosf(angle_delta);
-			x = x_new;
-		}
-	}
-	gGL.end();
-}
-
-void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
-{
-	gGL.pushUIMatrix();
-	{
-		gGL.translateUI(0.f, 0.f, -width / 2);
-		if( render_center )
-		{
-			gGL.color4fv(center_color.mV);
-			gGL.diffuseColor4fv(center_color.mV);
-			gl_deep_circle( radius, width, steps );
-		}
-		else
-		{
-			gGL.diffuseColor4fv(side_color.mV);
-			gl_washer_2d(radius, radius - width, steps, side_color, side_color);
-			gGL.translateUI(0.f, 0.f, width);
-			gl_washer_2d(radius - width, radius, steps, side_color, side_color);
-		}
-	}
-	gGL.popUIMatrix();
-}
-
-// Draw gray and white checkerboard with black border
-void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
-{
-	if (!LLGLSLShader::sNoFixedFunction)
-	{ 
-	// Initialize the first time this is called.
-	const S32 PIXELS = 32;
-	static GLubyte checkerboard[PIXELS * PIXELS];
-	static BOOL first = TRUE;
-	if( first )
-	{
-		for( S32 i = 0; i < PIXELS; i++ )
-		{
-			for( S32 j = 0; j < PIXELS; j++ )
-			{
-				checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
-			}
-		}
-		first = FALSE;
-	}
-	
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	// ...white squares
-	gGL.color4f( 1.f, 1.f, 1.f, alpha );
-	gl_rect_2d(rect);
-
-	// ...gray squares
-	gGL.color4f( .7f, .7f, .7f, alpha );
-	gGL.flush();
-
-		glPolygonStipple( checkerboard );
-
-		LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
-		gl_rect_2d(rect);
-	}
-	else
-	{ //polygon stipple is deprecated, use "Checker" texture
-		LLPointer<LLUIImage> img = LLUI::getUIImage("Checker");
-		gGL.getTexUnit(0)->bind(img->getImage());
-		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
-		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-
-		LLColor4 color(1.f, 1.f, 1.f, alpha);
-		LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
-
-		gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(),
-			img->getImage(), color, uv_rect);
-	}
-	
-	gGL.flush();
-}
-
-
-// Draws the area between two concentric circles, like
-// a doughnut or washer.
-void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
-{
-	const F32 DELTA = F_TWO_PI / steps;
-	const F32 SIN_DELTA = sin( DELTA );
-	const F32 COS_DELTA = cos( DELTA );
-
-	F32 x1 = outer_radius;
-	F32 y1 = 0.f;
-	F32 x2 = inner_radius;
-	F32 y2 = 0.f;
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.begin( LLRender::TRIANGLE_STRIP  );
-	{
-		steps += 1; // An extra step to close the circle.
-		while( steps-- )
-		{
-			gGL.color4fv(outer_color.mV);
-			gGL.vertex2f( x1, y1 );
-			gGL.color4fv(inner_color.mV);
-			gGL.vertex2f( x2, y2 );
-
-			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
-			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
-			x1 = x1_new;
-
-			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
-			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
-			x2 = x2_new;
-		}
-	}
-	gGL.end();
-}
-
-// Draws the area between two concentric circles, like
-// a doughnut or washer.
-void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
-{
-	const F32 DELTA = (end_radians - start_radians) / steps;
-	const F32 SIN_DELTA = sin( DELTA );
-	const F32 COS_DELTA = cos( DELTA );
-
-	F32 x1 = outer_radius * cos( start_radians );
-	F32 y1 = outer_radius * sin( start_radians );
-	F32 x2 = inner_radius * cos( start_radians );
-	F32 y2 = inner_radius * sin( start_radians );
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	gGL.begin( LLRender::TRIANGLE_STRIP  );
-	{
-		steps += 1; // An extra step to close the circle.
-		while( steps-- )
-		{
-			gGL.color4fv(outer_color.mV);
-			gGL.vertex2f( x1, y1 );
-			gGL.color4fv(inner_color.mV);
-			gGL.vertex2f( x2, y2 );
-
-			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
-			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
-			x1 = x1_new;
-
-			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
-			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
-			x2 = x2_new;
-		}
-	}
-	gGL.end();
-}
-
-void gl_rect_2d_simple_tex( S32 width, S32 height )
-{
-	gGL.begin( LLRender::QUADS );
-
-		gGL.texCoord2f(1.f, 1.f);
-		gGL.vertex2i(width, height);
-
-		gGL.texCoord2f(0.f, 1.f);
-		gGL.vertex2i(0, height);
-
-		gGL.texCoord2f(0.f, 0.f);
-		gGL.vertex2i(0, 0);
-
-		gGL.texCoord2f(1.f, 0.f);
-		gGL.vertex2i(width, 0);
-	
-	gGL.end();
-}
-
-void gl_rect_2d_simple( S32 width, S32 height )
-{
-	gGL.begin( LLRender::QUADS );
-		gGL.vertex2i(width, height);
-		gGL.vertex2i(0, height);
-		gGL.vertex2i(0, 0);
-		gGL.vertex2i(width, 0);
-	gGL.end();
-}
-
-void gl_segmented_rect_2d_tex(const S32 left, 
-							  const S32 top, 
-							  const S32 right, 
-							  const S32 bottom, 
-							  const S32 texture_width, 
-							  const S32 texture_height, 
-							  const S32 border_size, 
-							  const U32 edges)
-{
-	S32 width = llabs(right - left);
-	S32 height = llabs(top - bottom);
-
-	gGL.pushUIMatrix();
-
-	gGL.translateUI((F32)left, (F32)bottom, 0.f);
-	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
-
-	if (border_uv_scale.mV[VX] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
-	}
-	if (border_uv_scale.mV[VY] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
-	}
-
-	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
-	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 width_vec((F32)width, 0.f);
-	LLVector2 height_vec(0.f, (F32)height);
-
-	gGL.begin(LLRender::QUADS);
-	{
-		// draw bottom left
-		gGL.texCoord2f(0.f, 0.f);
-		gGL.vertex2f(0.f, 0.f);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv(border_width_left.mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv(border_height_bottom.mV);
-
-		// draw bottom middle
-		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv(border_width_left.mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv((width_vec - border_width_right).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		// draw bottom right
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv((width_vec - border_width_right).mV);
-
-		gGL.texCoord2f(1.f, 0.f);
-		gGL.vertex2fv(width_vec.mV);
-
-		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		// draw left 
-		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv(border_height_bottom.mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((height_vec - border_height_top).mV);
-
-		// draw middle
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		// draw right 
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		// draw top left
-		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((border_width_left + height_vec).mV);
-
-		gGL.texCoord2f(0.f, 1.f);
-		gGL.vertex2fv((height_vec).mV);
-
-		// draw top middle
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((border_width_left + height_vec).mV);
-
-		// draw top right
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f, 1.f);
-		gGL.vertex2fv((width_vec + height_vec).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
-	}
-	gGL.end();
-
-	gGL.popUIMatrix();
-}
-
-//FIXME: rewrite to use scissor?
-void gl_segmented_rect_2d_fragment_tex(const S32 left, 
-									   const S32 top, 
-									   const S32 right, 
-									   const S32 bottom, 
-									   const S32 texture_width, 
-									   const S32 texture_height, 
-									   const S32 border_size, 
-									   const F32 start_fragment, 
-									   const F32 end_fragment, 
-									   const U32 edges)
-{
-	S32 width = llabs(right - left);
-	S32 height = llabs(top - bottom);
-
-	gGL.pushUIMatrix();
-
-	gGL.translateUI((F32)left, (F32)bottom, 0.f);
-	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
-
-	if (border_uv_scale.mV[VX] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
-	}
-	if (border_uv_scale.mV[VY] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
-	}
-
-	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
-	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 width_vec((F32)width, 0.f);
-	LLVector2 height_vec(0.f, (F32)height);
-
-	F32 middle_start = border_scale / (F32)width;
-	F32 middle_end = 1.f - middle_start;
-
-	F32 u_min;
-	F32 u_max;
-	LLVector2 x_min;
-	LLVector2 x_max;
-
-	gGL.begin(LLRender::QUADS);
-	{
-		if (start_fragment < middle_start)
-		{
-			u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
-			u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
-			x_min = (start_fragment / middle_start) * border_width_left;
-			x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
-
-			// draw bottom left
-			gGL.texCoord2f(u_min, 0.f);
-			gGL.vertex2fv(x_min.mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-			gGL.vertex2fv(x_max.mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			// draw left 
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-			
-			// draw top left
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f);
-			gGL.vertex2fv((x_max + height_vec).mV);
-
-			gGL.texCoord2f(u_min, 1.f);
-			gGL.vertex2fv((x_min + height_vec).mV);
-		}
-
-		if (end_fragment > middle_start || start_fragment < middle_end)
-		{
-			x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec;
-			x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec;
-
-			// draw bottom middle
-			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-			gGL.vertex2fv(x_min.mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
-			gGL.vertex2fv((x_max).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			// draw middle
-			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			// draw top middle
-			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
-			gGL.vertex2fv((x_max + height_vec).mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
-			gGL.vertex2fv((x_min + height_vec).mV);
-		}
-
-		if (end_fragment > middle_end)
-		{
-			u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
-			u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX];
-			x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right);
-			x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
-
-			// draw bottom right
-			gGL.texCoord2f(u_min, 0.f);
-			gGL.vertex2fv((x_min).mV);
-
-			gGL.texCoord2f(u_max, 0.f);
-			gGL.vertex2fv(x_max.mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			// draw right 
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			// draw top right
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f);
-			gGL.vertex2fv((x_max + height_vec).mV);
-
-			gGL.texCoord2f(u_min, 1.f);
-			gGL.vertex2fv((x_min + height_vec).mV);
-		}
-	}
-	gGL.end();
-
-	gGL.popUIMatrix();
-}
-
-void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, 
-							 const LLVector3& width_vec, const LLVector3& height_vec)
-{
-	gGL.begin(LLRender::QUADS);
-	{
-		// draw bottom left
-		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
-		gGL.vertex3f(0.f, 0.f, 0.f);
-
-		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
-
-		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
-
-		// draw bottom middle
-		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
-
-		// draw bottom right
-		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
-
-		gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom);
-		gGL.vertex3fv(width_vec.mV);
-
-		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
-		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
-
-		// draw left 
-		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
-
-		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
-
-		// draw middle
-		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
-
-		// draw right 
-		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
-
-		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
-		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
-
-		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
-		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
-
-		// draw top left
-		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
-
-		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);
-		gGL.vertex3fv((height_vec).mV);
-
-		// draw top middle
-		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
-
-		// draw top right
-		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
-
-		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
-		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
-
-		gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
-		gGL.vertex3fv((width_vec + height_vec).mV);
-
-		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
-		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
-	}
-	gGL.end();
-
-}
-
-
 void LLUI::initClass(const settings_map_t& settings,
 					 LLImageProviderInterface* image_provider,
 					 LLUIAudioCallback audio_callback,
@@ -1633,6 +163,7 @@ void LLUI::initClass(const settings_map_t& settings,
 					 const LLVector2* scale_factor,
 					 const std::string& language)
 {
+	LLRender2D::initClass(image_provider,scale_factor);
 	sSettingGroups = settings;
 
 	if ((get_ptr_in_map(sSettingGroups, std::string("config")) == NULL) ||
@@ -1642,10 +173,8 @@ void LLUI::initClass(const settings_map_t& settings,
 		llerrs << "Failure to initialize configuration groups" << llendl;
 	}
 
-	sImageProvider = image_provider;
 	sAudioCallback = audio_callback;
 	sDeferredAudioCallback = deferred_audio_callback;
-	sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
 	sWindow = NULL; // set later in startup
 	LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow");
 
@@ -1679,10 +208,7 @@ void LLUI::initClass(const settings_map_t& settings,
 
 void LLUI::cleanupClass()
 {
-	if(sImageProvider)
-	{
-	sImageProvider->cleanUp();
-}
+	LLRender2D::cleanupClass();
 }
 
 void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups)
@@ -1706,60 +232,12 @@ void LLUI::dirtyRect(LLRect rect)
 	}		
 }
  
-
-//static
-void LLUI::translate(F32 x, F32 y, F32 z)
-{
-	gGL.translateUI(x,y,z);
-	LLFontGL::sCurOrigin.mX += (S32) x;
-	LLFontGL::sCurOrigin.mY += (S32) y;
-	LLFontGL::sCurDepth += z;
-}
-
-//static
-void LLUI::pushMatrix()
-{
-	gGL.pushUIMatrix();
-	LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
-}
-
-//static
-void LLUI::popMatrix()
-{
-	gGL.popUIMatrix();
-	LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
-	LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
-	LLFontGL::sOriginStack.pop_back();
-}
-
-//static 
-void LLUI::loadIdentity()
-{
-	gGL.loadUIIdentity(); 
-	LLFontGL::sCurOrigin.mX = 0;
-	LLFontGL::sCurOrigin.mY = 0;
-	LLFontGL::sCurDepth = 0.f;
-}
-
-//static
-void LLUI::setScaleFactor(const LLVector2 &scale_factor)
-{
-	sGLScaleFactor = scale_factor;
-}
-
-//static
-void LLUI::setLineWidth(F32 width)
-{
-	gGL.flush();
-	glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f));
-}
-
 //static 
 void LLUI::setMousePositionScreen(S32 x, S32 y)
 {
 	S32 screen_x, screen_y;
-	screen_x = llround((F32)x * sGLScaleFactor.mV[VX]);
-	screen_y = llround((F32)y * sGLScaleFactor.mV[VY]);
+	screen_x = llround((F32)x * getScaleFactor().mV[VX]);
+	screen_y = llround((F32)y * getScaleFactor().mV[VY]);
 	
 	LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert());
 }
@@ -1770,8 +248,8 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y)
 	LLCoordWindow cursor_pos_window;
 	getWindow()->getCursorPosition(&cursor_pos_window);
 	LLCoordGL cursor_pos_gl(cursor_pos_window.convert());
-	*x = llround((F32)cursor_pos_gl.mX / sGLScaleFactor.mV[VX]);
-	*y = llround((F32)cursor_pos_gl.mY / sGLScaleFactor.mV[VX]);
+	*x = llround((F32)cursor_pos_gl.mX / getScaleFactor().mV[VX]);
+	*y = llround((F32)cursor_pos_gl.mY / getScaleFactor().mV[VX]);
 }
 
 //static 
@@ -1885,21 +363,21 @@ LLVector2 LLUI::getWindowSize()
 	LLCoordWindow window_rect;
 	sWindow->getSize(&window_rect);
 
-	return LLVector2(window_rect.mX / sGLScaleFactor.mV[VX], window_rect.mY / sGLScaleFactor.mV[VY]);
+	return LLVector2(window_rect.mX / getScaleFactor().mV[VX], window_rect.mY / getScaleFactor().mV[VY]);
 }
 
 //static
 void LLUI::screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y)
 {
-	*gl_x = llround((F32)screen_x * sGLScaleFactor.mV[VX]);
-	*gl_y = llround((F32)screen_y * sGLScaleFactor.mV[VY]);
+	*gl_x = llround((F32)screen_x * getScaleFactor().mV[VX]);
+	*gl_y = llround((F32)screen_y * getScaleFactor().mV[VY]);
 }
 
 //static
 void LLUI::glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y)
 {
-	*screen_x = llround((F32)gl_x / sGLScaleFactor.mV[VX]);
-	*screen_y = llround((F32)gl_y / sGLScaleFactor.mV[VY]);
+	*screen_x = llround((F32)gl_x / getScaleFactor().mV[VX]);
+	*screen_y = llround((F32)gl_y / getScaleFactor().mV[VY]);
 }
 
 //static
@@ -1916,27 +394,6 @@ void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen)
 	glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom);
 }
 
-//static
-LLPointer<LLUIImage> LLUI::getUIImageByID(const LLUUID& image_id, S32 priority)
-{
-	if (sImageProvider)
-	{
-		return sImageProvider->getUIImageByID(image_id, priority);
-	}
-	else
-	{
-		return NULL;
-	}
-}
-
-//static 
-LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name, S32 priority)
-{
-	if (!name.empty() && sImageProvider)
-		return sImageProvider->getUIImage(name, priority);
-	else
-		return NULL;
-}
 
 LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
 {
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index 4c1703392a14a5d44333d3daa21693b54dd86511..0a0e0e164ec830191b912707ee8d37e169ec7827 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -1,6 +1,6 @@
 /** 
  * @file llui.h
- * @brief GL function declarations and other general static UI services.
+ * @brief General static UI services.
  *
  * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -24,122 +24,38 @@
  * $/LicenseInfo$
  */
 
-// All immediate-mode gl drawing should happen here.
 
 #ifndef LL_LLUI_H
 #define LL_LLUI_H
 
-#include "llpointer.h"		// LLPointer<>
 #include "llrect.h"
 #include "llcontrol.h"
 #include "llcoord.h"
-#include "llglslshader.h"
+#include "v2math.h"
 #include "llinitparam.h"
 #include "llregistry.h"
+#include "llrender2dutils.h"
+#include "llpointer.h"
 #include "lluicolor.h"
 #include "lluicolortable.h"
+#include "lluiimage.h"
 #include <boost/signals2.hpp>
 #include "lllazyvalue.h"
 #include "llframetimer.h"
 #include <limits>
 
-// LLUIFactory
-#include "llsd.h"
-
 // for initparam specialization
 #include "llfontgl.h"
 
 
-class LLColor4; 
-class LLVector3;
-class LLVector2;
-class LLUIImage;
 class LLUUID;
 class LLWindow;
 class LLView;
 class LLHelp;
 
-// UI colors
-extern const LLColor4 UI_VERTEX_COLOR;
 void make_ui_sound(const char* name);
 void make_ui_sound_deferred(const char * name);
 
-BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
-void gl_state_for_2d(S32 width, S32 height);
-
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
-void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
-void gl_rect_2d_simple( S32 width, S32 height );
-
-void gl_draw_x(const LLRect& rect, const LLColor4& color);
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
-void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
-void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
-void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
-
-void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
-
-void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
-void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
-void gl_deep_circle( F32 radius, F32 depth );
-void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
-void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
-void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
-void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
-
-void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-
-void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); 
-
-void gl_rect_2d_simple_tex( S32 width, S32 height );
-
-// segmented rectangles
-
-/*
-   TL |______TOP_________| TR 
-     /|                  |\  
-   _/_|__________________|_\_
-   L| |    MIDDLE        | |R
-   _|_|__________________|_|_
-    \ |    BOTTOM        | /  
-   BL\|__________________|/ BR
-      |                  |    
-*/
-
-typedef enum e_rounded_edge
-{
-	ROUNDED_RECT_LEFT	= 0x1, 
-	ROUNDED_RECT_TOP	= 0x2, 
-	ROUNDED_RECT_RIGHT	= 0x4, 
-	ROUNDED_RECT_BOTTOM	= 0x8,
-	ROUNDED_RECT_ALL	= 0xf
-}ERoundedEdge;
-
-
-void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec);
-
-inline void gl_rect_2d( const LLRect& rect, BOOL filled )
-{
-	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
-}
-
-inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
-{
-	gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
-}
-
 class LLImageProviderInterface;
 
 typedef	void (*LLUIAudioCallback)(const LLUUID& uuid);
@@ -281,10 +197,10 @@ class LLUI
 	static void cleanupClass();
 	static void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
 
-	static void pushMatrix();
-	static void popMatrix();
-	static void loadIdentity();
-	static void translate(F32 x, F32 y, F32 z = 0.0f);
+	static void pushMatrix() { LLRender2D::pushMatrix(); }
+	static void popMatrix() { LLRender2D::popMatrix(); }
+	static void loadIdentity() { LLRender2D::loadIdentity(); }
+	static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::translate(x, y, z); }
 
 	static LLRect	sDirtyRect;
 	static BOOL		sDirty;
@@ -329,10 +245,13 @@ class LLUI
 	static void getMousePositionScreen(S32 *x, S32 *y);
 	static void setMousePositionLocal(const LLView* viewp, S32 x, S32 y);
 	static void getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y);
-	static void setScaleFactor(const LLVector2& scale_factor);
-	static void setLineWidth(F32 width);
-	static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
-	static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
+	static LLVector2& getScaleFactor() { return LLRender2D::sGLScaleFactor; }
+	static void setScaleFactor(const LLVector2& scale_factor) { LLRender2D::setScaleFactor(scale_factor); }
+	static void setLineWidth(F32 width) { LLRender2D::setLineWidth(width); }
+	static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0)
+		{ return LLRender2D::getUIImageByID(image_id, priority); }
+	static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0)
+		{ return LLRender2D::getUIImage(name, priority); }
 	static LLVector2 getWindowSize();
 	static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y);
 	static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
@@ -362,12 +281,10 @@ class LLUI
 	static settings_map_t sSettingGroups;
 	static LLUIAudioCallback sAudioCallback;
 	static LLUIAudioCallback sDeferredAudioCallback;
-	static LLVector2		sGLScaleFactor;
 	static LLWindow*		sWindow;
 	static LLView*			sRootView;
 	static LLHelp*			sHelpImpl;
 private:
-	static LLImageProviderInterface* sImageProvider;
 	static std::vector<std::string> sXUIPaths;
 	static LLFrameTimer		sMouseIdleTimer;
 	static add_popup_t		sAddPopupFunc;
@@ -378,18 +295,6 @@ class LLUI
 
 // Moved LLLocalClipRect to lllocalcliprect.h
 
-//RN: maybe this needs to moved elsewhere?
-class LLImageProviderInterface
-{
-protected:
-	LLImageProviderInterface() {};
-	virtual ~LLImageProviderInterface() {};
-public:
-	virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
-	virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
-	virtual void cleanUp() = 0;
-};
-
 class LLCallbackRegistry
 {
 public:
@@ -438,10 +343,11 @@ class LLRegisterWith
 
 	// this avoids a MSVC bug where non-referenced static members are "optimized" away
 	// even if their constructors have side effects
-	void reference()
+	S32 reference()
 	{
 		S32 dummy;
 		dummy = 0;
+		return dummy;
 	}
 };
 
@@ -600,7 +506,4 @@ namespace LLInitParam
 	};
 }
 
-extern LLGLSLShader gSolidColorProgram;
-extern LLGLSLShader gUIProgram;
-
 #endif
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 8f0a48018fb26132f0ca1b5257a1110850dce4d3..c3f0e92cb071098476ac84d0c5ce306a1ea781d0 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -31,7 +31,7 @@
 #include "llurlentry_stub.cpp"
 #include "lltut.h"
 #include "../lluicolortable.h"
-#include "../lluiimage.h"
+#include "../llrender/lluiimage.h"
 
 #include <boost/regex.hpp>
 
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 109d3ca7bb6b543b760f006e12d9ec10233fb37b..55c1efefefd1c15ef9a5f06aad7a87ceb0cdeaf1 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -28,7 +28,7 @@
 #include "linden_common.h"
 
 #include "../llurlmatch.h"
-#include "../lluiimage.h"
+#include "../llrender/lluiimage.h"
 #include "lltut.h"
 
 // link seams
diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt
index 3c68b279f7d8ca1cd795f53c42a378821251c532..67dce8c0737e7fda21ff4fb057451aeac2e1bc0f 100644
--- a/indra/llvfs/CMakeLists.txt
+++ b/indra/llvfs/CMakeLists.txt
@@ -8,6 +8,7 @@ include(UnixInstall)
 
 include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
     )
 
 set(llvfs_SOURCE_FILES
@@ -44,12 +45,12 @@ if (LINUX)
   LIST(APPEND llvfs_SOURCE_FILES lldir_linux.cpp)
   LIST(APPEND llvfs_HEADER_FILES lldir_linux.h)
 
-  if (VIEWER AND INSTALL)
+  if (INSTALL)
     set_source_files_properties(lldir_linux.cpp
                                 PROPERTIES COMPILE_FLAGS
                                 "-DAPP_RO_DATA_DIR=\\\"${APP_SHARE_DIR}\\\""
                                 )
-  endif (VIEWER AND INSTALL)
+  endif (INSTALL)
 endif (LINUX)
 
 if (WINDOWS)
@@ -70,6 +71,7 @@ set(vfs_BOOST_LIBRARIES
     )
 
 target_link_libraries(llvfs
+    ${LLCOMMON_LIBRARIES}
     ${vfs_BOOST_LIBRARIES}
     )
 
diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp
index ca749c5eafb8dbb57fe1d94d490fe4137d898007..03d2cc25e335bcd9eb75ce6c15aaf1a8a663d45f 100644
--- a/indra/llvfs/llvfile.cpp
+++ b/indra/llvfs/llvfile.cpp
@@ -32,6 +32,7 @@
 #include "llthread.h"
 #include "llstat.h"
 #include "llvfs.h"
+#include "llmemory.h"
 
 const S32 LLVFile::READ			= 0x00000001;
 const S32 LLVFile::WRITE		= 0x00000002;
@@ -134,13 +135,13 @@ U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S
 		data = NULL;
 	}
 	else
-	{
-		data = new U8[file_size];
+	{		
+		data = (U8*) ll_aligned_malloc_16(file_size);
 		file.read(data, file_size);	/* Flawfinder: ignore */ 
 		
 		if (file.getLastBytesRead() != (S32)file_size)
 		{
-			delete[] data;
+			ll_aligned_free(data);
 			data = NULL;
 			file_size = 0;
 		}
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 341bddfffdb81bc83a134ea3d7323a47feb7e6c3..ad010164eb15977f259dc2b8436f3fb1d901ba45 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -32,12 +32,17 @@ include_directories(
     ${LLXML_INCLUDE_DIRS}
     ${DIRECTX_INCLUDE_DIR}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llwindow_SOURCE_FILES
     llkeyboard.cpp
     llkeyboardheadless.cpp
     llwindowheadless.cpp
     llwindowcallbacks.cpp
+    llwindow.cpp
     )
 
 set(llwindow_HEADER_FILES
@@ -50,7 +55,6 @@ set(llwindow_HEADER_FILES
     )
 
 set(viewer_SOURCE_FILES
-    llwindow.cpp
     llmousehandler.cpp
     )
 
@@ -62,13 +66,43 @@ set(viewer_HEADER_FILES
 
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
-if (LINUX AND VIEWER)
+if (LINUX)
   set(llwindow_LINK_LIBRARIES
+      ${LLCOMMON_LIBRARIES}
+      ${LLIMAGE_LIBRARIES}
+      ${LLMATH_LIBRARIES}
+      ${LLRENDER_LIBRARIES}
+      ${LLVFS_LIBRARIES}
+      ${LLWINDOW_LIBRARIES}
+      ${LLXML_LIBRARIES}
       ${UI_LIBRARIES}     # for GTK
       ${SDL_LIBRARY}
       fontconfig          # For FCInit and other FC* functions.
       )
-endif (LINUX AND VIEWER)
+
+  list(APPEND viewer_SOURCE_FILES 
+       llkeyboardsdl.cpp 
+       llwindowsdl.cpp
+       )
+  list(APPEND viewer_HEADER_FILES
+       llkeyboardsdl.h
+       llwindowsdl.h
+       )
+
+  if (BUILD_HEADLESS)
+    set(llwindowheadless_LINK_LIBRARIES
+        ${LLCOMMON_LIBRARIES}
+        ${LLIMAGE_LIBRARIES}
+        ${LLMATH_LIBRARIES}
+        ${LLRENDER_HEADLESS_LIBRARIES}
+        ${LLVFS_LIBRARIES}
+        ${LLWINDOW_HEADLESS_LIBRARIES}
+        ${LLXML_LIBRARIES}
+        fontconfig          # For FCInit and other FC* functions.
+        )
+  endif (BUILD_HEADLESS)
+
+endif (LINUX)
 
 if (DARWIN)
   list(APPEND llwindow_SOURCE_FILES
@@ -91,16 +125,6 @@ if (DARWIN)
       )
 endif (DARWIN)
 
-if (LINUX AND VIEWER)
-  list(APPEND viewer_SOURCE_FILES 
-       llkeyboardsdl.cpp 
-       llwindowsdl.cpp
-       )
-  list(APPEND viewer_HEADER_FILES
-       llkeyboardsdl.h
-       llwindowsdl.h
-       )
-endif (LINUX AND VIEWER)
 
 if (WINDOWS)
   list(APPEND llwindow_SOURCE_FILES
@@ -133,40 +157,41 @@ endif (SOLARIS)
 set_source_files_properties(${llwindow_HEADER_FILES}
                             PROPERTIES HEADER_FILE_ONLY TRUE)
 
-if (SERVER AND NOT WINDOWS AND NOT DARWIN)
-  set(server_SOURCE_FILES
+if (BUILD_HEADLESS)
+  set(llwindowheadless_SOURCE_FILES
        llwindowmesaheadless.cpp
+       llmousehandler.cpp
        )
-  set(server_HEADER_FILES
+  set(llwindowheadless_HEADER_FILES
        llwindowmesaheadless.h
+       llmousehandler.h
        )
-  copy_server_sources(
-      llwindow
-      )
-
-
-  set_source_files_properties(
-    ${server_SOURCE_FILES}
-    PROPERTIES
-    COMPILE_FLAGS "-DLL_MESA=1 -DLL_MESA_HEADLESS=1"
-    )
   add_library (llwindowheadless
     ${llwindow_SOURCE_FILES}
-    ${server_SOURCE_FILES}
+    ${llwindowheadless_SOURCE_FILES}
     )
-  target_link_libraries (llwindowheadless ${llwindow_LINK_LIBRARIES})
-endif (SERVER AND NOT WINDOWS AND NOT DARWIN)
+  set_property(TARGET llwindowheadless
+    PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
+    )
+  target_link_libraries (llwindowheadless ${llwindowheadless_LINK_LIBRARIES} dl)
+endif (BUILD_HEADLESS)
 
 if (llwindow_HEADER_FILES)
   list(APPEND llwindow_SOURCE_FILES ${llwindow_HEADER_FILES})
 endif (llwindow_HEADER_FILES)
-  list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
 
-if (VIEWER)
-  add_library (llwindow
-    ${llwindow_SOURCE_FILES}
-    ${viewer_SOURCE_FILES}
+list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
+
+add_library (llwindow
+  ${llwindow_SOURCE_FILES}
+  ${viewer_SOURCE_FILES}
+  )
+
+if (SDL_FOUND)
+  set_property(TARGET llwindow
+    PROPERTY COMPILE_DEFINITIONS LL_SDL=1
     )
-  target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
-endif (VIEWER)
+endif (SDL_FOUND)
+
+target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
 
diff --git a/indra/llwindow/GL/glh_extensions.h b/indra/llwindow/GL/glh_extensions.h
index d89d85930b6b6deaab89006580352cb3ed4d4123..554cb1731f27e20a4a1e4fbdc6d1e3971398f9e2 100644
--- a/indra/llwindow/GL/glh_extensions.h
+++ b/indra/llwindow/GL/glh_extensions.h
@@ -113,7 +113,7 @@ static const char* EatNonWhiteSpace(const char *str)
 int glh_init_extensions(const char *origReqExts)
 {
 	// Length of requested extensions string
-	unsigned reqExtsLen;
+	//unsigned reqExtsLen;
 	char *reqExts;
 	// Ptr for individual extensions within reqExts
 	char *reqExt;
@@ -155,8 +155,8 @@ int glh_init_extensions(const char *origReqExts)
 		return TRUE;
 	}
 	reqExts = strdup(origReqExts);
-	reqExtsLen = (S32)strlen(reqExts);
 	/*
+	reqExtsLen = (S32)strlen(reqExts);
 	if (NULL == gGLHExts.mUnsupportedExts)
 	{
 		gGLHExts.mUnsupportedExts = (char*)malloc(reqExtsLen + 1);
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index a15114cb9bc77a2fc62b2ba7be838d93e9c984a0..205466e9369255d8b0e0e29e1a73ceab07fcdc75 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -1636,35 +1636,53 @@ void check_vm_bloat()
 {
 #if LL_LINUX
 	// watch our own VM and RSS sizes, warn if we bloated rapidly
-	FILE *fp = fopen("/proc/self/stat", "r");
+	static const std::string STATS_FILE = "/proc/self/stat";
+	FILE *fp = fopen(STATS_FILE.c_str(), "r");
 	if (fp)
 	{
 		static long long last_vm_size = 0;
 		static long long last_rss_size = 0;
 		const long long significant_vm_difference = 250 * 1024*1024;
 		const long long significant_rss_difference = 50 * 1024*1024;
+		long long this_vm_size = 0;
+		long long this_rss_size = 0;
 
 		ssize_t res;
 		size_t dummy;
-		char *ptr;
+		char *ptr = NULL;
 		for (int i=0; i<22; ++i) // parse past the values we don't want
 		{
-			ptr = NULL;
 			res = getdelim(&ptr, &dummy, ' ', fp);
+			if (-1 == res)
+			{
+				llwarns << "Unable to parse " << STATS_FILE << llendl;
+				goto finally;
+			}
 			free(ptr);
+			ptr = NULL;
 		}
 		// 23rd space-delimited entry is vsize
-		ptr = NULL;
 		res = getdelim(&ptr, &dummy, ' ', fp);
 		llassert(ptr);
-		long long this_vm_size = atoll(ptr);
+		if (-1 == res)
+		{
+			llwarns << "Unable to parse " << STATS_FILE << llendl;
+			goto finally;
+		}
+		this_vm_size = atoll(ptr);
 		free(ptr);
-		// 24th space-delimited entry is RSS
 		ptr = NULL;
+		// 24th space-delimited entry is RSS
 		res = getdelim(&ptr, &dummy, ' ', fp);
 		llassert(ptr);
-		long long this_rss_size = getpagesize() * atoll(ptr);
+		if (-1 == res)
+		{
+			llwarns << "Unable to parse " << STATS_FILE << llendl;
+			goto finally;
+		}
+		this_rss_size = getpagesize() * atoll(ptr);
 		free(ptr);
+		ptr = NULL;
 
 		llinfos << "VM SIZE IS NOW " << (this_vm_size/(1024*1024)) << " MB, RSS SIZE IS NOW " << (this_rss_size/(1024*1024)) << " MB" << llendl;
 
@@ -1697,6 +1715,12 @@ void check_vm_bloat()
 		last_rss_size = this_rss_size;
 		last_vm_size = this_vm_size;
 
+finally:
+		if (NULL != ptr)
+		{
+			free(ptr);
+			ptr = NULL;
+		}
 		fclose(fp);
 	}
 #endif // LL_LINUX
diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt
index beefcda3610204afbb05a7813ebc91af182df0b7..cf96f26a77a2c17e7b464f5591f15e46ad796770 100644
--- a/indra/llxml/CMakeLists.txt
+++ b/indra/llxml/CMakeLists.txt
@@ -13,6 +13,9 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LLVFS_INCLUDE_DIRS}
     )
+include_directories(
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llxml_SOURCE_FILES
     llcontrol.cpp
@@ -39,9 +42,10 @@ list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES})
 add_library (llxml ${llxml_SOURCE_FILES})
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
-target_link_libraries( llxml
-    llvfs
-    llmath
+target_link_libraries(llxml
+    ${LLVFS_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLCOMMON_LIBRARIES}
     ${EXPAT_LIBRARIES}
     )
 
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 53d9380f4f85a6ee251e8e97b91b2adf561dc054..666c03e9fffc89295d0549544d0c3c18e9382104 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -850,12 +850,10 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 		return 0;
 	}
 
-	S32 ret = LLSDSerialize::fromXML(settings, infile);
-
-	if (ret <= 0)
+	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, infile))
 	{
 		infile.close();
-		llwarns << "Unable to open LLSD control file " << filename << ". Trying Legacy Method." << llendl;		
+		llwarns << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << llendl;
 		return loadFromFileLegacy(filename, TRUE, TYPE_STRING);
 	}
 
diff --git a/indra/lscript/lscript_compile/CMakeLists.txt b/indra/lscript/lscript_compile/CMakeLists.txt
index 3ed2892e0ed55ecca656b24ba15f04c22cdf7f9d..07662005b999ae39274f1ba6cd907870677244e0 100644
--- a/indra/lscript/lscript_compile/CMakeLists.txt
+++ b/indra/lscript/lscript_compile/CMakeLists.txt
@@ -45,6 +45,9 @@ include_directories(
     ${LLPRIMITIVE_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(lscript_generated_SOURCE_FILES
     indra.l.cpp
@@ -95,6 +98,7 @@ add_custom_command(
       ${CMAKE_CURRENT_BINARY_DIR}/indra.l.cpp
     COMMAND ${FLEX}
     ARGS
+      -P indra_
       -o${CMAKE_CURRENT_BINARY_DIR}/indra.l.cpp
       ${CMAKE_CURRENT_SOURCE_DIR}/indra.l
     DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/indra.l
@@ -112,8 +116,10 @@ if (WINDOWS)
         ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
         ${CMAKE_CURRENT_BINARY_DIR}/indra.y.hpp
       COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bison.bat
+      ARGS
         ${BISON} ${M4_PATH}
-        ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
+        -p indra_
+        -d -o ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/indra.y
       DEPENDS
         ${CMAKE_CURRENT_SOURCE_DIR}/bison.bat
@@ -128,6 +134,7 @@ else (WINDOWS)
       COMMAND
         ${BISON}
       ARGS
+        -p indra_
         -d -o ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/indra.y
       DEPENDS
diff --git a/indra/lscript/lscript_compile/bison.bat b/indra/lscript/lscript_compile/bison.bat
index 0baff4e5ef9c4bc6d98b36fd332d238542f29510..d40997225e01d8d744871d55002881587b966dbe 100644
--- a/indra/lscript/lscript_compile/bison.bat
+++ b/indra/lscript/lscript_compile/bison.bat
@@ -2,10 +2,11 @@
 @REM find m4, even if neither program is present in PATH.
 
 @set bison=%1
-set M4PATH=%2
+shift
+set M4PATH=%1
+shift
 set M4=
-@set output=%3
-@set input=%4
 
 set PATH=%M4PATH%;%PATH%
-%bison% -d -o %output% %input%
+@REM %* does not work with shift...
+%bison% %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l
index 96b7e57e9781bd3cb766c96418a88547c7685667..b2c49083cb267398b1c32ce636317b40504b84a8 100644
--- a/indra/lscript/lscript_compile/indra.l
+++ b/indra/lscript/lscript_compile/indra.l
@@ -56,6 +56,29 @@ void parse_string();
 
 #define ECHO do { } while (0)
 
+#define yyparse indra_parse
+#define yyerror indra_error
+#define yylval indra_lval
+#define yy_create_buffer indra__create_buffer
+#define yy_delete_buffer indra__delete_buffer
+#define yy_flex_debug indra__flex_debug
+#define yy_init_buffer indra__init_buffer
+#define yy_flush_buffer indra__flush_buffer
+#define yy_load_buffer_state indra__load_buffer_state
+#define yy_switch_to_buffer indra__switch_to_buffer
+#define yyin indra_in
+#define yyleng indra_leng
+#define yylex indra_lex
+#define yylineno indra_lineno
+#define yyout indra_out
+#define yyrestart indra_restart
+#define yytext indra_text
+#define yywrap indra_wrap
+#define yyalloc indra_alloc
+#define yyrealloc indra_realloc
+#define yyfree indra_free
+
+
 #if defined(__cplusplus)
 extern "C" { int yylex( void ); }
 extern "C" { int yyparse( void ); }
diff --git a/indra/lscript/lscript_execute/CMakeLists.txt b/indra/lscript/lscript_execute/CMakeLists.txt
index 3a16ffdc0105a5ec01dcfb3b95714604fc33f68e..49605982a825fbe7347a42944421b1b9d4243752 100644
--- a/indra/lscript/lscript_execute/CMakeLists.txt
+++ b/indra/lscript/lscript_execute/CMakeLists.txt
@@ -10,6 +10,9 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(lscript_execute_SOURCE_FILES
     llscriptresource.cpp
diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp
index d79e9f8bde496797dd3a2a6de2073d2b90df9fae..b12d2e4a1693bf2b9dff36e9df6c3d3315ffa535 100644
--- a/indra/lscript/lscript_execute/lscript_execute.cpp
+++ b/indra/lscript/lscript_execute/lscript_execute.cpp
@@ -806,16 +806,7 @@ void LLScriptExecute::runInstructions(BOOL b_print, const LLUUID &id,
 	//  is there a fault?
 	//	if yes, print out message and exit
 	S32 value = getVersion();
-	S32 major_version = 0;
-	if (value == LSL2_VERSION1_END_NUMBER)
-	{
-		major_version = 1;
-	}
-	else if (value == LSL2_VERSION_NUMBER)
-	{
-		major_version = 2;
-	}
-	else
+	if ( (value != LSL2_VERSION1_END_NUMBER) && (value != LSL2_VERSION_NUMBER) )
 	{
 		setFault(LSRF_VERSION_MISMATCH);
 	}
diff --git a/indra/lscript/lscript_execute/lscript_readlso.cpp b/indra/lscript/lscript_execute/lscript_readlso.cpp
index 35caa41ae18be324696e53d3985ab910d9d890fa..8b41cb5a721c47eab99734e57d1363a14ce02392 100644
--- a/indra/lscript/lscript_execute/lscript_readlso.cpp
+++ b/indra/lscript/lscript_execute/lscript_readlso.cpp
@@ -123,7 +123,7 @@ void LLScriptLSOParse::printRegisters(LLFILE *fp)
 void LLScriptLSOParse::printGlobals(LLFILE *fp)
 {
 	// print out registers first
-	S32				offset, varoffset;
+	S32				varoffset;
 	S32				ivalue;
 	F32				fpvalue;
 	LLVector3		vvalue;
@@ -144,7 +144,7 @@ void LLScriptLSOParse::printGlobals(LLFILE *fp)
 
 		// get offset to skip past name
 		varoffset = global_v_offset;
-		offset = bytestream2integer(mRawData, global_v_offset);
+		bytestream2integer(mRawData, global_v_offset);
 		
 		// get typeexport
 		type = *(mRawData + global_v_offset++);
@@ -262,8 +262,6 @@ void LLScriptLSOParse::printGlobalFunctions(LLFILE *fp)
 		fprintf(fp, "[Function #%d] [0x%X] %s\n", function_number, orig_function_offset, name);
 		fprintf(fp, "\tReturn Type: %s\n", LSCRIPTTypeNames[type]);
 		type = *(mRawData + function_offset++);
-		S32 params;
-		params = 0;
 		S32 pcount = 0;
 		while (type)
 		{
@@ -347,7 +345,6 @@ void LLScriptLSOParse::printStates(LLFILE *fp)
 				read_ahead = event_jump_table;
 
 				S32 temp_end;
-				S32 dummy;
 
 				opcode_end = worst_case_opcode_end;
 
@@ -356,7 +353,7 @@ void LLScriptLSOParse::printStates(LLFILE *fp)
 					if (event_handlers & LSCRIPTStateBitField[k])
 					{
 						temp_end = bytestream2integer(mRawData, read_ahead);
-						dummy = bytestream2integer(mRawData, read_ahead);
+						bytestream2integer(mRawData, read_ahead);
 						if (  (temp_end < opcode_end)
 							&&(temp_end > event_offset))
 						{
diff --git a/indra/lscript/lscript_library/CMakeLists.txt b/indra/lscript/lscript_library/CMakeLists.txt
index f6bc67a994a3ec83cd4309839602f4c3ba3380b4..5af850c41bc2df07b7b125fd0a5020d141cc6539 100644
--- a/indra/lscript/lscript_library/CMakeLists.txt
+++ b/indra/lscript/lscript_library/CMakeLists.txt
@@ -28,5 +28,8 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 add_library (lscript_library ${lscript_library_SOURCE_FILES})
diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt
index 3906a3bb8c802dbbc93ff4bdb9bbfc05d926fead..c59645bd70e45b7d3d9a5fdbcbea3de6a7727821 100644
--- a/indra/mac_crash_logger/CMakeLists.txt
+++ b/indra/mac_crash_logger/CMakeLists.txt
@@ -19,6 +19,10 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(mac_crash_logger_SOURCE_FILES
     mac_crash_logger.cpp
diff --git a/indra/mac_updater/CMakeLists.txt b/indra/mac_updater/CMakeLists.txt
index 00dcedecaa90560272fabefa6d52e599db9aaff9..a644984e58f2618755a362f15170ada1a9584b37 100644
--- a/indra/mac_updater/CMakeLists.txt
+++ b/indra/mac_updater/CMakeLists.txt
@@ -7,6 +7,7 @@ include(OpenSSL)
 include(CURL)
 include(CARes)
 include(LLCommon)
+include(LLMessage)
 include(LLVFS)
 include(Linking)
 
@@ -52,6 +53,7 @@ set_target_properties(mac-updater
   )
 
 target_link_libraries(mac-updater
+    ${LLMESSAGE_LIBRARIES}
     ${LLVFS_LIBRARIES}
     ${OPENSSL_LIBRARIES}
     ${CRYPTO_LIBRARIES}
diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt
index 3ad94b0c647bf4e4fb98a40437eaa03c9b8101ec..7367b9e5e654911c75a0bf8a9fca789a1c260378 100644
--- a/indra/media_plugins/base/CMakeLists.txt
+++ b/indra/media_plugins/base/CMakeLists.txt
@@ -11,7 +11,7 @@ include(LLRender)
 include(LLWindow)
 include(Linking)
 include(PluginAPI)
-include(FindOpenGL)
+include(OpenGL)
 
 include_directories(
     ${LLPLUGIN_INCLUDE_DIRS}
@@ -21,6 +21,9 @@ include_directories(
     ${LLRENDER_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 
 ### media_plugin_base
diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt
index 54dc5de1ea4e38ae55b81c5432584cb297d63ec3..171645ef0467e068197fd9df71dde2745235971e 100644
--- a/indra/media_plugins/example/CMakeLists.txt
+++ b/indra/media_plugins/example/CMakeLists.txt
@@ -12,7 +12,7 @@ include(LLWindow)
 include(Linking)
 include(PluginAPI)
 include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
 
 include(ExamplePlugin)
 
@@ -25,6 +25,9 @@ include_directories(
     ${LLRENDER_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 
 ### media_plugin_example
diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt
index 5786bd1e25f474601707a7e56b4f2f34daf427e7..447f6e06895ec7d5cbf69ab85bd03513664e178d 100644
--- a/indra/media_plugins/gstreamer010/CMakeLists.txt
+++ b/indra/media_plugins/gstreamer010/CMakeLists.txt
@@ -12,7 +12,7 @@ include(LLWindow)
 include(Linking)
 include(PluginAPI)
 include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
 
 include(GStreamer010Plugin)
 
@@ -27,6 +27,9 @@ include_directories(
     ${GSTREAMER010_INCLUDE_DIRS}
     ${GSTREAMER010_PLUGINS_BASE_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 ### media_plugin_gstreamer010
 
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
index cdb7f4faeb7e04380f28021037538ff44b9ac956..932aaffa1b9f79f3cc0b416c89a67bccc551894d 100644
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
@@ -278,10 +278,9 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps)
 static gboolean
 gst_slvideo_start (GstBaseSink * bsink)
 {
-	GstSLVideo *slvideo;
 	gboolean ret = TRUE;
 	
-	slvideo = GST_SLVIDEO(bsink);
+	GST_SLVIDEO(bsink);
 
 	return ret;
 }
diff --git a/indra/media_plugins/quicktime/CMakeLists.txt b/indra/media_plugins/quicktime/CMakeLists.txt
index f0b8f0d16706f5b491d783b45559b0cd9d8d8a31..58391007fff486a814a3ffe9fee3da1cd98e8489 100644
--- a/indra/media_plugins/quicktime/CMakeLists.txt
+++ b/indra/media_plugins/quicktime/CMakeLists.txt
@@ -12,7 +12,7 @@ include(LLWindow)
 include(Linking)
 include(PluginAPI)
 include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
 include(QuickTimePlugin)
 
 include_directories(
@@ -24,6 +24,9 @@ include_directories(
     ${LLRENDER_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 if (DARWIN)
     include(CMakeFindFrameworks)
diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt
index b36291f0e8686d771c6b6edf4f40eaa7e94518b1..0c1c3d800e1646aedf25caf4ad87083beef9b71b 100644
--- a/indra/media_plugins/webkit/CMakeLists.txt
+++ b/indra/media_plugins/webkit/CMakeLists.txt
@@ -13,7 +13,7 @@ include(UI)
 include(Linking)
 include(PluginAPI)
 include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
 include(PulseAudio)
 
 include(WebKitLibPlugin)
@@ -29,6 +29,9 @@ include_directories(
     ${LLWINDOW_INCLUDE_DIRS}
     ${LLQTWEBKIT_INCLUDE_DIR}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 
 ### media_plugin_webkit
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index bd0169fb2fdd01f9bfdac03ee7ed67c351d8f13d..4f7ce88165902737774ce1ca86872c13a30e671c 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -12,7 +12,7 @@ include(DragDrop)
 include(EXPAT)
 include(FMOD)
 include(OPENAL)
-include(FindOpenGL)
+include(OpenGL)
 include(Hunspell)
 include(JsonCpp)
 include(LLAudio)
@@ -46,6 +46,7 @@ include(LLLogin)
 include(VisualLeakDetector)
 include(GLOD)
 include(CMakeCopyIfDifferent)
+include(LLAppearance)
 
 if (NOT HAVOK_TPV)
    # When using HAVOK_TPV, the library is precompiled, so no need for this
@@ -67,7 +68,6 @@ include_directories(
     ${LLINVENTORY_INCLUDE_DIRS}
     ${LLMATH_INCLUDE_DIRS}
     ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
     ${LLPLUGIN_INCLUDE_DIRS}
     ${LLPRIMITIVE_INCLUDE_DIRS}
     ${LLRENDER_INCLUDE_DIRS}
@@ -83,6 +83,13 @@ include_directories(
     ${LIBS_PREBUILD_DIR}/include/hunspell
     ${OPENAL_LIB_INCLUDE_DIRS}
     ${LIBS_PREBUILT_DIR}/include/collada/1.4
+    ${LLAPPEARANCE_INCLUDE_DIRS}
+    )
+
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
     )
 
 set(viewer_SOURCE_FILES
@@ -169,7 +176,6 @@ set(viewer_SOURCE_FILES
     lldrawpooltree.cpp
     lldrawpoolwater.cpp
     lldrawpoolwlsky.cpp
-    lldriverparam.cpp
     lldynamictexture.cpp
     llemote.cpp
     llenvmanager.cpp
@@ -334,7 +340,6 @@ set(viewer_SOURCE_FILES
     lllistcontextmenu.cpp
     lllistview.cpp
     lllocalbitmaps.cpp
-    lllocaltextureobject.cpp
     lllocationhistory.cpp
     lllocationinputctrl.cpp
     lllogchat.cpp
@@ -454,12 +459,11 @@ set(viewer_SOURCE_FILES
     llpersistentnotificationstorage.cpp
     llphysicsmotion.cpp
     llphysicsshapebuilderutil.cpp
+    llpipelinelistener.cpp
     llplacesinventorybridge.cpp
     llplacesinventorypanel.cpp
     llplacesfolderview.cpp
     llpopupview.cpp
-    llpolymesh.cpp
-    llpolymorph.cpp
     llpostcard.cpp
     llpreview.cpp
     llpreviewanim.cpp
@@ -510,9 +514,6 @@ set(viewer_SOURCE_FILES
     llsyswellwindow.cpp
     llteleporthistory.cpp
     llteleporthistorystorage.cpp
-    lltexglobalcolor.cpp
-    lltexlayer.cpp
-    lltexlayerparams.cpp
     lltextureatlas.cpp
     lltextureatlasmanager.cpp
     lltexturecache.cpp
@@ -610,18 +611,18 @@ set(viewer_SOURCE_FILES
     llviewershadermgr.cpp
     llviewerstats.cpp
     llviewerstatsrecorder.cpp
+    llviewertexlayer.cpp
     llviewertexteditor.cpp
     llviewertexture.cpp
     llviewertextureanim.cpp
     llviewertexturelist.cpp
     llviewerthrottle.cpp
-    llviewervisualparam.cpp
+    llviewerwearable.cpp
     llviewerwindow.cpp
     llviewerwindowlistener.cpp
     llvlcomposition.cpp
     llvlmanager.cpp
     llvoavatar.cpp
-    llvoavatardefines.cpp
     llvoavatarself.cpp
     llvocache.cpp
     llvograss.cpp
@@ -642,10 +643,8 @@ set(viewer_SOURCE_FILES
     llwatchdog.cpp
     llwaterparammanager.cpp
     llwaterparamset.cpp
-    llwearable.cpp
     llwearableitemslist.cpp
     llwearablelist.cpp
-    llwearabletype.cpp
     llweb.cpp
     llwebprofile.cpp
     llwebsharing.cpp
@@ -757,7 +756,6 @@ set(viewer_HEADER_FILES
     lldrawpooltree.h
     lldrawpoolwater.h
     lldrawpoolwlsky.h
-    lldriverparam.h
     lldynamictexture.h
     llemote.h
     llenvmanager.h
@@ -921,7 +919,6 @@ set(viewer_HEADER_FILES
     lllistcontextmenu.h
     lllistview.h
     lllocalbitmaps.h
-    lllocaltextureobject.h
     lllocationhistory.h
     lllocationinputctrl.h
     lllogchat.h
@@ -1030,11 +1027,10 @@ set(viewer_HEADER_FILES
     llpersistentnotificationstorage.h
     llphysicsmotion.h
     llphysicsshapebuilderutil.h
+    llpipelinelistener.h
     llplacesinventorybridge.h
     llplacesinventorypanel.h
     llplacesfolderview.h
-    llpolymesh.h
-    llpolymorph.h
     llpopupview.h
     llpostcard.h
     llpreview.h
@@ -1088,9 +1084,6 @@ set(viewer_HEADER_FILES
     lltable.h
     llteleporthistory.h
     llteleporthistorystorage.h
-    lltexglobalcolor.h
-    lltexlayer.h
-    lltexlayerparams.h
     lltextureatlas.h
     lltextureatlasmanager.h
     lltexturecache.h
@@ -1189,18 +1182,18 @@ set(viewer_HEADER_FILES
     llviewershadermgr.h
     llviewerstats.h
     llviewerstatsrecorder.h
+    llviewertexlayer.h
     llviewertexteditor.h
     llviewertexture.h
     llviewertextureanim.h
     llviewertexturelist.h
     llviewerthrottle.h
-    llviewervisualparam.h
+    llviewerwearable.h
     llviewerwindow.h
     llviewerwindowlistener.h
     llvlcomposition.h
     llvlmanager.h
     llvoavatar.h
-    llvoavatardefines.h
     llvoavatarself.h
     llvocache.h
     llvograss.h
@@ -1221,10 +1214,8 @@ set(viewer_HEADER_FILES
     llwatchdog.h
     llwaterparammanager.h
     llwaterparamset.h
-    llwearable.h
     llwearableitemslist.h
     llwearablelist.h
-    llwearabletype.h
     llweb.h
     llwebprofile.h
     llwebsharing.h
@@ -1579,6 +1570,12 @@ add_executable(${VIEWER_BINARY_NAME}
     ${viewer_SOURCE_FILES}
     )
 
+if (SDL_FOUND)
+  set_property(TARGET ${VIEWER_BINARY_NAME}
+    PROPERTY COMPILE_DEFINITIONS LL_SDL=1
+    )
+endif (SDL_FOUND)
+
 # add package files
 file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
      ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@@ -1864,19 +1861,9 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${LLPHYSICS_LIBRARIES}
     ${LLPHYSICSEXTENSIONS_LIBRARIES}
     ${TCMALLOC_LIBRARIES}
+    ${LLAPPEARANCE_LIBRARIES}
     )
 
-if (USE_KDU)
-    target_link_libraries(${VIEWER_BINARY_NAME}
-        ${LLKDU_LIBRARIES}
-        ${KDU_LIBRARY}
-        )
-else (USE_KDU)
-    target_link_libraries(${VIEWER_BINARY_NAME}
-        ${LLIMAGEJ2COJ_LIBRARIES}
-        )
-endif (USE_KDU)
-
 build_version(viewer)
 
 set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
@@ -2095,6 +2082,15 @@ if (LL_TESTS)
     llworldmipmap.cpp
   )
 
+  set_source_files_properties(
+    llworldmap.cpp
+    llworldmipmap.cpp
+    PROPERTIES
+    LL_TEST_ADDITIONAL_SOURCE_FILES 
+    tests/llviewertexture_stub.cpp
+    #llviewertexturelist.cpp
+  )
+
   set_source_files_properties(
     lltranslate.cpp
     PROPERTIES
diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings
index 5c7cacedec00fd61740b972f0c2095deddaf3ece..1802e14703520d12ca79c529f217af4eb6a094c8 100644
--- a/indra/newview/English.lproj/InfoPlist.strings
+++ b/indra/newview/English.lproj/InfoPlist.strings
@@ -2,6 +2,6 @@
 
 CFBundleName = "Second Life";
 
-CFBundleShortVersionString = "Second Life version 2.1.0.13828";
-CFBundleGetInfoString = "Second Life version 2.1.0.13828, Copyright 2004-2009 Linden Research, Inc.";
+CFBundleShortVersionString = "Second Life version 3.4.1.264760";
+CFBundleGetInfoString = "Second Life version 3.4.1.264760, Copyright 2004-2009 Linden Research, Inc.";
 
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index f7b11b217c928cd41a89fa6826256158f9972e34..035d6cbe6cd423b0ef9e65cba74ec728dfe313e3 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -60,7 +60,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>2.1.0.13828</string>
+	<string>3.4.1.264760</string>
 	<key>CSResourcesFileMapped</key>
 	<true/>
 </dict>
diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml
old mode 100644
new mode 100755
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
old mode 100644
new mode 100755
index 4c305e1d6017b8823170c38b8fb788b01a9fc8e5..f66d8fca5b5a67bf9ef9e281b0bd2ae8f00c2b0d
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2003,6 +2003,39 @@
       <string>String</string>
       <key>Value</key>
       <string />
+    </map>
+  <key>DebugAvatarAppearanceMessage</key>
+  <map>
+    <key>Comment</key>
+    <string>Dump a bunch of XML files when handling appearance messages</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+  <key>DebugAvatarExperimentalServerAppearanceUpdate</key>
+  <map>
+    <key>Comment</key>
+    <string>Experiment with sending full cof_contents instead of cof_version</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+    <key>DebugAvatarAppearanceServiceURLOverride</key>
+    <map>
+      <key>Comment</key>
+      <string>URL to use for baked texture requests; overrides value returned by login server.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string />
     </map>
 	<key>DebugAvatarRezTime</key>
 	<map>
@@ -2025,6 +2058,17 @@
     <string>Boolean</string>
     <key>Value</key>
     <integer>1</integer>
+  </map>
+  <key>DebugAvatarCompositeBaked</key>
+  <map>
+    <key>Comment</key>
+    <string>Colorize avatar meshes based on baked/composite state.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
   </map>
     <key>DebugBeaconLineWidth</key>
     <map>
@@ -2037,6 +2081,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>DebugForceAppearanceRequestFailure</key>
+    <map>
+      <key>Comment</key>
+      <string>Request wrong cof version to test the failure path for server appearance update requests.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>DebugHideEmptySystemFolders</key>
     <map>
       <key>Comment</key>
@@ -4381,6 +4436,28 @@
       <key>Value</key>
       <real>1.0</real>
     </map>
+    <key>InventoryDebugSimulateOpFailureRate</key>
+    <map>
+      <key>Comment</key>
+        <string>Rate at which we simulate failures of copy/link requests in some operations</string>
+      <key>Persist</key>
+        <integer>1</integer>
+      <key>Type</key>
+        <string>F32</string>
+      <key>Value</key>
+        <real>0.0</real>
+    </map>
+    <key>InventoryDebugSimulateLateOpRate</key>
+    <map>
+      <key>Comment</key>
+        <string>Rate at which we simulate late-completing copy/link requests in some operations</string>
+      <key>Persist</key>
+        <integer>1</integer>
+      <key>Type</key>
+        <string>F32</string>
+      <key>Value</key>
+        <real>0.0</real>
+    </map>
     <key>InventoryDisplayInbox</key>
     <map>
         <key>Comment</key>
@@ -8903,6 +8980,28 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>DisableAllRenderTypes</key>
+    <map>
+      <key>Comment</key>
+      <string>Disables all rendering types.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>DisableAllRenderFeatures</key>
+    <map>
+      <key>Comment</key>
+      <string>Disables all rendering features.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>RenderHUDInSnapshot</key>
     <map>
       <key>Comment</key>
@@ -13340,6 +13439,28 @@
       <key>Value</key>
       <integer>-1</integer>
     </map>
+    <key>MaxFPS</key>
+    <map>
+      <key>Comment</key>
+      <string>Yield some time to the local host if we reach a threshold framerate.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <integer>-1.0</integer>
+    </map>
+    <key>ForcePeriodicRenderingTime</key>
+    <map>
+      <key>Comment</key>
+      <string>Periodically enable all rendering masks for a single frame.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <integer>-1.0</integer>
+    </map>
     <key>ZoomDirect</key>
     <map>
       <key>Comment</key>
@@ -14325,5 +14446,17 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
+
+  <key>DisablePrecacheDelayAfterTeleporting</key>
+  <map>
+    <key>Comment</key>
+    <string>Disables the artificial delay in the viewer that precaches some incoming assets</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
 </map>
 </llsd>
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
index 99a6fe85fe8178e1f07ba0b550b12e322966b722..9c82056fd7f71dda504eeb247ace58338bc2c7ff 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
@@ -31,7 +31,7 @@ out vec4 frag_color;
 
 uniform float minimum_alpha;
 
-vec4 diffuseLookup(vec2 texcoord);
+/* vec4 diffuseLookup(vec2 texcoord); */
 
 vec3 fullbrightAtmosTransport(vec3 light);
 vec4 applyWaterFog(vec4 color);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
index df182168f3c59baa50aa671339355b2267146a3a..d3dacf9bc4d81e65f7cd91eda199da74440a4d66 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
@@ -32,7 +32,7 @@ out vec4 frag_color;
 VARYING vec4 vertex_color;
 VARYING vec2 vary_texcoord0;
 
-vec4 diffuseLookup(vec2 texcoord);
+/* vec4 diffuseLookup(vec2 texcoord); */
 
 vec3 fullbrightAtmosTransport(vec3 light);
 vec4 applyWaterFog(vec4 color);
diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index 99dbfcae51e8d94d201fee72ae01434df3e35bb4..284e9c44b286ee6b4352b2f47759395eac54aed9 100644
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -1084,6 +1084,23 @@
          scale="0 0 .5" />
       </param_skeleton>
     </param>
+
+    <param
+     id="11001"
+     group="0"
+     name="Hover"
+     wearable="shape"
+     edit_group="shape_body"
+     edit_group_order="4"
+     label_min="Lower"
+     label_max="Higher"
+     value_min="-2"
+     value_max="2"
+     value_default="0"
+     camera_distance="2.5">
+      <param_skeleton />
+    </param>
+
   </skeleton>
 
   <mesh
@@ -12291,6 +12308,17 @@ render_pass="bump">
 	 <param_driver />
     </param>
 
+    <param
+     id="11000"
+     group="0"
+     name="AppearanceMessage_Version"
+     label="AppearanceMessage Version"
+     value_default="0"
+     value_min="0"
+     value_max="255">
+	 <param_driver />
+    </param>
+
   </driver_parameters>
 
   <morph_masks>
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index 20936c6460bee17d344a1459ffde905572c114a4..1381e49c62bb34f45a9f374b1da6ec57608fc3cb 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -45,6 +45,7 @@ if [ "`uname -m`" = "x86_64" ]; then
     echo '64-bit Linux detected.'
 fi
 
+
 ## Everything below this line is just for advanced troubleshooters.
 ##-------------------------------------------------------------------
 
@@ -60,7 +61,15 @@ fi
 export SDL_VIDEO_X11_DGAMOUSE=0
 
 ## - Works around a problem with misconfigured 64-bit systems not finding GL
-export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}":/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri
+I386_MULTIARCH="$(dpkg-architecture -ai386 -qDEB_HOST_MULTIARCH 2>/dev/null)"
+MULTIARCH_ERR=$?
+if [ $MULTIARCH_ERR -eq 0 ]; then
+    echo 'Multi-arch support detected.'
+    MULTIARCH_GL_DRIVERS="/usr/lib/${I386_MULTIARCH}/dri"
+    export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:${MULTIARCH_GL_DRIVERS}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri"
+else
+    export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri"
+fi
 
 ## - The 'scim' GTK IM module widely crashes the viewer.  Avoid it.
 if [ "$GTK_IM_MODULE" = "scim" ]; then
@@ -117,18 +126,32 @@ export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}"
 # Simply embedding $(<etc/gridargs.dat) into a command line treats each of
 # Second, Life and Developer as separate args -- no good. We need bash to
 # process quotes using eval.
-# First read it without scanning, then scan that string. Break quoted words
+# First, check if we have been instructed to skip reading in gridargs.dat:
+skip_gridargs=false
+argnum=0
+for ARG in "$@"; do
+    if [ "--skip-gridargs" == "$ARG" ]; then
+        skip_gridargs=true
+    else
+        ARGS[$argnum]="$ARG"
+        argnum=$(($argnum+1))
+    fi
+done
+
+# Second, read it without scanning, then scan that string. Break quoted words
 # into a bash array. Note that if gridargs.dat is empty, or contains only
 # whitespace, the resulting gridargs array will be empty -- zero entries --
 # therefore "${gridargs[@]}" entirely vanishes from the command line below,
 # just as we want.
-eval gridargs=("$(<etc/gridargs.dat)")
+if ! $skip_gridargs ; then
+    eval gridargs=("$(<etc/gridargs.dat)")
+fi
 
 # Run the program.
 # Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the
 # command line. But DO quote "$@": preserve separate args as individually
 # quoted. Similar remarks about the contents of gridargs.
-$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "$@"
+$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "${ARGS[@]}"
 LL_RUN_ERR=$?
 
 # Handle any resulting errors
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
index 8767955fcb57a9821dba6e3b0fc4e246e3b2b3e6..7662a9689daa0849a6a22146c722bb27dc48a9de 100644
--- a/indra/newview/llaccountingcostmanager.cpp
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -56,9 +56,9 @@ class LLAccountingCostResponder : public LLCurl::Responder
 		}
 	}
 	
-	void error( U32 statusNum, const std::string& reason )
+	void errorWithContent( U32 statusNum, const std::string& reason, const LLSD& content )
 	{
-		llwarns	<< "Transport error "<<reason<<llendl;	
+		llwarns << "Transport error [status:" << statusNum << "]: " << content <<llendl;
 		clearPendingRequests();
 
 		LLAccountingCostObserver* observer = mObserverHandle.get();
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 094d50207866598e2b87208fd65a09003f026beb..8c42defa73f25bc7a47871ffd8911b7b54848403 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -35,6 +35,7 @@
 #include "llagentlistener.h"
 #include "llagentwearables.h"
 #include "llagentui.h"
+#include "llappearancemgr.h"
 #include "llanimationstates.h"
 #include "llcallingcard.h"
 #include "llcapabilitylistener.h"
@@ -91,7 +92,7 @@
 #include "llworldmap.h"
 #include "stringize.h"
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 extern LLMenuBarGL* gMenuBarView;
 
@@ -808,6 +809,29 @@ void LLAgent::standUp()
 }
 
 
+void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id)
+{
+	llinfos << "called" << llendl;
+
+
+	// Old-style appearance entering a server-bake region.
+	if (isAgentAvatarValid() &&
+		!gAgentAvatarp->isUsingServerBakes() &&
+		(mRegionp->getCentralBakeVersion()>0))
+	{
+		llinfos << "update requested due to region transition" << llendl;
+		LLAppearanceMgr::instance().requestServerAppearanceUpdate();
+	}
+	// new-style appearance entering a non-bake region,
+	// need to check for existence of the baking service.
+	else if (isAgentAvatarValid() &&
+			 gAgentAvatarp->isUsingServerBakes() &&
+			 mRegionp->getCentralBakeVersion()==0)
+	{
+		gAgentAvatarp->checkForUnsupportedServerBakeAppearance();
+	}
+}
+
 //-----------------------------------------------------------------------------
 // setRegion()
 //-----------------------------------------------------------------------------
@@ -903,6 +927,19 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 	{
 		LLEnvManagerNew::instance().onRegionCrossing();
 	}
+
+	// If the newly entered region is using server bakes, and our
+	// current appearance is non-baked, request appearance update from
+	// server.
+	if (mRegionp->capabilitiesReceived())
+	{
+		handleServerBakeRegionTransition(mRegionp->getRegionID());
+	}
+	else
+	{
+		// Need to handle via callback after caps arrive.
+		mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::handleServerBakeRegionTransition,this,_1));
+	}
 }
 
 
@@ -1685,13 +1722,11 @@ void LLAgent::autoPilot(F32 *delta_yaw)
 
 		*delta_yaw = yaw;
 
-		// Compute when to start slowing down and when to stop
-		F32 stop_distance = mAutoPilotStopDistance;
+		// Compute when to start slowing down
 		F32 slow_distance;
 		if (getFlying())
 		{
 			slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f);
-			stop_distance = llmax(2.f, mAutoPilotStopDistance);
 		}
 		else
 		{
@@ -2277,7 +2312,7 @@ void LLAgent::setStartPosition( U32 location_id )
     if (isAgentAvatarValid())
     {
         // the z height is at the agent's feet
-        agent_pos.mV[VZ] -= 0.5f * gAgentAvatarp->mBodySize.mV[VZ];
+        agent_pos.mV[VZ] -= 0.5f * (gAgentAvatarp->mBodySize.mV[VZ] + gAgentAvatarp->mAvatarOffset.mV[VZ]);
     }
 
     agent_pos.mV[VX] = llclamp( agent_pos.mV[VX], INSET, REGION_WIDTH - INSET );
@@ -2496,7 +2531,7 @@ class LLMaturityPreferencesResponder : public LLHTTPClient::Responder
 	virtual ~LLMaturityPreferencesResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 
 protected:
 
@@ -2534,11 +2569,11 @@ void LLMaturityPreferencesResponder::result(const LLSD &pContent)
 	mAgent->handlePreferredMaturityResult(actualMaturity);
 }
 
-void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason)
+void LLMaturityPreferencesResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
 {
 	llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity)
-		<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '"
-		<< pReason << "' [status:" << pStatus << "]" << llendl;
+		<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error with [status:"
+		<< pStatus << "]: " << (pContent.isDefined() ? pContent : LLSD(pReason)) << llendl;
 	mAgent->handlePreferredMaturityError();
 }
 
@@ -2698,7 +2733,7 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
 		// If we don't have a region, report it as an error
 		if (getRegion() == NULL)
 		{
-			responderPtr->error(0U, "region is not defined");
+			responderPtr->errorWithContent(0U, "region is not defined", LLSD());
 		}
 		else
 		{
@@ -2708,7 +2743,8 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
 			// If the capability is not defined, report it as an error
 			if (url.empty())
 			{
-				responderPtr->error(0U, "capability 'UpdateAgentInformation' is not defined for region");
+				responderPtr->errorWithContent(0U, 
+							"capability 'UpdateAgentInformation' is not defined for region", LLSD());
 			}
 			else
 			{
@@ -3576,7 +3612,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
 		return;
 	}
 
-	if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
+	if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())
 	{
 		// ignore baked textures when in customize mode
 		return;
@@ -3600,7 +3636,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
 
 		if ((S32)texture_index < TEX_NUM_INDICES )
 		{	
-			const LLVOAvatarDictionary::TextureEntry *texture_entry = LLVOAvatarDictionary::instance().getTexture((ETextureIndex)texture_index);
+			const LLAvatarAppearanceDictionary::TextureEntry *texture_entry = LLAvatarAppearanceDictionary::instance().getTexture((ETextureIndex)texture_index);
 			if (texture_entry)
 			{
 				EBakedTextureIndex baked_index = texture_entry->mBakedTextureIndex;
@@ -4207,27 +4243,82 @@ void LLAgent::requestLeaveGodMode()
 	sendReliableMessage();
 }
 
+// For debugging, trace agent state at times appearance message are sent out.
+void LLAgent::dumpSentAppearance(const std::string& dump_prefix)
+{
+	std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml");
+
+	LLAPRFile outfile;
+	std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+	outfile.open(fullpath, LL_APR_WB );
+	apr_file_t* file = outfile.getFileHandle();
+	if (!file)
+	{
+		return;
+	}
+	else
+	{
+		LL_DEBUGS("Avatar") << "dumping sent appearance message to " << fullpath << llendl;
+	}
+
+	LLVisualParam* appearance_version_param = gAgentAvatarp->getVisualParam(11000);
+	if (appearance_version_param)
+	{
+		F32 value = appearance_version_param->getWeight();
+		dump_visual_param(file, appearance_version_param, value);
+	}
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+		 ++iter)
+	{
+		const ETextureIndex index = iter->first;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
+		if (texture_dict->mIsBakedTexture)
+		{
+			LLTextureEntry* entry = gAgentAvatarp->getTE((U8) index);
+			const LLUUID& uuid = entry->getID();
+			apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", index, uuid.asString().c_str());
+		}
+	}
+}
+
 //-----------------------------------------------------------------------------
 // sendAgentSetAppearance()
 //-----------------------------------------------------------------------------
 void LLAgent::sendAgentSetAppearance()
 {
-	if (!isAgentAvatarValid()) return;
-
-	if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures())) 
+	if (gAgentQueryManager.mNumPendingQueries > 0) 
 	{
 		return;
 	}
 
-	if (!gAgentWearables.changeInProgress())
+	if (!isAgentAvatarValid() || (getRegion() && getRegion()->getCentralBakeVersion())) return;
+
+	// At this point we have a complete appearance to send and are in a non-baking region.
+	// DRANO FIXME
+	//gAgentAvatarp->setIsUsingServerBakes(FALSE);
+	S32 sb_count, host_count, both_count, neither_count;
+	gAgentAvatarp->bakedTextureOriginCounts(sb_count, host_count, both_count, neither_count);
+	if (both_count != 0 || neither_count != 0)
 	{
-		// Change is fully resolved, can close some open phases.
-		gAgentAvatarp->getPhases().stopPhase("process_initial_wearables_update");
-		gAgentAvatarp->getPhases().stopPhase("wear_inventory_category");
+		llwarns << "bad bake texture state " << sb_count << "," << host_count << "," << both_count << "," << neither_count << llendl;
+	}
+	if (sb_count != 0 && host_count == 0)
+	{
+		gAgentAvatarp->setIsUsingServerBakes(true);
+	}
+	else if (sb_count == 0 && host_count != 0)
+	{
+		gAgentAvatarp->setIsUsingServerBakes(false);
+	}
+	else if (sb_count + host_count > 0)
+	{
+		llwarns << "unclear baked texture state, not sending appearance" << llendl;
+		return;
 	}
 	
-	gAgentAvatarp->sendAppearanceChangeMetrics();
-	LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;
+
+	LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;
 	//dumpAvatarTEs( "sendAgentSetAppearance()" );
 
 	LLMessageSystem* msg = gMessageSystem;
@@ -4241,7 +4332,7 @@ void LLAgent::sendAgentSetAppearance()
 	// NOTE -- when we start correcting all of the other Havok geometry 
 	// to compensate for the COLLISION_TOLERANCE ugliness we will have 
 	// to tweak this number again
-	const LLVector3 body_size = gAgentAvatarp->mBodySize;
+	const LLVector3 body_size = gAgentAvatarp->mBodySize + gAgentAvatarp->mAvatarOffset;
 	msg->addVector3Fast(_PREHASH_Size, body_size);	
 
 	// To guard against out of order packets
@@ -4255,7 +4346,7 @@ void LLAgent::sendAgentSetAppearance()
 
 	for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
 	{
-		const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
+		const ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
 
 		// if we're not wearing a skirt, we don't need the texture to be baked
 		if (texture_index == TEX_SKIRT_BAKED && !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
@@ -4266,19 +4357,30 @@ void LLAgent::sendAgentSetAppearance()
 		// IMG_DEFAULT_AVATAR means not baked. 0 index should be ignored for baked textures
 		if (!gAgentAvatarp->isTextureDefined(texture_index, 0))
 		{
+			LL_DEBUGS("Avatar") << "texture not current for baked " << (S32)baked_index << " local " << (S32)texture_index << llendl;
 			textures_current = FALSE;
 			break;
 		}
 	}
 
 	// only update cache entries if we have all our baked textures
+
+	// FIXME DRANO need additional check for not in appearance editing
+	// mode, if still using local composites need to set using local
+	// composites to false, and update mesh textures.
 	if (textures_current)
 	{
-		LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sending cached texture data" << LL_ENDL;
+		bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+		std::string dump_prefix = gAgentAvatarp->getFullname() + "_sent_appearance";
+		if (enable_verbose_dumps)
+		{
+			dumpSentAppearance(dump_prefix);
+		}
+		LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "TAT: Sending cached texture data" << LL_ENDL;
 		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 		{
 			BOOL generate_valid_hash = TRUE;
-			if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index))
+			if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLAvatarAppearanceDefines::EBakedTextureIndex)baked_index))
 			{
 				generate_valid_hash = FALSE;
 				LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << LL_ENDL;
@@ -4287,7 +4389,7 @@ void LLAgent::sendAgentSetAppearance()
 			const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash);
 			if (hash.notNull())
 			{
-				ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
+				ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
 				msg->nextBlockFast(_PREHASH_WearableData);
 				msg->addUUIDFast(_PREHASH_CacheID, hash);
 				msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
@@ -4323,7 +4425,7 @@ void LLAgent::sendAgentSetAppearance()
 		}
 	}
 
-//	llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;
+	//llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;
 	sendReliableMessage();
 }
 
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index daa15b0c1a46ac577c2644abf01b447460ecf1b8..f5f26f69d806167afe0ae382c4fccc2998b723d5 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -33,7 +33,8 @@
 #include "llagentdata.h" 			// gAgentID, gAgentSessionID
 #include "llcharacter.h"
 #include "llcoordframe.h"			// for mFrameAgent
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
+#include "llpermissionsflags.h"
 
 #include <boost/function.hpp>
 #include <boost/shared_ptr.hpp>
@@ -608,6 +609,7 @@ class LLAgent : public LLOldEvents::LLObservable
 
 	void            handleTeleportFinished();
 	void            handleTeleportFailed();
+	void			handleServerBakeRegionTransition(const LLUUID& region_id);
 
 	//--------------------------------------------------------------------
 	// Teleport State
@@ -842,6 +844,7 @@ class LLAgent : public LLOldEvents::LLObservable
 public:
 	void			sendMessage(); // Send message to this agent's region
 	void			sendReliableMessage();
+	void 			dumpSentAppearance(const std::string& dump_prefix);
 	void			sendAgentSetAppearance();
 	void 			sendAgentDataUpdateRequest();
 	void 			sendAgentUserInfoRequest();
@@ -900,7 +903,7 @@ class LLAgentQueryManager
 	S32				mNumPendingQueries;
 	S32				mWearablesCacheQueryID;
 	U32				mUpdateSerialNum;
-	S32		    	mActiveCacheQueries[LLVOAvatarDefines::BAKED_NUM_INDICES];
+	S32		    	mActiveCacheQueries[LLAvatarAppearanceDefines::BAKED_NUM_INDICES];
 };
 
 extern LLAgentQueryManager gAgentQueryManager;
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 9025c7af8be38b9bbd17ac5a73cbe478f09f3144..0896aa5972467beedf965b9318826ab5df116e99 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -50,7 +50,7 @@
 #include "llwindow.h"
 #include "llworld.h"
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 extern LLMenuBarGL* gMenuBarView;
 
@@ -594,7 +594,6 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
 	abs_target_offset.abs();
 
 	LLVector3 target_offset_dir = target_offset_origin;
-	F32 object_radius = mFocusObject->getVObjRadius();
 
 	BOOL target_outside_object_extents = FALSE;
 
@@ -689,17 +688,6 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
 
 	LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent());
 
-	// length projected orthogonal to target offset
-	F32 camera_offset_dist = (camera_offset_object - target_offset_dir * (camera_offset_object * target_offset_dir)).magVec();
-
-	// calculate whether the target point would be "visible" if it were outside the bounding box
-	// on the opposite of the splitting plane defined by object_split_axis;
-	BOOL exterior_target_visible = FALSE;
-	if (camera_offset_dist > object_radius)
-	{
-		// target is visible from camera, so turn off fov zoom
-		exterior_target_visible = TRUE;
-	}
 
 	F32 camera_offset_clip = camera_offset_object * object_split_axis;
 	F32 target_offset_clip = target_offset_dir * object_split_axis;
@@ -1079,8 +1067,8 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
 
 	if (!isAgentAvatarValid()) return;
 
-	LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot.getWorldRotation();
-	LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot.getWorldRotation();
+	LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation();
+	LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation();
 
 	if 	((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) &&
 		 (root_at * last_at_axis > 0.95f))
@@ -1433,7 +1421,7 @@ void LLAgentCamera::updateCamera()
 			LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() + 
 			LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation();
 		LLVector3 diff = mCameraPositionAgent - head_pos;
-		diff = diff * ~gAgentAvatarp->mRoot.getWorldRotation();
+		diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation();
 
 		LLJoint* torso_joint = gAgentAvatarp->mTorsop;
 		LLJoint* chest_joint = gAgentAvatarp->mChestp;
@@ -1457,7 +1445,7 @@ void LLAgentCamera::updateCamera()
 
 		gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff);
 
-		gAgentAvatarp->mRoot.updateWorldMatrixChildren();
+		gAgentAvatarp->mRoot->updateWorldMatrixChildren();
 
 		for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); 
 			 iter != gAgentAvatarp->mAttachmentPoints.end(); )
@@ -1658,7 +1646,6 @@ F32	LLAgentCamera::calcCameraFOVZoomFactor()
 	else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar)
 	{
 		// don't FOV zoom on mostly transparent objects
-		LLVector3 focus_offset = mFocusObjectOffset;
 		F32 obj_min_dist = 0.f;
 		calcCameraMinDistance(obj_min_dist);
 		F32 current_distance = llmax(0.001f, camera_offset_dir.magVec());
@@ -1685,7 +1672,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 	F32			camera_land_height;
 	LLVector3d	frame_center_global = !isAgentAvatarValid() ? 
 		gAgent.getPositionGlobal() :
-		gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition());
+		gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());
 	
 	BOOL		isConstrained = FALSE;
 	LLVector3d	head_offset;
@@ -1820,7 +1807,6 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 			// set the global camera position
 			LLVector3d camera_offset;
 			
-			LLVector3 av_pos = !isAgentAvatarValid() ? LLVector3::zero : gAgentAvatarp->getRenderPosition();
 			camera_offset.setVec( local_camera_offset );
 			camera_position_global = frame_center_global + head_offset + camera_offset;
 
@@ -2257,7 +2243,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
 //-----------------------------------------------------------------------------
 void LLAgentCamera::changeCameraToCustomizeAvatar()
 {
-	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid())
 	{
 		return;
 	}
@@ -2281,29 +2267,21 @@ void LLAgentCamera::changeCameraToCustomizeAvatar()
 		gFocusMgr.setKeyboardFocus( NULL );
 		gFocusMgr.setMouseCapture( NULL );
 
-		LLVOAvatarSelf::onCustomizeStart();
+		// Remove any pitch or rotation from the avatar
+		LLVector3 at = gAgent.getAtAxis();
+		at.mV[VZ] = 0.f;
+		at.normalize();
+		gAgent.resetAxes(at);
 
-		if (isAgentAvatarValid())
-		{
-			// Remove any pitch or rotation from the avatar
-			LLVector3 at = gAgent.getAtAxis();
-			at.mV[VZ] = 0.f;
-			at.normalize();
-			gAgent.resetAxes(at);
+		gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
+		gAgent.setCustomAnim(TRUE);
+		gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
+		LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
 
-			gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
-			gAgent.setCustomAnim(TRUE);
-			gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
-			LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
-
-			if (turn_motion)
-			{
-				// delay camera animation long enough to play through turn animation
-				setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
-			}
-
-			gAgentAvatarp->invalidateAll();
-			gAgentAvatarp->updateMeshTextures();
+		if (turn_motion)
+		{
+			// delay camera animation long enough to play through turn animation
+			setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
 		}
 	}
 
diff --git a/indra/newview/llagentpilot.cpp b/indra/newview/llagentpilot.cpp
index 734c502fcf69676804fd2b2328abfeb39bb3b257..c7872fc5f61e5f9ee169947061db292e48fef769 100644
--- a/indra/newview/llagentpilot.cpp
+++ b/indra/newview/llagentpilot.cpp
@@ -139,7 +139,7 @@ void LLAgentPilot::loadXML(const std::string& filename)
 
 	mActions.reset();
 	LLSD record;
-	while (!file.eof() && LLSDSerialize::fromXML(record, file))
+	while (!file.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(record, file))
 	{
 		Action action;
 		action.mTime = record["time"].asReal();
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
old mode 100644
new mode 100755
index e441f21f904374bc0530159c901b8080464dd4c2..c88694ef76b9054cfbe20543c33027a4681c0d07
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -47,7 +47,7 @@
 #include "lltooldraganddrop.h"
 #include "llviewerregion.h"
 #include "llvoavatarself.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
 #include "llwearablelist.h"
 
 #include <boost/scoped_ptr.hpp>
@@ -56,24 +56,21 @@ LLAgentWearables gAgentWearables;
 
 BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 ///////////////////////////////////////////////////////////////////////////////
 
 // Callback to wear and start editing an item that has just been created.
-class LLWearAndEditCallback : public LLInventoryCallback
+void wear_and_edit_cb(const LLUUID& inv_item)
 {
-	void fire(const LLUUID& inv_item)
-	{
-		if (inv_item.isNull()) return;
-
-		// Request editing the item after it gets worn.
-		gAgentWearables.requestEditingWearable(inv_item);
-
-		// Wear it.
-		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
-	}
-};
+	if (inv_item.isNull()) return;
+	
+	// Request editing the item after it gets worn.
+	gAgentWearables.requestEditingWearable(inv_item);
+	
+	// Wear it.
+	LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -82,7 +79,7 @@ class LLWearAndEditCallback : public LLInventoryCallback
 // wearable type stored in asset is some other value.
 // Calling this function whenever a wearable is added to increase visibility if this problem
 // turns up in other inventories.
-void checkWearableAgainstInventory(LLWearable *wearable)
+void checkWearableAgainstInventory(LLViewerWearable *wearable)
 {
 	if (wearable->getItemID().isNull())
 		return;
@@ -119,7 +116,7 @@ void LLAgentWearables::dump()
 		llinfos << "Type: " << i << " count " << count << llendl;
 		for (U32 j=0; j<count; j++)
 		{
-			LLWearable* wearable = getWearable((LLWearableType::EType)i,j);
+			LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)i,j);
 			if (wearable == NULL)
 			{
 				llinfos << "    " << j << " NULL wearable" << llendl;
@@ -159,6 +156,7 @@ struct LLAgentDumper
 };
 
 LLAgentWearables::LLAgentWearables() :
+	LLWearableData(),
 	mWearablesLoaded(FALSE)
 ,	mCOFChangeInProgress(false)
 {
@@ -182,12 +180,11 @@ void LLAgentWearables::initClass()
 }
 
 void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
-{ 
-	if (avatar)
-	{
-		avatar->outputRezTiming("Sending wearables request");
-		sendAgentWearablesRequest();
-	}
+{
+	llassert(avatar);
+	avatar->outputRezTiming("Sending wearables request");
+	sendAgentWearablesRequest();
+	setAvatarAppearance(avatar);
 }
 
 // wearables
@@ -213,12 +210,13 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal
  * @param todo Bitmask of actions to take on completion.
  */
 LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
-	LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLWearable* wearable, U32 todo) :
+	LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLViewerWearable* wearable, U32 todo, const std::string description) :
 	mType(type),
 	mIndex(index),	
 	mWearable(wearable),
 	mTodo(todo),
-	mCB(cb)
+	mCB(cb),
+	mDescription(description)
 {
 	llinfos << "constructor" << llendl;
 }
@@ -258,14 +256,14 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
 	}
 	if (mTodo & CALL_WEARITEM)
 	{
-		LLAppearanceMgr::instance().addCOFItemLink(inv_item, true);
+		LLAppearanceMgr::instance().addCOFItemLink(inv_item, true, NULL, mDescription);
 	}
 }
 
 void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::EType type,
 													   const U32 index,
 													   const LLUUID& item_id,
-													   LLWearable* wearable)
+													   LLViewerWearable* wearable)
 {
 	llinfos << "type " << type << " index " << index << " item " << item_id.asString() << llendl;
 
@@ -312,7 +310,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()
 	{
 		for (U32 index=0; index < getWearableCount((LLWearableType::EType)type); ++index)
 		{
-			LLWearable* wearable = getWearable((LLWearableType::EType)type,index);
+			LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type,index);
 			if (wearable)
 			{
 				if (wearable->getItemID().isNull())
@@ -354,7 +352,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()
 		U8 type_u8 = (U8)type;
 		gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8);
 
-		LLWearable* wearable = getWearable((LLWearableType::EType)type, 0);
+		LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type, 0);
 		if (wearable)
 		{
 			//llinfos << "Sending wearable " << wearable->getName() << llendl;
@@ -382,14 +380,14 @@ void LLAgentWearables::sendAgentWearablesUpdate()
 void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update,
 									const std::string new_name)
 {
-	LLWearable* old_wearable = getWearable(type, index);
+	LLViewerWearable* old_wearable = getViewerWearable(type, index);
 	if(!old_wearable) return;
 	bool name_changed = !new_name.empty() && (new_name != old_wearable->getName());
 	if (name_changed || old_wearable->isDirty() || old_wearable->isOldVersion())
 	{
 		LLUUID old_item_id = old_wearable->getItemID();
-		LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
-		new_wearable->setItemID(old_item_id); // should this be in LLWearable::copyDataFrom()?
+		LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
+		new_wearable->setItemID(old_item_id); // should this be in LLViewerWearable::copyDataFrom()?
 		setWearable(type,index,new_wearable);
 
 		// old_wearable may still be referred to by other inventory items. Revert
@@ -458,6 +456,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
 void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 									  const U32 index,
 									  const std::string& new_name,
+									  const std::string& description,
 									  BOOL save_in_lost_and_found)
 {
 	if (!isWearableCopyable(type, index))
@@ -465,7 +464,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 		llwarns << "LLAgent::saveWearableAs() not copyable." << llendl;
 		return;
 	}
-	LLWearable* old_wearable = getWearable(type, index);
+	LLViewerWearable* old_wearable = getViewerWearable(type, index);
 	if (!old_wearable)
 	{
 		llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl;
@@ -480,7 +479,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 	}
 	std::string trunc_name(new_name);
 	LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN);
-	LLWearable* new_wearable = LLWearableList::instance().createCopy(
+	LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(
 		old_wearable,
 		trunc_name);
 	LLPointer<LLInventoryCallback> cb =
@@ -489,7 +488,9 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 			type,
 			index,
 			new_wearable,
-			addWearableToAgentInventoryCallback::CALL_WEARITEM);
+			addWearableToAgentInventoryCallback::CALL_WEARITEM,
+			description
+			);
 	LLUUID category_id;
 	if (save_in_lost_and_found)
 	{
@@ -518,7 +519,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 
 void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index)
 {
-	LLWearable* wearable = getWearable(type, index);
+	LLViewerWearable* wearable = getViewerWearable(type, index);
 	llassert(wearable);
 	if (wearable)
 	{
@@ -553,13 +554,13 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string&
 			LLUUID curr_item_id = getWearableItemID((LLWearableType::EType)i,j);
 			if (curr_item_id == item_id)
 			{
-				LLWearable* old_wearable = getWearable((LLWearableType::EType)i,j);
+				LLViewerWearable* old_wearable = getViewerWearable((LLWearableType::EType)i,j);
 				llassert(old_wearable);
 				if (!old_wearable) continue;
 
 				std::string old_name = old_wearable->getName();
 				old_wearable->setName(new_name);
-				LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
+				LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
 				new_wearable->setItemID(item_id);
 				LLInventoryItem* item = gInventory.getItem(item_id);
 				if (item)
@@ -640,14 +641,14 @@ LLInventoryItem* LLAgentWearables::getWearableInventoryItem(LLWearableType::ETyp
 	return item;
 }
 
-const LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) const
+const LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) const
 {
 	const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
 	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
 	{
 		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
 		{
-			const LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+			const LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
 			if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
 			{
 				return curr_wearable;
@@ -657,14 +658,14 @@ const LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
 	return NULL;
 }
 
-LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
+LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
 {
 	const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
 	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
 	{
 		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
 		{
-			LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+			LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
 			if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
 			{
 				return curr_wearable;
@@ -674,13 +675,13 @@ LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
 	return NULL;
 }
 
-LLWearable*	LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id) 
+LLViewerWearable*	LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id) 
 {
 	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
 	{
 		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
 		{
-			LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+			LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
 			if (curr_wearable && (curr_wearable->getAssetID() == asset_id))
 			{
 				return curr_wearable;
@@ -699,215 +700,55 @@ void LLAgentWearables::sendAgentWearablesRequest()
 	gAgent.sendReliableMessage();
 }
 
-// static
-BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)
-{
-	return (gAgentWearables.getWearableCount(type) > 0);
-}
-
-LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index)
-{
-	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
-	if (wearable_iter == mWearableDatas.end())
-	{
-		return NULL;
-	}
-	wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	if (index>=wearable_vec.size())
-	{
-		return NULL;
-	}
-	else
-	{
-		return wearable_vec[index];
-	}
-}
-
-void LLAgentWearables::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable)
+LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/)
 {
-
-	LLWearable *old_wearable = getWearable(type,index);
-	if (!old_wearable)
-	{
-		pushWearable(type,wearable);
-		return;
-	}
-	
-	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
-	if (wearable_iter == mWearableDatas.end())
-	{
-		llwarns << "invalid type, type " << type << " index " << index << llendl; 
-		return;
-	}
-	wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	if (index>=wearable_vec.size())
-	{
-		llwarns << "invalid index, type " << type << " index " << index << llendl; 
-	}
-	else
-	{
-		wearable_vec[index] = wearable;
-		old_wearable->setLabelUpdated();
-		wearableUpdated(wearable);
-		checkWearableAgainstInventory(wearable);
-	}
+	return dynamic_cast<LLViewerWearable*> (getWearable(type, index));
 }
 
-U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLWearable *wearable)
+const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const
 {
-	if (wearable == NULL)
-	{
-		// no null wearables please!
-		llwarns << "Null wearable sent for type " << type << llendl;
-		return MAX_CLOTHING_PER_TYPE;
-	}
-	if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
-	{
-		mWearableDatas[type].push_back(wearable);
-		wearableUpdated(wearable);
-		checkWearableAgainstInventory(wearable);
-		return mWearableDatas[type].size()-1;
-	}
-	return MAX_CLOTHING_PER_TYPE;
+	return dynamic_cast<const LLViewerWearable*> (getWearable(type, index));
 }
 
-void LLAgentWearables::wearableUpdated(LLWearable *wearable)
+// static
+BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)
 {
-	gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE);
-	wearable->refreshName();
-	wearable->setLabelUpdated();
-
-	wearable->pullCrossWearableValues();
-
-	// Hack pt 2. If the wearable we just loaded has definition version 24,
-	// then force a re-save of this wearable after slamming the version number to 22.
-	// This number was incorrectly incremented for internal builds before release, and
-	// this fix will ensure that the affected wearables are re-saved with the right version number.
-	// the versions themselves are compatible. This code can be removed before release.
-	if( wearable->getDefinitionVersion() == 24 )
-	{
-		wearable->setDefinitionVersion(22);
-		U32 index = getWearableIndex(wearable);
-		llinfos << "forcing werable type " << wearable->getType() << " to version 22 from 24" << llendl;
-		saveWearable(wearable->getType(),index,TRUE);
-	}
-
+	return (gAgentWearables.getWearableCount(type) > 0);
 }
 
-void LLAgentWearables::popWearable(LLWearable *wearable)
+// virtual
+void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed)
 {
-	if (wearable == NULL)
+	if (isAgentAvatarValid())
 	{
-		// nothing to do here. move along.
-		return;
+		const BOOL upload_result = removed;
+		gAgentAvatarp->wearableUpdated(wearable->getType(), upload_result);
 	}
 
-	U32 index = getWearableIndex(wearable);
-	LLWearableType::EType type = wearable->getType();
+	LLWearableData::wearableUpdated(wearable, removed);
 
-	if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type))
+	if (!removed)
 	{
-		popWearable(type, index);
-	}
-}
+		LLViewerWearable* viewer_wearable = dynamic_cast<LLViewerWearable*>(wearable);
+		viewer_wearable->refreshName();
 
-void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index)
-{
-	LLWearable *wearable = getWearable(type, index);
-	if (wearable)
-	{
-		mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
-		if (isAgentAvatarValid())
+		// Hack pt 2. If the wearable we just loaded has definition version 24,
+		// then force a re-save of this wearable after slamming the version number to 22.
+		// This number was incorrectly incremented for internal builds before release, and
+		// this fix will ensure that the affected wearables are re-saved with the right version number.
+		// the versions themselves are compatible. This code can be removed before release.
+		if( wearable->getDefinitionVersion() == 24 )
 		{
-		gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE);
+			wearable->setDefinitionVersion(22);
+			U32 index = getWearableIndex(wearable);
+			llinfos << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << llendl;
+			saveWearable(wearable->getType(),index,TRUE);
 		}
-		wearable->setLabelUpdated();
-	}
-}
 
-U32	LLAgentWearables::getWearableIndex(const LLWearable *wearable) const
-{
-	if (wearable == NULL)
-	{
-		return MAX_CLOTHING_PER_TYPE;
+		checkWearableAgainstInventory(viewer_wearable);
 	}
-
-	const LLWearableType::EType type = wearable->getType();
-	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
-	if (wearable_iter == mWearableDatas.end())
-	{
-		llwarns << "tried to get wearable index with an invalid type!" << llendl;
-		return MAX_CLOTHING_PER_TYPE;
-	}
-	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	for(U32 index = 0; index < wearable_vec.size(); index++)
-	{
-		if (wearable_vec[index] == wearable)
-		{
-			return index;
-		}
-	}
-
-	return MAX_CLOTHING_PER_TYPE;
 }
 
-const LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index) const
-{
-	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
-	if (wearable_iter == mWearableDatas.end())
-	{
-		return NULL;
-	}
-	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	if (index>=wearable_vec.size())
-	{
-		return NULL;
-	}
-	else
-	{
-		return wearable_vec[index];
-	}
-}
-
-LLWearable* LLAgentWearables::getTopWearable(const LLWearableType::EType type)
-{
-	U32 count = getWearableCount(type);
-	if ( count == 0)
-	{
-		return NULL;
-	}
-
-	return getWearable(type, count-1);
-}
-
-LLWearable* LLAgentWearables::getBottomWearable(const LLWearableType::EType type)
-{
-	if (getWearableCount(type) == 0)
-	{
-		return NULL;
-	}
-
-	return getWearable(type, 0);
-}
-
-U32 LLAgentWearables::getWearableCount(const LLWearableType::EType type) const
-{
-	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
-	if (wearable_iter == mWearableDatas.end())
-	{
-		return 0;
-	}
-	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	return wearable_vec.size();
-}
-
-U32 LLAgentWearables::getWearableCount(const U32 tex_index) const
-{
-	const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((LLVOAvatarDefines::ETextureIndex)tex_index);
-	return getWearableCount(wearable_type);
-}
-
-
 BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const
 {
 	return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end();
@@ -920,7 +761,7 @@ U32 LLAgentWearables::itemUpdatePendingCount() const
 
 const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 index) const
 {
-	const LLWearable *wearable = getWearable(type,index);
+	const LLViewerWearable *wearable = getViewerWearable(type,index);
 	if (wearable)
 		return wearable->getItemID();
 	else
@@ -929,7 +770,7 @@ const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32
 
 const LLUUID LLAgentWearables::getWearableAssetID(LLWearableType::EType type, U32 index) const
 {
-	const LLWearable *wearable = getWearable(type,index);
+	const LLViewerWearable *wearable = getViewerWearable(type,index);
 	if (wearable)
 		return wearable->getAssetID();
 	else
@@ -955,8 +796,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
 
 	if (isAgentAvatarValid())
 	{
-		//gAgentAvatarp->clearPhases(); // reset phase timers for outfit loading.
-		gAgentAvatarp->getPhases().startPhase("process_initial_wearables_update");
+		gAgentAvatarp->startPhase("process_initial_wearables_update");
 		gAgentAvatarp->outputRezTiming("Received initial wearables update");
 	}
 
@@ -1012,7 +852,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
 			gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i);
 			if (asset_id.isNull())
 			{
-				LLWearable::removeFromAvatar(type, FALSE);
+				LLViewerWearable::removeFromAvatar(type, FALSE);
 			}
 			else
 			{
@@ -1058,7 +898,7 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type,
 	// Try to recover by replacing missing wearable with a new one.
 	LLNotificationsUtil::add("ReplacedMissingWearable");
 	lldebugs << "Wearable " << LLWearableType::getTypeLabel(type) << " could not be downloaded.  Replaced inventory item with default wearable." << llendl;
-	LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type);
+	LLViewerWearable* new_wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
 
 	setWearable(type,index,new_wearable);
 	//new_wearable->writeToAvatar(TRUE);
@@ -1093,9 +933,9 @@ void LLAgentWearables::recoverMissingWearableDone()
 	}
 }
 
-void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index)
+void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index)
 {
-	LLWearable* wearable = getWearable((LLWearableType::EType)wearable_type, wearable_index);
+	LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)wearable_type, wearable_index);
 	if (!wearable)
 	{
 		llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl;
@@ -1125,10 +965,10 @@ class OnWearableItemCreatedCB: public LLInventoryCallback
 		llinfos << "All items created" << llendl;
 		LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
 		LLAppearanceMgr::instance().linkAll(LLAppearanceMgr::instance().getCOF(),
-												mItemsToLink,
-												link_waiter);
+											mItemsToLink,
+											link_waiter);
 	}
-	void addPendingWearable(LLWearable *wearable)
+	void addPendingWearable(LLViewerWearable *wearable)
 	{
 		if (!wearable)
 		{
@@ -1163,7 +1003,7 @@ class OnWearableItemCreatedCB: public LLInventoryCallback
 			LLWearableType::EType type = item->getWearableType();
 			if (type < LLWearableType::WT_COUNT)
 			{
-				LLWearable *wearable = mWearablesAwaitingItems[type];
+				LLViewerWearable *wearable = mWearablesAwaitingItems[type];
 				if (wearable)
 					wearable->setItemID(inv_item);
 			}
@@ -1176,7 +1016,7 @@ class OnWearableItemCreatedCB: public LLInventoryCallback
 	
 private:
 	LLInventoryModel::item_array_t mItemsToLink;
-	std::vector<LLWearable*> mWearablesAwaitingItems;
+	std::vector<LLViewerWearable*> mWearablesAwaitingItems;
 };
 
 void LLAgentWearables::createStandardWearables()
@@ -1208,7 +1048,7 @@ void LLAgentWearables::createStandardWearables()
 		if (create[i])
 		{
 			llassert(getWearableCount((LLWearableType::EType)i) == 0);
-			LLWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i);
+			LLViewerWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i, gAgentAvatarp);
 			((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable);
 			// no need to update here...
 			LLUUID category_id = LLUUID::null;
@@ -1267,7 +1107,7 @@ void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
 
 
 void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
-												   LLWearable* wearable,
+												   LLViewerWearable* wearable,
 												   const LLUUID& category_id,
 												   BOOL notify)
 {
@@ -1305,7 +1145,7 @@ void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_
 	}
 	else
 	{
-		LLWearable* old_wearable = getWearable(type,index);
+		LLViewerWearable* old_wearable = getViewerWearable(type,index);
 		
 		if (old_wearable)
 		{
@@ -1360,10 +1200,10 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo
 	//LLAgentDumper dumper("removeWearable");
 	if (do_remove_all)
 	{
-		S32 max_entry = mWearableDatas[type].size()-1;
+		S32 max_entry = getWearableCount(type)-1;
 		for (S32 i=max_entry; i>=0; i--)
 		{
-			LLWearable* old_wearable = getWearable(type,i);
+			LLViewerWearable* old_wearable = getViewerWearable(type,i);
 			//queryWearableCache(); // moved below
 			if (old_wearable)
 			{
@@ -1371,11 +1211,11 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo
 				old_wearable->removeFromAvatar(TRUE);
 			}
 		}
-		mWearableDatas[type].clear();
+		clearWearableType(type);
 	}
 	else
 	{
-		LLWearable* old_wearable = getWearable(type, index);
+		LLViewerWearable* old_wearable = getViewerWearable(type, index);
 		//queryWearableCache(); // moved below
 
 		if (old_wearable)
@@ -1394,7 +1234,7 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo
 
 // Assumes existing wearables are not dirty.
 void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& items,
-										 const LLDynamicArray< LLWearable* >& wearables,
+										 const LLDynamicArray< LLViewerWearable* >& wearables,
 										 BOOL remove)
 {
 	llinfos << "setWearableOutfit() start" << llendl;
@@ -1419,7 +1259,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
 	S32 i;
 	for (i = 0; i < count; i++)
 	{
-		LLWearable* new_wearable = wearables[i];
+		LLViewerWearable* new_wearable = wearables[i];
 		LLPointer<LLInventoryItem> new_item = items[i];
 
 		llassert(new_wearable);
@@ -1439,8 +1279,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
 			{
 				pushWearable(type,new_wearable);
 			}
-			wearableUpdated(new_wearable);
-			checkWearableAgainstInventory(new_wearable);
+			const BOOL removed = FALSE;
+			wearableUpdated(new_wearable, removed);
 		}
 	}
 
@@ -1476,7 +1316,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
 
 
 // User has picked "wear on avatar" from a menu.
-void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
+void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append)
 {
 	//LLAgentDumper dumper("setWearableItem");
 	if (isWearingItem(new_item->getUUID()))
@@ -1491,7 +1331,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
 	{
 		// Remove old wearable, if any
 		// MULTI_WEARABLE: hardwired to 0
-		LLWearable* old_wearable = getWearable(type,0);
+		LLViewerWearable* old_wearable = getViewerWearable(type,0);
 		if (old_wearable)
 		{
 			const LLUUID& old_item_id = old_wearable->getItemID();
@@ -1517,7 +1357,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
 }
 
 // static 
-bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable)
+bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	LLInventoryItem* new_item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
@@ -1553,16 +1393,17 @@ bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD&
 
 // Called from setWearableItem() and onSetWearableDialog() to actually set the wearable.
 // MULTI_WEARABLE: unify code after null objects are gone.
-void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
+void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append)
 {
 	const LLWearableType::EType type = new_wearable->getType();
 
 	if (do_append && getWearableItemID(type,0).notNull())
 	{
 		new_wearable->setItemID(new_item->getUUID());
-		mWearableDatas[type].push_back(new_wearable);
+		const bool trigger_updated = false;
+		pushWearable(type, new_wearable, trigger_updated);
 		llinfos << "Added additional wearable for type " << type
-				<< " size is now " << mWearableDatas[type].size() << llendl;
+				<< " size is now " << getWearableCount(type) << llendl;
 		checkWearableAgainstInventory(new_wearable);
 	}
 	else
@@ -1570,7 +1411,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
 		// Replace the old wearable with a new one.
 		llassert(new_item->getAssetUUID() == new_wearable->getAssetID());
 
-		LLWearable *old_wearable = getWearable(type,0);
+		LLViewerWearable *old_wearable = getViewerWearable(type,0);
 		LLUUID old_item_id;
 		if (old_wearable)
 		{
@@ -1585,7 +1426,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
 			gInventory.notifyObservers();
 		}
 		llinfos << "Replaced current element 0 for type " << type
-				<< " size is now " << mWearableDatas[type].size() << llendl;
+				<< " size is now " << getWearableCount(type) << llendl;
 	}
 
 	//llinfos << "LLVOAvatar::setWearableItem()" << llendl;
@@ -1597,7 +1438,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
 
 void LLAgentWearables::queryWearableCache()
 {
-	if (!areWearablesLoaded())
+	if (!areWearablesLoaded() || (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()))
 	{
 		return;
 	}
@@ -1626,7 +1467,7 @@ void LLAgentWearables::queryWearableCache()
 			num_queries++;
 			// *NOTE: make sure at least one request gets packed
 
-			ETextureIndex te_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
+			ETextureIndex te_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
 
 			//llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;
 			gMessageSystem->nextBlockFast(_PREHASH_WearableData);
@@ -1645,53 +1486,21 @@ void LLAgentWearables::queryWearableCache()
 			gAgentAvatarp->outputRezTiming("Fetching textures from cache");
 		}
 
-		LL_INFOS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL;
+		LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL;
 		gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
 		gAgentQueryManager.mNumPendingQueries++;
 		gAgentQueryManager.mWearablesCacheQueryID++;
 	}
 }
 
-LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
-												 BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
+// virtual
+void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const
 {
-	LLUUID hash_id;
-	bool hash_computed = false;
-	LLMD5 hash;
-	const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
-
-	for (U8 i=0; i < baked_dict->mWearables.size(); i++)
-	{
-		const LLWearableType::EType baked_type = baked_dict->mWearables[i];
-		const U32 num_wearables = getWearableCount(baked_type);
-		for (U32 index = 0; index < num_wearables; ++index)
-		{
-			const LLWearable* wearable = getWearable(baked_type,index);
-			if (wearable)
-			{
-				LLUUID asset_id = wearable->getAssetID();
-				hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
-				hash_computed = true;
-			}
-		}
-	}
-	if (hash_computed)
+	// Add some garbage into the hash so that it becomes invalid.
+	if (isAgentAvatarValid())
 	{
-		hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
-
-		// Add some garbage into the hash so that it becomes invalid.
-		if (!generate_valid_hash)
-		{
-			if (isAgentAvatarValid())
-			{
-				hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
-			}
-		}
-		hash.finalize();
-		hash.raw_digest(hash_id.mData);
+		hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
 	}
-
-	return hash_id;
 }
 
 // User has picked "remove from avatar" from a menu.
@@ -1715,7 +1524,7 @@ void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &ty
 	}
 }
 
-// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to
+// Combines userRemoveMulipleAttachments() and userAttachMultipleAttachments() logic to
 // get attachments into desired state with minimal number of adds/removes.
 void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
 {
@@ -1811,31 +1620,6 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo
 	gMessageSystem->sendReliable(gAgent.getRegionHost());
 }
 
-void LLAgentWearables::userRemoveAllAttachments()
-{
-	if (!isAgentAvatarValid()) return;
-
-	llvo_vec_t objects_to_remove;
-	
-	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 *attached_object = (*attachment_iter);
-			if (attached_object)
-			{
-				objects_to_remove.push_back(attached_object);
-			}
-		}
-	}
-	userRemoveMultipleAttachments(objects_to_remove);
-}
-
 void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array)
 {
 	// Build a compound message to send all the objects that need to be rezzed.
@@ -1900,7 +1684,7 @@ void LLAgentWearables::checkWearablesLoaded() const
 
 // Returns false if the given wearable is already topmost/bottommost
 // (depending on closer_to_body parameter).
-bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body)
+bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body) const
 {
 	const LLWearable* wearable = getWearableFromItemID(item_id);
 	if (!wearable) return false;
@@ -1928,7 +1712,7 @@ void LLAgentWearables::updateWearablesLoaded()
 	}
 }
 
-bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const
+bool LLAgentWearables::canWearableBeRemoved(const LLViewerWearable* wearable) const
 {
 	if (!wearable) return false;
 	
@@ -1943,7 +1727,7 @@ void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake)
 	{
 		for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count)
 		{
-			LLWearable *wearable = getWearable((LLWearableType::EType)type,count);
+			LLViewerWearable *wearable = getViewerWearable((LLWearableType::EType)type,count);
 			llassert(wearable);
 			if (wearable)
 			{
@@ -1958,28 +1742,39 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos
 	if (!item) return false;
 	if (!item->isWearableType()) return false;
 
-	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(item->getWearableType());
-	if (wearable_iter == mWearableDatas.end()) return false;
-
-	wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	if (wearable_vec.empty()) return false;
+	LLWearableType::EType type = item->getWearableType();
+	U32 wearable_count = getWearableCount(type);
+	if (0 == wearable_count) return false;
 
 	const LLUUID& asset_id = item->getAssetUUID();
 
 	//nowhere to move if the wearable is already on any boundary (closest to the body/furthest from the body)
-	if (closer_to_body && asset_id == wearable_vec.front()->getAssetID()) return false;
-	if (!closer_to_body && asset_id == wearable_vec.back()->getAssetID()) return false;
+	if (closer_to_body)
+	{
+		LLViewerWearable* bottom_wearable = dynamic_cast<LLViewerWearable*>( getBottomWearable(type) );
+		if (bottom_wearable->getAssetID() == asset_id)
+		{
+			return false;
+		}
+	}
+	else // !closer_to_body
+	{
+		LLViewerWearable* top_wearable = dynamic_cast<LLViewerWearable*>( getTopWearable(type) );
+		if (top_wearable->getAssetID() == asset_id)
+		{
+			return false;
+		}
+	}
 
-	for (U32 i = 0; i < wearable_vec.size(); ++i)
+	for (U32 i = 0; i < wearable_count; ++i)
 	{
-		LLWearable* wearable = wearable_vec[i];
+		LLViewerWearable* wearable = getViewerWearable(type, i);
 		if (!wearable) continue;
 		if (wearable->getAssetID() != asset_id) continue;
 		
 		//swapping wearables
 		U32 swap_i = closer_to_body ? i-1 : i+1;
-		wearable_vec[i] = wearable_vec[swap_i];
-		wearable_vec[swap_i] = wearable;
+		swapWearables(type, i, swap_i);
 		return true;
 	}
 
@@ -1991,10 +1786,10 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
 {
 	if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return;
 
-	LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
+	LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
 	LLAssetType::EType asset_type = wearable->getAssetType();
 	LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
-	LLPointer<LLInventoryCallback> cb = wear ? new LLWearAndEditCallback : NULL;
+	LLPointer<LLInventoryCallback> cb = wear ? new LLBoostFuncInventoryCallback(wear_and_edit_cb) : NULL;
 	LLUUID folder_id;
 
 	if (parent_id.notNull())
@@ -2024,7 +1819,7 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)
 		return;
 	}
 
-	LLWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
+	LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
 	if (!wearable)
 	{
 		llwarns << "Cannot get wearable" << llendl;
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 5932be21c639be6626ed70fdf3fcac6d55ef6888..5be4648636792a5c883750c57b635b1ea5abb46a 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -36,16 +36,16 @@
 // newview
 #include "llinventorymodel.h"
 #include "llviewerinventory.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
+#include "llwearabledata.h"
 
 class LLInventoryItem;
 class LLVOAvatarSelf;
-class LLWearable;
+class LLViewerWearable;
 class LLInitialWearablesFetch;
 class LLViewerObject;
-class LLTexLayerTemplate;
 
-class LLAgentWearables : public LLInitClass<LLAgentWearables>
+class LLAgentWearables : public LLInitClass<LLAgentWearables>, public LLWearableData
 {
 	//--------------------------------------------------------------------
 	// Constructors / destructors / Initializers
@@ -79,10 +79,10 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 	bool			isCOFChangeInProgress() const { return mCOFChangeInProgress; }
 	void			updateWearablesLoaded();
 	void			checkWearablesLoaded() const;
-	bool			canMoveWearable(const LLUUID& item_id, bool closer_to_body);
+	bool			canMoveWearable(const LLUUID& item_id, bool closer_to_body) const;
 	
 	// Note: False for shape, skin, eyes, and hair, unless you have MORE than 1.
-	bool			canWearableBeRemoved(const LLWearable* wearable) const;
+	bool			canWearableBeRemoved(const LLViewerWearable* wearable) const;
 
 	void			animateAllWearableParams(F32 delta, BOOL upload_bake);
 
@@ -92,52 +92,38 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 public:
 	const LLUUID		getWearableItemID(LLWearableType::EType type, U32 index /*= 0*/) const;
 	const LLUUID		getWearableAssetID(LLWearableType::EType type, U32 index /*= 0*/) const;
-	const LLWearable*	getWearableFromItemID(const LLUUID& item_id) const;
-	LLWearable*	getWearableFromItemID(const LLUUID& item_id);
-	LLWearable*	getWearableFromAssetID(const LLUUID& asset_id);
+	const LLViewerWearable*	getWearableFromItemID(const LLUUID& item_id) const;
+	LLViewerWearable*	getWearableFromItemID(const LLUUID& item_id);
+	LLViewerWearable*	getWearableFromAssetID(const LLUUID& asset_id);
+	LLViewerWearable*		getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/); 
+	const LLViewerWearable*	getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
 	LLInventoryItem*	getWearableInventoryItem(LLWearableType::EType type, U32 index /*= 0*/);
 	static BOOL			selfHasWearable(LLWearableType::EType type);
-	LLWearable*			getWearable(const LLWearableType::EType type, U32 index /*= 0*/); 
-	const LLWearable* 	getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
-	LLWearable*		getTopWearable(const LLWearableType::EType type);
-	LLWearable*		getBottomWearable(const LLWearableType::EType type);
-	U32				getWearableCount(const LLWearableType::EType type) const;
-	U32				getWearableCount(const U32 tex_index) const;
-
-	static const U32 MAX_CLOTHING_PER_TYPE = 5; 
-
 
 	//--------------------------------------------------------------------
 	// Setters
 	//--------------------------------------------------------------------
-
 private:
-	// Low-level data structure setter - public access is via setWearableItem, etc.
-	void 			setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable);
-	U32 			pushWearable(const LLWearableType::EType type, LLWearable *wearable);
-	void			wearableUpdated(LLWearable *wearable);
-	void 			popWearable(LLWearable *wearable);
-	void			popWearable(const LLWearableType::EType type, U32 index);
-	
+	/*virtual*/void	wearableUpdated(LLWearable *wearable, BOOL removed);
 public:
-	void			setWearableItem(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false);
-	void			setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove);
+	void			setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false);
+	void			setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLViewerWearable* >& wearables, BOOL remove);
 	void			setWearableName(const LLUUID& item_id, const std::string& new_name);
-	void			addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index);
-	U32				getWearableIndex(const LLWearable *wearable) const;
+	// *TODO: Move this into llappearance/LLWearableData ?
+	void			addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index);
 
 protected:
-	void			setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false);
-	static bool		onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable);
+	void			setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append = false);
+	static bool		onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable);
 
 	void			addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
-												LLWearable* wearable, 
+												LLViewerWearable* wearable, 
 												const LLUUID& category_id = LLUUID::null,
 												BOOL notify = TRUE);
 	void 			addWearabletoAgentInventoryDone(const LLWearableType::EType type,
 													const U32 index,
 													const LLUUID& item_id,
-													LLWearable* wearable);
+													LLViewerWearable* wearable);
 	void			recoverMissingWearable(const LLWearableType::EType type, U32 index /*= 0*/);
 	void			recoverMissingWearableDone();
 
@@ -172,15 +158,14 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 public:
 	// Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)
 	static void		processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
-	LLUUID			computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
-											BOOL generate_valid_hash = TRUE);
 
 protected:
+	/*virtual*/ void	invalidateBakedTextureHash(LLMD5& hash) const;
 	void			sendAgentWearablesUpdate();
 	void			sendAgentWearablesRequest();
 	void			queryWearableCache();
 	void 			updateServer();
-	static void		onInitialWearableAssetArrived(LLWearable* wearable, void* userdata);
+	static void		onInitialWearableAssetArrived(LLViewerWearable* wearable, void* userdata);
 
 	//--------------------------------------------------------------------
 	// Outfits
@@ -198,7 +183,7 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 	// Save Wearables
 	//--------------------------------------------------------------------
 public:	
-	void			saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found);
+	void			saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, const std::string& description, BOOL save_in_lost_and_found);
 	void			saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE,
 								 const std::string new_name = "");
 	void			saveAllWearables();
@@ -215,7 +200,6 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 
 	static void 	userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
 	static void		userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
-	static void		userRemoveAllAttachments();
 	static void		userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
 
 	BOOL			itemUpdatePending(const LLUUID& item_id) const;
@@ -245,10 +229,6 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 	// Member variables
 	//--------------------------------------------------------------------
 private:
-	typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
-	typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t;	// wearable "categories" arranged by wearable type
-	wearableentry_map_t mWearableDatas;
-
 	static BOOL		mInitialWearablesUpdateReceived;
 	BOOL			mWearablesLoaded;
 	std::set<LLUUID>	mItemsAwaitingWearableUpdate;
@@ -289,15 +269,17 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 		addWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb,
 											LLWearableType::EType type,
 											U32 index,
-											LLWearable* wearable,
-											U32 todo = CALL_NONE);
+											LLViewerWearable* wearable,
+											U32 todo = CALL_NONE,
+											const std::string description = "");
 		virtual void fire(const LLUUID& inv_item);
 	private:
 		LLWearableType::EType mType;
 		U32 mIndex;
-		LLWearable* mWearable;
+		LLViewerWearable* mWearable;
 		U32 mTodo;
 		LLPointer<LLRefCount> mCB;
+		std::string mDescription;
 	};
 
 }; // LLAgentWearables
diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index e31e39dca2ed8c6d79cce5a425964fa505aafd28..2d2d730396bc9583311d0e162ef9eff44d251f2b 100644
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -35,61 +35,52 @@
 #include "llvoavatarself.h"
 
 
-class LLOrderMyOutfitsOnDestroy: public LLInventoryCallback
+void order_my_outfits_cb()
 {
-public:
-	LLOrderMyOutfitsOnDestroy() {};
-
-	virtual ~LLOrderMyOutfitsOnDestroy()
+	if (!LLApp::isRunning())
 	{
-		if (!LLApp::isRunning())
-		{
-			llwarns << "called during shutdown, skipping" << llendl;
-			return;
-		}
+		llwarns << "called during shutdown, skipping" << llendl;
+		return;
+	}
 		
-		const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
-		if (my_outfits_id.isNull()) return;
-
-		LLInventoryModel::cat_array_t* cats;
-		LLInventoryModel::item_array_t* items;
-		gInventory.getDirectDescendentsOf(my_outfits_id, cats, items);
-		if (!cats) return;
+	const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+	if (my_outfits_id.isNull()) return;
 
-		//My Outfits should at least contain saved initial outfit and one another outfit
-		if (cats->size() < 2)
-		{
-			llwarning("My Outfits category was not populated properly", 0);
-			return;
-		}
+	LLInventoryModel::cat_array_t* cats;
+	LLInventoryModel::item_array_t* items;
+	gInventory.getDirectDescendentsOf(my_outfits_id, cats, items);
+	if (!cats) return;
 
-		llinfos << "Starting updating My Outfits with wearables ordering information" << llendl;
+	//My Outfits should at least contain saved initial outfit and one another outfit
+	if (cats->size() < 2)
+	{
+		llwarning("My Outfits category was not populated properly", 0);
+		return;
+	}
 
-		for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin();
-			outfit_iter != cats->end(); ++outfit_iter)
-		{
-			const LLUUID& cat_id = (*outfit_iter)->getUUID();
-			if (cat_id.isNull()) continue;
+	llinfos << "Starting updating My Outfits with wearables ordering information" << llendl;
 
-			// saved initial outfit already contains wearables ordering information
-			if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue;
+	for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin();
+		 outfit_iter != cats->end(); ++outfit_iter)
+	{
+		const LLUUID& cat_id = (*outfit_iter)->getUUID();
+		if (cat_id.isNull()) continue;
 
-			LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id);
-		}
+		// saved initial outfit already contains wearables ordering information
+		if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue;
 
-		llinfos << "Finished updating My Outfits with wearables ordering information" << llendl;
+		LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id);
 	}
 
-	/* virtual */ void fire(const LLUUID& inv_item) {};
-};
-
+	llinfos << "Finished updating My Outfits with wearables ordering information" << llendl;
+}
 
 LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :
 	LLInventoryFetchDescendentsObserver(cof_id)
 {
 	if (isAgentAvatarValid())
 	{
-		gAgentAvatarp->getPhases().startPhase("initial_wearables_fetch");
+		gAgentAvatarp->startPhase("initial_wearables_fetch");
 		gAgentAvatarp->outputRezTiming("Initial wearables fetch started");
 	}
 }
@@ -108,7 +99,7 @@ void LLInitialWearablesFetch::done()
 	doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this));
 	if (isAgentAvatarValid())
 	{
-		gAgentAvatarp->getPhases().stopPhase("initial_wearables_fetch");
+		gAgentAvatarp->stopPhase("initial_wearables_fetch");
 		gAgentAvatarp->outputRezTiming("Initial wearables fetch done");
 	}
 }
@@ -563,7 +554,7 @@ void LLLibraryOutfitsFetch::contentsDone()
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t wearable_array;
 	
-	LLPointer<LLOrderMyOutfitsOnDestroy> order_myoutfits_on_destroy = new LLOrderMyOutfitsOnDestroy;
+	LLPointer<LLInventoryCallback> order_myoutfits_on_destroy = new LLBoostFuncInventoryCallback(no_op_inventory_func, order_my_outfits_cb);
 
 	for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin();
 		 folder_iter != mImportedClothingFolders.end();
diff --git a/indra/newview/llappearance.h b/indra/newview/llappearance.h
index a28b77b1fcc4965094e77ad3201cdc6a37461e6c..05dfac4e420550006c69714c31f836757648dc65 100644
--- a/indra/newview/llappearance.h
+++ b/indra/newview/llappearance.h
@@ -38,14 +38,14 @@ class LLAppearance
 	void	addParam( S32 id, F32 value )				{ mParamMap[id] = value; }
 	F32		getParam( S32 id, F32 defval )				{ return get_if_there(mParamMap, id, defval ); }
 
-	void	addTexture( S32 te, const LLUUID& uuid )	{ if( te < LLVOAvatarDefines::TEX_NUM_INDICES ) mTextures[te] = uuid; }
-	const LLUUID& getTexture( S32 te )					{ return ( te < LLVOAvatarDefines::TEX_NUM_INDICES ) ? mTextures[te] : LLUUID::null; }
+	void	addTexture( S32 te, const LLUUID& uuid )	{ if( te < LLAvatarAppearanceDefines::TEX_NUM_INDICES ) mTextures[te] = uuid; }
+	const LLUUID& getTexture( S32 te )					{ return ( te < LLAvatarAppearanceDefines::TEX_NUM_INDICES ) ? mTextures[te] : LLUUID::null; }
 	
-	void	clear()										{ mParamMap.clear(); for( S32 i=0; i<LLVOAvatarDefines::TEX_NUM_INDICES; i++ ) mTextures[i].setNull(); }
+	void	clear()										{ mParamMap.clear(); for( S32 i=0; i<LLAvatarAppearanceDefines::TEX_NUM_INDICES; i++ ) mTextures[i].setNull(); }
 
 	typedef std::map<S32, F32> param_map_t;
 	param_map_t mParamMap;
-	LLUUID	mTextures[LLVOAvatarDefines::TEX_NUM_INDICES];
+	LLUUID	mTextures[LLAvatarAppearanceDefines::TEX_NUM_INDICES];
 };
 
 #endif  // LL_LLAPPEARANCE_H
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
old mode 100644
new mode 100755
index 769b4eafe17eb48bc1a316f8af7f1a2f67f9260e..652f199e2835686dbe4426cd4a47ac41bbe782b4
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -26,6 +26,7 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include <boost/lexical_cast.hpp>
 #include "llaccordionctrltab.h"
 #include "llagent.h"
 #include "llagentcamera.h"
@@ -49,6 +50,13 @@
 #include "llvoavatarself.h"
 #include "llviewerregion.h"
 #include "llwearablelist.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
 
 std::string self_av_string()
 {
@@ -155,71 +163,342 @@ LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id, const std::string
 	}
 }
 
-class LLWearInventoryCategoryCallback : public LLInventoryCallback
+// We want this to be much lower (e.g. 15.0 is usually fine), bumping
+// up for now until we can diagnose some cases of very slow response
+// to requests.
+const F32 DEFAULT_RETRY_AFTER_INTERVAL = 300.0;
+
+// Given the current back-end problems, retrying is causing too many
+// duplicate items. Bump this back to 2 once they are resolved (or can
+// leave at 0 if the operations become actually reliable).
+const S32 DEFAULT_MAX_RETRIES = 0;
+
+class LLCallAfterInventoryBatchMgr: public LLEventTimer 
 {
 public:
-	LLWearInventoryCategoryCallback(const LLUUID& cat_id, bool append)
-	{
-		mCatID = cat_id;
-		mAppend = append;
+	LLCallAfterInventoryBatchMgr(const LLUUID& dst_cat_id,
+								 const std::string& phase_name,
+								 nullary_func_t on_completion_func,
+								 nullary_func_t on_failure_func = no_op,
+								 F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
+								 S32 max_retries = DEFAULT_MAX_RETRIES
+		):
+		mDstCatID(dst_cat_id),
+		mTrackingPhase(phase_name),
+		mOnCompletionFunc(on_completion_func),
+		mOnFailureFunc(on_failure_func),
+		mRetryAfter(retry_after),
+		mMaxRetries(max_retries),
+		mPendingRequests(0),
+		mFailCount(0),
+		mCompletionOrFailureCalled(false),
+		mRetryCount(0),
+		LLEventTimer(5.0)
+	{
+		if (!mTrackingPhase.empty())
+		{
+			selfStartPhase(mTrackingPhase);
+		}
+	}
+
+	void addItems(LLInventoryModel::item_array_t& src_items)
+	{
+		for (LLInventoryModel::item_array_t::const_iterator it = src_items.begin();
+			 it != src_items.end();
+			 ++it)
+		{
+			LLViewerInventoryItem* item = *it;
+			llassert(item);
+			addItem(item->getUUID());
+		}
+	}
 
-		LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
+	// Request or re-request operation for specified item.
+	void addItem(const LLUUID& item_id)
+	{
+		LL_DEBUGS("Avatar") << "item_id " << item_id << llendl;
 		
-		selfStartPhase("wear_inventory_category_callback");
+		if (!requestOperation(item_id))
+		{
+			LL_DEBUGS("Avatar") << "item_id " << item_id << " requestOperation false, skipping" << llendl;
+			return;
+		}
+
+		mPendingRequests++;
+		// On a re-request, this will reset the timer.
+		mWaitTimes[item_id] = LLTimer();
+		if (mRetryCounts.find(item_id) == mRetryCounts.end())
+		{
+			mRetryCounts[item_id] = 0;
+		}
+		else
+		{
+			mRetryCounts[item_id]++;
+		}
 	}
-	void fire(const LLUUID& item_id)
+
+	virtual bool requestOperation(const LLUUID& item_id) = 0;
+
+	void onOp(const LLUUID& src_id, const LLUUID& dst_id, LLTimer timestamp)
 	{
-		/*
-		 * Do nothing.  We only care about the destructor
-		 *
-		 * The reason for this is that this callback is used in a hack where the
-		 * same callback is given to dozens of items, and the destructor is called
-		 * after the last item has fired the event and dereferenced it -- if all
-		 * the events actually fire!
-		 */
-		LL_DEBUGS("Avatar") << self_av_string() << " fired on copied item, id " << item_id << LL_ENDL;
+		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateLateOpRate"))
+		{
+			llwarns << "Simulating late operation by punting handling to later" << llendl;
+			doAfterInterval(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,src_id,dst_id,timestamp),
+							mRetryAfter);
+			return;
+		}
+		mPendingRequests--;
+		F32 elapsed = timestamp.getElapsedTimeF32();
+		LL_DEBUGS("Avatar") << "op done, src_id " << src_id << " dst_id " << dst_id << " after " << elapsed << " seconds" << llendl;
+		if (mWaitTimes.find(src_id) == mWaitTimes.end())
+		{
+			// No longer waiting for this item - either serviced
+			// already or gave up after too many retries.
+			llwarns << "duplicate or late operation, src_id " << src_id << "dst_id " << dst_id
+					<< " elapsed " << elapsed << " after end " << (S32) mCompletionOrFailureCalled << llendl;
+		}
+		mTimeStats.push(elapsed);
+		mWaitTimes.erase(src_id);
+		if (mWaitTimes.empty() && !mCompletionOrFailureCalled)
+		{
+			onCompletionOrFailure();
+		}
 	}
 
-protected:
-	~LLWearInventoryCategoryCallback()
+	void onCompletionOrFailure()
 	{
-		LL_INFOS("Avatar") << self_av_string() << "done all inventory callbacks" << LL_ENDL;
+		assert (!mCompletionOrFailureCalled);
+		mCompletionOrFailureCalled = true;
 		
-		selfStopPhase("wear_inventory_category_callback");
-
-		// Is the destructor called by ordinary dereference, or because the app's shutting down?
-		// If the inventory callback manager goes away, we're shutting down, no longer want the callback.
-		if( LLInventoryCallbackManager::is_instantiated() )
+		// Will never call onCompletion() if any item has been flagged as
+		// a failure - otherwise could wind up with corrupted
+		// outfit, involuntary nudity, etc.
+		reportStats();
+		if (!mTrackingPhase.empty())
 		{
-			LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend);
+			selfStopPhase(mTrackingPhase);
+		}
+		if (!mFailCount)
+		{
+			onCompletion();
 		}
 		else
 		{
-			llwarns << self_av_string() << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl;
+			onFailure();
 		}
 	}
 
-private:
-	LLUUID mCatID;
-	bool mAppend;
-};
+	void onFailure()
+	{
+		llinfos << "failed" << llendl;
+		mOnFailureFunc();
+	}
 
+	void onCompletion()
+	{
+		llinfos << "done" << llendl;
+		mOnCompletionFunc();
+	}
+	
+	// virtual
+	// Will be deleted after returning true - only safe to do this if all callbacks have fired.
+	BOOL tick()
+	{
+		// mPendingRequests will be zero if all requests have been
+		// responded to.  mWaitTimes.empty() will be true if we have
+		// received at least one reply for each UUID.  If requests
+		// have been dropped and retried, these will not necessarily
+		// be the same.  Only safe to return true if all requests have
+		// been serviced, since it will result in this object being
+		// deleted.
+		bool all_done = (mPendingRequests==0);
 
-//Inventory callback updating "dirty" state when destroyed
-class LLUpdateDirtyState: public LLInventoryCallback
+		if (!mWaitTimes.empty())
+		{
+			llwarns << "still waiting on " << mWaitTimes.size() << " items" << llendl;
+			for (std::map<LLUUID,LLTimer>::iterator it = mWaitTimes.begin();
+				 it != mWaitTimes.end();)
+			{
+				// Use a copy of iterator because it may be erased/invalidated.
+				std::map<LLUUID,LLTimer>::iterator curr_it = it;
+				++it;
+				
+				F32 time_waited = curr_it->second.getElapsedTimeF32();
+				S32 retries = mRetryCounts[curr_it->first];
+				if (time_waited > mRetryAfter)
+				{
+					if (retries < mMaxRetries)
+					{
+						LL_DEBUGS("Avatar") << "Waited " << time_waited <<
+							" for " << curr_it->first << ", retrying" << llendl;
+						mRetryCount++;
+						addItem(curr_it->first);
+					}
+					else
+					{
+						llwarns << "Giving up on " << curr_it->first << " after too many retries" << llendl;
+						mWaitTimes.erase(curr_it);
+						mFailCount++;
+					}
+				}
+				if (mWaitTimes.empty())
+				{
+					onCompletionOrFailure();
+				}
+
+			}
+		}
+		return all_done;
+	}
+
+	void reportStats()
+	{
+		LL_DEBUGS("Avatar") << "Phase: " << mTrackingPhase << llendl;
+		LL_DEBUGS("Avatar") << "mFailCount: " << mFailCount << llendl;
+		LL_DEBUGS("Avatar") << "mRetryCount: " << mRetryCount << llendl;
+		LL_DEBUGS("Avatar") << "Times: n " << mTimeStats.getCount() << " min " << mTimeStats.getMinValue() << " max " << mTimeStats.getMaxValue() << llendl;
+		LL_DEBUGS("Avatar") << "Mean " << mTimeStats.getMean() << " stddev " << mTimeStats.getStdDev() << llendl;
+	}
+	
+	virtual ~LLCallAfterInventoryBatchMgr()
+	{
+		LL_DEBUGS("Avatar") << "deleting" << llendl;
+	}
+
+protected:
+	std::string mTrackingPhase;
+	std::map<LLUUID,LLTimer> mWaitTimes;
+	std::map<LLUUID,S32> mRetryCounts;
+	LLUUID mDstCatID;
+	nullary_func_t mOnCompletionFunc;
+	nullary_func_t mOnFailureFunc;
+	F32 mRetryAfter;
+	S32 mMaxRetries;
+	S32 mPendingRequests;
+	S32 mFailCount;
+	S32 mRetryCount;
+	bool mCompletionOrFailureCalled;
+	LLViewerStats::StatsAccumulator mTimeStats;
+};
+
+class LLCallAfterInventoryCopyMgr: public LLCallAfterInventoryBatchMgr
 {
 public:
-	LLUpdateDirtyState() {}
-	virtual ~LLUpdateDirtyState()
+	LLCallAfterInventoryCopyMgr(LLInventoryModel::item_array_t& src_items,
+								const LLUUID& dst_cat_id,
+								const std::string& phase_name,
+								nullary_func_t on_completion_func,
+								nullary_func_t on_failure_func = no_op,
+								 F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
+								 S32 max_retries = DEFAULT_MAX_RETRIES
+		):
+		LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries)
+	{
+		addItems(src_items);
+	}
+	
+	virtual bool requestOperation(const LLUUID& item_id)
 	{
-		if (LLAppearanceMgr::instanceExists())
+		LLViewerInventoryItem *item = gInventory.getItem(item_id);
+		llassert(item);
+		LL_DEBUGS("Avatar") << "copying item " << item_id << llendl;
+		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
 		{
-			LLAppearanceMgr::getInstance()->updateIsDirty();
+			LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+			return true;
 		}
+		copy_inventory_item(
+			gAgent.getID(),
+			item->getPermissions().getOwner(),
+			item->getUUID(),
+			mDstCatID,
+			std::string(),
+			new LLBoostFuncInventoryCallback(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer()))
+			);
+		return true;
 	}
-	virtual void fire(const LLUUID&) {}
 };
 
+class LLCallAfterInventoryLinkMgr: public LLCallAfterInventoryBatchMgr
+{
+public:
+	LLCallAfterInventoryLinkMgr(LLInventoryModel::item_array_t& src_items,
+								const LLUUID& dst_cat_id,
+								const std::string& phase_name,
+								nullary_func_t on_completion_func,
+								nullary_func_t on_failure_func = no_op,
+								 F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
+								 S32 max_retries = DEFAULT_MAX_RETRIES
+		):
+		LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries)
+	{
+		addItems(src_items);
+	}
+	
+	virtual bool requestOperation(const LLUUID& item_id)
+	{
+		bool request_sent = false;
+		LLViewerInventoryItem *item = gInventory.getItem(item_id);
+		if (item)
+		{
+			if (item->getParentUUID() == mDstCatID)
+			{
+				LL_DEBUGS("Avatar") << "item " << item_id << " name " << item->getName() << " is already a child of " << mDstCatID << llendl;
+				return false;
+			}
+			LL_DEBUGS("Avatar") << "linking item " << item_id << " name " << item->getName() << " to " << mDstCatID << llendl;
+			// create an inventory item link.
+			if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
+			{
+				LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+				return true;
+			}
+			link_inventory_item(gAgent.getID(),
+								item->getLinkedUUID(),
+								mDstCatID,
+								item->getName(),
+								item->getActualDescription(),
+								LLAssetType::AT_LINK,
+								new LLBoostFuncInventoryCallback(
+									boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer())));
+			return true;
+		}
+		else
+		{
+			// create a base outfit link if appropriate.
+			LLViewerInventoryCategory *catp = gInventory.getCategory(item_id);
+			if (!catp)
+			{
+				llwarns << "link request failed, id not found as inventory item or category " << item_id << llendl;
+				return false;
+			}
+			const LLUUID cof = LLAppearanceMgr::instance().getCOF();
+			std::string new_outfit_name = "";
+
+			LLAppearanceMgr::instance().purgeBaseOutfitLink(cof);
+
+			if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
+			{
+				if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
+				{
+					LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+					return true;
+				}
+				LL_DEBUGS("Avatar") << "linking folder " << item_id << " name " << catp->getName() << " to cof " << cof << llendl;
+				link_inventory_item(gAgent.getID(), item_id, cof, catp->getName(), "",
+									LLAssetType::AT_LINK_FOLDER, 
+									new LLBoostFuncInventoryCallback(
+										boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer())));
+				new_outfit_name = catp->getName();
+				request_sent = true;
+			}
+	
+			LLAppearanceMgr::instance().updatePanelOutfitName(new_outfit_name);
+		}
+		return request_sent;
+	}
+};
 
 LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool update_base_outfit_ordering):
 	mFireCount(0),
@@ -278,7 +557,7 @@ struct LLFoundData
 	std::string mName;
 	LLAssetType::EType mAssetType;
 	LLWearableType::EType mWearableType;
-	LLWearable* mWearable;
+	LLViewerWearable* mWearable;
 	bool mIsReplacement;
 };
 
@@ -302,7 +581,7 @@ class LLWearableHoldingPattern
 	void recoverMissingWearable(LLWearableType::EType type);
 	void clearCOFLinksForMissingWearables();
 	
-	void onWearableAssetFetch(LLWearable *wearable);
+	void onWearableAssetFetch(LLViewerWearable *wearable);
 	void onAllComplete();
 
 	typedef std::list<LLFoundData> found_list_t;
@@ -328,7 +607,7 @@ class LLWearableHoldingPattern
 	typedef std::set<LLWearableHoldingPattern*> type_set_hp;
 	static type_set_hp sActiveHoldingPatterns;
 	bool mIsMostRecent;
-	std::set<LLWearable*> mLateArrivals;
+	std::set<LLViewerWearable*> mLateArrivals;
 	bool mIsAllComplete;
 };
 
@@ -559,100 +838,72 @@ bool LLWearableHoldingPattern::pollFetchCompletion()
 	return done;
 }
 
-class RecoveredItemLinkCB: public LLInventoryCallback
+void recovered_item_link_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
 {
-public:
-	RecoveredItemLinkCB(LLWearableType::EType type, LLWearable *wearable, LLWearableHoldingPattern* holder):
-		mHolder(holder),
-		mWearable(wearable),
-		mType(type)
+	if (!holder->isMostRecent())
 	{
+		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+		// runway skip here?
 	}
-	void fire(const LLUUID& item_id)
-	{
-		if (!mHolder->isMostRecent())
-		{
-			llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
-			// runway skip here?
-		}
 
-		llinfos << "Recovered item link for type " << mType << llendl;
-		mHolder->eraseTypeToLink(mType);
-		// Add wearable to FoundData for actual wearing
-		LLViewerInventoryItem *item = gInventory.getItem(item_id);
-		LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
+	llinfos << "Recovered item link for type " << type << llendl;
+	holder->eraseTypeToLink(type);
+	// Add wearable to FoundData for actual wearing
+	LLViewerInventoryItem *item = gInventory.getItem(item_id);
+	LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
 
-		if (linked_item)
-		{
-			gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
+	if (linked_item)
+	{
+		gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
 			
-			if (item)
-			{
-				LLFoundData found(linked_item->getUUID(),
-								  linked_item->getAssetUUID(),
-								  linked_item->getName(),
-								  linked_item->getType(),
-								  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID,
-								  true // is replacement
-					);
-				found.mWearable = mWearable;
-				mHolder->getFoundList().push_front(found);
-			}
-			else
-			{
-				llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl;
-			}
+		if (item)
+		{
+			LLFoundData found(linked_item->getUUID(),
+							  linked_item->getAssetUUID(),
+							  linked_item->getName(),
+							  linked_item->getType(),
+							  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID,
+							  true // is replacement
+				);
+			found.mWearable = wearable;
+			holder->getFoundList().push_front(found);
 		}
 		else
 		{
-			llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl;
+			llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl;
 		}
 	}
-private:
-	LLWearableHoldingPattern* mHolder;
-	LLWearable *mWearable;
-	LLWearableType::EType mType;
-};
+	else
+	{
+		llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl;
+	}
+}
 
-class RecoveredItemCB: public LLInventoryCallback
+void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
 {
-public:
-	RecoveredItemCB(LLWearableType::EType type, LLWearable *wearable, LLWearableHoldingPattern* holder):
-		mHolder(holder),
-		mWearable(wearable),
-		mType(type)
+	if (!holder->isMostRecent())
 	{
+		// runway skip here?
+		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
 	}
-	void fire(const LLUUID& item_id)
-	{
-		if (!mHolder->isMostRecent())
-		{
-			// runway skip here?
-			llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
-		}
 
-		LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << mType << LL_ENDL;
-		LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
-		mWearable->setItemID(item_id);
-		LLPointer<LLInventoryCallback> cb = new RecoveredItemLinkCB(mType,mWearable,mHolder);
-		mHolder->eraseTypeToRecover(mType);
-		llassert(itemp);
-		if (itemp)
-		{
-			link_inventory_item( gAgent.getID(),
-					     item_id,
-					     LLAppearanceMgr::instance().getCOF(),
-					     itemp->getName(),
-						 itemp->getDescription(),
-					     LLAssetType::AT_LINK,
-					     cb);
-		}
+	LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL;
+	LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
+	wearable->setItemID(item_id);
+	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder));
+	holder->eraseTypeToRecover(type);
+	llassert(itemp);
+	if (itemp)
+	{
+		link_inventory_item( gAgent.getID(),
+							 item_id,
+							 LLAppearanceMgr::instance().getCOF(),
+							 itemp->getName(),
+							 itemp->getDescription(),
+							 LLAssetType::AT_LINK,
+							 cb);
 	}
-private:
-	LLWearableHoldingPattern* mHolder;
-	LLWearable *mWearable;
-	LLWearableType::EType mType;
-};
+}
 
 void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type)
 {
@@ -666,11 +917,11 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type
 	LLNotificationsUtil::add("ReplacedMissingWearable");
 	lldebugs << "Wearable " << LLWearableType::getTypeLabel(type)
 			 << " could not be downloaded.  Replaced inventory item with default wearable." << llendl;
-	LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
+	LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
 
 	// Add a new one in the lost and found folder.
 	const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
-	LLPointer<LLInventoryCallback> cb = new RecoveredItemCB(type,wearable,this);
+	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_cb,_1,type,wearable,this));
 
 	create_inventory_item(gAgent.getID(),
 						  gAgent.getSessionID(),
@@ -699,7 +950,7 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
 		{
 			// Wearable link that was never resolved; remove links to it from COF
 			LL_INFOS("Avatar") << self_av_string() << "removing link for unresolved item " << data.mItemID.asString() << LL_ENDL;
-			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false);
+			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
 		}
 	}
 }
@@ -773,11 +1024,11 @@ void LLWearableHoldingPattern::handleLateArrivals()
 		 iter != getFoundList().end(); ++iter)
 	{
 		LLFoundData& data = *iter;
-		for (std::set<LLWearable*>::iterator wear_it = mLateArrivals.begin();
+		for (std::set<LLViewerWearable*>::iterator wear_it = mLateArrivals.begin();
 			 wear_it != mLateArrivals.end();
 			 ++wear_it)
 		{
-			LLWearable *wearable = *wear_it;
+			LLViewerWearable *wearable = *wear_it;
 
 			if(wearable->getAssetID() == data.mAssetID)
 			{
@@ -813,7 +1064,7 @@ void LLWearableHoldingPattern::handleLateArrivals()
 		if (data.mWearable && data.mIsReplacement &&
 			replaced_types.find(data.mWearableType) != replaced_types.end())
 		{
-			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false);
+			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
 			std::list<LLFoundData>::iterator clobber_ator = iter;
 			++iter;
 			getFoundList().erase(clobber_ator);
@@ -837,7 +1088,7 @@ void LLWearableHoldingPattern::resetTime(F32 timeout)
 	mWaitTime.setTimerExpirySec(timeout);
 }
 
-void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
+void LLWearableHoldingPattern::onWearableAssetFetch(LLViewerWearable *wearable)
 {
 	if (!isMostRecent())
 	{
@@ -888,7 +1139,7 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
 	}
 }
 
-static void onWearableAssetFetch(LLWearable* wearable, void* data)
+static void onWearableAssetFetch(LLViewerWearable* wearable, void* data)
 {
 	LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
 	holder->onWearableAssetFetch(wearable);
@@ -927,6 +1178,18 @@ const LLUUID LLAppearanceMgr::getCOF() const
 	return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
 }
 
+S32 LLAppearanceMgr::getCOFVersion() const
+{
+	LLViewerInventoryCategory *cof = gInventory.getCategory(getCOF());
+	if (cof)
+	{
+		return cof->getVersion();
+	}
+	else
+	{
+		return LLViewerInventoryCategory::VERSION_UNKNOWN;
+	}
+}
 
 const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink()
 {
@@ -995,6 +1258,18 @@ const LLUUID LLAppearanceMgr::getBaseOutfitUUID()
 	return outfit_cat->getUUID();
 }
 
+void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace = false)
+{
+	if (inv_item.isNull())
+		return;
+	
+	LLViewerInventoryItem *item = gInventory.getItem(inv_item);
+	if (item)
+	{
+		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, do_replace);
+	}
+}
+
 bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_update, bool replace, LLPointer<LLInventoryCallback> cb)
 {
 	if (item_id_to_wear.isNull()) return false;
@@ -1014,8 +1289,8 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
 
 	if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID()))
 	{
-		LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(replace);
-		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb);
+		LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb,_1,replace));
+		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(), cb);
 		return false;
 	} 
 	else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID()))
@@ -1041,7 +1316,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
 			if ((replace && wearable_count != 0) ||
 				(wearable_count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) )
 			{
-				removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false);
+				removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1));
 			}
 			addCOFItemLink(item_to_wear, do_update, cb);
 		} 
@@ -1051,7 +1326,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
 		
 		// Remove the existing wearables of the same type.
 		// Remove existing body parts anyway because we must not be able to wear e.g. two skins.
-		removeCOFLinksOfType(item_to_wear->getWearableType(), false);
+		removeCOFLinksOfType(item_to_wear->getWearableType());
 
 		addCOFItemLink(item_to_wear, do_update, cb);
 		break;
@@ -1149,11 +1424,13 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id)
 
 	LLInventoryModel::item_array_t::const_iterator it = items.begin();
 	const LLInventoryModel::item_array_t::const_iterator it_end = items.end();
+	uuid_vec_t uuids_to_remove;
 	for( ; it_end != it; ++it)
 	{
 		LLViewerInventoryItem* item = *it;
-		removeItemFromAvatar(item->getUUID());
+		uuids_to_remove.push_back(item->getUUID());
 	}
+	removeItemsFromAvatar(uuids_to_remove);
 }
 
 // Create a copy of src_id + contents as a subfolder of dst_id.
@@ -1197,13 +1474,13 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
 		{
 			case LLAssetType::AT_LINK:
 			{
-				//LLInventoryItem::getDescription() is used for a new description 
+				//getActualDescription() is used for a new description 
 				//to propagate ordering information saved in descriptions of links
 				link_inventory_item(gAgent.getID(),
 									item->getLinkedUUID(),
 									dst_id,
 									item->getName(),
-									item->LLInventoryItem::getDescription(),
+									item->getActualDescription(),
 									LLAssetType::AT_LINK, cb);
 				break;
 			}
@@ -1383,7 +1660,7 @@ void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)
 	}
 }
 
-void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_links)
+void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_links, LLInventoryModel::item_array_t* keep_items)
 {
 	LLInventoryModel::cat_array_t cats;
 	LLInventoryModel::item_array_t items;
@@ -1396,8 +1673,19 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin
 			continue;
 		if (item->getIsLinkType())
 		{
+#if 0
+			if (keep_items && keep_items->find(item) != LLInventoryModel::item_array_t::FAIL)
+			{
+				llinfos << "preserved item" << llendl;
+			}
+			else
+			{
+				gInventory.purgeObject(item->getUUID());
+			}
+#else
 			gInventory.purgeObject(item->getUUID());
 		}
+#endif
 	}
 }
 
@@ -1437,7 +1725,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,
 							item->getLinkedUUID(),
 							cat_uuid,
 							item->getName(),
-							item->LLInventoryItem::getDescription(),
+							item->getActualDescription(),
 							LLAssetType::AT_LINK,
 							cb);
 
@@ -1508,40 +1796,31 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
 	getDescendentsOfAssetType(category, gest_items, LLAssetType::AT_GESTURE, false);
 	removeDuplicateItems(gest_items);
 	
-	// Remove current COF contents.
-	bool keep_outfit_links = append;
-	purgeCategory(cof, keep_outfit_links);
-	gInventory.notifyObservers();
-
 	// Create links to new COF contents.
-	LL_DEBUGS("Avatar") << self_av_string() << "creating LLUpdateAppearanceOnDestroy" << LL_ENDL;
-	LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy(!append);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL;
-#endif
-	linkAll(cof, body_items, link_waiter);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking wear items" << LL_ENDL;
-#endif
-	linkAll(cof, wear_items, link_waiter);
+	LLInventoryModel::item_array_t all_items;
+	all_items += body_items;
+	all_items += wear_items;
+	all_items += obj_items;
+	all_items += gest_items;
 
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking obj items" << LL_ENDL;
-#endif
-	linkAll(cof, obj_items, link_waiter);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking gesture items" << LL_ENDL;
-#endif
-	linkAll(cof, gest_items, link_waiter);
+	// Will link all the above items.
+	LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
+	linkAll(cof,all_items,link_waiter);
 
 	// Add link to outfit if category is an outfit. 
 	if (!append)
 	{
 		createBaseOutfitLink(category, link_waiter);
 	}
+
+	// Remove current COF contents.  Have to do this after creating
+	// the link_waiter so links can be followed for any items that get
+	// carried over (e.g. keeping old shape if the new outfit does not
+	// contain one)
+	bool keep_outfit_links = append;
+	purgeCategory(cof, keep_outfit_links, &all_items);
+	gInventory.notifyObservers();
+
 	LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;
 }
 
@@ -1577,7 +1856,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
 {
 	lldebugs << "updateAgentWearables()" << llendl;
 	LLInventoryItem::item_array_t items;
-	LLDynamicArray< LLWearable* > wearables;
+	LLDynamicArray< LLViewerWearable* > wearables;
 
 	// For each wearable type, find the wearables of that type.
 	for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ )
@@ -1586,7 +1865,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
 			 iter != holder->getFoundList().end(); ++iter)
 		{
 			LLFoundData& data = *iter;
-			LLWearable* wearable = data.mWearable;
+			LLViewerWearable* wearable = data.mWearable;
 			if( wearable && ((S32)wearable->getType() == i) )
 			{
 				LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID);
@@ -1622,7 +1901,7 @@ static void remove_non_link_items(LLInventoryModel::item_array_t &items)
 }
 
 //a predicate for sorting inventory items by actual descriptions
-bool sort_by_description(const LLInventoryItem* item1, const LLInventoryItem* item2)
+bool sort_by_actual_description(const LLInventoryItem* item1, const LLInventoryItem* item2)
 {
 	if (!item1 || !item2) 
 	{
@@ -1630,7 +1909,7 @@ bool sort_by_description(const LLInventoryItem* item1, const LLInventoryItem* it
 		return true;
 	}
 
-	return item1->LLInventoryItem::getDescription() < item2->LLInventoryItem::getDescription();
+	return item1->getActualDescription() < item2->getActualDescription();
 }
 
 void item_array_diff(LLInventoryModel::item_array_t& full_list,
@@ -1712,11 +1991,10 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
 		return;
 	}
 
-	LLVOAvatar::ScopedPhaseSetter(gAgentAvatarp,"update_appearance_from_cof");
-	
 	BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF);
+	selfStartPhase("update_appearance_from_cof");
 
-	LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
+	LL_DEBUGS("Avatar") << self_av_string() << "starting" << LL_ENDL;
 
 	//checking integrity of the COF in terms of ordering of wearables, 
 	//checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state)
@@ -1730,9 +2008,18 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
 	// the saved outfit stored as a folder link
 	updateIsDirty();
 
+	// Send server request for appearance update
+	if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
+	{
+		requestServerAppearanceUpdate();
+	}
+	// DRANO really should wait for the appearance message to set this.
+	// verify that deleting this line doesn't break anything.
+	//gAgentAvatarp->setIsUsingServerBakes(gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion());
+	
 	//dumpCat(getCOF(),"COF, start");
 
-	bool follow_folder_links = true;
+	bool follow_folder_links = false;
 	LLUUID current_outfit_id = getCOF();
 
 	// Find all the wearables that are in the COF's subtree.
@@ -1820,6 +2107,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
 		// Fetch the wearables about to be worn.
 		LLWearableList::instance().getAsset(found.mAssetID,
 											found.mName,
+											gAgentAvatarp,
 											found.mAssetType,
 											onWearableAssetFetch,
 											(void*)holder);
@@ -1954,22 +2242,15 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap
 			pid,
 			LLFolderType::FT_NONE,
 			name);
-		LLPointer<LLInventoryCallback> cb = new LLWearInventoryCategoryCallback(new_cat_id, append);
-		it = items->begin();
-		for(; it < end; ++it)
-		{
-			item = *it;
-			if(item)
-			{
-				copy_inventory_item(
-					gAgent.getID(),
-					item->getPermissions().getOwner(),
-					item->getUUID(),
-					new_cat_id,
-					std::string(),
-					cb);
-			}
-		}
+
+		// Create a CopyMgr that will copy items, manage its own destruction
+		new LLCallAfterInventoryCopyMgr(
+			*items, new_cat_id, std::string("wear_inventory_category_callback"),
+			boost::bind(&LLAppearanceMgr::wearInventoryCategoryOnAvatar,
+						LLAppearanceMgr::getInstance(),
+						gInventory.getCategory(new_cat_id),
+						append));
+
 		// BAP fixes a lag in display of created dir.
 		gInventory.notifyObservers();
 	}
@@ -1986,7 +2267,13 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
 	// Avoid unintentionally overwriting old wearables.  We have to do
 	// this up front to avoid having to deal with the case of multiple
 	// wearables being dirty.
-	if(!category) return;
+	if (!category) return;
+
+	if ( !LLInventoryCallbackManager::is_instantiated() )
+	{
+		// shutting down, ignore.
+		return;
+	}
 
 	LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName()
 			 << "'" << LL_ENDL;
@@ -2053,10 +2340,11 @@ bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventor
 class LLDeferredCOFLinkObserver: public LLInventoryObserver
 {
 public:
-	LLDeferredCOFLinkObserver(const LLUUID& item_id, bool do_update, LLPointer<LLInventoryCallback> cb = NULL):
+	LLDeferredCOFLinkObserver(const LLUUID& item_id, bool do_update, LLPointer<LLInventoryCallback> cb = NULL, std::string description = ""):
 		mItemID(item_id),
 		mDoUpdate(do_update),
-		mCallback(cb)
+		mCallback(cb),
+		mDescription(description)
 	{
 	}
 
@@ -2078,28 +2366,49 @@ class LLDeferredCOFLinkObserver: public LLInventoryObserver
 private:
 	const LLUUID mItemID;
 	bool mDoUpdate;
+	std::string mDescription;
 	LLPointer<LLInventoryCallback> mCallback;
 };
 
 
 // BAP - note that this runs asynchronously if the item is not already loaded from inventory.
 // Dangerous if caller assumes link will exist after calling the function.
-void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPointer<LLInventoryCallback> cb)
+void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPointer<LLInventoryCallback> cb, const std::string description)
 {
 	const LLInventoryItem *item = gInventory.getItem(item_id);
 	if (!item)
 	{
-		LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, do_update, cb);
+		LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, do_update, cb, description);
 		gInventory.addObserver(observer);
 	}
 	else
 	{
-		addCOFItemLink(item, do_update, cb);
+		addCOFItemLink(item, do_update, cb, description);
+	}
+}
+
+void modified_cof_cb(const LLUUID& inv_item)
+{
+	LLAppearanceMgr::instance().updateAppearanceFromCOF();
+
+	// Start editing the item if previously requested.
+	gAgentWearables.editWearableIfRequested(inv_item);
+
+	// TODO: camera mode may not be changed if a debug setting is tweaked
+	if( gAgentCamera.cameraCustomizeAvatar() )
+	{
+		// If we're in appearance editing mode, the current tab may need to be refreshed
+		LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+		if (panel)
+		{
+			panel->showDefaultSubpart();
+		}
 	}
 }
 
-void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update, LLPointer<LLInventoryCallback> cb)
+void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update, LLPointer<LLInventoryCallback> cb, const std::string description)
 {		
+	std::string link_description = description;
 	const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item);
 	if (!vitem)
 	{
@@ -2161,37 +2470,106 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update
 	{
 		if(do_update && cb.isNull())
 		{
-			cb = new ModifiedCOFCallback;
+			cb = new LLBoostFuncInventoryCallback(modified_cof_cb);
+		}
+		if (vitem->getIsLinkType())
+		{
+			link_description = vitem->getActualDescription();
 		}
-		const std::string description = vitem->getIsLinkType() ? vitem->getDescription() : "";
 		link_inventory_item( gAgent.getID(),
 							 vitem->getLinkedUUID(),
 							 getCOF(),
 							 vitem->getName(),
-							 description,
+							 link_description,
 							 LLAssetType::AT_LINK,
 							 cb);
 	}
 	return;
 }
 
-// BAP remove ensemble code for 2.1?
-void LLAppearanceMgr::addEnsembleLink( LLInventoryCategory* cat, bool do_update )
+LLInventoryModel::item_array_t LLAppearanceMgr::findCOFItemLinks(const LLUUID& item_id)
 {
-#if SUPPORT_ENSEMBLES
-	// BAP add check for already in COF.
-	LLPointer<LLInventoryCallback> cb = do_update ? new ModifiedCOFCallback : 0;
-	link_inventory_item( gAgent.getID(),
-						 cat->getLinkedUUID(),
-						 getCOF(),
-						 cat->getName(),
-						 cat->getDescription(),
-						 LLAssetType::AT_LINK_FOLDER,
-						 cb);
-#endif
+
+	LLInventoryModel::item_array_t result;
+	const LLViewerInventoryItem *vitem =
+		dynamic_cast<const LLViewerInventoryItem*>(gInventory.getItem(item_id));
+
+	if (vitem)
+	{
+		LLInventoryModel::cat_array_t cat_array;
+		LLInventoryModel::item_array_t item_array;
+		gInventory.collectDescendents(LLAppearanceMgr::getCOF(),
+									  cat_array,
+									  item_array,
+									  LLInventoryModel::EXCLUDE_TRASH);
+		for (S32 i=0; i<item_array.count(); i++)
+		{
+			const LLViewerInventoryItem* inv_item = item_array.get(i).get();
+			if (inv_item->getLinkedUUID() == vitem->getLinkedUUID())
+			{
+				result.put(item_array.get(i));
+			}
+		}
+	}
+	return result;
 }
 
-void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, bool do_update)
+void LLAppearanceMgr::removeAllClothesFromAvatar()
+{
+	// Fetch worn clothes (i.e. the ones in COF).
+	LLInventoryModel::item_array_t clothing_items;
+	LLInventoryModel::cat_array_t dummy;
+	LLIsType is_clothing(LLAssetType::AT_CLOTHING);
+	gInventory.collectDescendentsIf(getCOF(),
+									dummy,
+									clothing_items,
+									LLInventoryModel::EXCLUDE_TRASH,
+									is_clothing,
+									false);
+	uuid_vec_t item_ids;
+	for (LLInventoryModel::item_array_t::iterator it = clothing_items.begin();
+		it != clothing_items.end(); ++it)
+	{
+		item_ids.push_back((*it).get()->getLinkedUUID());
+	}
+
+	// Take them off by removing from COF.
+	removeItemsFromAvatar(item_ids);
+}
+
+void LLAppearanceMgr::removeAllAttachmentsFromAvatar()
+{
+	if (!isAgentAvatarValid()) return;
+
+	LLAgentWearables::llvo_vec_t objects_to_remove;
+	
+	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 *attached_object = (*attachment_iter);
+			if (attached_object)
+			{
+				objects_to_remove.push_back(attached_object);
+			}
+		}
+	}
+	uuid_vec_t ids_to_remove;
+	for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_remove.begin();
+		 it != objects_to_remove.end();
+		 ++it)
+	{
+		ids_to_remove.push_back((*it)->getAttachmentItemID());
+	}
+	removeItemsFromAvatar(ids_to_remove);
+}
+
+void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id)
 {
 	gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
 
@@ -2209,13 +2587,9 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, bool do_update)
 			gInventory.purgeObject(item->getUUID());
 		}
 	}
-	if (do_update)
-	{
-		LLAppearanceMgr::updateAppearanceFromCOF();
-	}
 }
 
-void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, bool do_update)
+void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type)
 {
 	LLFindWearablesOfType filter_wearables_of_type(type);
 	LLInventoryModel::cat_array_t cats;
@@ -2231,11 +2605,6 @@ void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, bool do_u
 			gInventory.purgeObject(item->getUUID());
 		}
 	}
-
-	if (do_update)
-	{
-		updateAppearanceFromCOF();
-	}
 }
 
 bool sort_by_linked_uuid(const LLViewerInventoryItem* item1, const LLViewerInventoryItem* item2)
@@ -2303,7 +2672,7 @@ void LLAppearanceMgr::updateIsDirty()
 
 			if (item1->getLinkedUUID() != item2->getLinkedUUID() || 
 				item1->getName() != item2->getName() ||
-				item1->LLInventoryItem::getDescription() != item2->LLInventoryItem::getDescription())
+				item1->getActualDescription() != item2->getActualDescription())
 			{
 				mOutfitIsDirty = true;
 				return;
@@ -2372,7 +2741,7 @@ void LLAppearanceMgr::copyLibraryGestures()
 			folder_name == COMMON_GESTURES_FOLDER ||
 			folder_name == OTHER_GESTURES_FOLDER)
 		{
-			cb = new ActivateGestureCallback;
+			cb = new LLBoostFuncInventoryCallback(activate_gesture_cb);
 		}
 
 		LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name);
@@ -2426,6 +2795,16 @@ void LLAppearanceMgr::onFirstFullyVisible()
 	}
 }
 
+// update "dirty" state - defined outside class to allow for calling
+// after appearance mgr instance has been destroyed.
+void appearance_mgr_update_dirty_state()
+{
+	if (LLAppearanceMgr::instanceExists())
+	{
+		LLAppearanceMgr::getInstance()->updateIsDirty();
+	}
+}
+
 bool LLAppearanceMgr::updateBaseOutfit()
 {
 	if (isOutfitLocked())
@@ -2446,8 +2825,8 @@ bool LLAppearanceMgr::updateBaseOutfit()
 	// in a Base Outfit we do not remove items, only links
 	purgeCategory(base_outfit_id, false);
 
-
-	LLPointer<LLInventoryCallback> dirty_state_updater = new LLUpdateDirtyState();
+	LLPointer<LLInventoryCallback> dirty_state_updater =
+		new LLBoostFuncInventoryCallback(no_op_inventory_func, appearance_mgr_update_dirty_state);
 
 	//COF contains only links so we copy to the Base Outfit only links
 	shallowCopyCategoryContents(getCOF(), base_outfit_id, dirty_state_updater);
@@ -2504,8 +2883,8 @@ struct WearablesOrderComparator
 			return true;
 		}
 		
-		const std::string& desc1 = item1->LLInventoryItem::getDescription();
-		const std::string& desc2 = item2->LLInventoryItem::getDescription();
+		const std::string& desc1 = item1->getActualDescription();
+		const std::string& desc2 = item2->getActualDescription();
 		
 		bool item1_valid = (desc1.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc1[0]);
 		bool item2_valid = (desc2.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc2[0]);
@@ -2563,7 +2942,7 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base
 			if (!item) continue;
 
 			std::string new_order_str = build_order_string((LLWearableType::EType)type, i);
-			if (new_order_str == item->LLInventoryItem::getDescription()) continue;
+			if (new_order_str == item->getActualDescription()) continue;
 
 			item->setDescription(new_order_str);
 			item->setComplete(TRUE);
@@ -2578,52 +2957,424 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base
 	if (inventory_changed) gInventory.notifyObservers();
 }
 
+// This is intended for use with HTTP Clients/Responders, but is not
+// specifically coupled with those classes.
+class LLHTTPRetryPolicy: public LLThreadSafeRefCount
+{
+public:
+	LLHTTPRetryPolicy() {}
+	virtual ~LLHTTPRetryPolicy() {}
+	virtual bool shouldRetry(U32 status, F32& seconds_to_wait) = 0;
+};
+
+// Example of simplest possible policy, not necessarily recommended.
+class LLAlwaysRetryImmediatelyPolicy: public LLHTTPRetryPolicy
+{
+public:
+	LLAlwaysRetryImmediatelyPolicy() {}
+	bool shouldRetry(U32 status, F32& seconds_to_wait)
+	{
+		seconds_to_wait = 0.0;
+		return true;
+	}
+};
+
+// Very general policy with geometric back-off after failures,
+// up to a maximum delay, and maximum number of retries.
+class LLAdaptiveRetryPolicy: public LLHTTPRetryPolicy
+{
+public:
+	LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 backoff_factor, U32 max_retries):
+		mMinDelay(min_delay),
+		mMaxDelay(max_delay),
+		mBackoffFactor(backoff_factor),
+		mMaxRetries(max_retries),
+		mDelay(min_delay),
+		mRetryCount(0)
+	{
+	}
 
+	bool shouldRetry(U32 status, F32& seconds_to_wait)
+	{
+		seconds_to_wait = mDelay;
+		mDelay = llclamp(mDelay*mBackoffFactor,mMinDelay,mMaxDelay);
+		mRetryCount++;
+		return (mRetryCount<=mMaxRetries);
+	}
 
+private:
+	F32 mMinDelay; // delay never less than this value
+	F32 mMaxDelay; // delay never exceeds this value
+	F32 mBackoffFactor; // delay increases by this factor after each retry, up to mMaxDelay.
+	U32 mMaxRetries; // maximum number of times shouldRetry will return true.
+	F32 mDelay; // current delay.
+	U32 mRetryCount; // number of times shouldRetry has been called.
+};
 
-class LLShowCreatedOutfit: public LLInventoryCallback
+class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder
 {
 public:
-	LLShowCreatedOutfit(LLUUID& folder_id, bool show_panel = true): mFolderID(folder_id), mShowPanel(show_panel)
-	{}
+	RequestAgentUpdateAppearanceResponder()
+	{
+		mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10);
+	}
 
-	virtual ~LLShowCreatedOutfit()
+	virtual ~RequestAgentUpdateAppearanceResponder()
 	{
-		if (!LLApp::isRunning())
+	}
+
+	// Successful completion.
+	/* virtual */ void result(const LLSD& content)
+	{
+		LL_DEBUGS("Avatar") << "content: " << ll_pretty_print_sd(content) << LL_ENDL;
+		if (content["success"].asBoolean())
 		{
-			llwarns << "called during shutdown, skipping" << llendl;
-			return;
+			LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
+			if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+			{
+				dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_ok", content);
+			}
 		}
+		else
+		{
+			onFailure(200);
+		}
+	}
 
-		LLSD key;
+	// Error
+	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	{
+		llwarns << "appearance update request failed, status: " << status << " reason: " << reason << " code: " << content["code"].asInteger() << " error: \"" << content["error"].asString() << "\"" << llendl;
+		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+		{
+			dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
+			debugCOF(content);
 		
-		//EXT-7727. For new accounts LLShowCreatedOutfit is created during login process
-		// add may be processed after login process is finished
-		if (mShowPanel)
+		}
+		onFailure(status);
+	}	
+
+	void onFailure(U32 status)
+	{
+		F32 seconds_to_wait;
+		if (mRetryPolicy->shouldRetry(status,seconds_to_wait))
+		{
+			llinfos << "retrying" << llendl;
+			doAfterInterval(boost::bind(&LLAppearanceMgr::requestServerAppearanceUpdate,
+										LLAppearanceMgr::getInstance(),
+										LLCurl::ResponderPtr(this)),
+							seconds_to_wait);
+		}
+		else
+		{
+			llwarns << "giving up after too many retries" << llendl;
+		}
+	}	
+
+	void dumpContents(const std::string outprefix, const LLSD& content)
+	{
+		std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml");
+		std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+		std::ofstream ofs(fullpath.c_str(), std::ios_base::out);
+		ofs << LLSDOStreamer<LLSDXMLFormatter>(content, LLSDFormatter::OPTIONS_PRETTY);
+		LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL;
+	}
+
+	void debugCOF(const LLSD& content)
+	{
+		LL_DEBUGS("Avatar") << "AIS COF, version found: " << content["expected"].asInteger() << llendl;
+		std::set<LLUUID> ais_items, local_items;
+		const LLSD& cof_raw = content["cof_raw"];
+		for (LLSD::array_const_iterator it = cof_raw.beginArray();
+			 it != cof_raw.endArray(); ++it)
+		{
+			const LLSD& item = *it;
+			if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF())
+			{
+				ais_items.insert(item["item_id"].asUUID());
+				if (item["type"].asInteger() == 24) // link
+				{
+					LL_DEBUGS("Avatar") << "Link: item_id: " << item["item_id"].asUUID()
+										<< " linked_item_id: " << item["asset_id"].asUUID()
+										<< " name: " << item["name"].asString()
+										<< llendl; 
+				}
+				else if (item["type"].asInteger() == 25) // folder link
+				{
+					LL_DEBUGS("Avatar") << "Folder link: item_id: " << item["item_id"].asUUID()
+										<< " linked_item_id: " << item["asset_id"].asUUID()
+										<< " name: " << item["name"].asString()
+										<< llendl; 
+					
+				}
+				else
+				{
+					LL_DEBUGS("Avatar") << "Other: item_id: " << item["item_id"].asUUID()
+										<< " linked_item_id: " << item["asset_id"].asUUID()
+										<< " name: " << item["name"].asString()
+										<< llendl; 
+				}
+			}
+		}
+		LL_DEBUGS("Avatar") << llendl;
+		LL_DEBUGS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger() << llendl;
+		LLInventoryModel::cat_array_t cat_array;
+		LLInventoryModel::item_array_t item_array;
+		gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
+									  cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
+		for (S32 i=0; i<item_array.count(); i++)
+		{
+			const LLViewerInventoryItem* inv_item = item_array.get(i).get();
+			local_items.insert(inv_item->getUUID());
+			LL_DEBUGS("Avatar") << "item_id: " << inv_item->getUUID()
+								<< " linked_item_id: " << inv_item->getLinkedUUID()
+								<< " name: " << inv_item->getName()
+								<< llendl;
+		}
+		LL_DEBUGS("Avatar") << llendl;
+		for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it)
+		{
+			if (ais_items.find(*it) == ais_items.end())
+			{
+				LL_DEBUGS("Avatar") << "LOCAL ONLY: " << *it << llendl;
+			}
+		}
+		for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)
 		{
-			LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key);
+			if (local_items.find(*it) == local_items.end())
+			{
+				LL_DEBUGS("Avatar") << "AIS ONLY: " << *it << llendl;
+			}
+		}
+	}
+
+	LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
+};
 
+LLSD LLAppearanceMgr::dumpCOF() const
+{
+	LLSD links = LLSD::emptyArray();
+	LLMD5 md5;
+	
+	LLInventoryModel::cat_array_t cat_array;
+	LLInventoryModel::item_array_t item_array;
+	gInventory.collectDescendents(getCOF(),cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
+	for (S32 i=0; i<item_array.count(); i++)
+	{
+		const LLViewerInventoryItem* inv_item = item_array.get(i).get();
+		LLSD item;
+		LLUUID item_id(inv_item->getUUID());
+		md5.update((unsigned char*)item_id.mData, 16);
+		item["description"] = inv_item->getActualDescription();
+		md5.update(inv_item->getActualDescription());
+		item["asset_type"] = inv_item->getActualType();
+		LLUUID linked_id(inv_item->getLinkedUUID());
+		item["linked_id"] = linked_id;
+		md5.update((unsigned char*)linked_id.mData, 16);
+
+		if (LLAssetType::AT_LINK == inv_item->getActualType())
+		{
+			const LLViewerInventoryItem* linked_item = inv_item->getLinkedItem();
+			if (NULL == linked_item)
+			{
+				llwarns << "Broken link for item '" << inv_item->getName()
+						<< "' (" << inv_item->getUUID()
+						<< ") during requestServerAppearanceUpdate" << llendl;
+				continue;
+			}
+			// Some assets may be 'hidden' and show up as null in the viewer.
+			//if (linked_item->getAssetUUID().isNull())
+			//{
+			//	llwarns << "Broken link (null asset) for item '" << inv_item->getName()
+			//			<< "' (" << inv_item->getUUID()
+			//			<< ") during requestServerAppearanceUpdate" << llendl;
+			//	continue;
+			//}
+			LLUUID linked_asset_id(linked_item->getAssetUUID());
+			md5.update((unsigned char*)linked_asset_id.mData, 16);
+			U32 flags = linked_item->getFlags();
+			md5.update(boost::lexical_cast<std::string>(flags));
+		}
+		else if (LLAssetType::AT_LINK_FOLDER != inv_item->getActualType())
+		{
+			llwarns << "Non-link item '" << inv_item->getName()
+					<< "' (" << inv_item->getUUID()
+					<< ") type " << (S32) inv_item->getActualType()
+					<< " during requestServerAppearanceUpdate" << llendl;
+			continue;
 		}
-		LLOutfitsList *outfits_list =
-			dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab"));
-		if (outfits_list)
+		links.append(item);
+	}
+	LLSD result = LLSD::emptyMap();
+	result["cof_contents"] = links;
+	char cof_md5sum[MD5HEX_STR_SIZE];
+	md5.finalize();
+	md5.hex_digest(cof_md5sum);
+	result["cof_md5sum"] = std::string(cof_md5sum);
+	return result;
+}
+
+void LLAppearanceMgr::requestServerAppearanceUpdate(LLCurl::ResponderPtr responder_ptr)
+{
+	if (gAgentAvatarp->isEditingAppearance()) 
+	{
+		// don't send out appearance updates if in appearance editing mode
+		return;
+	}
+
+	if (!gAgent.getRegion())
+	{
+		llwarns << "Region not set, cannot request server appearance update" << llendl;
+		return;
+	}
+	if (gAgent.getRegion()->getCentralBakeVersion()==0)
+	{
+		llwarns << "Region does not support baking" << llendl;
+	}
+	std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance");	
+	if (url.empty())
+	{
+		llwarns << "No cap for UpdateAvatarAppearance." << llendl;
+		return;
+	}
+	
+	LLSD body;
+	S32 cof_version = getCOFVersion();
+	if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate"))
+	{
+		body = dumpCOF();
+	}
+	else
+	{
+		body["cof_version"] = cof_version;
+		if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
 		{
-			outfits_list->setSelectedOutfitByUUID(mFolderID);
+			body["cof_version"] = cof_version+999;
 		}
+	}
+	LL_DEBUGS("Avatar") << "request url " << url << " my_cof_version " << cof_version << llendl;
+	
+	//LLCurl::ResponderPtr responder_ptr;
+	if (!responder_ptr.get())
+	{
+		responder_ptr = new RequestAgentUpdateAppearanceResponder;
+	}
+	LLHTTPClient::post(url, body, responder_ptr);
+	llassert(cof_version >= gAgentAvatarp->mLastUpdateRequestCOFVersion);
+	gAgentAvatarp->mLastUpdateRequestCOFVersion = cof_version;
+}
 
-		LLAppearanceMgr::getInstance()->updateIsDirty();
-		gAgentWearables.notifyLoadingFinished(); // New outfit is saved.
-		LLAppearanceMgr::getInstance()->updatePanelOutfitName("");
+class LLIncrementCofVersionResponder : public LLHTTPClient::Responder
+{
+public:
+	LLIncrementCofVersionResponder() : LLHTTPClient::Responder()
+	{
+		mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 16.0, 2.0, 5);
+	}
+
+	virtual ~LLIncrementCofVersionResponder()
+	{
 	}
 
-	virtual void fire(const LLUUID&)
-	{}
+	virtual void result(const LLSD &pContent)
+	{
+		llinfos << "Successfully incremented agent's COF." << llendl;
+		S32 new_version = pContent["category"]["version"].asInteger();
 
-private:
-	LLUUID mFolderID;
-	bool mShowPanel;
+		// cof_version should have increased
+		llassert(new_version > gAgentAvatarp->mLastUpdateRequestCOFVersion);
+
+		gAgentAvatarp->mLastUpdateRequestCOFVersion = new_version;
+	}
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& content)
+	{
+		llwarns << "While attempting to increment the agent's cof we got an error with [status:"
+				<< pStatus << "]: " << content << llendl;
+		F32 seconds_to_wait;
+		if (mRetryPolicy->shouldRetry(pStatus,seconds_to_wait))
+		{
+			llinfos << "retrying" << llendl;
+			doAfterInterval(boost::bind(&LLAppearanceMgr::incrementCofVersion,
+										LLAppearanceMgr::getInstance(),
+										LLHTTPClient::ResponderPtr(this)),
+										seconds_to_wait);
+		}
+		else
+		{
+			llwarns << "giving up after too many retries" << llendl;
+		}
+	}
+
+	LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
 };
 
+void LLAppearanceMgr::incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr)
+{
+	// If we don't have a region, report it as an error
+	if (gAgent.getRegion() == NULL)
+	{
+		llwarns << "Region not set, cannot request cof_version increment" << llendl;
+		return;
+	}
+
+	std::string url = gAgent.getRegion()->getCapability("IncrementCofVersion");
+	if (url.empty())
+	{
+		llwarns << "No cap for IncrementCofVersion." << llendl;
+		return;
+	}
+
+	llinfos << "Requesting cof_version be incremented via capability to: "
+			<< url << llendl;
+	LLSD headers;
+	LLSD body = LLSD::emptyMap();
+
+	if (!responder_ptr.get())
+	{
+		responder_ptr = LLHTTPClient::ResponderPtr(new LLIncrementCofVersionResponder());
+	}
+
+	LLHTTPClient::get(url, body, responder_ptr, headers, 30.0f);
+}
+
+std::string LLAppearanceMgr::getAppearanceServiceURL() const
+{
+	if (gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride").empty())
+	{
+		return mAppearanceServiceURL;
+	}
+	return gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride");
+}
+
+void show_created_outfit(LLUUID& folder_id, bool show_panel = true)
+{
+	if (!LLApp::isRunning())
+	{
+		llwarns << "called during shutdown, skipping" << llendl;
+		return;
+	}
+	
+	LLSD key;
+	
+	//EXT-7727. For new accounts inventory callback is created during login process
+	// and may be processed after login process is finished
+	if (show_panel)
+	{
+		LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key);
+		
+	}
+	LLOutfitsList *outfits_list =
+		dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab"));
+	if (outfits_list)
+	{
+		outfits_list->setSelectedOutfitByUUID(folder_id);
+	}
+	
+	LLAppearanceMgr::getInstance()->updateIsDirty();
+	gAgentWearables.notifyLoadingFinished(); // New outfit is saved.
+	LLAppearanceMgr::getInstance()->updatePanelOutfitName("");
+}
+
 LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)
 {
 	if (!isAgentAvatarValid()) return LLUUID::null;
@@ -2639,7 +3390,8 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, b
 
 	updateClothingOrderingInfo();
 
-	LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id,show_panel);
+	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(no_op_inventory_func,
+																		 boost::bind(show_created_outfit,folder_id,show_panel));
 	shallowCopyCategoryContents(getCOF(),folder_id, cb);
 	createBaseOutfitLink(folder_id, cb);
 
@@ -2656,33 +3408,26 @@ void LLAppearanceMgr::wearBaseOutfit()
 	updateCOF(base_outfit_id);
 }
 
-void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
+void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
 {
-	LLViewerInventoryItem * item_to_remove = gInventory.getItem(id_to_remove);
-	if (!item_to_remove) return;
-
-	switch (item_to_remove->getType())
+	if (ids_to_remove.empty())
 	{
-		case LLAssetType::AT_CLOTHING:
-			if (get_is_item_worn(id_to_remove))
-			{
-				//*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
-				LLWearableBridge::removeItemFromAvatar(item_to_remove);
-			}
-			break;
-		case LLAssetType::AT_OBJECT:
-			LLVOAvatarSelf::detachAttachmentIntoInventory(item_to_remove->getLinkedUUID());
-		default:
-			break;
+		llwarns << "called with empty list, nothing to do" << llendl;
+	}
+	for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
+	{
+		const LLUUID& id_to_remove = *it;
+		const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);
+		removeCOFItemLinks(linked_item_id);
 	}
+	updateAppearanceFromCOF();
+}
 
-	// *HACK: Force to remove garbage from COF.
-	// Unworn links or objects can't be processed by existed removing functionality
-	// since it is not designed for such cases. As example attachment object can't be removed
-	// since sever don't sends message _PREHASH_KillObject in that case.
-	// Also we can't check is link was successfully removed from COF since in case
-	// deleting attachment link removing performs asynchronously in process_kill_object callback.
-	removeCOFItemLinks(id_to_remove,false);
+void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
+{
+	LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove);
+	removeCOFItemLinks(linked_item_id);
+	updateAppearanceFromCOF();
 }
 
 bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body)
@@ -2711,8 +3456,8 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b
 	closer_to_body ? --it : ++it;
 	LLViewerInventoryItem* swap_item = *it;
 	if (!swap_item) return false;
-	std::string tmp = swap_item->LLInventoryItem::getDescription();
-	swap_item->setDescription(item->LLInventoryItem::getDescription());
+	std::string tmp = swap_item->getActualDescription();
+	swap_item->setDescription(item->getActualDescription());
 	item->setDescription(tmp);
 
 
@@ -2745,7 +3490,7 @@ void LLAppearanceMgr::sortItemsByActualDescription(LLInventoryModel::item_array_
 {
 	if (items.size() < 2) return;
 
-	std::sort(items.begin(), items.end(), sort_by_description);
+	std::sort(items.begin(), items.end(), sort_by_actual_description);
 }
 
 //#define DUMP_CAT_VERBOSE
@@ -2811,7 +3556,7 @@ LLAppearanceMgr::~LLAppearanceMgr()
 
 void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
 {
-	llinfos << "setAttachmentInvLinkEnable => " << (int) val << llendl;
+	LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int) val << llendl;
 	mAttachmentInvLinkEnabled = val;
 }
 
@@ -2855,7 +3600,7 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
 
 	   if (mAttachmentInvLinkEnabled)
 	   {
-		   LLAppearanceMgr::removeCOFItemLinks(item_id, false);
+		   LLAppearanceMgr::removeCOFItemLinks(item_id);
 	   }
 	   else
 	   {
@@ -2949,9 +3694,9 @@ class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver
 	}
 	virtual void done()
 	{
-		// What we do here is get the complete information on the items in
-		// the library, and set up an observer that will wait for that to
-		// happen.
+		// What we do here is get the complete information on the
+		// items in the requested category, and set up an observer
+		// that will wait for that to happen.
 		LLInventoryModel::cat_array_t cat_array;
 		LLInventoryModel::item_array_t item_array;
 		gInventory.collectDescendents(mComplete.front(),
@@ -2964,9 +3709,8 @@ class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver
 			llwarns << "Nothing fetched in category " << mComplete.front()
 					<< llendl;
 			gInventory.removeObserver(this);
+			doOnIdleOneTime(mCallable);
 
-			// lets notify observers that loading is finished.
-			gAgentWearables.notifyLoadingFinished();
 			delete this;
 			return;
 		}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
old mode 100644
new mode 100755
index c1d561781d21f947f00b540480f7d3571add79df..46252afbde14799662de45582dbf63150c1f819d
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -35,7 +35,6 @@
 #include "llinventoryobserver.h"
 #include "llviewerinventory.h"
 
-class LLWearable;
 class LLWearableHoldingPattern;
 class LLInventoryCallback;
 class LLOutfitUnLockTimer;
@@ -93,6 +92,10 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 
 	// Find the Current Outfit folder.
 	const LLUUID getCOF() const;
+	S32 getCOFVersion() const;
+
+	// Debugging - get truncated LLSD summary of COF contents.
+	LLSD dumpCOF() const;
 
 	// Finds the folder link to the currently worn outfit
 	const LLViewerInventoryItem *getBaseOutfitLink();
@@ -107,6 +110,7 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	// Update the displayed outfit name in UI.
 	void updatePanelOutfitName(const std::string& name);
 
+	void purgeBaseOutfitLink(const LLUUID& category);
 	void createBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> link_waiter);
 
 	void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
@@ -126,15 +130,17 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 				 LLPointer<LLInventoryCallback> cb);
 
 	// Add COF link to individual item.
-	void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
-	void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
+	void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
+	void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
 
-	// Remove COF entries
-	void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true);
-	void removeCOFLinksOfType(LLWearableType::EType type, bool do_update = true);
+	// Find COF entries referencing the given item.
+	LLInventoryModel::item_array_t findCOFItemLinks(const LLUUID& item_id);
 
-	// Add COF link to ensemble folder.
-	void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
+	// Remove COF entries
+	void removeCOFItemLinks(const LLUUID& item_id);
+	void removeCOFLinksOfType(LLWearableType::EType type);
+	void removeAllClothesFromAvatar();
+	void removeAllAttachmentsFromAvatar();
 
 	//has the current outfit changed since it was loaded?
 	bool isOutfitDirty() { return mOutfitIsDirty; }
@@ -162,6 +168,7 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	bool updateBaseOutfit();
 
 	//Remove clothing or detach an object from the agent (a bodypart cannot be removed)
+	void removeItemsFromAvatar(const uuid_vec_t& item_ids);
 	void removeItemFromAvatar(const LLUUID& item_id);
 
 
@@ -182,6 +189,20 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 
 	bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; }
 
+	void requestServerAppearanceUpdate(LLCurl::ResponderPtr responder_ptr = NULL);
+
+	void incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr = NULL);
+
+	// *HACK Remove this after server side texture baking is deployed on all sims.
+	void incrementCofVersionLegacy();
+
+	void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
+	std::string getAppearanceServiceURL() const;
+
+private:
+	std::string		mAppearanceServiceURL;
+	
+
 protected:
 	LLAppearanceMgr();
 	~LLAppearanceMgr();
@@ -201,9 +222,7 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 								   LLInventoryModel::item_array_t& gest_items,
 								   bool follow_folder_links);
 
-	void purgeCategory(const LLUUID& category, bool keep_outfit_links);
-	void purgeBaseOutfitLink(const LLUUID& category);
-
+	void purgeCategory(const LLUUID& category, bool keep_outfit_links, LLInventoryModel::item_array_t* keep_items = NULL);
 	static void onOutfitRename(const LLSD& notification, const LLSD& response);
 
 	void setOutfitLocked(bool locked);
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 53c694eaca23bc83f16fcdf04026de19fc960e1c..3adf956ae3ab33f897ca169eae7f0521296e3afe 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -292,6 +292,10 @@ LLTimer gLogoutTimer;
 static const F32 LOGOUT_REQUEST_TIME = 6.f;  // this will be cut short by the LogoutReply msg.
 F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
 
+
+S32 gPendingMetricsUploads = 0;
+
+
 BOOL				gDisconnected = FALSE;
 
 // used to restore texture state after a mode switch
@@ -682,6 +686,15 @@ LLAppViewer::~LLAppViewer()
 	removeMarkerFile();
 }
 
+class LLUITranslationBridge : public LLTranslationBridge
+{
+public:
+	virtual std::string getString(const std::string &xml_desc)
+	{
+		return LLTrans::getString(xml_desc);
+	}
+};
+
 bool LLAppViewer::init()
 {	
 	//
@@ -693,6 +706,10 @@ bool LLAppViewer::init()
 	//
 	LLFastTimer::reset();
 
+	// initialize LLWearableType translation bridge.
+	// Memory will be cleaned up in ::cleanupClass()
+	LLWearableType::initClass(new LLUITranslationBridge());
+
 	// initialize SSE options
 	LLVector4a::initClass();
 
@@ -786,7 +803,7 @@ bool LLAppViewer::init()
 		LLUIImageList::getInstance(),
 		ui_audio_callback,
 		deferred_ui_audio_callback,
-		&LLUI::sGLScaleFactor);
+		&LLUI::getScaleFactor());
 	LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
 
 	// NOW LLUI::getLanguage() should work. gDirUtilp must know the language
@@ -1775,6 +1792,8 @@ bool LLAppViewer::cleanup()
 	llinfos << "Cleaning up Objects" << llendflush;
 	
 	LLViewerObject::cleanupVOClasses();
+
+	LLAvatarAppearance::cleanupClass();
 	
 	LLPostProcess::cleanupClass();
 
@@ -2014,6 +2033,8 @@ bool LLAppViewer::cleanup()
 	llinfos << "Cleaning up LLProxy." << llendl;
 	LLProxy::cleanupClass();
 
+	LLWearableType::cleanupClass();
+
 	LLMainLoopRepeater::instance().stop();
 
 	//release all private memory pools.
@@ -3573,6 +3594,12 @@ void LLAppViewer::requestQuit()
 
 	// Try to send metrics back to the grid
 	metricsSend(!gDisconnected);
+
+	// Try to send last batch of avatar rez metrics.
+	if (!gDisconnected && isAgentAvatarValid())
+	{
+		gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
+	}
 	
 	LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
 	effectp->setPositionGlobal(gAgent.getPositionGlobal());
@@ -4365,7 +4392,6 @@ void LLAppViewer::idle()
 			// The 5-second interval is nice for this purpose.  If the object debug
 			// bit moves or is disabled, please give this a suitable home.
 			LLViewerAssetStatsFF::record_fps_main(gFPSClamped);
-			LLViewerAssetStatsFF::record_avatar_stats();
 		}
 	}
 
@@ -4681,6 +4707,13 @@ void LLAppViewer::idleShutdown()
 		return;
 	}
 
+	if (gPendingMetricsUploads > 0
+		&& gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
+		&& !logoutRequestSent())
+	{
+		return;
+	}
+
 	// All floaters are closed.  Tell server we want to quit.
 	if( !logoutRequestSent() )
 	{
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 7563d672e3cb8d680cf14d7f69f5838674e4822f..08039100b3e7e8385f5d90d47a65197762fae974 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -342,6 +342,8 @@ extern LLFrameTimer gLoggedInTime;
 extern F32 gLogoutMaxTime;
 extern LLTimer gLogoutTimer;
 
+extern S32 gPendingMetricsUploads;
+
 extern F32 gSimLastTime; 
 extern F32 gSimFrames;
 
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 8326be433e9db7ebf519b38e30cf6141c7d0f020..82b93b52a2a126c4858879519f753a30ece3009d 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -92,7 +92,7 @@ void nvapi_error(NvAPI_Status status)
 	llwarns << szDesc << llendl;
 
 	//should always trigger when asserts are enabled
-	llassert(status == NVAPI_OK);
+	//llassert(status == NVAPI_OK);
 }
 
 // Create app mutex creates a unique global windows object. 
diff --git a/indra/newview/llassetuploadqueue.cpp b/indra/newview/llassetuploadqueue.cpp
index f943759bb89c66fe1e27d633b60ea195ad307637..4bdb690225d6b871876ceb0e5a33de65fcf81086 100644
--- a/indra/newview/llassetuploadqueue.cpp
+++ b/indra/newview/llassetuploadqueue.cpp
@@ -69,10 +69,11 @@ class LLAssetUploadChainResponder : public LLUpdateTaskInventoryResponder
 		delete mData;
    	}
 	
-	virtual void error(U32 statusNum, const std::string& reason)
+	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
    	{
-		llwarns << "Error: " << reason << llendl;
-		LLUpdateTaskInventoryResponder::error(statusNum, reason);
+		llwarns << "LLAssetUploadChainResponder Error [status:" 
+				<< statusNum << "]: " << content << llendl;
+		LLUpdateTaskInventoryResponder::errorWithContent(statusNum, reason, content);
    		LLAssetUploadQueue *queue = mSupplier->get();
    		if (queue)
 		{
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 7b2c536f5add55b5a58027110a12cb2c477bd470..25648023879a9ee2e99ddd17f04df74292e4fcd7 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -48,8 +48,8 @@
 #include "llviewercontrol.h"
 #include "llviewerobjectlist.h"
 #include "llviewermenufile.h"
+#include "llviewertexlayer.h"
 #include "llviewerwindow.h"
-#include "lltexlayer.h"
 #include "lltrans.h"
 
 // library includes
@@ -225,10 +225,10 @@ LLAssetUploadResponder::~LLAssetUploadResponder()
 }
 
 // virtual
-void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
+void LLAssetUploadResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 {
-	llinfos << "LLAssetUploadResponder::error " << statusNum 
-			<< " reason: " << reason << llendl;
+	llinfos << "LLAssetUploadResponder::error [status:" 
+			<< statusNum << "]: " << content << llendl;
 	LLSD args;
 	switch(statusNum)
 	{
@@ -340,9 +340,9 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(
 }
 
 // virtual
-void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reason)
+void LLNewAgentInventoryResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 {
-	LLAssetUploadResponder::error(statusNum, reason);
+	LLAssetUploadResponder::errorWithContent(statusNum, reason, content);
 	//LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE);
 }
 
@@ -456,7 +456,7 @@ LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data,
 
 LLSendTexLayerResponder::~LLSendTexLayerResponder()
 {
-	// mBakedUploadData is normally deleted by calls to LLTexLayerSetBuffer::onTextureUploadComplete() below
+	// mBakedUploadData is normally deleted by calls to LLViewerTexLayerSetBuffer::onTextureUploadComplete() below
 	if (mBakedUploadData)
 	{	// ...but delete it in the case where uploadComplete() is never called
 		delete mBakedUploadData;
@@ -477,22 +477,23 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content)
 	if (result == "complete"
 		&& mBakedUploadData != NULL)
 	{	// Invoke 
-		LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
+		LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
 		mBakedUploadData = NULL;	// deleted in onTextureUploadComplete()
 	}
 	else
 	{	// Invoke the original callback with an error result
-		LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
+		LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
 		mBakedUploadData = NULL;	// deleted in onTextureUploadComplete()
 	}
 }
 
-void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason)
+void LLSendTexLayerResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 {
-	llinfos << "status: " << statusNum << " reason: " << reason << llendl;
+	llinfos << "LLSendTexLayerResponder error [status:"
+			<< statusNum << "]: " << content << llendl;
 	
 	// Invoke the original callback with an error result
-	LLTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
+	LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
 	mBakedUploadData = NULL;	// deleted in onTextureUploadComplete()
 }
 
diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h
index 381b919c4a4c15587d0227d22bedfb89a167a43b..a6d1016136c6a49f86578e4077bf1acc010a822d 100644
--- a/indra/newview/llassetuploadresponders.h
+++ b/indra/newview/llassetuploadresponders.h
@@ -42,7 +42,7 @@ class LLAssetUploadResponder : public LLHTTPClient::Responder
 							LLAssetType::EType asset_type);
 	~LLAssetUploadResponder();
 
-    virtual void error(U32 statusNum, const std::string& reason);
+    virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
 	virtual void result(const LLSD& content);
 	virtual void uploadUpload(const LLSD& content);
 	virtual void uploadComplete(const LLSD& content);
@@ -67,7 +67,7 @@ class LLNewAgentInventoryResponder : public LLAssetUploadResponder
 		const LLSD& post_data,
 		const std::string& file_name,
 		LLAssetType::EType asset_type);
-    virtual void error(U32 statusNum, const std::string& reason);
+    virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
 	virtual void uploadComplete(const LLSD& content);
 	virtual void uploadFailure(const LLSD& content);
 };
@@ -122,7 +122,7 @@ class LLSendTexLayerResponder : public LLAssetUploadResponder
 	~LLSendTexLayerResponder();
 
 	virtual void uploadComplete(const LLSD& content);
-	virtual void error(U32 statusNum, const std::string& reason);
+	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
 
 	LLBakedUploadData * mBakedUploadData;
 };
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index 714bde6f372c8d4241a16d366cc8a22455a4d7d7..f34ad2376994316c71cc874fd33af9e695a542a8 100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -39,6 +39,8 @@
 #include "lluictrlfactory.h"
 #include "llagentdata.h"
 #include "llfloaterimsession.h"
+#include "llviewertexture.h"
+#include "llavatarappearancedefines.h"
 
 // library includes
 #include "llavatarnamecache.h"
diff --git a/indra/newview/llbuycurrencyhtml.cpp b/indra/newview/llbuycurrencyhtml.cpp
index e5a9be020311da047208e1646899560ae9b92915..459123a5d8b162b9c65f15fac4bd21d69417ac76 100644
--- a/indra/newview/llbuycurrencyhtml.cpp
+++ b/indra/newview/llbuycurrencyhtml.cpp
@@ -61,6 +61,10 @@ class LLBuyCurrencyHTMLHandler :
 		if ( params.size() >= 3 )
 		{
 			result_code = params[ 2 ].asInteger();
+			if ( result_code != 0 )
+			{
+				LL_WARNS("LLBuyCurrency") << "Received nonzero result code: " << result_code << LL_ENDL ;
+			}
 		};
 
 		// open the legacy XUI based currency floater
diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp
index 357a6582d162b582eef2561ca7fdc471c45d0bc0..79ec43dfe920278d25a72c4151921a32a904974c 100644
--- a/indra/newview/llcallbacklist.cpp
+++ b/indra/newview/llcallbacklist.cpp
@@ -27,6 +27,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llcallbacklist.h"
+#include "lleventtimer.h"
 
 // Library includes
 #include "llerror.h"
@@ -180,6 +181,54 @@ void doOnIdleRepeating(bool_func_t callable)
 	gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor);
 }
 
+class NullaryFuncEventTimer: public LLEventTimer
+{
+public:
+	NullaryFuncEventTimer(nullary_func_t callable, F32 seconds):
+		LLEventTimer(seconds),
+		mCallable(callable)
+	{
+	}
+
+private:
+	BOOL tick()
+	{
+		mCallable();
+		return TRUE;
+	}
+
+	nullary_func_t mCallable;
+};
+
+// Call a given callable once after specified interval.
+void doAfterInterval(nullary_func_t callable, F32 seconds)
+{
+	new NullaryFuncEventTimer(callable, seconds);
+}
+
+class BoolFuncEventTimer: public LLEventTimer
+{
+public:
+	BoolFuncEventTimer(bool_func_t callable, F32 seconds):
+		LLEventTimer(seconds),
+		mCallable(callable)
+	{
+	}
+private:
+	BOOL tick()
+	{
+		return mCallable();
+	}
+
+	bool_func_t mCallable;
+};
+
+// Call a given callable every specified number of seconds, until it returns true.
+void doPeriodically(bool_func_t callable, F32 seconds)
+{
+	new BoolFuncEventTimer(callable, seconds);
+}
+
 #ifdef _DEBUG
 
 void test1(void *data)
diff --git a/indra/newview/llcallbacklist.h b/indra/newview/llcallbacklist.h
index 97f3bfd9ee29b6f061c76d0d4a21cb5d800da616..0516c9cdb44e663d47d123b555a7550ce0c774c3 100644
--- a/indra/newview/llcallbacklist.h
+++ b/indra/newview/llcallbacklist.h
@@ -61,6 +61,12 @@ void doOnIdleOneTime(nullary_func_t callable);
 // Repeatedly call a callable in idle loop until it returns true.
 void doOnIdleRepeating(bool_func_t callable);
 
+// Call a given callable once after specified interval.
+void doAfterInterval(nullary_func_t callable, F32 seconds);
+
+// Call a given callable every specified number of seconds, until it returns true.
+void doPeriodically(bool_func_t callable, F32 seconds);
+
 extern LLCallbackList gIdleCallbacks;
 
 #endif
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 30306b230f3f2081189c847c4b569eeae69eef6f..14583e402d53551164fa2fe91161e2fd8f3d989f 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -184,7 +184,8 @@ LLVector3d LLAvatarTracker::getGlobalPos()
 		global_pos = object->getPositionGlobal();
 		// HACK - for making the tracker point above the avatar's head
 		// rather than its groin
-		global_pos.mdV[VZ] += 0.7f * ((LLVOAvatar *)object)->mBodySize.mV[VZ];
+		LLVOAvatar* av = (LLVOAvatar*)object;
+		global_pos.mdV[VZ] += 0.7f * (av->mBodySize.mV[VZ] + av->mAvatarOffset.mV[VZ]);
 
 		mTrackingData->mGlobalPositionEstimate = global_pos;
 	}
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 53926c1fef6de4e531d81fe8b137362430853ae7..0f138873ac8cec543dbc16078ef48098af611934 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -408,16 +408,7 @@ class LLChatHistoryHeader: public LLPanel
 		S32 user_name_width = user_name_rect.getWidth();
 		S32 time_box_width = time_box->getRect().getWidth();
 
-		if (time_box->getVisible() && user_name_width <= mMinUserNameWidth)
-		{
-			time_box->setVisible(FALSE);
-
-			user_name_rect.mRight += time_box_width;
-			user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight());
-			user_name->setRect(user_name_rect);
-		}
-
-		if (!time_box->getVisible() && user_name_width > mMinUserNameWidth + time_box_width)
+		if (!time_box->getVisible() && user_name_width > mMinUserNameWidth)
 		{
 			user_name_rect.mRight -= time_box_width;
 			user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight());
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index 43c6b558bc920e7d6cd7199a7fac6e5eb2fc3881..88884042d4d0c482f65a1c1e5c1d84d3e483c6fb 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -430,14 +430,12 @@ void LLChicletPanel::onMessageCountChanged(const LLSD& data)
 {
     // *TODO : we either suppress this method or return a value. Right now, it servers no purpose.
     /*
-	LLUUID session_id = data["session_id"].asUUID();
-	S32 unread = data["participant_unread"].asInteger();
 
-	LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
-	if (im_floater && im_floater->getVisible() && im_floater->hasFocus())
-	{
-		unread = 0;
-	}
+	//LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
+	//if (im_floater && im_floater->getVisible() && im_floater->hasFocus())
+	//{
+	//	unread = 0;
+	//}
     */
 }
 
diff --git a/indra/newview/llclassifiedstatsresponder.cpp b/indra/newview/llclassifiedstatsresponder.cpp
index b4da31895fcdf2488898736ebe0e3ecad35136d9..e3cd83e174211bc4bcd997285adf96c93fedf899 100644
--- a/indra/newview/llclassifiedstatsresponder.cpp
+++ b/indra/newview/llclassifiedstatsresponder.cpp
@@ -62,8 +62,7 @@ void LLClassifiedStatsResponder::result(const LLSD& content)
 }
 
 /*virtual*/
-void LLClassifiedStatsResponder::error(U32 status, const std::string& reason)
+void LLClassifiedStatsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llinfos << "LLClassifiedStatsResponder::error("
-		<< status << ": " << reason << ")" << llendl;
+	llinfos << "LLClassifiedStatsResponder::error [status:" << status << "]: " << content << llendl;
 }
diff --git a/indra/newview/llclassifiedstatsresponder.h b/indra/newview/llclassifiedstatsresponder.h
index 3db1868cb2860c8084ba8594e8ba80ab756c3de4..06dcb62fd055e6ad4fadf8ccdae343e01602c920 100644
--- a/indra/newview/llclassifiedstatsresponder.h
+++ b/indra/newview/llclassifiedstatsresponder.h
@@ -39,7 +39,7 @@ class LLClassifiedStatsResponder : public LLHTTPClient::Responder
 	virtual void result(const LLSD& content);
 	//If we get back an error (not found, etc...), handle it here
 	
-	virtual void error(U32 status, const std::string& reason);
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 
 protected:
 	LLUUID mClassifiedID;
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index e9c7a3fa0394691089d183e97a3663c4f41de137..e86d6930e89025c04ebb19a369fdb2f99758c89a 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -139,8 +139,7 @@ class CofAttachmentContextMenu : public CofContextMenu
 	{
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 
-		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
-		registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, mUUIDs));
+		registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
 
 		return createFromFile("menu_cof_attachment.xml");
 	}
@@ -173,9 +172,8 @@ class CofClothingContextMenu : public CofContextMenu
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
 		LLUUID selected_id = mUUIDs.back();
-		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
 
-		registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs));
+		registrar.add("Clothing.TakeOff", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
 		registrar.add("Clothing.Replace", boost::bind(replaceWearable, selected_id));
 		registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));
 		registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id));
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index 5b942f283afc49c8619845e97a6bcc8c5e884771..f1f7da5fd1f7f5865b5330578588c4fee9129656 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -241,8 +241,8 @@ void LLColorSwatchCtrl::draw()
 	{
 		if (!mFallbackImageName.empty())
 		{
-			LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, TRUE, 
-				LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+			LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, FTT_LOCAL_FILE, TRUE, 
+				LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 			if( fallback_image->getComponents() == 4 )
 			{	
 				gl_rect_2d_checkerboard( interior );
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 4f5f9e22b69ddfe6ef1256d37bd945ec07b6789b..458842447459c0a2391e6a1d21654a5e88aa87a3 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -161,18 +161,6 @@ BOOL LLFloaterScriptQueue::start()
 {
 	std::string buffer;
 
-	LLSelectMgr *mgr = LLSelectMgr::getInstance();
-	LLObjectSelectionHandle selectHandle = mgr->getSelection();
-	U32 n_objects = 0;
-	if (gSavedSettings.getBOOL("EditLinkedParts"))
-	{
-		n_objects = selectHandle->getObjectCount();
-	}
-	else
-	{
-		n_objects = selectHandle->getRootObjectCount();
-	}
-
 	LLStringUtil::format_map_t args;
 	args["[START]"] = mStartString;
 	args["[COUNT]"] = llformat ("%d", mObjectIDs.count());
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index 1e03582a29176f2fb11c06baebfd7bde3f3ae7c6..d7d9f8291068d8d29946fff7cb9aef7a4f91bfe7 100644
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -327,6 +327,8 @@ BOOL LLDirPicker::getDir(std::string* filename)
 		return FALSE;
 	}
 
+#if !LL_MESA_HEADLESS
+
 	if (mFilePicker)
 	{
 		GtkWindow* picker = mFilePicker->buildFilePicker(false, true,
@@ -340,6 +342,8 @@ BOOL LLDirPicker::getDir(std::string* filename)
 		   return (!mFilePicker->getFirstFile().empty());
 		}
 	}
+#endif // !LL_MESA_HEADLESS
+
 	return FALSE;
 }
 
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index 4b0d3b361d55368130ede7598cd1a9d3805670df..bb1d263670d3504b96796793ec358ae305a8bb0e 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -511,7 +511,6 @@ F32 LLDrawable::updateXform(BOOL undamped)
 	//scaling
 	LLVector3 target_scale = mVObjp->getScale();
 	LLVector3 old_scale = mCurrentScale;
-	LLVector3 dest_scale = target_scale;
 	
 	// Damping
 	F32 dist_squared = 0.f;
@@ -1237,7 +1236,6 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
 	LLCamera ret = camera;
 	LLXformMatrix* mat = mDrawable->getXform();
 	LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix();
-	LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix());
 
 	LLVector3 delta = ret.getOrigin() - center;
 	LLQuaternion rot = ~mat->getRotation();
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 1b0b11298c302d0b95c8ed48ec56532d7c001ed1..e8d43c86312fe6658e19929daec7bbe5ad6987f4 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -153,7 +153,7 @@ void LLStandardBumpmap::addstandard()
 		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label;
 		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = 
 			LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id));	
-		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
+		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::BOOST_BUMP) ;
 		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );
 		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0) ;
 		LLStandardBumpmap::sStandardBumpmapCount++;
@@ -1075,7 +1075,7 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
 			src_image->getHeight() != bump->getHeight())// ||
 			//(LLPipeline::sRenderDeferred && bump->getComponents() != 4))
 		{
-			src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
+			src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ;
 			src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL );
 			src_image->forceToSaveRawImage(0) ;
 		}
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 9bc32fddbdbd641e4b9b1cb82e4482b62fd32122..0adb42428d470ea0c717b1bcdecbeb84607eb79c 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -69,7 +69,8 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
 	sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");
 	sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
 	mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga", 
-													TRUE, LLViewerTexture::BOOST_UI, 
+													FTT_LOCAL_FILE,
+													TRUE, LLGLTexture::BOOST_UI, 
 													LLViewerTexture::FETCHED_TEXTURE,
 													format, int_format,
 													LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb"));
@@ -78,7 +79,8 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
 	mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
 
 	m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c", 
-													TRUE, LLViewerTexture::BOOST_UI, 
+													FTT_LOCAL_FILE,
+													TRUE, LLGLTexture::BOOST_UI, 
 													LLViewerTexture::FETCHED_TEXTURE,
 													format, int_format,
 													LLUUID("38b86f85-2575-52a9-a531-23108d8da837"));
@@ -86,7 +88,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
 	//gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
 	m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
 	
-	mTexturep->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
+	mTexturep->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
 	
 	//gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 }
@@ -170,7 +172,7 @@ void LLDrawPoolTerrain::render(S32 pass)
 	LLVLComposition *compp = regionp->getComposition();
 	for (S32 i = 0; i < 4; i++)
 	{
-		compp->mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
+		compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
 		compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
 	}
 
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 4f6eaa5a5b778b099e53e65cf599ff26d088be7a..5ddc15df42769f22b08dcea0ef1b3a735c6c9f7a 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -66,11 +66,11 @@ LLVector3 LLDrawPoolWater::sLightDir;
 LLDrawPoolWater::LLDrawPoolWater() :
 	LLFacePool(POOL_WATER)
 {
-	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	gGL.getTexUnit(0)->bind(mHBTex[0]) ;
 	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
 
-	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	gGL.getTexUnit(0)->bind(mHBTex[1]);
 	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
 
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index fa42b157a72865276280d6d98e8fe6be6a94d9e8..29ad4f34d25b2378c76772d1b5e59826273f2da1 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -107,7 +107,7 @@ void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum
 	{
 		setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
 	}
-	createGLTexture(0, raw_image, 0, TRUE, LLViewerTexture::DYNAMIC_TEX);
+	createGLTexture(0, raw_image, 0, TRUE, LLGLTexture::DYNAMIC_TEX);
 	setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
 	mGLTexturep->setGLTextureCreated(false);
 }
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index c51e7d1e1a76ff64171cdd483ffc49c5d47c1bb1..d287ae6eebab25d83da53b8aa33bc0f4bb67c140 100644
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -72,8 +72,8 @@ class LLViewerDynamicTexture : public LLViewerTexture
 	
 	/*virtual*/ S8 getType() const ;
 
-	S32			getOriginX()	{ return mOrigin.mX; }
-	S32			getOriginY()	{ return mOrigin.mY; }
+	S32			getOriginX() const	{ return mOrigin.mX; }
+	S32			getOriginY() const	{ return mOrigin.mY; }
 	
 	S32			getSize()		{ return mFullWidth * mFullHeight * mComponents; }
 
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp
index 7ed22d68f6061a1a02cfc44d94bcd2f526f8f85b..2669b0340fbef96ce1b72b8114fda1c77326d13a 100644
--- a/indra/newview/llestateinfomodel.cpp
+++ b/indra/newview/llestateinfomodel.cpp
@@ -65,12 +65,12 @@ void LLEstateInfoModel::sendEstateInfo()
 	}
 }
 
-bool LLEstateInfoModel::getUseFixedSun()			const {	return mFlags & REGION_FLAGS_SUN_FIXED;				}
-bool LLEstateInfoModel::getIsExternallyVisible()	const {	return mFlags & REGION_FLAGS_EXTERNALLY_VISIBLE;	}
-bool LLEstateInfoModel::getAllowDirectTeleport()	const {	return mFlags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT;	}
-bool LLEstateInfoModel::getDenyAnonymous()			const {	return mFlags & REGION_FLAGS_DENY_ANONYMOUS; 		}
-bool LLEstateInfoModel::getDenyAgeUnverified()		const {	return mFlags & REGION_FLAGS_DENY_AGEUNVERIFIED;	}
-bool LLEstateInfoModel::getAllowVoiceChat()			const {	return mFlags & REGION_FLAGS_ALLOW_VOICE;			}
+bool LLEstateInfoModel::getUseFixedSun()			const {	return getFlag(REGION_FLAGS_SUN_FIXED);				}
+bool LLEstateInfoModel::getIsExternallyVisible()	const {	return getFlag(REGION_FLAGS_EXTERNALLY_VISIBLE);	}
+bool LLEstateInfoModel::getAllowDirectTeleport()	const {	return getFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT);	}
+bool LLEstateInfoModel::getDenyAnonymous()			const {	return getFlag(REGION_FLAGS_DENY_ANONYMOUS); 		}
+bool LLEstateInfoModel::getDenyAgeUnverified()		const {	return getFlag(REGION_FLAGS_DENY_AGEUNVERIFIED);	}
+bool LLEstateInfoModel::getAllowVoiceChat()			const {	return getFlag(REGION_FLAGS_ALLOW_VOICE);			}
 
 void LLEstateInfoModel::setUseFixedSun(bool val)			{ setFlag(REGION_FLAGS_SUN_FIXED, 				val);	}
 void LLEstateInfoModel::setIsExternallyVisible(bool val)	{ setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE,		val);	}
@@ -122,9 +122,9 @@ class LLEstateChangeInfoResponder : public LLHTTPClient::Responder
 	}
 
 	// if we get an error response
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		llwarns << "Failed to commit estate info (" << status << "): " << reason << llendl;
+		llwarns << "Failed to commit estate info [status:" << status << "]: " << content << llendl;
 	}
 };
 
@@ -199,18 +199,6 @@ void LLEstateInfoModel::commitEstateInfoDataserver()
 	gAgent.sendMessage();
 }
 
-void LLEstateInfoModel::setFlag(U32 flag, bool val)
-{
-	if (val)
-	{
-		mFlags |= flag;
-	}
-	else
-	{
-		mFlags &= ~flag;
-	}
-}
-
 std::string LLEstateInfoModel::getInfoDump()
 {
 	LLSD dump;
diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h
index 56391eda912f29583a0d5b3251ad12b29049bcf9..538f2f7c756f868fb58a6746da963974e6b40592 100644
--- a/indra/newview/llestateinfomodel.h
+++ b/indra/newview/llestateinfomodel.h
@@ -85,19 +85,38 @@ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
 private:
 	bool commitEstateInfoCaps();
 	void commitEstateInfoDataserver();
-	U32  getFlags() const { return mFlags; }
-	void setFlag(U32 flag, bool val);
+	inline bool getFlag(U64 flag) const;
+	inline void setFlag(U64 flag, bool val);
+	U64  getFlags() const { return mFlags; }
 	std::string getInfoDump();
 
 	// estate info
 	std::string	mName;			/// estate name
 	LLUUID		mOwnerID;		/// estate owner id
 	U32			mID;			/// estate id
-	U32			mFlags;			/// estate flags
+	U64			mFlags;			/// estate flags
 	F32			mSunHour;		/// estate sun hour
 
 	update_signal_t mUpdateSignal; /// emitted when we receive update from sim
 	update_signal_t mCommitSignal; /// emitted when our update gets applied to sim
 };
 
+inline bool LLEstateInfoModel::getFlag(U64 flag) const
+{
+	return ((mFlags & flag) != 0);
+}
+
+inline void LLEstateInfoModel::setFlag(U64 flag, bool val)
+{
+	if (val)
+	{
+		mFlags |= flag;
+	}
+	else
+	{
+		mFlags &= ~flag;
+	}
+}
+
+
 #endif // LL_LLESTATEINFOMODEL_H
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 2c786b7f8be8714ee90e27a76e623eddb84d71a6..e0f7223a8ce745949d1ee8c60df93da53f322f74 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -62,7 +62,7 @@ namespace
 
 		
 		void handleMessage(const LLSD& content);
-		virtual	void error(U32 status, const std::string& reason);
+		virtual	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 		virtual	void result(const LLSD&	content);
 
 		virtual void completedRaw(U32 status,
@@ -187,7 +187,7 @@ namespace
 	}
 
 	//virtual
-	void LLEventPollResponder::error(U32 status, const	std::string& reason)
+	void LLEventPollResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
 		if (mDone) return;
 
@@ -207,13 +207,13 @@ namespace
 										+ mErrorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC
 									, this);
 
-			llwarns << "Unexpected HTTP error.  status: " << status << ", reason: " << reason << llendl;
+			llwarns << "LLEventPollResponder error [status:" << status << "]: " << content << llendl;
 		}
 		else
 		{
-			llwarns <<	"LLEventPollResponder::error: <" << mCount << "> got "
-					<<	status << ": " << reason
-					<<	(mDone ? " -- done"	: "") << llendl;
+			llwarns << "LLEventPollResponder error <" << mCount 
+					<< "> [status:" << status << "]: " << content
+					<< (mDone ? " -- done" : "") << llendl;
 			stop();
 
 			// At this point we have given up and the viewer will not receive HTTP messages from the simulator.
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 28e4b3279303bb8771db59d5b66100a744e6d52b..281f852b0aa26cd885cc2e980ae4958418205690 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -555,8 +555,8 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
 /* removed in lieu of raycast uv detection
 void LLFace::renderSelectedUV()
 {
-	LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLViewerTexture::BOOST_UI);
-	LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLViewerTexture::BOOST_UI);
+	LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLGLTexture::BOOST_UI);
+	LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLGLTexture::BOOST_UI);
 
 	LLGLSUVSelect object_select;
 
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 4dfb93f1bca3359ace15787dc845598b2a710266..fbf72b1a852d5b0411f5475a011a2937f9eba6e0 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -368,7 +368,7 @@ void LLFastTimerView::draw()
 
 	S32 left, top, right, bottom;
 	S32 x, y, barw, barh, dx, dy;
-	S32 texth, textw;
+	S32 texth;
 	LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("Rounded_Square");
 
 	// Draw the window background
@@ -399,7 +399,6 @@ void LLFastTimerView::draw()
 
 		tdesc = llformat("Full bar = %s [Click to pause/reset] [SHIFT-Click to toggle]",modedesc[mDisplayMode]);
 		LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
-		textw = LLFontGL::getFontMonospace()->getWidth(tdesc);
 
 		x = xleft, y -= (texth + 2);
 		tdesc = llformat("Justification = %s [CTRL-Click to toggle]",centerdesc[mDisplayCenter]);
@@ -526,8 +525,6 @@ void LLFastTimerView::draw()
 
 			y -= (texth + 2);
 
-			textw = dx + LLFontGL::getFontMonospace()->getWidth(idp->getName()) + 40;
-
 			if (idp->getCollapsed()) 
 			{
 				it.skipDescendants();
@@ -1073,7 +1070,7 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
 	{ //read base log into memory
 		S32 i = 0;
 		std::ifstream is(base.c_str());
-		while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+		while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
 		{
 			base_data[i++] = cur;
 		}
@@ -1086,7 +1083,7 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
 	{ //read current log into memory
 		S32 i = 0;
 		std::ifstream is(target.c_str());
-		while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+		while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
 		{
 			cur_data[i++] = cur;
 
@@ -1377,7 +1374,7 @@ LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is)
 	stats_map_t time_stats;
 	stats_map_t sample_stats;
 
-	while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+	while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
 	{
 		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
 		{
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index e30dd51acbd0c69e1501bc29ae794f9e12a3019b..6d90667194fd3a8bb3ad7ca9508fe9495e3a1501 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -1649,7 +1649,6 @@ void LLFavoritesOrderStorage::saveItemsOrder( const LLInventoryModel::item_array
 
 	gInventory.notifyObservers();
 }
-
 // See also LLInventorySort where landmarks in the Favorites folder are sorted.
 class LLViewerInventoryItemSort
 {
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index e000adc4aa4adadb1585e35d6e4c2d6b5f817118..f06e9b9b6459c18766d6605d26644a3b098d7dba 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -161,7 +161,7 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 
 	boost::signals2::connection mEndDragConnection;
 };
-
+/*
 class AddFavoriteLandmarkCallback : public LLInventoryCallback
 {
 public:
@@ -173,7 +173,7 @@ class AddFavoriteLandmarkCallback : public LLInventoryCallback
 
 	LLUUID mTargetLandmarkId;
 };
-
+*/
 /**
  * Class to store sorting order of favorites landmarks in a local file. EXT-3985.
  * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix.
@@ -272,5 +272,4 @@ class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
 	};
 
 };
-
 #endif // LL_LLFAVORITESBARCTRL_H
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 4bf5b26b3b0794f213ee116d17f6fae3440bfcf1..d13f85baa2ec0b2fd309dee63d6b2dcd67ffe2f9 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -1103,6 +1103,7 @@ void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer
 
 GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context)
 {
+#ifndef LL_MESA_HEADLESS
 	if (LLWindowSDL::ll_try_gtk_init())
 	{
 		GtkWidget *win = NULL;
@@ -1174,6 +1175,9 @@ GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::stri
 	{
 		return NULL;
 	}
+#else
+	return NULL;
+#endif //LL_MESA_HEADLESS
 }
 
 static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter,
@@ -1473,7 +1477,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
 	return FALSE;
 }
 
-BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
+BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
 {
 	// if local file browsing is turned off, return without opening dialog
 	// (Even though this is a stub, I think we still should not return anything at all)
@@ -1494,7 +1498,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
 	default: break;
 	}
 	mFiles.push_back(filename);
-	llinfos << "getOpenFile: Will try to open file: " << hackyfilename << llendl;
+	llinfos << "getOpenFile: Will try to open file: " << filename << llendl;
 	return TRUE;
 }
 
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index a5ee4607a101c6b04c35df538681dc986f53f4ca..caad0afec054069262a9f4672bf55018c9aae67b 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -270,9 +270,6 @@ void LLVolumeImplFlexible::setAttributesOfAllSections(LLVector3* inScale)
 	mSection[0].mVelocity.setVec(0,0,0);
 	mSection[0].mAxisRotation.setQuat(begin_rot,0,0,1);
 
-	LLVector3 parentSectionPosition = mSection[0].mPosition;
-	LLVector3 last_direction = mSection[0].mDirection;
-
 	remapSections(mSection, mInitializedRes, mSection, mSimulateRes);
 	mInitializedRes = mSimulateRes;
 
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index 2939d31087efdfa0466c4071bcc8b6f2adc5fd0f..3c40e2d4bccde545327912fbb3a9793c3b04eb00 100644
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -38,6 +38,7 @@
 #include "message.h"
 
 #include "llagent.h"
+#include "llassetstorage.h"
 #include "llcombobox.h"
 #include "llestateinfomodel.h"
 #include "llmimetypes.h"
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index f7dd4a4a6be2b2bb16de5c758a2604f9d189b073..3e0e82b579e7de0a5d3bfc856689ae061b847c28 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -483,8 +483,7 @@ class LLAvatarPickerResponder : public LLHTTPClient::Responder
 		}
 		else
 		{
-			llinfos << "avatar picker failed " << status
-					<< " reason " << reason << llendl;
+			llwarns << "avatar picker failed [status:" << status << "]: " << content << llendl;
 			
 		}
 	}
diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp
index 4e10b4fc2c0d31f6fa2e34b953aafcc427cda5fc..048837acfec375183044c66715028ca0502bf946 100644
--- a/indra/newview/llfloateravatartextures.cpp
+++ b/indra/newview/llfloateravatartextures.cpp
@@ -32,12 +32,13 @@
 
 #include "llagent.h"
 #include "llagentwearables.h"
+#include "llviewerwearable.h"
 #include "lltexturectrl.h"
 #include "lluictrlfactory.h"
 #include "llviewerobjectlist.h"
 #include "llvoavatarself.h"
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLSD& id)
   : LLFloater(id),
@@ -53,7 +54,7 @@ BOOL LLFloaterAvatarTextures::postBuild()
 {
 	for (U32 i=0; i < TEX_NUM_INDICES; i++)
 	{
-		const std::string tex_name = LLVOAvatarDictionary::getInstance()->getTexture(ETextureIndex(i))->mName;
+		const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(ETextureIndex(i))->mName;
 		mTextures[i] = getChild<LLTextureCtrl>(tex_name);
 	}
 	mTitle = getTitle();
@@ -75,13 +76,13 @@ static void update_texture_ctrl(LLVOAvatar* avatarp,
 								 ETextureIndex te)
 {
 	LLUUID id = IMG_DEFAULT_AVATAR;
-	const LLVOAvatarDictionary::TextureEntry* tex_entry = LLVOAvatarDictionary::getInstance()->getTexture(te);
+	const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture(te);
 	if (tex_entry->mIsLocalTexture)
 	{
 		if (avatarp->isSelf())
 		{
 			const LLWearableType::EType wearable_type = tex_entry->mWearableType;
-			LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0);
+			LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);
 			if (wearable)
 			{
 				LLLocalTextureObject *lto = wearable->getLocalTextureObject(te);
@@ -163,17 +164,17 @@ void LLFloaterAvatarTextures::onClickDump(void* data)
 			const LLTextureEntry* te = avatarp->getTE(i);
 			if (!te) continue;
 
-			const LLVOAvatarDictionary::TextureEntry* tex_entry = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)(i));
+			const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)(i));
 			if (!tex_entry)
 				continue;
 
 			if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i))
 			{
 				LLUUID id = IMG_DEFAULT_AVATAR;
-				LLWearableType::EType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType((ETextureIndex)i);
+				LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType((ETextureIndex)i);
 				if (avatarp->isSelf())
 				{
-					LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0);
+					LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);
 					if (wearable)
 					{
 						LLLocalTextureObject *lto = wearable->getLocalTextureObject(i);
diff --git a/indra/newview/llfloateravatartextures.h b/indra/newview/llfloateravatartextures.h
index 85ff545855ecc67e504a8bc319864feae72cc688..02474a10e15d2fc255e86f59df8d9a23eb6504d8 100644
--- a/indra/newview/llfloateravatartextures.h
+++ b/indra/newview/llfloateravatartextures.h
@@ -30,7 +30,7 @@
 #include "llfloater.h"
 #include "lluuid.h"
 #include "llstring.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
 
 class LLTextureCtrl;
 
@@ -51,7 +51,7 @@ class LLFloaterAvatarTextures : public LLFloater
 private:
 	LLUUID	mID;
 	std::string mTitle;
-	LLTextureCtrl* mTextures[LLVOAvatarDefines::TEX_NUM_INDICES];
+	LLTextureCtrl* mTextures[LLAvatarAppearanceDefines::TEX_NUM_INDICES];
 };
 
 #endif
diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp
index fffd724b221111556406b5cc80fe336e508cb855..aa6ace2a616a072d359ab934cf8d9f97e0c00d3c 100644
--- a/indra/newview/llfloaterbuycontents.cpp
+++ b/indra/newview/llfloaterbuycontents.cpp
@@ -40,6 +40,7 @@
 #include "llcheckboxctrl.h"
 #include "llinventorydefines.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"	// for gInventory
 #include "llfirstuse.h"
 #include "llfloaterreg.h"
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 8223e89b64752078a0d5b6442c623b4b3b8f32d9..42857b2aa21d91f2622b28e328c40edca12d3d1f 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -538,7 +538,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo()
 	LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
 	if (resellable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+		if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
 		{
 			resellable_clause->setText(getString("can_not_resell"));
 		}
@@ -551,7 +551,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo()
 	LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
 	if (changeable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+		if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
 		{
 			changeable_clause->setText(getString("can_change"));
 		}
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index 62848586cdbb1438589b502fc5312f18e2d0c8d4..f2deb6a805e5083fe78e54ffef0daa2464bfc877 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -1102,12 +1102,12 @@ BOOL	LLPreviewAnimation::render()
 
 	gGL.flush();
 
-	LLVector3 target_pos = avatarp->mRoot.getWorldPosition();
+	LLVector3 target_pos = avatarp->mRoot->getWorldPosition();
 
 	LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * 
 		LLQuaternion(mCameraYaw, LLVector3::z_axis);
 
-	LLQuaternion av_rot = avatarp->mRoot.getWorldRotation() * camera_rot;
+	LLQuaternion av_rot = avatarp->mRoot->getWorldRotation() * camera_rot;
 	LLViewerCamera::getInstance()->setOriginAndLookAt(
 		target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot),		// camera
 		LLVector3::z_axis,																	// up
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index 38abdcc8307db33c0436d32f3a75965a8a7a6b63..fe6223fbf53598f804b21495d561d6430c2beec9 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -164,9 +164,9 @@ LLFloaterGodTools::~LLFloaterGodTools()
 }
 
 
-U32 LLFloaterGodTools::computeRegionFlags() const
+U64 LLFloaterGodTools::computeRegionFlags() const
 {
-	U32 flags = gAgent.getRegion()->getRegionFlags();
+	U64 flags = gAgent.getRegion()->getRegionFlags();
 	if (mPanelRegionTools) flags = mPanelRegionTools->computeRegionFlags(flags);
 	if (mPanelObjectTools) flags = mPanelObjectTools->computeRegionFlags(flags);
 	return flags;
@@ -210,7 +210,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
 	if (!msg) return;
 
 	//const S32 SIM_NAME_BUF = 256;
-	U32 region_flags;
+	U64 region_flags;
 	U8 sim_access;
 	U8 agent_limit;
 	std::string sim_name;
@@ -231,13 +231,23 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
 	msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, sim_name);
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, estate_id);
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, parent_estate_id);
-	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, region_flags);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, sim_access);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, agent_limit);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, object_bonus_factor);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor, billable_factor);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
 
+	if (msg->has(_PREHASH_RegionInfo3))
+	{
+		msg->getU64Fast(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended, region_flags);
+	}
+	else
+	{
+		U32 flags = 0;
+		msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
+		region_flags = flags;
+	}
+
 	if (host != gAgent.getRegionHost())
 	{
 		// Update is for a different region than the one we're in.
@@ -341,6 +351,7 @@ void LLFloaterGodTools::sendGodUpdateRegionInfo()
 		LLMessageSystem *msg = gMessageSystem;
 		LLPanelRegionTools *rtool = god_tools->mPanelRegionTools;
 
+		U64 region_flags = computeRegionFlags();
 		msg->newMessage("GodUpdateRegionInfo");
 		msg->nextBlockFast(_PREHASH_AgentData);
 		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
@@ -349,11 +360,14 @@ void LLFloaterGodTools::sendGodUpdateRegionInfo()
 		msg->addStringFast(_PREHASH_SimName, rtool->getSimName());
 		msg->addU32Fast(_PREHASH_EstateID, rtool->getEstateID());
 		msg->addU32Fast(_PREHASH_ParentEstateID, rtool->getParentEstateID());
-		msg->addU32Fast(_PREHASH_RegionFlags, computeRegionFlags());
+		// Legacy flags
+		msg->addU32Fast(_PREHASH_RegionFlags, U32(region_flags));
 		msg->addF32Fast(_PREHASH_BillableFactor, rtool->getBillableFactor());
 		msg->addS32Fast(_PREHASH_PricePerMeter, rtool->getPricePerMeter());
 		msg->addS32Fast(_PREHASH_RedirectGridX, rtool->getRedirectGridX());
 		msg->addS32Fast(_PREHASH_RedirectGridY, rtool->getRedirectGridY());
+		msg->nextBlockFast(_PREHASH_RegionInfo2);
+		msg->addU64Fast(_PREHASH_RegionFlagsExtended, region_flags);
 
 		gAgent.sendReliableMessage();
 	}
@@ -434,7 +448,7 @@ LLPanelRegionTools::~LLPanelRegionTools()
 	// base class will take care of everything
 }
 
-U32 LLPanelRegionTools::computeRegionFlags(U32 flags) const
+U64 LLPanelRegionTools::computeRegionFlags(U64 flags) const
 {
 	flags &= getRegionFlagsMask();
 	flags |= getRegionFlags();
@@ -562,9 +576,9 @@ S32 LLPanelRegionTools::getGridPosY() const
 	return getChild<LLUICtrl>("gridposy")->getValue().asInteger();
 }
 
-U32 LLPanelRegionTools::getRegionFlags() const
+U64 LLPanelRegionTools::getRegionFlags() const
 {
-	U32 flags = 0x0;
+	U64 flags = 0x0;
 	flags = getChild<LLUICtrl>("check prelude")->getValue().asBoolean()  
 					? set_prelude_flags(flags)
 					: unset_prelude_flags(flags);
@@ -601,9 +615,9 @@ U32 LLPanelRegionTools::getRegionFlags() const
 	return flags;
 }
 
-U32 LLPanelRegionTools::getRegionFlagsMask() const
+U64 LLPanelRegionTools::getRegionFlagsMask() const
 {
-	U32 flags = 0xffffffff;
+	U64 flags = 0xFFFFFFFFFFFFFFFFULL;
 	flags = getChild<LLUICtrl>("check prelude")->getValue().asBoolean()
 				? set_prelude_flags(flags)
 				: unset_prelude_flags(flags);
@@ -684,7 +698,7 @@ void LLPanelRegionTools::setParentEstateID(U32 id)
 	getChild<LLUICtrl>("parentestate")->setValue((S32)id);
 }
 
-void LLPanelRegionTools::setCheckFlags(U32 flags)
+void LLPanelRegionTools::setCheckFlags(U64 flags)
 {
 	getChild<LLUICtrl>("check prelude")->setValue(is_prelude(flags) ? TRUE : FALSE);
 	getChild<LLUICtrl>("check fixed sun")->setValue(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE);
@@ -943,7 +957,7 @@ void LLPanelObjectTools::refresh()
 }
 
 
-U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const
+U64 LLPanelObjectTools::computeRegionFlags(U64 flags) const
 {
 	if (getChild<LLUICtrl>("disable scripts")->getValue().asBoolean())
 	{
@@ -973,7 +987,7 @@ U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const
 }
 
 
-void LLPanelObjectTools::setCheckFlags(U32 flags)
+void LLPanelObjectTools::setCheckFlags(U64 flags)
 {
 	getChild<LLUICtrl>("disable scripts")->setValue(flags & REGION_FLAGS_SKIP_SCRIPTS ? TRUE : FALSE);
 	getChild<LLUICtrl>("disable collisions")->setValue(flags & REGION_FLAGS_SKIP_COLLISIONS ? TRUE : FALSE);
diff --git a/indra/newview/llfloatergodtools.h b/indra/newview/llfloatergodtools.h
index 1aa8b838fb70516acdcc5420e8f1424caa6a1663..cbaeee705180dbf3cdec361e1017a22e5b059d86 100644
--- a/indra/newview/llfloatergodtools.h
+++ b/indra/newview/llfloatergodtools.h
@@ -98,7 +98,7 @@ class LLFloaterGodTools
 	~LLFloaterGodTools();
 	
 protected:
-	U32 computeRegionFlags() const;
+	U64 computeRegionFlags() const;
 
 protected:
 
@@ -147,8 +147,8 @@ class LLPanelRegionTools
 	const std::string getSimName() const;
 	U32 getEstateID() const;
 	U32 getParentEstateID() const;
-	U32 getRegionFlags() const;
-	U32 getRegionFlagsMask() const;
+	U64 getRegionFlags() const;
+	U64 getRegionFlagsMask() const;
 	F32 getBillableFactor() const;
 	S32 getPricePerMeter() const;
 	S32 getGridPosX() const;
@@ -160,7 +160,7 @@ class LLPanelRegionTools
 	void setSimName(const std::string& name);
 	void setEstateID(U32 id);
 	void setParentEstateID(U32 id);
-	void setCheckFlags(U32 flags);
+	void setCheckFlags(U64 flags);
 	void setBillableFactor(F32 billable_factor);
 	void setPricePerMeter(S32 price);
 	void setGridPosX(S32 pos);
@@ -168,7 +168,7 @@ class LLPanelRegionTools
 	void setRedirectGridX(S32 pos);
 	void setRedirectGridY(S32 pos);
 
-	U32 computeRegionFlags(U32 initial_flags) const;
+	U64 computeRegionFlags(U64 initial_flags) const;
 	void clearAllWidgets();
 	void enableAllWidgets();
 
@@ -218,10 +218,10 @@ class LLPanelObjectTools
 	/*virtual*/ void refresh();
 
 	void setTargetAvatar(const LLUUID& target_id);
-	U32 computeRegionFlags(U32 initial_flags) const;
+	U64 computeRegionFlags(U64 initial_flags) const;
 	void clearAllWidgets();
 	void enableAllWidgets();
-	void setCheckFlags(U32 flags);
+	void setCheckFlags(U64 flags);
 
 	void onChangeAnything();
 	void onApplyChanges();
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 2575f6f8172d13c6e32ba39d17390208b535aa39..52e678ce248e651f40be20242586339f461f37d4 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -593,7 +593,7 @@ S8 LLImagePreviewAvatar::getType() const
 
 void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male) 
 { 
-	mTargetJoint = mDummyAvatar->mRoot.findJoint(joint_name);
+	mTargetJoint = mDummyAvatar->mRoot->findJoint(joint_name);
 	// clear out existing test mesh
 	if (mTargetMesh)
 	{
@@ -612,9 +612,9 @@ void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const
 		mDummyAvatar->updateVisualParams();
 		mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
 	}
-	mDummyAvatar->mRoot.setVisible(FALSE, TRUE);
+	mDummyAvatar->mRoot->setVisible(FALSE, TRUE);
 
-	mTargetMesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name);
+	mTargetMesh = dynamic_cast<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));
 	mTargetMesh->setTestTexture(mTextureName);
 	mTargetMesh->setVisible(TRUE, FALSE);
 	mCameraDistance = distance;
@@ -631,7 +631,7 @@ void LLImagePreviewAvatar::clearPreviewTexture(const std::string& mesh_name)
 {
 	if (mDummyAvatar)
 	{
-		LLViewerJointMesh *mesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name);
+		LLViewerJointMesh *mesh = dynamic_cast<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));
 		// clear out existing test mesh
 		if (mesh)
 		{
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 7296ec3cedadf17b12a498628b06895c1a7d2e59..58817485fb564dac0ff0296ec12aa73c7d299de4 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -585,6 +585,28 @@ void LLFloaterIMContainer::returnFloaterToHost()
 	floater->onTearOffClicked();
 }
 
+void LLFloaterIMContainer::setMinimized(BOOL b)
+{
+	bool was_minimized = isMinimized();
+	LLMultiFloater::setMinimized(b);
+
+	//Switching from minimized to un-minimized
+	if(was_minimized && !b)
+	{
+		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession);
+
+		if(session_floater && !session_floater->isTornOff())
+		{
+			//When in DND mode, remove stored IM notifications
+			//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+			if(gAgent.isDoNotDisturb() && mSelectedSession.notNull())
+			{
+				LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSelectedSession);
+			}
+		}
+	}
+}
+
 void LLFloaterIMContainer::setVisible(BOOL visible)
 {	LLFloaterIMNearbyChat* nearby_chat;
 	if (visible)
@@ -597,10 +619,21 @@ void LLFloaterIMContainer::setVisible(BOOL visible)
 			// *TODO: find a way to move this to XML as a default panel or something like that
 			LLSD name("nearby_chat");
 			LLFloaterReg::toggleInstanceOrBringToFront(name);
-            setSelectedSession(LLUUID(NULL));
+            selectConversationPair(LLUUID(NULL), false, false);
 		}
 		openNearbyChat();
-        selectConversationPair(getSelectedSession(), false, false);
+		flashConversationItemWidget(mSelectedSession,false);
+
+		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession);
+		if(session_floater && !session_floater->isMinimized())
+		{
+			//When in DND mode, remove stored IM notifications
+			//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+			if(gAgent.isDoNotDisturb() && mSelectedSession.notNull())
+			{
+				LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSelectedSession);
+			}
+		}
 	}
 
 	nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
@@ -1389,13 +1422,6 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
     		widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
     		mConversationsRoot->scrollToShowSelection();
     	}
-
-        //When in DND mode, remove stored IM notifications
-        //Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
-        if(gAgent.isDoNotDisturb() && session_id.notNull())
-        {
-            LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, session_id);
-        }
     }
 
     /* floater processing */
@@ -1420,14 +1446,19 @@ BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool
 			{
 				showStub(true);
 			}
+
+			//When in DND mode, remove stored IM notifications
+			//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+			if(gAgent.isDoNotDisturb() && session_id.notNull())
+			{
+				LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, session_id);
+			}
 		}
 
 		// Set the focus on the selected floater
-		if (!session_floater->hasFocus())
+		if (!session_floater->hasFocus() && !session_floater->isMinimized())
 		{
-			BOOL is_minimized = session_floater->isMinimized();
 			session_floater->setFocus(focus_floater);
-			session_floater->setMinimized(is_minimized);
 		}
 	}
 	flashConversationItemWidget(session_id,false);
@@ -1986,8 +2017,11 @@ void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
 {
 	// Always unminimize before trying to close.
 	// Most of the time the user will never see this state.
-	setMinimized(FALSE);
-
+	if(isMinimized())
+	{
+		LLMultiFloater::setMinimized(FALSE);
+	}
+	
 	LLFloater::closeFloater(app_quitting);
 }
 
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
index 52b672241f614b1539de3f56597ef581aea8118e..e39d20ec35880415da2e381efc7fb9a071f452d2 100644
--- a/indra/newview/llfloaterimcontainer.h
+++ b/indra/newview/llfloaterimcontainer.h
@@ -59,6 +59,7 @@ class LLFloaterIMContainer
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/ void draw();
+	/*virtual*/ void setMinimized(BOOL b);
 	/*virtual*/ void setVisible(BOOL visible);
 	/*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
 	/*virtual*/ void updateResizeLimits();
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index d86e1b3fd7a52a4bbe913473e2c1be07dc8d01fe..49f36a2f321b1b1152a4f4eddf680fb4fff8d84a 100644
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -264,7 +264,7 @@ void LLFloaterIMNearbyChat::setVisibleAndFrontmost(BOOL take_focus, const LLSD&
 
 	if(!isTornOff() && matchesKey(key))
 	{
-		LLFloaterIMContainer::getInstance()->selectConversationPair(mSessionID, true, false);
+		LLFloaterIMContainer::getInstance()->selectConversationPair(mSessionID, true, take_focus);
 	}
 }
 
@@ -328,7 +328,7 @@ void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp)
 void LLFloaterIMNearbyChat::show()
 {
 		openFloater(getKey());
-	}
+}
 
 bool LLFloaterIMNearbyChat::isChatVisible() const
 {
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
index 6d5145f205fc754fb43f1a3c35b0dbbaa85c94ea..8ec85e11602709d7791b9d95c9d08251b8152960 100644
--- a/indra/newview/llfloaterimsession.cpp
+++ b/indra/newview/llfloaterimsession.cpp
@@ -39,6 +39,7 @@
 #include "llchannelmanager.h"
 #include "llchiclet.h"
 #include "llchicletbar.h"
+#include "lldonotdisturbnotificationstorage.h"
 #include "llfloaterreg.h"
 #include "llfloateravatarpicker.h"
 #include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
@@ -645,6 +646,23 @@ void LLFloaterIMSession::setDocked(bool docked, bool pop_on_undock)
 	}
 }
 
+void LLFloaterIMSession::setMinimized(BOOL b)
+{
+	bool wasMinimized = isMinimized();
+	LLFloaterIMSessionTab::setMinimized(b);
+
+	//Switching from minimized state to un-minimized state
+	if(wasMinimized && !b)
+	{
+		//When in DND mode, remove stored IM notifications
+		//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+		if(gAgent.isDoNotDisturb())
+		{
+			LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSessionID);
+		}
+	}
+}
+
 void LLFloaterIMSession::setVisible(BOOL visible)
 {
 	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
@@ -713,6 +731,18 @@ BOOL LLFloaterIMSession::getVisible()
 	return visible;
 }
 
+void LLFloaterIMSession::setFocus(BOOL focus)
+{
+	LLFloaterIMSessionTab::setFocus(focus);
+
+	//When in DND mode, remove stored IM notifications
+	//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+	if(focus && gAgent.isDoNotDisturb())
+	{
+		LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSessionID);
+	}
+}
+
 //static
 bool LLFloaterIMSession::toggle(const LLUUID& session_id)
 {
@@ -1125,9 +1155,10 @@ class LLSessionInviteResponder : public LLHTTPClient::Responder
 		mSessionID = session_id;
 	}
 
-	void error(U32 statusNum, const std::string& reason)
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 	{
-		llinfos << "Error inviting all agents to session" << llendl;
+		llwarns << "Error inviting all agents to session [status:" 
+				<< statusNum << "]: " << content << llendl;
 		//throw something back to the viewer here?
 	}
 
diff --git a/indra/newview/llfloaterimsession.h b/indra/newview/llfloaterimsession.h
index cb330bca0f25baba9de25f04f702a32c103309aa..a0e0171b344baa322714bc3766e6851f499e7197 100644
--- a/indra/newview/llfloaterimsession.h
+++ b/indra/newview/llfloaterimsession.h
@@ -65,8 +65,10 @@ class LLFloaterIMSession
 
 	// LLView overrides
 	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void setMinimized(BOOL b);
 	/*virtual*/ void setVisible(BOOL visible);
 	/*virtual*/ BOOL getVisible();
+	/*virtual*/ void setFocus(BOOL focus);
 	// Check typing timeout timer.
 
 	/*virtual*/ void draw();
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 0a30fef768e48f85b1bd015f9b945d1af89835b0..8290494c229c7d596e03e1d26e02ee5c839c01c2 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -557,7 +557,7 @@ void LLPanelLandGeneral::refresh()
 		BOOL is_leased = (LLParcel::OS_LEASED == parcel->getOwnershipStatus());
 		BOOL region_xfer = FALSE;
 		if(regionp
-		   && !(regionp->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL))
+		   && !(regionp->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)))
 		{
 			region_xfer = TRUE;
 		}
@@ -2120,7 +2120,7 @@ void LLPanelLandOptions::refreshSearch()
 			LLViewerParcelMgr::isParcelModifiableByAgent(
 				parcel, GP_LAND_CHANGE_IDENTITY)
 			&& region
-			&& !(region->getRegionFlags() & REGION_FLAGS_BLOCK_PARCEL_SEARCH);
+			&& !(region->getRegionFlag(REGION_FLAGS_BLOCK_PARCEL_SEARCH));
 
 	// There is a bug with this panel whereby the Show Directory bit can be 
 	// slammed off by the Region based on an override.  Since this data is cached
@@ -2873,7 +2873,7 @@ void LLPanelLandCovenant::refresh()
 	LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
 	if (resellable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+		if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
 		{
 			resellable_clause->setText(getString("can_not_resell"));
 		}
@@ -2886,7 +2886,7 @@ void LLPanelLandCovenant::refresh()
 	LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
 	if (changeable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+		if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
 		{
 			changeable_clause->setText(getString("can_change"));
 		}
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index ea839e6f5a5023a3e91c5d36cccbaa73a9332c8a..100f1d580b96e0ea05ed425a62e03d799b8cc717 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -760,7 +760,6 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
 void LLFloaterModelPreview::draw()
 {
 	LLFloater::draw();
-	LLRect r = getRect();
 
 	mModelPreview->update();
 
@@ -1684,7 +1683,6 @@ bool LLModelLoader::doLoadModel()
 						
 						//If no skeleton, do a breadth-first search to get at specific joints
 						bool rootNode = false;
-						bool skeletonWithNoRootNode = false;
 						
 						//Need to test for a skeleton that does not have a root node
 						//This occurs when your instance controller does not have an associated scene 
@@ -1695,10 +1693,6 @@ bool LLModelLoader::doLoadModel()
 							{
 								rootNode = true;
 							}
-							else 
-							{
-								skeletonWithNoRootNode = true;
-							}
 
 						}
 						if ( !pSkeleton || !rootNode )
@@ -2502,7 +2496,7 @@ void LLModelLoader::loadTextures()
 				if(!material.mDiffuseMapFilename.empty())
 				{
 					material.mDiffuseMap = 
-						LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW);
+						LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW);
 					material.mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE);
 					material.mDiffuseMap->forceToSaveRawImage(0, F32_MAX);
 					mNumOfFetchingTextures++ ;
@@ -5020,16 +5014,9 @@ BOOL LLModelPreview::render()
 	bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean();	
 	bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean();
 
-	bool resetJoints = false;
 	if ( upload_joints != mLastJointUpdate )
 	{
-		if ( mLastJointUpdate )
-		{
-			resetJoints = true;
-		}
-
 		mLastJointUpdate = upload_joints;
-
 	}
 
 	for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp
index c7fab2573f29dfffaa97471fbad3059ec4b18e93..3a7ca17b73d34d3d71c34bcf090c2e57b87f52d9 100644
--- a/indra/newview/llfloaterregiondebugconsole.cpp
+++ b/indra/newview/llfloaterregiondebugconsole.cpp
@@ -75,7 +75,7 @@ namespace
 	{
 	public:
 		/* virtual */
-		void error(U32 status, const std::string& reason)
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 		{
 			sConsoleReplySignal(UNABLE_TO_SEND_COMMAND);
 		}
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index e6b76159a1947754b3fd76d631b4acb940fab7c9..50c013a49dfa3b479cf8adffada194f5b1a1a2b3 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -318,7 +318,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	// extract message
 	std::string sim_name;
 	std::string sim_type = LLTrans::getString("land_type_unknown");
-	U32 region_flags;
+	U64 region_flags;
 	U8 agent_limit;
 	F32 object_bonus_factor;
 	U8 sim_access;
@@ -328,7 +328,6 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	BOOL use_estate_sun;
 	F32 sun_hour;
 	msg->getString("RegionInfo", "SimName", sim_name);
-	msg->getU32("RegionInfo", "RegionFlags", region_flags);
 	msg->getU8("RegionInfo", "MaxAgents", agent_limit);
 	msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor);
 	msg->getU8("RegionInfo", "SimAccess", sim_access);
@@ -347,6 +346,17 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 		LLTrans::findString(sim_type, sim_type); // try localizing sim product name
 	}
 
+	if (msg->has(_PREHASH_RegionInfo3))
+	{
+		msg->getU64("RegionInfo3", "RegionFlagsExtended", region_flags);
+	}
+	else
+	{
+		U32 flags = 0;
+		msg->getU32("RegionInfo", "RegionFlags", flags);
+		region_flags = flags;
+	}
+
 	// GENERAL PANEL
 	panel = tab->getChild<LLPanel>("General");
 	panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name));
@@ -378,9 +388,9 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	panel = tab->getChild<LLPanel>("Debug");
 
 	panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name) );
-	panel->getChild<LLUICtrl>("disable_scripts_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_SCRIPTS)) );
-	panel->getChild<LLUICtrl>("disable_collisions_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_COLLISIONS)) );
-	panel->getChild<LLUICtrl>("disable_physics_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_PHYSICS)) );
+	panel->getChild<LLUICtrl>("disable_scripts_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_SCRIPTS) ? TRUE : FALSE )) );
+	panel->getChild<LLUICtrl>("disable_collisions_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_COLLISIONS) ? TRUE : FALSE )) );
+	panel->getChild<LLUICtrl>("disable_physics_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_PHYSICS) ? TRUE : FALSE )) );
 	panel->setCtrlsEnabled(allow_modify);
 
 	// TERRAIN PANEL
@@ -748,9 +758,10 @@ class ConsoleRequestResponder : public LLHTTPClient::Responder
 {
 public:
 	/*virtual*/
-	void error(U32 status, const std::string& reason)
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		llwarns << "requesting mesh_rez_enabled failed" << llendl;
+		llwarns << "ConsoleRequestResponder error requesting mesh_rez_enabled [status:"
+				<< status << "]: " << content << llendl;
 	}
 };
 
@@ -760,9 +771,10 @@ class ConsoleUpdateResponder : public LLHTTPClient::Responder
 {
 public:
 	/* virtual */
-	void error(U32 status, const std::string& reason)
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		llwarns << "Updating mesh enabled region setting failed" << llendl;
+		llwarns << "ConsoleRequestResponder error updating mesh enabled region setting [status:"
+				<< status << "]: " << content << llendl;
 	}
 };
 
@@ -2239,10 +2251,10 @@ class LLEstateChangeInfoResponder : public LLHTTPClient::Responder
 	}
 	
 	// if we get an error response
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		llinfos << "LLEstateChangeInfoResponder::error "
-			<< status << ": " << reason << llendl;
+		llinfos << "LLEstateChangeInfoResponder::error [status:"
+			<< status << "]: " << content << llendl;
 	}
 private:
 	LLHandle<LLPanel> mpPanel;
@@ -2318,7 +2330,7 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)
 	LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
 	if (resellable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+		if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
 		{
 			resellable_clause->setText(getString("can_not_resell"));
 		}
@@ -2331,7 +2343,7 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)
 	LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
 	if (changeable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+		if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
 		{
 			changeable_clause->setText(getString("can_change"));
 		}
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 0e4c7406c581cfe583bebd17b98ba43ec7f59ea9..35b63c54803fde1765942cd98b507c7cf9962daa 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -111,9 +111,6 @@ LLFloaterReporter::LLFloaterReporter(const LLSD& key)
 // static
 void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
 {
-	U32 region_flags;
-	msg->getU32("RegionInfo", "RegionFlags", region_flags);
-	
 	if ( LLFloaterReg::instanceVisible("reporter") )
 	{
 		LLNotificationsUtil::add("HelpReportAbuseEmailLL");
@@ -713,7 +710,7 @@ class LLUserReportResponder : public LLHTTPClient::Responder
 public:
 	LLUserReportResponder(): LLHTTPClient::Responder()  {}
 
-	void error(U32 status, const std::string& reason)
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
 		// *TODO do some user messaging here
 		LLUploadDialog::modalUploadFinished();
@@ -783,8 +780,8 @@ void LLFloaterReporter::takeScreenshot()
 
 	// store in the image list so it doesn't try to fetch from the server
 	LLPointer<LLViewerFetchedTexture> image_in_list = 
-		LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::FETCHED_TEXTURE);
-	image_in_list->createGLTexture(0, raw, 0, TRUE, LLViewerTexture::OTHER);
+		LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid);
+	image_in_list->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER);
 	
 	// the texture picker then uses that texture
 	LLTexturePicker* texture = getChild<LLTextureCtrl>("screenshot");
@@ -831,12 +828,7 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,
 		return;
 	}
 
-	EReportType report_type = UNKNOWN_REPORT;
-	if (data->mPreferredLocation == LLResourceData::INVALID_LOCATION)
-	{
-		report_type = COMPLAINT_REPORT;
-	}
-	else 
+	if (data->mPreferredLocation != LLResourceData::INVALID_LOCATION)
 	{
 		llwarns << "Unknown report type : " << data->mPreferredLocation << llendl;
 	}
diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp
index b691db1049f04756867a7a3cf3b1791207a3ee15..6c17f62c1e862729d5d416781857c1c679244731 100644
--- a/indra/newview/llfloaterscriptdebug.cpp
+++ b/indra/newview/llfloaterscriptdebug.cpp
@@ -105,7 +105,7 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std:
 
 	if (objectp)
 	{
-		objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", TRUE, LLViewerTexture::BOOST_UI));
+		objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI));
 		floater_label = llformat("%s(%.0f, %.0f, %.0f)",
 						user_name.c_str(),
 						objectp->getPositionRegion().mV[VX],
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index 8d8bba7b179d41c8166a4ec93c23f5cd595c467b..13cb3c2eb00256ad87432ae0710d8a23a71ff251 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -221,9 +221,9 @@ void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content)
 	}
 }
 
-void fetchScriptLimitsRegionInfoResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsRegionInfoResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llwarns << "Error from responder " << reason << llendl;
+	llwarns << "fetchScriptLimitsRegionInfoResponder error [status:" << status << "]: " << content << llendl;
 }
 
 void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)
@@ -308,9 +308,9 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)
 	}
 }
 
-void fetchScriptLimitsRegionSummaryResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsRegionSummaryResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llwarns << "Error from responder " << reason << llendl;
+	llwarns << "fetchScriptLimitsRegionSummaryResponder error [status:" << status << "]: " << content << llendl;
 }
 
 void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content_ref)
@@ -417,9 +417,9 @@ result (map)
 	}
 }
 
-void fetchScriptLimitsRegionDetailsResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsRegionDetailsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llwarns << "Error from responder " << reason << llendl;
+	llwarns << "fetchScriptLimitsRegionDetailsResponder error [status:" << status << "]: " << content << llendl;
 }
 
 void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)
@@ -513,9 +513,9 @@ void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)
 	}
 }
 
-void fetchScriptLimitsAttachmentInfoResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsAttachmentInfoResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llwarns << "Error from responder " << reason << llendl;
+	llwarns << "fetchScriptLimitsAttachmentInfoResponder error [status:" << status << "]: " << content << llendl;
 }
 
 ///----------------------------------------------------------------------------
diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h
index 9bcfa5fe1426ad3aad34d9986306be6c9d3526c4..f8732ef94bb02f14db6c46cf0b2661e24953eb50 100644
--- a/indra/newview/llfloaterscriptlimits.h
+++ b/indra/newview/llfloaterscriptlimits.h
@@ -89,7 +89,7 @@ class fetchScriptLimitsRegionInfoResponder: public LLHTTPClient::Responder
 		fetchScriptLimitsRegionInfoResponder(const LLSD& info) : mInfo(info) {};
 
 		void result(const LLSD& content);
-		void error(U32 status, const std::string& reason);
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	public:
 	protected:
 		LLSD mInfo;
@@ -101,7 +101,7 @@ class fetchScriptLimitsRegionSummaryResponder: public LLHTTPClient::Responder
 		fetchScriptLimitsRegionSummaryResponder(const LLSD& info) : mInfo(info) {};
 
 		void result(const LLSD& content);
-		void error(U32 status, const std::string& reason);
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	public:
 	protected:
 		LLSD mInfo;
@@ -113,7 +113,7 @@ class fetchScriptLimitsRegionDetailsResponder: public LLHTTPClient::Responder
 		fetchScriptLimitsRegionDetailsResponder(const LLSD& info) : mInfo(info) {};
 
 		void result(const LLSD& content);
-		void error(U32 status, const std::string& reason);
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	public:
 	protected:
 		LLSD mInfo;
@@ -125,7 +125,7 @@ class fetchScriptLimitsAttachmentInfoResponder: public LLHTTPClient::Responder
 		fetchScriptLimitsAttachmentInfoResponder() {};
 
 		void result(const LLSD& content);
-		void error(U32 status, const std::string& reason);
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	public:
 	protected:
 };
diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp
index 96b5c6b09bd30e1b20286cc51d10073acb9d4e76..5f9556a870d66810af487f69807501b362bf54c9 100644
--- a/indra/newview/llfloatersidepanelcontainer.cpp
+++ b/indra/newview/llfloatersidepanelcontainer.cpp
@@ -28,10 +28,13 @@
 
 #include "llfloaterreg.h"
 #include "llfloatersidepanelcontainer.h"
+#include "llpaneleditwearable.h"
 
 // newview includes
 #include "llsidetraypanelcontainer.h"
 #include "lltransientfloatermgr.h"
+#include "llpaneloutfitedit.h"
+#include "llsidepanelappearance.h"
 
 //static
 const std::string LLFloaterSidePanelContainer::sMainPanelName("main_panel");
@@ -54,6 +57,27 @@ void LLFloaterSidePanelContainer::onOpen(const LLSD& key)
 	getChild<LLPanel>(sMainPanelName)->onOpen(key);
 }
 
+void LLFloaterSidePanelContainer::onClickCloseBtn()
+{
+	LLPanelOutfitEdit* panel_outfit_edit =
+		dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfit_edit"));
+	if (panel_outfit_edit)
+	{
+		LLFloater *parent = gFloaterView->getParentFloater(panel_outfit_edit);
+		if (parent == this )
+		{
+			LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance*>(getPanel("appearance"));
+			if ( panel_appearance )
+			{
+				panel_appearance->getWearable()->onClose();
+				panel_appearance->showOutfitsInventoryPanel();
+			}
+		}
+	}
+	
+	LLFloater::onClickCloseBtn();
+}
+
 LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_name, const LLSD& params)
 {
 	LLView* view = findChildView(panel_name, true);
diff --git a/indra/newview/llfloatersidepanelcontainer.h b/indra/newview/llfloatersidepanelcontainer.h
index 10d85867ce5807e7fa0ab2ef5e09de5d3d7fc039..491723471fb1109211764fe9b6757234071b9cf4 100644
--- a/indra/newview/llfloatersidepanelcontainer.h
+++ b/indra/newview/llfloatersidepanelcontainer.h
@@ -51,6 +51,8 @@ class LLFloaterSidePanelContainer : public LLFloater
 
 	/*virtual*/ void onOpen(const LLSD& key);
 
+	/*virtual*/ void onClickCloseBtn();
+
 	LLPanel* openChildPanel(const std::string& panel_name, const LLSD& params);
 
 	static void showPanel(const std::string& floater_name, const LLSD& key);
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 15e0b89f6ccb970cd37e91133cd2c1bc3baa5ae9..0106a1615d3b31aee80b08e693b41e0af2825fa6 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -855,7 +855,6 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID)
 		LLPanel* panel = LLUICtrlFactory::create<LLPanel>(panel_params);	// create a new panel
 
 		panel->buildFromFile(path);										// build it
-		LLRect new_size = panel->getRect();								// get its rectangle
 		panel->setOrigin(2,2);											// reset its origin point so it's not offset by -left or other XUI attributes
 		(*floaterp)->setTitle(path);									// use the file name as its title, since panels have no guaranteed meaningful name attribute
 		panel->setUseBoundingRect(TRUE);								// enable the use of its outer bounding rect (normally disabled because it's O(n) on the number of sub-elements)
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index a4dfd9449678a332be1a98fa69196bf0e9d75f01..5c6ce9d311df02207c2f1edd8bb80bf293f9981a 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -521,7 +521,7 @@ class CreateFriendCardCallback : public LLInventoryCallback
 	void fire(const LLUUID& inv_item_id)
 	{
 		LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
-
+		
 		if (item)
 			LLFriendCardsManager::instance().extractAvatarID(item->getCreatorUUID());
 	}
@@ -557,7 +557,7 @@ void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
 		lldebugs << "Sent create_inventory_item for " << avatarID << ", " << name << llendl;
 
 		// TODO: mantipov: Is CreateFriendCardCallback really needed? Probably not
-		LLPointer<LLInventoryCallback> cb = new CreateFriendCardCallback();
+		LLPointer<LLInventoryCallback> cb = new CreateFriendCardCallback;
 
 		create_inventory_callingcard(avatarID, findFriendAllSubfolderUUIDImpl(), cb);
 	}
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index f307505ff80b08697e6fd4517df75b8c65b3bb5d..9aa86297fc084808db2f7eb95a3cb10fd5e887c1 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -338,7 +338,7 @@ void LLGestureMgr::deactivateGesture(const LLUUID& item_id)
 
 	gAgent.sendReliableMessage();
 
-	LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id, false);
+	LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id);
 
 	notifyObservers();
 }
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 1208c9378e9024f84582c879eed315a5b7f1c597..60fa53f491c1d94b9d6e2018a5a1e330f2eb4260 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -79,10 +79,10 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 	S32 top =	llmax(y, mDragStartY);
 	S32 bottom =llmin(y, mDragStartY);
 
-	left = llround((F32) left * LLUI::sGLScaleFactor.mV[VX]);
-	right = llround((F32) right * LLUI::sGLScaleFactor.mV[VX]);
-	top = llround((F32) top * LLUI::sGLScaleFactor.mV[VY]);
-	bottom = llround((F32) bottom * LLUI::sGLScaleFactor.mV[VY]);
+	left = llround((F32) left * LLUI::getScaleFactor().mV[VX]);
+	right = llround((F32) right * LLUI::getScaleFactor().mV[VX]);
+	top = llround((F32) top * LLUI::getScaleFactor().mV[VY]);
+	bottom = llround((F32) bottom * LLUI::getScaleFactor().mV[VY]);
 
 	F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
 	F32 old_near_plane = LLViewerCamera::getInstance()->getNear();
diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp
index 188c4bcf25a8ce9a473bcc9e79e22e17cafa0e86..2d0fc26c2a140e69a6210e55cd3a0470f9b6c4b1 100644
--- a/indra/newview/llgroupiconctrl.cpp
+++ b/indra/newview/llgroupiconctrl.cpp
@@ -29,6 +29,7 @@
 #include "llgroupiconctrl.h"
 
 #include "llagent.h"
+#include "llviewertexture.h"
 /*
 #include "llavatarconstants.h"
 #include "llcallingcard.h" // for LLAvatarTracker
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 81eb1d397e822a00bd3c7502120bd133c4d4990a..cbd844cdac07743deb4a444a3a602a5b5b44cdf3 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1847,14 +1847,15 @@ class GroupMemberDataResponder : public LLHTTPClient::Responder
 		GroupMemberDataResponder() {}
 		virtual ~GroupMemberDataResponder() {}
 		virtual void result(const LLSD& pContent);
-		virtual void error(U32 pStatus, const std::string& pReason);
+		virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 private:
 		LLSD mMemberData;
 };
 
-void GroupMemberDataResponder::error(U32 pStatus, const std::string& pReason)
+void GroupMemberDataResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
 {
-	LL_WARNS("GrpMgr") << "Error receiving group member data." << LL_ENDL;
+	LL_WARNS("GrpMgr") << "Error receiving group member data [status:" 
+		<< pStatus << "]: " << pContent << LL_ENDL;
 }
 
 void GroupMemberDataResponder::result(const LLSD& content)
diff --git a/indra/newview/llhomelocationresponder.cpp b/indra/newview/llhomelocationresponder.cpp
index 4850d18d994004c0599f9e6f58258579cfa95970..37428c4a44b5769885613c4ffc247f0c3b63b5a4 100644
--- a/indra/newview/llhomelocationresponder.cpp
+++ b/indra/newview/llhomelocationresponder.cpp
@@ -97,7 +97,7 @@ void LLHomeLocationResponder::result( const LLSD& content )
   }
 }
 
-void LLHomeLocationResponder::error( U32 status, const std::string& reason )
+void LLHomeLocationResponder::errorWithContent( U32 status, const std::string& reason, const LLSD& content )
 {
-  llinfos << "received error(" << reason  << ")" << llendl;
+	llwarns << "LLHomeLocationResponder error [status:" << status << "]: " << content << llendl;
 }
diff --git a/indra/newview/llhomelocationresponder.h b/indra/newview/llhomelocationresponder.h
index d640b9c894b4b38a89cfd6c24d14a687d78f1910..9bf4b12c4e9eef85c5e5cbd45de4b9fa220f2f35 100644
--- a/indra/newview/llhomelocationresponder.h
+++ b/indra/newview/llhomelocationresponder.h
@@ -36,7 +36,7 @@
 class LLHomeLocationResponder : public LLHTTPClient::Responder
 {
 	virtual void result( const LLSD& content );
-	virtual void error( U32 status, const std::string& reason );
+	virtual void errorWithContent( U32 status, const std::string& reason, const LLSD& content );
 };
 
 #endif
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index bc3b220dc098d9183782f865469c1e78251e6db0..9dde65ceb6bde7e29301a30405f3c722892de6a0 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -636,7 +636,7 @@ bool LLHUDEffectLookAt::calcTargetPosition()
 			}
 			else
 			{
-				target_rot = target_av->mRoot.getWorldRotation();
+				target_rot = target_av->mRoot->getWorldRotation();
 			}
 		}
 		else // target obj is not an avatar
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 579b6008ae85ad769e63b2bccba042383b3fc8f0..3c6bcd982995b9a19fb34ce228bb7241f5d6d259 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -186,11 +186,8 @@ void LLHUDText::renderText()
 		LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
 	}
 
-	LLVector2 border_scale_vec((F32)border_width / (F32)imagep->getTextureWidth(), (F32)border_height / (F32)imagep->getTextureHeight());
 	LLVector3 width_vec = mWidth * x_pixel_vec;
 	LLVector3 height_vec = mHeight * y_pixel_vec;
-	LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec;
-	LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec;
 
 	mRadius = (width_vec + height_vec).magVec() * 0.5f;
 
@@ -440,7 +437,7 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)
 	LLVector3 x_pixel_vec;
 	LLVector3 y_pixel_vec;
 	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
-	LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec);
+//	LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec);
 //	if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen)
 //	{
 //		// bubble off-screen, so find a spot for it along screen edge
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index c64ecdc47a67a0c475ec37d02bda72bfbe3934ea..59272d721fb6509b19f2a6210b288194357c8026 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -394,9 +394,10 @@ class LLSessionInviteResponder : public LLHTTPClient::Responder
 		mSessionID = session_id;
 	}
 
-	void error(U32 statusNum, const std::string& reason)
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 	{
-		llinfos << "Error inviting all agents to session" << llendl;
+		llwarns << "Error inviting all agents to session [status:" 
+				<< statusNum << "]: " << content << llendl;
 		//throw something back to the viewer here?
 	}
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index e237cb7f9eaf316c0f3827b4192670e6b2e628b2..2c20409381d3331018c0b099d9a45ee7c62eb435 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -175,6 +175,7 @@ void on_new_message(const LLSD& msg)
     enum {CLOSED, NOT_ON_TOP, ON_TOP, ON_TOP_AND_ITEM_IS_SELECTED} conversations_floater_status;
 
 
+
     LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
 	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
 
@@ -182,18 +183,19 @@ void on_new_message(const LLSD& msg)
 	{
 		conversations_floater_status = CLOSED;
 	}
-	else if (!session_floater || !LLFloater::isVisible(session_floater)
-	            || session_floater->isMinimized() || !session_floater->hasFocus())
+	else if (!im_box->hasFocus() &&
+			    !(session_floater && LLFloater::isVisible(session_floater)
+	            && !session_floater->isMinimized() && session_floater->hasFocus()))
 	{
 		conversations_floater_status = NOT_ON_TOP;
 	}
-	else if ((session_floater->hasFocus()) && (im_box->getSelectedSession() == session_id))
+	else if (im_box->getSelectedSession() != session_id)
 	{
-		conversations_floater_status = ON_TOP_AND_ITEM_IS_SELECTED;
+		conversations_floater_status = ON_TOP;
     }
 	else
 	{
-		conversations_floater_status = ON_TOP;
+		conversations_floater_status = ON_TOP_AND_ITEM_IS_SELECTED;
 	}
 
     //  determine user prefs for this session
@@ -226,7 +228,7 @@ void on_new_message(const LLSD& msg)
     // 0. nothing - exit
     if (("none" == user_preferences ||
     		ON_TOP_AND_ITEM_IS_SELECTED == conversations_floater_status)
-    	&& session_floater->isMessagePaneExpanded())
+    	    && session_floater->isMessagePaneExpanded())
     {
     	return;
     }
@@ -1398,7 +1400,7 @@ class LLStartConferenceChatResponder : public LLHTTPClient::Responder
 		mAgents = agents_to_invite;
 	}
 
-	virtual void error(U32 statusNum, const std::string& reason)
+	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 	{
 		//try an "old school" way.
 		if ( statusNum == 400 )
@@ -1410,6 +1412,9 @@ class LLStartConferenceChatResponder : public LLHTTPClient::Responder
 				mAgents);
 		}
 
+		llwarns << "LLStartConferenceChatResponder error [status:"
+				<< statusNum << "]: " << content << llendl;
+
 		//else throw an error back to the client?
 		//in theory we should have just have these error strings
 		//etc. set up in this file as opposed to the IMMgr,
@@ -1555,8 +1560,10 @@ class LLViewerChatterBoxInvitationAcceptResponder :
 		}
 	}
 
-	void error(U32 statusNum, const std::string& reason)
-	{		
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+	{
+		llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:"
+				<< statusNum << "]: " << content << llendl;
 		//throw something back to the viewer here?
 		if ( gIMMgr )
 		{
@@ -2844,6 +2851,8 @@ LLUUID LLIMMgr::addSession(
 	//we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions
 	if (!new_session) return session_id;
 	
+    llinfos << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << llendl;
+    
 	//Per Plan's suggestion commented "explicit offline status warning" out to make Dessie happier (see EXT-3609)
 	//*TODO After February 2010 remove this commented out line if no one will be missing that warning
 	//noteOfflineUsers(session_id, floater, ids);
@@ -2879,6 +2888,8 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
 
 	LLIMModel::getInstance()->clearSession(session_id);
 
+    llinfos << "LLIMMgr::removeSession, session removed, session id = " << session_id << llendl;
+
 	notifyObserverSessionRemoved(session_id);
 }
 
@@ -2896,7 +2907,6 @@ void LLIMMgr::inviteToSession(
 	// voice invite question is different from default only for group call (EXT-7118)
 	std::string question_type = "VoiceInviteQuestionDefault";
 
-	BOOL ad_hoc_invite = FALSE;
 	BOOL voice_invite = FALSE;
 	bool is_linden = LLMuteList::getInstance()->isLinden(caller_name);
 
@@ -2919,13 +2929,11 @@ void LLIMMgr::inviteToSession(
 		//else it's an ad-hoc
 		//and a voice ad-hoc
 		notify_box_type = "VoiceInviteAdHoc";
-		ad_hoc_invite = TRUE;
 		voice_invite = TRUE;
 	}
 	else if ( inv_type == INVITATION_TYPE_IMMEDIATE )
 	{
 		notify_box_type = "InviteAdHoc";
-		ad_hoc_invite = TRUE;
 	}
 
 	LLSD payload;
@@ -3510,10 +3518,9 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 			}
 			std::string buffer = saved + message;
 
-			BOOL is_this_agent = FALSE;
 			if(from_id == gAgentID)
 			{
-				is_this_agent = TRUE;
+				return;
 			}
 			gIMMgr->addMessage(
 				session_id,
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 1e15dc832cd91f8a62c008baa4956252845715f9..9c6db3676f56baf328126c966e249388848c52e2 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -292,6 +292,11 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data)
 	delete mPropertiesRequest;
 	mPropertiesRequest = NULL;
 }
+/*
+prep#
+			virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+				llwarns << "MuteVoiceResponder error [status:" << status << "]: " << content << llendl;
+	*/
 
 void LLInspectAvatar::updateVolumeSlider()
 {
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 0ee78d57bd380cf592b9c002872cb506d2d2b36c..a5043a30acce7fcde10fb3a452515cdcc2a831c2 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -51,6 +51,7 @@
 #include "llclipboard.h"
 #include "llinventorydefines.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"
 #include "llinventorymodelbackgroundfetch.h"
 #include "llinventorypanel.h"
@@ -96,8 +97,6 @@ struct LLMoveInv
 using namespace LLOldEvents;
 
 // Function declarations
-void remove_inventory_category_from_avatar(LLInventoryCategory* category);
-void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id);
 bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
 bool confirm_attachment_rez(const LLSD& notification, const LLSD& response);
 void teleport_via_landmark(const LLUUID& asset_id);
@@ -1545,7 +1544,7 @@ LLUIImagePtr LLItemBridge::getIcon() const
 										mIsLink);
 	}
 	
-	return LLInventoryIcon::getIcon(LLInventoryIcon::ICONNAME_OBJECT);
+	return LLInventoryIcon::getIcon(LLInventoryType::ICONNAME_OBJECT);
 }
 
 LLUIImagePtr LLItemBridge::getIconOverlay() const
@@ -2649,7 +2648,6 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
 	if(drop && accept)
 	{
 		it = inventory_objects.begin();
-		LLInventoryObject::object_list_t::iterator first_it = inventory_objects.begin();
 		LLMoveInv* move_inv = new LLMoveInv;
 		move_inv->mObjectID = object_id;
 		move_inv->mCategoryID = category_id;
@@ -2926,7 +2924,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 		LLViewerInventoryCategory* cat = getCategory();
 		if(!cat) return;
 
-		remove_inventory_category_from_avatar ( cat );
+		LLAppearanceMgr::instance().takeOffOutfit( cat->getLinkedUUID() );
 		return;
 	}
 	else if ("purge" == action)
@@ -5236,7 +5234,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
 		else if(item && item->isFinished())
 		{
 			// must be in library. copy it to our inventory and put it on.
-			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
+			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
 			copy_inventory_item(
 				gAgent.getID(),
 				item->getPermissions().getOwner(),
@@ -5253,11 +5251,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
 	}
 	else if (isRemoveAction(action))
 	{
-		LLInventoryItem* item = gInventory.getItem(mUUID);
-		if(item)
-		{
-			LLVOAvatarSelf::detachAttachmentIntoInventory(item->getLinkedUUID());
-		}
+		LLAppearanceMgr::instance().removeItemFromAvatar(mUUID);
 	}
 	else LLItemBridge::performAction(model, action);
 }
@@ -5549,120 +5543,6 @@ LLWearableBridge::LLWearableBridge(LLInventoryPanel* inventory,
 	mInvType = inv_type;
 }
 
-void remove_inventory_category_from_avatar( LLInventoryCategory* category )
-{
-	if(!category) return;
-	lldebugs << "remove_inventory_category_from_avatar( " << category->getName()
-			 << " )" << llendl;
-
-
-	if (gAgentCamera.cameraCustomizeAvatar())
-	{
-		// switching to outfit editor should automagically save any currently edited wearable
-		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
-	}
-
-	remove_inventory_category_from_avatar_step2(TRUE, category->getUUID() );
-}
-
-struct OnRemoveStruct
-{
-	LLUUID mUUID;
-	OnRemoveStruct(const LLUUID& uuid):
-		mUUID(uuid)
-	{
-	}
-};
-
-void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id)
-{
-
-	// Find all the wearables that are in the category's subtree.
-	lldebugs << "remove_inventory_category_from_avatar_step2()" << llendl;
-	if(proceed)
-	{
-		LLInventoryModel::cat_array_t cat_array;
-		LLInventoryModel::item_array_t item_array;
-		LLFindWearables is_wearable;
-		gInventory.collectDescendentsIf(category_id,
-										cat_array,
-										item_array,
-										LLInventoryModel::EXCLUDE_TRASH,
-										is_wearable);
-		S32 i;
-		S32 wearable_count = item_array.count();
-
-		LLInventoryModel::cat_array_t	obj_cat_array;
-		LLInventoryModel::item_array_t	obj_item_array;
-		LLIsType is_object( LLAssetType::AT_OBJECT );
-		gInventory.collectDescendentsIf(category_id,
-										obj_cat_array,
-										obj_item_array,
-										LLInventoryModel::EXCLUDE_TRASH,
-										is_object);
-		S32 obj_count = obj_item_array.count();
-
-		// Find all gestures in this folder
-		LLInventoryModel::cat_array_t	gest_cat_array;
-		LLInventoryModel::item_array_t	gest_item_array;
-		LLIsType is_gesture( LLAssetType::AT_GESTURE );
-		gInventory.collectDescendentsIf(category_id,
-										gest_cat_array,
-										gest_item_array,
-										LLInventoryModel::EXCLUDE_TRASH,
-										is_gesture);
-		S32 gest_count = gest_item_array.count();
-
-		if (wearable_count > 0)	//Loop through wearables.  If worn, remove.
-		{
-			for(i = 0; i  < wearable_count; ++i)
-			{
-				LLViewerInventoryItem *item = item_array.get(i);
-				if (item->getType() == LLAssetType::AT_BODYPART)
-					continue;
-				if (gAgent.isTeen() && item->isWearableType() &&
-					(item->getWearableType() == LLWearableType::WT_UNDERPANTS || item->getWearableType() == LLWearableType::WT_UNDERSHIRT))
-					continue;
-				if (get_is_item_worn(item->getUUID()))
-				{
-					LLWearableList::instance().getAsset(item->getAssetUUID(),
-														item->getName(),
-														item->getType(),
-														LLWearableBridge::onRemoveFromAvatarArrived,
-														new OnRemoveStruct(item->getLinkedUUID()));
-				}
-			}
-		}
-
-		if (obj_count > 0)
-		{
-			for(i = 0; i  < obj_count; ++i)
-			{
-				LLViewerInventoryItem *obj_item = obj_item_array.get(i);
-				if (get_is_item_worn(obj_item->getUUID()))
-				{
-					LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID());
-				}
-			}
-		}
-
-		if (gest_count > 0)
-		{
-			for(i = 0; i  < gest_count; ++i)
-			{
-				LLViewerInventoryItem *gest_item = gest_item_array.get(i);
-				if (get_is_item_worn(gest_item->getUUID()))
-				{
-					LLGestureMgr::instance().deactivateGesture( gest_item->getLinkedUUID() );
-					gInventory.updateItem( gest_item );
-					gInventory.notifyObservers();
-				}
-
-			}
-		}
-	}
-}
-
 BOOL LLWearableBridge::renameItem(const std::string& new_name)
 {
 	if (get_is_item_worn(mUUID))
@@ -5873,7 +5753,7 @@ void LLWearableBridge::wearAddOnAvatar()
 }
 
 // static
-void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userdata )
+void LLWearableBridge::onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
 {
 	LLUUID* item_id = (LLUUID*) userdata;
 	if(wearable)
@@ -5899,7 +5779,7 @@ void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userda
 
 // static
 // BAP remove the "add" code path once everything is fully COF-ified.
-void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata )
+void LLWearableBridge::onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
 {
 	LLUUID* item_id = (LLUUID*) userdata;
 	if(wearable)
@@ -5959,95 +5839,12 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data)
 	return FALSE;
 }
 
-// static
-void LLWearableBridge::onRemoveFromAvatar(void* user_data)
-{
-	LLWearableBridge* self = (LLWearableBridge*)user_data;
-	if(!self) return;
-	if(get_is_item_worn(self->mUUID))
-	{
-		LLViewerInventoryItem* item = self->getItem();
-		if (item)
-		{
-			LLUUID parent_id = item->getParentUUID();
-			LLWearableList::instance().getAsset(item->getAssetUUID(),
-												item->getName(),
-												item->getType(),
-												onRemoveFromAvatarArrived,
-												new OnRemoveStruct(LLUUID(self->mUUID)));
-		}
-	}
-}
-
-// static
-void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,
-												 void* userdata)
-{
-	OnRemoveStruct *on_remove_struct = (OnRemoveStruct*) userdata;
-	const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID);
-	if(wearable)
-	{
-		if( get_is_item_worn( item_id ) )
-		{
-			LLWearableType::EType type = wearable->getType();
-
-			if( !(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES ) ) //&&
-				//!((!gAgent.isTeen()) && ( type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT )) )
-			{
-				bool do_remove_all = false;
-				U32 index = gAgentWearables.getWearableIndex(wearable);
-				gAgentWearables.removeWearable( type, do_remove_all, index );
-			}
-		}
-	}
-
-	// Find and remove this item from the COF.
-	LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false);
-	gInventory.notifyObservers();
-
-	delete on_remove_struct;
-}
-
-// static
-void LLWearableBridge::removeAllClothesFromAvatar()
-{
-	// Fetch worn clothes (i.e. the ones in COF).
-	LLInventoryModel::item_array_t clothing_items;
-	LLInventoryModel::cat_array_t dummy;
-	LLIsType is_clothing(LLAssetType::AT_CLOTHING);
-	gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(),
-									dummy,
-									clothing_items,
-									LLInventoryModel::EXCLUDE_TRASH,
-									is_clothing,
-									false);
-
-	// Take them off by removing from COF.
-	for (LLInventoryModel::item_array_t::const_iterator it = clothing_items.begin(); it != clothing_items.end(); ++it)
-	{
-		LLAppearanceMgr::instance().removeItemFromAvatar((*it)->getUUID());
-	}
-}
-
-// static
-void LLWearableBridge::removeItemFromAvatar(LLViewerInventoryItem *item)
-{
-	if (item)
-	{
-		LLWearableList::instance().getAsset(item->getAssetUUID(),
-											item->getName(),
-											item->getType(),
-											LLWearableBridge::onRemoveFromAvatarArrived,
-											new OnRemoveStruct(item->getUUID()));
-	}
-}
-
 void LLWearableBridge::removeFromAvatar()
 {
+	llwarns << "safe to remove?" << llendl;
 	if (get_is_item_worn(mUUID))
 	{
-		LLViewerInventoryItem* item = getItem();
-		removeItemFromAvatar(item);
+		LLAppearanceMgr::instance().removeItemFromAvatar(mUUID);
 	}
 }
 
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 5c6cf0f0f0f2b85ff4d72eced06fc0214c267464..517153e1710c440955989e411b3e7ac3d75bcec4 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -34,7 +34,7 @@
 #include "llinventoryobserver.h"
 #include "llinventorypanel.h"
 #include "llviewercontrol.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
 #include "lltooldraganddrop.h"
 
 class LLInventoryFilter;
@@ -509,10 +509,10 @@ class LLWearableBridge : public LLItemBridge
 
 	static void		onWearOnAvatar( void* userdata );	// Access to wearOnAvatar() from menu
 	static BOOL		canWearOnAvatar( void* userdata );
-	static void		onWearOnAvatarArrived( LLWearable* wearable, void* userdata );
+	static void		onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
 	void			wearOnAvatar();
 
-	static void		onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata );
+	static void		onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
 	void			wearAddOnAvatar();
 
 	static BOOL		canEditOnAvatar( void* userdata );	// Access to editOnAvatar() from menu
@@ -520,9 +520,6 @@ class LLWearableBridge : public LLItemBridge
 	void			editOnAvatar();
 
 	static BOOL		canRemoveFromAvatar( void* userdata );
-	static void		onRemoveFromAvatar( void* userdata );
-	static void		onRemoveFromAvatarArrived( LLWearable* wearable, 	void* userdata );
-	static void 	removeItemFromAvatar(LLViewerInventoryItem *item);
 	static void 	removeAllClothesFromAvatar();
 	void			removeFromAvatar();
 protected:
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 34734d57c5f9fe842f2b91fc7771c5d7b4eedfe2..02a2475cfd44831532a232886c173baa6bdd3992 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -25,6 +25,8 @@
  */
 
 #include "llviewerprecompiledheaders.h"
+
+#include "linden_common.h"
 #include "llinventoryicon.h"
 
 #include "lldictionary.h"
@@ -41,7 +43,7 @@ struct IconEntry : public LLDictionaryEntry
 };
 
 class LLIconDictionary : public LLSingleton<LLIconDictionary>,
-						 public LLDictionary<LLInventoryIcon::EIconName, IconEntry>
+						 public LLDictionary<LLInventoryType::EIconName, IconEntry>
 {
 public:
 	LLIconDictionary();
@@ -49,48 +51,48 @@ class LLIconDictionary : public LLSingleton<LLIconDictionary>,
 
 LLIconDictionary::LLIconDictionary()
 {
-	addEntry(LLInventoryIcon::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture"));
-	addEntry(LLInventoryIcon::ICONNAME_SOUND, 					new IconEntry("Inv_Sound"));
-	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard"));
-	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard"));
-	addEntry(LLInventoryIcon::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark"));
-	addEntry(LLInventoryIcon::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark"));
-	addEntry(LLInventoryIcon::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing"));
-	addEntry(LLInventoryIcon::ICONNAME_OBJECT, 					new IconEntry("Inv_Object"));
-	addEntry(LLInventoryIcon::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi"));
-	addEntry(LLInventoryIcon::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin"));
-	addEntry(LLInventoryIcon::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot"));
-
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye"));
-
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo"));
-	addEntry(LLInventoryIcon::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation"));
-	addEntry(LLInventoryIcon::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture"));
-
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, 		new IconEntry("Inv_Physics"));
-
-	addEntry(LLInventoryIcon::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem"));
-	addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkFolder"));
-	addEntry(LLInventoryIcon::ICONNAME_MESH,	 				new IconEntry("Inv_Mesh"));
-
-	addEntry(LLInventoryIcon::ICONNAME_INVALID, 				new IconEntry("Inv_Invalid"));
-
-	addEntry(LLInventoryIcon::ICONNAME_NONE, 					new IconEntry("NONE"));
+	addEntry(LLInventoryType::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture"));
+	addEntry(LLInventoryType::ICONNAME_SOUND, 					new IconEntry("Inv_Sound"));
+	addEntry(LLInventoryType::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard"));
+	addEntry(LLInventoryType::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard"));
+	addEntry(LLInventoryType::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark"));
+	addEntry(LLInventoryType::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark"));
+	addEntry(LLInventoryType::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing"));
+	addEntry(LLInventoryType::ICONNAME_OBJECT, 					new IconEntry("Inv_Object"));
+	addEntry(LLInventoryType::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi"));
+	addEntry(LLInventoryType::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin"));
+	addEntry(LLInventoryType::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot"));
+
+	addEntry(LLInventoryType::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye"));
+
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo"));
+	addEntry(LLInventoryType::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation"));
+	addEntry(LLInventoryType::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture"));
+
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_PHYSICS, 		new IconEntry("Inv_Physics"));
+
+	addEntry(LLInventoryType::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem"));
+	addEntry(LLInventoryType::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkFolder"));
+	addEntry(LLInventoryType::ICONNAME_MESH,	 				new IconEntry("Inv_Mesh"));
+
+	addEntry(LLInventoryType::ICONNAME_INVALID, 				new IconEntry("Inv_Invalid"));
+
+	addEntry(LLInventoryType::ICONNAME_NONE, 					new IconEntry("NONE"));
 }
 
 LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type,
@@ -102,7 +104,7 @@ LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type,
 	return LLUI::getUIImage(icon_name);
 }
 
-LLUIImagePtr LLInventoryIcon::getIcon(EIconName idx)
+LLUIImagePtr LLInventoryIcon::getIcon(LLInventoryType::EIconName idx)
 {
 	return LLUI::getUIImage(getIconName(idx));
 }
@@ -112,56 +114,56 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
 												U32 misc_flag,
 												BOOL item_is_multi)
 {
-	EIconName idx = ICONNAME_OBJECT;
+	LLInventoryType::EIconName idx = LLInventoryType::ICONNAME_OBJECT;
 	if (item_is_multi)
 	{
-		idx = ICONNAME_OBJECT_MULTI;
+		idx = LLInventoryType::ICONNAME_OBJECT_MULTI;
 		return getIconName(idx);
 	}
 	
 	switch(asset_type)
 	{
 		case LLAssetType::AT_TEXTURE:
-			idx = (inventory_type == LLInventoryType::IT_SNAPSHOT) ? ICONNAME_SNAPSHOT : ICONNAME_TEXTURE;
+			idx = (inventory_type == LLInventoryType::IT_SNAPSHOT) ? LLInventoryType::ICONNAME_SNAPSHOT : LLInventoryType::ICONNAME_TEXTURE;
 			break;
 		case LLAssetType::AT_SOUND:
-			idx = ICONNAME_SOUND;
+			idx = LLInventoryType::ICONNAME_SOUND;
 			break;
 		case LLAssetType::AT_CALLINGCARD:
-			idx = (misc_flag != 0) ? ICONNAME_CALLINGCARD_ONLINE : ICONNAME_CALLINGCARD_OFFLINE;
+			idx = (misc_flag != 0) ? LLInventoryType::ICONNAME_CALLINGCARD_ONLINE : LLInventoryType::ICONNAME_CALLINGCARD_OFFLINE;
 			break;
 		case LLAssetType::AT_LANDMARK:
-			idx = (misc_flag != 0) ? ICONNAME_LANDMARK_VISITED : ICONNAME_LANDMARK;
+			idx = (misc_flag != 0) ? LLInventoryType::ICONNAME_LANDMARK_VISITED : LLInventoryType::ICONNAME_LANDMARK;
 			break;
 		case LLAssetType::AT_SCRIPT:
 		case LLAssetType::AT_LSL_TEXT:
 		case LLAssetType::AT_LSL_BYTECODE:
-			idx = ICONNAME_SCRIPT;
+			idx = LLInventoryType::ICONNAME_SCRIPT;
 			break;
 		case LLAssetType::AT_CLOTHING:
 		case LLAssetType::AT_BODYPART:
 			idx = assignWearableIcon(misc_flag);
 			break;
 		case LLAssetType::AT_NOTECARD:
-			idx = ICONNAME_NOTECARD;
+			idx = LLInventoryType::ICONNAME_NOTECARD;
 			break;
 		case LLAssetType::AT_ANIMATION:
-			idx = ICONNAME_ANIMATION;
+			idx = LLInventoryType::ICONNAME_ANIMATION;
 			break;
 		case LLAssetType::AT_GESTURE:
-			idx = ICONNAME_GESTURE;
+			idx = LLInventoryType::ICONNAME_GESTURE;
 			break;
 		case LLAssetType::AT_LINK:
-			idx = ICONNAME_LINKITEM;
+			idx = LLInventoryType::ICONNAME_LINKITEM;
 			break;
 		case LLAssetType::AT_LINK_FOLDER:
-			idx = ICONNAME_LINKFOLDER;
+			idx = LLInventoryType::ICONNAME_LINKFOLDER;
 			break;
 		case LLAssetType::AT_OBJECT:
-			idx = ICONNAME_OBJECT;
+			idx = LLInventoryType::ICONNAME_OBJECT;
 			break;
 		case LLAssetType::AT_MESH:
-			idx = ICONNAME_MESH;
+			idx = LLInventoryType::ICONNAME_MESH;
 		default:
 			break;
 	}
@@ -170,13 +172,13 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
 }
 
 
-const std::string& LLInventoryIcon::getIconName(EIconName idx)
+const std::string& LLInventoryIcon::getIconName(LLInventoryType::EIconName idx)
 {
 	const IconEntry *entry = LLIconDictionary::instance().lookup(idx);
 	return entry->mName;
 }
 
-LLInventoryIcon::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag)
+LLInventoryType::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag)
 {
 	const LLWearableType::EType wearable_type = LLWearableType::EType(LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK & misc_flag);
 	return LLWearableType::getIconName(wearable_type);
diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h
index 5c8acf9e85f06bf3a8cb4c41a826e3cedbbd4741..2197c53bb8395c500ec97705f7cc1f01673c4a53 100644
--- a/indra/newview/llinventoryicon.h
+++ b/indra/newview/llinventoryicon.h
@@ -35,66 +35,20 @@
 class LLInventoryIcon
 {
 public:
-	enum EIconName
-	{
-		ICONNAME_TEXTURE,
-		ICONNAME_SOUND,
-		ICONNAME_CALLINGCARD_ONLINE,
-		ICONNAME_CALLINGCARD_OFFLINE,
-		ICONNAME_LANDMARK,
-		ICONNAME_LANDMARK_VISITED,
-		ICONNAME_SCRIPT,
-		ICONNAME_CLOTHING,
-		ICONNAME_OBJECT,
-		ICONNAME_OBJECT_MULTI,
-		ICONNAME_NOTECARD,
-		ICONNAME_BODYPART,
-		ICONNAME_SNAPSHOT,
-		
-		ICONNAME_BODYPART_SHAPE,
-		ICONNAME_BODYPART_SKIN,
-		ICONNAME_BODYPART_HAIR,
-		ICONNAME_BODYPART_EYES,
-		ICONNAME_CLOTHING_SHIRT,
-		ICONNAME_CLOTHING_PANTS,
-		ICONNAME_CLOTHING_SHOES,
-		ICONNAME_CLOTHING_SOCKS,
-		ICONNAME_CLOTHING_JACKET,
-		ICONNAME_CLOTHING_GLOVES,
-		ICONNAME_CLOTHING_UNDERSHIRT,
-		ICONNAME_CLOTHING_UNDERPANTS,
-		ICONNAME_CLOTHING_SKIRT,
-		ICONNAME_CLOTHING_ALPHA,
-		ICONNAME_CLOTHING_TATTOO,
-
-		ICONNAME_ANIMATION,
-		ICONNAME_GESTURE,
-
-		ICONNAME_CLOTHING_PHYSICS,
-		
-		ICONNAME_LINKITEM,
-		ICONNAME_LINKFOLDER,
-		ICONNAME_MESH,
-
-		ICONNAME_INVALID,
-		ICONNAME_COUNT,
-		ICONNAME_NONE = -1
-	};
-
 	static const std::string& getIconName(LLAssetType::EType asset_type,
 										  LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE,
 										  U32 misc_flag = 0, // different meanings depending on item type
 										  BOOL item_is_multi = FALSE);
-	static const std::string& getIconName(EIconName idx);
+	static const std::string& getIconName(LLInventoryType::EIconName idx);
 
 	static LLUIImagePtr getIcon(LLAssetType::EType asset_type,
 								LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE,
 								U32 misc_flag = 0, // different meanings depending on item type
 								BOOL item_is_multi = FALSE);
-	static LLUIImagePtr getIcon(EIconName idx);
+	static LLUIImagePtr getIcon(LLInventoryType::EIconName idx);
 
 protected:
-	static EIconName assignWearableIcon(U32 misc_flag);
+	static LLInventoryType::EIconName assignWearableIcon(U32 misc_flag);
 };
 #endif // LL_LLINVENTORYICON_H
 
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index 3e0849a79578d793e0890e45d8a4d74b77b46545..06017964365eed2b2d0b57e5ddda5271ddcf21e4 100644
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -37,6 +37,7 @@
 #include "lltextutil.h"
 
 // newview
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"
 #include "llviewerinventory.h"
 
@@ -230,7 +231,7 @@ const std::string& LLPanelInventoryListItemBase::getDescription() const
 	{
 		return LLStringUtil::null;
 	}
-	return inv_item->getDescription();
+	return inv_item->getActualDescription();
 }
 
 time_t LLPanelInventoryListItemBase::getCreationDate() const
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
old mode 100644
new mode 100755
index e7d59d92d9dfe68def7d82d9fb3f491eb489c11e..935fe2b4d0e88c6c70c7e5f310ebaf7e4755f9e0
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -460,9 +460,10 @@ class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
 	{
 	}
 	
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		LL_WARNS("InvAPI") << "CreateInventoryCategory failed.   status = " << status << ", reasion = \"" << reason << "\"" << LL_ENDL;
+		LL_WARNS("InvAPI") << "CreateInventoryCategory failed [status:"
+				<< status << "]: " << content << LL_ENDL;
 	}
 	
 	virtual void result(const LLSD& content)
@@ -1410,7 +1411,6 @@ void  LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
 	item_array_t items;
 	update_map_t update;
 	S32 count = content["items"].size();
-	bool all_one_folder = true;
 	LLUUID folder_id;
 	// Does this loop ever execute more than once?
 	for(S32 i = 0; i < count; ++i)
@@ -1443,10 +1443,6 @@ void  LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
 		{
 			folder_id = titem->getParentUUID();
 		}
-		else
-		{
-			all_one_folder = false;
-		}
 	}
 
 	U32 changes = 0x0;
@@ -1460,10 +1456,9 @@ void  LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
 }
 
 //If we get back an error (not found, etc...), handle it here
-void LLInventoryModel::fetchInventoryResponder::error(U32 status, const std::string& reason)
+void LLInventoryModel::fetchInventoryResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llinfos << "fetchInventory::error "
-		<< status << ": " << reason << llendl;
+	llwarns << "fetchInventory error [status:" << status << "]: " << content << llendl;
 	gInventory.notifyObservers();
 }
 
@@ -1996,8 +1991,9 @@ bool LLInventoryModel::loadSkeleton(
 		{
 			LLViewerInventoryCategory* cat = (*invalid_cat_it).get();
 			cat->setVersion(NO_VERSION);
-			llinfos << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl;
+			LL_DEBUGS("Inventory") << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl;
 		}
+		LL_INFOS("Inventory") << "Invalidated " << invalid_categories.size() << " categories due to invalid descendents cache" << llendl;
 
 		// At this point, we need to set the known descendents for each
 		// category which successfully cached so that we do not
@@ -2534,7 +2530,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account)
 	item_array_t items;
 	update_map_t update;
 	S32 count = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
-	bool all_one_folder = true;
 	LLUUID folder_id;
 	// Does this loop ever execute more than once?
 	for(S32 i = 0; i < count; ++i)
@@ -2566,10 +2561,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account)
 		{
 			folder_id = titem->getParentUUID();
 		}
-		else
-		{
-			all_one_folder = false;
-		}
 	}
 	if(account)
 	{
@@ -3295,8 +3286,71 @@ void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, c
 	}
 }
 
+//* @param[in] items vector of items in order to be saved.
+/*
+void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items)
+{
+	int sortField = 0;
+
+	// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
+	for (item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
+	{
+		LLViewerInventoryItem* item = *i;
+
+		item->setSortField(++sortField);
+		item->setComplete(TRUE);
+		item->updateServer(FALSE);
+
+		updateItem(item);
 
+		// Tell the parent folder to refresh its sort order.
+		addChangedMask(LLInventoryObserver::SORT, item->getParentUUID());
+	}
 
+	notifyObservers();
+}
+*/
+// See also LLInventorySort where landmarks in the Favorites folder are sorted.
+class LLViewerInventoryItemSort
+{
+public:
+	bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
+	{
+		return a->getSortField() < b->getSortField();
+	}
+};
+
+/**
+ * Sorts passed items by LLViewerInventoryItem sort field.
+ *
+ * @param[in, out] items - array of items, not sorted.
+ */
+//static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
+//{
+//	static LLViewerInventoryItemSort sort_functor;
+//	std::sort(items.begin(), items.end(), sort_functor);
+//}
+
+// * @param source_item_id - LLUUID of the source item to be moved into new position
+// * @param target_item_id - LLUUID of the target item before which source item should be placed.
+/*
+void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
+{
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLIsType is_type(LLAssetType::AT_LANDMARK);
+	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+	gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
+
+	// ensure items are sorted properly before changing order. EXT-3498
+	rearrange_item_order_by_sort_field(items);
+
+	// update order
+	updateItemsOrder(items, source_item_id, target_item_id);
+
+	saveItemsOrder(items);
+}
+*/
 //----------------------------------------------------------------------------
 
 // *NOTE: DEBUG functionality
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 503de627a0b8689e562b5d36fb7463c98405f85e..8aac879a93780c1e9b27296b6589905b9684d938 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -84,7 +84,7 @@ class LLInventoryModel
 	public:
 		fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
 		void result(const LLSD& content);			
-		void error(U32 status, const std::string& reason);
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	protected:
 		LLSD mRequestSD;
 	};
@@ -231,7 +231,8 @@ class LLInventoryModel
 	// Returns the uuid of the category that specifies 'type' as what it 
 	// defaults to containing. The category is not necessarily only for that type. 
 	//    NOTE: If create_folder is true, this will create a new inventory category 
-	//    on the fly if one does not exist. 
+	//    on the fly if one does not exist. *NOTE: if find_in_library is true it 
+	//    will search in the user's library folder instead of "My Inventory"
 	const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type, 
 										 bool create_folder = true);
 	//    will search in the user's library folder instead of "My Inventory"
@@ -363,6 +364,12 @@ class LLInventoryModel
 	// Returns end() of the vector if not found.
 	static LLInventoryModel::item_array_t::iterator findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
 
+
+	// Rearranges Landmarks inside Favorites folder.
+	// Moves source landmark before target one.
+	void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
+	//void saveItemsOrder(const LLInventoryModel::item_array_t& items);
+
 	//--------------------------------------------------------------------
 	// Creation
 	//--------------------------------------------------------------------
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index f4d0110b0f478114b74ea91d7fb3ed635355713a..f2b39e71863d35f0f962f47d78677b2031d90f75 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -183,7 +183,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *)
 
 void LLInventoryModelBackgroundFetch::backgroundFetch()
 {
-	if (mBackgroundFetchActive && gAgent.getRegion())
+	if (mBackgroundFetchActive && gAgent.getRegion() && gAgent.getRegion()->capabilitiesReceived())
 	{
 		// If we'll be using the capability, we'll be sending batches and the background thing isn't as important.
 		if (gSavedSettings.getBOOL("UseHTTPInventory")) 
@@ -366,7 +366,7 @@ class LLInventoryModelFetchItemResponder : public LLInventoryModel::fetchInvento
 public:
 	LLInventoryModelFetchItemResponder(const LLSD& request_sd) : LLInventoryModel::fetchInventoryResponder(request_sd) {};
 	void result(const LLSD& content);			
-	void error(U32 status, const std::string& reason);
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 };
 
 void LLInventoryModelFetchItemResponder::result( const LLSD& content )
@@ -375,9 +375,9 @@ void LLInventoryModelFetchItemResponder::result( const LLSD& content )
 	LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
 }
 
-void LLInventoryModelFetchItemResponder::error( U32 status, const std::string& reason )
+void LLInventoryModelFetchItemResponder::errorWithContent( U32 status, const std::string& reason, const LLSD& content )
 {
-	LLInventoryModel::fetchInventoryResponder::error(status, reason);
+	LLInventoryModel::fetchInventoryResponder::errorWithContent(status, reason, content);
 	LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
 }
 
@@ -391,7 +391,7 @@ class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::Responder
 	{};
 	//LLInventoryModelFetchDescendentsResponder() {};
 	void result(const LLSD& content);
-	void error(U32 status, const std::string& reason);
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 protected:
 	BOOL getIsRecursive(const LLUUID& cat_id) const;
 private:
@@ -529,12 +529,12 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
 }
 
 // If we get back an error (not found, etc...), handle it here.
-void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::string& reason)
+void LLInventoryModelFetchDescendentsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
 	LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
 
-	llinfos << "LLInventoryModelFetchDescendentsResponder::error "
-		<< status << ": " << reason << llendl;
+	llinfos << "LLInventoryModelFetchDescendentsResponder::error [status:"
+			<< status << "]: " << content << llendl;
 						
 	fetcher->incrFetchCount(-1);
 
@@ -564,7 +564,6 @@ BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat
 {
 	return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end());
 }
-
 // Bundle up a bunch of requests to send all at once.
 // static   
 void LLInventoryModelBackgroundFetch::bulkFetch()
@@ -687,20 +686,23 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
 	{
 		if (folder_count)
 		{
-			std::string url = region->getCapability("FetchInventoryDescendents2");   
-			mFetchCount++;
-			if (folder_request_body["folders"].size())
-			{
-				LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats);
-				LLHTTPClient::post(url, folder_request_body, fetcher, 300.0);
-			}
-			if (folder_request_body_lib["folders"].size())
+			std::string url = region->getCapability("FetchInventoryDescendents2");   			
+			if ( !url.empty() )
 			{
-				std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2");
+				mFetchCount++;
+				if (folder_request_body["folders"].size())
+				{
+					LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats);
+					LLHTTPClient::post(url, folder_request_body, fetcher, 300.0);
+				}
+				if (folder_request_body_lib["folders"].size())
+				{
+					std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2");
 
-				LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats);
-				LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0);
-			}
+					LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats);
+					LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0);
+				}
+			}					
 		}
 		if (item_count)
 		{
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index fabcd50c7d8d52bbd9e9e0514f5d41d685d1d1b6..cf1fd4c0d08d43778c1de8930eb6dbc7210b803a 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -401,8 +401,6 @@ void LLInventoryPanel::modelChanged(U32 mask)
 	static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh");
 	LLFastTimer t2(FTM_REFRESH);
 
-	bool handled = false;
-
 	if (!mViewsInitialized) return;
 	
 	const LLInventoryModel* model = getModel();
@@ -437,7 +435,6 @@ void LLInventoryPanel::modelChanged(U32 mask)
 		// Empty out the display name for relabel.
 		if (mask & LLInventoryObserver::LABEL)
 		{
-			handled = true;
 			if (view_item)
 			{
 				// Request refresh on this item (also flags for filtering)
@@ -456,7 +453,6 @@ void LLInventoryPanel::modelChanged(U32 mask)
 		// Destroy and regenerate the UI.
 		if (mask & LLInventoryObserver::REBUILD)
 		{
-			handled = true;
 			if (model_item && view_item && viewmodel_item)
 			{
 				const LLUUID& idp = viewmodel_item->getUUID();
@@ -500,8 +496,6 @@ void LLInventoryPanel::modelChanged(U32 mask)
 					LLInventoryObserver::ADD |
 					LLInventoryObserver::REMOVE))
 		{
-			handled = true;
-
 			//////////////////////////////
 			// ADD Operation
 			// Item exists in memory but a UI element hasn't been created for it.
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 97ba5b634a1f99c83541bc6f7ac9f1d5b1d396cf..25df4889b0d69973132c69da1ad3b0517575b3ae 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -53,7 +53,7 @@
 #include "llviewerobject.h"
 #include "llface.h"
 #include "llvoavatarself.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
 #include "llagentwearables.h"
 #include "lltexlayerparams.h"
 #include "llvovolume.h"
@@ -195,7 +195,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
 					mLastModified = new_last_modified;
 
 					LLPointer<LLViewerFetchedTexture> texture = new LLViewerFetchedTexture
-						("file://"+mFilename, mWorldID, LL_LOCAL_USE_MIPMAPS);
+						("file://"+mFilename, FTT_LOCAL_FILE, mWorldID, LL_LOCAL_USE_MIPMAPS);
 
 					texture->createGLTexture(LL_LOCAL_DISCARD_LEVEL, raw_image);
 					texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image);
@@ -437,8 +437,8 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)
 					LLFace* face = object->mDrawable->getFace(face_iter);
 					if (face && face->getTexture() && face->getTexture()->getID() == old_id)
 					{
-						object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture
-							(new_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+						object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture(
+							new_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
 
 						update_obj = true;
 					}
@@ -481,7 +481,7 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
 	U32 count = gAgentWearables.getWearableCount(type);
 	for(U32 wearable_iter = 0; wearable_iter < count; wearable_iter++)
 	{
-		LLWearable* wearable = gAgentWearables.getWearable(type, wearable_iter);
+		LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_iter);
 		if (wearable)
 		{
 			std::vector<LLLocalTextureObject*> texture_list = wearable->getLocalTextureListSeq();
@@ -493,11 +493,11 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
 				if (lto && lto->getID() == old_id)
 				{
 					U32 local_texlayer_index = 0; /* can't keep that as static const, gives errors, so i'm leaving this var here */
-					LLVOAvatarDefines::EBakedTextureIndex baked_texind =
+					LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind =
 						lto->getTexLayer(local_texlayer_index)->getTexLayerSet()->getBakedTexIndex();
 				
-					LLVOAvatarDefines::ETextureIndex reg_texind = getTexIndex(type, baked_texind);
-					if (reg_texind != LLVOAvatarDefines::TEX_NUM_INDICES)
+					LLAvatarAppearanceDefines::ETextureIndex reg_texind = getTexIndex(type, baked_texind);
+					if (reg_texind != LLAvatarAppearanceDefines::TEX_NUM_INDICES)
 					{
 						U32 index = gAgentWearables.getWearableIndex(wearable);
 						gAgentAvatarp->setLocalTexture(reg_texind, gTextureList.getImage(new_id), FALSE, index);
@@ -513,10 +513,10 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
 	}
 }
 
-LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
-	LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind)
+LLAvatarAppearanceDefines::ETextureIndex LLLocalBitmap::getTexIndex(
+	LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind)
 {
-	LLVOAvatarDefines::ETextureIndex result = LLVOAvatarDefines::TEX_NUM_INDICES; // using as a default/fail return.
+	LLAvatarAppearanceDefines::ETextureIndex result = LLAvatarAppearanceDefines::TEX_NUM_INDICES; // using as a default/fail return.
 
 	switch(type)
 	{
@@ -524,32 +524,32 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 		{
 			switch(baked_texind)
 			{
-				case LLVOAvatarDefines::BAKED_EYES:
+				case LLAvatarAppearanceDefines::BAKED_EYES:
 				{
-					result = LLVOAvatarDefines::TEX_EYES_ALPHA;
+					result = LLAvatarAppearanceDefines::TEX_EYES_ALPHA;
 					break;
 				}
 
-				case LLVOAvatarDefines::BAKED_HAIR:
+				case LLAvatarAppearanceDefines::BAKED_HAIR:
 				{
-					result = LLVOAvatarDefines::TEX_HAIR_ALPHA;
+					result = LLAvatarAppearanceDefines::TEX_HAIR_ALPHA;
 					break;
 				}
 
-				case LLVOAvatarDefines::BAKED_HEAD:
+				case LLAvatarAppearanceDefines::BAKED_HEAD:
 				{
-					result = LLVOAvatarDefines::TEX_HEAD_ALPHA;
+					result = LLAvatarAppearanceDefines::TEX_HEAD_ALPHA;
 					break;
 				}
 
-				case LLVOAvatarDefines::BAKED_LOWER:
+				case LLAvatarAppearanceDefines::BAKED_LOWER:
 				{
-					result = LLVOAvatarDefines::TEX_LOWER_ALPHA;
+					result = LLAvatarAppearanceDefines::TEX_LOWER_ALPHA;
 					break;
 				}
-				case LLVOAvatarDefines::BAKED_UPPER:
+				case LLAvatarAppearanceDefines::BAKED_UPPER:
 				{
-					result = LLVOAvatarDefines::TEX_UPPER_ALPHA;
+					result = LLAvatarAppearanceDefines::TEX_UPPER_ALPHA;
 					break;
 				}
 
@@ -565,9 +565,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_EYES:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_EYES)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_EYES)
 			{
-				result = LLVOAvatarDefines::TEX_EYES_IRIS;
+				result = LLAvatarAppearanceDefines::TEX_EYES_IRIS;
 			}
 
 			break;
@@ -575,9 +575,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_GLOVES:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
 			{
-				result = LLVOAvatarDefines::TEX_UPPER_GLOVES;
+				result = LLAvatarAppearanceDefines::TEX_UPPER_GLOVES;
 			}
 
 			break;
@@ -585,13 +585,13 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_JACKET:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
 			{
-				result = LLVOAvatarDefines::TEX_LOWER_JACKET;
+				result = LLAvatarAppearanceDefines::TEX_LOWER_JACKET;
 			}
-			else if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+			else if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
 			{
-				result = LLVOAvatarDefines::TEX_UPPER_JACKET;
+				result = LLAvatarAppearanceDefines::TEX_UPPER_JACKET;
 			}
 
 			break;
@@ -599,9 +599,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_PANTS:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
 			{
-				result = LLVOAvatarDefines::TEX_LOWER_PANTS;
+				result = LLAvatarAppearanceDefines::TEX_LOWER_PANTS;
 			}
 
 			break;
@@ -609,9 +609,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_SHIRT:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
 			{
-				result = LLVOAvatarDefines::TEX_UPPER_SHIRT;
+				result = LLAvatarAppearanceDefines::TEX_UPPER_SHIRT;
 			}
 
 			break;
@@ -619,9 +619,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_SHOES:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
 			{
-				result = LLVOAvatarDefines::TEX_LOWER_SHOES;
+				result = LLAvatarAppearanceDefines::TEX_LOWER_SHOES;
 			}
 
 			break;
@@ -631,20 +631,20 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 		{
 			switch(baked_texind)
 			{
-				case LLVOAvatarDefines::BAKED_HEAD:
+				case LLAvatarAppearanceDefines::BAKED_HEAD:
 				{
-					result = LLVOAvatarDefines::TEX_HEAD_BODYPAINT;
+					result = LLAvatarAppearanceDefines::TEX_HEAD_BODYPAINT;
 					break;
 				}
 
-				case LLVOAvatarDefines::BAKED_LOWER:
+				case LLAvatarAppearanceDefines::BAKED_LOWER:
 				{
-					result = LLVOAvatarDefines::TEX_LOWER_BODYPAINT;
+					result = LLAvatarAppearanceDefines::TEX_LOWER_BODYPAINT;
 					break;
 				}
-				case LLVOAvatarDefines::BAKED_UPPER:
+				case LLAvatarAppearanceDefines::BAKED_UPPER:
 				{
-					result = LLVOAvatarDefines::TEX_UPPER_BODYPAINT;
+					result = LLAvatarAppearanceDefines::TEX_UPPER_BODYPAINT;
 					break;
 				}
 
@@ -659,9 +659,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_SKIRT:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_SKIRT)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_SKIRT)
 			{
-				result = LLVOAvatarDefines::TEX_SKIRT;
+				result = LLAvatarAppearanceDefines::TEX_SKIRT;
 			}
 
 			break;
@@ -669,9 +669,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_SOCKS:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
 			{
-				result = LLVOAvatarDefines::TEX_LOWER_SOCKS;
+				result = LLAvatarAppearanceDefines::TEX_LOWER_SOCKS;
 			}
 
 			break;
@@ -681,20 +681,20 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 		{
 			switch(baked_texind)
 			{
-				case LLVOAvatarDefines::BAKED_HEAD:
+				case LLAvatarAppearanceDefines::BAKED_HEAD:
 				{
-					result = LLVOAvatarDefines::TEX_HEAD_TATTOO;
+					result = LLAvatarAppearanceDefines::TEX_HEAD_TATTOO;
 					break;
 				}
 
-				case LLVOAvatarDefines::BAKED_LOWER:
+				case LLAvatarAppearanceDefines::BAKED_LOWER:
 				{
-					result = LLVOAvatarDefines::TEX_LOWER_TATTOO;
+					result = LLAvatarAppearanceDefines::TEX_LOWER_TATTOO;
 					break;
 				}
-				case LLVOAvatarDefines::BAKED_UPPER:
+				case LLAvatarAppearanceDefines::BAKED_UPPER:
 				{
-					result = LLVOAvatarDefines::TEX_UPPER_TATTOO;
+					result = LLAvatarAppearanceDefines::TEX_UPPER_TATTOO;
 					break;
 				}
 
@@ -709,9 +709,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_UNDERPANTS:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
 			{
-				result = LLVOAvatarDefines::TEX_LOWER_UNDERPANTS;
+				result = LLAvatarAppearanceDefines::TEX_LOWER_UNDERPANTS;
 			}
 
 			break;
@@ -719,9 +719,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_UNDERSHIRT:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
 			{
-				result = LLVOAvatarDefines::TEX_UPPER_UNDERSHIRT;
+				result = LLAvatarAppearanceDefines::TEX_UPPER_UNDERSHIRT;
 			}
 
 			break;
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index 7a23c7ef6e3d2a203b07b4137960f58e00fafd40..580b6dfa7e06ffff4ded45e3247b10a59c9bc8e2 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -28,11 +28,14 @@
 #ifndef LL_LOCALBITMAPS_H
 #define LL_LOCALBITMAPS_H
 
+#include "llavatarappearancedefines.h"
 #include "lleventtimer.h"
+#include "llimage.h"
+#include "llpointer.h"
 #include "llwearabletype.h"
-#include "llvoavatardefines.h"
 
 class LLScrollListCtrl;
+class LLViewerObject;
 
 class LLLocalBitmap
 {
@@ -63,7 +66,7 @@ class LLLocalBitmap
 		void updateUserPrims(LLUUID old_id, LLUUID new_id);
 		void updateUserSculpts(LLUUID old_id, LLUUID new_id);
 		void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type);
-		LLVOAvatarDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind);
+		LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind);
 
 	private: /* private enums */
 		enum ELinkStatus
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 8d9d70b50eea2892118cd4c13d676ac6ead1b4e5..5022dba934415c8dc27ac55b0cd90d0779afd035 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -1217,11 +1217,11 @@ void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon)
 	case SCRIPTS_ICON:
 	{
 		LLViewerRegion* region = gAgent.getRegion();
-		if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
+		if(region && region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS))
 		{
 			LLNotificationsUtil::add("ScriptsStopped");
 		}
-		else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
+		else if(region && region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS))
 		{
 			LLNotificationsUtil::add("ScriptsNotRunning");
 		}
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 9ec5d7c20c4c60026f77cb98defd0b0da8b25c35..a7d6cb5eac0ae4e35b201b07162952d903585965 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -53,7 +53,7 @@
 #include "llresmgr.h"
 #include "pipeline.h"
 #include "llglheaders.h"
-
+#include "lluiimage.h"
 // Local constants...
 const S32 VERTICAL_OFFSET = 50;
 
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 826e8d560a5ffc01746fb2e9a69c0169f6f8f23d..d79f1040bba740c385ecbf13e72e446df852f073 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -1689,7 +1689,6 @@ void LLManipRotate::highlightManipulators( S32 x, S32 y )
 		return;
 	}
 	
-	LLQuaternion object_rot = first_object->getRenderRotation();
 	LLVector3 rotation_center = gAgent.getPosAgentFromGlobal(mRotationCenter);
 	LLVector3 mouse_dir_x;
 	LLVector3 mouse_dir_y;
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index 00a0bf889431465a0f36383a00a3e97be8ea53b4..ae0884ac5d179f75bc01fe14780a6f1864d56fc9 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -1191,9 +1191,6 @@ void LLManipScale::dragFace( S32 x, S32 y )
 		mInSnapRegime = FALSE;
 	}
 
-	BOOL send_scale_update = FALSE;
-	BOOL send_position_update = FALSE;
-
 	LLVector3 dir_agent;
 	if( part_dir_local.mV[VX] )
 	{
@@ -1210,8 +1207,6 @@ void LLManipScale::dragFace( S32 x, S32 y )
 	stretchFace( 
 		projected_vec(drag_start_dir_f, dir_agent) + drag_start_center_agent,
 		projected_vec(drag_delta, dir_agent));
-	send_position_update = TRUE;
-	send_scale_update = TRUE;
 
 	mDragPointGlobal = drag_point_global;
 }
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 362308c1765d4b402283ecfaf9618cecf321b01d..b62db70ec84e4e0d75ddb767e118065a444387b0 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -485,7 +485,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 	}
 
 	// Throttle updates to 10 per second.
-	BOOL send_update = FALSE;
 
 	LLVector3		axis_f;
 	LLVector3d		axis_d;
@@ -702,11 +701,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 				LLVector3 old_position_local = object->getPosition();
 				LLVector3 new_position_local = selectNode->mSavedPositionLocal + (clamped_relative_move_f * objWorldRotation);
 
-				// move and clamp root object first, before adjusting children
-				if (new_position_local != old_position_local)
-				{
-					send_update = TRUE;
-				}
 				//RN: I forget, but we need to do this because of snapping which doesn't often result
 				// in position changes even when the mouse moves
 				object->setPosition(new_position_local);
@@ -716,8 +710,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 
 				if (selectNode->mIndividualSelection)
 				{
-					send_update = FALSE;
-		
 					// counter-translate child objects if we are moving the root as an individual
 					object->resetChildrenPosition(old_position_local - new_position_local, TRUE) ;					
 				}
@@ -753,7 +745,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 				}
 
 				// PR: Only update if changed
-				LLVector3d old_position_global = object->getPositionGlobal();
 				LLVector3 old_position_agent = object->getPositionAgent();
 				LLVector3 new_position_agent = gAgent.getPosAgentFromGlobal(new_position_global);
 				if (object->isRootEdit())
@@ -775,11 +766,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 				{
 					// counter-translate child objects if we are moving the root as an individual
 					object->resetChildrenPosition(old_position_agent - new_position_agent, TRUE) ;					
-					send_update = FALSE;
-				}
-				else if (old_position_global != new_position_global)
-				{
-					send_update = TRUE;
 				}
 			}
 			selectNode->mLastPositionLocal  = object->getPosition();
@@ -1310,7 +1296,6 @@ void LLManipTranslate::renderSnapGuides()
 					// add in off-axis offset
 					tick_start += (mSnapOffsetAxis * mSnapOffsetMeters);
 
-					BOOL is_sub_tick = FALSE;
 					F32 tick_scale = 1.f;
 					for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
 					{
@@ -1319,7 +1304,6 @@ void LLManipTranslate::renderSnapGuides()
 							break;
 						}
 						tick_scale *= 0.7f;
-						is_sub_tick = TRUE;
 					}
 
 // 					S32 num_ticks_to_fade = is_sub_tick ? num_ticks_per_side / 2 : num_ticks_per_side;
@@ -1542,7 +1526,6 @@ void LLManipTranslate::renderSnapGuides()
 		
 		float a = line_alpha;
 
-		LLColor4 col = LLUIColorTable::instance().getColor("SilhouetteChildColor");
 		{
 			//draw grid behind objects
 			LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 99b4707158fbc9d8d2ff3119826dfbed8075d951..2075aeed63210d69a80e552a4f3361dc026b0eb3 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -119,8 +119,8 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
 
 	if(!getDecoupleTextureSize())
 	{
-		S32 screen_width = llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]);
-		S32 screen_height = llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]);
+		S32 screen_width = llround((F32)getRect().getWidth() * LLUI::getScaleFactor().mV[VX]);
+		S32 screen_height = llround((F32)getRect().getHeight() * LLUI::getScaleFactor().mV[VY]);
 			
 		setTextureSize(screen_width, screen_height);
 	}
@@ -469,8 +469,8 @@ void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
 {
 	if(!getDecoupleTextureSize())
 	{
-		S32 screen_width = llround((F32)width * LLUI::sGLScaleFactor.mV[VX]);
-		S32 screen_height = llround((F32)height * LLUI::sGLScaleFactor.mV[VY]);
+		S32 screen_width = llround((F32)width * LLUI::getScaleFactor().mV[VX]);
+		S32 screen_height = llround((F32)height * LLUI::getScaleFactor().mV[VY]);
 
 		// when floater is minimized, these sizes are negative
 		if ( screen_height > 0 && screen_width > 0 )
@@ -667,7 +667,7 @@ bool LLMediaCtrl::ensureMediaSourceExists()
 			mMediaSource->addObserver( this );
 			mMediaSource->setBackgroundColor( getBackgroundColor() );
 			mMediaSource->setTrustedBrowser(mTrusted);
-			mMediaSource->setPageZoomFactor( LLUI::sGLScaleFactor.mV[ VX ] );
+			mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
 
 			if(mClearCache)
 			{
@@ -750,7 +750,7 @@ void LLMediaCtrl::draw()
 	{
 		gGL.pushUIMatrix();
 		{
-			mMediaSource->setPageZoomFactor( LLUI::sGLScaleFactor.mV[ VX ] );
+			mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
 
 			// scale texture to fit the space using texture coords
 			gGL.getTexUnit(0)->bind(media_texture);
@@ -864,14 +864,14 @@ void LLMediaCtrl::convertInputCoords(S32& x, S32& y)
 		coords_opengl = mMediaSource->getMediaPlugin()->getTextureCoordsOpenGL();
 	}
 	
-	x = llround((F32)x * LLUI::sGLScaleFactor.mV[VX]);
+	x = llround((F32)x * LLUI::getScaleFactor().mV[VX]);
 	if ( ! coords_opengl )
 	{
-		y = llround((F32)(y) * LLUI::sGLScaleFactor.mV[VY]);
+		y = llround((F32)(y) * LLUI::getScaleFactor().mV[VY]);
 	}
 	else
 	{
-		y = llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]);
+		y = llround((F32)(getRect().getHeight() - y) * LLUI::getScaleFactor().mV[VY]);
 	};
 }
 
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 31038b4aaca1c5e63653597c2f9ce0513762520b..e3b46d5d2f3fd7727d844cf69d51e1c3e94b330f 100644
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -564,7 +564,7 @@ LLMediaDataClient::Responder::Responder(const request_ptr_t &request)
 }
 
 /*virtual*/
-void LLMediaDataClient::Responder::error(U32 status, const std::string& reason)
+void LLMediaDataClient::Responder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
 	mRequest->stopTracking();
 
@@ -596,8 +596,8 @@ void LLMediaDataClient::Responder::error(U32 status, const std::string& reason)
 	}
 	else 
 	{
-		std::string msg = boost::lexical_cast<std::string>(status) + ": " + reason;
-		LL_WARNS("LLMediaDataClient") << *mRequest << " http error(" << msg << ")" << LL_ENDL;
+		LL_WARNS("LLMediaDataClient") << *mRequest << " http error [status:" 
+				<< status << "]:" << content << ")" << LL_ENDL;
 	}
 }
 
@@ -1003,7 +1003,7 @@ LLMediaDataClient::Responder *LLObjectMediaNavigateClient::RequestNavigate::crea
 }
 
 /*virtual*/
-void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string& reason)
+void LLObjectMediaNavigateClient::Responder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
 	getRequest()->stopTracking();
 
@@ -1017,7 +1017,7 @@ void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string
 	// class
 	if (status == HTTP_SERVICE_UNAVAILABLE)
 	{
-		LLMediaDataClient::Responder::error(status, reason);
+		LLMediaDataClient::Responder::errorWithContent(status, reason, content);
 	}
 	else
 	{
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index ab90915c555410284ee0fa339eddd47a98bf3598..89e20a28d097e95c732b206fb509a9ec7498ea61 100644
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -195,7 +195,7 @@ class LLMediaDataClient : public LLRefCount
 	public:
 		Responder(const request_ptr_t &request);
 		//If we get back an error (not found, etc...), handle it here
-		virtual void error(U32 status, const std::string& reason);
+		virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 		//If we get back a normal response, handle it here.	 Default just logs it.
 		virtual void result(const LLSD& content);
 
@@ -400,7 +400,7 @@ class LLObjectMediaNavigateClient : public LLMediaDataClient
     public:
         Responder(const request_ptr_t &request)
             : LLMediaDataClient::Responder(request) {}
-		virtual void error(U32 status, const std::string& reason);
+		virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
         virtual void result(const LLSD &content);
     private:
         void mediaNavigateBounceBack();
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 1223615079772e274ff703f6ea17e85964ca2c5f..17311dd75e5663efc98bf5f5b5ceaff5acb1eb89 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -3222,6 +3222,7 @@ void LLPhysicsDecomp::doDecomposition()
 		param_map[params[i].mName] = params+i;
 	}
 
+	U32 ret = LLCD_OK;
 	//set parameter values
 	for (decomp_params::iterator iter = mCurRequest->mParams.begin(); iter != mCurRequest->mParams.end(); ++iter)
 	{
@@ -3235,7 +3236,6 @@ void LLPhysicsDecomp::doDecomposition()
 			continue;
 		}
 
-		U32 ret = LLCD_OK;
 
 		if (param->mType == LLCDParam::LLCD_FLOAT)
 		{
@@ -3254,8 +3254,6 @@ void LLPhysicsDecomp::doDecomposition()
 
 	mCurRequest->setStatusMessage("Executing.");
 
-	LLCDResult ret = LLCD_OK;
-	
 	if (LLConvexDecomposition::getInstance() != NULL)
 	{
 		ret = LLConvexDecomposition::getInstance()->executeStage(stage);
diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp
index eaa044cb593053442337d8aedc3578fb7edfb42e..252d1b78ea013e96402ee87f4cd704acddb104b4 100644
--- a/indra/newview/llmorphview.cpp
+++ b/indra/newview/llmorphview.cpp
@@ -99,8 +99,6 @@ void	LLMorphView::initialize()
 //-----------------------------------------------------------------------------
 void	LLMorphView::shutdown()
 {
-	LLVOAvatarSelf::onCustomizeEnd();
-
 	if (isAgentAvatarValid())
 	{
 		gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE );
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 1bda7640bd32825149e429ab3a451a85adfd5692..dea90b90426f1ee72360ecf39418b8a2667e9e04 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -150,7 +150,7 @@ void LLNetMap::draw()
 	static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white);
 	static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white);
 	static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
-	static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
+	//static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
 	static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
 	static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
 	
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index a346909027d7a37a6c0e1bf874461131e8142bc3..0682af1278c95dda4fde4c44b32255d2f982893f 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -31,7 +31,7 @@
 #include "../llui/llview.h"
 #include "llmutelist.h"
 #include "llspeakingindicatormanager.h"
-#include "../llui/lluiimage.h"
+//#include "../llui/lluiimage.h"
 
 class LLTextBox;
 class LLUICtrlFactory;
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 6889b98ab1778e46ef334cb8f6d81b026c5df9c7..862e4be203a5dea41b621fc98acf92b814b7bd2d 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -55,6 +55,7 @@
 #include "lltrans.h"
 #include "llscrollcontainer.h"
 #include "llstatusbar.h"
+#include "llviewertexture.h"
 
 const S32 MINIMUM_PRICE_FOR_LISTING = 50;	// L$
 
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index 77e1487f3835764938b749fae338a67cfb70c95b..1a427338e5ae54c2cd11b41d743538bc1010388a 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -78,8 +78,6 @@ const char* LLPanelContents::PERMS_ANYONE_CONTROL_KEY = "perms_anyone_control";
 
 BOOL LLPanelContents::postBuild()
 {
-	LLRect rect = this->getRect();
-
 	setMouseOpaque(FALSE);
 
 	childSetAction("button new script",&LLPanelContents::onClickNewScript, this);
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 6b9edcb07c6f890a3835d5e2b09271d778209adf..e71dba5caee73871c17c7e9d531ceeed95a2b2a2 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -28,7 +28,7 @@
 
 #include "llpaneleditwearable.h"
 #include "llpanel.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
 #include "lluictrl.h"
 #include "llscrollingpanellist.h"
 #include "llvisualparam.h"
@@ -52,6 +52,7 @@
 #include "lltexturectrl.h"
 #include "lltextureentry.h"
 #include "llviewercontrol.h"    // gSavedSettings
+#include "llviewerregion.h"
 #include "llviewertexturelist.h"
 #include "llagentcamera.h"
 #include "llmorphview.h"
@@ -104,7 +105,7 @@ enum ESubpart {
         SUBPART_PHYSICS_ADVANCED,
  };
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 typedef std::vector<ESubpart> subpart_vec_t;
 
@@ -718,8 +719,8 @@ BOOL LLPanelEditWearable::postBuild()
         mBtnBack = getChild<LLButton>("back_btn");
         mBackBtnLabel = mBtnBack->getLabelUnselected();
         mBtnBack->setLabel(LLStringUtil::null);
-        // handled at appearance panel level?
-        //mBtnBack->setClickedCallback(boost::bind(&LLPanelEditWearable::onBackButtonClicked, this));
+
+        mBtnBack->setClickedCallback(boost::bind(&LLPanelEditWearable::onBackButtonClicked, this));
 
         mNameEditor = getChild<LLLineEditor>("description");
 
@@ -762,11 +763,11 @@ BOOL LLPanelEditWearable::postBuild()
 
         mWearablePtr = NULL;
 
-        configureAlphaCheckbox(LLVOAvatarDefines::TEX_LOWER_ALPHA, "lower alpha texture invisible");
-        configureAlphaCheckbox(LLVOAvatarDefines::TEX_UPPER_ALPHA, "upper alpha texture invisible");
-        configureAlphaCheckbox(LLVOAvatarDefines::TEX_HEAD_ALPHA, "head alpha texture invisible");
-        configureAlphaCheckbox(LLVOAvatarDefines::TEX_EYES_ALPHA, "eye alpha texture invisible");
-        configureAlphaCheckbox(LLVOAvatarDefines::TEX_HAIR_ALPHA, "hair alpha texture invisible");
+        configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_LOWER_ALPHA, "lower alpha texture invisible");
+        configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_UPPER_ALPHA, "upper alpha texture invisible");
+        configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_HEAD_ALPHA, "head alpha texture invisible");
+        configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_EYES_ALPHA, "eye alpha texture invisible");
+        configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_HAIR_ALPHA, "hair alpha texture invisible");
 
         // configure tab expanded callbacks
         for (U32 type_index = 0; type_index < (U32)LLWearableType::WT_COUNT; ++type_index)
@@ -856,6 +857,14 @@ void LLPanelEditWearable::draw()
         LLPanel::draw();
 }
 
+void LLPanelEditWearable::onClose()
+{
+	if ( isDirty() )
+	{
+		revertChanges();
+	}
+}
+
 void LLPanelEditWearable::setVisible(BOOL visible)
 {
         if (!visible)
@@ -865,13 +874,22 @@ void LLPanelEditWearable::setVisible(BOOL visible)
         LLPanel::setVisible(visible);
 }
 
-void LLPanelEditWearable::setWearable(LLWearable *wearable, BOOL disable_camera_switch)
+void LLPanelEditWearable::setWearable(LLViewerWearable *wearable, BOOL disable_camera_switch)
 {
         showWearable(mWearablePtr, FALSE, disable_camera_switch);
         mWearablePtr = wearable;
         showWearable(mWearablePtr, TRUE, disable_camera_switch);
 }
 
+//static 
+void LLPanelEditWearable::onBackButtonClicked(void* userdata)
+{
+    LLPanelEditWearable *panel = (LLPanelEditWearable*) userdata;
+	if ( panel->isDirty() )
+	{
+		LLAppearanceMgr::instance().setOutfitDirty( true );		
+	}
+}
 
 //static 
 void LLPanelEditWearable::onRevertButtonClicked(void* userdata)
@@ -922,7 +940,7 @@ void LLPanelEditWearable::onCommitSexChange()
         }
 
         bool is_new_sex_male = (gSavedSettings.getU32("AvatarSex") ? SEX_MALE : SEX_FEMALE) == SEX_MALE;
-        LLWearable*     wearable = gAgentWearables.getWearable(type, index);
+        LLViewerWearable*     wearable = gAgentWearables.getViewerWearable(type, index);
         if (wearable)
         {
                 wearable->setVisualParamWeight(param->getID(), is_new_sex_male, FALSE);
@@ -1007,13 +1025,11 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)
                 return;
 
         bool is_modifiable = false;
-        bool is_copyable   = false;
 
         if(mWearableItem)
         {
                 const LLPermissions& perm = mWearableItem->getPermissions();
                 is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID());
-                is_copyable = perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID());
         }
 
         if (is_modifiable)
@@ -1030,6 +1046,11 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)
         }
 }
 
+void LLPanelEditWearable::incrementCofVersionLegacy()
+{
+
+}
+
 void LLPanelEditWearable::saveChanges(bool force_save_as)
 {
         if (!mWearablePtr || !isDirty())
@@ -1041,17 +1062,50 @@ void LLPanelEditWearable::saveChanges(bool force_save_as)
         U32 index = gAgentWearables.getWearableIndex(mWearablePtr);
 
         std::string new_name = mNameEditor->getText();
+
+		// Find an existing link to this wearable's inventory item, if any, and its description field.
+		LLInventoryItem *link_item = NULL;
+		std::string description;
+		LLInventoryModel::item_array_t links =
+			LLAppearanceMgr::instance().findCOFItemLinks(mWearablePtr->getItemID());
+		if (links.size()>0)
+		{
+			link_item = links.get(0).get();
+			if (link_item && link_item->getIsLinkType())
+			{
+				description = link_item->getActualDescription();
+			}
+		}
+
         if (force_save_as)
         {
                 // the name of the wearable has changed, re-save wearable with new name
-                LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID(),false);
-                gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, FALSE);
+                LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID());
+			gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, description, FALSE);
                 mNameEditor->setText(mWearableItem->getName());
         }
         else
         {
+			// Make another copy of this link, with the same
+			// description.  This is needed to bump the COF
+			// version so texture baking service knows appearance has changed.
+			if (link_item)
+			{
+				// Create new link
+				link_inventory_item( gAgent.getID(),
+									 link_item->getLinkedUUID(),
+									 LLAppearanceMgr::instance().getCOF(),
+									 link_item->getName(),
+									 description,
+									 LLAssetType::AT_LINK,
+									 NULL);
+				// Remove old link
+				gInventory.purgeObject(link_item->getUUID());
+			}
                 gAgentWearables.saveWearable(mWearablePtr->getType(), index, TRUE, new_name);
         }
+
+	
 }
 
 void LLPanelEditWearable::revertChanges()
@@ -1069,7 +1123,7 @@ void LLPanelEditWearable::revertChanges()
         gAgentAvatarp->wearableUpdated(mWearablePtr->getType(), FALSE);
 }
 
-void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show, BOOL disable_camera_switch)
+void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BOOL disable_camera_switch)
 {
         if (!wearable)
         {
@@ -1440,12 +1494,11 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value
         {
                 panel_list->clearPanels();
                 value_map_t::iterator end = sorted_params.end();
-                S32 height = 0;
                 for(value_map_t::iterator it = sorted_params.begin(); it != end; ++it)
                 {
                         LLPanel::Params p;
                         p.name("LLScrollingPanelParam");
-                        LLWearable *wearable = this->getWearable();
+                        LLViewerWearable *wearable = this->getWearable();
                         LLScrollingPanelParamBase *panel_param = NULL;
                         if (wearable && wearable->getType() == LLWearableType::WT_PHYSICS) // Hack to show a different panel for physics.  Should generalize this later.
                         {
@@ -1455,7 +1508,7 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value
                         {
                                 panel_param = new LLScrollingPanelParam( p, NULL, (*it).second, TRUE, this->getWearable(), jointp);
                         }
-                        height = panel_list->addPanel( panel_param );
+                        panel_list->addPanel( panel_param );
                 }
         }
 }
@@ -1505,7 +1558,7 @@ void LLPanelEditWearable::updateVerbs()
         }
 }
 
-void LLPanelEditWearable::configureAlphaCheckbox(LLVOAvatarDefines::ETextureIndex te, const std::string& name)
+void LLPanelEditWearable::configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name)
 {
         LLCheckBoxCtrl* checkbox = mPanelAlpha->getChild<LLCheckBoxCtrl>(name);
         checkbox->setCommitCallback(boost::bind(&LLPanelEditWearable::onInvisibilityCommit, this, checkbox, te));
@@ -1513,7 +1566,7 @@ void LLPanelEditWearable::configureAlphaCheckbox(LLVOAvatarDefines::ETextureInde
         mAlphaCheckbox2Index[name] = te;
 }
 
-void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLVOAvatarDefines::ETextureIndex te)
+void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te)
 {
         if (!checkbox_ctrl) return;
         if (!getWearable()) return;
@@ -1557,7 +1610,7 @@ void LLPanelEditWearable::updateAlphaCheckboxes()
         for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin();
                 iter != mAlphaCheckbox2Index.end(); ++iter )
         {
-                LLVOAvatarDefines::ETextureIndex te = (LLVOAvatarDefines::ETextureIndex)iter->second;
+                LLAvatarAppearanceDefines::ETextureIndex te = (LLAvatarAppearanceDefines::ETextureIndex)iter->second;
                 LLCheckBoxCtrl* ctrl = mPanelAlpha->getChild<LLCheckBoxCtrl>(iter->first);
                 if (ctrl)
                 {
@@ -1575,7 +1628,7 @@ void LLPanelEditWearable::initPreviousAlphaTextures()
         initPreviousAlphaTextureEntry(TEX_LOWER_ALPHA);
 }
 
-void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te)
+void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te)
 {
         LLLocalTextureObject *lto = getWearable()->getLocalTextureObject(te);
         if (lto)
diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h
index 692a7ce90fa06df8939da6d094ca1acbb3ec9614..6533d55f2fc6e1ea9cc141d0023689fd9e7a92ef 100644
--- a/indra/newview/llpaneleditwearable.h
+++ b/indra/newview/llpaneleditwearable.h
@@ -30,12 +30,12 @@
 #include "llpanel.h"
 #include "llscrollingpanellist.h"
 #include "llmodaldialog.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
 #include "llwearabletype.h"
 
 class LLAccordionCtrl;
 class LLCheckBoxCtrl;
-class LLWearable;
+class LLViewerWearable;
 class LLTextBox;
 class LLViewerInventoryItem;
 class LLViewerVisualParam;
@@ -54,12 +54,13 @@ class LLPanelEditWearable : public LLPanel
 	/*virtual*/ BOOL 		postBuild();
 	/*virtual*/ BOOL		isDirty() const;	// LLUICtrl
 	/*virtual*/ void		draw();	
+				void		onClose();
 
 	// changes camera angle to default for selected subpart
 	void				changeCamera(U8 subpart);
 
-	LLWearable* 		getWearable() { return mWearablePtr; }
-	void				setWearable(LLWearable *wearable, BOOL disable_camera_switch = FALSE);
+	LLViewerWearable*	getWearable() { return mWearablePtr; }
+	void				setWearable(LLViewerWearable *wearable, BOOL disable_camera_switch = FALSE);
 
 	void				saveChanges(bool force_save_as = false);
 	void				revertChanges();
@@ -70,17 +71,17 @@ class LLPanelEditWearable : public LLPanel
 	void 				updateScrollingPanelList();
 
 	static void			onRevertButtonClicked(void* userdata);
+	static void			onBackButtonClicked(void* userdata); 
 	void				onCommitSexChange();
 	void				onSaveAsButtonClicked();
 	void				saveAsCallback(const LLSD& notification, const LLSD& response);
 
 	virtual void		setVisible(BOOL visible);
 
-
 private:
 	typedef std::map<F32, LLViewerVisualParam*> value_map_t;
 
-	void				showWearable(LLWearable* wearable, BOOL show, BOOL disable_camera_switch = FALSE);
+	void				showWearable(LLViewerWearable* wearable, BOOL show, BOOL disable_camera_switch = FALSE);
 	void				updateScrollingPanelUI();
 	LLPanel*			getPanel(LLWearableType::EType type);
 	void				getSortedParams(value_map_t &sorted_params, const std::string &edit_group);
@@ -94,17 +95,17 @@ class LLPanelEditWearable : public LLPanel
 	void				toggleTypeSpecificControls(LLWearableType::EType type);
 	void				updateTypeSpecificControls(LLWearableType::EType type);
 
-	//alpha mask checkboxes
-	void configureAlphaCheckbox(LLVOAvatarDefines::ETextureIndex te, const std::string& name);
-	void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLVOAvatarDefines::ETextureIndex te);
+	// alpha mask checkboxes
+	void configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name);
+	void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te);
 	void updateAlphaCheckboxes();
 	void initPreviousAlphaTextures();
-	void initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te);
+	void initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te);
 
 	// callback for HeightUnits parameter.
 	bool changeHeightUnits(const LLSD& new_value);
 
-	// updates current metric and replacemet metric label text
+	// updates current metric and replacement metric label text
 	void updateMetricLayout(BOOL new_value);
 
 	// updates avatar height label
@@ -114,8 +115,11 @@ class LLPanelEditWearable : public LLPanel
 
 	void setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel);
 
+	// *HACK Remove this when serverside texture baking is available on all regions.
+	void incrementCofVersionLegacy();
+
 	// the pointer to the wearable we're editing. NULL means we're not editing a wearable.
-	LLWearable *mWearablePtr;
+	LLViewerWearable *mWearablePtr;
 	LLViewerInventoryItem* mWearableItem;
 
 	// these are constant no matter what wearable we're editing
@@ -128,7 +132,7 @@ class LLPanelEditWearable : public LLPanel
 	LLTextBox *mTxtAvatarHeight;
 
 
-	// localized and parametrized strings that used to build avatar_height_label
+	// localized and parameterized strings that used to build avatar_height_label
 	std::string mMeters;
 	std::string mFeet;
 	std::string mHeigth;
@@ -151,7 +155,7 @@ class LLPanelEditWearable : public LLPanel
 	LLPanel *mPanelEyes;
 	LLPanel *mPanelHair;
 
-	//clothes
+	// clothes
 	LLPanel *mPanelShirt;
 	LLPanel *mPanelPants;
 	LLPanel *mPanelShoes;
@@ -165,10 +169,10 @@ class LLPanelEditWearable : public LLPanel
 	LLPanel *mPanelTattoo;
 	LLPanel *mPanelPhysics;
 
-	typedef std::map<std::string, LLVOAvatarDefines::ETextureIndex> string_texture_index_map_t;
+	typedef std::map<std::string, LLAvatarAppearanceDefines::ETextureIndex> string_texture_index_map_t;
 	string_texture_index_map_t mAlphaCheckbox2Index;
 
-	typedef std::map<LLVOAvatarDefines::ETextureIndex, LLUUID> s32_uuid_map_t;
+	typedef std::map<LLAvatarAppearanceDefines::ETextureIndex, LLUUID> s32_uuid_map_t;
 	s32_uuid_map_t mPreviousAlphaTexture;
 };
 
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 202be9671b4d4bdb092b69391c7f518de57fecba..445c0d811f202a76c7e701eb46e8440d84b6557d 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -84,7 +84,6 @@ BOOL	LLPanelFace::postBuild()
 	childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
 	childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
 
-	LLRect	rect = this->getRect();
 	LLTextureCtrl*	mTextureCtrl;
 	LLColorSwatchCtrl*	mColorSwatch;
 
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index 37755fb851a5b75e7b8154d898d072b260cd5e46..c927aeacb30d4b495e9110bc5501ce5595042ea4 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -1383,13 +1383,11 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
 	S32 cur_land_tax;
 	S32 cur_group_tax;
 	S32 cur_parcel_dir_fee;
-	S32 cur_total_tax;
 	S32 proj_object_tax;
 	S32 proj_light_tax;
 	S32 proj_land_tax;
 	S32 proj_group_tax;
 	S32 proj_parcel_dir_fee;
-	S32 proj_total_tax;
 	S32	non_exempt_members;
 
 	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_IntervalDays, interval_days );
@@ -1413,8 +1411,6 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
 	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_LastTaxDate, last_stipend_date);
 	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_TaxDate, next_stipend_date);
 
-	cur_total_tax = cur_object_tax + cur_light_tax + cur_land_tax + cur_group_tax +  cur_parcel_dir_fee;
-	proj_total_tax = proj_object_tax + proj_light_tax + proj_land_tax + proj_group_tax + proj_parcel_dir_fee;
 
 	if (interval_days != mImplementationp->mIntervalLength || 
 		current_interval != mImplementationp->mCurrentInterval)
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 93b108efcc78399bbbd2306f2fe5ef39b7ddab06..522ba5afae403b2c17f3492adf4200ab0dbf7e09 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -35,6 +35,7 @@
 #include "llviewerinventory.h"
 #include "llinventorydefines.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"
 #include "llfloaterinventory.h"
 #include "llagent.h"
diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp
index 04c1a86f69fd73fee2dfc166aba0e7ea25ab45b2..5321ebc7773d5d8d825885840d38f06f57ab3522 100644
--- a/indra/newview/llpanelland.cpp
+++ b/indra/newview/llpanelland.cpp
@@ -166,7 +166,7 @@ void LLPanelLandInfo::refresh()
 		getChildView("button abandon land")->setEnabled(owner_release || manager_releaseable || gAgent.isGodlike());
 
 		// only mainland sims are subdividable by owner
-		if (regionp->getRegionFlags() && REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+		if (regionp->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
 		{
 			getChildView("button subdivide land")->setEnabled(owner_divide || manager_divideable || gAgent.isGodlike());
 		}
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index c57746ec00abe8a5f31992612fc18c1b1c8256ca..5c9b968ac908e3c5b19b0c8af053df0d6b60e712 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -209,24 +209,6 @@ void LLPanelLandmarkInfo::processParcelInfo(const LLParcelData& parcel_data)
 		mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_PG));
 	}
 
-	S32 region_x;
-	S32 region_y;
-	S32 region_z;
-
-	// If the region position is zero, grab position from the global
-	if(mPosRegion.isExactlyZero())
-	{
-		region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
-		region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
-		region_z = llround(parcel_data.global_z);
-	}
-	else
-	{
-		region_x = llround(mPosRegion.mV[VX]);
-		region_y = llround(mPosRegion.mV[VY]);
-		region_z = llround(mPosRegion.mV[VZ]);
-	}
-
 	LLSD info;
 	info["update_verbs"] = true;
 	info["global_x"] = parcel_data.global_x;
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index d87b565b328d1b6fe6a0b98f177b11babf98a3ae..25ef9a3d6a7f280efb1e2452c5e60382b0afbb0e 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -439,10 +439,9 @@ void LLPanelObject::getState( )
 	mCtrlRotY->setEnabled( enable_rotate );
 	mCtrlRotZ->setEnabled( enable_rotate );
 
-	BOOL owners_identical;
 	LLUUID owner_id;
 	std::string owner_name;
-	owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
+	LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
 
 	// BUG? Check for all objects being editable?
 	S32 roots_selected = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 7555ac7b2caf9510ce5ee0d3351fc2517c6ae165..d7130820ab0b6b0bd6e4a1d0905946edccce31fe 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -47,6 +47,7 @@
 #include "llfolderview.h"
 #include "llinventorybridge.h"
 #include "llinventorydefines.h"
+#include "llinventoryicon.h"
 #include "llinventoryfilter.h"
 #include "llinventoryfunctions.h"
 #include "llpreviewanim.h"
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index e641370d2eb0d15960931d1a49f8611973643f3e..131e8e9359122b1a9d0a701a2d4654590845d2b7 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -365,10 +365,8 @@ void LLPanelPermissions::refresh()
 	
 	// Update creator text field
 	getChildView("Creator:")->setEnabled(TRUE);
-	BOOL creators_identical;
 	std::string creator_name;
-	creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID,
-																	  creator_name);
+	LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name);
 
 	getChild<LLUICtrl>("Creator Name")->setValue(creator_name);
 	getChildView("Creator Name")->setEnabled(TRUE);
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index 83b70d9f29868d4b2708b186c36216992923d9d7..5d9971c16c14ad562dc7a8e9aaa32b42bbf453c0 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -568,7 +568,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 
 		mTerraformLimitsText->setText(parcel->getAllowTerraform() ? on : off);
 
-		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+		if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
 		{
 			mSubdivideText->setText(getString("can_change"));
 		}
@@ -576,7 +576,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 		{
 			mSubdivideText->setText(getString("can_not_change"));
 		}
-		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+		if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
 		{
 			mResaleText->setText(getString("can_not_resell"));
 		}
diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp
index 343c140bbbe4435be6d46a93fa3a9b0c05071ddd..9dd665198f6b7d165e505c14ff7113c126fd943f 100644
--- a/indra/newview/llpaneltopinfobar.cpp
+++ b/indra/newview/llpaneltopinfobar.cpp
@@ -417,11 +417,11 @@ void LLPanelTopInfoBar::onParcelIconClick(EParcelIcon icon)
 	case SCRIPTS_ICON:
 	{
 		LLViewerRegion* region = gAgent.getRegion();
-		if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
+		if(region && region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS))
 		{
 			LLNotificationsUtil::add("ScriptsStopped");
 		}
-		else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
+		else if(region && region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS))
 		{
 			LLNotificationsUtil::add("ScriptsNotRunning");
 		}
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 13b746dbabb3ccc24f6006e97f1971819e4eafeb..02d363d7952eb3d99e74feedeef75014b4162dec 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -252,10 +252,9 @@ void LLPanelVolume::getState( )
 		return;
 	}
 
-	BOOL owners_identical;
 	LLUUID owner_id;
 	std::string owner_name;
-	owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
+	LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
 
 	// BUG? Check for all objects being editable?
 	BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced();
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index 3b9934d4be36b08b941ac55b711a455af598fc3d..aa3ed22bee8b7b089e559e9187c0f0391a5da882 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -77,11 +77,7 @@ class LLWearingGearMenu
 	{
 		uuid_vec_t selected_uuids;
 		mPanelWearing->getSelectedItemsUUIDs(selected_uuids);
-
-		for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it)
-		{
-				LLAppearanceMgr::instance().removeItemFromAvatar(*it);
-		}
+		LLAppearanceMgr::instance().removeItemsFromAvatar(selected_uuids);
 	}
 
 	LLToggleableMenu*		mMenu;
@@ -97,12 +93,11 @@ class LLWearingContextMenu : public LLListContextMenu
 	{
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 
-		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
-
 		registrar.add("Wearing.Edit", boost::bind(&edit_outfit));
-		registrar.add("Wearing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs));
-		registrar.add("Wearing.Detach", boost::bind(handleMultiple, take_off, mUUIDs));
-
+		registrar.add("Wearing.TakeOff",
+					  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
+		registrar.add("Wearing.Detach", 
+					  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
 		LLContextMenu* menu = createFromFile("menu_wearing_tab.xml");
 
 		updateMenuItemsVisibility(menu);
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index 2dd01e931e097b9c510adfab4af61b63b772401a..c277359133285f460f0000c587b14118ff9dd854 100644
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -108,7 +108,7 @@ class NavMeshStatusResponder : public LLHTTPClient::Responder
 	virtual ~NavMeshStatusResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 
 protected:
 
@@ -130,7 +130,7 @@ class NavMeshResponder : public LLHTTPClient::Responder
 	virtual ~NavMeshResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 
 protected:
 
@@ -151,7 +151,7 @@ class AgentStateResponder : public LLHTTPClient::Responder
 	virtual ~AgentStateResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 
 protected:
 
@@ -170,7 +170,7 @@ class NavMeshRebakeResponder : public LLHTTPClient::Responder
 	virtual ~NavMeshRebakeResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 
 protected:
 
@@ -190,9 +190,11 @@ class LinksetsResponder
 	virtual ~LinksetsResponder();
 
 	void handleObjectLinksetsResult(const LLSD &pContent);
-	void handleObjectLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL);
+	void handleObjectLinksetsError(U32 pStatus, const std::string &pReason, 
+								   const LLSD& pContent, const std::string &pURL);
 	void handleTerrainLinksetsResult(const LLSD &pContent);
-	void handleTerrainLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL);
+	void handleTerrainLinksetsError(U32 pStatus, const std::string &pReason,
+									const LLSD& pContent, const std::string &pURL);
 
 protected:
 
@@ -230,7 +232,7 @@ class ObjectLinksetsResponder : public LLHTTPClient::Responder
 	virtual ~ObjectLinksetsResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string &pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
 
 protected:
 
@@ -250,7 +252,7 @@ class TerrainLinksetsResponder : public LLHTTPClient::Responder
 	virtual ~TerrainLinksetsResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string &pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
 
 protected:
 
@@ -270,7 +272,7 @@ class CharactersResponder : public LLHTTPClient::Responder
 	virtual ~CharactersResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string &pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
 
 protected:
 
@@ -800,9 +802,9 @@ void NavMeshStatusResponder::result(const LLSD &pContent)
 	LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
 }
 
-void NavMeshStatusResponder::error(U32 pStatus, const std::string& pReason)
+void NavMeshStatusResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
 {
-	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "NavMeshStatusResponder error [status:" << pStatus << "]: " << pContent << llendl;
 	LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID);
 	LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
 }
@@ -828,9 +830,9 @@ void NavMeshResponder::result(const LLSD &pContent)
 	mNavMeshPtr->handleNavMeshResult(pContent, mNavMeshVersion);
 }
 
-void NavMeshResponder::error(U32 pStatus, const std::string& pReason)
+void NavMeshResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
 {
-	mNavMeshPtr->handleNavMeshError(pStatus, pReason, mCapabilityURL, mNavMeshVersion);
+	mNavMeshPtr->handleNavMeshError(pStatus, pReason, pContent, mCapabilityURL, mNavMeshVersion);
 }
 
 //---------------------------------------------------------------------------
@@ -855,9 +857,9 @@ void AgentStateResponder::result(const LLSD &pContent)
 	LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion);
 }
 
-void AgentStateResponder::error(U32 pStatus, const std::string &pReason)
+void AgentStateResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
 {
-	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "AgentStateResponder error [status:" << pStatus << "]: " << pContent << llendl;
 	LLPathfindingManager::getInstance()->handleAgentState(FALSE);
 }
 
@@ -881,9 +883,9 @@ void NavMeshRebakeResponder::result(const LLSD &pContent)
 	mRebakeNavMeshCallback(true);
 }
 
-void NavMeshRebakeResponder::error(U32 pStatus, const std::string &pReason)
+void NavMeshRebakeResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
 {
-	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "NavMeshRebakeResponder error [status:" << pStatus << "]: " << pContent << llendl;
 	mRebakeNavMeshCallback(false);
 }
 
@@ -916,9 +918,11 @@ void LinksetsResponder::handleObjectLinksetsResult(const LLSD &pContent)
 	}
 }
 
-void LinksetsResponder::handleObjectLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL)
+void LinksetsResponder::handleObjectLinksetsError(U32 pStatus, const std::string &pReason,
+												 const LLSD& pContent, const std::string &pURL)
 {
-	llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "LinksetsResponder object linksets error with request to URL '" << pURL << "' [status:"
+			<< pStatus << "]: " << pContent << llendl;
 	mObjectMessagingState = kReceivedError;
 	if (mTerrainMessagingState != kWaiting)
 	{
@@ -937,8 +941,11 @@ void LinksetsResponder::handleTerrainLinksetsResult(const LLSD &pContent)
 	}
 }
 
-void LinksetsResponder::handleTerrainLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL)
+void LinksetsResponder::handleTerrainLinksetsError(U32 pStatus, const std::string &pReason,
+												   const LLSD& pContent, const std::string &pURL)
 {
+	llwarns << "LinksetsResponder terrain linksets error with request to URL '" << pURL << "' [status:"
+			<< pStatus << "]: " << pContent << llendl;
 	mTerrainMessagingState = kReceivedError;
 	if (mObjectMessagingState != kWaiting)
 	{
@@ -988,9 +995,9 @@ void ObjectLinksetsResponder::result(const LLSD &pContent)
 	mLinksetsResponsderPtr->handleObjectLinksetsResult(pContent);
 }
 
-void ObjectLinksetsResponder::error(U32 pStatus, const std::string &pReason)
+void ObjectLinksetsResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
 {
-	mLinksetsResponsderPtr->handleObjectLinksetsError(pStatus, pReason, mCapabilityURL);
+	mLinksetsResponsderPtr->handleObjectLinksetsError(pStatus, pReason, pContent, mCapabilityURL);
 }
 
 //---------------------------------------------------------------------------
@@ -1013,9 +1020,9 @@ void TerrainLinksetsResponder::result(const LLSD &pContent)
 	mLinksetsResponsderPtr->handleTerrainLinksetsResult(pContent);
 }
 
-void TerrainLinksetsResponder::error(U32 pStatus, const std::string &pReason)
+void TerrainLinksetsResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
 {
-	mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, mCapabilityURL);
+	mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, pContent, mCapabilityURL);
 }
 
 //---------------------------------------------------------------------------
@@ -1040,9 +1047,9 @@ void CharactersResponder::result(const LLSD &pContent)
 	mCharactersCallback(mRequestId, LLPathfindingManager::kRequestCompleted, characterListPtr);
 }
 
-void CharactersResponder::error(U32 pStatus, const std::string &pReason)
+void CharactersResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
 {
-	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "CharactersResponder error [status:" << pStatus << "]: " << pContent << llendl;
 
 	LLPathfindingObjectListPtr characterListPtr =  LLPathfindingObjectListPtr(new LLPathfindingCharacterList());
 	mCharactersCallback(mRequestId, LLPathfindingManager::kRequestError, characterListPtr);
diff --git a/indra/newview/llpathfindingnavmesh.cpp b/indra/newview/llpathfindingnavmesh.cpp
index e01dd3a152f78baf17db8aa69aea42fe29e7ea2d..0c23e5ac923785ae99a64625f321ad6b4af2bf1e 100644
--- a/indra/newview/llpathfindingnavmesh.cpp
+++ b/indra/newview/llpathfindingnavmesh.cpp
@@ -184,9 +184,10 @@ void LLPathfindingNavMesh::handleNavMeshError()
 	setRequestStatus(kNavMeshRequestError);
 }
 
-void LLPathfindingNavMesh::handleNavMeshError(U32 pStatus, const std::string &pReason, const std::string &pURL, U32 pNavMeshVersion)
+void LLPathfindingNavMesh::handleNavMeshError(U32 pStatus, const std::string &pReason, const LLSD& pContent, const std::string &pURL, U32 pNavMeshVersion)
 {
-	llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "LLPathfindingNavMesh error with request to URL '" << pURL << "' [status:"
+			<< pStatus << "]: " << pContent << llendl;
 	if (mNavMeshStatus.getVersion() == pNavMeshVersion)
 	{
 		handleNavMeshError();
diff --git a/indra/newview/llpathfindingnavmesh.h b/indra/newview/llpathfindingnavmesh.h
index 7a844f54cebf407f6350b8596a7f38e993d02467..b872ccad7cbd24235889a427beb36b512cd2c292 100644
--- a/indra/newview/llpathfindingnavmesh.h
+++ b/indra/newview/llpathfindingnavmesh.h
@@ -74,7 +74,7 @@ class LLPathfindingNavMesh
 	void handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion);
 	void handleNavMeshNotEnabled();
 	void handleNavMeshError();
-	void handleNavMeshError(U32 pStatus, const std::string &pReason, const std::string &pURL, U32 pNavMeshVersion);
+	void handleNavMeshError(U32 pStatus, const std::string &pReason, const LLSD& pContent, const std::string &pURL, U32 pNavMeshVersion);
 
 protected:
 
diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp
index cb6989c9dde1c42c7bb8c1d1a084ab36c573b515..3ee0746412f826b37ac211cebc4237bdde72b5a7 100644
--- a/indra/newview/llphysicsmotion.cpp
+++ b/indra/newview/llphysicsmotion.cpp
@@ -166,7 +166,7 @@ class LLPhysicsMotion
 		}
 
         
-        void setParamValue(LLViewerVisualParam *param,
+        void setParamValue(const LLViewerVisualParam *param,
                            const F32 new_value_local,
                                                    F32 behavior_maxeffect);
 
@@ -428,14 +428,13 @@ F32 LLPhysicsMotion::toLocal(const LLVector3 &world)
 F32 LLPhysicsMotion::calculateVelocity_local()
 {
 	const F32 world_to_model_scale = 100.0f;
-        LLJoint *joint = mJointState->getJoint();
-        const LLVector3 position_world = joint->getWorldPosition();
-        const LLQuaternion rotation_world = joint->getWorldRotation();
-        const LLVector3 last_position_world = mPosition_world;
+	LLJoint *joint = mJointState->getJoint();
+	const LLVector3 position_world = joint->getWorldPosition();
+	const LLVector3 last_position_world = mPosition_world;
 	const LLVector3 positionchange_world = (position_world-last_position_world) * world_to_model_scale;
-        const LLVector3 velocity_world = positionchange_world;
-        const F32 velocity_local = toLocal(velocity_world);
-        return velocity_local;
+	const LLVector3 velocity_world = positionchange_world;
+	const F32 velocity_local = toLocal(velocity_world);
+	return velocity_local;
 }
 
 F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local)
@@ -673,12 +672,10 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
 								 0,
 								 FALSE);
 			}
-			for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin();
-			     iter != driver_param->mDriven.end();
-			     ++iter)
+			S32 num_driven = driver_param->getDrivenParamsCount();
+			for (S32 i = 0; i < num_driven; ++i)
 			{
-				LLDrivenEntry &entry = (*iter);
-				LLViewerVisualParam *driven_param = entry.mParam;
+				const LLViewerVisualParam *driven_param = driver_param->getDrivenParam(i);
 				setParamValue(driven_param,position_new_local_clamped, behavior_maxeffect);
 			}
 		}
@@ -758,7 +755,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
 }
 
 // Range of new_value_local is assumed to be [0 , 1] normalized.
-void LLPhysicsMotion::setParamValue(LLViewerVisualParam *param,
+void LLPhysicsMotion::setParamValue(const LLViewerVisualParam *param,
                                     F32 new_value_normalized,
 				    F32 behavior_maxeffect)
 {
diff --git a/indra/newview/llpipelinelistener.cpp b/indra/newview/llpipelinelistener.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..20759239bf5f66663c8b77385d6bc56135b426da
--- /dev/null
+++ b/indra/newview/llpipelinelistener.cpp
@@ -0,0 +1,216 @@
+/**
+ * @file   llpipelinelistener.h
+ * @author Don Kjer
+ * @date   2012-07-09
+ * @brief  Implementation for LLPipelineListener
+ * 
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+
+#include "llpipelinelistener.h"
+
+#include "pipeline.h"
+#include "stringize.h"
+#include <sstream>
+#include "llviewermenu.h"
+
+
+namespace {
+	// Render Types
+	void toggle_render_types_wrapper(LLSD const& request)
+	{
+		for (LLSD::array_const_iterator iter = request["types"].beginArray();
+			iter != request["types"].endArray();
+			++iter)
+		{
+			U32 render_type = render_type_from_string( iter->asString() );
+			if ( render_type != 0 )
+			{
+				LLPipeline::toggleRenderTypeControl( (void*) render_type );
+			}
+		}
+	}
+
+	void has_render_type_wrapper(LLSD const& request)
+	{
+		LLEventAPI::Response response(LLSD(), request);
+		U32 render_type = render_type_from_string( request["type"].asString() );
+		if ( render_type != 0 )
+		{
+			response["value"] = LLPipeline::hasRenderTypeControl( (void*) render_type );
+		}
+		else
+		{
+			response.error(STRINGIZE("unknown type '" << request["type"].asString() << "'"));
+		}
+	}
+
+	void disable_all_render_types_wrapper(LLSD const& request)
+	{
+		gPipeline.clearAllRenderTypes();
+	}
+
+	void enable_all_render_types_wrapper(LLSD const& request)
+	{
+		gPipeline.setAllRenderTypes();
+	}
+
+	// Render Features
+	void toggle_render_features_wrapper(LLSD const& request)
+	{
+		for (LLSD::array_const_iterator iter = request["features"].beginArray();
+			iter != request["features"].endArray();
+			++iter)
+		{
+			U32 render_feature = feature_from_string( iter->asString() );
+			if ( render_feature != 0 )
+			{
+				LLPipeline::toggleRenderDebugControl( (void*) render_feature );
+			}
+		}
+	}
+
+	void has_render_feature_wrapper(LLSD const& request)
+	{
+		LLEventAPI::Response response(LLSD(), request);
+		U32 render_feature = feature_from_string( request["feature"].asString() );
+		if ( render_feature != 0 )
+		{
+			response["value"] = gPipeline.hasRenderDebugFeatureMask(render_feature);
+		}
+		else
+		{
+			response.error(STRINGIZE("unknown feature '" << request["feature"].asString() << "'"));
+		}
+	}
+
+	void disable_all_render_features_wrapper(LLSD const& request)
+	{
+		gPipeline.clearAllRenderDebugFeatures();
+	}
+
+	void enable_all_render_features_wrapper(LLSD const& request)
+	{
+		gPipeline.setAllRenderDebugFeatures();
+	}
+
+	// Render Info Displays
+	void toggle_info_displays_wrapper(LLSD const& request)
+	{
+		for (LLSD::array_const_iterator iter = request["displays"].beginArray();
+			iter != request["displays"].endArray();
+			++iter)
+		{
+			U32 info_display = info_display_from_string( iter->asString() );
+			if ( info_display != 0 )
+			{
+				LLPipeline::toggleRenderDebug( (void*) info_display );
+			}
+		}
+	}
+
+	void has_info_display_wrapper(LLSD const& request)
+	{
+		LLEventAPI::Response response(LLSD(), request);
+		U32 info_display = info_display_from_string( request["display"].asString() );
+		if ( info_display != 0 )
+		{
+			response["value"] = gPipeline.hasRenderDebugMask(info_display);
+		}
+		else
+		{
+			response.error(STRINGIZE("unknown display '" << request["display"].asString() << "'"));
+		}
+	}
+
+	void disable_all_info_displays_wrapper(LLSD const& request)
+	{
+		gPipeline.clearAllRenderDebugDisplays();
+	}
+
+	void enable_all_info_displays_wrapper(LLSD const& request)
+	{
+		gPipeline.setAllRenderDebugDisplays();
+	}
+
+}
+
+
+LLPipelineListener::LLPipelineListener():
+	LLEventAPI("LLPipeline",
+			   "API to te rendering pipeline.")
+{
+	// Render Types
+	add("toggleRenderTypes",
+		"Toggle rendering [\"types\"]:\n"
+		"See: llviewermenu.cpp:render_type_from_string for list of available types.",
+		&toggle_render_types_wrapper);
+	add("hasRenderType",
+		"Check if rendering [\"type\"] is enabled:\n"
+		"See: llviewermenu.cpp:render_type_from_string for list of available types.",
+		&has_render_type_wrapper,
+		LLSDMap("reply", LLSD()));
+	add("disableAllRenderTypes",
+		"Turn off all rendering types.",
+		&disable_all_render_types_wrapper);
+	add("enableAllRenderTypes",
+		"Turn on all rendering types.",
+		&enable_all_render_types_wrapper);
+
+	// Render Features
+	add("toggleRenderFeatures",
+		"Toggle rendering [\"features\"]:\n"
+		"See: llviewermenu.cpp:feature_from_string for list of available features.",
+		&toggle_render_features_wrapper);
+	add("hasRenderFeature",
+		"Check if rendering [\"feature\"] is enabled:\n"
+		"See: llviewermenu.cpp:render_feature_from_string for list of available features.",
+		&has_render_feature_wrapper,
+		LLSDMap("reply", LLSD()));
+	add("disableAllRenderFeatures",
+		"Turn off all rendering features.",
+		&disable_all_render_features_wrapper);
+	add("enableAllRenderFeatures",
+		"Turn on all rendering features.",
+		&enable_all_render_features_wrapper);
+
+	// Render Info Displays
+	add("toggleRenderInfoDisplays",
+		"Toggle info [\"displays\"]:\n"
+		"See: llviewermenu.cpp:info_display_from_string for list of available displays.",
+		&toggle_info_displays_wrapper);
+	add("hasRenderInfoDisplay",
+		"Check if info [\"display\"] is enabled:\n"
+		"See: llviewermenu.cpp:info_display_from_string for list of available displays.",
+		&has_info_display_wrapper,
+		LLSDMap("reply", LLSD()));
+	add("disableAllRenderInfoDisplays",
+		"Turn off all info displays.",
+		&disable_all_info_displays_wrapper);
+	add("enableAllRenderInfoDisplays",
+		"Turn on all info displays.",
+		&enable_all_info_displays_wrapper);
+}
+
diff --git a/indra/newview/llpipelinelistener.h b/indra/newview/llpipelinelistener.h
new file mode 100644
index 0000000000000000000000000000000000000000..da1898e57b62caed56c36d3268c19ce7fbd38fcd
--- /dev/null
+++ b/indra/newview/llpipelinelistener.h
@@ -0,0 +1,41 @@
+/**
+ * @file   llpipelinelistener.h
+ * @author Don Kjer
+ * @date   2012-07-09
+ * @brief  Wrap subset of LLPipeline API in event API
+ * 
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLPIPELINELISTENER_H)
+#define LL_LLPIPELINELISTENER_H
+
+#include "lleventapi.h"
+
+/// Listen on an LLEventPump with specified name for LLPipeline request events.
+class LLPipelineListener: public LLEventAPI
+{
+public:
+	LLPipelineListener();
+};
+
+#endif /* ! defined(LL_LLPIPELINELISTENER_H) */
diff --git a/indra/newview/llpostcard.cpp b/indra/newview/llpostcard.cpp
index 4f2d6da7e593be9494fb66b07e9139358e386b0e..aebe636f5994e093fcacd4d2b1316641daf02e01 100644
--- a/indra/newview/llpostcard.cpp
+++ b/indra/newview/llpostcard.cpp
@@ -35,6 +35,7 @@
 #include "message.h"
 
 #include "llagent.h"
+#include "llassetstorage.h"
 #include "llassetuploadresponders.h"
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 3ff5a05d81e7b7a3a12246b19d879a56307af28b..91a98792eb56b3dd0e529db8c3dce9e9d1e4d916 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -70,7 +70,7 @@ LLPreviewTexture::LLPreviewTexture(const LLSD& key)
 	  mAspectRatio(0.f),
 	  mPreviewToSave(FALSE),
 	  mImage(NULL),
-	  mImageOldBoostLevel(LLViewerTexture::BOOST_NONE)
+	  mImageOldBoostLevel(LLGLTexture::BOOST_NONE)
 {
 	updateImageID();
 	if (key.has("save_as"))
@@ -468,9 +468,9 @@ void LLPreviewTexture::onAspectRatioCommit(LLUICtrl* ctrl, void* userdata)
 
 void LLPreviewTexture::loadAsset()
 {
-	mImage = LLViewerTextureManager::getFetchedTexture(mImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 	mImageOldBoostLevel = mImage->getBoostLevel();
-	mImage->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
+	mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
 	mImage->forceToSaveRawImage(0) ;
 	mAssetStatus = PREVIEW_ASSET_LOADING;
 	mUpdateDimensions = TRUE;
diff --git a/indra/newview/llproductinforequest.cpp b/indra/newview/llproductinforequest.cpp
index 93bf8b232898eb62540da8de050c8eb1e2fcaf1a..1390000fc506eb1bbba570224824e0283f52fe64 100644
--- a/indra/newview/llproductinforequest.cpp
+++ b/indra/newview/llproductinforequest.cpp
@@ -43,10 +43,10 @@ class LLProductInfoRequestResponder : public LLHTTPClient::Responder
 	}
 
 	//If we get back an error (not found, etc...), handle it here
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		llwarns << "LLProductInfoRequest::error("
-		<< status << ": " << reason << ")" << llendl;
+		llwarns << "LLProductInfoRequest error [status:"
+				<< status << ":] " << content << llendl;
 	}
 };
 
diff --git a/indra/newview/llregioninfomodel.cpp b/indra/newview/llregioninfomodel.cpp
index 698c4f9bb93833a084e40903dba5933a715e42a8..590e24648238644d0a5db6c7c3cdee467daa218a 100644
--- a/indra/newview/llregioninfomodel.cpp
+++ b/indra/newview/llregioninfomodel.cpp
@@ -119,7 +119,7 @@ void LLRegionInfoModel::sendRegionTerrain(const LLUUID& invoice) const
 
 bool LLRegionInfoModel::getUseFixedSun() const
 {
-	return mRegionFlags & REGION_FLAGS_SUN_FIXED;
+	return ((mRegionFlags & REGION_FLAGS_SUN_FIXED) != 0);
 }
 
 void LLRegionInfoModel::setUseFixedSun(bool fixed)
@@ -141,7 +141,6 @@ void LLRegionInfoModel::update(LLMessageSystem* msg)
 	msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, mSimName);
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, mEstateID);
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, mParentEstateID);
-	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, mRegionFlags);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, mSimAccess);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, mAgentLimit);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, mObjectBonusFactor);
@@ -159,6 +158,17 @@ void LLRegionInfoModel::update(LLMessageSystem* msg)
 	msg->getF32(_PREHASH_RegionInfo, _PREHASH_SunHour, mSunHour);
 	LL_DEBUGS("Windlight Sync") << "Got region sun hour: " << mSunHour << LL_ENDL;
 
+	if (msg->has(_PREHASH_RegionInfo3))
+	{
+		msg->getU64Fast(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended, mRegionFlags);
+	}
+	else
+	{
+		U32 flags = 0;
+		msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
+		mRegionFlags = flags;
+	}
+
 	// the only reasonable way to decide if we actually have any data is to
 	// check to see if any of these fields have nonzero sizes
 	if (msg->getSize(_PREHASH_RegionInfo2, _PREHASH_ProductSKU) > 0 ||
diff --git a/indra/newview/llregioninfomodel.h b/indra/newview/llregioninfomodel.h
index 89efd827674980814e915f9416ca5894afca2f62..d22a0de4635bfd14abd5e7f862aeb86073fd26aa 100644
--- a/indra/newview/llregioninfomodel.h
+++ b/indra/newview/llregioninfomodel.h
@@ -52,7 +52,7 @@ class LLRegionInfoModel : public LLSingleton<LLRegionInfoModel>
 	U8			mSimAccess;
 	U8			mAgentLimit;
 
-	U32			mRegionFlags;
+	U64			mRegionFlags;
 	U32			mEstateID;
 	U32			mParentEstateID;
 
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 3862dac340d0db44d3ed0411a56c7cbee3a4ac01..500dec7ee5841878bfbddb2857f9a590c6b847b9 100644
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -62,10 +62,10 @@ void LLRemoteParcelRequestResponder::result(const LLSD& content)
 
 //If we get back an error (not found, etc...), handle it here
 //virtual
-void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason)
+void LLRemoteParcelRequestResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llinfos << "LLRemoteParcelRequest::error("
-		<< status << ": " << reason << ")" << llendl;
+	llwarns << "LLRemoteParcelRequest error [status:"
+			<< status << "]: " << content << llendl;
 
 	// Panel inspecting the information may be closed and destroyed
 	// before this response is received.
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index 74cf1616dfada4296020107f8eedcbc79c290b03..b87056573b1bfea0ea4753f9a220b57b83b11763 100644
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -44,7 +44,7 @@ class LLRemoteParcelRequestResponder : public LLHTTPClient::Responder
 	/*virtual*/ void result(const LLSD& content);
 
 	//If we get back an error (not found, etc...), handle it here
-	/*virtual*/ void error(U32 status, const std::string& reason);
+	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 
 protected:
 	LLHandle<LLRemoteParcelInfoObserver> mObserverHandle;
diff --git a/indra/newview/llsaveoutfitcombobtn.cpp b/indra/newview/llsaveoutfitcombobtn.cpp
index cbad85cfd3f794a23a38e7a5101f2f8b2f32bd46..32295cd96f29b3c5acf352b8accb1e571b4579fa 100644
--- a/indra/newview/llsaveoutfitcombobtn.cpp
+++ b/indra/newview/llsaveoutfitcombobtn.cpp
@@ -76,8 +76,8 @@ void LLSaveOutfitComboBtn::saveOutfit(bool as_new)
 	if (panel_outfits_inventory)
 	{
 		panel_outfits_inventory->onSave();
-	}
-
+	} 	
+    
 	//*TODO how to get to know when base outfit is updated or new outfit is created?
 }
 
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index 154555b261a089cde8a7756df3cbf174075b5544..168a941ec379fe10092caa913a4c5bfbafafe202 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -730,7 +730,6 @@ void LLScreenChannel::showToastsTop()
 
 	LLRect	toast_rect;	
 	S32		top = channel_rect.mTop;
-	S32		toast_margin = 0;
 	std::vector<ToastElem>::reverse_iterator it;
 
 	updateRect();
@@ -753,7 +752,7 @@ void LLScreenChannel::showToastsTop()
 			}
 
 			top = toast->getRect().mBottom - toast->getTopPad();
-			toast_margin = gSavedSettings.getS32("ToastGap");
+			gSavedSettings.getS32("ToastGap");
 		}
 
 		LLToast* toast = it->getToast();
diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp
index 05b82ba967e3dfda182491e45553b80da7d32c42..a7e24b86b13e765fb727e29e766ee0044cb1b759 100644
--- a/indra/newview/llscrollingpanelparam.cpp
+++ b/indra/newview/llscrollingpanelparam.cpp
@@ -267,7 +267,7 @@ void LLScrollingPanelParam::onHintHeldDown( LLVisualParamHint* hint )
 				&& new_percent < slider->getMaxValue())
 			{
 				mWearable->setVisualParamWeight( hint->getVisualParam()->getID(), new_weight, FALSE);
-				mWearable->writeToAvatar();
+				mWearable->writeToAvatar(gAgentAvatarp);
 				gAgentAvatarp->updateVisualParams();
 
 				slider->setValue( weightToPercent( new_weight ) );
@@ -300,7 +300,7 @@ void LLScrollingPanelParam::onHintMinMouseUp( void* userdata )
 				&& new_percent < slider->getMaxValue())
 			{
 				self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE);
-				self->mWearable->writeToAvatar();
+				self->mWearable->writeToAvatar(gAgentAvatarp);
 				slider->setValue( self->weightToPercent( new_weight ) );
 			}
 		}
@@ -334,7 +334,7 @@ void LLScrollingPanelParam::onHintMaxMouseUp( void* userdata )
 					&& new_percent < slider->getMaxValue())
 				{
 					self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE);
-					self->mWearable->writeToAvatar();
+					self->mWearable->writeToAvatar(gAgentAvatarp);
 					slider->setValue( self->weightToPercent( new_weight ) );
 				}
 			}
diff --git a/indra/newview/llscrollingpanelparambase.cpp b/indra/newview/llscrollingpanelparambase.cpp
index 62e3039d2fe67ea1f2183395b18bfbd17ae13af3..8e083ddb6c8ff60d466f01d8e72f2d3ee1c96f0f 100644
--- a/indra/newview/llscrollingpanelparambase.cpp
+++ b/indra/newview/llscrollingpanelparambase.cpp
@@ -94,7 +94,7 @@ void LLScrollingPanelParamBase::onSliderMoved(LLUICtrl* ctrl, void* userdata)
 	if (current_weight != new_weight )
 	{
 		self->mWearable->setVisualParamWeight( param->getID(), new_weight, FALSE );
-		self->mWearable->writeToAvatar();
+		self->mWearable->writeToAvatar(gAgentAvatarp);
 		gAgentAvatarp->updateVisualParams();
 	}
 }
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 30400a4c6a6b7d44a616ca8c33ae0414a3f32627..928d26646b2b777f5e45213117ddb425f6f324da 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -1239,7 +1239,6 @@ void LLSecAPIBasicHandler::_readProtectedData()
 									llifstream::binary);
 
 	if (!protected_data_stream.fail()) {
-		int offset;
 		U8 salt[STORE_SALT_SIZE];
 		U8 buffer[BUFFER_READ_SIZE];
 		U8 decrypted_buffer[BUFFER_READ_SIZE];
@@ -1250,7 +1249,6 @@ void LLSecAPIBasicHandler::_readProtectedData()
 
 		// read in the salt and key
 		protected_data_stream.read((char *)salt, STORE_SALT_SIZE);
-		offset = 0;
 		if (protected_data_stream.gcount() < STORE_SALT_SIZE)
 		{
 			throw LLProtectedDataException("Config file too short.");
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 343316d30a79349370a401a6464928f52137b736..4681efd3e5901335ca04f36ce61ac7d1ef1b8d38 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1180,7 +1180,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
 	if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount())
 	{
 		//LLViewerObject* root = getSelectedParentObject(mSelectedObjects->getFirstObject());
-		LLBBox bbox = mSavedSelectionBBox;
 		mGridOrigin = mSavedSelectionBBox.getCenterAgent();
 		mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f;
 
@@ -1198,7 +1197,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
 	else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull())
 	{
 		mGridRotation = first_grid_object->getRenderRotation();
-		LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition();
 
 		LLVector4a min_extents(F32_MAX);
 		LLVector4a max_extents(-F32_MAX);
@@ -1605,7 +1603,7 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
 				// Texture picker defaults aren't inventory items
 				// * Don't need to worry about permissions for them
 				// * Can just apply the texture and be done with it.
-				objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+				objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
 			}
 			return true;
 		}
@@ -1771,7 +1769,7 @@ BOOL LLSelectMgr::selectionRevertTextures()
 					}
 					else
 					{
-						object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+						object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
 					}
 				}
 			}
@@ -5185,7 +5183,7 @@ void LLSelectMgr::updateSilhouettes()
 
 	if (!mSilhouetteImagep)
 	{
-		mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", TRUE, LLViewerTexture::BOOST_UI);
+		mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI);
 	}
 
 	mHighlightedObjects->cleanupNodes();
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index adb97ac800adf0c52f1e3254766152d8375bbfc0..74fa5a87bba7b96cf49046ce58da33e501b2bf49 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -47,7 +47,7 @@
 #include "llviewercontrol.h"
 #include "llviewerregion.h"
 #include "llvoavatarself.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
 
 static LLRegisterPanelClassWrapper<LLSidepanelAppearance> t_appearance("sidepanel_appearance");
 
@@ -198,7 +198,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
 
 		if (is_outfit_edit_visible || is_wearable_edit_visible)
 		{
-			const LLWearable *wearable_ptr = mEditWearable->getWearable();
+			const LLViewerWearable *wearable_ptr = mEditWearable->getWearable();
 			if (!wearable_ptr)
 			{
 				llwarns << "Visibility change to invalid wearable" << llendl;
@@ -206,12 +206,9 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
 			}
 			// Disable camera switch is currently just for WT_PHYSICS type since we don't want to freeze the avatar
 			// when editing its physics.
-			const BOOL disable_camera_motion = LLWearableType::getDisableCameraSwitch(wearable_ptr->getType());
-			if (!gAgentCamera.cameraCustomizeAvatar() && 
-				!disable_camera_motion &&
-				gSavedSettings.getBOOL("AppearanceCameraMovement"))
+			if (!gAgentCamera.cameraCustomizeAvatar())
 			{
-				gAgentCamera.changeCameraToCustomizeAvatar();
+				LLVOAvatarSelf::onCustomizeStart(LLWearableType::getDisableCameraSwitch(wearable_ptr->getType()));
 			}
 			if (is_wearable_edit_visible)
 			{
@@ -234,7 +231,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
 		{
 			gAgentCamera.changeCameraToDefault();
 			gAgentCamera.resetView();
-		}
+		}	
 	}
 }
 
@@ -283,7 +280,7 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked()
 {
 	if (gAgentWearables.areWearablesLoaded())
 	{
-		gAgentCamera.changeCameraToCustomizeAvatar();
+		LLVOAvatarSelf::onCustomizeStart();
 	}
 }
 
@@ -329,7 +326,7 @@ void LLSidepanelAppearance::showOutfitEditPanel()
 	toggleOutfitEditPanel(TRUE);
 }
 
-void LLSidepanelAppearance::showWearableEditPanel(LLWearable *wearable /* = NULL*/, BOOL disable_camera_switch)
+void LLSidepanelAppearance::showWearableEditPanel(LLViewerWearable *wearable /* = NULL*/, BOOL disable_camera_switch)
 {
 	toggleMyOutfitsPanel(FALSE);
 	toggleOutfitEditPanel(FALSE, TRUE); // don't switch out of edit appearance mode
@@ -371,19 +368,19 @@ void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_cam
 	if (visible)
 	{
 		mOutfitEdit->onOpen(LLSD());
-		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
-		{
-			gAgentCamera.changeCameraToCustomizeAvatar();
-		}
+		LLVOAvatarSelf::onCustomizeStart(disable_camera_switch);
 	}
-	else if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
+	else 
 	{
-		gAgentCamera.changeCameraToDefault();
-		gAgentCamera.resetView();
+		if (!disable_camera_switch)   // if we're just switching between outfit and wearable editing, don't end customization.
+		{
+			LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch);
+			LLAppearanceMgr::getInstance()->updateIsDirty();
+		}
 	}
 }
 
-void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable, BOOL disable_camera_switch)
+void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearable *wearable, BOOL disable_camera_switch)
 {
 	if (!mEditWearable || mEditWearable->getVisible() == visible)
 	{
@@ -393,7 +390,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we
 
 	if (!wearable)
 	{
-		wearable = gAgentWearables.getWearable(LLWearableType::WT_SHAPE, 0);
+		wearable = gAgentWearables.getViewerWearable(LLWearableType::WT_SHAPE, 0);
 	}
 	if (!wearable)
 	{
@@ -405,10 +402,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we
 
 	if (visible)
 	{
-		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
-		{
-			gAgentCamera.changeCameraToCustomizeAvatar();
-		}
+		LLVOAvatarSelf::onCustomizeStart(disable_camera_switch);
 		mEditWearable->setWearable(wearable, disable_camera_switch);
 		mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency
 	}
@@ -416,10 +410,10 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we
 	{
 		// Save changes if closing.
 		mEditWearable->saveChanges();
-		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
+		LLAppearanceMgr::getInstance()->updateIsDirty();
+		if (!disable_camera_switch)   // if we're just switching between outfit and wearable editing, don't end customization.
 		{
-			gAgentCamera.changeCameraToDefault();
-			gAgentCamera.resetView();
+			LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch);
 		}
 	}
 }
@@ -453,13 +447,12 @@ void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name)
 }
 
 //static
-void LLSidepanelAppearance::editWearable(LLWearable *wearable, LLView *data, BOOL disable_camera_switch)
+void LLSidepanelAppearance::editWearable(LLViewerWearable *wearable, LLView *data, BOOL disable_camera_switch)
 {
 	LLFloaterSidePanelContainer::showPanel("appearance", LLSD());
 	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(data);
 	if (panel)
 	{
-		panel->showOutfitsInventoryPanel();
 		panel->showWearableEditPanel(wearable, disable_camera_switch);
 	}
 }
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index 6dd35202665663707e7911ff330d717273b6ddb0..762f557a8004e471b1a9f9b14a255e3f0817ff17 100644
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -36,7 +36,7 @@
 class LLFilterEditor;
 class LLCurrentlyWornFetchObserver;
 class LLPanelEditWearable;
-class LLWearable;
+class LLViewerWearable;
 class LLPanelOutfitsInventory;
 
 class LLSidepanelAppearance : public LLPanel
@@ -47,11 +47,11 @@ class LLSidepanelAppearance : public LLPanel
 	virtual ~LLSidepanelAppearance();
 
 	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void onOpen(const LLSD& key);	
 
 	void refreshCurrentOutfitName(const std::string& name = "");
 
-	static void editWearable(LLWearable *wearable, LLView *data, BOOL disable_camera_switch = FALSE);
+	static void editWearable(LLViewerWearable *wearable, LLView *data, BOOL disable_camera_switch = FALSE);
 
 	void fetchInventory();
 	void inventoryFetched();
@@ -59,11 +59,12 @@ class LLSidepanelAppearance : public LLPanel
 
 	void showOutfitsInventoryPanel();
 	void showOutfitEditPanel();
-	void showWearableEditPanel(LLWearable *wearable = NULL, BOOL disable_camera_switch = FALSE);
+	void showWearableEditPanel(LLViewerWearable *wearable = NULL, BOOL disable_camera_switch = FALSE);
 	void setWearablesLoading(bool val);
 	void showDefaultSubpart();
 	void updateScrollingPanelList();
 	void updateToVisibility( const LLSD& new_visibility );
+	LLPanelEditWearable* getWearable(){ return mEditWearable; }
 
 private:
 	void onFilterEdit(const std::string& search_string);
@@ -74,7 +75,7 @@ class LLSidepanelAppearance : public LLPanel
 
 	void toggleMyOutfitsPanel(BOOL visible);
 	void toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch = FALSE);
-	void toggleWearableEditPanel(BOOL visible, LLWearable* wearable = NULL, BOOL disable_camera_switch = FALSE);
+	void toggleWearableEditPanel(BOOL visible, LLViewerWearable* wearable = NULL, BOOL disable_camera_switch = FALSE);
 
 	LLFilterEditor*			mFilterEditor;
 	LLPanelOutfitsInventory* mPanelOutfitsInventory;
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 5532bdc71a8a2dc12ee5c0bdfd6f12e340e53b96..ad7c939728fe36b668a7f4d8283c13223a0289f4 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -370,10 +370,8 @@ void LLSidepanelTaskInfo::refresh()
 	
 	// Update creator text field
 	getChildView("Creator:")->setEnabled(TRUE);
-	BOOL creators_identical;
 	std::string creator_name;
-	creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID,
-																	  creator_name);
+	LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name);
 
 	getChild<LLUICtrl>("Creator Name")->setValue(creator_name);
 	getChildView("Creator Name")->setEnabled(TRUE);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 3ed6e244984e06ee1fd20b34cf8b87e0e6173bcb..f85e855fd3a87549da2ee1faecc14906daf024f2 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3544,9 +3544,9 @@ void renderTexturePriority(LLDrawable* drawable)
 		drawBox(center, size);
 		
 		/*S32 boost = imagep->getBoostLevel();
-		if (boost>LLViewerTexture::BOOST_NONE)
+		if (boost>LLGLTexture::BOOST_NONE)
 		{
-			F32 t = (F32) boost / (F32) (LLViewerTexture::BOOST_MAX_LEVEL-1);
+			F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1);
 			LLVector4 col = lerp(boost_cold, boost_hot, t);
 			LLGLEnable blend_on(GL_BLEND);
 			gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
@@ -3998,7 +3998,7 @@ void renderAgentTarget(LLVOAvatar* avatar)
 	{
 		renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
 		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f));
-		renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
+		renderCrossHairs(avatar->mRoot->getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
 		renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));
 	}
 }
@@ -4062,9 +4062,6 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable>
 			return;
 		}
 
-		LLVector4a nodeCenter = group->mBounds[0];
-		LLVector4a octCenter = group->mOctreeNode->getCenter();
-
 		group->rebuildGeom();
 		group->rebuildMesh();
 
@@ -4539,9 +4536,6 @@ class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler
 
 	virtual bool check(LLDrawable* drawable)
 	{	
-		LLVector3 local_start = mStart;
-		LLVector3 local_end = mEnd;
-
 		if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())
 		{
 			return false;
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 8783d99b118094144412eebf5bf8f4eebf819e74..a4582071e8b3922b4d8fe60d74511496f7b62a37 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -853,7 +853,10 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
 		}
 	}
 }
-
+/*prep#
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+		llwarns << "ModerationResponder error [status:" << status << "]: " << content << llendl;
+		*/
 void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
 {
 	LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id);
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 37e6ded986f48ef1cc4598354d6eb2be298c0057..8b71f1067fe03be6013517b7457a5dce9b71dd1f 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -316,7 +316,6 @@ bool idle_startup()
 {
 	const F32 PRECACHING_DELAY = gSavedSettings.getF32("PrecachingDelay");
 	static LLTimer timeout;
-	static S32 timeout_count = 0;
 
 	static LLTimer login_time;
 
@@ -332,7 +331,6 @@ bool idle_startup()
 
 	// last location by default
 	static S32  agent_location_id = START_LOCATION_ID_LAST;
-	static S32  location_which = START_LOCATION_ID_LAST;
 
 	static bool show_connect_box = true;
 
@@ -744,8 +742,6 @@ bool idle_startup()
 
 		gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
 
-		timeout_count = 0;
-
 		// Login screen needs menus for preferences, but we can enter
 		// this startup phase more than once.
 		if (gLoginMenuBarView == NULL)
@@ -772,10 +768,6 @@ bool idle_startup()
 				gUserCredential = gLoginHandler.initializeLoginInfo();                 
 				display_startup();
 			}     
-			if (gHeadlessClient)
-			{
-				LL_WARNS("AppInit") << "Waiting at connection box in headless client.  Did you mean to add autologin params?" << LL_ENDL;
-			}
 			// Make sure the process dialog doesn't hide things
 			display_startup();
 			gViewerWindow->setShowProgress(FALSE);
@@ -993,15 +985,12 @@ bool idle_startup()
 		  {
 		  case LLSLURL::LOCATION:
 		    agent_location_id = START_LOCATION_ID_URL;
-		    location_which = START_LOCATION_ID_LAST;
 		    break;
 		  case LLSLURL::LAST_LOCATION:
 		    agent_location_id = START_LOCATION_ID_LAST;
-		    location_which = START_LOCATION_ID_LAST;
 		    break;
 		  default:
 		    agent_location_id = START_LOCATION_ID_HOME;
-		    location_which = START_LOCATION_ID_HOME;
 		    break;
 		  }
 
@@ -1254,6 +1243,9 @@ bool idle_startup()
 		LLPostProcess::initClass();
 		display_startup();
 
+		LLAvatarAppearance::initClass();
+		display_startup();
+
 		LLViewerObject::initVOClasses();
 		display_startup();
 
@@ -2588,12 +2580,17 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 	}
 	else
 	{
+		// FIXME SH-3860 - this creates a race condition, where COF
+		// changes (base outfit link added) after appearance update
+		// request has been submitted.
 		sWearablesLoadedCon = gAgentWearables.addLoadedCallback(LLStartUp::saveInitialOutfit);
 
 		bool do_copy = true;
 		bool do_append = false;
 		LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
-		LLAppearanceMgr::instance().wearInventoryCategory(cat, do_copy, do_append);
+		// Need to fetch cof contents before we can wear.
+		callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(),
+							   boost::bind(&LLAppearanceMgr::wearInventoryCategory, LLAppearanceMgr::getInstance(), cat, do_copy, do_append));
 		lldebugs << "initial outfit category id: " << cat_id << llendl;
 	}
 
@@ -3455,6 +3452,14 @@ bool process_login_success_response()
 
 	}
 
+	// set the location of the Agent Appearance service, from which we can request
+	// avatar baked textures if they are supported by the current region
+	std::string agent_appearance_url = response["agent_appearance_service"];
+	if (!agent_appearance_url.empty())
+	{
+		LLAppearanceMgr::instance().setAppearanceServiceURL(agent_appearance_url);
+	}
+
 	// Set the location of the snapshot sharing config endpoint
 	std::string snapshot_config_url = response["snapshot_config_url"];
 	if(!snapshot_config_url.empty())
@@ -3499,13 +3504,6 @@ bool process_login_success_response()
 
 void transition_back_to_login_panel(const std::string& emsg)
 {
-	if (gHeadlessClient && gSavedSettings.getBOOL("AutoLogin"))
-	{
-		LL_WARNS("AppInit") << "Failed to login!" << LL_ENDL;
-		LL_WARNS("AppInit") << emsg << LL_ENDL;
-		exit(0);
-	}
-
 	// Bounce back to the login screen.
 	reset_login(); // calls LLStartUp::setStartupState( STATE_LOGIN_SHOW );
 	gSavedSettings.setBOOL("AutoLogin", FALSE);
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index ec11a23eb8c290915177331e1b9436910b2a9532..93c7f54101372724aea6ef9e381aecca56354d08 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -1246,8 +1246,6 @@ BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y,
 		y_end = tex_width;
 	}
 
-	LLVector3d origin_global = from_region_handle(getRegion()->getHandle());
-
 	// OK, for now, just have the composition value equal the height at the point.
 	LLVector3 location;
 	LLColor4U coloru;
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 007eb8e33f844fc50f532e15143a17ca2ceb35a4..e2d0fdf3576579558378b1d947ad45019ccd992f 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -571,8 +571,8 @@ void LLFloaterTexturePicker::draw()
 		mTexturep = NULL;
 		if(mImageAssetID.notNull())
 		{
-			mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES);
-			mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
+			mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID);
+			mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
 		}
 
 		if (mTentativeLabel)
@@ -1442,9 +1442,9 @@ void LLTextureCtrl::draw()
 	}
 	else if (!mImageAssetID.isNull())
 	{
-		LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES,LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+		LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES,LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 		
-		texture->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
+		texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
 		texture->forceToSaveRawImage(0) ;
 
 		mTexturep = texture;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 7de66b139f5886cbc6d2c6d27f0ec8cce2afccd3..be5fde9e2b020b31b88e4bbabb0955552270f1fb 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -389,7 +389,8 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
 	
 protected:
-	LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host,
+	LLTextureFetchWorker(LLTextureFetch* fetcher, FTType f_type,
+						 const std::string& url, const LLUUID& id, const LLHost& host,
 						 F32 priority, S32 discard, S32 size);
 
 private:
@@ -501,11 +502,13 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	};
 	static const char* sStateDescs[];
 	e_state mState;
+	void setState(e_state new_state);
 	e_write_to_cache_state mWriteToCacheState;
 	LLTextureFetch* mFetcher;
 	LLPointer<LLImageFormatted> mFormattedImage;
 	LLPointer<LLImageRaw> mRawImage;
 	LLPointer<LLImageRaw> mAuxImage;
+	FTType mFTType;
 	LLUUID mID;
 	LLHost mHost;
 	std::string mUrl;
@@ -827,6 +830,7 @@ volatile bool LLTextureFetch::svMetricsDataBreak(true);	// Start with a data bre
 // called from MAIN THREAD
 
 LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
+										   FTType f_type, // Fetched image type
 										   const std::string& url, // Optional URL
 										   const LLUUID& id,	// Image UUID
 										   const LLHost& host,	// Simulator host
@@ -838,6 +842,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mState(INIT),
 	  mWriteToCacheState(NOT_WRITE),
 	  mFetcher(fetcher),
+	  mFTType(f_type),
 	  mID(id),
 	  mHost(host),
 	  mUrl(url),
@@ -1024,7 +1029,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
 	mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE);
 	if ((prioritize && mState == INIT) || mState == DONE)
 	{
-		mState = INIT;
+		setState(INIT);
 		U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
 		setPriority(work_priority);
 	}
@@ -1088,12 +1093,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
 	{
 		if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
 		{
+			LL_DEBUGS("Texture") << mID << " abort: mImagePriority < F_ALMOST_ZERO" << llendl;
 			return true; // abort
 		}
 	}
 	if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)
 	{
 		//nowhere to get data, abort.
+		LL_WARNS("Texture") << mID << " abort, nowhere to get data" << llendl;
 		return true ;
 	}
 
@@ -1136,7 +1143,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		clearPackets(); // TODO: Shouldn't be necessary
 		mCacheReadHandle = LLTextureCache::nullHandle();
 		mCacheWriteHandle = LLTextureCache::nullHandle();
-		mState = LOAD_FROM_TEXTURE_CACHE;
+		setState(LOAD_FROM_TEXTURE_CACHE);
 		mInCache = FALSE;
 		mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE
 		LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority)
@@ -1153,7 +1160,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			S32 size = mDesiredSize - offset;
 			if (size <= 0)
 			{
-				mState = CACHE_POST;
+				setState(CACHE_POST);
 				return false;
 			}
 			mFileSize = 0;
@@ -1171,6 +1178,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
 																		  offset, size, responder);
 				mCacheReadTimer.reset();
 			}
+/* SH-3980 - disabling caching of server bakes until we can fix the blurring problems */
+/*			else if ((mUrl.empty()||mFTType==FTT_SERVER_BAKE) && mFetcher->canLoadFromCache()) */
 			else if (mUrl.empty() && mFetcher->canLoadFromCache())
 			{
 				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
@@ -1183,18 +1192,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			}
 			else if(!mUrl.empty() && mCanUseHTTP)
 			{
-				if (!(mUrl.compare(0, 7, "http://") == 0))
-				{
-					// *TODO:?remove this warning
-					llwarns << "Unknown URL Type: " << mUrl << llendl;
-				}
 				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-				mState = WAIT_HTTP_RESOURCE;
+				setState(WAIT_HTTP_RESOURCE);
 			}
 			else
 			{
 				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-				mState = LOAD_FROM_NETWORK;
+				setState(LOAD_FROM_NETWORK);
 			}
 		}
 
@@ -1204,7 +1208,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			if (mFetcher->mTextureCache->readComplete(mCacheReadHandle, false))
 			{
 				mCacheReadHandle = LLTextureCache::nullHandle();
-				mState = CACHE_POST;
+				setState(CACHE_POST);
 				// fall through
 			}
 			else
@@ -1212,6 +1216,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				//
 				//This should never happen
 				//
+				LL_DEBUGS("Texture") << mID << " this should never happen" << llendl;
 				return false;
 			}
 		}
@@ -1230,7 +1235,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			// we have enough data, decode it
 			llassert_always(mFormattedImage->getDataSize() > 0);
 			mLoadedDiscard = mDesiredDiscard;
-			mState = DECODE_IMAGE;
+			if (mLoadedDiscard < 0)
+			{
+				LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+									<< ", should be >=0" << llendl;
+			}
+			setState(DECODE_IMAGE);
 			mInCache = TRUE;
 			mWriteToCacheState = NOT_WRITE ;
 			LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
@@ -1243,13 +1253,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			if (mUrl.compare(0, 7, "file://") == 0)
 			{
 				// failed to load local file, we're done.
+				LL_WARNS("Texture") << mID << ": abort, failed to load local file " << mUrl << LL_ENDL;
 				return true;
 			}
 			// need more data
 			else
 			{
 				LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL;
-				mState = LOAD_FROM_NETWORK;
+				setState(LOAD_FROM_NETWORK);
 			}
 			
 			// fall through
@@ -1290,9 +1301,15 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				mCanUseHTTP = false;
 			}
 		}
+#if 0 /* SH-3980 - disabling caching of server bakes until we can fix the blurring problems */
+		if (mFTType == FTT_SERVER_BAKE)
+		{
+			mWriteToCacheState = CAN_WRITE;
+		}
+#endif
 		if (mCanUseHTTP && !mUrl.empty())
 		{
-			mState = WAIT_HTTP_RESOURCE;
+			setState(WAIT_HTTP_RESOURCE);
 			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 			if(mWriteToCacheState != NOT_WRITE)
 			{
@@ -1322,6 +1339,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			//mFetcher->addToNetworkQueue(this);
 			//recordTextureStart(false);
 			//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+
+			LL_DEBUGS("Texture") << mID << " does this happen?" << llendl;
 			return false;
 		}
 	}
@@ -1340,10 +1359,16 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			{
 				// processSimulatorPackets() failed
 // 				llwarns << "processSimulatorPackets() failed to load buffer" << llendl;
+				LL_WARNS("Texture") << mID << " processSimulatorPackets() failed to load buffer" << llendl;
 				return true; // failed
 			}
 			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-			mState = DECODE_IMAGE;
+			if (mLoadedDiscard < 0)
+			{
+				LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+									<< ", should be >=0" << llendl;
+			}
+			setState(DECODE_IMAGE);
 			mWriteToCacheState = SHOULD_WRITE;
 			recordTextureDone(false);
 		}
@@ -1367,14 +1392,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		// Otherwise, advance into the HTTP states.
 		if (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore())
 		{
-			mState = WAIT_HTTP_RESOURCE2;
+			setState(WAIT_HTTP_RESOURCE2);
 			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
 			mFetcher->addHttpWaiter(this->mID);
 			++mResourceWaitCount;
 			return false;
 		}
 		
-		mState = SEND_HTTP_REQ;
+		setState(SEND_HTTP_REQ);
 		// *NOTE:  You must invoke releaseHttpSemaphore() if you transition
 		// to a state other than SEND_HTTP_REQ or WAIT_HTTP_REQ or abort
 		// the request.
@@ -1391,6 +1416,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		if (! mCanUseHTTP)
 		{
 			releaseHttpSemaphore();
+			LL_WARNS("Texture") << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << llendl;
 			return true; // abort
 		}
 
@@ -1407,13 +1433,19 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					// We already have all the data, just decode it
 					mLoadedDiscard = mFormattedImage->getDiscardLevel();
 					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-					mState = DECODE_IMAGE;
+					if (mLoadedDiscard < 0)
+					{
+						LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+											<< ", should be >=0" << llendl;
+					}
+					setState(DECODE_IMAGE);
 					releaseHttpSemaphore();
 					return false;
 				}
 				else
 				{
 					releaseHttpSemaphore();
+					LL_WARNS("Texture") << mID << " SEND_HTTP_REQ abort: cur_size " << cur_size << " <=0" << llendl;
 					return true; // abort.
 				}
 			}
@@ -1471,7 +1503,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		mFetcher->addToHTTPQueue(mID);
 		recordTextureStart(true);
 		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
-		mState = WAIT_HTTP_REQ;	
+		setState(WAIT_HTTP_REQ);	
 		
 		// fall through
 	}
@@ -1489,8 +1521,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				{
 					if(mWriteToCacheState == NOT_WRITE) //map tiles
 					{
-						mState = DONE;
+						setState(DONE);
 						releaseHttpSemaphore();
+						LL_DEBUGS("Texture") << mID << " abort: WAIT_HTTP_REQ not found" << llendl;
 						return true; // failed, means no map tile on the empty region.
 					}
 
@@ -1499,7 +1532,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					// roll back to try UDP
 					if (mCanUseNET)
 					{
-						mState = INIT;
+						setState(INIT);
 						mCanUseHTTP = false;
 						mUrl.clear();
 						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
@@ -1530,15 +1563,21 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					// Use available data
 					mLoadedDiscard = mFormattedImage->getDiscardLevel();
 					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-					mState = DECODE_IMAGE;
+					if (mLoadedDiscard < 0)
+					{
+						LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+											<< ", should be >=0" << llendl;
+					}
+					setState(DECODE_IMAGE);
 					releaseHttpSemaphore();
 					return false; 
 				}
 
 				// Fail harder
 				resetFormattedData();
-				mState = DONE;
+				setState(DONE);
 				releaseHttpSemaphore();
+				LL_WARNS("Texture") << mID << " abort: fail harder" << llendl;
 				return true; // failed
 			}
 			
@@ -1547,6 +1586,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			// next time the texture is requested, even if the data have already been fetched.
 			if(mWriteToCacheState != NOT_WRITE)
 			{
+				// Why do we want to keep url if NOT_WRITE - is this a proxy for map tiles?
 				mUrl.clear();
 			}
 			
@@ -1560,7 +1600,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				}
 
 				// abort.
-				mState = DONE;
+				setState(DONE);
+				LL_WARNS("Texture") << mID << " abort: no data received" << llendl;
 				releaseHttpSemaphore();
 				return true;
 			}
@@ -1578,7 +1619,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				{
 					LL_WARNS("Texture") << "Partial HTTP response produces break in image data for texture "
 										<< mID << ".  Aborting load."  << LL_ENDL;
-					mState = DONE;
+					setState(DONE);
 					releaseHttpSemaphore();
 					return true;
 				}
@@ -1626,7 +1667,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			mHttpReplyOffset = 0;
 			
 			mLoadedDiscard = mRequestedDiscard;
-			mState = DECODE_IMAGE;
+			if (mLoadedDiscard < 0)
+			{
+				LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+									<< ", should be >=0" << llendl;
+			}
+			setState(DECODE_IMAGE);
 			if (mWriteToCacheState != NOT_WRITE)
 			{
 				mWriteToCacheState = SHOULD_WRITE ;
@@ -1657,31 +1703,34 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		if (textures_decode_disabled)
 		{
 			// for debug use, don't decode
-			mState = DONE;
+			setState(DONE);
 			return true;
 		}
 
 		if (mDesiredDiscard < 0)
 		{
 			// We aborted, don't decode
-			mState = DONE;
+			setState(DONE);
+			LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: desired discard " << mDesiredDiscard << "<0" << llendl;
 			return true;
 		}
 		
 		if (mFormattedImage->getDataSize() <= 0)
 		{
-			//llerrs << "Decode entered with invalid mFormattedImage. ID = " << mID << llendl;
+			llwarns << "Decode entered with invalid mFormattedImage. ID = " << mID << llendl;
 			
 			//abort, don't decode
-			mState = DONE;
+			setState(DONE);
+			LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: (mFormattedImage->getDataSize() <= 0)" << llendl;
 			return true;
 		}
 		if (mLoadedDiscard < 0)
 		{
-			//llerrs << "Decode entered with invalid mLoadedDiscard. ID = " << mID << llendl;
+			llwarns << "Decode entered with invalid mLoadedDiscard. ID = " << mID << llendl;
 
 			//abort, don't decode
-			mState = DONE;
+			setState(DONE);
+			LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: mLoadedDiscard < 0" << llendl;
 			return true;
 		}
 
@@ -1691,7 +1740,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		S32 discard = mHaveAllData ? 0 : mLoadedDiscard;
 		U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;
 		mDecoded  = FALSE;
-		mState = DECODE_IMAGE_UPDATE;
+		setState(DECODE_IMAGE_UPDATE);
 		LL_DEBUGS("Texture") << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard
 				<< " All Data: " << mHaveAllData << LL_ENDL;
 		mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, image_priority, discard, mNeedsAux,
@@ -1719,13 +1768,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					mFormattedImage = NULL;
 					++mRetryAttempt;
 					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-					mState = INIT;
+					setState(INIT);
 					return false;
 				}
 				else
 				{
 // 					llwarns << "UNABLE TO LOAD TEXTURE: " << mID << " RETRIES: " << mRetryAttempt << llendl;
-					mState = DONE; // failed
+					setState(DONE); // failed
 				}
 			}
 			else
@@ -1734,7 +1783,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				LL_DEBUGS("Texture") << mID << ": Decoded. Discard: " << mDecodedDiscard
 						<< " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL;
 				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-				mState = WRITE_TO_CACHE;
+				setState(WRITE_TO_CACHE);
 			}
 			// fall through
 		}
@@ -1750,7 +1799,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		{
 			// If we're in a local cache or we didn't actually receive any new data,
 			// or we failed to load anything, skip
-			mState = DONE;
+			setState(DONE);
 			return false;
 		}
 		S32 datasize = mFormattedImage->getDataSize();
@@ -1769,7 +1818,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
 		U32 cache_priority = mWorkPriority;
 		mWritten = FALSE;
-		mState = WAIT_ON_WRITE;
+		setState(WAIT_ON_WRITE);
 		++mCacheWriteCount;
 		CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID);
 		mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,
@@ -1782,7 +1831,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 	{
 		if (writeToCacheComplete())
 		{
-			mState = DONE;
+			setState(DONE);
 			// fall through
 		}
 		else
@@ -1803,7 +1852,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		if (mDecodedDiscard >= 0 && mDesiredDiscard < mDecodedDiscard)
 		{
 			// More data was requested, return to INIT
-			mState = INIT;
+			setState(INIT);
+			LL_DEBUGS("Texture") << mID << " more data requested, returning to INIT: " 
+								 << " mDecodedDiscard " << mDecodedDiscard << ">= 0 && mDesiredDiscard " << mDesiredDiscard
+								 << "<" << " mDecodedDiscard " << mDecodedDiscard << llendl;
 			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 			return false;
 		}
@@ -1843,10 +1895,10 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe
 	bool partial = false;
 	LLCore::HttpStatus status(response->getStatus());
 	
-	lldebugs << "HTTP COMPLETE: " << mID
-			 << " status: " << status.toHex()
-			 << " '" << status.toString() << "'"
-			 << llendl;
+	LL_DEBUGS("Texture") << "HTTP COMPLETE: " << mID
+						 << " status: " << status.toHex()
+						 << " '" << status.toString() << "'"
+						 << llendl;
 //	unsigned int offset(0), length(0), full_length(0);
 //	response->getRange(&offset, &length, &full_length);
 // 	llwarns << "HTTP COMPLETE: " << mID << " handle: " << handle
@@ -2401,7 +2453,7 @@ LLTextureFetch::~LLTextureFetch()
 	// ~LLQueuedThread() called here
 }
 
-bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
 								   S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
 {
 	if(mFetcherLocked)
@@ -2430,6 +2482,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
 	std::string exten = gDirUtilp->getExtension(url);
 	if (!url.empty() && (!exten.empty() && LLImageBase::getCodecFromExtension(exten) != IMG_CODEC_J2C))
 	{
+		LL_DEBUGS("Texture") << "full request for " << id << " exten is not J2C: " << exten << llendl;
 		// Only do partial requests for J2C at the moment
 		desired_size = MAX_IMAGE_DATA_SIZE;
 		desired_discard = 0;
@@ -2472,7 +2525,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
 		worker->setCanUseHTTP(can_use_http) ;
 		if (!worker->haveWork())
 		{
-			worker->mState = LLTextureFetchWorker::INIT;
+			worker->setState(LLTextureFetchWorker::INIT);
 			worker->unlockWorkMutex();									// -Mw
 
 			worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
@@ -2484,7 +2537,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
 	}
 	else
 	{
-		worker = new LLTextureFetchWorker(this, url, id, host, priority, desired_discard, desired_size);
+		worker = new LLTextureFetchWorker(this, f_type, url, id, host, priority, desired_discard, desired_size);
 		lockQueue();													// +Mfq
 		mRequestMap[id] = worker;
 		unlockQueue();													// -Mfq
@@ -2496,7 +2549,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
 		worker->unlockWorkMutex();										// -Mw
 	}
 	
-// 	llinfos << "REQUESTED: " << id << " Discard: " << desired_discard << llendl;
+ 	LL_DEBUGS("Texture") << "REQUESTED: " << id << " Discard: " << desired_discard << " size " << desired_size << llendl;
 	return true;
 }
 
@@ -3165,6 +3218,30 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
 	return true;
 }
 
+void LLTextureFetchWorker::setState(e_state new_state)
+{
+	static const char* e_state_name[] =
+	{
+		"INVALID",
+		"INIT",
+		"LOAD_FROM_TEXTURE_CACHE",
+		"CACHE_POST",
+		"LOAD_FROM_NETWORK",
+		"LOAD_FROM_SIMULATOR",
+		"WAIT_HTTP_RESOURCE",
+		"WAIT_HTTP_RESOURCE2",
+		"SEND_HTTP_REQ",
+		"WAIT_HTTP_REQ",
+		"DECODE_IMAGE",
+		"DECODE_IMAGE_UPDATE",
+		"WRITE_TO_CACHE",
+		"WAIT_ON_WRITE",
+		"DONE"
+	};
+	LL_DEBUGS("Texture") << "id: " << mID << " FTType: " << mFTType << " disc: " << mDesiredDiscard << " sz: " << mDesiredSize << " state: " << e_state_name[mState] << " => " << e_state_name[new_state] << llendl;
+	mState = new_state;
+}
+
 // Threads:  T*
 bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
 										U16 data_size, U8* data)
@@ -3221,7 +3298,7 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8
 	llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
 	res = worker->insertPacket(0, data, data_size);
 	worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
-	worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR;
+	worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
 	worker->unlockWorkMutex();											// -Mw
 	return res;
 }
@@ -3271,7 +3348,7 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1
 		(worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))
 	{
 		worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
-		worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR;
+		worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
 	}
 	else
 	{
@@ -3534,7 +3611,7 @@ void LLTextureFetch::releaseHttpWaiters()
 			break;
 		}
 		
-		worker->mState = LLTextureFetchWorker::SEND_HTTP_REQ;
+		worker->setState(LLTextureFetchWorker::SEND_HTTP_REQ);
 		worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
 		worker->unlockWorkMutex();										// -Mw
 
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 5ea3c14e1a5da462d0178c0f2c661dddfcc1eba9..902a3d7a25431054b235e171fc1504fbebac0927 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -44,8 +44,8 @@
 #include "httpoptions.h"
 #include "httpheaders.h"
 #include "httphandler.h"
+#include "llviewertexture.h"
 
-class LLViewerTexture;
 class LLTextureFetchWorker;
 class LLImageDecodeThread;
 class LLHost;
@@ -77,7 +77,7 @@ class LLTextureFetch : public LLWorkerThread
 	void shutDownImageDecodeThread();
 
 	// Threads:  T* (but Tmain mostly)
-	bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+	bool createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
 					   S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http);
 
 	// Requests that a fetch operation be deleted from the queue.
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 16c42dbd4330458dd3cc31fd4962788ab690af1b..e80136b286307082e3ae189988fd9f223fc73698 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -40,7 +40,7 @@
 #include "lltooltip.h"
 #include "llappviewer.h"
 #include "llselectmgr.h"
-#include "lltexlayer.h"
+#include "llviewertexlayer.h"
 #include "lltexturecache.h"
 #include "lltexturefetch.h"
 #include "llviewercontrol.h"
@@ -170,7 +170,7 @@ void LLTextureBar::draw()
 	{
 		color = LLColor4::green4;
 	}
-	else if (mImagep->getBoostLevel() > LLViewerTexture::BOOST_NONE)
+	else if (mImagep->getBoostLevel() > LLGLTexture::BOOST_NONE)
 	{
 		color = LLColor4::magenta;
 	}
@@ -420,14 +420,14 @@ void LLAvatarTexBar::draw()
 	LLColor4 color;
 	
 	U32 line_num = 1;
-	for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
-		const LLVOAvatarDefines::EBakedTextureIndex baked_index = baked_iter->first;
-		const LLTexLayerSet *layerset = avatarp->debugGetLayerSet(baked_index);
+		const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
+		const LLViewerTexLayerSet *layerset = avatarp->debugGetLayerSet(baked_index);
 		if (!layerset) continue;
-		const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+		const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
 		if (!layerset_buffer) continue;
 
 		LLColor4 text_color = LLColor4::white;
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 4dc0d424ac4e104434f1b1f22a025a4993b10b73..beb45e8179f8e946aac04f45c9ac183468bf8f4c 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -33,6 +33,7 @@
 #include "llbutton.h"
 #include "lliconctrl.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llnotifications.h"
 #include "llviewertexteditor.h"
 
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 4ef5ad845c5af04795095fe3267b5e6a62579df6..8bfde2bcf1f9d59248fd09682e4bcfc8605d6e3c 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -207,8 +207,6 @@ void LLToastNotifyPanel::adjustPanelForScriptNotice(S32 button_panel_width, S32
 
 void LLToastNotifyPanel::adjustPanelForTipNotice()
 {
-	LLRect info_rect = mInfoPanel->getRect();
-	LLRect this_rect = getRect();
 	//we don't need display ControlPanel for tips because they doesn't contain any buttons. 
 	mControlPanel->setVisible(FALSE);
 	reshape(getRect().getWidth(), mInfoPanel->getRect().getHeight());
diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp
index aba43a971534def7c0b709438c1104522f0dd09c..08d82ea9cbce569070dda56f00ffc441bb1cd342 100644
--- a/indra/newview/lltoolbrush.cpp
+++ b/indra/newview/lltoolbrush.cpp
@@ -657,7 +657,7 @@ bool LLToolBrushLand::canTerraform(LLViewerRegion* regionp) const
 {
 	if (!regionp) return false;
 	if (regionp->canManageEstate()) return true;
-	return !(regionp->getRegionFlags() & REGION_FLAGS_BLOCK_TERRAFORM);
+	return !regionp->getRegionFlag(REGION_FLAGS_BLOCK_TERRAFORM);
 }
 
 // static
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index 923fbecb1a2d3d2ee1f38bd7110c28fc7b461af2..5270c3d33ff12f83dca2d1d0a9b449225fab4aa1 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -471,7 +471,7 @@ BOOL LLToolCompCreate::handleMouseDown(S32 x, S32 y, MASK mask)
 	
 	mObjectPlacedOnMouseDown = TRUE;
 
-	return TRUE;
+	return handled;
 }
 
 void LLToolCompCreate::pickCallback(const LLPickInfo& pick_info)
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index 94c97158a8e0c8ea8dcce6c5ce53f543984c33a4..e085834326323ac3bc442434f0873c391fefc19a 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1247,7 +1247,7 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,
 	if (!item || !item->isFinished()) return;
 	
 	//if (regionp
-	//	&& (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX))
+	//	&& (regionp->getRegionFlag(REGION_FLAGS_SANDBOX)))
 	//{
 	//	LLFirstUse::useSandbox();
 	//}
@@ -1741,7 +1741,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
 	{
 		if(mSource == SOURCE_LIBRARY)
 		{
-			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
+			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
 			copy_inventory_item(
 				gAgent.getID(),
 				item->getPermissions().getOwner(),
@@ -2094,7 +2094,7 @@ EAcceptance LLToolDragAndDrop::dad3dActivateGesture(
 			{
 				// create item based on that one, and put it on if that
 				// was a success.
-				LLPointer<LLInventoryCallback> cb = new ActivateGestureCallback();
+				LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(activate_gesture_cb);
 				copy_inventory_item(
 					gAgent.getID(),
 					item->getPermissions().getOwner(),
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index a754d8ee7ee63c68307382fbdcf16ea7a240c147..857b0f07146555cb123c854d1008be66fa950650 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -314,8 +314,6 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
 	S32 dx = gViewerWindow->getCurrentMouseDX();
 	S32 dy = gViewerWindow->getCurrentMouseDY();
 	
-	BOOL moved_outside_slop = FALSE;
-	
 	if (hasMouseCapture() && mValidClickPoint)
 	{
 		mAccumX += llabs(dx);
@@ -323,19 +321,11 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
 
 		if (mAccumX >= SLOP_RANGE)
 		{
-			if (!mOutsideSlopX)
-			{
-				moved_outside_slop = TRUE;
-			}
 			mOutsideSlopX = TRUE;
 		}
 
 		if (mAccumY >= SLOP_RANGE)
 		{
-			if (!mOutsideSlopY)
-			{
-				moved_outside_slop = TRUE;
-			}
 			mOutsideSlopY = TRUE;
 		}
 	}
diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp
index 857d1053618a44fab58f872a52639f00efa86103..c1735adc9c799ceb941ad88065c6e1d17f116df9 100644
--- a/indra/newview/lltoolgun.cpp
+++ b/indra/newview/lltoolgun.cpp
@@ -42,7 +42,7 @@
 #include "llhudmanager.h"
 #include "lltoolmgr.h"
 #include "lltoolgrab.h"
-
+#include "lluiimage.h"
 // Linden library includes
 #include "llwindow.h"			// setMouseClipping()
 
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index 0d5daf129fc51c471e59ef9242ea34111c4d62ef..148e5a015b199b4397c567cf7f36a6b4b2b3e4b5 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -34,6 +34,7 @@
 #include "llaudioengine.h"
 #include "llviewercontrol.h"
 #include "llfontgl.h"
+#include "llwearable.h"
 #include "sound_ids.h"
 #include "v3math.h"
 #include "v3color.h"
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index f24891baf6a6b4474769a0cb17106a5314aedac5..fc9a316759e45046c09d18f93c43390112746978 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -791,14 +791,10 @@ BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
 	
 	LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
 	LLUUID owner;
-	S32 width = 0;
-	S32 height = 0;
 	
 	if ( hover_parcel )
 	{
 		owner = hover_parcel->getOwnerID();
-		width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth());
-		height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight());
 	}
 	
 	// Line: "Land"
@@ -1593,9 +1589,6 @@ BOOL LLToolPie::handleRightClickPick()
 
 	// didn't click in any UI object, so must have clicked in the world
 	LLViewerObject *object = mPick.getObject();
-	LLViewerObject *parent = NULL;
-	if(object)
-		parent = object->getRootEdit();
 	
 	// Can't ignore children here.
 	LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index 93ba3b25587c79ecd6334255ccd5bec27a1b467e..641fbc50422e966a8dfa98b32fabb9e62faeea3f 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -182,7 +182,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )
 		return FALSE;
 	}
 
-	if (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX)
+	if (regionp->getRegionFlag(REGION_FLAGS_SANDBOX))
 	{
 		//LLFirstUse::useSandbox();
 	}
@@ -485,7 +485,7 @@ BOOL LLToolPlacer::addDuplicate(S32 x, S32 y)
 										FALSE);				// select copy
 
 	if (regionp
-		&& (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX))
+		&& (regionp->getRegionFlag(REGION_FLAGS_SANDBOX)))
 	{
 		//LLFirstUse::useSandbox();
 	}
diff --git a/indra/newview/lluploadfloaterobservers.cpp b/indra/newview/lluploadfloaterobservers.cpp
index 5a6a17fbca81a7b4b01dfe79100380643ed23372..1d777b3f7f380be2e6fc0e560a52d580dc900851 100644
--- a/indra/newview/lluploadfloaterobservers.cpp
+++ b/indra/newview/lluploadfloaterobservers.cpp
@@ -33,9 +33,10 @@ LLUploadModelPremissionsResponder::LLUploadModelPremissionsResponder(const LLHan
 {
 }
 
-void LLUploadModelPremissionsResponder::error(U32 status, const std::string& reason)
+void LLUploadModelPremissionsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llwarns << "LLUploadModelPremissionsResponder::error("<< status << ": " << reason << ")" << llendl;
+	llwarns << "LLUploadModelPremissionsResponder error [status:"
+			<< status << "]: " << content << llendl;
 
 	LLUploadPermissionsObserver* observer = mObserverHandle.get();
 
diff --git a/indra/newview/lluploadfloaterobservers.h b/indra/newview/lluploadfloaterobservers.h
index 79aad282d71329e0c1f01414bd2643b980ee439e..b43ddb44d95456e57c9e952a51153c4409675d39 100644
--- a/indra/newview/lluploadfloaterobservers.h
+++ b/indra/newview/lluploadfloaterobservers.h
@@ -86,7 +86,7 @@ class LLUploadModelPremissionsResponder : public LLHTTPClient::Responder
 
 	LLUploadModelPremissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer);
 
-	void error(U32 status, const std::string& reason);
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 
 	void result(const LLSD& content);
 
diff --git a/indra/newview/llurlhistory.cpp b/indra/newview/llurlhistory.cpp
index edec30f8c45f9a8646bf43487a35341f66f7753b..dd17068be55b9a3ac68312d3a3daa64050ca3bf8 100644
--- a/indra/newview/llurlhistory.cpp
+++ b/indra/newview/llurlhistory.cpp
@@ -112,8 +112,6 @@ void LLURLHistory::addURL(const std::string& collection, const std::string& url)
 // static
 void LLURLHistory::removeURL(const std::string& collection, const std::string& url)
 {
-	LLSD::array_iterator iter = sHistorySD[collection].beginArray();
-	LLSD::array_iterator end = sHistorySD[collection].endArray();
 	for(int index = 0; index < sHistorySD[collection].size(); index++)
 	{
 		if(sHistorySD[collection].get(index).asString() == url)
diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp
old mode 100644
new mode 100755
index 4c59fd037195925fe656ac3d99a5085061381173..aaa81c57d42c53a74c08e31eb770b22f94cece11
--- a/indra/newview/llviewerassetstats.cpp
+++ b/indra/newview/llviewerassetstats.cpp
@@ -160,9 +160,7 @@ LLViewerAssetStats::LLViewerAssetStats()
 
 LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src)
 	: mRegionHandle(src.mRegionHandle),
-	  mResetTimestamp(src.mResetTimestamp),
-	  mPhaseStats(src.mPhaseStats),
-	  mAvatarRezStates(src.mAvatarRezStates)
+	  mResetTimestamp(src.mResetTimestamp)
 {
 	const PerRegionContainer::const_iterator it_end(src.mRegionStats.end());
 	for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it)
@@ -258,17 +256,6 @@ LLViewerAssetStats::recordFPS(F32 fps)
 	mCurRegionStats->mFPS.record(fps);
 }
 
-void
-LLViewerAssetStats::recordAvatarStats()
-{
-	std::vector<S32> rez_counts;
-	LLVOAvatar::getNearbyRezzedStats(rez_counts);
-	mAvatarRezStates = rez_counts;
-	mPhaseStats.clear();
-	mPhaseStats["cloud"] = LLViewerStats::PhaseMap::getPhaseStats("cloud");
-	mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray");
-}
-
 LLSD
 LLViewerAssetStats::asLLSD(bool compact_output)
 {
@@ -299,11 +286,6 @@ LLViewerAssetStats::asLLSD(bool compact_output)
 	static const LLSD::String max_tag("max");
 	static const LLSD::String mean_tag("mean");
 
-	// Avatar sub-tags
-	static const LLSD::String avatar_tag("avatar");
-	static const LLSD::String avatar_nearby_tag("nearby");
-	static const LLSD::String avatar_phase_stats_tag("phase_stats");
-	
 	const duration_t now = LLViewerAssetStatsFF::get_timestamp();
 	mCurRegionStats->accumulateTime(now);
 
@@ -362,16 +344,6 @@ LLViewerAssetStats::asLLSD(bool compact_output)
 	LLSD ret = LLSD::emptyMap();
 	ret["regions"] = regions;
 	ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6);
-	LLSD avatar_info;
-	avatar_info[avatar_nearby_tag] = LLSD::emptyArray();
-	for (S32 rez_stat=0; rez_stat < mAvatarRezStates.size(); ++rez_stat)
-	{
-		std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
-		avatar_info[avatar_nearby_tag][rez_status_name] = mAvatarRezStates[rez_stat];
-	}
-	avatar_info[avatar_phase_stats_tag]["cloud"] = mPhaseStats["cloud"].getData();
-	avatar_info[avatar_phase_stats_tag]["cloud-or-gray"] = mPhaseStats["cloud-or-gray"].getData();
-	ret[avatar_tag] = avatar_info;
 	
 	return ret;
 }
@@ -470,15 +442,6 @@ record_fps_main(F32 fps)
 	gViewerAssetStatsMain->recordFPS(fps);
 }
 
-void
-record_avatar_stats()
-{
-	if (! gViewerAssetStatsMain)
-		return;
-
-	gViewerAssetStatsMain->recordAvatarStats();
-}
-
 // 'thread1' - should be for TextureFetch thread
 
 void
diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h
old mode 100644
new mode 100755
index 83197522306f2572ce64bec9e908354d1ab1f255..e4581d2120629c4e0695d59c41348b8e527557de
--- a/indra/newview/llviewerassetstats.h
+++ b/indra/newview/llviewerassetstats.h
@@ -256,10 +256,6 @@ class LLViewerAssetStats
 
 	// Time of last reset
 	duration_t mResetTimestamp;
-
-	// Nearby avatar stats
-	std::vector<S32> mAvatarRezStates;
-	LLViewerStats::phase_stats_t mPhaseStats;
 };
 
 
@@ -318,8 +314,6 @@ void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_t
 
 void record_fps_main(F32 fps);
 
-void record_avatar_stats();
-
 /**
  * Region context, event and duration loggers for Thread 1.
  */
diff --git a/indra/newview/llviewerattachmenu.cpp b/indra/newview/llviewerattachmenu.cpp
index db7dc3fea61615b24efa0dd6dd936610715d863a..3975292ed3a6e7871384b9d21cebbfbf39876008 100644
--- a/indra/newview/llviewerattachmenu.cpp
+++ b/indra/newview/llviewerattachmenu.cpp
@@ -121,7 +121,7 @@ void LLViewerAttachMenu::attachObjects(const uuid_vec_t& items, const std::strin
 		else if(item && item->isFinished())
 		{
 			// must be in library. copy it to our inventory and put it on.
-			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp);
+			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp));
 			copy_inventory_item(gAgent.getID(),
 								item->getPermissions().getOwner(),
 								item->getUUID(),
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index a437a8b3b53624fbfc657507db888792291a474e..b5aa0ac92aa489b045999356310fc38de1211a5a 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -136,9 +136,6 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 &center,
 
 	mLastPointOfInterest = point_of_interest;
 
-	// constrain to max distance from avatar
-	LLVector3 camera_offset = center - gAgent.getPositionAgent();
-
 	LLViewerRegion * regp = gAgent.getRegion();
 	F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f;
 
@@ -318,7 +315,7 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
 {
 	F32 fov_y, aspect;
 	fov_y = RAD_TO_DEG * getView();
-	BOOL z_default_near, z_default_far = FALSE;
+	BOOL z_default_far = FALSE;
 	if (z_far <= 0)
 	{
 		z_default_far = TRUE;
@@ -326,7 +323,6 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
 	}
 	if (z_near <= 0)
 	{
-		z_default_near = TRUE;
 		z_near = getNear();
 	}
 	aspect = getAspect();
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 40577118ba75945778d5eee5874ac6f392645a1c..cf59e679551fbfaa939697420b40190b0ed35b97 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1424,7 +1424,7 @@ void render_ui_2d()
 		gGL.pushMatrix();
 		S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2);
 		S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2);
-		gGL.scalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f);
+		gGL.scalef(LLUI::getScaleFactor().mV[0], LLUI::getScaleFactor().mV[1], 1.f);
 		gGL.translatef((F32)half_width, (F32)half_height, 0.f);
 		F32 zoom = gAgentCamera.mHUDCurZoom;
 		gGL.scalef(zoom,zoom,1.f);
@@ -1462,10 +1462,10 @@ void render_ui_2d()
 				LLUI::sDirtyRect = last_rect;
 				last_rect = t_rect;
 			
-				last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::sGLScaleFactor.mV[0]);
-				last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::sGLScaleFactor.mV[0]);
-				last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::sGLScaleFactor.mV[1]);
-				last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::sGLScaleFactor.mV[1]);
+				last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]);
+				last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]);
+				last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]);
+				last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]);
 
 				LLRect clip_rect(last_rect);
 				
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
index 6bd5631df6e6914d0548c29b044e171bfa195b18..f81206ffecd27f57a1a3c8779c9b2d92f24ca94d 100644
--- a/indra/newview/llviewerdisplayname.cpp
+++ b/indra/newview/llviewerdisplayname.cpp
@@ -60,8 +60,10 @@ class LLSetDisplayNameResponder : public LLHTTPClient::Responder
 {
 public:
 	// only care about errors
-	/*virtual*/ void error(U32 status, const std::string& reason)
+	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
+		llwarns << "LLSetDisplayNameResponder error [status:"
+				<< status << "]: " << content << llendl;
 		LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
 		LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
 	}
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index a187318eb7672159fd404cd80388ef505f8e24d4..fff9821e86d0efa81fc939cd278529443f4be0b7 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -64,6 +64,11 @@
 #include "llavatarnamecache.h"
 #include "llavataractions.h"
 #include "lllogininstance.h"
+#include "llfavoritesbar.h"
+
+// Two do-nothing ops for use in callbacks.
+void no_op_inventory_func(const LLUUID&) {} 
+void no_op() {}
 
 ///----------------------------------------------------------------------------
 /// Helper class to store special inventory item names and their localized values.
@@ -588,7 +593,7 @@ void LLViewerInventoryCategory::copyViewerCategory(const LLViewerInventoryCatego
 {
 	copyCategory(other);
 	mOwnerID = other->mOwnerID;
-	mVersion = other->mVersion;
+	setVersion(other->getVersion());
 	mDescendentCount = other->mDescendentCount;
 	mDescendentsRequested = other->mDescendentsRequested;
 }
@@ -656,9 +661,19 @@ void LLViewerInventoryCategory::removeFromServer( void )
 	gAgent.sendReliableMessage();
 }
 
+S32 LLViewerInventoryCategory::getVersion() const
+{
+	return mVersion;
+}
+
+void LLViewerInventoryCategory::setVersion(S32 version)
+{
+	mVersion = version;
+}
+
 bool LLViewerInventoryCategory::fetch()
 {
-	if((VERSION_UNKNOWN == mVersion)
+	if((VERSION_UNKNOWN == getVersion())
 	   && mDescendentsRequested.hasExpired())	//Expired check prevents multiple downloads.
 	{
 		LL_DEBUGS("InventoryFetch") << "Fetching category children: " << mName << ", UUID: " << mUUID << LL_ENDL;
@@ -949,46 +964,7 @@ void LLInventoryCallbackManager::fire(U32 callback_id, const LLUUID& item_id)
 	}
 }
 
-void WearOnAvatarCallback::fire(const LLUUID& inv_item)
-{
-	if (inv_item.isNull())
-		return;
-
-	LLViewerInventoryItem *item = gInventory.getItem(inv_item);
-	if (item)
-	{
-		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, mReplace);
-	}
-}
-
-void ModifiedCOFCallback::fire(const LLUUID& inv_item)
-{
-	LLAppearanceMgr::instance().updateAppearanceFromCOF();
-
-	// Start editing the item if previously requested.
-	gAgentWearables.editWearableIfRequested(inv_item);
-
-	// TODO: camera mode may not be changed if a debug setting is tweaked
-	if( gAgentCamera.cameraCustomizeAvatar() )
-	{
-		// If we're in appearance editing mode, the current tab may need to be refreshed
-		LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
-		if (panel)
-		{
-			panel->showDefaultSubpart();
-		}
-	}
-}
-
-RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp)
-{
-	mAttach = attachmentp;
-}
-RezAttachmentCallback::~RezAttachmentCallback()
-{
-}
-
-void RezAttachmentCallback::fire(const LLUUID& inv_item)
+void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp)
 {
 	if (inv_item.isNull())
 		return;
@@ -996,11 +972,11 @@ void RezAttachmentCallback::fire(const LLUUID& inv_item)
 	LLViewerInventoryItem *item = gInventory.getItem(inv_item);
 	if (item)
 	{
-		rez_attachment(item, mAttach);
+		rez_attachment(item, attachmentp);
 	}
 }
 
-void ActivateGestureCallback::fire(const LLUUID& inv_item)
+void activate_gesture_cb(const LLUUID& inv_item)
 {
 	if (inv_item.isNull())
 		return;
@@ -1013,7 +989,7 @@ void ActivateGestureCallback::fire(const LLUUID& inv_item)
 	LLGestureMgr::instance().activateGesture(inv_item);
 }
 
-void CreateGestureCallback::fire(const LLUUID& inv_item)
+void create_gesture_cb(const LLUUID& inv_item)
 {
 	if (inv_item.isNull())
 		return;
@@ -1031,7 +1007,6 @@ void CreateGestureCallback::fire(const LLUUID& inv_item)
 }
 
 
-
 LLInventoryCallbackManager gInventoryCallbacks;
 
 void create_inventory_item(const LLUUID& agent_id, const LLUUID& session_id,
@@ -1157,6 +1132,11 @@ void link_inventory_item(
 		}
 	}
 
+#if 1 // debugging stuff
+	LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id);
+	lldebugs << "cat: " << cat << llendl;
+	
+#endif
 	LLMessageSystem* msg = gMessageSystem;
 	msg->newMessageFast(_PREHASH_LinkInventoryItem);
 	msg->nextBlock(_PREHASH_AgentData);
@@ -1283,7 +1263,7 @@ void create_new_item(const std::string& name,
 	
 	if (inv_type == LLInventoryType::IT_GESTURE)
 	{
-		LLPointer<LLInventoryCallback> cb = new CreateGestureCallback();
+		LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(create_gesture_cb);
 		create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
 							  parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
 							  NOT_WEARABLE, next_owner_perm, cb);
@@ -1444,6 +1424,28 @@ const std::string& LLViewerInventoryItem::getName() const
 	return  LLInventoryItem::getName();
 }
 
+S32 LLViewerInventoryItem::getSortField() const
+{
+	return LLFavoritesOrderStorage::instance().getSortIndex(mUUID);
+}
+
+//void LLViewerInventoryItem::setSortField(S32 sortField)
+//{
+//	LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField);
+//	getSLURL();
+//}
+
+void LLViewerInventoryItem::getSLURL()
+{
+	LLFavoritesOrderStorage::instance().getSLURL(mAssetUUID);
+}
+
+const LLPermissions& LLViewerInventoryItem::getPermissions() const
+{
+	// Use the actual permissions of the symlink, not its parent.
+	return LLInventoryItem::getPermissions();	
+}
+
 const LLUUID& LLViewerInventoryItem::getCreatorUUID() const
 {
 	if (const LLViewerInventoryItem *linked_item = getLinkedItem())
@@ -1514,6 +1516,17 @@ LLWearableType::EType LLViewerInventoryItem::getWearableType() const
 	return LLWearableType::EType(getFlags() & LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK);
 }
 
+
+time_t LLViewerInventoryItem::getCreationDate() const
+{
+	return LLInventoryItem::getCreationDate();
+}
+
+U32 LLViewerInventoryItem::getCRC32() const
+{
+	return LLInventoryItem::getCRC32();	
+}
+
 // *TODO: mantipov: should be removed with LMSortPrefix patch in llinventorymodel.cpp, EXT-3985
 static char getSeparator() { return '@'; }
 BOOL LLViewerInventoryItem::extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName)
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 3cf03c3bc52085c496ee4ef2682ec6cd3ccc94ac..61b1b8d84651ce46f6c54dbc722d0730c229e208 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -35,6 +35,7 @@
 #include <boost/signals2.hpp>	// boost::signals2::trackable
 
 class LLInventoryPanel;
+class LLFolderView;
 class LLFolderBridge;
 class LLViewerInventoryCategory;
 
@@ -60,6 +61,10 @@ class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::tr
 	virtual const LLUUID& getAssetUUID() const;
 	virtual const LLUUID& getProtectedAssetUUID() const; // returns LLUUID::null if current agent does not have permission to expose this asset's UUID to the user
 	virtual const std::string& getName() const;
+	virtual S32 getSortField() const;
+	//virtual void setSortField(S32 sortField);
+	virtual void getSLURL(); //Caches SLURL for landmark. //*TODO: Find a better way to do it and remove this method from here.
+	virtual const LLPermissions& getPermissions() const;
 	virtual const bool getIsFullPerm() const; // 'fullperm' in the popular sense: modify-ok & copy-ok & transfer-ok, no special god rules applied
 	virtual const LLUUID& getCreatorUUID() const;
 	virtual const std::string& getDescription() const;
@@ -68,11 +73,8 @@ class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::tr
 	virtual bool isWearableType() const;
 	virtual LLWearableType::EType getWearableType() const;
 	virtual U32 getFlags() const;
-
-    using LLInventoryItem::getPermissions;
-	using LLInventoryItem::getCreationDate;
-	using LLInventoryItem::setCreationDate;
-	using LLInventoryItem::getCRC32;
+	virtual time_t getCreationDate() const;
+	virtual U32 getCRC32() const; // really more of a checksum.
 
 	static BOOL extractSortFieldAndDisplayName(const std::string& name, S32* sortField, std::string* displayName);
 
@@ -204,13 +206,13 @@ class LLViewerInventoryCategory  : public LLInventoryCategory
 
 	// Version handling
 	enum { VERSION_UNKNOWN = -1, VERSION_INITIAL = 1 };
-	S32 getVersion() const { return mVersion; }
-	void setVersion(S32 version) { mVersion = version; }
+	S32 getVersion() const;
+	void setVersion(S32 version);
 
 	// Returns true if a fetch was issued.
 	bool fetch();
 
-	// used to help make cacheing more robust - for example, if
+	// used to help make caching more robust - for example, if
 	// someone is getting 4 packets but logs out after 3. the viewer
 	// may never know the cache is wrong.
 	enum { DESCENDENT_COUNT_UNKNOWN = -1 };
@@ -218,7 +220,7 @@ class LLViewerInventoryCategory  : public LLInventoryCategory
 	void setDescendentCount(S32 descendents) { mDescendentCount = descendents; }
 
 	// file handling on the viewer. These are not meant for anything
-	// other than cacheing.
+	// other than caching.
 	bool exportFileLocal(LLFILE* fp) const;
 	bool importFileLocal(LLFILE* fp);
 	void determineFolderType();
@@ -241,47 +243,60 @@ class LLInventoryCallback : public LLRefCount
 	virtual void fire(const LLUUID& inv_item) = 0;
 };
 
-class WearOnAvatarCallback : public LLInventoryCallback
+class LLViewerJointAttachment;
+
+void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp);
+
+void activate_gesture_cb(const LLUUID& inv_item);
+
+void create_gesture_cb(const LLUUID& inv_item);
+
+class AddFavoriteLandmarkCallback : public LLInventoryCallback
 {
 public:
-	WearOnAvatarCallback(bool do_replace = false) : mReplace(do_replace) {}
-	
+	AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
+	void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
+
+private:
 	void fire(const LLUUID& inv_item);
 
-protected:
-	bool mReplace;
+	LLUUID mTargetLandmarkId;
 };
 
-class ModifiedCOFCallback : public LLInventoryCallback
-{
-	void fire(const LLUUID& inv_item);
-};
+typedef boost::function<void(const LLUUID&)> inventory_func_type;
+void no_op_inventory_func(const LLUUID&); // A do-nothing inventory_func
 
-class LLViewerJointAttachment;
+typedef boost::function<void()> nullary_func_type;
+void no_op(); // A do-nothing nullary func.
 
-class RezAttachmentCallback : public LLInventoryCallback
+// Shim between inventory callback and boost function/callable
+class LLBoostFuncInventoryCallback: public LLInventoryCallback
 {
 public:
-	RezAttachmentCallback(LLViewerJointAttachment *attachmentp);
-	void fire(const LLUUID& inv_item);
 
-protected:
-	~RezAttachmentCallback();
+	LLBoostFuncInventoryCallback(inventory_func_type fire_func,
+								 nullary_func_type destroy_func = no_op):
+		mFireFunc(fire_func),
+		mDestroyFunc(destroy_func)
+	{
+	}
 
-private:
-	LLViewerJointAttachment* mAttach;
-};
+	// virtual
+	void fire(const LLUUID& item_id)
+	{
+		mFireFunc(item_id);
+	}
 
-class ActivateGestureCallback : public LLInventoryCallback
-{
-public:
-	void fire(const LLUUID& inv_item);
-};
+	// virtual
+	~LLBoostFuncInventoryCallback()
+	{
+		mDestroyFunc();
+	}
+	
 
-class CreateGestureCallback : public LLInventoryCallback
-{
-public:
-	void fire(const LLUUID& inv_item);
+private:
+	inventory_func_type mFireFunc;
+	nullary_func_type mDestroyFunc;
 };
 
 // misc functions
diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp
index a907f102f87f55a4680224c1d522b024b0577158..e46299f9d2d54ae2cf90c2aff73944100d9ceaa6 100644
--- a/indra/newview/llviewerjoint.cpp
+++ b/indra/newview/llviewerjoint.cpp
@@ -35,50 +35,26 @@
 #include "llrender.h"
 #include "llmath.h"
 #include "llglheaders.h"
-#include "llrendersphere.h"
 #include "llvoavatar.h"
 #include "pipeline.h"
 
-#define DEFAULT_LOD 0.0f
-
-const S32 MIN_PIXEL_AREA_3PASS_HAIR = 64*64;
-
-//-----------------------------------------------------------------------------
-// Static Data
-//-----------------------------------------------------------------------------
-BOOL					LLViewerJoint::sDisableLOD = FALSE;
+static const S32 MIN_PIXEL_AREA_3PASS_HAIR = 64*64;
 
 //-----------------------------------------------------------------------------
 // LLViewerJoint()
-// Class Constructor
+// Class Constructors
 //-----------------------------------------------------------------------------
-LLViewerJoint::LLViewerJoint()
-	:       LLJoint()
-{
-	init();
-}
+LLViewerJoint::LLViewerJoint() :
+	LLAvatarJoint()
+{ }
 
+LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) :
+	LLAvatarJoint(name, parent)
+{ }
 
-//-----------------------------------------------------------------------------
-// LLViewerJoint()
-// Class Constructor
-//-----------------------------------------------------------------------------
-LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent)
-	:	LLJoint(name, parent)
-{
-	init();
-}
-
-
-void LLViewerJoint::init()
-{
-	mValid = FALSE;
-	mComponents = SC_JOINT | SC_BONE | SC_AXES;
-	mMinPixelArea = DEFAULT_LOD;
-	mPickName = PN_DEFAULT;
-	mVisible = TRUE;
-	mMeshID = 0;
-}
+LLViewerJoint::LLViewerJoint(S32 joint_num) :
+	LLAvatarJoint(joint_num)
+{ }
 
 
 //-----------------------------------------------------------------------------
@@ -89,154 +65,6 @@ LLViewerJoint::~LLViewerJoint()
 {
 }
 
-
-//--------------------------------------------------------------------
-// setValid()
-//--------------------------------------------------------------------
-void LLViewerJoint::setValid( BOOL valid, BOOL recursive )
-{
-	//----------------------------------------------------------------
-	// set visibility for this joint
-	//----------------------------------------------------------------
-	mValid = valid;
-	
-	//----------------------------------------------------------------
-	// set visibility for children
-	//----------------------------------------------------------------
-	if (recursive)
-	{
-		for (child_list_t::iterator iter = mChildren.begin();
-			 iter != mChildren.end(); ++iter)
-		{
-			LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-			joint->setValid(valid, TRUE);
-		}
-	}
-
-}
-
-//--------------------------------------------------------------------
-// renderSkeleton()
-// DEBUG (UNUSED)
-//--------------------------------------------------------------------
-// void LLViewerJoint::renderSkeleton(BOOL recursive)
-// {
-// 	F32 nc = 0.57735f;
-
-// 	//----------------------------------------------------------------
-// 	// push matrix stack
-// 	//----------------------------------------------------------------
-// 	gGL.pushMatrix();
-
-// 	//----------------------------------------------------------------
-// 	// render the bone to my parent
-// 	//----------------------------------------------------------------
-// 	if (mComponents & SC_BONE)
-// 	{
-// 		drawBone();
-// 	}
-
-// 	//----------------------------------------------------------------
-// 	// offset to joint position and 
-// 	// rotate to our orientation
-// 	//----------------------------------------------------------------
-// 	gGL.loadIdentity();
-// 	gGL.multMatrix( &getWorldMatrix().mMatrix[0][0] );
-
-// 	//----------------------------------------------------------------
-// 	// render joint axes
-// 	//----------------------------------------------------------------
-// 	if (mComponents & SC_AXES)
-// 	{
-// 		gGL.begin(LLRender::LINES);
-// 		gGL.color3f( 1.0f, 0.0f, 0.0f );
-// 		gGL.vertex3f( 0.0f,            0.0f, 0.0f );
-// 		gGL.vertex3f( 0.1f, 0.0f, 0.0f );
-
-// 		gGL.color3f( 0.0f, 1.0f, 0.0f );
-// 		gGL.vertex3f( 0.0f, 0.0f,            0.0f );
-// 		gGL.vertex3f( 0.0f, 0.1f, 0.0f );
-
-// 		gGL.color3f( 0.0f, 0.0f, 1.0f );
-// 		gGL.vertex3f( 0.0f, 0.0f, 0.0f );
-// 		gGL.vertex3f( 0.0f, 0.0f, 0.1f );
-// 		gGL.end();
-// 	}
-
-// 	//----------------------------------------------------------------
-// 	// render the joint graphic
-// 	//----------------------------------------------------------------
-// 	if (mComponents & SC_JOINT)
-// 	{
-// 		gGL.color3f( 1.0f, 1.0f, 0.0f );
-
-// 		gGL.begin(LLRender::TRIANGLES);
-
-// 		// joint top half
-// 		glNormal3f(nc, nc, nc);
-// 		gGL.vertex3f(0.0f,             0.0f, 0.05f);
-// 		gGL.vertex3f(0.05f,       0.0f,       0.0f);
-// 		gGL.vertex3f(0.0f,       0.05f,       0.0f);
-
-// 		glNormal3f(-nc, nc, nc);
-// 		gGL.vertex3f(0.0f,             0.0f, 0.05f);
-// 		gGL.vertex3f(0.0f,       0.05f,       0.0f);
-// 		gGL.vertex3f(-0.05f,      0.0f,       0.0f);
-		
-// 		glNormal3f(-nc, -nc, nc);
-// 		gGL.vertex3f(0.0f,             0.0f, 0.05f);
-// 		gGL.vertex3f(-0.05f,      0.0f,      0.0f);
-// 		gGL.vertex3f(0.0f,      -0.05f,      0.0f);
-
-// 		glNormal3f(nc, -nc, nc);
-// 		gGL.vertex3f(0.0f,              0.0f, 0.05f);
-// 		gGL.vertex3f(0.0f,       -0.05f,       0.0f);
-// 		gGL.vertex3f(0.05f,        0.0f,       0.0f);
-		
-// 		// joint bottom half
-// 		glNormal3f(nc, nc, -nc);
-// 		gGL.vertex3f(0.0f,             0.0f, -0.05f);
-// 		gGL.vertex3f(0.0f,       0.05f,        0.0f);
-// 		gGL.vertex3f(0.05f,       0.0f,        0.0f);
-
-// 		glNormal3f(-nc, nc, -nc);
-// 		gGL.vertex3f(0.0f,             0.0f, -0.05f);
-// 		gGL.vertex3f(-0.05f,      0.0f,        0.0f);
-// 		gGL.vertex3f(0.0f,       0.05f,        0.0f);
-		
-// 		glNormal3f(-nc, -nc, -nc);
-// 		gGL.vertex3f(0.0f,              0.0f, -0.05f);
-// 		gGL.vertex3f(0.0f,       -0.05f,        0.0f);
-// 		gGL.vertex3f(-0.05f,       0.0f,        0.0f);
-
-// 		glNormal3f(nc, -nc, -nc);
-// 		gGL.vertex3f(0.0f,             0.0f,  -0.05f);
-// 		gGL.vertex3f(0.05f,       0.0f,         0.0f);
-// 		gGL.vertex3f(0.0f,      -0.05f,         0.0f);
-		
-// 		gGL.end();
-// 	}
-
-// 	//----------------------------------------------------------------
-// 	// render children
-// 	//----------------------------------------------------------------
-// 	if (recursive)
-// 	{
-// 		for (child_list_t::iterator iter = mChildren.begin();
-// 			 iter != mChildren.end(); ++iter)
-// 		{
-// 			LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-// 			joint->renderSkeleton();
-// 		}
-// 	}
-
-// 	//----------------------------------------------------------------
-// 	// pop matrix stack
-// 	//----------------------------------------------------------------
-// 	gGL.popMatrix();
-// }
-
-
 //--------------------------------------------------------------------
 // render()
 //--------------------------------------------------------------------
@@ -317,13 +145,13 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
 	for (child_list_t::iterator iter = mChildren.begin();
 		 iter != mChildren.end(); ++iter)
 	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
 		F32 jointLOD = joint->getLOD();
 		if (pixelArea >= jointLOD || sDisableLOD)
 		{
 			triangle_count += joint->render( pixelArea, TRUE, is_dummy );
 
-			if (jointLOD != DEFAULT_LOD)
+			if (jointLOD != DEFAULT_AVATAR_JOINT_LOD)
 			{
 				break;
 			}
@@ -333,72 +161,6 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
 	return triangle_count;
 }
 
-
-//--------------------------------------------------------------------
-// drawBone()
-// DEBUG (UNUSED)
-//--------------------------------------------------------------------
-// void LLViewerJoint::drawBone()
-// {
-// 	if ( mParent == NULL )
-// 		return;
-
-// 	F32 boneSize = 0.02f;
-
-// 	// rotate to point to child (bone direction)
-// 	gGL.pushMatrix();
-
-// 	LLVector3 boneX = getPosition();
-// 	F32 length = boneX.normVec();
-
-// 	LLVector3 boneZ(1.0f, 0.0f, 1.0f);
-	
-// 	LLVector3 boneY = boneZ % boneX;
-// 	boneY.normVec();
-
-// 	boneZ = boneX % boneY;
-
-// 	LLMatrix4 rotateMat;
-// 	rotateMat.setFwdRow( boneX );
-// 	rotateMat.setLeftRow( boneY );
-// 	rotateMat.setUpRow( boneZ );
-// 	gGL.multMatrix( &rotateMat.mMatrix[0][0] );
-
-// 	// render the bone
-// 	gGL.color3f( 0.5f, 0.5f, 0.0f );
-
-// 	gGL.begin(LLRender::TRIANGLES);
-
-// 	gGL.vertex3f( length,     0.0f,       0.0f);
-// 	gGL.vertex3f( 0.0f,       boneSize,  0.0f);
-// 	gGL.vertex3f( 0.0f,       0.0f,       boneSize);
-
-// 	gGL.vertex3f( length,     0.0f,        0.0f);
-// 	gGL.vertex3f( 0.0f,       0.0f,        -boneSize);
-// 	gGL.vertex3f( 0.0f,       boneSize,   0.0f);
-
-// 	gGL.vertex3f( length,     0.0f,        0.0f);
-// 	gGL.vertex3f( 0.0f,       -boneSize,  0.0f);
-// 	gGL.vertex3f( 0.0f,       0.0f,        -boneSize);
-
-// 	gGL.vertex3f( length,     0.0f,        0.0f);
-// 	gGL.vertex3f( 0.0f,       0.0f,        boneSize);
-// 	gGL.vertex3f( 0.0f,       -boneSize,  0.0f);
-
-// 	gGL.end();
-
-// 	// restore matrix
-// 	gGL.popMatrix();
-// }
-
-//--------------------------------------------------------------------
-// isTransparent()
-//--------------------------------------------------------------------
-BOOL LLViewerJoint::isTransparent()
-{
-	return FALSE;
-}
-
 //--------------------------------------------------------------------
 // drawShape()
 //--------------------------------------------------------------------
@@ -407,213 +169,4 @@ U32 LLViewerJoint::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
 	return 0;
 }
 
-//--------------------------------------------------------------------
-// setSkeletonComponents()
-//--------------------------------------------------------------------
-void LLViewerJoint::setSkeletonComponents( U32 comp, BOOL recursive )
-{
-	mComponents = comp;
-	if (recursive)
-	{
-		for (child_list_t::iterator iter = mChildren.begin();
-			 iter != mChildren.end(); ++iter)
-		{
-			LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-			joint->setSkeletonComponents(comp, recursive);
-		}
-	}
-}
-
-void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
-{
-	for (child_list_t::iterator iter = mChildren.begin();
-		 iter != mChildren.end(); ++iter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-		joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
-	}
-}
-
-void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
-{
-	for (child_list_t::iterator iter = mChildren.begin();
-		 iter != mChildren.end(); ++iter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-		joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
-	}
-}
-
-void LLViewerJoint::updateJointGeometry()
-{
-	for (child_list_t::iterator iter = mChildren.begin();
-		 iter != mChildren.end(); ++iter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-		joint->updateJointGeometry();
-	}
-}
-
-
-BOOL LLViewerJoint::updateLOD(F32 pixel_area, BOOL activate)
-{
-	BOOL lod_changed = FALSE;
-	BOOL found_lod = FALSE;
-
-	for (child_list_t::iterator iter = mChildren.begin();
-		 iter != mChildren.end(); ++iter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-		F32 jointLOD = joint->getLOD();
-		
-		if (found_lod || jointLOD == DEFAULT_LOD)
-		{
-			// we've already found a joint to enable, so enable the rest as alternatives
-			lod_changed |= joint->updateLOD(pixel_area, TRUE);
-		}
-		else
-		{
-			if (pixel_area >= jointLOD || sDisableLOD)
-			{
-				lod_changed |= joint->updateLOD(pixel_area, TRUE);
-				found_lod = TRUE;
-			}
-			else
-			{
-				lod_changed |= joint->updateLOD(pixel_area, FALSE);
-			}
-		}
-	}
-	return lod_changed;
-}
-
-void LLViewerJoint::dump()
-{
-	for (child_list_t::iterator iter = mChildren.begin();
-		 iter != mChildren.end(); ++iter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-		joint->dump();
-	}
-}
-
-void LLViewerJoint::setVisible(BOOL visible, BOOL recursive)
-{
-	mVisible = visible;
-
-	if (recursive)
-	{
-		for (child_list_t::iterator iter = mChildren.begin();
-			 iter != mChildren.end(); ++iter)
-		{
-			LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-			joint->setVisible(visible, recursive);
-		}
-	}
-}
-
-
-void LLViewerJoint::setMeshesToChildren()
-{
-	removeAllChildren();
-	for (std::vector<LLViewerJointMesh*>::iterator iter = mMeshParts.begin();
-		iter != mMeshParts.end(); iter++)
-	{
-		addChild((LLViewerJointMesh *) *iter);
-	}
-}
-//-----------------------------------------------------------------------------
-// LLViewerJointCollisionVolume()
-//-----------------------------------------------------------------------------
-
-LLViewerJointCollisionVolume::LLViewerJointCollisionVolume()
-{
-	mUpdateXform = FALSE;
-}
-
-LLViewerJointCollisionVolume::LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent) : LLViewerJoint(name, parent)
-{
-	
-}
-
-void LLViewerJointCollisionVolume::renderCollision()
-{
-	updateWorldMatrix();
-	
-	gGL.pushMatrix();
-	gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] );
-
-	gGL.diffuseColor3f( 0.f, 0.f, 1.f );
-	
-	gGL.begin(LLRender::LINES);
-	
-	LLVector3 v[] = 
-	{
-		LLVector3(1,0,0),
-		LLVector3(-1,0,0),
-		LLVector3(0,1,0),
-		LLVector3(0,-1,0),
-
-		LLVector3(0,0,-1),
-		LLVector3(0,0,1),
-	};
-
-	//sides
-	gGL.vertex3fv(v[0].mV); 
-	gGL.vertex3fv(v[2].mV);
-
-	gGL.vertex3fv(v[0].mV); 
-	gGL.vertex3fv(v[3].mV);
-
-	gGL.vertex3fv(v[1].mV); 
-	gGL.vertex3fv(v[2].mV);
-
-	gGL.vertex3fv(v[1].mV); 
-	gGL.vertex3fv(v[3].mV);
-
-
-	//top
-	gGL.vertex3fv(v[0].mV); 
-	gGL.vertex3fv(v[4].mV);
-
-	gGL.vertex3fv(v[1].mV); 
-	gGL.vertex3fv(v[4].mV);
-
-	gGL.vertex3fv(v[2].mV); 
-	gGL.vertex3fv(v[4].mV);
-
-	gGL.vertex3fv(v[3].mV); 
-	gGL.vertex3fv(v[4].mV);
-
-
-	//bottom
-	gGL.vertex3fv(v[0].mV); 
-	gGL.vertex3fv(v[5].mV);
-
-	gGL.vertex3fv(v[1].mV); 
-	gGL.vertex3fv(v[5].mV);
-
-	gGL.vertex3fv(v[2].mV); 
-	gGL.vertex3fv(v[5].mV);
-
-	gGL.vertex3fv(v[3].mV); 
-	gGL.vertex3fv(v[5].mV);
-
-	gGL.end();
-
-	gGL.popMatrix();
-}
-
-LLVector3 LLViewerJointCollisionVolume::getVolumePos(LLVector3 &offset)
-{
-	mUpdateXform = TRUE;
-	
-	LLVector3 result = offset;
-	result.scaleVec(getScale());
-	result.rotVec(getWorldRotation());
-	result += getWorldPosition();
-
-	return result;
-}
-
 // End
diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h
index 76e3833acbf4fcaff77dd3796abd77c1a2c9df7c..fd262b6e804793cfdc602545bd83dbd668ff2cd9 100644
--- a/indra/newview/llviewerjoint.h
+++ b/indra/newview/llviewerjoint.h
@@ -30,7 +30,8 @@
 //-----------------------------------------------------------------------------
 // Header Files
 //-----------------------------------------------------------------------------
-#include "lljoint.h"
+#include "llavatarjoint.h"
+#include "lljointpickname.h"
 
 class LLFace;
 class LLViewerJointMesh;
@@ -39,124 +40,25 @@ class LLViewerJointMesh;
 // class LLViewerJoint
 //-----------------------------------------------------------------------------
 class LLViewerJoint :
-	public LLJoint
+	public virtual LLAvatarJoint
 {
 public:
 	LLViewerJoint();
+	LLViewerJoint(S32 joint_num);
+	// *TODO: Only used for LLVOAvatarSelf::mScreenp.  *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
 	LLViewerJoint(const std::string &name, LLJoint *parent = NULL);
 	virtual ~LLViewerJoint();
 
-	// Gets the validity of this joint
-	BOOL getValid() { return mValid; }
-
-	// Sets the validity of this joint
-	virtual void setValid( BOOL valid, BOOL recursive=FALSE );
-
-	// Primarily for debugging and character setup
-	// Derived classes may add text/graphic output.
-	// Draw skeleton graphic for debugging and character setup
- 	void renderSkeleton(BOOL recursive=TRUE); // debug only (unused)
-
-	// Draws a bone graphic to the parent joint.
-	// Derived classes may add text/graphic output.
-	// Called by renderSkeleton().
- 	void drawBone(); // debug only (unused)
-
 	// Render character hierarchy.
 	// Traverses the entire joint hierarchy, setting up
 	// transforms and calling the drawShape().
 	// Derived classes may add text/graphic output.
 	virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );	// Returns triangle count
 
-	// Returns true if this object is transparent.
-	// This is used to determine in which order to draw objects.
-	virtual BOOL isTransparent();
-
-	// Returns true if this object should inherit scale modifiers from its immediate parent
-	virtual BOOL inheritScale() { return FALSE; }
-
 	// Draws the shape attached to a joint.
 	// Called by render().
 	virtual U32 drawShape( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );
 	virtual void drawNormals() {}
-
-	enum Components
-	{
-		SC_BONE		= 1,
-		SC_JOINT	= 2,
-		SC_AXES		= 4
-	};
-
-	// Selects which skeleton components to draw
-	void setSkeletonComponents( U32 comp, BOOL recursive = TRUE );
-
-	// Returns which skeleton components are enables for drawing
-	U32 getSkeletonComponents() { return mComponents; }
-
-	// Sets the level of detail for this node as a minimum
-	// pixel area threshold.  If the current pixel area for this
-	// object is less than the specified threshold, the node is
-	// not traversed.  In addition, if a value is specified (not
-	// default of 0.0), and the pixel area is larger than the
-	// specified minimum, the node is rendered, but no other siblings
-	// of this node under the same parent will be.
-	F32 getLOD() { return mMinPixelArea; }
-	void setLOD( F32 pixelArea ) { mMinPixelArea = pixelArea; }
-	
-	// Sets the OpenGL selection stack name that is pushed and popped
-	// with this joint state.  The default value indicates that no name
-	// should be pushed/popped.
-	enum PickName
-	{
-		PN_DEFAULT = -1,
-		PN_0 = 0,
-		PN_1 = 1,
-		PN_2 = 2,
-		PN_3 = 3,
-		PN_4 = 4,
-		PN_5 = 5
-	};
-	void setPickName(PickName name) { mPickName = name; }
-	PickName getPickName() { return mPickName; }
-
-	virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
-	virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
-	virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
-	virtual void updateJointGeometry();
-	virtual void dump();
-
-	void setVisible( BOOL visible, BOOL recursive );
-
-	// Takes meshes in mMeshParts and sets each one as a child joint
-	void setMeshesToChildren();
-
-public:
-	static BOOL	sDisableLOD;
-	std::vector<LLViewerJointMesh*> mMeshParts;
-	void setMeshID( S32 id ) {mMeshID = id;}
-
-protected:
-	void init();
-
-	BOOL		mValid;
-	U32			mComponents;
-	F32			mMinPixelArea;
-	PickName	mPickName;
-	BOOL		mVisible;
-	S32			mMeshID;
-};
-
-class LLViewerJointCollisionVolume : public LLViewerJoint
-{
-public:
-	LLViewerJointCollisionVolume();
-	LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent = NULL);
-	virtual ~LLViewerJointCollisionVolume() {};
-
-	virtual BOOL inheritScale() { return TRUE; }
-
-	void renderCollision();
-	LLVector3 getVolumePos(LLVector3 &offset);
 };
 
 #endif // LL_LLVIEWERJOINT_H
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 5d1aa870a3165ee455c8d2dc4e90825cec78658a..64454a03d1a7e4b5bb92617eb60b0e69a054859c 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -42,7 +42,7 @@
 #include "llface.h"
 #include "llgldbg.h"
 #include "llglheaders.h"
-#include "lltexlayer.h"
+#include "llviewertexlayer.h"
 #include "llviewercamera.h"
 #include "llviewercontrol.h"
 #include "llviewertexturelist.h"
@@ -67,101 +67,20 @@ static const U32 sRenderMask = LLVertexBuffer::MAP_VERTEX |
 							   LLVertexBuffer::MAP_NORMAL |
 							   LLVertexBuffer::MAP_TEXCOORD0;
 
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::LLSkinJoint
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// LLSkinJoint
-//-----------------------------------------------------------------------------
-LLSkinJoint::LLSkinJoint()
-{
-	mJoint       = NULL;
-}
-
-//-----------------------------------------------------------------------------
-// ~LLSkinJoint
-//-----------------------------------------------------------------------------
-LLSkinJoint::~LLSkinJoint()
-{
-	mJoint = NULL;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLSkinJoint::setupSkinJoint()
-//-----------------------------------------------------------------------------
-BOOL LLSkinJoint::setupSkinJoint( LLViewerJoint *joint)
-{
-	// find the named joint
-	mJoint = joint;
-	if ( !mJoint )
-	{
-		llinfos << "Can't find joint" << llendl;
-	}
-
-	// compute the inverse root skin matrix
-	mRootToJointSkinOffset.clearVec();
-
-	LLVector3 rootSkinOffset;
-	while (joint)
-	{
-		rootSkinOffset += joint->getSkinOffset();
-		joint = (LLViewerJoint*)joint->getParent();
-	}
-
-	mRootToJointSkinOffset = -rootSkinOffset;
-	mRootToParentJointSkinOffset = mRootToJointSkinOffset;
-	mRootToParentJointSkinOffset += mJoint->getSkinOffset();
-
-	return TRUE;
-}
-
-
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // LLViewerJointMesh
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
-BOOL LLViewerJointMesh::sPipelineRender = FALSE;
-EAvatarRenderPass LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;
-U32 LLViewerJointMesh::sClothingMaskImageName = 0;
-LLColor4 LLViewerJointMesh::sClothingInnerColor;
 
 //-----------------------------------------------------------------------------
 // LLViewerJointMesh()
 //-----------------------------------------------------------------------------
 LLViewerJointMesh::LLViewerJointMesh()
 	:
-	mTexture( NULL ),
-	mLayerSet( NULL ),
-	mTestImageName( 0 ),
-	mFaceIndexCount(0),
-	mIsTransparent(FALSE)
+	LLAvatarJointMesh()
 {
-
-	mColor[0] = 1.0f;
-	mColor[1] = 1.0f;
-	mColor[2] = 1.0f;
-	mColor[3] = 1.0f;
-	mShiny = 0.0f;
-	mCullBackFaces = TRUE;
-
-	mMesh = NULL;
-
-	mNumSkinJoints = 0;
-	mSkinJoints = NULL;
-
-	mFace = NULL;
-
-	mMeshID = 0;
-	mUpdateXform = FALSE;
-
-	mValid = FALSE;
 }
 
 
@@ -171,199 +90,6 @@ LLViewerJointMesh::LLViewerJointMesh()
 //-----------------------------------------------------------------------------
 LLViewerJointMesh::~LLViewerJointMesh()
 {
-	mMesh = NULL;
-	mTexture = NULL;
-	freeSkinData();
-}
-
-
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::allocateSkinData()
-//-----------------------------------------------------------------------------
-BOOL LLViewerJointMesh::allocateSkinData( U32 numSkinJoints )
-{
-	mSkinJoints = new LLSkinJoint[ numSkinJoints ];
-	mNumSkinJoints = numSkinJoints;
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::freeSkinData()
-//-----------------------------------------------------------------------------
-void LLViewerJointMesh::freeSkinData()
-{
-	mNumSkinJoints = 0;
-	delete [] mSkinJoints;
-	mSkinJoints = NULL;
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::getColor()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha )
-{
-	*red   = mColor[0];
-	*green = mColor[1];
-	*blue  = mColor[2];
-	*alpha = mColor[3];
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::setColor()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha )
-{
-	mColor[0] = red;
-	mColor[1] = green;
-	mColor[2] = blue;
-	mColor[3] = alpha;
-}
-
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::getTexture()
-//--------------------------------------------------------------------
-//LLViewerTexture *LLViewerJointMesh::getTexture()
-//{
-//	return mTexture;
-//}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::setTexture()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::setTexture( LLViewerTexture *texture )
-{
-	mTexture = texture;
-
-	// texture and dynamic_texture are mutually exclusive
-	if( texture )
-	{
-		mLayerSet = NULL;
-		//texture->bindTexture(0);
-		//texture->setClamp(TRUE, TRUE);
-	}
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::setLayerSet()
-// Sets the shape texture (takes precedence over normal texture)
-//--------------------------------------------------------------------
-void LLViewerJointMesh::setLayerSet( LLTexLayerSet* layer_set )
-{
-	mLayerSet = layer_set;
-	
-	// texture and dynamic_texture are mutually exclusive
-	if( layer_set )
-	{
-		mTexture = NULL;
-	}
-}
-
-
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::getMesh()
-//--------------------------------------------------------------------
-LLPolyMesh *LLViewerJointMesh::getMesh()
-{
-	return mMesh;
-}
-
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::setMesh()
-//-----------------------------------------------------------------------------
-void LLViewerJointMesh::setMesh( LLPolyMesh *mesh )
-{
-	// set the mesh pointer
-	mMesh = mesh;
-
-	// release any existing skin joints
-	freeSkinData();
-
-	if ( mMesh == NULL )
-	{
-		return;
-	}
-
-	// acquire the transform from the mesh object
-	setPosition( mMesh->getPosition() );
-	setRotation( mMesh->getRotation() );
-	setScale( mMesh->getScale() );
-
-	// create skin joints if necessary
-	if ( mMesh->hasWeights() && !mMesh->isLOD())
-	{
-		U32 numJointNames = mMesh->getNumJointNames();
-		
-		allocateSkinData( numJointNames );
-		std::string *jointNames = mMesh->getJointNames();
-
-		U32 jn;
-		for (jn = 0; jn < numJointNames; jn++)
-		{
-			//llinfos << "Setting up joint " << jointNames[jn] << llendl;
-			LLViewerJoint* joint = (LLViewerJoint*)(getRoot()->findJoint(jointNames[jn]) );
-			mSkinJoints[jn].setupSkinJoint( joint );
-		}
-	}
-
-	// setup joint array
-	if (!mMesh->isLOD())
-	{
-		setupJoint((LLViewerJoint*)getRoot());
-	}
-
-//	llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl;
-}
-
-//-----------------------------------------------------------------------------
-// setupJoint()
-//-----------------------------------------------------------------------------
-void LLViewerJointMesh::setupJoint(LLViewerJoint* current_joint)
-{
-//	llinfos << "Mesh: " << getName() << llendl;
-
-//	S32 joint_count = 0;
-	U32 sj;
-	for (sj=0; sj<mNumSkinJoints; sj++)
-	{
-		LLSkinJoint &js = mSkinJoints[sj];
-
-		if (js.mJoint != current_joint)
-		{
-			continue;
-		}
-
-		// we've found a skinjoint for this joint..
-
-		// is the last joint in the array our parent?
-		if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == &current_joint->getParent()->getWorldMatrix())
-		{
-			// ...then just add ourselves
-			LLViewerJoint* jointp = js.mJoint;
-			mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js));
-//			llinfos << "joint " << joint_count << js.mJoint->getName() << llendl;
-//			joint_count++;
-		}
-		// otherwise add our parent and ourselves
-		else
-		{
-			mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getParent()->getWorldMatrix(), NULL));
-//			llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl;
-//			joint_count++;
-			mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getWorldMatrix(), &js));
-//			llinfos << "joint " << joint_count << current_joint->getName() << llendl;
-//			joint_count++;
-		}
-	}
-
-	// depth-first traversal
-	for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin();
-		 iter != current_joint->mChildren.end(); ++iter)
-	{
-		LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
-		setupJoint(child_joint);
-	}
 }
 
 const S32 NUM_AXES = 3;
@@ -474,21 +200,6 @@ void LLViewerJointMesh::uploadJointMatrices()
 	}
 }
 
-//--------------------------------------------------------------------
-// LLViewerJointMesh::drawBone()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::drawBone()
-{
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::isTransparent()
-//--------------------------------------------------------------------
-BOOL LLViewerJointMesh::isTransparent()
-{
-	return mIsTransparent;
-}
-
 //--------------------------------------------------------------------
 // DrawElementsBLEND and utility code
 //--------------------------------------------------------------------
@@ -544,6 +255,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 	llassert( !(mTexture.notNull() && mLayerSet) );  // mutually exclusive
 
 	LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP;
+	LLViewerTexLayerSet *layerset = dynamic_cast<LLViewerTexLayerSet*>(mLayerSet);
 	if (mTestImageName)
 	{
 		gGL.getTexUnit(diffuse_channel)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName);
@@ -558,11 +270,11 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 			gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
 		}
 	}
-	else if( !is_dummy && mLayerSet )
+	else if( !is_dummy && layerset )
 	{
-		if(	mLayerSet->hasComposite() )
+		if(	layerset->hasComposite() )
 		{
-			gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getComposite());
+			gGL.getTexUnit(diffuse_channel)->bind(layerset->getViewerComposite());
 		}
 		else
 		{
diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h
index dd5dae1dc1e997cd330ffcfbf9c6aa03e0eedbdd..0db2836e150b749e8e2c03e1a0fa34340deb1e48 100644
--- a/indra/newview/llviewerjointmesh.h
+++ b/indra/newview/llviewerjointmesh.h
@@ -1,6 +1,6 @@
 /** 
  * @file llviewerjointmesh.h
- * @brief Implementation of LLViewerJointMesh class
+ * @brief Declaration of LLViewerJointMesh class
  *
  * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -29,64 +29,20 @@
 
 #include "llviewerjoint.h"
 #include "llviewertexture.h"
+#include "llavatarjointmesh.h"
 #include "llpolymesh.h"
 #include "v4color.h"
 
 class LLDrawable;
 class LLFace;
 class LLCharacter;
-class LLTexLayerSet;
-
-typedef enum e_avatar_render_pass
-{
-	AVATAR_RENDER_PASS_SINGLE,
-	AVATAR_RENDER_PASS_CLOTHING_INNER,
-	AVATAR_RENDER_PASS_CLOTHING_OUTER
-} EAvatarRenderPass;
-
-class LLSkinJoint
-{
-public:
-	LLSkinJoint();
-	~LLSkinJoint();
-	BOOL setupSkinJoint( LLViewerJoint *joint);
-
-	LLViewerJoint	*mJoint;
-	LLVector3		mRootToJointSkinOffset;
-	LLVector3		mRootToParentJointSkinOffset;
-};
+class LLViewerTexLayerSet;
 
 //-----------------------------------------------------------------------------
 // class LLViewerJointMesh
 //-----------------------------------------------------------------------------
-class LLViewerJointMesh : public LLViewerJoint
+class LLViewerJointMesh : public LLAvatarJointMesh, public LLViewerJoint
 {
-	friend class LLVOAvatar;
-protected:
-	LLColor4					mColor;			// color value
-// 	LLColor4					mSpecular;		// specular color (always white for now)
-	F32							mShiny;			// shiny value
-	LLPointer<LLViewerTexture>	mTexture;		// ptr to a global texture
-	LLTexLayerSet*				mLayerSet;		// ptr to a layer set owned by the avatar
-	U32 						mTestImageName;		// handle to a temporary texture for previewing uploads
-	LLPolyMesh*					mMesh;			// ptr to a global polymesh
-	BOOL						mCullBackFaces;	// true by default
-	LLFace*						mFace;			// ptr to a face w/ AGP copy of mesh
-
-	U32							mFaceIndexCount;
-	BOOL						mIsTransparent;
-
-	U32							mNumSkinJoints;
-	LLSkinJoint*				mSkinJoints;
-	S32							mMeshID;
-
-public:
-	static BOOL					sPipelineRender;
-	//RN: this is here for testing purposes
-	static U32					sClothingMaskImageName;
-	static EAvatarRenderPass	sRenderPass;
-	static LLColor4				sClothingInnerColor;
-
 public:
 	// Constructor
 	LLViewerJointMesh();
@@ -94,67 +50,28 @@ class LLViewerJointMesh : public LLViewerJoint
 	// Destructor
 	virtual ~LLViewerJointMesh();
 
-	// Gets the shape color
-	void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha );
-
-	// Sets the shape color
-	void setColor( F32 red, F32 green, F32 blue, F32 alpha );
-
-	// Sets the shininess
-	void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; };
-
-	// Sets the shape texture
-	void setTexture( LLViewerTexture *texture );
-
-	void setTestTexture( U32 name ) { mTestImageName = name; }
-
-	// Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture)
-	void setLayerSet( LLTexLayerSet* layer_set );
-
-	// Gets the poly mesh
-	LLPolyMesh *getMesh();
-
-	// Sets the poly mesh
-	void setMesh( LLPolyMesh *mesh );
-
-	// Sets up joint matrix data for rendering
-	void setupJoint(LLViewerJoint* current_joint);
-
 	// Render time method to upload batches of joint matrices
 	void uploadJointMatrices();
 
-	// Sets ID for picking
-	void setMeshID( S32 id ) {mMeshID = id;}
-
-	// Gets ID for picking
-	S32 getMeshID() { return mMeshID; }	
-
 	// overloaded from base class
-	/*virtual*/ void drawBone();
-	/*virtual*/ BOOL isTransparent();
 	/*virtual*/ U32 drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy );
 
+	// necessary because MS's compiler warns on function inheritance via dominance in the diamond inheritance here.
+	// warns even though LLViewerJoint holds the only non virtual implementation.
+	/*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ) { return LLViewerJoint::render(pixelArea,first_pass,is_dummy);}
+
 	/*virtual*/ void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
 	/*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
 	/*virtual*/ BOOL updateLOD(F32 pixel_area, BOOL activate);
 	/*virtual*/ void updateJointGeometry();
 	/*virtual*/ void dump();
 
-	void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; }
-
 	/*virtual*/ BOOL isAnimatable() const { return FALSE; }
 	
 private:
 
 	//copy mesh into given face's vertex buffer, applying current animation pose
 	static void updateGeometry(LLFace* face, LLPolyMesh* mesh);
-
-private:
-	// Allocate skin data
-	BOOL allocateSkinData( U32 numSkinJoints );
-
-	// Free skin data
-	void freeSkinData();
 };
 
 #endif // LL_LLVIEWERJOINTMESH_H
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index 4543a1ba9a7933465401f2caf23aaff4762c8651..297906803bdd63846ea181c7b09d73b8ca879b13 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -406,11 +406,9 @@ void LLViewerMediaFocus::update()
 	LLViewerObject *viewer_object = getFocusedObject();
 	S32 face = mFocusedObjectFace;
 	LLVector3 normal = mFocusedObjectNormal;
-	bool focus = true;
 	
 	if(!media_impl || !viewer_object)
 	{
-		focus = false;
 		media_impl = getHoverMediaImpl();
 		viewer_object = getHoverObject();
 		face = mHoverObjectFace;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 66db0ac8f3d8c61648cc89db89cea889cdb8ad6f..beca08203fdd5aa3b85f59c84ad50e27dfdc5fa4 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -125,7 +125,7 @@
 #include "llpathfindingmanager.h"
 #include "boost/unordered_map.hpp"
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 typedef LLPointer<LLViewerObject> LLViewerObjectPtr;
 
@@ -1577,11 +1577,26 @@ class LLAdvancedEnableGrabBakedTexture : public view_listener_t
 ///////////////////////
 
 
+class LLAdvancedEnableAppearanceToXML : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+	}
+};
+
 class LLAdvancedAppearanceToXML : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		LLVOAvatar::dumpArchetypeXML(NULL);
+		std::string emptyname;
+		LLVOAvatar* avatar =
+			find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+		if (!avatar)
+		{
+			avatar = gAgentAvatarp;
+		}
+		avatar->dumpArchetypeXML(emptyname);
 		return true;
 	}
 };
@@ -2827,7 +2842,7 @@ class LLSelfRemoveAllAttachments : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		LLAgentWearables::userRemoveAllAttachments();
+		LLAppearanceMgr::instance().removeAllAttachmentsFromAvatar();
 		return true;
 	}
 };
@@ -6437,23 +6452,21 @@ class LLAttachmentDetachFromPoint : public view_listener_t
 {
 	bool handleEvent(const LLSD& user_data)
 	{
+		uuid_vec_t ids_to_remove;
 		const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL);
 		if (attachment->getNumObjects() > 0)
 		{
-			gMessageSystem->newMessage("ObjectDetach");
-			gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-			gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-			gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			
 			for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator iter = attachment->mAttachedObjects.begin();
 				 iter != attachment->mAttachedObjects.end();
 				 iter++)
 			{
 				LLViewerObject *attached_object = (*iter);
-				gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
-				gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID());
+				ids_to_remove.push_back(attached_object->getAttachmentItemID());
 			}
-			gMessageSystem->sendReliable( gAgent.getRegionHost() );
+		}
+		if (!ids_to_remove.empty())
+		{
+			LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove);
 		}
 		return true;
 	}
@@ -6526,17 +6539,8 @@ class LLAttachmentDetach : public view_listener_t
 			return true;
 		}
 
-		// The sendDetach() method works on the list of selected
-		// objects.  Thus we need to clear the list, make sure it only
-		// contains the object the user clicked, send the message,
-		// then clear the list.
-		// We use deselectAll to update the simulator's notion of what's
-		// selected, and removeAll just to change things locally.
-		//RN: I thought it was more useful to detach everything that was selected
-		if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
-		{
-			LLSelectMgr::getInstance()->sendDetach();
-		}
+		LLAppearanceMgr::instance().removeItemFromAvatar(object->getAttachmentItemID());
+
 		return true;
 	}
 };
@@ -7391,7 +7395,7 @@ void handle_grab_baked_texture(void* data)
 	if(folder_id.notNull())
 	{
 		std::string name;
-		name = "Baked " + LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
+		name = "Baked " + LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
 
 		LLUUID item_id;
 		item_id.generate();
@@ -7650,6 +7654,10 @@ void handle_rebake_textures(void*)
 	// Slam pending upload count to "unstick" things
 	bool slam_for_debug = true;
 	gAgentAvatarp->forceBakeAllTextures(slam_for_debug);
+	if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
+	{
+		LLAppearanceMgr::instance().requestServerAppearanceUpdate();
+	}
 }
 
 void toggle_visibility(void* user_data)
@@ -7932,7 +7940,7 @@ class LLEditTakeOff : public view_listener_t
 	{
 		std::string clothing = userdata.asString();
 		if (clothing == "all")
-			LLWearableBridge::removeAllClothesFromAvatar();
+			LLAppearanceMgr::instance().removeAllClothesFromAvatar();
 		else
 		{
 			LLWearableType::EType type = LLWearableType::typeNameToType(clothing);
@@ -7942,8 +7950,8 @@ class LLEditTakeOff : public view_listener_t
 			{
 				// MULTI-WEARABLES: assuming user wanted to remove top shirt.
 				U32 wearable_index = gAgentWearables.getWearableCount(type) - 1;
-				LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(gAgentWearables.getWearableInventoryItem(type,wearable_index));
-				LLWearableBridge::removeItemFromAvatar(item);
+				LLUUID item_id = gAgentWearables.getWearableItemID(type,wearable_index);
+				LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
 			}
 				
 		}
@@ -8283,8 +8291,6 @@ void initialize_menus()
 
 	view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
 
-
-	commit.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::showAgentInventory));
 	enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed));
 
 	// Agent
@@ -8503,6 +8509,7 @@ void initialize_menus()
 
 	// Advanced > Character > Character Tests
 	view_listener_t::addMenu(new LLAdvancedAppearanceToXML(), "Advanced.AppearanceToXML");
+	view_listener_t::addMenu(new LLAdvancedEnableAppearanceToXML(), "Advanced.EnableAppearanceToXML");
 	view_listener_t::addMenu(new LLAdvancedToggleCharacterGeometry(), "Advanced.ToggleCharacterGeometry");
 
 	view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 01534503f32dbcd1b161033106e4518b884a7237..143420e2274971e814ee97484d0293651ef1be8e 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -138,6 +138,11 @@ bool handle_go_to();
 // Export to XML or Collada
 void handle_export_selected( void * );
 
+// Convert strings to internal types
+U32 render_type_from_string(std::string render_type);
+U32 feature_from_string(std::string feature);
+U32 info_display_from_string(std::string info_display);
+
 class LLViewerMenuHolderGL : public LLMenuHolderGL
 {
 public:
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index a13c793899e56498dd2938f54a346555b676d53a..3c0d6189ac170d30f46646a23ad3565a8023a0d7 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -633,7 +633,6 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain)
 bool join_group_response(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	BOOL delete_context_data = TRUE;
 	bool accept_invite = false;
 
 	LLUUID group_id = notification["payload"]["group_id"].asUUID();
@@ -662,7 +661,6 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
 		}
 		else
 		{
-			delete_context_data = FALSE;
 			LLSD args;
 			args["NAME"] = name;
 			LLNotificationsUtil::add("JoinedTooManyGroupsMember", args, notification["payload"]);
@@ -675,7 +673,6 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
 		// sure the user is sure they want to join.
 		if (fee > 0)
 		{
-			delete_context_data = FALSE;
 			LLSD args;
 			args["COST"] = llformat("%d", fee);
 			// Set the fee for next time to 0, so that we don't keep
@@ -3444,7 +3441,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 	LLColor4	color(1.0f, 1.0f, 1.0f, 1.0f);
 	LLUUID		from_id;
 	LLUUID		owner_id;
-	BOOL		is_owned_by_me = FALSE;
 	LLViewerObject*	chatter;
 
 	msg->getString("ChatData", "FromName", from_name);
@@ -3529,13 +3525,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 				gAgent.heardChat(chat.mFromID);
 			}
 		}
-
-		is_owned_by_me = chatter->permYouOwner();
 	}
 
 	if (is_audible)
 	{
-		BOOL visible_in_chat_bubble = FALSE;
+		//BOOL visible_in_chat_bubble = FALSE;
 
 		color.setVec(1.f,1.f,1.f,1.f);
 		msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg);
@@ -3618,7 +3612,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 			
 			if (!is_muted && !is_do_not_disturb)
 			{
-				visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles");
+				//visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles");
 				std::string formated_msg = "";
 				LLViewerChat::formatChatMsg(chat, formated_msg);
 				LLChat chat_bubble = chat;
@@ -4958,9 +4952,19 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data)
 	// Various hacks that aren't statistics, but are being handled here.
 	//
 	U32 max_tasks_per_region;
-	U32 region_flags;
+	U64 region_flags;
 	msg->getU32("Region", "ObjectCapacity", max_tasks_per_region);
-	msg->getU32("Region", "RegionFlags", region_flags);
+
+	if (msg->has(_PREHASH_RegionInfo))
+	{
+		msg->getU64("RegionInfo", "RegionFlagsExtended", region_flags);
+	}
+	else
+	{
+		U32 flags = 0;
+		msg->getU32("Region", "RegionFlags", flags);
+		region_flags = flags;
+	}
 
 	LLViewerRegion* regionp = gAgent.getRegion();
 	if (regionp)
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index b1a60197a2cbfbc997e2c58edef9953b08e4afd8..fcf5af76ff4c32eb191c8bf1e078f1c18fe852e1 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -3266,14 +3266,14 @@ void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */)
 	S32 tex_count = getNumTEs();
 	for (i = 0; i < tex_count; i++)
 	{
- 		getTEImage(i)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
+ 		getTEImage(i)->setBoostLevel(LLGLTexture::BOOST_SELECTED);
 	}
 
 	if (isSculpted() && !isMesh())
 	{
 		LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
 		LLUUID sculpt_id = sculpt_params->getSculptTexture();
-		LLViewerTextureManager::getFetchedTexture(sculpt_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
+		LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED);
 	}
 	
 	if (boost_children)
@@ -4016,7 +4016,7 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
 //	if (mDrawable.notNull() && mDrawable->isVisible())
 //	{
 		const LLUUID& image_id = getTE(te)->getID();
-		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 //	}
 }
 
@@ -4034,15 +4034,15 @@ void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
 	}
 }
 
-
-S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host)
+S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)
 {
+	const LLUUID& uuid = image->getID();
 	S32 retval = 0;
 	if (uuid != getTE(te)->getID() ||
 		uuid == LLUUID::null)
 	{
 		retval = LLPrimitive::setTETexture(te, uuid);
-		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
+		mTEImages[te] = image;
 		setChanged(TEXTURE);
 		if (mDrawable.notNull())
 		{
@@ -4065,7 +4065,9 @@ void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
 S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
 {
 	// Invalid host == get from the agent's sim
-	return setTETextureCore(te, uuid, LLHost::invalid);
+	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(
+		uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid);
+	return setTETextureCore(te,image);
 }
 
 
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 97cf0a4850c7d236ca546eeeff8a515b670b800d..728d279c39b1282c6e277e5a756ef73680c7b942 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -301,7 +301,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	/*virtual*/	void	setNumTEs(const U8 num_tes);
 	/*virtual*/	void	setTE(const U8 te, const LLTextureEntry &texture_entry);
 	/*virtual*/ S32		setTETexture(const U8 te, const LLUUID &uuid);
-	S32 setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host);
+	S32 				setTETextureCore(const U8 te, LLViewerTexture *image);
 	/*virtual*/ S32		setTEColor(const U8 te, const LLColor3 &color);
 	/*virtual*/ S32		setTEColor(const U8 te, const LLColor4 &color);
 	/*virtual*/ S32		setTEScale(const U8 te, const F32 s, const F32 t);
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 4049e31472c2f2fea39e85eaec26ce4c00c1b412..11d34ad0841a4b48c32b66c1a7cb6b8d8fad6ccb 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -284,7 +284,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 {
 	LLFastTimer t(FTM_PROCESS_OBJECTS);	
 	
-	LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
 	LLViewerObject *objectp;
 	S32			num_objects;
 	U32			local_id;
@@ -303,6 +302,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 	{
 		//llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl;
 		gTerseObjectUpdates += num_objects;
+		/*
 		S32 size;
 		if (mesgsys->getReceiveCompressedSize())
 		{
@@ -312,10 +312,12 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 		{
 			size = mesgsys->getReceiveSize();
 		}
-		//llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+		llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+		*/
 	}
 	else
 	{
+		/*
 		S32 size;
 		if (mesgsys->getReceiveCompressedSize())
 		{
@@ -326,7 +328,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 			size = mesgsys->getReceiveSize();
 		}
 
-		// llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+		llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+		*/
 		gFullObjectUpdates += num_objects;
 	}
 
@@ -688,12 +691,12 @@ class LLObjectCostResponder : public LLCurl::Responder
 		}
 	}
 
-	void error(U32 statusNum, const std::string& reason)
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 	{
 		llwarns
 			<< "Transport error requesting object cost "
-			<< "HTTP status: " << statusNum << ", reason: "
-			<< reason << "." << llendl;
+			<< "[status: " << statusNum << "]: "
+			<< content << llendl;
 
 		// TODO*: Error message to user
 		// For now just clear the request from the pending list
@@ -777,12 +780,12 @@ class LLPhysicsFlagsResponder : public LLCurl::Responder
 		}
 	}
 
-	void error(U32 statusNum, const std::string& reason)
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 	{
 		llwarns
 			<< "Transport error requesting object physics flags "
-			<< "HTTP status: " << statusNum << ", reason: "
-			<< reason << "." << llendl;
+			<< "[status: " << statusNum << "]: "
+			<< content << llendl;
 
 		// TODO*: Error message to user
 		// For now just clear the request from the pending list
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 90fbc41daa8f38477b50ff77981ac8277045eb60..386b2fd4001a4807f086322a7386c5e604430247 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -85,7 +85,6 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
 			}
 
 			// we're in a parcel
-			bool new_parcel = false;
 			S32 parcelid = parcel->getLocalID();						
 
 			LLUUID regionid = gAgent.getRegion()->getRegionID();
@@ -94,7 +93,6 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
 				LL_DEBUGS("Media") << "New parcel, parcel id = " << parcelid << ", region id = " << regionid << LL_ENDL;
 				sMediaParcelLocalID = parcelid;
 				sMediaRegionID = regionid;
-				new_parcel = true;
 			}
 
 			std::string mediaUrl = std::string ( parcel->getMediaURL () );
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 77e382b8c71956ca3c1b35130c30645183a899c4..4cdb568d17de14beabfd8355f6294ee9b77f66fc 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -696,8 +696,8 @@ bool LLViewerParcelMgr::allowAgentScripts(const LLViewerRegion* region, const LL
 	// This mirrors the traditional menu bar parcel icon code, but is not
 	// technically correct.
 	return region
-		&& !(region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
-		&& !(region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
+		&& !region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS)
+		&& !region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
 		&& parcel
 		&& parcel->getAllowOtherScripts();
 }
@@ -2057,7 +2057,7 @@ void LLViewerParcelMgr::startReleaseLand()
 		return;
 	}
 /*
-	if ((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+	if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)
 		&& !gAgent.isGodlike())
 	{
 		LLSD args;
@@ -2302,7 +2302,7 @@ void LLViewerParcelMgr::startDeedLandToGroup()
 	/*
 	if(!gAgent.isGodlike())
 	{
-		if((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+		if(region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)
 			&& (mCurrentParcel->getOwnerID() != region->getOwner()))
 		{
 			LLSD args;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index e4234a538d19c8402ba5d917d0a08d1e17ce4cc9..b8b53aa6e45f9cc83ea75b4d187313a0f170cb3a 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -142,7 +142,8 @@ class LLViewerRegionImpl {
 	LLUUID mCacheID;
 
 	CapabilityMap mCapabilities;
-	
+	CapabilityMap mSecondCapabilitiesTracker; 
+
 	LLEventPoll* mEventPoll;
 
 	S32 mSeedCapMaxAttempts;
@@ -209,9 +210,9 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
 	virtual ~BaseCapabilitiesComplete()
 	{ }
 
-    void error(U32 statusNum, const std::string& reason)
+    void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
     {
-		LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL;
+		LL_WARNS2("AppInit", "Capabilities") << "[status:" << statusNum << ":] " << content << LL_ENDL;
 		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
 		if (regionp)
 		{
@@ -219,7 +220,7 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
 		}
     }
 
-    void result(const LLSD& content)
+   void result(const LLSD& content)
     {
 		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
 		if(!regionp) //region was removed
@@ -237,6 +238,7 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
 		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
 		{
 			regionp->setCapability(iter->first, iter->second);
+			
 			LL_DEBUGS2("AppInit", "Capabilities") << "got capability for " 
 				<< iter->first << LL_ENDL;
 
@@ -265,6 +267,62 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
 	S32 mID;
 };
 
+class BaseCapabilitiesCompleteTracker :  public LLHTTPClient::Responder
+{
+	LOG_CLASS(BaseCapabilitiesCompleteTracker);
+public:
+	BaseCapabilitiesCompleteTracker( U64 region_handle)
+	: mRegionHandle(region_handle)
+	{ }
+	
+	virtual ~BaseCapabilitiesCompleteTracker()
+	{ }
+
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+	{
+		llwarns << "BaseCapabilitiesCompleteTracker error [status:"
+				<< statusNum << "]: " << content << llendl;
+	}
+
+	void result(const LLSD& content)
+	{
+		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+		if( !regionp ) 
+		{
+			return ;
+		}		
+		LLSD::map_const_iterator iter;
+		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
+		{
+			regionp->setCapabilityDebug(iter->first, iter->second);	
+			//llinfos<<"BaseCapabilitiesCompleteTracker New Caps "<<iter->first<<" "<< iter->second<<llendl;
+		}
+		
+		if ( regionp->getRegionImpl()->mCapabilities.size() != regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() )
+		{
+			llinfos<<"BaseCapabilitiesCompleteTracker "<<"Sim sent duplicate seed caps that differs in size - most likely content."<<llendl;			
+			//todo#add cap debug versus original check?
+			/*CapabilityMap::const_iterator iter = regionp->getRegionImpl()->mCapabilities.begin();
+			while (iter!=regionp->getRegionImpl()->mCapabilities.end() )
+			{
+				llinfos<<"BaseCapabilitiesCompleteTracker Original "<<iter->first<<" "<< iter->second<<llendl;
+				++iter;
+			}
+			*/
+			regionp->getRegionImplNC()->mSecondCapabilitiesTracker.clear();
+		}
+
+	}
+
+	static BaseCapabilitiesCompleteTracker* build( U64 region_handle )
+	{
+		return new BaseCapabilitiesCompleteTracker( region_handle );
+	}
+
+private:
+	U64 mRegionHandle;	
+};
+
 
 LLViewerRegion::LLViewerRegion(const U64 &handle,
 							   const LLHost &host,
@@ -278,9 +336,11 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	mZoning(""),
 	mIsEstateManager(FALSE),
 	mRegionFlags( REGION_FLAGS_DEFAULT ),
+	mRegionProtocols( 0 ),
 	mSimAccess( SIM_ACCESS_MIN ),
 	mBillableFactor(1.0),
 	mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
+	mCentralBakeVersion(0),
 	mClassID(0),
 	mCPURatio(0),
 	mColoName("unknown"),
@@ -453,18 +513,6 @@ void LLViewerRegion::sendReliableMessage()
 	gMessageSystem->sendReliable(mImpl->mHost);
 }
 
-void LLViewerRegion::setFlags(BOOL b, U32 flags)
-{
-	if (b)
-	{
-		mRegionFlags |=  flags;
-	}
-	else
-	{
-		mRegionFlags &= ~flags;
-	}
-}
-
 void LLViewerRegion::setWaterHeight(F32 water_level)
 {
 	mImpl->mLandp->setWaterHeight(water_level);
@@ -477,10 +525,10 @@ F32 LLViewerRegion::getWaterHeight() const
 
 BOOL LLViewerRegion::isVoiceEnabled() const
 {
-	return (getRegionFlags() & REGION_FLAGS_ALLOW_VOICE);
+	return getRegionFlag(REGION_FLAGS_ALLOW_VOICE);
 }
 
-void LLViewerRegion::setRegionFlags(U32 flags)
+void LLViewerRegion::setRegionFlags(U64 flags)
 {
 	mRegionFlags = flags;
 }
@@ -573,7 +621,7 @@ std::string LLViewerRegion::getLocalizedSimProductName() const
 }
 
 // static
-std::string LLViewerRegion::regionFlagsToString(U32 flags)
+std::string LLViewerRegion::regionFlagsToString(U64 flags)
 {
 	std::string result;
 
@@ -1388,7 +1436,8 @@ void LLViewerRegion::unpackRegionHandshake()
 {
 	LLMessageSystem *msg = gMessageSystem;
 
-	U32 region_flags;
+	U64 region_flags = 0;
+	U64 region_protocols = 0;
 	U8 sim_access;
 	std::string sim_name;
 	LLUUID sim_owner;
@@ -1397,7 +1446,6 @@ void LLViewerRegion::unpackRegionHandshake()
 	F32 billable_factor;
 	LLUUID cache_id;
 
-	msg->getU32		("RegionInfo", "RegionFlags", region_flags);
 	msg->getU8		("RegionInfo", "SimAccess", sim_access);
 	msg->getString	("RegionInfo", "SimName", sim_name);
 	msg->getUUID	("RegionInfo", "SimOwner", sim_owner);
@@ -1406,7 +1454,20 @@ void LLViewerRegion::unpackRegionHandshake()
 	msg->getF32		("RegionInfo", "BillableFactor", billable_factor);
 	msg->getUUID	("RegionInfo", "CacheID", cache_id );
 
+	if (msg->has(_PREHASH_RegionInfo4))
+	{
+		msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionFlagsExtended, region_flags);
+		msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionProtocols, region_protocols);
+	}
+	else
+	{
+		U32 flags = 0;
+		msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
+		region_flags = flags;
+	}
+
 	setRegionFlags(region_flags);
+	setRegionProtocols(region_protocols);
 	setSimAccess(sim_access);
 	setRegionNameAndZone(sim_name);
 	setOwner(sim_owner);
@@ -1445,6 +1506,8 @@ void LLViewerRegion::unpackRegionHandshake()
 		mProductName = productName;
 	}
 
+
+	mCentralBakeVersion = region_protocols & 1; // was (S32)gSavedSettings.getBOOL("UseServerTextureBaking");
 	LLVLComposition *compp = getComposition();
 	if (compp)
 	{
@@ -1524,11 +1587,12 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("EventQueueGet");
 
 	if (gSavedSettings.getBOOL("UseHTTPInventory"))
-	{
+	{	
 		capabilityNames.append("FetchLib2");
 		capabilityNames.append("FetchLibDescendents2");
 		capabilityNames.append("FetchInventory2");
 		capabilityNames.append("FetchInventoryDescendents2");
+		capabilityNames.append("IncrementCOFVersion");
 	}
 
 	capabilityNames.append("GetDisplayNames");
@@ -1542,7 +1606,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("LandResources");
 	capabilityNames.append("MapLayer");
 	capabilityNames.append("MapLayerGod");
-	capabilityNames.append("MeshUploadFlag");
+	capabilityNames.append("MeshUploadFlag");	
 	capabilityNames.append("NavMeshGenerationStatus");
 	capabilityNames.append("NewFileAgentInventory");
 	capabilityNames.append("ObjectMedia");
@@ -1571,6 +1635,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("UntrustedSimulatorMessage");
 	capabilityNames.append("UpdateAgentInformation");
 	capabilityNames.append("UpdateAgentLanguage");
+	capabilityNames.append("UpdateAvatarAppearance");
 	capabilityNames.append("UpdateGestureAgentInventory");
 	capabilityNames.append("UpdateGestureTaskInventory");
 	capabilityNames.append("UpdateNotecardAgentInventory");
@@ -1581,7 +1646,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("ViewerMetrics");
 	capabilityNames.append("ViewerStartAuction");
 	capabilityNames.append("ViewerStats");
-	
+
 	// Please add new capabilities alphabetically to reduce
 	// merge conflicts.
 }
@@ -1589,8 +1654,14 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 void LLViewerRegion::setSeedCapability(const std::string& url)
 {
 	if (getCapability("Seed") == url)
-    {
-		// llwarns << "Ignoring duplicate seed capability" << llendl;
+    {	
+		//llwarns << "Ignoring duplicate seed capability" << llendl;
+		//Instead of just returning we build up a second set of seed caps and compare them 
+		//to the "original" seed cap received and determine why there is problem!
+		LLSD capabilityNames = LLSD::emptyArray();
+		mImpl->buildCapabilityNames( capabilityNames );
+		LLHTTPClient::post( url, capabilityNames, BaseCapabilitiesCompleteTracker::build(getHandle() ),
+							LLSD(), CAP_REQUEST_TIMEOUT );
 		return;
     }
 	
@@ -1663,9 +1734,9 @@ class SimulatorFeaturesReceived : public LLHTTPClient::Responder
     { }
 	
 	
-    void error(U32 statusNum, const std::string& reason)
+    void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
     {
-		LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL;
+		LL_WARNS2("AppInit", "SimulatorFeatures") << "[status:" << statusNum << "]: " << content << LL_ENDL;
 		retry();
     }
 
@@ -1726,6 +1797,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u
 	}
 }
 
+void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::string& url)
+{
+	mImpl->mSecondCapabilitiesTracker[name] = url;
+}
+
 bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
 {
 	return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
@@ -1733,6 +1809,11 @@ bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
 
 std::string LLViewerRegion::getCapability(const std::string& name) const
 {
+	if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia")))
+	{
+		llwarns << "getCapability called before caps received" << llendl;
+	}
+	
 	CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
 	if(iter == mImpl->mCapabilities.end())
 	{
@@ -1792,7 +1873,7 @@ LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
 
 // the viewer can not yet distinquish between normal- and estate-owned objects
 // so we collapse these two bits and enable the UI if either are set
-const U32 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
+const U64 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
 											| REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT;
 
 bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const
@@ -1800,7 +1881,7 @@ bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<
 	return (mParcelOverlay != NULL)
 		&& (mParcelOverlay->isOwnedSelf(pos)
 			|| mParcelOverlay->isOwnedGroup(pos)
-			|| ((mRegionFlags & ALLOW_RETURN_ENCROACHING_OBJECT)
+			|| (getRegionFlag(ALLOW_RETURN_ENCROACHING_OBJECT)
 				&& mParcelOverlay->encroachesOwned(boxes)) );
 }
 
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index c9fffaf30e4abff15de3dbc7f31bddf8bef0cbbe..b5fe4677b76111471b3d870ad068e5ea88359e67 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -109,13 +109,13 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	//void setAgentOffset(const LLVector3d &offset);
 	void updateRenderMatrix();
 
-	void setAllowDamage(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_DAMAGE); }
-	void setAllowLandmark(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_LANDMARK); }
-	void setAllowSetHome(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_SET_HOME); }
-	void setResetHomeOnTeleport(BOOL b) { setFlags(b, REGION_FLAGS_RESET_HOME_ON_TELEPORT); }
-	void setSunFixed(BOOL b) { setFlags(b, REGION_FLAGS_SUN_FIXED); }
-	void setBlockFly(BOOL b) { setFlags(b, REGION_FLAGS_BLOCK_FLY); }
-	void setAllowDirectTeleport(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_DIRECT_TELEPORT); }
+	void setAllowDamage(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DAMAGE, b); }
+	void setAllowLandmark(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_LANDMARK, b); }
+	void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); }
+	void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); }
+	void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); }
+	void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); }
+	void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); }
 
 
 	inline BOOL getAllowDamage()			const;
@@ -156,8 +156,15 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	LLViewerParcelOverlay *getParcelOverlay() const
 			{ return mParcelOverlay; }
 
-	void setRegionFlags(U32 flags);
-	U32 getRegionFlags() const					{ return mRegionFlags; }
+	inline void setRegionFlag(U64 flag, BOOL on);
+	inline BOOL getRegionFlag(U64 flag) const;
+	void setRegionFlags(U64 flags);
+	U64 getRegionFlags() const					{ return mRegionFlags; }
+
+	inline void setRegionProtocol(U64 protocol, BOOL on);
+	BOOL getRegionProtocol(U64 protocol) const;
+	void setRegionProtocols(U64 protocols)			{ mRegionProtocols = protocols; }
+	U64 getRegionProtocols() const					{ return mRegionProtocols; }
 
 	void setTimeDilation(F32 time_dilation);
 	F32  getTimeDilation() const				{ return mTimeDilation; }
@@ -195,7 +202,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	std::string getLocalizedSimProductName() const;
 
 	// Returns "Sandbox", "Expensive", etc.
-	static std::string regionFlagsToString(U32 flags);
+	static std::string regionFlagsToString(U64 flags);
 
 	// Returns translated version of "Mature", "PG", "Adult", etc.
 	static std::string accessToString(U8 sim_access);
@@ -234,6 +241,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	void failedSeedCapability();
 	S32 getNumSeedCapRetries();
 	void setCapability(const std::string& name, const std::string& url);
+	void setCapabilityDebug(const std::string& name, const std::string& url);
 	// implements LLCapabilityProvider
     virtual std::string getCapability(const std::string& name) const;
 
@@ -278,6 +286,8 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 
 	F32 getLandHeightRegion(const LLVector3& region_pos);
 
+	U8 getCentralBakeVersion() { return mCentralBakeVersion; }
+
 	void getInfo(LLSD& info);
 	
 	bool meshRezEnabled() const;
@@ -330,7 +340,9 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 
 	void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
 	void getNeighboringRegionsStatus( std::vector<S32>& regions );
-	
+	const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }
+	LLViewerRegionImpl * getRegionImplNC() { return mImpl; }
+
 public:
 	struct CompareDistance
 	{
@@ -345,7 +357,6 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 protected:
 	void disconnectAllNeighbors();
 	void initStats();
-	void setFlags(BOOL b, U32 flags);
 
 public:
 	LLWind  mWind;
@@ -390,11 +401,13 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	U32		mPingDelay;
 	F32		mDeltaTime;				// Time since last measurement of lastPackets, Bits, etc
 
-	U32		mRegionFlags;			// includes damage flags
+	U64		mRegionFlags;			// includes damage flags
+	U64		mRegionProtocols;		// protocols supported by this region
 	U8		mSimAccess;
 	F32 	mBillableFactor;
 	U32		mMaxTasks;				// max prim count
 	F32		mCameraDistanceSquared;	// updated once per frame
+	U8		mCentralBakeVersion;
 	
 	// Information for Homestead / CR-53
 	S32 mClassID;
@@ -423,6 +436,40 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	LLSD mSimulatorFeatures;
 };
 
+inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const
+{
+	return ((mRegionProtocols & protocol) != 0);
+}
+
+inline void LLViewerRegion::setRegionProtocol(U64 protocol, BOOL on)
+{
+	if (on)
+	{
+		mRegionProtocols |= protocol;
+	}
+	else
+	{
+		mRegionProtocols &= ~protocol;
+	}
+}
+
+inline BOOL LLViewerRegion::getRegionFlag(U64 flag) const
+{
+	return ((mRegionFlags & flag) != 0);
+}
+
+inline void LLViewerRegion::setRegionFlag(U64 flag, BOOL on)
+{
+	if (on)
+	{
+		mRegionFlags |= flag;
+	}
+	else
+	{
+		mRegionFlags &= ~flag;
+	}
+}
+
 inline BOOL LLViewerRegion::getAllowDamage() const
 {
 	return ((mRegionFlags & REGION_FLAGS_ALLOW_DAMAGE) !=0);
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index d6dd645e8cc483473a986febaf52dc00be10a24a..e3d28f2f5c21f42d51f641274e62d211e96a624d 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -229,7 +229,6 @@ extern LLGLSLShader			gSplatTextureRectProgram;
 extern LLGLSLShader			gGlowCombineFXAAProgram;
 extern LLGLSLShader			gDebugProgram;
 extern LLGLSLShader			gClipProgram;
-extern LLGLSLShader			gAlphaMaskProgram;
 
 //output tex0[tc0] + tex1[tc1]
 extern LLGLSLShader			gTwoTextureAddProgram;
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 35839ae45912ef4c693ae3bd9bfd2fc5cda049f8..35bba4184e63f342776ebe6f2d244d265626e44f 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -752,25 +752,6 @@ void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name)
 	timer.unpause();
 }
 
-void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name)
-{
-	phase_map_t::iterator iter = mPhaseMap.find(phase_name);
-	if (iter != mPhaseMap.end())
-	{
-		if (iter->second.getStarted())
-		{
-			// Going from started to paused state - record stats.
-			recordPhaseStat(phase_name,iter->second.getElapsedTimeF32());
-		}
-		lldebugs << "stopPhase " << phase_name << llendl;
-		iter->second.pause();
-	}
-	else
-	{
-		lldebugs << "stopPhase " << phase_name << " is not started, no-op" << llendl;
-	}
-}
-
 void LLViewerStats::PhaseMap::stopAllPhases()
 {
 	for (phase_map_t::iterator iter = mPhaseMap.begin();
@@ -814,6 +795,19 @@ LLViewerStats::PhaseMap::PhaseMap()
 {
 }
 
+
+void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name)
+{
+	phase_map_t::iterator iter = mPhaseMap.find(phase_name);
+	if (iter != mPhaseMap.end())
+	{
+		if (iter->second.getStarted())
+		{
+			// Going from started to stopped state - record stats.
+			iter->second.stop();
+		}
+	}
+}
 // static
 LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)
 {
@@ -833,3 +827,18 @@ void LLViewerStats::PhaseMap::recordPhaseStat(const std::string& phase_name, F32
 	stats.push(value);
 }
 
+
+bool LLViewerStats::PhaseMap::getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed)
+{
+	phase_map_t::iterator iter = mPhaseMap.find(phase_name);
+	if (iter != mPhaseMap.end())
+	{
+		elapsed =  iter->second.getElapsedTimeF32();
+		completed = !iter->second.getStarted();
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index e02a4ccdc70756bc1a913509ebabd228ed77796a..6b2461be41fb51fd9eca307590412fa09de80ad2 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -289,6 +289,7 @@ class LLViewerStats : public LLSingleton<LLViewerStats>
 	public:
 		PhaseMap();
 		LLFrameTimer& 	getPhaseTimer(const std::string& phase_name);
+		bool 			getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed);
 		void			startPhase(const std::string& phase_name);
 		void			stopPhase(const std::string& phase_name);
 		void			stopAllPhases();
@@ -296,8 +297,11 @@ class LLViewerStats : public LLSingleton<LLViewerStats>
 		LLSD			dumpPhases();
 		static StatsAccumulator& getPhaseStats(const std::string& phase_name);
 		static void recordPhaseStat(const std::string& phase_name, F32 value);
+		phase_map_t::iterator begin() { return mPhaseMap.begin(); }
+		phase_map_t::iterator end() { return mPhaseMap.end(); }
 	};
 
+
 private:
 	F64	mStats[ST_COUNT];
 
diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..777e1f9c76a6d6e7240b6b18cd0d09b1466bb086
--- /dev/null
+++ b/indra/newview/llviewertexlayer.cpp
@@ -0,0 +1,748 @@
+/** 
+ * @file llviewertexlayer.cpp
+ * @brief Viewer texture layer. Used for avatars.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewertexlayer.h"
+
+#include "llagent.h"
+#include "llimagej2c.h"
+#include "llnotificationsutil.h"
+#include "llvfile.h"
+#include "llvfs.h"
+#include "llviewerregion.h"
+#include "llglslshader.h"
+#include "llvoavatarself.h"
+#include "pipeline.h"
+#include "llassetuploadresponders.h"
+#include "llviewercontrol.h"
+
+static const S32 BAKE_UPLOAD_ATTEMPTS = 7;
+static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt
+
+// runway consolidate
+extern std::string self_av_string();
+
+
+//-----------------------------------------------------------------------------
+// LLBakedUploadData()
+//-----------------------------------------------------------------------------
+LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar,
+									 LLViewerTexLayerSet* layerset,
+									 const LLUUID& id,
+									 bool highest_res) :
+	mAvatar(avatar),
+	mTexLayerSet(layerset),
+	mID(id),
+	mStartTime(LLFrameTimer::getTotalTime()),		// Record starting time
+	mIsHighestRes(highest_res)
+{ 
+}
+
+//-----------------------------------------------------------------------------
+// LLViewerTexLayerSetBuffer
+// The composite image that a LLViewerTexLayerSet writes to.  Each LLViewerTexLayerSet has one.
+//-----------------------------------------------------------------------------
+
+// static
+S32 LLViewerTexLayerSetBuffer::sGLByteCount = 0;
+
+LLViewerTexLayerSetBuffer::LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, 
+										 S32 width, S32 height) :
+	// ORDER_LAST => must render these after the hints are created.
+	LLTexLayerSetBuffer(owner),
+	LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), 
+	mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
+	mNeedsUpload(FALSE),
+	mNumLowresUploads(0),
+	mUploadFailCount(0),
+	mNeedsUpdate(TRUE),
+	mNumLowresUpdates(0)
+{
+	LLViewerTexLayerSetBuffer::sGLByteCount += getSize();
+	mNeedsUploadTimer.start();
+	mNeedsUpdateTimer.start();
+}
+
+LLViewerTexLayerSetBuffer::~LLViewerTexLayerSetBuffer()
+{
+	LLViewerTexLayerSetBuffer::sGLByteCount -= getSize();
+	destroyGLTexture();
+	for( S32 order = 0; order < ORDER_COUNT; order++ )
+	{
+		LLViewerDynamicTexture::sInstances[order].erase(this);  // will fail in all but one case.
+	}
+}
+
+//virtual 
+S8 LLViewerTexLayerSetBuffer::getType() const 
+{
+	return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ;
+}
+
+//virtual 
+void LLViewerTexLayerSetBuffer::restoreGLTexture() 
+{	
+	LLViewerDynamicTexture::restoreGLTexture() ;
+}
+
+//virtual 
+void LLViewerTexLayerSetBuffer::destroyGLTexture() 
+{
+	LLViewerDynamicTexture::destroyGLTexture() ;
+}
+
+// static
+void LLViewerTexLayerSetBuffer::dumpTotalByteCount()
+{
+	llinfos << "Composite System GL Buffers: " << (LLViewerTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl;
+}
+
+void LLViewerTexLayerSetBuffer::requestUpdate()
+{
+	restartUpdateTimer();
+	mNeedsUpdate = TRUE;
+	mNumLowresUpdates = 0;
+	// If we're in the middle of uploading a baked texture, we don't care about it any more.
+	// When it's downloaded, ignore it.
+	mUploadID.setNull();
+}
+
+void LLViewerTexLayerSetBuffer::requestUpload()
+{
+	conditionalRestartUploadTimer();
+	mNeedsUpload = TRUE;
+	mNumLowresUploads = 0;
+	mUploadPending = TRUE;
+}
+
+void LLViewerTexLayerSetBuffer::conditionalRestartUploadTimer()
+{
+	// If we requested a new upload but haven't even uploaded
+	// a low res version of our last upload request, then
+	// keep the timer ticking instead of resetting it.
+	if (mNeedsUpload && (mNumLowresUploads == 0))
+	{
+		mNeedsUploadTimer.unpause();
+	}
+	else
+	{
+		mNeedsUploadTimer.reset();
+		mNeedsUploadTimer.start();
+	}
+}
+
+void LLViewerTexLayerSetBuffer::restartUpdateTimer()
+{
+	mNeedsUpdateTimer.reset();
+	mNeedsUpdateTimer.start();
+}
+
+void LLViewerTexLayerSetBuffer::cancelUpload()
+{
+	mNeedsUpload = FALSE;
+	mUploadPending = FALSE;
+	mNeedsUploadTimer.pause();
+	mUploadRetryTimer.reset();
+}
+
+// virtual
+BOOL LLViewerTexLayerSetBuffer::needsRender()
+{
+	llassert(mTexLayerSet->getAvatarAppearance() == gAgentAvatarp);
+	if (!isAgentAvatarValid()) return FALSE;
+
+	const BOOL upload_now = mNeedsUpload && isReadyToUpload();
+	const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
+
+	// Don't render if we don't want to (or aren't ready to) upload or update.
+	if (!(update_now || upload_now))
+	{
+		return FALSE;
+	}
+
+	// Don't render if we're animating our appearance.
+	if (gAgentAvatarp->getIsAppearanceAnimating())
+	{
+		return FALSE;
+	}
+
+	// Don't render if we are trying to create a shirt texture but aren't wearing a skirt.
+	if (gAgentAvatarp->getBakedTE(getViewerTexLayerSet()) == LLAvatarAppearanceDefines::TEX_SKIRT_BAKED && 
+		!gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
+	{
+		cancelUpload();
+		return FALSE;
+	}
+
+	// Render if we have at least minimal level of detail for each local texture.
+	return getViewerTexLayerSet()->isLocalTextureDataAvailable();
+}
+
+// virtual
+void LLViewerTexLayerSetBuffer::preRenderTexLayerSet()
+{
+	LLTexLayerSetBuffer::preRenderTexLayerSet();
+	
+	// keep depth buffer, we don't need to clear it
+	LLViewerDynamicTexture::preRender(FALSE);
+}
+
+// virtual
+void LLViewerTexLayerSetBuffer::postRenderTexLayerSet(BOOL success)
+{
+
+	LLTexLayerSetBuffer::postRenderTexLayerSet(success);
+	LLViewerDynamicTexture::postRender(success);
+}
+
+// virtual
+void LLViewerTexLayerSetBuffer::midRenderTexLayerSet(BOOL success)
+{
+	// do we need to upload, and do we have sufficient data to create an uploadable composite?
+	// TODO: When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
+	const BOOL upload_now = mNeedsUpload && isReadyToUpload();
+	const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
+
+	if(upload_now)
+	{
+		if (!success)
+		{
+			llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegionName() << llendl;
+			mUploadPending = FALSE;
+		}
+		else
+		{
+			LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+			if (layer_set->isVisible())
+			{
+				layer_set->getAvatar()->debugBakedTextureUpload(layer_set->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish.
+				doUpload();
+			}
+			else
+			{
+				mUploadPending = FALSE;
+				mNeedsUpload = FALSE;
+				mNeedsUploadTimer.pause();
+				layer_set->getAvatar()->setNewBakedTexture(layer_set->getBakedTexIndex(),IMG_INVISIBLE);
+			}
+		}
+	}
+	
+	if (update_now)
+	{
+		doUpdate();
+	}
+
+	// *TODO: Old logic does not check success before setGLTextureCreated
+	// we have valid texture data now
+	mGLTexturep->setGLTextureCreated(true);
+}
+
+BOOL LLViewerTexLayerSetBuffer::isInitialized(void) const
+{
+	return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
+}
+
+BOOL LLViewerTexLayerSetBuffer::uploadPending() const
+{
+	return mUploadPending;
+}
+
+BOOL LLViewerTexLayerSetBuffer::uploadNeeded() const
+{
+	return mNeedsUpload;
+}
+
+BOOL LLViewerTexLayerSetBuffer::uploadInProgress() const
+{
+	return !mUploadID.isNull();
+}
+
+BOOL LLViewerTexLayerSetBuffer::isReadyToUpload() const
+{
+	if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries.
+	if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance()) return FALSE; // Don't upload if avatar is being edited.
+
+	BOOL ready = FALSE;
+	if (getViewerTexLayerSet()->isLocalTextureDataFinal())
+	{
+		// If we requested an upload and have the final LOD ready, upload (or wait a while if this is a retry)
+		if (mUploadFailCount == 0)
+		{
+			ready = TRUE;
+		}
+		else
+		{
+			ready = mUploadRetryTimer.getElapsedTimeF32() >= BAKE_UPLOAD_RETRY_DELAY * (1 << (mUploadFailCount - 1));
+		}
+	}
+	else
+	{
+		// Upload if we've hit a timeout.  Upload is a pretty expensive process so we need to make sure
+		// we aren't doing uploads too frequently.
+		const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout");
+		if (texture_timeout != 0)
+		{
+			// The timeout period increases exponentially between every lowres upload in order to prevent
+			// spamming the server with frequent uploads.
+			const U32 texture_timeout_threshold = texture_timeout*(1 << mNumLowresUploads);
+
+			// If we hit our timeout and have textures available at even lower resolution, then upload.
+			const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout_threshold;
+			const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable();
+			ready = has_lower_lod && is_upload_textures_timeout;
+		}
+	}
+
+	return ready;
+}
+
+BOOL LLViewerTexLayerSetBuffer::isReadyToUpdate() const
+{
+	// If we requested an update and have the final LOD ready, then update.
+	if (getViewerTexLayerSet()->isLocalTextureDataFinal()) return TRUE;
+
+	// If we haven't done an update yet, then just do one now regardless of state of textures.
+	if (mNumLowresUpdates == 0) return TRUE;
+
+	// Update if we've hit a timeout.  Unlike for uploads, we can make this timeout fairly small
+	// since render unnecessarily doesn't cost much.
+	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout");
+	if (texture_timeout != 0)
+	{
+		// If we hit our timeout and have textures available at even lower resolution, then update.
+		const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout;
+		const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable();
+		if (has_lower_lod && is_update_textures_timeout) return TRUE; 
+	}
+
+	return FALSE;
+}
+
+BOOL LLViewerTexLayerSetBuffer::requestUpdateImmediate()
+{
+	mNeedsUpdate = TRUE;
+	BOOL result = FALSE;
+
+	if (needsRender())
+	{
+		preRender(FALSE);
+		result = render();
+		postRender(result);
+	}
+
+	return result;
+}
+
+// Create the baked texture, send it out to the server, then wait for it to come
+// back so we can switch to using it.
+void LLViewerTexLayerSetBuffer::doUpload()
+{
+	LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+	LL_DEBUGS("Avatar") << "Uploading baked " << layer_set->getBodyRegionName() << llendl;
+	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
+
+	// Don't need caches since we're baked now.  (note: we won't *really* be baked 
+	// until this image is sent to the server and the Avatar Appearance message is received.)
+	layer_set->deleteCaches();
+
+	// Get the COLOR information from our texture
+	U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ];
+	glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
+	stop_glerror();
+
+	// Get the MASK information from our texture
+	LLGLSUIDefault gls_ui;
+	LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 );
+	U8* baked_mask_data = baked_mask_image->getData(); 
+	layer_set->gatherMorphMaskAlpha(baked_mask_data,
+									mOrigin.mX, mOrigin.mY,
+									mFullWidth, mFullHeight);
+
+
+	// Create the baked image from our color and mask information
+	const S32 baked_image_components = 5; // red green blue [bump] clothing
+	LLPointer<LLImageRaw> baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components );
+	U8* baked_image_data = baked_image->getData();
+	S32 i = 0;
+	for (S32 u=0; u < mFullWidth; u++)
+	{
+		for (S32 v=0; v < mFullHeight; v++)
+		{
+			baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
+			baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
+			baked_image_data[5*i + 2] = baked_color_data[4*i + 2];
+			baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes.
+			baked_image_data[5*i + 4] = baked_mask_data[i];
+			i++;
+		}
+	}
+	
+	LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C;
+	const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)
+	if (compressedImage->encode(baked_image, comment_text))
+	{
+		LLTransactionID tid;
+		tid.generate();
+		const LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+		if (LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(),
+							   gVFS, asset_id, LLAssetType::AT_TEXTURE))
+		{
+			// Read back the file and validate.
+			BOOL valid = FALSE;
+			LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
+			S32 file_size = 0;
+			LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE);
+			file_size = file.getSize();
+			U8* data = integrity_test->allocateData(file_size);
+			file.read(data, file_size);
+			if (data)
+			{
+				valid = integrity_test->validate(data, file_size); // integrity_test will delete 'data'
+			}
+			else
+			{
+				integrity_test->setLastError("Unable to read entire file");
+			}
+			
+			if (valid)
+			{
+				const bool highest_lod = layer_set->isLocalTextureDataFinal();
+				// Baked_upload_data is owned by the responder and deleted after the request completes.
+				LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, 
+																			 layer_set, 
+																			 asset_id,
+																			 highest_lod);
+				// upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.
+				mUploadID = asset_id;
+
+				// Upload the image
+				const std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture");
+				if(!url.empty()
+					&& !LLPipeline::sForceOldBakedUpload // toggle debug setting UploadBakedTexOld to change between the new caps method and old method
+					&& (mUploadFailCount < (BAKE_UPLOAD_ATTEMPTS - 1))) // Try last ditch attempt via asset store if cap upload is failing.
+				{
+					LLSD body = LLSD::emptyMap();
+					// The responder will call LLViewerTexLayerSetBuffer::onTextureUploadComplete()
+					LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data));
+					llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl;
+				} 
+				else
+				{
+					gAssetStorage->storeAssetData(tid,
+												  LLAssetType::AT_TEXTURE,
+												  LLViewerTexLayerSetBuffer::onTextureUploadComplete,
+												  baked_upload_data,
+												  TRUE,		// temp_file
+												  TRUE,		// is_priority
+												  TRUE);	// store_local
+					llinfos << "Baked texture upload via Asset Store." <<  llendl;
+				}
+
+				if (highest_lod)
+				{
+					// Sending the final LOD for the baked texture.  All done, pause 
+					// the upload timer so we know how long it took.
+					mNeedsUpload = FALSE;
+					mNeedsUploadTimer.pause();
+				}
+				else
+				{
+					// Sending a lower level LOD for the baked texture.  Restart the upload timer.
+					mNumLowresUploads++;
+					mNeedsUploadTimer.unpause();
+					mNeedsUploadTimer.reset();
+				}
+
+				// Print out notification that we uploaded this texture.
+				if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+				{
+					const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
+					LLSD args;
+					args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32());
+					args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32());
+					args["BODYREGION"] = layer_set->getBodyRegionName();
+					args["RESOLUTION"] = lod_str;
+					LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args);
+					LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
+				}
+			}
+			else
+			{
+				// The read back and validate operation failed.  Remove the uploaded file.
+				mUploadPending = FALSE;
+				LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE, LLVFile::WRITE);
+				file.remove();
+				llinfos << "Unable to create baked upload file (reason: corrupted)." << llendl;
+			}
+		}
+	}
+	else
+	{
+		// The VFS write file operation failed.
+		mUploadPending = FALSE;
+		llinfos << "Unable to create baked upload file (reason: failed to write file)" << llendl;
+	}
+
+	delete [] baked_color_data;
+}
+
+// Mostly bookkeeping; don't need to actually "do" anything since
+// render() will actually do the update.
+void LLViewerTexLayerSetBuffer::doUpdate()
+{
+	LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+	const BOOL highest_lod = layer_set->isLocalTextureDataFinal();
+	if (highest_lod)
+	{
+		mNeedsUpdate = FALSE;
+	}
+	else
+	{
+		mNumLowresUpdates++;
+	}
+
+	restartUpdateTimer();
+
+	// need to switch to using this layerset if this is the first update
+	// after getting the lowest LOD
+	layer_set->getAvatar()->updateMeshTextures();
+	
+	// Print out notification that we updated this texture.
+	if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+	{
+		const BOOL highest_lod = layer_set->isLocalTextureDataFinal();
+		const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
+		LLSD args;
+		args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32());
+		args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32());
+		args["BODYREGION"] = layer_set->getBodyRegionName();
+		args["RESOLUTION"] = lod_str;
+		LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args);
+		LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
+	}
+}
+
+// static
+void LLViewerTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
+												  void* userdata,
+												  S32 result,
+												  LLExtStat ext_status) // StoreAssetData callback (not fixed)
+{
+	LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata;
+
+	if (isAgentAvatarValid() &&
+		!gAgentAvatarp->isDead() &&
+		(baked_upload_data->mAvatar == gAgentAvatarp) && // Sanity check: only the user's avatar should be uploading textures.
+		(baked_upload_data->mTexLayerSet->hasComposite()))
+	{
+		LLViewerTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getViewerComposite();
+		S32 failures = layerset_buffer->mUploadFailCount;
+		layerset_buffer->mUploadFailCount = 0;
+
+		if (layerset_buffer->mUploadID.isNull())
+		{
+			// The upload got canceled, we should be in the
+			// process of baking a new texture so request an
+			// upload with the new data
+
+			// BAP: does this really belong in this callback, as
+			// opposed to where the cancellation takes place?
+			// suspect this does nothing.
+			layerset_buffer->requestUpload();
+		}
+		else if (baked_upload_data->mID == layerset_buffer->mUploadID)
+		{
+			// This is the upload we're currently waiting for.
+			layerset_buffer->mUploadID.setNull();
+			const std::string name(baked_upload_data->mTexLayerSet->getBodyRegionName());
+			const std::string resolution = baked_upload_data->mIsHighestRes ? " full res " : " low res ";
+			if (result >= 0)
+			{
+				layerset_buffer->mUploadPending = FALSE; // Allows sending of AgentSetAppearance later
+				LLAvatarAppearanceDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->getViewerTexLayerSet());
+				// Update baked texture info with the new UUID
+				U64 now = LLFrameTimer::getTotalTime();		// Record starting time
+				llinfos << "Baked" << resolution << "texture upload for " << name << " took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl;
+				gAgentAvatarp->setNewBakedTexture(baked_te, uuid);
+			}
+			else
+			{	
+				++failures;
+				S32 max_attempts = baked_upload_data->mIsHighestRes ? BAKE_UPLOAD_ATTEMPTS : 1; // only retry final bakes
+				llwarns << "Baked" << resolution << "texture upload for " << name << " failed (attempt " << failures << "/" << max_attempts << ")" << llendl;
+				if (failures < max_attempts)
+				{
+					layerset_buffer->mUploadFailCount = failures;
+					layerset_buffer->mUploadRetryTimer.start();
+					layerset_buffer->requestUpload();
+				}
+			}
+		}
+		else
+		{
+			llinfos << "Received baked texture out of date, ignored." << llendl;
+		}
+
+		gAgentAvatarp->dirtyMesh();
+	}
+	else
+	{
+		// Baked texture failed to upload (in which case since we
+		// didn't set the new baked texture, it means that they'll try
+		// and rebake it at some point in the future (after login?)),
+		// or this response to upload is out of date, in which case a
+		// current response should be on the way or already processed.
+		llwarns << "Baked upload failed" << llendl;
+	}
+
+	delete baked_upload_data;
+}
+
+//-----------------------------------------------------------------------------
+// LLViewerTexLayerSet
+// An ordered set of texture layers that get composited into a single texture.
+//-----------------------------------------------------------------------------
+
+LLViewerTexLayerSet::LLViewerTexLayerSet(LLAvatarAppearance* const appearance) :
+	LLTexLayerSet(appearance),
+	mUpdatesEnabled( FALSE )
+{
+}
+
+// virtual
+LLViewerTexLayerSet::~LLViewerTexLayerSet()
+{
+}
+
+// Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on.
+BOOL LLViewerTexLayerSet::isLocalTextureDataAvailable() const
+{
+	if (!mAvatarAppearance->isSelf()) return FALSE;
+	return getAvatar()->isLocalTextureDataAvailable(this);
+}
+
+
+// Returns TRUE if all of the data for the textures that this layerset depends on have arrived.
+BOOL LLViewerTexLayerSet::isLocalTextureDataFinal() const
+{
+	if (!mAvatarAppearance->isSelf()) return FALSE;
+	return getAvatar()->isLocalTextureDataFinal(this);
+}
+
+// virtual
+void LLViewerTexLayerSet::requestUpdate()
+{
+	if( mUpdatesEnabled )
+	{
+		createComposite();
+		getViewerComposite()->requestUpdate(); 
+	}
+}
+
+void LLViewerTexLayerSet::requestUpload()
+{
+	createComposite();
+	getViewerComposite()->requestUpload();
+}
+
+void LLViewerTexLayerSet::cancelUpload()
+{
+	if(mComposite)
+	{
+		getViewerComposite()->cancelUpload();
+	}
+}
+
+void LLViewerTexLayerSet::updateComposite()
+{
+	createComposite();
+	getViewerComposite()->requestUpdateImmediate();
+}
+
+// virtual
+void LLViewerTexLayerSet::createComposite()
+{
+	if(!mComposite)
+	{
+		S32 width = mInfo->getWidth();
+		S32 height = mInfo->getHeight();
+		// Composite other avatars at reduced resolution
+		if( !mAvatarAppearance->isSelf() )
+		{
+			llerrs << "composites should not be created for non-self avatars!" << llendl;
+		}
+		mComposite = new LLViewerTexLayerSetBuffer( this, width, height );
+	}
+}
+
+void LLViewerTexLayerSet::setUpdatesEnabled( BOOL b )
+{
+	mUpdatesEnabled = b; 
+}
+
+LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar()
+{
+	return dynamic_cast<LLVOAvatarSelf*> (mAvatarAppearance);
+}
+
+const LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar() const
+{
+	return dynamic_cast<const LLVOAvatarSelf*> (mAvatarAppearance);
+}
+
+LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite()
+{
+	return dynamic_cast<LLViewerTexLayerSetBuffer*> (getComposite());
+}
+
+const LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite() const
+{
+	return dynamic_cast<const LLViewerTexLayerSetBuffer*> (getComposite());
+}
+
+
+const std::string LLViewerTexLayerSetBuffer::dumpTextureInfo() const
+{
+	if (!isAgentAvatarValid()) return "";
+
+	const BOOL is_high_res = !mNeedsUpload;
+	const U32 num_low_res = mNumLowresUploads;
+	const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32();
+	const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(getViewerTexLayerSet());
+
+	std::string status 				= "CREATING ";
+	if (!uploadNeeded()) status 	= "DONE     ";
+	if (uploadInProgress()) status 	= "UPLOADING";
+
+	std::string text = llformat("[%s] [HiRes:%d LoRes:%d] [Elapsed:%d] %s",
+								status.c_str(),
+								is_high_res, num_low_res,
+								upload_time, 
+								local_texture_info.c_str());
+	return text;
+}
diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h
new file mode 100644
index 0000000000000000000000000000000000000000..959c883da86d9789427e18b89e6d3e5068545749
--- /dev/null
+++ b/indra/newview/llviewertexlayer.h
@@ -0,0 +1,180 @@
+/** 
+ * @file llviewertexlayer.h
+ * @brief Viewer Texture layer classes. Used for avatars.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_VIEWER_TEXLAYER_H
+#define LL_VIEWER_TEXLAYER_H
+
+#include "lldynamictexture.h"
+#include "llextendedstatus.h"
+#include "lltexlayer.h"
+
+class LLVOAvatarSelf;
+class LLViewerTexLayerSetBuffer;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLViewerTexLayerSet
+//
+// An ordered set of texture layers that gets composited into a single texture.
+// Only exists for llavatarappearanceself.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLViewerTexLayerSet : public LLTexLayerSet
+{
+public:
+	LLViewerTexLayerSet(LLAvatarAppearance* const appearance);
+	virtual ~LLViewerTexLayerSet();
+
+	/*virtual*/void				requestUpdate();
+	void						requestUpload();
+	void						cancelUpload();
+	BOOL						isLocalTextureDataAvailable() const;
+	BOOL						isLocalTextureDataFinal() const;
+	void						updateComposite();
+	/*virtual*/void				createComposite();
+	void						setUpdatesEnabled(BOOL b);
+	BOOL						getUpdatesEnabled()	const 	{ return mUpdatesEnabled; }
+
+	LLVOAvatarSelf*				getAvatar();
+	const LLVOAvatarSelf*		getAvatar()	const;
+	LLViewerTexLayerSetBuffer*	getViewerComposite();
+	const LLViewerTexLayerSetBuffer*	getViewerComposite() const;
+
+private:
+	BOOL						mUpdatesEnabled;
+
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLViewerTexLayerSetBuffer
+//
+// The composite image that a LLViewerTexLayerSet writes to.  Each LLViewerTexLayerSet has one.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLViewerTexLayerSetBuffer : public LLTexLayerSetBuffer, public LLViewerDynamicTexture
+{
+	LOG_CLASS(LLViewerTexLayerSetBuffer);
+
+public:
+	LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
+	virtual ~LLViewerTexLayerSetBuffer();
+
+public:
+	/*virtual*/ S8          getType() const;
+	BOOL					isInitialized(void) const;
+	static void				dumpTotalByteCount();
+	const std::string		dumpTextureInfo() const;
+	virtual void 			restoreGLTexture();
+	virtual void 			destroyGLTexture();
+private:
+	LLViewerTexLayerSet*	getViewerTexLayerSet() 
+		{ return dynamic_cast<LLViewerTexLayerSet*> (mTexLayerSet); }
+	const LLViewerTexLayerSet*	getViewerTexLayerSet() const
+		{ return dynamic_cast<const LLViewerTexLayerSet*> (mTexLayerSet); }
+	static S32				sGLByteCount;
+
+	//--------------------------------------------------------------------
+	// Tex Layer Render
+	//--------------------------------------------------------------------
+	virtual void			preRenderTexLayerSet();
+	virtual void			midRenderTexLayerSet(BOOL success);
+	virtual void			postRenderTexLayerSet(BOOL success);
+	virtual S32				getCompositeOriginX() const { return getOriginX(); }
+	virtual S32				getCompositeOriginY() const { return getOriginY(); }
+	virtual S32				getCompositeWidth() const { return getFullWidth(); }
+	virtual S32				getCompositeHeight() const { return getFullHeight(); }
+
+	//--------------------------------------------------------------------
+	// Dynamic Texture Interface
+	//--------------------------------------------------------------------
+public:
+	/*virtual*/ BOOL		needsRender();
+protected:
+	// Pass these along for tex layer rendering.
+	virtual void			preRender(BOOL clear_depth) { preRenderTexLayerSet(); }
+	virtual void			postRender(BOOL success) { postRenderTexLayerSet(success); }
+	virtual BOOL			render() { return renderTexLayerSet(); }
+	
+	//--------------------------------------------------------------------
+	// Uploads
+	//--------------------------------------------------------------------
+public:
+	void					requestUpload();
+	void					cancelUpload();
+	BOOL					uploadNeeded() const; 			// We need to upload a new texture
+	BOOL					uploadInProgress() const; 		// We have started uploading a new texture and are awaiting the result
+	BOOL					uploadPending() const; 			// We are expecting a new texture to be uploaded at some point
+	static void				onTextureUploadComplete(const LLUUID& uuid,
+													void* userdata,
+													S32 result, LLExtStat ext_status);
+protected:
+	BOOL					isReadyToUpload() const;
+	void					doUpload(); 					// Does a read back and upload.
+	void					conditionalRestartUploadTimer();
+private:
+	BOOL					mNeedsUpload; 					// Whether we need to send our baked textures to the server
+	U32						mNumLowresUploads; 				// Number of times we've sent a lowres version of our baked textures to the server
+	BOOL					mUploadPending; 				// Whether we have received back the new baked textures
+	LLUUID					mUploadID; 						// The current upload process (null if none).
+	LLFrameTimer    		mNeedsUploadTimer; 				// Tracks time since upload was requested and performed.
+	S32						mUploadFailCount;				// Number of consecutive upload failures
+	LLFrameTimer    		mUploadRetryTimer; 				// Tracks time since last upload failure.
+
+	//--------------------------------------------------------------------
+	// Updates
+	//--------------------------------------------------------------------
+public:
+	void					requestUpdate();
+	BOOL					requestUpdateImmediate();
+protected:
+	BOOL					isReadyToUpdate() const;
+	void					doUpdate();
+	void					restartUpdateTimer();
+private:
+	BOOL					mNeedsUpdate; 					// Whether we need to locally update our baked textures
+	U32						mNumLowresUpdates; 				// Number of times we've locally updated with lowres version of our baked textures
+	LLFrameTimer    		mNeedsUpdateTimer; 				// Tracks time since update was requested and performed.
+};
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLBakedUploadData
+//
+// Used by LLTexLayerSetBuffer for a callback.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+struct LLBakedUploadData
+{
+	LLBakedUploadData(const LLVOAvatarSelf* avatar,
+					  LLViewerTexLayerSet* layerset, 
+					  const LLUUID& id,
+					  bool highest_res);
+	~LLBakedUploadData() {}
+	const LLUUID				mID;
+	const LLVOAvatarSelf*		mAvatar; // note: backlink only; don't LLPointer 
+	LLViewerTexLayerSet*		mTexLayerSet;
+   	const U64					mStartTime;	// for measuring baked texture upload time
+   	const bool					mIsHighestRes; // whether this is a "final" bake, or intermediate low res
+};
+
+#endif  // LL_VIEWER_TEXLAYER_H
+
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 122d8f4a961e46fbb0091822ee8feccc673ddba9..8036a4e2585996cbbf934b820d73bd40052b65c1 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -1052,8 +1052,6 @@ void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end)
 {
 	LLWString text = getWText();
 
-	LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get()  );
-
 	// Start with i just after the first embedded item
 	for(S32 idx = start; idx < end; idx++ )
 	{
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 08fcb60d035e628b7705fc11a820583deb813e2d..eb6c453e765d74bbcc984d12006fc5587be1aa10 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -58,6 +58,7 @@
 #include "lltextureatlas.h"
 #include "lltextureatlasmanager.h"
 #include "lltextureentry.h"
+#include "lltexturemanagerbridge.h"
 #include "llmediaentry.h"
 #include "llvovolume.h"
 #include "llviewermedia.h"
@@ -231,7 +232,7 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(BOOL usemipma
 	if(generate_gl_tex)
 	{
 		tex->generateGLTexture() ;
-		tex->setCategory(LLViewerTexture::LOCAL) ;
+		tex->setCategory(LLGLTexture::LOCAL) ;
 	}
 	return tex ;
 }
@@ -241,14 +242,14 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLUUID&
 	if(generate_gl_tex)
 	{
 		tex->generateGLTexture() ;
-		tex->setCategory(LLViewerTexture::LOCAL) ;
+		tex->setCategory(LLGLTexture::LOCAL) ;
 	}
 	return tex ;
 }
 LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) 
 {
 	LLPointer<LLViewerTexture> tex = new LLViewerTexture(raw, usemipmaps) ;
-	tex->setCategory(LLViewerTexture::LOCAL) ;
+	tex->setCategory(LLGLTexture::LOCAL) ;
 	return tex ;
 }
 LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex) 
@@ -257,13 +258,14 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 wid
 	if(generate_gl_tex)
 	{
 		tex->generateGLTexture() ;
-		tex->setCategory(LLViewerTexture::LOCAL) ;
+		tex->setCategory(LLGLTexture::LOCAL) ;
 	}
 	return tex ;
 }
 
 LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
 	                                               const LLUUID &image_id,											       
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -271,11 +273,12 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
 												   LLGLenum primary_format,
 												   LLHost request_from_host)
 {
-	return gTextureList.getImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
+	return gTextureList.getImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
 }
 	
 LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
-	                                               const std::string& filename,												   
+	                                               const std::string& filename,
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -283,11 +286,12 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
 												   LLGLenum primary_format, 
 												   const LLUUID& force_id)
 {
-	return gTextureList.getImageFromFile(filename, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
+	return gTextureList.getImageFromFile(filename, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
 }
 
 //static 
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,									 
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,
+									 FTType f_type,
 									 BOOL usemipmaps,
 									 LLViewerTexture::EBoostLevel boost_priority,
 									 S8 texture_type,
@@ -296,14 +300,34 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const s
 									 const LLUUID& force_id
 									 )
 {
-	return gTextureList.getImageFromUrl(url, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
+	return gTextureList.getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
 }
 
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) 
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) 
 {
-	return gTextureList.getImageFromHost(image_id, host) ;
+	return gTextureList.getImageFromHost(image_id, f_type, host) ;
 }
 
+// Create a bridge to the viewer texture manager.
+class LLViewerTextureManagerBridge : public LLTextureManagerBridge
+{
+	/*virtual*/ LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE)
+	{
+		return LLViewerTextureManager::getLocalTexture(usemipmaps, generate_gl_tex);
+	}
+
+	/*virtual*/ LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE)
+	{
+		return LLViewerTextureManager::getLocalTexture(width, height, components, usemipmaps, generate_gl_tex);
+	}
+
+	/*virtual*/ LLGLTexture* getFetchedTexture(const LLUUID &image_id)
+	{
+		return LLViewerTextureManager::getFetchedTexture(image_id);
+	}
+};
+
+
 void LLViewerTextureManager::init()
 {
 	{
@@ -349,12 +373,12 @@ void LLViewerTextureManager::init()
 	imagep->setCachedRawImage(0, image_raw) ;
 	image_raw = NULL;
 #else
- 	LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI);
+ 	LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 #endif
 	LLViewerFetchedTexture::sDefaultImagep->dontDiscard();
-	LLViewerFetchedTexture::sDefaultImagep->setCategory(LLViewerTexture::OTHER) ;
+	LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER) ;
 
- 	LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLViewerTexture::BOOST_UI);
+ 	LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ;
 
 	image_raw = new LLImageRaw(32,32,3);
@@ -373,6 +397,9 @@ void LLViewerTextureManager::init()
 	LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);
 
 	LLViewerTexture::initClass() ;
+	
+	// Create a texture manager bridge.
+	gTextureManagerBridgep = new LLViewerTextureManagerBridge;
 
 	if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))
 	{
@@ -389,6 +416,7 @@ void LLViewerTextureManager::cleanup()
 {
 	stop_glerror();
 
+	delete gTextureManagerBridgep;
 	LLImageGL::sDefaultGLTexture = NULL ;
 	LLViewerTexture::sNullImagep = NULL;
 	LLViewerTexture::sBlackImagep = NULL;
@@ -416,25 +444,6 @@ void LLViewerTexture::initClass()
 	}
 }
 
-// static
-S32 LLViewerTexture::getTotalNumOfCategories() 
-{
-	return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ;
-}
-
-// static
-//index starts from zero.
-S32 LLViewerTexture::getIndexFromCategory(S32 category) 
-{
-	return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ;
-}
-
-//static 
-S32 LLViewerTexture::getCategoryFromIndex(S32 index)
-{
-	return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ;
-}
-
 // tuning params
 const F32 discard_bias_delta = .25f;
 const F32 discard_delta_time = 0.5f;
@@ -571,70 +580,54 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
 //-------------------------------------------------------------------------------------------
 const U32 LLViewerTexture::sCurrentFileVersion = 1;
 
-LLViewerTexture::LLViewerTexture(BOOL usemipmaps)
+LLViewerTexture::LLViewerTexture(BOOL usemipmaps) :
+	LLGLTexture(usemipmaps)
 {
 	init(true);
-	mUseMipMaps = usemipmaps ;
 
 	mID.generate();
 	sImageCount++;
 }
 
-LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps)
-	: mID(id)
+LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps) :
+	LLGLTexture(usemipmaps),
+	mID(id)
 {
 	init(true);
-	mUseMipMaps = usemipmaps ;
 	
 	sImageCount++;
 }
 
-LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) 
+LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)  :
+	LLGLTexture(width, height, components, usemipmaps)
 {
 	init(true);
 
-	mFullWidth = width ;
-	mFullHeight = height ;
-	mUseMipMaps = usemipmaps ;
-	mComponents = components ;
-	setTexelsPerImage();
-
 	mID.generate();
 	sImageCount++;
 }
 
-LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps)	
+LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) :
+	LLGLTexture(raw, usemipmaps)
 {
 	init(true);
-	mUseMipMaps = usemipmaps ;
-	mGLTexturep = new LLImageGL(raw, usemipmaps) ;
 	
-	// Create an empty image of the specified size and width
 	mID.generate();
 	sImageCount++;
 }
 
 LLViewerTexture::~LLViewerTexture()
 {
+	// LL_DEBUGS("Avatar") << mID << llendl;
 	cleanup();
 	sImageCount--;
 }
 
+// virtual
 void LLViewerTexture::init(bool firstinit)
 {
-	mBoostLevel = LLViewerTexture::BOOST_NONE;
 	mSelectedTime = 0.f;
-
-	mFullWidth = 0;
-	mFullHeight = 0;
-	mTexelsPerImage = 0 ;
-	mUseMipMaps = FALSE ;
-	mComponents = 0 ;
-
-	mTextureState = NO_DELETE ;
-	mDontDiscard = FALSE;
 	mMaxVirtualSize = 0.f;
-	mNeedsGLTexture = FALSE ;
 	mMaxVirtualSizeResetInterval = 1;
 	mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ;
 	mAdditionalDecodePriority = 0.f ;	
@@ -655,19 +648,12 @@ void LLViewerTexture::cleanup()
 {
 	mFaceList.clear() ;
 	mVolumeList.clear();
-	if(mGLTexturep)
-	{
-		mGLTexturep->cleanup();
-	}
 }
 
 // virtual
 void LLViewerTexture::dump()
 {
-	if(mGLTexturep)
-	{
-		mGLTexturep->dump();
-	}
+	LLGLTexture::dump();
 
 	llinfos << "LLViewerTexture"
 			<< " mID " << mID
@@ -690,10 +676,8 @@ void LLViewerTexture::setBoostLevel(S32 level)
 	{
 		mSelectedTime = gFrameTimeSeconds;
 	}
-
 }
 
-
 bool LLViewerTexture::bindDefaultImage(S32 stage) 
 {
 	if (stage < 0) return false;
@@ -886,294 +870,18 @@ void LLViewerTexture::reorganizeVolumeList()
 	mVolumeList.erase(mVolumeList.begin() + mNumVolumes, mVolumeList.end());
 }
 
-
-
 //virtual
 void LLViewerTexture::switchToCachedImage()
 {
 	//nothing here.
 }
 
-void LLViewerTexture::forceActive()
-{
-	mTextureState = ACTIVE ; 
-}
-
-void LLViewerTexture::setActive() 
-{ 
-	if(mTextureState != NO_DELETE)
-	{
-		mTextureState = ACTIVE ; 
-	}
-}
-
-//set the texture to stay in memory
-void LLViewerTexture::setNoDelete() 
-{ 
-	mTextureState = NO_DELETE ;
-}
-
-void LLViewerTexture::generateGLTexture() 
-{	
-	if(mGLTexturep.isNull())
-	{
-		mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
-	}
-}
-
-LLImageGL* LLViewerTexture::getGLTexture() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep ;
-}
-
-BOOL LLViewerTexture::createGLTexture() 
-{
-	if(mGLTexturep.isNull())
-	{
-		generateGLTexture() ;
-	}
-
-	return mGLTexturep->createGLTexture() ;
-}
-
-BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category)
-{
-	llassert(mGLTexturep.notNull()) ;	
-
-	BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ;
-
-	if(ret)
-	{
-		mFullWidth = mGLTexturep->getCurrentWidth() ;
-		mFullHeight = mGLTexturep->getCurrentHeight() ; 
-		mComponents = mGLTexturep->getComponents() ;	
-		setTexelsPerImage();
-	}
-
-	return ret ;
-}
-
 //virtual
 void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)
 {
 	//nothing here.
 }
 
-void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
-{
-	llassert(mGLTexturep.notNull()) ;
-	
-	mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ;
-}
-void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode)
-{
-	llassert(mGLTexturep.notNull()) ;
-	mGLTexturep->setAddressMode(mode) ;
-}
-void LLViewerTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
-{
-	llassert(mGLTexturep.notNull()) ;
-	mGLTexturep->setFilteringOption(option) ;
-}
-
-//virtual
-S32	LLViewerTexture::getWidth(S32 discard_level) const
-{
-	llassert(mGLTexturep.notNull()) ;
-	return mGLTexturep->getWidth(discard_level) ;
-}
-
-//virtual
-S32	LLViewerTexture::getHeight(S32 discard_level) const
-{
-	llassert(mGLTexturep.notNull()) ;
-	return mGLTexturep->getHeight(discard_level) ;
-}
-
-S32 LLViewerTexture::getMaxDiscardLevel() const
-{
-	llassert(mGLTexturep.notNull()) ;
-	return mGLTexturep->getMaxDiscardLevel() ;
-}
-S32 LLViewerTexture::getDiscardLevel() const
-{
-	llassert(mGLTexturep.notNull()) ;
-	return mGLTexturep->getDiscardLevel() ;
-}
-S8  LLViewerTexture::getComponents() const 
-{ 
-	llassert(mGLTexturep.notNull()) ;
-	
-	return mGLTexturep->getComponents() ;
-}
-
-LLGLuint LLViewerTexture::getTexName() const 
-{ 
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getTexName() ; 
-}
-
-BOOL LLViewerTexture::hasGLTexture() const 
-{
-	if(mGLTexturep.notNull())
-	{
-		return mGLTexturep->getHasGLTexture() ;
-	}
-	return FALSE ;
-}
-
-BOOL LLViewerTexture::getBoundRecently() const
-{
-	if(mGLTexturep.notNull())
-	{
-		return mGLTexturep->getBoundRecently() ;
-	}
-	return FALSE ;
-}
-
-LLTexUnit::eTextureType LLViewerTexture::getTarget(void) const
-{
-	llassert(mGLTexturep.notNull()) ;
-	return mGLTexturep->getTarget() ;
-}
-
-BOOL LLViewerTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
-}
-
-BOOL LLViewerTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
-}
-
-void LLViewerTexture::setGLTextureCreated (bool initialized)
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	mGLTexturep->setGLTextureCreated (initialized) ;
-}
-
-void  LLViewerTexture::setCategory(S32 category) 
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	mGLTexturep->setCategory(category) ;
-}
-
-LLTexUnit::eTextureAddressMode LLViewerTexture::getAddressMode(void) const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getAddressMode() ;
-}
-
-S32 LLViewerTexture::getTextureMemory() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->mTextureMemory ;
-}
-
-LLGLenum LLViewerTexture::getPrimaryFormat() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getPrimaryFormat() ;
-}
-
-BOOL LLViewerTexture::getIsAlphaMask() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getIsAlphaMask() ;
-}
-
-BOOL LLViewerTexture::getMask(const LLVector2 &tc)
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getMask(tc) ;
-}
-
-F32 LLViewerTexture::getTimePassedSinceLastBound()
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getTimePassedSinceLastBound() ;
-}
-BOOL LLViewerTexture::getMissed() const 
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getMissed() ;
-}
-
-BOOL LLViewerTexture::isJustBound() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->isJustBound() ;
-}
-
-void LLViewerTexture::forceUpdateBindStats(void) const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->forceUpdateBindStats() ;
-}
-
-U32 LLViewerTexture::getTexelsInAtlas() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getTexelsInAtlas() ;
-}
-
-U32 LLViewerTexture::getTexelsInGLTexture() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getTexelsInGLTexture() ;
-}
-
-BOOL LLViewerTexture::isGLTextureCreated() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->isGLTextureCreated() ;
-}
-
-S32  LLViewerTexture::getDiscardLevelInAtlas() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getDiscardLevelInAtlas() ;
-}
-
-void LLViewerTexture::destroyGLTexture() 
-{
-	if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
-	{
-		mGLTexturep->destroyGLTexture() ;
-		mTextureState = DELETED ;	
-	}	
-}
-
-void LLViewerTexture::setTexelsPerImage()
-{
-	S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
-	S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
-	mTexelsPerImage = (F32)fullwidth * fullheight;
-}
-
 BOOL LLViewerTexture::isLargeImage()
 {
 	return  (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize ;
@@ -1197,25 +905,32 @@ void LLViewerTexture::updateBindStatsForTester()
 //start of LLViewerFetchedTexture
 //----------------------------------------------------------------------------------------------
 
-LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps)
+LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps)
 	: LLViewerTexture(id, usemipmaps),
 	mTargetHost(host)
 {
 	init(TRUE) ;
+	mFTType = f_type;
+	if (mFTType == FTT_HOST_BAKE)
+	{
+		mCanUseHTTP = false;
+	}
 	generateGLTexture() ;
 }
 	
-LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps)
+LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps)
 	: LLViewerTexture(raw, usemipmaps)
 {
 	init(TRUE) ;
+	mFTType = f_type;
 }
 	
-LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps)
+LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps)
 	: LLViewerTexture(id, usemipmaps),
 	mUrl(url)
 {
 	init(TRUE) ;
+	mFTType = f_type;
 	generateGLTexture() ;
 }
 
@@ -1281,6 +996,8 @@ void LLViewerFetchedTexture::init(bool firstinit)
 	mLastCallBackActiveTime = 0.f;
 
 	mInDebug = FALSE;
+
+	mFTType = FTT_UNKNOWN;
 }
 
 LLViewerFetchedTexture::~LLViewerFetchedTexture()
@@ -1301,6 +1018,11 @@ S8 LLViewerFetchedTexture::getType() const
 	return LLViewerTexture::FETCHED_TEXTURE ;
 }
 
+FTType LLViewerFetchedTexture::getFTType() const
+{
+	return mFTType;
+}
+
 void LLViewerFetchedTexture::cleanup()
 {
 	for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
@@ -1345,6 +1067,7 @@ void LLViewerFetchedTexture::loadFromFastCache()
 		{ 
 			//discard all oversized textures.
 			destroyRawImage();
+			llwarns << "oversized, setting as missing" << llendl;
 			setIsMissingAsset();
 			mRawDiscardLevel = INVALID_DISCARD_LEVEL ;
 		}
@@ -1454,7 +1177,8 @@ void LLViewerFetchedTexture::destroyTexture()
 	{
 		return ;
 	}
-	
+
+	//LL_DEBUGS("Avatar") << mID << llendl;
 	destroyGLTexture() ;
 	mFullyLoaded = FALSE ;
 }
@@ -1610,6 +1334,7 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
 		// An inappropriately-sized image was uploaded (through a non standard client)
 		// We treat these images as missing assets which causes them to
 		// be renderd as 'missing image' and to stop requesting data
+		llwarns << "!size_ok, setting as missing" << llendl;
 		setIsMissingAsset();
 		destroyRawImage();
 		return FALSE;
@@ -1757,7 +1482,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 		// Don't decode anything we don't need
 		priority = -4.0f;
 	}
-	else if ((mBoostLevel == LLViewerTexture::BOOST_UI || mBoostLevel == LLViewerTexture::BOOST_ICON) && !have_all_data)
+	else if ((mBoostLevel == LLGLTexture::BOOST_UI || mBoostLevel == LLGLTexture::BOOST_ICON) && !have_all_data)
 	{
 		priority = 1.f;
 	}
@@ -2068,6 +1793,7 @@ bool LLViewerFetchedTexture::updateFetch()
 				{ 
 					//discard all oversized textures.
 					destroyRawImage();
+					llwarns << "oversize, setting as missing" << llendl;
 					setIsMissingAsset();
 					mRawDiscardLevel = INVALID_DISCARD_LEVEL ;
 					mIsFetching = FALSE ;
@@ -2097,6 +1823,10 @@ bool LLViewerFetchedTexture::updateFetch()
 				// We finished but received no data
 				if (current_discard < 0)
 				{
+					llwarns << "!mIsFetching, setting as missing, decode_priority " << decode_priority
+							<< " mRawDiscardLevel " << mRawDiscardLevel
+							<< " current_discard " << current_discard
+							<< llendl;
 					setIsMissingAsset();
 					desired_discard = -1;
 				}
@@ -2164,7 +1894,7 @@ bool LLViewerFetchedTexture::updateFetch()
 		// Load the texture progressively: we try not to rush to the desired discard too fast.
 		// If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps
 		// This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around
-		S32 delta_level = (mBoostLevel > LLViewerTexture::BOOST_NONE) ? 2 : 1 ; 
+		S32 delta_level = (mBoostLevel > LLGLTexture::BOOST_NONE) ? 2 : 1 ; 
 		if (current_discard < 0)
 		{
 			desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level);
@@ -2212,7 +1942,7 @@ bool LLViewerFetchedTexture::updateFetch()
 		
 		// bypass texturefetch directly by pulling from LLTextureCache
 		bool fetch_request_created = false;
-		fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mUrl, getID(),getTargetHost(), decode_priority,
+		fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
 																			  w, h, c, desired_discard, needsAux(), mCanUseHTTP);
 		
 		if (fetch_request_created)
@@ -2229,11 +1959,13 @@ bool LLViewerFetchedTexture::updateFetch()
 	}
 	else if (mHasFetcher && !mIsFetching)
 	{
-		// Only delete requests that haven't receeived any network data for a while
+		// Only delete requests that haven't received any network data
+		// for a while.  Note - this is the normal mechanism for
+		// deleting requests, not just a place to handle timeouts.
 		const F32 FETCH_IDLE_TIME = 5.f;
 		if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)
 		{
-// 			llinfos << "Deleting request: " << getID() << " Discard: " << current_discard << " <= min:" << mMinDiscardLevel << " or priority == 0: " << decode_priority << llendl;
+ 			LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << llendl;
 			LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
 			mHasFetcher = FALSE;
 		}
@@ -2281,8 +2013,10 @@ void LLViewerFetchedTexture::setIsMissingAsset()
 	}
 	else
 	{
-		//it is normal no map tile on an empty region.
-		//llwarns << mUrl << ": Marking image as missing" << llendl;
+		// This may or may not be an error - it is normal to have no
+		// map tile on an empty region, but bad if we're failing on a
+		// server bake texture.
+		llwarns << mUrl << ": Marking image as missing" << llendl;
 	}
 	if (mHasFetcher)
 	{
@@ -2415,7 +2149,7 @@ void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::so
 			destroySavedRawImage() ;
 		}
 	}
-	else if(needsToSaveRawImage() && mBoostLevel != LLViewerTexture::BOOST_PREVIEW)
+	else if(needsToSaveRawImage() && mBoostLevel != LLGLTexture::BOOST_PREVIEW)
 	{
 		if(desired_raw_discard != INVALID_DISCARD_LEVEL)
 		{
@@ -2873,7 +2607,7 @@ void LLViewerFetchedTexture::setCachedRawImage()
 		S32 h = mRawImage->getHeight() ;
 
 		S32 max_size = MAX_CACHED_RAW_IMAGE_AREA ;
-		if(LLViewerTexture::BOOST_TERRAIN == mBoostLevel)
+		if(LLGLTexture::BOOST_TERRAIN == mBoostLevel)
 		{
 			max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA ;
 		}		
@@ -3197,14 +2931,14 @@ BOOL LLViewerFetchedTexture::insertToAtlas()
 //----------------------------------------------------------------------------------------------
 //start of LLViewerLODTexture
 //----------------------------------------------------------------------------------------------
-LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps)
-	: LLViewerFetchedTexture(id, host, usemipmaps)
+LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps)
+	: LLViewerFetchedTexture(id, f_type, host, usemipmaps)
 {
 	init(TRUE) ;
 }
 
-LLViewerLODTexture::LLViewerLODTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps)
-	: LLViewerFetchedTexture(url, id, usemipmaps)
+LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps)
+	: LLViewerFetchedTexture(url, f_type, id, usemipmaps)
 {
 	init(TRUE) ;
 }
@@ -3246,7 +2980,7 @@ void LLViewerLODTexture::processTextureStats()
 		if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
 			mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
 	}
-	else if (mBoostLevel < LLViewerTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
+	else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
 	{
 		// If the image has not been significantly visible in a while, we don't want it
 		mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1));
@@ -3296,7 +3030,7 @@ void LLViewerLODTexture::processTextureStats()
 				mCalculatedDiscardLevel = discard_level;
 			}
 		}
-		if (mBoostLevel < LLViewerTexture::BOOST_SCULPTED)
+		if (mBoostLevel < LLGLTexture::BOOST_SCULPTED)
 		{
 			discard_level += sDesiredDiscardBias;
 			discard_level *= sDesiredDiscardScale; // scale
@@ -3322,7 +3056,7 @@ void LLViewerLODTexture::processTextureStats()
 		//
 
 		S32 current_discard = getDiscardLevel();
-		if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLViewerTexture::BOOST_SCULPTED && current_discard >= 0)
+		if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLGLTexture::BOOST_SCULPTED && current_discard >= 0)
 		{
 			if(desired_discard_bias_max <= sDesiredDiscardBias && !mForceToSaveRawImage)
 			{
@@ -3465,7 +3199,7 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
 
 	setMediaImpl() ;
 
-	setCategory(LLViewerTexture::MEDIA) ;
+	setCategory(LLGLTexture::MEDIA) ;
 	
 	LLViewerTexture* tex = gTextureList.findImage(mID) ;
 	if(tex) //this media is a parcel media for tex.
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 2e7949e9a38f84d42ef8b42feba503d09baba45e..f2e1a90713afade6a10f4ed4432648eac3c8395e 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -27,7 +27,7 @@
 #ifndef LL_LLVIEWERTEXTURE_H					
 #define LL_LLVIEWERTEXTURE_H
 
-#include "lltexture.h"
+#include "llgltexture.h"
 #include "lltimer.h"
 #include "llframetimer.h"
 #include "llhost.h"
@@ -88,14 +88,9 @@ class LLLoadedCallbackEntry
 
 class LLTextureBar;
 
-class LLViewerTexture : public LLTexture
+class LLViewerTexture : public LLGLTexture
 {
 public:
-	enum
-	{
-		MAX_IMAGE_SIZE_DEFAULT = 1024,
-		INVALID_DISCARD_LEVEL = 0x7fff
-	};
 	enum
 	{
 		LOCAL_TEXTURE,		
@@ -107,43 +102,6 @@ class LLViewerTexture : public LLTexture
 		INVALID_TEXTURE_TYPE
 	};
 
-	enum EBoostLevel
-	{
-		BOOST_NONE 			= 0,
-		BOOST_AVATAR_BAKED	,
-		BOOST_AVATAR		,
-		BOOST_CLOUDS		,
-		BOOST_SCULPTED      ,
-		
-		BOOST_HIGH 			= 10,
-		BOOST_BUMP          ,
-		BOOST_TERRAIN		, // has to be high priority for minimap / low detail
-		BOOST_SELECTED		,		
-		BOOST_AVATAR_BAKED_SELF	,
-		BOOST_AVATAR_SELF	, // needed for baking avatar
-		BOOST_SUPER_HIGH    , //textures higher than this need to be downloaded at the required resolution without delay.
-		BOOST_HUD			,
-		BOOST_ICON			,
-		BOOST_UI			,
-		BOOST_PREVIEW		,
-		BOOST_MAP			,
-		BOOST_MAP_VISIBLE	,		
-		BOOST_MAX_LEVEL,
-
-		//other texture Categories
-		LOCAL = BOOST_MAX_LEVEL,
-		AVATAR_SCRATCH_TEX,
-		DYNAMIC_TEX,
-		MEDIA,
-		ATLAS,
-		OTHER,
-		MAX_GL_IMAGE_CATEGORY
-	};
-
-	static S32 getTotalNumOfCategories() ;
-	static S32 getIndexFromCategory(S32 category) ;
-	static S32 getCategoryFromIndex(S32 index) ;
-
 	typedef std::vector<LLFace*> ll_face_list_t;
 	typedef std::vector<LLVOVolume*> ll_volume_list_t;
 
@@ -168,8 +126,7 @@ class LLViewerTexture : public LLTexture
 	/*virtual*/ bool bindDefaultImage(const S32 stage = 0) ;
 	/*virtual*/ void forceImmediateUpdate() ;
 	
-	const LLUUID& getID() const { return mID; }
-	
+	/*virtual*/ const LLUUID& getID() const { return mID; }
 	void setBoostLevel(S32 level);
 	S32  getBoostLevel() { return mBoostLevel; }
 
@@ -177,13 +134,12 @@ class LLViewerTexture : public LLTexture
 	void resetTextureStats();	
 	void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;}
 	void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;}
+	S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; }
 
 	virtual F32  getMaxVirtualSize() ;
 
 	LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;}
 	
-	S32 getFullWidth() const { return mFullWidth; }
-	S32 getFullHeight() const { return mFullHeight; }	
 	/*virtual*/ void setKnownDrawSize(S32 width, S32 height);
 
 	virtual void addFace(LLFace* facep) ;
@@ -196,60 +152,8 @@ class LLViewerTexture : public LLTexture
 	S32 getNumVolumes() const;
 	const ll_volume_list_t* getVolumeList() const { return &mVolumeList; }
 
-	void generateGLTexture() ;
-	void destroyGLTexture() ;
 	
-	//---------------------------------------------------------------------------------------------
-	//functions to access LLImageGL
-	//---------------------------------------------------------------------------------------------
-	/*virtual*/S32	       getWidth(S32 discard_level = -1) const;
-	/*virtual*/S32	       getHeight(S32 discard_level = -1) const;
-	
-	BOOL       hasGLTexture() const ;
-	LLGLuint   getTexName() const ;		
-	BOOL       createGLTexture() ;
-	BOOL       createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLViewerTexture::OTHER);
 	virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
-
-	void       setFilteringOption(LLTexUnit::eTextureFilterOptions option);
-	void       setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
-	void       setAddressMode(LLTexUnit::eTextureAddressMode mode);
-	BOOL       setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
-	BOOL       setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
-	void       setGLTextureCreated (bool initialized);
-	void       setCategory(S32 category) ;
-
-	LLTexUnit::eTextureAddressMode getAddressMode(void) const ;
-	S32        getMaxDiscardLevel() const;
-	S32        getDiscardLevel() const;
-	S8		   getComponents() const ;		
-	BOOL       getBoundRecently() const;
-	S32        getTextureMemory() const ;
-	LLGLenum   getPrimaryFormat() const;
-	BOOL       getIsAlphaMask() const ;
-	LLTexUnit::eTextureType getTarget(void) const ;
-	BOOL       getMask(const LLVector2 &tc);
-	F32        getTimePassedSinceLastBound();
-	BOOL       getMissed() const ;
-	BOOL       isJustBound()const ;
-	void       forceUpdateBindStats(void) const;
-
-	U32        getTexelsInAtlas() const ;
-	U32        getTexelsInGLTexture() const ;
-	BOOL       isGLTextureCreated() const ;
-	S32        getDiscardLevelInAtlas() const ;
-	//---------------------------------------------------------------------------------------------
-	//end of functions to access LLImageGL
-	//---------------------------------------------------------------------------------------------
-
-	//-----------------
-	/*virtual*/ void setActive() ;
-	void forceActive() ;
-	void setNoDelete() ;
-	void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
-	BOOL getDontDiscard() const { return mDontDiscard; }
-	//-----------------	
-	
 	BOOL isLargeImage() ;	
 	
 	void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;}
@@ -262,36 +166,22 @@ class LLViewerTexture : public LLTexture
 	void init(bool firstinit) ;	
 	void reorganizeFaceList() ;
 	void reorganizeVolumeList() ;
-	void setTexelsPerImage();
 private:
 	friend class LLBumpImageList;
 	friend class LLUIImageList;
 
-	//note: do not make this function public.
-	/*virtual*/ LLImageGL* getGLTexture() const ;
 	virtual void switchToCachedImage();
 	
 	static bool isMemoryForTextureLow() ;
 protected:
 	LLUUID mID;
-	S32 mBoostLevel;				// enum describing priority level
 	F32 mSelectedTime;				// time texture was last selected
-	S32 mFullWidth;
-	S32 mFullHeight;
-	BOOL  mUseMipMaps ;
-	S8  mComponents;
-	F32 mTexelsPerImage;			// Texels per image.
-	mutable S8  mNeedsGLTexture;
 	mutable F32 mMaxVirtualSize;	// The largest virtual size of the image, in pixels - how much data to we need?	
 	mutable S32  mMaxVirtualSizeResetCounter ;
 	mutable S32  mMaxVirtualSizeResetInterval;
 	mutable F32 mAdditionalDecodePriority;  // priority add to mDecodePriority.
 	LLFrameTimer mLastReferencedTimer;	
 
-	//GL texture
-	LLPointer<LLImageGL> mGLTexturep ;
-	S8 mDontDiscard;			// Keep full res version of this image (for UI, etc)
-
 	ll_face_list_t    mFaceList ; //reverse pointer pointing to the faces using this image as texture
 	U32               mNumFaces ;
 	LLFrameTimer      mLastFaceListUpdateTimer ;
@@ -303,17 +193,6 @@ class LLViewerTexture : public LLTexture
 	//do not use LLPointer here.
 	LLViewerMediaTexture* mParcelMedia ;
 
-protected:
-	typedef enum 
-	{
-		DELETED = 0,         //removed from memory
-		DELETION_CANDIDATE,  //ready to be removed from memory
-		INACTIVE,            //not be used for the last certain period (i.e., 30 seconds).
-		ACTIVE,              //just being used, can become inactive if not being used for a certain time (10 seconds).
-		NO_DELETE = 99       //stay in memory, can not be removed.
-	} LLGLTextureState;
-	LLGLTextureState  mTextureState ;
-
 	static F32 sTexelPixelRatio;
 public:
 	static const U32 sCurrentFileVersion;	
@@ -353,6 +232,16 @@ class LLViewerTexture : public LLTexture
 };
 
 
+enum FTType
+{
+	FTT_UNKNOWN = -1,
+	FTT_DEFAULT = 0, // standard texture fetched by id.
+	FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there.
+	FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host.
+	FTT_MAP_TILE, // tiles are fetched from map server directly.
+	FTT_LOCAL_FILE // fetch directly from a local file.
+};
+
 //
 //textures are managed in gTextureList.
 //raw image data is fetched from remote or local cache
@@ -366,9 +255,9 @@ class LLViewerFetchedTexture : public LLViewerTexture
 protected:
 	/*virtual*/ ~LLViewerFetchedTexture();
 public:
-	LLViewerFetchedTexture(const LLUUID& id, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
-	LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps);
-	LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps = TRUE);
+	LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
+	LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps);
+	LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
 
 public:
 	static F32 maxDecodePriority();
@@ -393,6 +282,7 @@ class LLViewerFetchedTexture : public LLViewerTexture
 
 public:
 	/*virtual*/ S8 getType() const ;
+	FTType getFTType() const;
 	/*virtual*/ void forceImmediateUpdate() ;
 	/*virtual*/ void dump() ;
 
@@ -428,6 +318,7 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	// the priority list, and cause horrible things to happen.
 	void setDecodePriority(F32 priority = -1.0f);
 	F32 getDecodePriority() const { return mDecodePriority; };
+	F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; };
 
 	void setAdditionalDecodePriority(F32 priority) ;
 	
@@ -509,7 +400,7 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	S32 getCurrentDiscardLevelForFetching() ;
 
 private:
-	void init(bool firstinit) ;
+	void init(bool firstinit) ;	
 	void cleanup() ;
 
 	void saveRawImage() ;
@@ -556,7 +447,8 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	S8  mHasFetcher;				// We've made a fecth request
 	S8  mIsFetching;				// Fetch request is active
 	bool mCanUseHTTP ;              //This texture can be fetched through http if true.
-	
+
+	FTType mFTType; // What category of image is this - map tile, server bake, etc?
 	mutable S8 mIsMissingAsset;		// True if we know that there is no image asset with this image id in the database.		
 
 	typedef std::list<LLLoadedCallbackEntry*> callback_list_t;
@@ -616,8 +508,8 @@ class LLViewerLODTexture : public LLViewerFetchedTexture
 	/*virtual*/ ~LLViewerLODTexture(){}
 
 public:
-	LLViewerLODTexture(const LLUUID& id, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
-	LLViewerLODTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps = TRUE);
+	LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
+	LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
 
 	/*virtual*/ S8 getType() const;
 	// Process image stats to determine priority/quality requirements.
@@ -731,8 +623,9 @@ class LLViewerTextureManager
 	static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
 
 	static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,									 
+									 FTType f_type = FTT_DEFAULT,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -740,8 +633,9 @@ class LLViewerTextureManager
 									 );
 	
 	static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename,									 
+									 FTType f_type = FTT_LOCAL_FILE,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -749,15 +643,16 @@ class LLViewerTextureManager
 									 );
 
 	static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url,									 
+									 FTType f_type,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
 									 const LLUUID& force_id = LLUUID::null
 									 );
 
-	static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) ;
+	static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ;
 
 	static void init() ;
 	static void cleanup() ;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index b9f5c432d09544430a5e7d4b1c2bf54afde2bb95..d2af48f5286d78a95ee1eb1bd18168cddc757883 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -112,10 +112,10 @@ void LLViewerTextureList::doPreloadImages()
 	llassert_always(mUUIDMap.empty()) ;
 
 	// Set the "missing asset" image
-	LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
+	LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
 	
 	// Set the "white" image
-	LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
+	LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
 	LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
 	LLUIImageList* image_list = LLUIImageList::getInstance();
 
@@ -130,33 +130,33 @@ void LLViewerTextureList::doPreloadImages()
 	//uv_test->setMipFilterNearest(TRUE, TRUE);
 
 	// prefetch specific UUIDs
-	LLViewerTextureManager::getFetchedTexture(IMG_SHOT, TRUE);
-	LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF, TRUE);
-	LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+	LLViewerTextureManager::getFetchedTexture(IMG_SHOT);
+	LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF);
+	LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
 	if (image) 
 	{
 		image->setAddressMode(LLTexUnit::TAM_WRAP);
 		mImagePreloads.insert(image);
 	}
-	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
 	if (image) 
 	{
 		image->setAddressMode(LLTexUnit::TAM_WRAP);	
 		mImagePreloads.insert(image);
 	}
-	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
 	if (image) 
 	{
 		image->setAddressMode(LLTexUnit::TAM_WRAP);
 		mImagePreloads.insert(image);
 	}
-	image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+	image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
 	if (image) 
 	{
 		image->setAddressMode(LLTexUnit::TAM_WRAP);	
 		mImagePreloads.insert(image);
 	}
-	image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
+	image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
 		0,0,LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"));
 	if (image) 
 	{
@@ -198,7 +198,7 @@ void LLViewerTextureList::doPrefetchImages()
 
 		if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type)
 		{
-			LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, MIPMAP_TRUE, LLViewerTexture::BOOST_NONE, texture_type);
+			LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, texture_type);
 			if (image)
 			{
 				image->addTextureStats((F32)pixel_area);
@@ -228,7 +228,9 @@ void LLViewerTextureList::shutdown()
 		if (!image->hasGLTexture() ||
 			!image->getUseDiscard() ||
 			image->needsAux() ||
-			image->getTargetHost() != LLHost::invalid)
+			image->getTargetHost() != LLHost::invalid ||
+			!image->getUrl().empty()
+			)
 		{
 			continue; // avoid UI, baked, and other special images
 		}
@@ -322,7 +324,8 @@ void LLViewerTextureList::restoreGL()
 
 ///////////////////////////////////////////////////////////////////////////////
 
-LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,												   
+LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -339,15 +342,16 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
 	if (full_path.empty())
 	{
 		llwarns << "Failed to find local image file: " << filename << llendl;
-		return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI);
+		return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	}
 
 	std::string url = "file://" + full_path;
 
-	return getImageFromUrl(url, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id);
+	return getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id);
 }
 
 LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& url,
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -372,16 +376,33 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
 	}
 
 	LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id);
-	
+
+	if (!imagep.isNull())
+	{
+		LLViewerFetchedTexture *texture = imagep.get();
+		if (texture->getUrl().empty())
+		{
+			llwarns << "Requested texture " << new_id << " already exists but does not have a URL" << llendl;
+		}
+		else if (texture->getUrl() != url)
+		{
+			// This is not an error as long as the images really match -
+			// e.g. could be two avatars wearing the same outfit.
+			LL_DEBUGS("Avatar") << "Requested texture " << new_id
+								<< " already exists with a different url, requested: " << url
+								<< " current: " << texture->getUrl() << llendl;
+		}
+		
+	}
 	if (imagep.isNull())
 	{
 		switch(texture_type)
 		{
 		case LLViewerTexture::FETCHED_TEXTURE:
-			imagep = new LLViewerFetchedTexture(url, new_id, usemipmaps);
+			imagep = new LLViewerFetchedTexture(url, f_type, new_id, usemipmaps);
 			break ;
 		case LLViewerTexture::LOD_TEXTURE:
-			imagep = new LLViewerLODTexture(url, new_id, usemipmaps);
+			imagep = new LLViewerLODTexture(url, f_type, new_id, usemipmaps);
 			break ;
 		default:
 			llerrs << "Invalid texture type " << texture_type << llendl ;
@@ -411,7 +432,8 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
 }
 
 
-LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,											       
+LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -430,14 +452,34 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
 	
 	if ((&image_id == NULL) || image_id.isNull())
 	{
-		return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI));
+		return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI));
 	}
 	
 	LLPointer<LLViewerFetchedTexture> imagep = findImage(image_id);
-	
+	if (!imagep.isNull())
+	{
+		LLViewerFetchedTexture *texture = imagep.get();
+		if (request_from_host.isOk() &&
+			!texture->getTargetHost().isOk())
+		{
+			llwarns << "Requested texture " << image_id << " already exists but does not have a host" << llendl;
+		}
+		else if (request_from_host.isOk() &&
+				 texture->getTargetHost().isOk() &&
+				 request_from_host != texture->getTargetHost())
+		{
+			llwarns << "Requested texture " << image_id << " already exists with a different target host, requested: " 
+					<< request_from_host << " current: " << texture->getTargetHost() << llendl;
+		}
+		if (f_type != FTT_DEFAULT && imagep->getFTType() != f_type)
+		{
+			llwarns << "FTType mismatch: requested " << f_type << " image has " << imagep->getFTType() << llendl;
+		}
+		
+	}
 	if (imagep.isNull())
 	{
-		imagep = createImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
+		imagep = createImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
 	}
 
 	imagep->setGLTextureCreated(true);
@@ -446,7 +488,8 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
 }
 
 //when this function is called, there is no such texture in the gTextureList with image_id.
-LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,											       
+LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -460,10 +503,10 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
 	switch(texture_type)
 	{
 	case LLViewerTexture::FETCHED_TEXTURE:
-		imagep = new LLViewerFetchedTexture(image_id, request_from_host, usemipmaps);
+		imagep = new LLViewerFetchedTexture(image_id, f_type, request_from_host, usemipmaps);
 		break ;
 	case LLViewerTexture::LOD_TEXTURE:
-		imagep = new LLViewerLODTexture(image_id, request_from_host, usemipmaps);
+		imagep = new LLViewerLODTexture(image_id, f_type, request_from_host, usemipmaps);
 		break ;
 	default:
 		llerrs << "Invalid texture type " << texture_type << llendl ;
@@ -1353,7 +1396,7 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d
 	U8 *data = new U8[data_size];
 	msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
 	
-	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 	if (!image)
 	{
 		delete [] data;
@@ -1425,7 +1468,7 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d
 	U8 *data = new U8[data_size];
 	msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
 	
-	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 	if (!image)
 	{
 		delete [] data;
@@ -1456,6 +1499,7 @@ void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **
 	LLViewerFetchedTexture* image = gTextureList.findImage( image_id );
 	if( image )
 	{
+		llwarns << "not in db" << llendl;
 		image->setIsMissingAsset();
 	}
 }
@@ -1525,22 +1569,22 @@ LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name, S32 priori
 LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std::string& filename,
 											  BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority )
 {
-	if (boost_priority == LLViewerTexture::BOOST_NONE)
+	if (boost_priority == LLGLTexture::BOOST_NONE)
 	{
-		boost_priority = LLViewerTexture::BOOST_UI;
+		boost_priority = LLGLTexture::BOOST_UI;
 	}
-	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, MIPMAP_NO, boost_priority);
+	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, FTT_LOCAL_FILE, MIPMAP_NO, boost_priority);
 	return loadUIImage(imagep, name, use_mips, scale_rect, clip_rect);
 }
 
 LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id,
 											BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority)
 {
-	if (boost_priority == LLViewerTexture::BOOST_NONE)
+	if (boost_priority == LLGLTexture::BOOST_NONE)
 	{
-		boost_priority = LLViewerTexture::BOOST_UI;
+		boost_priority = LLGLTexture::BOOST_UI;
 	}
-	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, MIPMAP_NO, boost_priority);
+	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, MIPMAP_NO, boost_priority);
 	return loadUIImage(imagep, id.asString(), use_mips, scale_rect, clip_rect);
 }
 
@@ -1563,7 +1607,7 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
 	//Note:
 	//Some other textures such as ICON also through this flow to be fetched.
 	//But only UI textures need to set this callback.
-	if(imagep->getBoostLevel() == LLViewerTexture::BOOST_UI)
+	if(imagep->getBoostLevel() == LLGLTexture::BOOST_UI)
 	{
 		LLUIImageLoadData* datap = new LLUIImageLoadData;
 		datap->mImageName = name;
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 3dda973d3fa98edf01d20a9c573c8cd514e2589f..136042620d5e193718d1c3ad042a64861d85603a 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -130,8 +130,9 @@ class LLViewerTextureList
 	void removeImageFromList(LLViewerFetchedTexture *image);
 
 	LLViewerFetchedTexture * getImage(const LLUUID &image_id,									 
+									 FTType f_type = FTT_DEFAULT,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -139,8 +140,9 @@ class LLViewerTextureList
 									 );
 	
 	LLViewerFetchedTexture * getImageFromFile(const std::string& filename,									 
+									 FTType f_type = FTT_LOCAL_FILE,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -148,8 +150,9 @@ class LLViewerTextureList
 									 );
 	
 	LLViewerFetchedTexture* getImageFromUrl(const std::string& url,
+									 FTType f_type,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -157,8 +160,9 @@ class LLViewerTextureList
 									 );
 
 	LLViewerFetchedTexture* createImage(const LLUUID &image_id,
+									 FTType f_type,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -167,8 +171,8 @@ class LLViewerTextureList
 	
 	// Request image from a specific host, used for baked avatar textures.
 	// Implemented in header in case someone changes default params above. JC
-	LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host)
-	{ return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }	
+	LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, FTType f_type, LLHost host)
+	{ return getImage(image_id, f_type, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }	
 
 public:
 	typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t;	
@@ -233,11 +237,11 @@ class LLUIImageList : public LLImageProviderInterface, public LLSingleton<LLUIIm
 	LLPointer<LLUIImage> loadUIImageByName(const std::string& name, const std::string& filename,
 		                           BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, 
 								   const LLRect& clip_rect = LLRect::null,
-		                           LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI);
+		                           LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI);
 	LLPointer<LLUIImage> loadUIImageByID(const LLUUID& id,
 								 BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, 
 								 const LLRect& clip_rect = LLRect::null,
-								 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI);
+								 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI);
 
 	LLPointer<LLUIImage> loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, const LLRect& clip_rect = LLRect::null);
 
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e8425dc76a1d5eb77c94ac8a4fdb9a9a6e36cbc0
--- /dev/null
+++ b/indra/newview/llviewerwearable.cpp
@@ -0,0 +1,656 @@
+/** 
+ * @file llviewerwearable.cpp
+ * @brief LLViewerWearable class implementation
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llagentwearables.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llnotificationsutil.h"
+#include "llsidepanelappearance.h"
+#include "lltextureentry.h"
+#include "llviewertexlayer.h"
+#include "llvoavatarself.h"
+#include "llavatarappearancedefines.h"
+#include "llviewerwearable.h"
+#include "llviewercontrol.h"
+#include "llviewerregion.h"
+
+using namespace LLAvatarAppearanceDefines;
+
+// support class - remove for 2.1 (hackity hack hack)
+class LLOverrideBakedTextureUpdate
+{
+public:
+	LLOverrideBakedTextureUpdate(bool temp_state)
+	{
+		U32 num_bakes = (U32) LLAvatarAppearanceDefines::BAKED_NUM_INDICES;
+		for( U32 index = 0; index < num_bakes; ++index )
+		{
+			composite_enabled[index] = gAgentAvatarp->isCompositeUpdateEnabled(index);
+		}
+		gAgentAvatarp->setCompositeUpdatesEnabled(temp_state);
+	}
+
+	~LLOverrideBakedTextureUpdate()
+	{
+		U32 num_bakes = (U32)LLAvatarAppearanceDefines::BAKED_NUM_INDICES;		
+		for( U32 index = 0; index < num_bakes; ++index )
+		{
+			gAgentAvatarp->setCompositeUpdatesEnabled(index, composite_enabled[index]);
+		}
+	}
+private:
+	bool composite_enabled[LLAvatarAppearanceDefines::BAKED_NUM_INDICES];
+};
+
+// Private local functions
+static std::string asset_id_to_filename(const LLUUID &asset_id);
+
+LLViewerWearable::LLViewerWearable(const LLTransactionID& transaction_id) :
+	LLWearable()
+{
+	mTransactionID = transaction_id;
+	mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
+}
+
+LLViewerWearable::LLViewerWearable(const LLAssetID& asset_id) :
+	LLWearable()
+{
+	mAssetID = asset_id;
+	mTransactionID.setNull();
+}
+
+// virtual
+LLViewerWearable::~LLViewerWearable()
+{
+}
+
+// virtual
+LLWearable::EImportResult LLViewerWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
+{
+	// suppress texlayerset updates while wearables are being imported. Layersets will be updated
+	// when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.
+	LLOverrideBakedTextureUpdate stop_bakes(false);
+
+	LLWearable::EImportResult result = LLWearable::importStream(input_stream, avatarp);
+	if (LLWearable::FAILURE == result) return result;
+	if (LLWearable::BAD_HEADER == result)
+	{
+		// Shouldn't really log the asset id for security reasons, but
+		// we need it in this case.
+		llwarns << "Bad Wearable asset header: " << mAssetID << llendl;
+		//gVFS->dumpMap();
+		return result;
+	}
+
+	LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );
+	LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN );
+
+	te_map_t::const_iterator iter = mTEMap.begin();
+	te_map_t::const_iterator end = mTEMap.end();
+	for (; iter != end; ++iter)
+	{
+		S32 te = iter->first;
+		LLLocalTextureObject* lto = iter->second;
+		LLUUID textureid = LLUUID::null;
+		if (lto)
+		{
+			textureid = lto->getID();
+		}
+
+		LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( textureid );
+		if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
+		{
+			image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(textureid, (LLAvatarAppearanceDefines::ETextureIndex)te), NULL);
+		}
+	}
+
+	return result;
+}
+
+
+// Avatar parameter and texture definitions can change over time.
+// This function returns true if parameters or textures have been added or removed
+// since this wearable was created.
+BOOL LLViewerWearable::isOldVersion() const
+{
+	if (!isAgentAvatarValid()) return FALSE;
+
+	if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion )
+	{
+		llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
+		llassert(0);
+	}
+
+	if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion )
+	{
+		return TRUE;
+	}
+
+	S32 param_count = 0;
+	for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
+		param;
+		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
+	{
+		if( (param->getWearableType() == mType) && (param->isTweakable() ) )
+		{
+			param_count++;
+			if( !is_in_map(mVisualParamIndexMap, param->getID() ) )
+			{
+				return TRUE;
+			}
+		}
+	}
+	if( param_count != mVisualParamIndexMap.size() )
+	{
+		return TRUE;
+	}
+
+
+	S32 te_count = 0;
+	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			te_count++;
+			if( !is_in_map(mTEMap, te ) )
+			{
+				return TRUE;
+			}
+		}
+	}
+	if( te_count != mTEMap.size() )
+	{
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+// Avatar parameter and texture definitions can change over time.
+// * If parameters or textures have been REMOVED since the wearable was created,
+// they're just ignored, so we consider the wearable clean even though isOldVersion()
+// will return true. 
+// * If parameters or textures have been ADDED since the wearable was created,
+// they are taken to have default values, so we consider the wearable clean
+// only if those values are the same as the defaults.
+BOOL LLViewerWearable::isDirty() const
+{
+	if (!isAgentAvatarValid()) return FALSE;
+
+	for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
+		param;
+		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
+	{
+		if( (param->getWearableType() == mType) 
+			&& (param->isTweakable() ) 
+			&& !param->getCrossWearable())
+		{
+			F32 current_weight = getVisualParamWeight(param->getID());
+			current_weight = llclamp( current_weight, param->getMinWeight(), param->getMaxWeight() );
+			F32 saved_weight = get_if_there(mSavedVisualParamMap, param->getID(), param->getDefaultWeight());
+			saved_weight = llclamp( saved_weight, param->getMinWeight(), param->getMaxWeight() );
+			
+			U8 a = F32_to_U8( saved_weight, param->getMinWeight(), param->getMaxWeight() );
+			U8 b = F32_to_U8( current_weight, param->getMinWeight(), param->getMaxWeight() );
+			if( a != b  )
+			{
+				return TRUE;
+			}
+		}
+	}
+
+	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			te_map_t::const_iterator current_iter = mTEMap.find(te);
+			if(current_iter != mTEMap.end())
+			{
+ 				const LLUUID& current_image_id = current_iter->second->getID();
+				te_map_t::const_iterator saved_iter = mSavedTEMap.find(te);
+				if(saved_iter != mSavedTEMap.end())
+				{
+					const LLUUID& saved_image_id = saved_iter->second->getID();
+					if (saved_image_id != current_image_id)
+					{
+						// saved vs current images are different, wearable is dirty
+						return TRUE;
+					}
+				}
+				else
+				{
+					// image found in current image list but not saved image list
+					return TRUE;
+				}
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+
+void LLViewerWearable::setParamsToDefaults()
+{
+	if (!isAgentAvatarValid()) return;
+
+	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
+	{
+		if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->isTweakable() ) )
+		{
+			setVisualParamWeight(param->getID(),param->getDefaultWeight(), FALSE);
+		}
+	}
+}
+
+void LLViewerWearable::setTexturesToDefaults()
+{
+	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			LLUUID id = getDefaultTextureImageID((ETextureIndex) te);
+			LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id );
+			if( mTEMap.find(te) == mTEMap.end() )
+			{
+				mTEMap[te] = new LLLocalTextureObject(image, id);
+				createLayers(te, gAgentAvatarp);
+			}
+			else
+			{
+				// Local Texture Object already created, just set image and UUID
+				LLLocalTextureObject *lto = mTEMap[te];
+				lto->setID(id);
+				lto->setImage(image);
+			}
+		}
+	}
+}
+
+
+// virtual
+LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) const
+{
+	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+	const std::string &default_image_name = texture_dict->mDefaultImageName;
+	if (default_image_name == "")
+	{
+		return IMG_DEFAULT_AVATAR;
+	}
+	else
+	{
+		return LLUUID(gSavedSettings.getString(default_image_name));
+	}
+}
+
+
+// Updates the user's avatar's appearance
+//virtual
+void LLViewerWearable::writeToAvatar(LLAvatarAppearance *avatarp)
+{
+	LLVOAvatarSelf* viewer_avatar = dynamic_cast<LLVOAvatarSelf*>(avatarp);
+
+	if (!avatarp || !viewer_avatar) return;
+
+	if (!viewer_avatar->isValid()) return;
+
+#if 0
+	// FIXME DRANO - kludgy way to avoid overwriting avatar state from wearables.
+	// Ideally would avoid calling this func in the first place.
+	if (viewer_avatar->isUsingServerBakes() &&
+		!viewer_avatar->isUsingLocalAppearance())
+	{
+		return;
+	}
+#endif
+
+	ESex old_sex = avatarp->getSex();
+
+	LLWearable::writeToAvatar(avatarp);
+
+
+	// Pull texture entries
+	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			te_map_t::const_iterator iter = mTEMap.find(te);
+			LLUUID image_id;
+			if(iter != mTEMap.end())
+			{
+				image_id = iter->second->getID();
+			}
+			else
+			{	
+				image_id = getDefaultTextureImageID((ETextureIndex) te);
+			}
+			LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE );
+			// MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this.
+			viewer_avatar->setLocalTextureTE(te, image, 0);
+		}
+	}
+
+	ESex new_sex = avatarp->getSex();
+	if( old_sex != new_sex )
+	{
+		viewer_avatar->updateSexDependentLayerSets( FALSE );
+	}	
+	
+//	if( upload_bake )
+//	{
+//		gAgent.sendAgentSetAppearance();
+//	}
+}
+
+
+// Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values.
+// static 
+void LLViewerWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake )
+{
+	if (!isAgentAvatarValid()) return;
+
+	// You can't just remove body parts.
+	if( (type == LLWearableType::WT_SHAPE) ||
+		(type == LLWearableType::WT_SKIN) ||
+		(type == LLWearableType::WT_HAIR) ||
+		(type == LLWearableType::WT_EYES) )
+	{
+		return;
+	}
+
+	// Pull params
+	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
+	{
+		if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->isTweakable() ) )
+		{
+			S32 param_id = param->getID();
+			gAgentAvatarp->setVisualParamWeight( param_id, param->getDefaultWeight(), upload_bake );
+		}
+	}
+
+	if(gAgentCamera.cameraCustomizeAvatar())
+	{
+		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
+	}
+
+	gAgentAvatarp->updateVisualParams();
+	gAgentAvatarp->wearableUpdated(type, FALSE);
+
+//	if( upload_bake )
+//	{
+//		gAgent.sendAgentSetAppearance();
+//	}
+}
+
+// Does not copy mAssetID.
+// Definition version is current: removes obsolete enties and creates default values for new ones.
+void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)
+{
+	if (!isAgentAvatarValid()) return;
+
+	mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
+
+	mName = src->mName;
+	mDescription = src->mDescription;
+	mPermissions = src->mPermissions;
+	mSaleInfo = src->mSaleInfo;
+
+	setType(src->mType, gAgentAvatarp);
+
+	mSavedVisualParamMap.clear();
+	// Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed)
+	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
+		param;
+		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
+	{
+		if( (param->getWearableType() == mType) )
+		{
+			S32 id = param->getID();
+			F32 weight = src->getVisualParamWeight(id);
+			mSavedVisualParamMap[id] = weight;
+		}
+	}
+
+	destroyTextures();
+	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
+	for (S32 te = 0; te < TEX_NUM_INDICES; te++)
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			te_map_t::const_iterator iter = src->mTEMap.find(te);
+			LLUUID image_id;
+			LLViewerFetchedTexture *image = NULL;
+			if(iter != src->mTEMap.end())
+			{
+				image = dynamic_cast<LLViewerFetchedTexture*> (src->getLocalTextureObject(te)->getImage());
+				image_id = src->getLocalTextureObject(te)->getID();
+				mTEMap[te] = new LLLocalTextureObject(image, image_id);
+				mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
+				mTEMap[te]->setBakedReady(src->getLocalTextureObject(te)->getBakedReady());
+				mTEMap[te]->setDiscard(src->getLocalTextureObject(te)->getDiscard());
+			}
+			else
+			{
+				image_id = getDefaultTextureImageID((ETextureIndex) te);
+				image = LLViewerTextureManager::getFetchedTexture( image_id );
+				mTEMap[te] = new LLLocalTextureObject(image, image_id);
+				mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
+			}
+			createLayers(te, gAgentAvatarp);
+		}
+	}
+
+	// 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();
+}
+
+void LLViewerWearable::setItemID(const LLUUID& item_id)
+{
+	mItemID = item_id;
+}
+
+void LLViewerWearable::revertValues()
+{
+#if 0
+	// DRANO avoid overwrite when not in local appearance
+	if (isAgentAvatarValid() && gAgentAvatarp->isUsingServerBakes() && !gAgentAvatarp->isUsingLocalAppearance())
+	{
+		return;
+	}
+#endif
+	LLWearable::revertValues();
+
+
+	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+	if( panel )
+	{
+		panel->updateScrollingPanelList();
+	}
+}
+
+void LLViewerWearable::saveValues()
+{
+	LLWearable::saveValues();
+
+	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+	if( panel )
+	{
+		panel->updateScrollingPanelList();
+	}
+}
+
+// virtual
+void LLViewerWearable::setUpdated() const
+{ 
+	gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID());
+}
+
+void LLViewerWearable::refreshName()
+{
+	LLUUID item_id = getItemID();
+	LLInventoryItem* item = gInventory.getItem(item_id);
+	if( item )
+	{
+		mName = item->getName();
+	}
+}
+
+// virtual
+void LLViewerWearable::addToBakedTextureHash(LLMD5& hash) const
+{
+	LLUUID asset_id = getAssetID();
+	hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
+}
+
+struct LLWearableSaveData
+{
+	LLWearableType::EType mType;
+};
+
+void LLViewerWearable::saveNewAsset() const
+{
+//	llinfos << "LLViewerWearable::saveNewAsset() type: " << getTypeName() << llendl;
+	//llinfos << *this << llendl;
+
+	const std::string filename = asset_id_to_filename(mAssetID);
+	LLFILE* fp = LLFile::fopen(filename, "wb");		/* Flawfinder: ignore */
+	BOOL successful_save = FALSE;
+	if(fp && exportFile(fp))
+	{
+		successful_save = TRUE;
+	}
+	if(fp)
+	{
+		fclose(fp);
+		fp = NULL;
+	}
+	if(!successful_save)
+	{
+		std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str());
+		llwarns << buffer << llendl;
+		
+		LLSD args;
+		args["NAME"] = mName;
+		LLNotificationsUtil::add("CannotSaveWearableOutOfSpace", args);
+		return;
+	}
+
+	// save it out to database
+	if( gAssetStorage )
+	{
+		 /*
+		std::string url = gAgent.getRegion()->getCapability("NewAgentInventory");
+		if (!url.empty())
+		{
+			llinfos << "Update Agent Inventory via capability" << llendl;
+			LLSD body;
+			body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::assetToFolderType(getAssetType()));
+			body["asset_type"] = LLAssetType::lookup(getAssetType());
+			body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE);
+			body["name"] = getName();
+			body["description"] = getDescription();
+			LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename));
+		}
+		else
+		{
+		}
+		 */
+		 LLWearableSaveData* data = new LLWearableSaveData;
+		 data->mType = mType;
+		 gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(),
+                                     &LLViewerWearable::onSaveNewAssetComplete,
+                                     (void*)data);
+	}
+}
+
+// static
+void LLViewerWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
+{
+	LLWearableSaveData* data = (LLWearableSaveData*)userdata;
+	const std::string& type_name = LLWearableType::getTypeName(data->mType);
+	if(0 == status)
+	{
+		// Success
+		llinfos << "Saved wearable " << type_name << llendl;
+	}
+	else
+	{
+		std::string buffer = llformat("Unable to save %s to central asset store.", type_name.c_str());
+		llwarns << buffer << " Status: " << status << llendl;
+		LLSD args;
+		args["NAME"] = type_name;
+		LLNotificationsUtil::add("CannotSaveToAssetStore", args);
+	}
+
+	// Delete temp file
+	const std::string src_filename = asset_id_to_filename(new_asset_id);
+	LLFile::remove(src_filename);
+
+	// delete the context data
+	delete data;
+
+}
+
+std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w)
+{
+	s << "wearable " << LLWearableType::getTypeName(w.mType) << "\n";
+	s << "    Name: " << w.mName << "\n";
+	s << "    Desc: " << w.mDescription << "\n";
+	//w.mPermissions
+	//w.mSaleInfo
+
+	s << "    Params:" << "\n";
+	for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin();
+		 iter != w.mVisualParamIndexMap.end(); ++iter)
+	{
+		S32 param_id = iter->first;
+		LLVisualParam *wearable_param = iter->second;
+		F32 param_weight = wearable_param->getWeight();
+		s << "        " << param_id << " " << param_weight << "\n";
+	}
+
+	s << "    Textures:" << "\n";
+	for (LLViewerWearable::te_map_t::const_iterator iter = w.mTEMap.begin();
+		 iter != w.mTEMap.end(); ++iter)
+	{
+		S32 te = iter->first;
+		const LLUUID& image_id = iter->second->getID();
+		s << "        " << te << " " << image_id << "\n";
+	}
+	return s;
+}
+
+std::string asset_id_to_filename(const LLUUID &asset_id)
+{
+	std::string asset_id_string;
+	asset_id.toString(asset_id_string);
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl";	
+	return filename;
+}
diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h
new file mode 100644
index 0000000000000000000000000000000000000000..65566f23a5a9981d6b3a5dc7ecac34a5d8d12a6e
--- /dev/null
+++ b/indra/newview/llviewerwearable.h
@@ -0,0 +1,104 @@
+/** 
+ * @file llviewerwearable.h
+ * @brief LLViewerWearable class header file
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_VIEWER_WEARABLE_H
+#define LL_VIEWER_WEARABLE_H
+
+#include "llwearable.h"
+#include "llavatarappearancedefines.h"
+
+class LLVOAvatar;
+
+class LLViewerWearable : public LLWearable
+{
+	friend class LLWearableList;
+
+	//--------------------------------------------------------------------
+	// Constructors and destructors
+	//--------------------------------------------------------------------
+private:
+	// Private constructors used by LLViewerWearableList
+	LLViewerWearable(const LLTransactionID& transactionID);
+	LLViewerWearable(const LLAssetID& assetID);
+public:
+	virtual ~LLViewerWearable();
+
+	//--------------------------------------------------------------------
+	// Accessors
+	//--------------------------------------------------------------------
+public:
+	const LLUUID&				getItemID() const { return mItemID; }
+	const LLAssetID&			getAssetID() const { return mAssetID; }
+	const LLTransactionID&		getTransactionID() const { return mTransactionID; }
+	void						setItemID(const LLUUID& item_id);
+
+public:
+
+	BOOL				isDirty() const;
+	BOOL				isOldVersion() const;
+
+	/*virtual*/ void	writeToAvatar(LLAvatarAppearance *avatarp);
+	void				removeFromAvatar( BOOL upload_bake )	{ LLViewerWearable::removeFromAvatar( mType, upload_bake ); }
+	static void			removeFromAvatar( LLWearableType::EType type, BOOL upload_bake ); 
+
+	/*virtual*/ EImportResult	importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
+	
+	void				setParamsToDefaults();
+	void				setTexturesToDefaults();
+
+	/*virtual*/ LLUUID	getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const;
+
+
+	void				saveNewAsset() const;
+	static void			onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status );
+
+	void				copyDataFrom(const LLViewerWearable* src);
+
+	friend std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w);
+
+	/*virtual*/ void	revertValues();
+	/*virtual*/ void	saveValues();
+
+	// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
+	/*virtual*/void		setUpdated() const;
+
+	// the wearable was worn. make sure the name of the wearable object matches the LLViewerInventoryItem,
+	// not the wearable asset itself.
+	void				refreshName();
+
+	// Update the baked texture hash.
+	/*virtual*/void		addToBakedTextureHash(LLMD5& hash) const;
+
+protected:
+	LLAssetID			mAssetID;
+	LLTransactionID		mTransactionID;
+
+	LLUUID				mItemID;  // ID of the inventory item in the agent's inventory	
+};
+
+
+#endif  // LL_VIEWER_WEARABLE_H
+
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 4afd90b44c016fea130eba705047782ab2bbb1eb..0910b7536d40698e60d652c8d4aa38161b05f76a 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -383,7 +383,7 @@ class LLDebugText
 
 			if (isAgentAvatarValid())
 			{
-				tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition());
+				tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());
 				agent_root_center_text = llformat("AgentRootCenter %f %f %f",
 												  (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
 			}
@@ -1573,6 +1573,16 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	LLViewerWindow::sMovieBaseName = "SLmovie";
 	resetSnapshotLoc();
 
+
+	/*
+	LLWindowCallbacks* callbacks,
+	const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags,
+	BOOL fullscreen, 
+	BOOL clearBg,
+	BOOL disable_vsync,
+	BOOL ignore_pixel_depth,
+	U32 fsaa_samples)
+	*/
 	// create window
 	mWindow = LLWindowManager::createWindow(this,
 		p.title, p.name, p.x, p.y, p.width, p.height, 0,
@@ -2147,7 +2157,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
 
 		calcDisplayScale();
 	
-		BOOL display_scale_changed = mDisplayScale != LLUI::sGLScaleFactor;
+		BOOL display_scale_changed = mDisplayScale != LLUI::getScaleFactor();
 		LLUI::setScaleFactor(mDisplayScale);
 
 		// update our window rectangle
@@ -2353,7 +2363,7 @@ void LLViewerWindow::draw()
 		// scale view by UI global scale factor and aspect ratio correction factor
 		gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
 
-		LLVector2 old_scale_factor = LLUI::sGLScaleFactor;
+		LLVector2 old_scale_factor = LLUI::getScaleFactor();
 		// apply camera zoom transform (for high res screenshots)
 		F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
 		S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
@@ -2367,7 +2377,7 @@ void LLViewerWindow::draw()
 						(F32)getWindowHeightScaled() * -(F32)pos_y, 
 						0.f);
 			gGL.scalef(zoom_factor, zoom_factor, 1.f);
-			LLUI::sGLScaleFactor *= zoom_factor;
+			LLUI::getScaleFactor() *= zoom_factor;
 		}
 
 		// Draw tool specific overlay on world
@@ -2415,7 +2425,7 @@ void LLViewerWindow::draw()
 				LLFontGL::HCENTER, LLFontGL::TOP);
 		}
 
-		LLUI::sGLScaleFactor = old_scale_factor;
+		LLUI::setScaleFactor(old_scale_factor);
 	}
 	LLUI::popMatrix();
 	gGL.popMatrix();
@@ -3218,8 +3228,8 @@ void LLViewerWindow::updateLayout()
 
 void LLViewerWindow::updateMouseDelta()
 {
-	S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]);
-	S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]);
+	S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]);
+	S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]);
 
 	//RN: fix for asynchronous notification of mouse leaving window not working
 	LLCoordWindow mouse_pos;
@@ -4784,7 +4794,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
 		gResizeScreenTexture = TRUE;
 		gWindowResized = TRUE;
 
-		if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
+		if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())
 		{
 			LLVisualParamHint::requestHintUpdates();
 		}
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index abb515348068ace099458dd50e717898cd6f5b17..94760e3c8351ce1ec50bb40b707f2f8a0e6c89b6 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -223,7 +223,7 @@ BOOL LLVLComposition::generateComposition()
 	{
 		if (mDetailTextures[i]->getDiscardLevel() < 0)
 		{
-			mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail
+			mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
 			mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE);
 			return FALSE;
 		}
@@ -240,7 +240,7 @@ BOOL LLVLComposition::generateComposition()
 				ddiscard++;
 				min_dim /= 2;
 			}
-			mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail
+			mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
 			mDetailTextures[i]->setMinDiscardLevel(ddiscard);
 			return FALSE;
 		}
@@ -376,9 +376,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
 	LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
 	U8 *rawp = raw->getData();
 
-	F32 tex_width_inv = 1.f/tex_width;
-	F32 tex_height_inv = 1.f/tex_height;
-
 	F32 st_x_stride, st_y_stride;
 	st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width);
 	st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height);
@@ -413,11 +410,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
 			tex1 = tex0 + 1;
 			tex1 = llclamp(tex1, 0, 3);
 
-			F32 xy_int_i, xy_int_j;
-
-			xy_int_i = i * tex_width_inv;
-			xy_int_j = j * tex_height_inv;
-
 			st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps;
 			for (U32 k = 0; k < tex_comps; k++)
 			{
@@ -461,7 +453,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
 	for (S32 i = 0; i < 4; i++)
 	{
 		// Un-boost detatil textures (will get re-boosted if rendering in high detail)
-		mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_NONE);
+		mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_NONE);
 		mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1);
 	}
 	
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
old mode 100644
new mode 100755
index a3093f069dbb92ef4106b35f81b86b2bc1263f34..0475e9fc8922c490d1efa5c94589663ec497a193
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -24,18 +24,13 @@
  * $/LicenseInfo$
  */
 
-#if LL_MSVC
-// disable warning about boost::lexical_cast returning uninitialized data
-// when it fails to parse the string
-#pragma warning (disable:4701)
-#endif
-
 #include "llviewerprecompiledheaders.h"
 
 #include "llvoavatar.h"
 
 #include <stdio.h>
 #include <ctype.h>
+#include <sstream>
 
 #include "llaudioengine.h"
 #include "noise.h"
@@ -53,6 +48,7 @@
 #include "llcallingcard.h"		// IDEVO for LLAvatarTracker
 #include "lldrawpoolavatar.h"
 #include "lldriverparam.h"
+#include "llpolyskeletaldistortion.h"
 #include "lleditingmotion.h"
 #include "llemote.h"
 //#include "llfirstuse.h"
@@ -78,15 +74,16 @@
 #include "llselectmgr.h"
 #include "llsprite.h"
 #include "lltargetingmotion.h"
-#include "lltexlayer.h"
 #include "lltoolmorph.h"
 #include "llviewercamera.h"
+#include "llviewertexlayer.h"
 #include "llviewertexturelist.h"
 #include "llviewermenu.h"
 #include "llviewerobjectlist.h"
 #include "llviewerparcelmgr.h"
 #include "llviewershadermgr.h"
 #include "llviewerstats.h"
+#include "llviewerwearable.h"
 #include "llvoavatarself.h"
 #include "llvovolume.h"
 #include "llworld.h"
@@ -103,22 +100,17 @@
 
 #include "lldebugmessagebox.h"
 #include "llsdutil.h"
+#include "llsdserialize.h"
 
 extern F32 SPEED_ADJUST_MAX;
 extern F32 SPEED_ADJUST_MAX_SEC;
 extern F32 ANIM_SPEED_MAX;
 extern F32 ANIM_SPEED_MIN;
 
-#if LL_MSVC
-// disable boost::lexical_cast warning
-#pragma warning (disable:4702)
-#endif
-
-#include <boost/lexical_cast.hpp>
 
 // #define OUTPUT_BREAST_DATA
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 //-----------------------------------------------------------------------------
 // Global constants
@@ -139,7 +131,6 @@ const LLUUID ANIM_AGENT_PHYSICS_MOTION = LLUUID("7360e029-3cb8-ebc4-863e-212df44
 //-----------------------------------------------------------------------------
 // Constants
 //-----------------------------------------------------------------------------
-const std::string AVATAR_DEFAULT_CHAR = "avatar";
 
 const S32 MIN_PIXEL_AREA_FOR_COMPOSITE = 1024;
 const F32 SHADOW_OFFSET_AMT = 0.03f;
@@ -196,8 +187,6 @@ const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f;
 const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f;
 const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f;
 
-const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
-
 enum ERenderName
 {
 	RENDER_NAME_NEVER,
@@ -244,6 +233,24 @@ struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarColli
 							scale;
 };
 
+struct LLAppearanceMessageContents
+{
+	LLAppearanceMessageContents():
+		mAppearanceVersion(-1),
+		mParamAppearanceVersion(-1),
+		mCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)
+	{
+	}
+	LLTEContents mTEContents;
+	S32 mAppearanceVersion;
+	S32 mParamAppearanceVersion;
+	S32 mCOFVersion;
+	// For future use:
+	//U32 appearance_flags = 0;
+	std::vector<F32> mParamWeights;
+	std::vector<LLVisualParam*> mParams;
+};
+
 struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>
 	{
 	Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> >	bone;
@@ -255,6 +262,8 @@ struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoi
 	{}
 };
 
+	
+
 struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo>
 {
 	LLVOAvatarBoneInfo() 
@@ -284,6 +293,8 @@ struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo
 	Mandatory<LLVOAvatarChildJoint>	skeleton_root;
 };
 
+
+
 //-----------------------------------------------------------------------------
 // class LLBodyNoiseMotion
 //-----------------------------------------------------------------------------
@@ -605,11 +616,7 @@ class LLPelvisFixMotion :
 //-----------------------------------------------------------------------------
 // Static Data
 //-----------------------------------------------------------------------------
-LLXmlTree LLVOAvatar::sXMLTree;
-LLXMLNodePtr LLVOAvatar::sSkeletonXMLTree;
-LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL;
-LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL;
-LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL;
+LLAvatarAppearanceDictionary *LLVOAvatar::sAvatarDictionary = NULL;
 S32 LLVOAvatar::sFreezeCounter = 0;
 U32 LLVOAvatar::sMaxVisible = 12;
 F32 LLVOAvatar::sRenderDistance = 256.f;
@@ -656,15 +663,13 @@ static F32 calc_bouncy_animation(F32 x);
 LLVOAvatar::LLVOAvatar(const LLUUID& id,
 					   const LLPCode pcode,
 					   LLViewerRegion* regionp) :
+	LLAvatarAppearance(&gAgentWearables),
 	LLViewerObject(id, pcode, regionp),
-	mIsDummy(FALSE),
 	mSpecialRenderMode(0),
 	mAttachmentGeometryBytes(0),
 	mAttachmentSurfaceArea(0.f),
 	mTurning(FALSE),
-	mPelvisToFoot(0.f),
 	mLastSkeletonSerialNum( 0 ),
-	mHeadOffset(),
 	mIsSitting(FALSE),
 	mTimeVisible(),
 	mTyping(FALSE),
@@ -689,9 +694,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	mFirstAppearanceMessageReceived( FALSE ),
 	mCulled( FALSE ),
 	mVisibilityRank(0),
-	mTexSkinColor( NULL ),
-	mTexHairColor( NULL ),
-	mTexEyeColor( NULL ),
 	mNeedsSkin(FALSE),
 	mLastSkinTime(0.f),
 	mUpdatePeriod(1),
@@ -699,12 +701,15 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	mFullyLoaded(FALSE),
 	mPreviousFullyLoaded(FALSE),
 	mFullyLoadedInitialized(FALSE),
-	mSupportsAlphaLayers(FALSE),
 	mLoadedCallbacksPaused(FALSE),
 	mHasPelvisOffset( FALSE ),
 	mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar")),
-	mLastRezzedStatus(-1)
-
+	mLastRezzedStatus(-1),
+	mIsEditingAppearance(FALSE),
+	mUseLocalAppearance(FALSE),
+	mUseServerBakes(FALSE), // FIXME DRANO consider using boost::optional, defaulting to unknown.
+	mLastUpdateRequestCOFVersion(-1),
+	mLastUpdateReceivedCOFVersion(-1)
 {
 	//VTResume();  // VTune
 	
@@ -716,28 +721,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 
 	mPelvisp = NULL;
 
-	mBakedTextureDatas.resize(BAKED_NUM_INDICES);
-	for (U32 i = 0; i < mBakedTextureDatas.size(); i++ )
-	{
-		mBakedTextureDatas[i].mLastTextureIndex = IMG_DEFAULT_AVATAR;
-		mBakedTextureDatas[i].mTexLayerSet = NULL;
-		mBakedTextureDatas[i].mIsLoaded = false;
-		mBakedTextureDatas[i].mIsUsed = false;
-		mBakedTextureDatas[i].mMaskTexName = 0;
-		mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i);
-	}
-
 	mDirtyMesh = 2;	// Dirty geometry, need to regenerate.
 	mMeshTexturesDirty = FALSE;
 	mHeadp = NULL;
 
-	mIsBuilt = FALSE;
-
-	mNumJoints = 0;
-	mSkeleton = NULL;
-
-	mNumCollisionVolumes = 0;
-	mCollisionVolumes = NULL;
 
 	// set up animation variables
 	mSpeed = 0.f;
@@ -824,50 +811,13 @@ LLVOAvatar::~LLVOAvatar()
 		debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");
 		}
 
+	logPendingPhases();
+	
 	lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
 
-	mRoot.removeAllChildren();
-	mJointMap.clear();
-
-	deleteAndClearArray(mSkeleton);
-	deleteAndClearArray(mCollisionVolumes);
-
-	mNumJoints = 0;
-
-	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
-	{
-		deleteAndClear(mBakedTextureDatas[i].mTexLayerSet);
-		mBakedTextureDatas[i].mMeshes.clear();
-
-		for (morph_list_t::iterator iter2 = mBakedTextureDatas[i].mMaskedMorphs.begin();
-			 iter2 != mBakedTextureDatas[i].mMaskedMorphs.end(); iter2++)
-		{
-			LLMaskedMorph* masked_morph = (*iter2);
-			delete masked_morph;
-		}
-	}
-
 	std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());
 	mAttachmentPoints.clear();
 
-	deleteAndClear(mTexSkinColor);
-	deleteAndClear(mTexHairColor);
-	deleteAndClear(mTexEyeColor);
-
-	std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer());
-	mMeshes.clear();
-
-	for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin();
-		 jointIter != mMeshLOD.end(); 
-		 ++jointIter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint *) *jointIter;
-		std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer());
-		joint->mMeshParts.clear();
-	}
-	std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer());
-	mMeshLOD.clear();
-	
 	mDead = TRUE;
 	
 	mAnimationSources.clear();
@@ -912,7 +862,7 @@ BOOL LLVOAvatar::isFullyTextured() const
 {
 	for (S32 i = 0; i < mMeshLOD.size(); i++)
 	{
-		LLViewerJoint* joint = (LLViewerJoint*) mMeshLOD[i];
+		LLAvatarJoint* joint = mMeshLOD[i];
 		if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT))
 		{
 			continue; // don't care about skirt textures if we're not wearing one.
@@ -921,19 +871,19 @@ BOOL LLVOAvatar::isFullyTextured() const
 		{
 			continue; // nonexistent LOD OK.
 		}
-		std::vector<LLViewerJointMesh*>::iterator meshIter = joint->mMeshParts.begin();
+		avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin();
 		if (meshIter != joint->mMeshParts.end())
 		{
-			LLViewerJointMesh *mesh = (LLViewerJointMesh *) *meshIter;
+			LLAvatarJointMesh *mesh = (*meshIter);
 			if (!mesh)
 			{
 				continue; // nonexistent mesh OK
 			}
-			if (mesh->mTexture.notNull() && mesh->mTexture->hasGLTexture())
+			if (mesh->hasGLTexture())
 			{
 				continue; // Mesh exists and has a baked texture.
 			}
-			if (mesh->mLayerSet && mesh->mLayerSet->hasComposite())
+			if (mesh->hasComposite())
 			{
 				continue; // Mesh exists and has a composite texture.
 			}
@@ -952,6 +902,7 @@ BOOL LLVOAvatar::hasGray() const
 S32 LLVOAvatar::getRezzedStatus() const
 {
 	if (getIsCloud()) return 0;
+	if (isFullyTextured() && allBakedTexturesCompletelyDownloaded()) return 3;
 	if (isFullyTextured()) return 2;
 	llassert(hasGray());
 	return 1; // gray
@@ -1007,7 +958,7 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)
 void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts)
 {
 	counts.clear();
-	counts.resize(3);
+	counts.resize(4);
 	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
 		 iter != LLCharacter::sInstances.end(); ++iter)
 	{
@@ -1025,6 +976,7 @@ std::string LLVOAvatar::rezStatusToString(S32 rez_status)
 	if (rez_status==0) return "cloud";
 	if (rez_status==1) return "gray";
 	if (rez_status==2) return "textured";
+	if (rez_status==3) return "textured_and_downloaded";
 	return "unknown";
 }
 
@@ -1086,15 +1038,15 @@ void LLVOAvatar::dumpBakedStatus()
 		{
 			llcont << " Unbaked (";
 			
-			for (LLVOAvatarDictionary::BakedTextures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-				 iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+			for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+				 iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 				 ++iter)
 			{
-				const LLVOAvatarDictionary::BakedEntry *baked_dict = iter->second;
+				const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = iter->second;
 				const ETextureIndex index = baked_dict->mTextureIndex;
 				if (!inst->isTextureDefined(index))
 				{
-					llcont << " " << LLVOAvatarDictionary::getInstance()->getTexture(index)->mName;
+					llcont << " " << LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mName;
 				}
 			}
 			llcont << " ) " << inst->getUnbakedPixelAreaRank();
@@ -1115,7 +1067,7 @@ void LLVOAvatar::restoreGL()
 	gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
 	for (U32 i = 0; i < gAgentAvatarp->mBakedTextureDatas.size(); i++)
 	{
-		gAgentAvatarp->invalidateComposite(gAgentAvatarp->mBakedTextureDatas[i].mTexLayerSet, FALSE);
+		gAgentAvatarp->invalidateComposite(gAgentAvatarp->getTexLayerSet(i), FALSE);
 	}
 	gAgentAvatarp->updateMeshTextures();
 }
@@ -1142,7 +1094,7 @@ void LLVOAvatar::resetImpostors()
 // static
 void LLVOAvatar::deleteCachedImages(bool clearAll)
 {	
-	if (LLTexLayerSet::sHasCaches)
+	if (LLViewerTexLayerSet::sHasCaches)
 	{
 		lldebugs << "Deleting layer set caches" << llendl;
 		for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
@@ -1151,7 +1103,7 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)
 			LLVOAvatar* inst = (LLVOAvatar*) *iter;
 			inst->deleteLayerSetCaches(clearAll);
 		}
-		LLTexLayerSet::sHasCaches = FALSE;
+		LLViewerTexLayerSet::sHasCaches = FALSE;
 	}
 	LLVOAvatarSelf::deleteScratchTextures();
 	LLTexLayerStaticImageList::getInstance()->deleteCachedImages();
@@ -1164,97 +1116,6 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)
 //------------------------------------------------------------------------
 void LLVOAvatar::initClass()
 { 
-	std::string xmlFile;
-
-	xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml";
-	BOOL success = sXMLTree.parseFile( xmlFile, FALSE );
-	if (!success)
-	{
-		llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl;
-	}
-
-	// now sanity check xml file
-	LLXmlTreeNode* root = sXMLTree.getRoot();
-	if (!root) 
-	{
-		llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl;
-		return;
-	}
-
-	//-------------------------------------------------------------------------
-	// <linden_avatar version="1.0"> (root)
-	//-------------------------------------------------------------------------
-	if( !root->hasName( "linden_avatar" ) )
-	{
-		llerrs << "Invalid avatar file header: " << xmlFile << llendl;
-	}
-	
-	std::string version;
-	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
-	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
-	{
-		llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl;
-	}
-
-	S32 wearable_def_version = 1;
-	static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version");
-	root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version );
-	LLWearable::setCurrentDefinitionVersion( wearable_def_version );
-
-	std::string mesh_file_name;
-
-	LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" );
-	if (!skeleton_node)
-	{
-		llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl;
-		return;
-	}
-	
-	std::string skeleton_file_name;
-	static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
-	if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name))
-	{
-		llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl;
-	}
-	
-	std::string skeleton_path;
-	skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name);
-	if (!parseSkeletonFile(skeleton_path))
-	{
-		llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;
-	}
-
-	// parse avatar_lad.xml
-	if (sAvatarXmlInfo)
-	{ //this can happen if a login attempt failed
-		deleteAndClear(sAvatarXmlInfo);
-	}
-	sAvatarXmlInfo = new LLVOAvatarXmlInfo;
-	if (!sAvatarXmlInfo->parseXmlSkeletonNode(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-	if (!sAvatarXmlInfo->parseXmlMeshNodes(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-	if (!sAvatarXmlInfo->parseXmlColorNodes(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-	if (!sAvatarXmlInfo->parseXmlLayerNodes(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-	if (!sAvatarXmlInfo->parseXmlDriverNodes(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-	if (!sAvatarXmlInfo->parseXmlMorphNodes(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-
 	gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise");
 	gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot");
 	gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION,"physics_motion");
@@ -1271,84 +1132,11 @@ void LLVOAvatar::initClass()
 
 void LLVOAvatar::cleanupClass()
 {
-	deleteAndClear(sAvatarXmlInfo);
-	sSkeletonXMLTree = NULL;
-	sXMLTree.cleanup();
 }
 
+// virtual
 void LLVOAvatar::initInstance(void)
 {
-	//-------------------------------------------------------------------------
-	// initialize joint, mesh and shape members
-	//-------------------------------------------------------------------------
-	mRoot.setName( "mRoot" );
-	
-	for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
-		 ++iter)
-	{
-		const EMeshIndex mesh_index = iter->first;
-		const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second;
-		LLViewerJoint* joint = new LLViewerJoint();
-		joint->setName(mesh_dict->mName);
-		joint->setMeshID(mesh_index);
-		mMeshLOD.push_back(joint);
-		
-		/* mHairLOD.setName("mHairLOD");
-		   mHairMesh0.setName("mHairMesh0");
-		   mHairMesh0.setMeshID(MESH_ID_HAIR);
-		   mHairMesh1.setName("mHairMesh1"); */
-		for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
-		{
-			LLViewerJointMesh* mesh = new LLViewerJointMesh();
-			std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast<std::string>(lod);
-			// We pre-pended an m - need to capitalize first character for camelCase
-			mesh_name[1] = toupper(mesh_name[1]);
-			mesh->setName(mesh_name);
-			mesh->setMeshID(mesh_index);
-			mesh->setPickName(mesh_dict->mPickName);
-			mesh->setIsTransparent(FALSE);
-			switch((int)mesh_index)
-			{
-				case MESH_ID_HAIR:
-					mesh->setIsTransparent(TRUE);
-					break;
-				case MESH_ID_SKIRT:
-					mesh->setIsTransparent(TRUE);
-					break;
-				case MESH_ID_EYEBALL_LEFT:
-				case MESH_ID_EYEBALL_RIGHT:
-					mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
-					break;
-			}
-			
-			joint->mMeshParts.push_back(mesh);
-		}
-	}
-	
-	//-------------------------------------------------------------------------
-	// associate baked textures with meshes
-	//-------------------------------------------------------------------------
-	for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
-		 ++iter)
-	{
-		const EMeshIndex mesh_index = iter->first;
-		const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second;
-		const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID;
-		// Skip it if there's no associated baked texture.
-		if (baked_texture_index == BAKED_NUM_INDICES) continue;
-		
-		for (std::vector<LLViewerJointMesh* >::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();
-			 iter != mMeshLOD[mesh_index]->mMeshParts.end(); 
-			 ++iter)
-		{
-			LLViewerJointMesh* mesh = (LLViewerJointMesh*) *iter;
-			mBakedTextureDatas[(int)baked_texture_index].mMeshes.push_back(mesh);
-		}
-	}
-	
-	
 	//-------------------------------------------------------------------------
 	// register motions
 	//-------------------------------------------------------------------------
@@ -1407,10 +1195,9 @@ void LLVOAvatar::initInstance(void)
 		registerMotion( ANIM_AGENT_SIT_FEMALE,				LLKeyframeMotion::create );
 		registerMotion( ANIM_AGENT_TARGET,					LLTargetingMotion::create );
 		registerMotion( ANIM_AGENT_WALK_ADJUST,				LLWalkAdjustMotion::create );
-		
 	}
-	
-	buildCharacter();
+
+	LLAvatarAppearance::initInstance();
 	
 	// preload specific motions here
 	createMotion( ANIM_AGENT_CUSTOMIZE);
@@ -1419,7 +1206,30 @@ void LLVOAvatar::initInstance(void)
 	//VTPause();  // VTune
 	
 	mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) );
+}
+
+// virtual
+LLAvatarJoint* LLVOAvatar::createAvatarJoint()
+{
+	return new LLViewerJoint();
+}
+
+// virtual
+LLAvatarJoint* LLVOAvatar::createAvatarJoint(S32 joint_num)
+{
+	return new LLViewerJoint(joint_num);
+}
+
+// virtual
+LLAvatarJointMesh* LLVOAvatar::createAvatarJointMesh()
+{
+	return new LLViewerJointMesh();
+}
 
+// virtual
+LLTexLayerSet* LLVOAvatar::createTexLayerSet()
+{
+	return new LLViewerTexLayerSet(this);
 }
 
 const LLVector3 LLVOAvatar::getRenderPosition() const
@@ -1494,7 +1304,7 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
 	float max_attachment_span = get_default_max_prim_scale() * 5.0f;
 	
 	//stretch bounding box by joint positions
-	for (polymesh_map_t::iterator i = mMeshes.begin(); i != mMeshes.end(); ++i)
+	for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i)
 	{
 		LLPolyMesh* mesh = i->second;
 		for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++)
@@ -1732,149 +1542,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
 	return hit;
 }
 
-//-----------------------------------------------------------------------------
-// parseSkeletonFile()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)
-{
-	//-------------------------------------------------------------------------
-	// parse the file
-	//-------------------------------------------------------------------------
-
-	LLXMLNodePtr skeleton_xml;
-	BOOL parsesuccess = LLXMLNode::parseFile(filename, skeleton_xml, NULL);
-
-	if (!parsesuccess || skeleton_xml.isNull())
-	{
-		llerrs << "Can't parse skeleton file: " << filename << llendl;
-		return FALSE;
-	}
-
-	// Process XML data
-	if (sAvatarSkeletonInfo)
-	{ //this can happen if a login attempt failed
-		delete sAvatarSkeletonInfo;
-	}
-	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo;
-
-	LLXUIParser parser;
-	parser.readXUI(skeleton_xml, *sAvatarSkeletonInfo, filename);
-	if (!sAvatarSkeletonInfo->validateBlock())
-	{
-		llerrs << "Error parsing skeleton XML file: " << filename << llendl;
-	}
-
-	if( !skeleton_xml->hasName( "linden_skeleton" ) )
-	{
-		llerrs << "Invalid avatar skeleton file header: " << filename << llendl;
-		return FALSE;
-	}
-
-	if (sAvatarSkeletonInfo->version() != "1.0")
-	{
-		llerrs << "Invalid avatar skeleton file version: " << sAvatarSkeletonInfo->version() << " in file: " << filename << llendl;
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// setupBone()
-//-----------------------------------------------------------
-BOOL LLVOAvatar::setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num)
-{
-	LLViewerJoint* joint = NULL;
-	if (info.bone.isChosen())
-	{
-		joint = (LLViewerJoint*)getCharacterJoint(joint_num);
-		if (!joint)
-		{
-			llwarns << "Too many bones" << llendl;
-			return FALSE;
-		}
-		joint->setName( info.bone().name );
-		joint->setPosition(info.bone().pos);
-		joint->setRotation(mayaQ(info.bone().rot().mV[VX], info.bone().rot().mV[VY], info.bone().rot().mV[VZ], LLQuaternion::XYZ));
-		joint->setScale(info.bone().scale);
-		joint->setSkinOffset( info.bone().pivot );
-		joint_num++;
-
-		for (LLInitParam::ParamIterator<LLVOAvatarChildJoint>::const_iterator child_it = info.bone().children.begin(),
-				end_it = info.bone().children.end();
-			child_it != end_it;
-			++child_it)
-		{
-			if (!setupBone(*child_it, joint, volume_num, joint_num))
-			{
-				return FALSE;
-			}
-	}
-	}
-	else // collision volume
-	{
-		if (volume_num >= (S32)mNumCollisionVolumes)
-		{
-			llwarns << "Too many bones" << llendl;
-			return FALSE;
-		}
-		joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]);
-		joint->setName( info.collision_volume.name);
-		joint->setPosition(info.collision_volume.pos);
-		joint->setRotation(mayaQ(info.collision_volume.rot().mV[VX], info.collision_volume.rot().mV[VY], info.collision_volume.rot().mV[VZ], LLQuaternion::XYZ));
-		joint->setScale(info.collision_volume.scale);
-		volume_num++;
-	}
-
-	// add to parent
-	if (parent)
-	{
-		parent->addChild( joint );
-	}
-
-	joint->setDefaultFromCurrentXform();
-	
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// buildSkeleton()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)
-{
-	//-------------------------------------------------------------------------
-	// allocate joints
-	//-------------------------------------------------------------------------
-	if (!allocateCharacterJoints(info->num_bones))
-	{
-		llerrs << "Can't allocate " << info->num_bones() << " joints" << llendl;
-		return FALSE;
-	}
 	
-	//-------------------------------------------------------------------------
-	// allocate volumes
-	//-------------------------------------------------------------------------
-	if (info->num_collision_volumes)
-	{
-		if (!allocateCollisionVolumes(info->num_collision_volumes))
-		{
-			llerrs << "Can't allocate " << info->num_collision_volumes() << " collision volumes" << llendl;
-			return FALSE;
-		}
-	}
-
-	S32 current_joint_num = 0;
-	S32 current_volume_num = 0;
-
-	if (!setupBone(info->skeleton_root, NULL, current_volume_num, current_joint_num))
-	{
-			llerrs << "Error parsing bone in skeleton file" << llendl;
-			return FALSE;
-		}
-
-	return TRUE;
-}
-
 LLVOAvatar* LLVOAvatar::asAvatar()
 {
 	return this;
@@ -1906,113 +1574,14 @@ void LLVOAvatar::startDefaultMotions()
 // LLVOAvatar::buildCharacter()
 // Deferred initialization and rebuild of the avatar.
 //-----------------------------------------------------------------------------
+// virtual
 void LLVOAvatar::buildCharacter()
 {
-	//-------------------------------------------------------------------------
-	// remove all references to our existing skeleton
-	// so we can rebuild it
-	//-------------------------------------------------------------------------
-	flushAllMotions();
+	LLAvatarAppearance::buildCharacter();
 
-	//-------------------------------------------------------------------------
-	// remove all of mRoot's children
-	//-------------------------------------------------------------------------
-	mRoot.removeAllChildren();
-	mJointMap.clear();
+	// Not done building yet; more to do.
 	mIsBuilt = FALSE;
 
-	//-------------------------------------------------------------------------
-	// clear mesh data
-	//-------------------------------------------------------------------------
-	for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin();
-		 jointIter != mMeshLOD.end(); ++jointIter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*) *jointIter;
-		for (std::vector<LLViewerJointMesh*>::iterator meshIter = joint->mMeshParts.begin();
-			 meshIter != joint->mMeshParts.end(); ++meshIter)
-		{
-			LLViewerJointMesh * mesh = (LLViewerJointMesh *) *meshIter;
-			mesh->setMesh(NULL);
-		}
-	}
-
-	//-------------------------------------------------------------------------
-	// (re)load our skeleton and meshes
-	//-------------------------------------------------------------------------
-	LLTimer timer;
-
-	BOOL status = loadAvatar();
-	stop_glerror();
-
-// 	gPrintMessagesThisFrame = TRUE;
-	lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl;
-
-	if (!status)
-	{
-		if (isSelf())
-		{
-			llerrs << "Unable to load user's avatar" << llendl;
-		}
-		else
-		{
-			llwarns << "Unable to load other's avatar" << llendl;
-		}
-		return;
-	}
-
-	//-------------------------------------------------------------------------
-	// initialize "well known" joint pointers
-	//-------------------------------------------------------------------------
-	mPelvisp		= (LLViewerJoint*)mRoot.findJoint("mPelvis");
-	mTorsop			= (LLViewerJoint*)mRoot.findJoint("mTorso");
-	mChestp			= (LLViewerJoint*)mRoot.findJoint("mChest");
-	mNeckp			= (LLViewerJoint*)mRoot.findJoint("mNeck");
-	mHeadp			= (LLViewerJoint*)mRoot.findJoint("mHead");
-	mSkullp			= (LLViewerJoint*)mRoot.findJoint("mSkull");
-	mHipLeftp		= (LLViewerJoint*)mRoot.findJoint("mHipLeft");
-	mHipRightp		= (LLViewerJoint*)mRoot.findJoint("mHipRight");
-	mKneeLeftp		= (LLViewerJoint*)mRoot.findJoint("mKneeLeft");
-	mKneeRightp		= (LLViewerJoint*)mRoot.findJoint("mKneeRight");
-	mAnkleLeftp		= (LLViewerJoint*)mRoot.findJoint("mAnkleLeft");
-	mAnkleRightp	= (LLViewerJoint*)mRoot.findJoint("mAnkleRight");
-	mFootLeftp		= (LLViewerJoint*)mRoot.findJoint("mFootLeft");
-	mFootRightp		= (LLViewerJoint*)mRoot.findJoint("mFootRight");
-	mWristLeftp		= (LLViewerJoint*)mRoot.findJoint("mWristLeft");
-	mWristRightp	= (LLViewerJoint*)mRoot.findJoint("mWristRight");
-	mEyeLeftp		= (LLViewerJoint*)mRoot.findJoint("mEyeLeft");
-	mEyeRightp		= (LLViewerJoint*)mRoot.findJoint("mEyeRight");
-
-	//-------------------------------------------------------------------------
-	// Make sure "well known" pointers exist
-	//-------------------------------------------------------------------------
-	if (!(mPelvisp && 
-		  mTorsop &&
-		  mChestp &&
-		  mNeckp &&
-		  mHeadp &&
-		  mSkullp &&
-		  mHipLeftp &&
-		  mHipRightp &&
-		  mKneeLeftp &&
-		  mKneeRightp &&
-		  mAnkleLeftp &&
-		  mAnkleRightp &&
-		  mFootLeftp &&
-		  mFootRightp &&
-		  mWristLeftp &&
-		  mWristRightp &&
-		  mEyeLeftp &&
-		  mEyeRightp))
-	{
-		llerrs << "Failed to create avatar." << llendl;
-		return;
-	}
-
-	//-------------------------------------------------------------------------
-	// initialize the pelvis
-	//-------------------------------------------------------------------------
-	mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) );
-	
 	//-------------------------------------------------------------------------
 	// set head offset from pelvis
 	//-------------------------------------------------------------------------
@@ -2065,11 +1634,11 @@ void LLVOAvatar::releaseMeshData()
 	//llinfos << "Releasing" << llendl;
 
 	// cleanup mesh data
-	for (std::vector<LLViewerJoint*>::iterator iter = mMeshLOD.begin();
+	for (avatar_joint_list_t::iterator iter = mMeshLOD.begin();
 		 iter != mMeshLOD.end(); 
 		 ++iter)
 	{
-		LLViewerJoint* joint = (LLViewerJoint*) *iter;
+		LLAvatarJoint* joint = (*iter);
 		joint->setValid(FALSE, TRUE);
 	}
 
@@ -2158,7 +1727,11 @@ void LLVOAvatar::updateMeshData()
 				last_v_num = num_vertices ;
 				last_i_num = num_indices ;
 
-				mMeshLOD[part_index++]->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
+				LLViewerJoint* part_mesh = getViewerJoint(part_index++);
+				if (part_mesh)
+				{
+					part_mesh->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
+				}
 			}
 			if(num_vertices < 1)//skip empty meshes
 			{
@@ -2232,7 +1805,11 @@ void LLVOAvatar::updateMeshData()
 					rigid = true;
 				}
 				
-				mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid);
+				LLViewerJoint* mesh = getViewerJoint(k);
+				if (mesh)
+				{
+					mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid);
+				}
 			}
 
 			stop_glerror();
@@ -2253,84 +1830,17 @@ void LLVOAvatar::updateMeshData()
 //------------------------------------------------------------------------
 
 //------------------------------------------------------------------------
-// The viewer can only suggest a good size for the agent,
-// the simulator will keep it inside a reasonable range.
-void LLVOAvatar::computeBodySize() 
+// LLVOAvatar::processUpdateMessage()
+//------------------------------------------------------------------------
+U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
+									 void **user_data,
+									 U32 block_num, const EObjectUpdateType update_type,
+									 LLDataPacker *dp)
 {
-	LLVector3 pelvis_scale = mPelvisp->getScale();
-
-	// some of the joints have not been cached
-	LLVector3 skull = mSkullp->getPosition();
-	LLVector3 skull_scale = mSkullp->getScale();
-
-	LLVector3 neck = mNeckp->getPosition();
-	LLVector3 neck_scale = mNeckp->getScale();
-
-	LLVector3 chest = mChestp->getPosition();
-	LLVector3 chest_scale = mChestp->getScale();
+	const BOOL has_name = !getNVPair("FirstName");
 
-	// the rest of the joints have been cached
-	LLVector3 head = mHeadp->getPosition();
-	LLVector3 head_scale = mHeadp->getScale();
-
-	LLVector3 torso = mTorsop->getPosition();
-	LLVector3 torso_scale = mTorsop->getScale();
-
-	LLVector3 hip = mHipLeftp->getPosition();
-	LLVector3 hip_scale = mHipLeftp->getScale();
-
-	LLVector3 knee = mKneeLeftp->getPosition();
-	LLVector3 knee_scale = mKneeLeftp->getScale();
-
-	LLVector3 ankle = mAnkleLeftp->getPosition();
-	LLVector3 ankle_scale = mAnkleLeftp->getScale();
-
-	LLVector3 foot  = mFootLeftp->getPosition();
-
-	mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
-				 	knee.mV[VZ] * hip_scale.mV[VZ] -
-				 	ankle.mV[VZ] * knee_scale.mV[VZ] -
-				 	foot.mV[VZ] * ankle_scale.mV[VZ];
-
-	LLVector3 new_body_size;
-	new_body_size.mV[VZ] = mPelvisToFoot +
-					   // the sqrt(2) correction below is an approximate
-					   // correction to get to the top of the head
-					   F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) + 
-					   head.mV[VZ] * neck_scale.mV[VZ] + 
-					   neck.mV[VZ] * chest_scale.mV[VZ] + 
-					   chest.mV[VZ] * torso_scale.mV[VZ] + 
-					   torso.mV[VZ] * pelvis_scale.mV[VZ]; 
-
-	// TODO -- measure the real depth and width
-	new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
-	new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
-
-	if (new_body_size != mBodySize)
-	{
-		mBodySize = new_body_size;
-
-		if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF())
-		{	// notify simulator of change in size
-			// but not if we are in the middle of updating appearance
-			gAgent.sendAgentSetAppearance();
-		}
-	}
-}
-
-//------------------------------------------------------------------------
-// LLVOAvatar::processUpdateMessage()
-//------------------------------------------------------------------------
-U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
-									 void **user_data,
-									 U32 block_num, const EObjectUpdateType update_type,
-									 LLDataPacker *dp)
-{
-	LLVector3 old_vel = getVelocity();
-	const BOOL has_name = !getNVPair("FirstName");
-
-	// Do base class updates...
-	U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
+	// Do base class updates...
+	U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
 
 	// Print out arrival information once we have name of avatar.
 		if (has_name && getNVPair("FirstName"))
@@ -2354,20 +1864,50 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
 	return retval;
 }
 
-// virtual
-S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
+LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUUID& uuid)
 {
-	// The core setTETexture() method requests images, so we need
-	// to redirect certain avatar texture requests to different sims.
-	if (isIndexBakedTexture((ETextureIndex)te))
+	LLViewerFetchedTexture *result = NULL;
+
+	if (uuid == IMG_DEFAULT_AVATAR ||
+		uuid == IMG_DEFAULT ||
+		uuid == IMG_INVISIBLE)
 	{
-		LLHost target_host = getObjectHost();
-		return setTETextureCore(te, uuid, target_host);
+		// Should already exist, don't need to find it on sim or baked-texture host.
+		result = gTextureList.findImage(uuid);
 	}
-	else
+
+	if (!result)
 	{
-		return setTETextureCore(te, uuid, LLHost::invalid);
+		const std::string url = getImageURL(te,uuid);
+		if (!url.empty())
+		{
+			LL_DEBUGS("Avatar") << avString() << "from URL " << url << llendl;
+			result = LLViewerTextureManager::getFetchedTextureFromUrl(
+				url, FTT_SERVER_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid);
+		}
+		else
+		{
+			LL_DEBUGS("Avatar") << avString() << "from host " << uuid << llendl;
+			LLHost host = getObjectHost();
+			result = LLViewerTextureManager::getFetchedTexture(
+				uuid, FTT_HOST_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
+		}
+	}
+	return result;
+}
+
+// virtual
+S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
+{
+	if (!isIndexBakedTexture((ETextureIndex)te))
+	{
+		// Sim still sends some uuids for non-baked slots sometimes - ignore.
+		return LLViewerObject::setTETexture(te, LLUUID::null);
 	}
+
+	LLViewerFetchedTexture *image = getBakedTextureImage(te,uuid);
+	llassert(image);
+	return setTETextureCore(te, image);
 }
 
 static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Avatar Update");
@@ -2413,7 +1953,8 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 		return;
 	}	
 
- 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)))
+	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))
+		&& !(gSavedSettings.getBOOL("DisableAllRenderTypes")))
 	{
 		return;
 	}
@@ -2478,7 +2019,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 	
 	// animate the character
 	// store off last frame's root position to be consistent with camera position
-	LLVector3 root_pos_last = mRoot.getWorldPosition();
+	LLVector3 root_pos_last = mRoot->getWorldPosition();
 	BOOL detailed_update = updateCharacter(agent);
 
 	static LLUICachedControl<bool> visualizers_in_calls("ShowVoiceVisualizersInCalls", false);
@@ -2597,11 +2138,11 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 		if ( mIsSitting )
 		{
 			LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] );
-			mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset );
+			mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot->getWorldPosition() + headOffset );
 		}
 		else 
 		{
-			LLVector3 tagPos = mRoot.getWorldPosition();
+			LLVector3 tagPos = mRoot->getWorldPosition();
 			tagPos[VZ] -= mPelvisToFoot;
 			tagPos[VZ] += ( mBodySize[VZ] + 0.125f );
 			mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos );
@@ -3206,8 +2747,6 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
 		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
 
-		char line[MAX_STRING];		/* Flawfinder: ignore */
-		line[0] = '\0';
 		std::deque<LLChat>::iterator chat_iter = mChats.begin();
 		mNameText->clearString();
 
@@ -3334,7 +2873,7 @@ void LLVOAvatar::invalidateNameTags()
 // Compute name tag position during idle update
 void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
 {
-	LLQuaternion root_rot = mRoot.getWorldRotation();
+	LLQuaternion root_rot = mRoot->getWorldRotation();
 	LLQuaternion inv_root_rot = ~root_rot;
 	LLVector3 pixel_right_vec;
 	LLVector3 pixel_up_vec;
@@ -3353,7 +2892,7 @@ void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
 	local_camera_up.scaleVec(avatar_ellipsoid);
 	local_camera_at.scaleVec(avatar_ellipsoid);
 
-	LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot.getLastWorldPosition()) * inv_root_rot;
+	LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot->getLastWorldPosition()) * inv_root_rot;
 
 	if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD)
 	{
@@ -3362,7 +2901,7 @@ void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
 	
 	mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f));
 
-	LLVector3 name_position = mRoot.getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);
+	LLVector3 name_position = mRoot->getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);
 	name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));	
 	name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET;
 
@@ -3423,13 +2962,13 @@ void LLVOAvatar::idleUpdateBelowWater()
 void LLVOAvatar::slamPosition()
 {
 	gAgent.setPositionAgent(getPositionAgent());
-	mRoot.setWorldPosition(getPositionAgent()); // teleport
+	mRoot->setWorldPosition(getPositionAgent()); // teleport
 	setChanged(TRANSLATED);
 	if (mDrawable.notNull())
 	{
 		gPipeline.updateMoveNormalAsync(mDrawable);
 	}
-	mRoot.updateWorldMatrixChildren();
+	mRoot->updateWorldMatrixChildren();
 }
 
 bool LLVOAvatar::isVisuallyMuted() const
@@ -3450,6 +2989,47 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 {
 	// clear debug text
 	mDebugText.clear();
+
+	if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+	{
+		S32 central_bake_version = -1;
+		if (getRegion())
+		{
+			central_bake_version = getRegion()->getCentralBakeVersion();
+		}
+		bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded();
+		bool all_local_downloaded = allLocalTexturesCompletelyDownloaded();
+		std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d",
+										  isSelf() ? (all_local_downloaded ? "L" : "l") : "-",
+										  all_baked_downloaded ? "B" : "b",
+										  mUseLocalAppearance, mIsEditingAppearance,
+										  mUseServerBakes, central_bake_version);
+		std::string origin_string = bakedTextureOriginInfo();
+		debug_line += " [" + origin_string + "]";
+		S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion();
+		S32 last_request_cof_version = mLastUpdateRequestCOFVersion;
+		S32 last_received_cof_version = mLastUpdateReceivedCOFVersion;
+		if (isSelf())
+		{
+			debug_line += llformat(" - cof: %d req: %d rcv:%d",
+								   curr_cof_version, last_request_cof_version, last_received_cof_version);
+			if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
+			{
+				debug_line += " FORCING ERRS";
+			}
+		}
+		else
+		{
+			debug_line += llformat(" - cof rcv:%d", last_received_cof_version);
+		}
+		addDebugText(debug_line);
+	}
+	if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
+	{
+		if (!mBakedTextureDebugText.empty())
+			addDebugText(mBakedTextureDebugText);
+	}
+				 
 	if (LLVOAvatar::sShowAnimationDebug)
 	{
 		for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
@@ -3586,8 +3166,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 	xyVel.mV[VZ] = 0.0f;
 	speed = xyVel.length();
 
-	BOOL throttle = TRUE;
-
 	if (!(mIsSitting && getParent()))
 	{
 		//--------------------------------------------------------------------
@@ -3598,11 +3176,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		if (mTimeLast == 0.0f)
 		{
 			mTimeLast = animation_time;
-			throttle = FALSE;
 
 			// put the pelvis at slaved position/mRotation
-			mRoot.setWorldPosition( getPositionAgent() ); // first frame
-			mRoot.setWorldRotation( getRotation() );
+			mRoot->setWorldPosition( getPositionAgent() ); // first frame
+			mRoot->setWorldRotation( getRotation() );
 		}
 	
 		//--------------------------------------------------------------------
@@ -3627,6 +3204,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		}
 
 		root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition());
+		root_pos.mdV[VZ] += getVisualParamWeight(AVATAR_HOVER);
+
 
 		resolveHeightGlobal(root_pos, ground_under_pelvis, normal);
 		F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]);				
@@ -3645,10 +3224,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		
 		LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
 
-		if (newPosition != mRoot.getXform()->getWorldPosition())
+		if (newPosition != mRoot->getXform()->getWorldPosition())
 		{		
-			mRoot.touch();
-			mRoot.setWorldPosition( newPosition ); // regular update				
+			mRoot->touch();
+			mRoot->setWorldPosition( newPosition ); // regular update				
 		}
 
 
@@ -3709,7 +3288,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 				
 			}
 
-			LLQuaternion root_rotation = mRoot.getWorldMatrix().quaternion();
+			LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion();
 			F32 root_roll, root_pitch, root_yaw;
 			root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw);
 
@@ -3718,7 +3297,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 			// and head turn.  Once in motion, it must conform however.
 			BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook();
 
-			LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV );
+			LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV );
 
 			static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow");
 			static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast");
@@ -3804,14 +3383,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 
 			F32 u = llclamp((deltaTime / pelvis_lag_time), 0.0f, 1.0f);	
 
-			mRoot.setWorldRotation( slerp(u, mRoot.getWorldRotation(), wQv) );
+			mRoot->setWorldRotation( slerp(u, mRoot->getWorldRotation(), wQv) );
 			
 		}
 	}
 	else if (mDrawable.notNull())
 	{
-		mRoot.setPosition(mDrawable->getPosition());
-		mRoot.setRotation(mDrawable->getRotation());
+		mRoot->setPosition(mDrawable->getPosition());
+		mRoot->setRotation(mDrawable->getRotation());
 	}
 	
 	//-------------------------------------------------------------------------
@@ -3907,7 +3486,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		}
 	}
 
-	mRoot.updateWorldMatrixChildren();
+	mRoot->updateWorldMatrixChildren();
 
 	if (!mDebugText.size() && mText.notNull())
 	{
@@ -3931,7 +3510,7 @@ void LLVOAvatar::updateHeadOffset()
 {
 	// since we only care about Z, just grab one of the eyes
 	LLVector3 midEyePt = mEyeLeftp->getWorldPosition();
-	midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot.getWorldPosition();
+	midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot->getWorldPosition();
 	midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstance()->getNear(), midEyePt.mV[VZ]);
 
 	if (mDrawable.notNull())
@@ -3969,8 +3548,8 @@ void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount,
 void LLVOAvatar::postPelvisSetRecalc( void )
 {	
 	computeBodySize(); 
-	mRoot.touch();
-	mRoot.updateWorldMatrixChildren();	
+	mRoot->touch();
+	mRoot->updateWorldMatrixChildren();	
 	dirtyMesh();
 	updateHeadOffset();
 }
@@ -4118,7 +3697,7 @@ void LLVOAvatar::updateVisibility()
 // private
 bool LLVOAvatar::shouldAlphaMask()
 {
-	const bool should_alpha_mask = mSupportsAlphaLayers && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
+	const bool should_alpha_mask = !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
 							&& !LLDrawPoolAvatar::sSkipTransparent;
 
 	return should_alpha_mask;
@@ -4157,19 +3736,44 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 		if (mNeedsSkin)
 		{
 			//generate animated mesh
-			mMeshLOD[MESH_ID_LOWER_BODY]->updateJointGeometry();
-			mMeshLOD[MESH_ID_UPPER_BODY]->updateJointGeometry();
+			LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
+			LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
+			LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT);
+			LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH);
+			LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
+			LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
+
+			if(upper_mesh)
+			{
+				upper_mesh->updateJointGeometry();
+			}
+			if (lower_mesh)
+			{
+				lower_mesh->updateJointGeometry();
+			}
 
 			if( isWearingWearableType( LLWearableType::WT_SKIRT ) )
 			{
-				mMeshLOD[MESH_ID_SKIRT]->updateJointGeometry();
+				if(skirt_mesh)
+				{
+					skirt_mesh->updateJointGeometry();
+				}
 			}
 
 			if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
 			{
-				mMeshLOD[MESH_ID_EYELASH]->updateJointGeometry();
-				mMeshLOD[MESH_ID_HEAD]->updateJointGeometry();
-				mMeshLOD[MESH_ID_HAIR]->updateJointGeometry();
+				if(eyelash_mesh)
+				{
+					eyelash_mesh->updateJointGeometry();
+				}
+				if(head_mesh)
+				{
+					head_mesh->updateJointGeometry();
+				}
+				if(hair_mesh)
+				{
+					hair_mesh->updateJointGeometry();
+				}
 			}
 			mNeedsSkin = FALSE;
 			mLastSkinTime = gFrameTimeSeconds;
@@ -4286,19 +3890,31 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 			{
 				if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy)
 				{
-					num_indices += mMeshLOD[MESH_ID_HEAD]->render(mAdjustedPixelArea, TRUE, mIsDummy);
+					LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
+					if (head_mesh)
+					{
+						num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy);
+					}
 					first_pass = FALSE;
 				}
 			}
 			if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy)
 			{
-				num_indices += mMeshLOD[MESH_ID_UPPER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+				LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
+				if (upper_mesh)
+				{
+					num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+				}
 				first_pass = FALSE;
 			}
 			
 			if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy)
 			{
-				num_indices += mMeshLOD[MESH_ID_LOWER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+				LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
+				if (lower_mesh)
+				{
+					num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+				}
 				first_pass = FALSE;
 			}
 		}
@@ -4331,7 +3947,11 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
 	if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (mIsDummy || isTextureVisible(TEX_SKIRT_BAKED)) )
 	{
 		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f);
-		num_indices += mMeshLOD[MESH_ID_SKIRT]->render(mAdjustedPixelArea, FALSE);
+		LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT);
+		if (skirt_mesh)
+		{
+			num_indices += skirt_mesh->render(mAdjustedPixelArea, FALSE);
+		}
 		first_pass = FALSE;
 		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
 	}
@@ -4345,16 +3965,23 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
 		
 		if (isTextureVisible(TEX_HEAD_BAKED))
 		{
-			num_indices += mMeshLOD[MESH_ID_EYELASH]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+			LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH);
+			if (eyelash_mesh)
+			{
+				num_indices += eyelash_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+			}
 			first_pass = FALSE;
 		}
 		// Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair)
 		// TODO: 1.25 will be able to switch this logic back to calling isTextureVisible();
-
-		if ( getImage(TEX_HAIR_BAKED, 0)
-			&& getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha)
+		if ( getImage(TEX_HAIR_BAKED, 0) && 
+		     getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha)		
 		{
-			num_indices += mMeshLOD[MESH_ID_HAIR]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+			LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
+			if (hair_mesh)
+			{
+				num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+			}
 			first_pass = FALSE;
 		}
 		if (LLPipeline::sImpostorRender)
@@ -4398,8 +4025,16 @@ U32 LLVOAvatar::renderRigid()
 
 	if (isTextureVisible(TEX_EYES_BAKED)  || mIsDummy)
 	{
-		num_indices += mMeshLOD[MESH_ID_EYEBALL_LEFT]->render(mAdjustedPixelArea, TRUE, mIsDummy);
-		num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy);
+		LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT);
+		LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT);
+		if (eyeball_left)
+		{
+			num_indices += eyeball_left->render(mAdjustedPixelArea, TRUE, mIsDummy);
+		}
+		if(eyeball_right)
+		{
+			num_indices += eyeball_right->render(mAdjustedPixelArea, TRUE, mIsDummy);
+		}
 	}
 
 	if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)
@@ -4446,11 +4081,224 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
 	return 6;
 }
 
-//------------------------------------------------------------------------
-// LLVOAvatar::updateTextures()
-//------------------------------------------------------------------------
+bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const
+{
+	for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+	{
+		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+		if (imagep && imagep->getDiscardLevel()!=0)
+		{
+			return false;
+		}
+	}
+	return true;
+}
+
+bool LLVOAvatar::allLocalTexturesCompletelyDownloaded() const
+{
+	std::set<LLUUID> local_ids;
+	collectLocalTextureUUIDs(local_ids);
+	return allTexturesCompletelyDownloaded(local_ids);
+}
+
+bool LLVOAvatar::allBakedTexturesCompletelyDownloaded() const
+{
+	std::set<LLUUID> baked_ids;
+	collectBakedTextureUUIDs(baked_ids);
+	return allTexturesCompletelyDownloaded(baked_ids);
+}
+
+void LLVOAvatar::bakedTextureOriginCounts(S32 &sb_count, // server-bake, has origin URL.
+										  S32 &host_count, // host-based bake, has host.
+										  S32 &both_count, // error - both host and URL set.
+										  S32 &neither_count) // error - neither set.
+{
+	sb_count = host_count = both_count = neither_count = 0;
+	
+	std::set<LLUUID> baked_ids;
+	collectBakedTextureUUIDs(baked_ids);
+	for (std::set<LLUUID>::const_iterator it = baked_ids.begin(); it != baked_ids.end(); ++it)
+	{
+		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+		bool has_url = false, has_host = false;
+		if (!imagep->getUrl().empty())
+		{
+			has_url = true;
+		}
+		if (imagep->getTargetHost().isOk())
+		{
+			has_host = true;
+		}
+		if (has_url && !has_host) sb_count++;
+		else if (has_host && !has_url) host_count++;
+		else if (has_host && has_url) both_count++;
+		else if (!has_host && !has_url) neither_count++;
+	}
+}
+
+std::string LLVOAvatar::bakedTextureOriginInfo()
+{
+	std::string result;
+	
+	std::set<LLUUID> baked_ids;
+	collectBakedTextureUUIDs(baked_ids);
+	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+	{
+		ETextureIndex texture_index = mBakedTextureDatas[i].mTextureIndex;
+		LLViewerFetchedTexture *imagep =
+			LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
+		if (!imagep ||
+			imagep->getID() == IMG_DEFAULT ||
+			imagep->getID() == IMG_DEFAULT_AVATAR)
+			
+		{
+			result += "-";
+		}
+		else
+		{
+			bool has_url = false, has_host = false;
+			if (!imagep->getUrl().empty())
+			{
+				has_url = true;
+			}
+			if (imagep->getTargetHost().isOk())
+			{
+				has_host = true;
+			}
+			S32 discard = imagep->getDiscardLevel();
+			if (has_url && !has_host) result += discard ? "u" : "U"; // server-bake texture with url 
+			else if (has_host && !has_url) result += discard ? "h" : "H"; // old-style texture on sim
+			else if (has_host && has_url) result += discard ? "x" : "X"; // both origins?
+			else if (!has_host && !has_url) result += discard ? "n" : "N"; // no origin?
+			if (discard != 0)
+			{
+				result += llformat("(%d/%d)",discard,imagep->getDesiredDiscardLevel());
+			}
+		}
+
+	}
+	return result;
+}
+
+S32 LLVOAvatar::totalTextureMemForUUIDS(std::set<LLUUID>& ids)
+{
+	S32 result = 0;
+	for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+	{
+		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+		if (imagep)
+		{
+			result += imagep->getTextureMemory();
+		}
+	}
+	return result;
+}
+	
+void LLVOAvatar::collectLocalTextureUUIDs(std::set<LLUUID>& ids) const
+{
+	for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
+	{
+		LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index);
+		U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
+
+		LLViewerFetchedTexture *imagep = NULL;
+		for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++)
+		{
+			imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
+			if (imagep)
+			{
+				const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
+				if (texture_dict->mIsLocalTexture)
+				{
+					ids.insert(imagep->getID());
+				}
+			}
+		}
+	}
+	ids.erase(IMG_DEFAULT);
+	ids.erase(IMG_DEFAULT_AVATAR);
+	ids.erase(IMG_INVISIBLE);
+}
+
+void LLVOAvatar::collectBakedTextureUUIDs(std::set<LLUUID>& ids) const
+{
+	for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
+	{
+		LLViewerFetchedTexture *imagep = NULL;
+		if (isIndexBakedTexture((ETextureIndex) texture_index))
+		{
+			imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
+			if (imagep)
+			{
+				ids.insert(imagep->getID());
+			}
+		}
+	}
+	ids.erase(IMG_DEFAULT);
+	ids.erase(IMG_DEFAULT_AVATAR);
+	ids.erase(IMG_INVISIBLE);
+}
+
+void LLVOAvatar::collectTextureUUIDs(std::set<LLUUID>& ids)
+{
+	collectLocalTextureUUIDs(ids);
+	collectBakedTextureUUIDs(ids);
+}
+
+void LLVOAvatar::releaseOldTextures()
+{
+	S32 current_texture_mem = 0;
+	
+	// Any textures that we used to be using but are no longer using should no longer be flagged as "NO_DELETE"
+	std::set<LLUUID> baked_texture_ids;
+	collectBakedTextureUUIDs(baked_texture_ids);
+	S32 new_baked_mem = totalTextureMemForUUIDS(baked_texture_ids);
+
+	std::set<LLUUID> local_texture_ids;
+	collectLocalTextureUUIDs(local_texture_ids);
+	//S32 new_local_mem = totalTextureMemForUUIDS(local_texture_ids);
+
+	std::set<LLUUID> new_texture_ids;
+	new_texture_ids.insert(baked_texture_ids.begin(),baked_texture_ids.end());
+	new_texture_ids.insert(local_texture_ids.begin(),local_texture_ids.end());
+	S32 new_total_mem = totalTextureMemForUUIDS(new_texture_ids);
+
+	//S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs);
+	//LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << llendl;  
+	if (!isSelf() && new_total_mem > new_baked_mem)
+	{
+			llwarns << "extra local textures stored for non-self av" << llendl;
+	}
+	for (std::set<LLUUID>::iterator it = mTextureIDs.begin(); it != mTextureIDs.end(); ++it)
+	{
+		if (new_texture_ids.find(*it) == new_texture_ids.end())
+		{
+			LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+			if (imagep)
+			{
+				current_texture_mem += imagep->getTextureMemory();
+				if (imagep->getTextureState() == LLGLTexture::NO_DELETE)
+				{
+					// This will allow the texture to be deleted if not in use.
+					imagep->forceActive();
+
+					// This resets the clock to texture being flagged
+					// as unused, preventing the texture from being
+					// deleted immediately. If other avatars or
+					// objects are using it, it can still be flagged
+					// no-delete by them.
+					imagep->forceUpdateBindStats();
+				}
+			}
+		}
+	}
+	mTextureIDs = new_texture_ids;
+}
+
 void LLVOAvatar::updateTextures()
 {
+	releaseOldTextures();
+	
 	BOOL render_avatar = TRUE;
 
 	if (mIsDummy)
@@ -4493,7 +4341,7 @@ void LLVOAvatar::updateTextures()
 	mHasGrey = FALSE; // debug
 	for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
 	{
-		LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)texture_index);
+		LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index);
 		U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
 		const LLTextureEntry *te = getTE(texture_index);
 
@@ -4516,11 +4364,11 @@ void LLVOAvatar::updateTextures()
 			imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
 			if (imagep)
 			{
-				const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
+				const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
 				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
 				if (texture_dict->mIsLocalTexture)
 				{
-					addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]);
+					addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, mBakedTextureDatas[baked_index].mIsUsed);
 				}
 			}
 		}
@@ -4532,6 +4380,7 @@ void LLVOAvatar::updateTextures()
 			if (isIndexBakedTexture((ETextureIndex)texture_index)
 				&& imagep->getID() != IMG_DEFAULT_AVATAR
 				&& imagep->getID() != IMG_INVISIBLE
+				&& !isUsingServerBakes() 
 				&& !imagep->getTargetHost().isOk())
 			{
 				LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture "
@@ -4552,7 +4401,7 @@ void LLVOAvatar::updateTextures()
 
 
 void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture* imagep,
-									   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index )
+									   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)
 {
 	// No local texture stats for non-self avatars
 	return;
@@ -4626,7 +4475,6 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel
 	//the texture pipeline will stop fetching this texture.
 
 	imagep->resetTextureStats();
-	imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures.
 	imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
 	imagep->resetMaxVirtualSizeResetCounter() ;
 
@@ -4635,7 +4483,7 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel
 	imagep->addTextureStats(pixel_area / texel_area_ratio);
 	imagep->setBoostLevel(boost_level);
 	
-	if(boost_level != LLViewerTexture::BOOST_AVATAR_BAKED_SELF)
+	if(boost_level != LLGLTexture::BOOST_AVATAR_BAKED_SELF)
 	{
 		imagep->setAdditionalDecodePriority(ADDITIONAL_PRI) ;
 	}
@@ -4668,6 +4516,30 @@ void LLVOAvatar::setTexEntry(const U8 index, const LLTextureEntry &te)
 	setTE(index, te);
 }
 
+const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid)
+{
+	llassert(isIndexBakedTexture(ETextureIndex(te)));
+	std::string url = "";
+	if (isUsingServerBakes())
+	{
+		const std::string& appearance_service_url = LLAppearanceMgr::instance().getAppearanceServiceURL();
+		if (appearance_service_url.empty())
+		{
+			// Probably a server-side issue if we get here:
+			llwarns << "AgentAppearanceServiceURL not set - Baked texture requests will fail" << llendl;
+			return url;
+		}
+	
+		const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
+		if (texture_entry != NULL)
+		{
+			url = appearance_service_url + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString();
+			//llinfos << "baked texture url: " << url << llendl;
+		}
+	}
+	return url;
+}
+
 //-----------------------------------------------------------------------------
 // resolveHeight()
 //-----------------------------------------------------------------------------
@@ -5008,48 +4880,6 @@ void LLVOAvatar::stopMotionFromSource(const LLUUID& source_id)
 {
 }
 
-//-----------------------------------------------------------------------------
-// getVolumePos()
-//-----------------------------------------------------------------------------
-LLVector3 LLVOAvatar::getVolumePos(S32 joint_index, LLVector3& volume_offset)
-{
-	if (joint_index > mNumCollisionVolumes)
-	{
-		return LLVector3::zero;
-	}
-
-	return mCollisionVolumes[joint_index].getVolumePos(volume_offset);
-}
-
-//-----------------------------------------------------------------------------
-// findCollisionVolume()
-//-----------------------------------------------------------------------------
-LLJoint* LLVOAvatar::findCollisionVolume(U32 volume_id)
-{
-	if ((S32)volume_id > mNumCollisionVolumes)
-	{
-		return NULL;
-	}
-	
-	return &mCollisionVolumes[volume_id];
-}
-
-//-----------------------------------------------------------------------------
-// findCollisionVolume()
-//-----------------------------------------------------------------------------
-S32 LLVOAvatar::getCollisionVolumeID(std::string &name)
-{
-	for (S32 i = 0; i < mNumCollisionVolumes; i++)
-	{
-		if (mCollisionVolumes[i].getName() == name)
-		{
-			return i;
-		}
-	}
-
-	return -1;
-}
-
 //-----------------------------------------------------------------------------
 // addDebugText()
 //-----------------------------------------------------------------------------
@@ -5079,7 +4909,7 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
 
 	if (iter == mJointMap.end() || iter->second == NULL)
 	{ //search for joint and cache found joint in lookup table
-		jointp = mRoot.findJoint(name);
+		jointp = mRoot->findJoint(name);
 		mJointMap[name] = jointp;
 	}
 	else
@@ -5095,10 +4925,12 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
 //-----------------------------------------------------------------------------
 void LLVOAvatar::resetJointPositions( void )
 {
-	for(S32 i = 0; i < (S32)mNumJoints; ++i)
+	avatar_joint_list_t::iterator iter = mSkeleton.begin();
+	avatar_joint_list_t::iterator end  = mSkeleton.end();
+	for (; iter != end; ++iter)
 	{
-		mSkeleton[i].restoreOldXform();
-		mSkeleton[i].setId( LLUUID::null );
+		(*iter)->restoreOldXform();
+		(*iter)->setId( LLUUID::null );
 	}
 	mHasPelvisOffset = false;
 	mPelvisFixup	 = mLastPelvisFixup;
@@ -5108,7 +4940,7 @@ void LLVOAvatar::resetJointPositions( void )
 //-----------------------------------------------------------------------------
 void LLVOAvatar::resetSpecificJointPosition( const std::string& name )
 {
-	LLJoint* pJoint = mRoot.findJoint( name );
+	LLJoint* pJoint = mRoot->findJoint( name );
 	
 	if ( pJoint  && pJoint->doesJointNeedToBeReset() )
 	{
@@ -5130,16 +4962,17 @@ void LLVOAvatar::resetSpecificJointPosition( const std::string& name )
 //-----------------------------------------------------------------------------
 void LLVOAvatar::resetJointPositionsToDefault( void )
 {
-
 	//Subsequent joints are relative to pelvis
-	for( S32 i = 0; i < (S32)mNumJoints; ++i )
+	avatar_joint_list_t::iterator iter = mSkeleton.begin();
+	avatar_joint_list_t::iterator end  = mSkeleton.end();
+	for (; iter != end; ++iter)
 	{
-		LLJoint* pJoint = (LLJoint*)&mSkeleton[i];
+		LLJoint* pJoint = (*iter);
 		if ( pJoint->doesJointNeedToBeReset() )
 		{
-
 			pJoint->setId( LLUUID::null );
 			//restore joints to default positions, however skip over the pelvis
+			// *TODO: How does this pointer check skip over pelvis?
 			if ( pJoint )
 			{
 				pJoint->restoreOldXform();
@@ -5238,23 +5071,6 @@ F32 LLVOAvatar::getPixelArea() const
 }
 
 
-//-----------------------------------------------------------------------------
-// LLVOAvatar::getHeadMesh()
-//-----------------------------------------------------------------------------
-LLPolyMesh*	LLVOAvatar::getHeadMesh()
-{
-	return mMeshLOD[MESH_ID_HEAD]->mMeshParts[0]->getMesh();
-}
-
-
-//-----------------------------------------------------------------------------
-// LLVOAvatar::getUpperBodyMesh()
-//-----------------------------------------------------------------------------
-LLPolyMesh*	LLVOAvatar::getUpperBodyMesh()
-{
-	return mMeshLOD[MESH_ID_UPPER_BODY]->mMeshParts[0]->getMesh();
-}
-
 
 //-----------------------------------------------------------------------------
 // LLVOAvatar::getPosGlobalFromAgent()
@@ -5272,281 +5088,35 @@ LLVector3	LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position)
 	return gAgent.getPosAgentFromGlobal(position);
 }
 
+
 //-----------------------------------------------------------------------------
-// allocateCharacterJoints()
+// requestStopMotion()
 //-----------------------------------------------------------------------------
-BOOL LLVOAvatar::allocateCharacterJoints( U32 num )
+// virtual
+void LLVOAvatar::requestStopMotion( LLMotion* motion )
 {
-	deleteAndClearArray(mSkeleton);
-	mNumJoints = 0;
-
-	mSkeleton = new LLViewerJoint[num];
-	
-	for(S32 joint_num = 0; joint_num < (S32)num; joint_num++)
-	{
-		mSkeleton[joint_num].setJointNum(joint_num);
-	}
-
-	if (!mSkeleton)
-	{
-		return FALSE;
-	}
-
-	mNumJoints = num;
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// allocateCollisionVolumes()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::allocateCollisionVolumes( U32 num )
-{
-	deleteAndClearArray(mCollisionVolumes);
-	mNumCollisionVolumes = 0;
-
-	mCollisionVolumes = new LLViewerJointCollisionVolume[num];
-	if (!mCollisionVolumes)
-	{
-		return FALSE;
-	}
-
-	mNumCollisionVolumes = num;
-	return TRUE;
-}
-
-
-//-----------------------------------------------------------------------------
-// getCharacterJoint()
-//-----------------------------------------------------------------------------
-LLJoint *LLVOAvatar::getCharacterJoint( U32 num )
-{
-	if ((S32)num >= mNumJoints 
-	    || (S32)num < 0)
-	{
-		return NULL;
-	}
-	return (LLJoint*)&mSkeleton[num];
-}
-
-//-----------------------------------------------------------------------------
-// requestStopMotion()
-//-----------------------------------------------------------------------------
-// virtual
-void LLVOAvatar::requestStopMotion( LLMotion* motion )
-{
-	// Only agent avatars should handle the stop motion notifications.
-}
-
-//-----------------------------------------------------------------------------
-// loadAvatar()
-//-----------------------------------------------------------------------------
-static LLFastTimer::DeclareTimer FTM_LOAD_AVATAR("Load Avatar");
-
-BOOL LLVOAvatar::loadAvatar()
-{
-// 	LLFastTimer t(FTM_LOAD_AVATAR);
-	
-	// avatar_skeleton.xml
-	if( !buildSkeleton(sAvatarSkeletonInfo) )
-	{
-		llwarns << "avatar file: buildSkeleton() failed" << llendl;
-		return FALSE;
-	}
-
-	// avatar_lad.xml : <skeleton>
-	if( !loadSkeletonNode() )
-	{
-		llwarns << "avatar file: loadNodeSkeleton() failed" << llendl;
-		return FALSE;
-	}
-	
-	// avatar_lad.xml : <mesh>
-	if( !loadMeshNodes() )
-	{
-		llwarns << "avatar file: loadNodeMesh() failed" << llendl;
-		return FALSE;
-	}
-	
-	// avatar_lad.xml : <global_color>
-	if( sAvatarXmlInfo->mTexSkinColorInfo )
-	{
-		mTexSkinColor = new LLTexGlobalColor( this );
-		if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) )
-		{
-			llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl;
-			return FALSE;
-		}
-	}
-	else
-	{
-		llwarns << "<global_color> name=\"skin_color\" not found" << llendl;
-		return FALSE;
-	}
-	if( sAvatarXmlInfo->mTexHairColorInfo )
-	{
-		mTexHairColor = new LLTexGlobalColor( this );
-		if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) )
-		{
-			llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl;
-			return FALSE;
-		}
-	}
-	else
-	{
-		llwarns << "<global_color> name=\"hair_color\" not found" << llendl;
-		return FALSE;
-	}
-	if( sAvatarXmlInfo->mTexEyeColorInfo )
-	{
-		mTexEyeColor = new LLTexGlobalColor( this );
-		if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) )
-		{
-			llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl;
-			return FALSE;
-		}
-	}
-	else
-	{
-		llwarns << "<global_color> name=\"eye_color\" not found" << llendl;
-		return FALSE;
-	}
-	
-	// avatar_lad.xml : <layer_set>
-	if (sAvatarXmlInfo->mLayerInfoList.empty())
-	{
-		llwarns << "avatar file: missing <layer_set> node" << llendl;
-		return FALSE;
-	}
-
-	if (sAvatarXmlInfo->mMorphMaskInfoList.empty())
-	{
-		llwarns << "avatar file: missing <morph_masks> node" << llendl;
-		return FALSE;
-	}
-
-	// avatar_lad.xml : <morph_masks>
-	for (LLVOAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin();
-		 iter != sAvatarXmlInfo->mMorphMaskInfoList.end();
-		 ++iter)
-	{
-		LLVOAvatarXmlInfo::LLVOAvatarMorphInfo *info = *iter;
-
-		EBakedTextureIndex baked = LLVOAvatarDictionary::findBakedByRegionName(info->mRegion); 
-		if (baked != BAKED_NUM_INDICES)
-		{
-			LLPolyMorphTarget *morph_param;
-			const std::string *name = &info->mName;
-			morph_param = (LLPolyMorphTarget *)(getVisualParam(name->c_str()));
-			if (morph_param)
-			{
-				BOOL invert = info->mInvert;
-				addMaskedMorph(baked, morph_param, invert, info->mLayer);
-			}
-		}
-
-	}
-
-	loadLayersets();	
-	
-	// avatar_lad.xml : <driver_parameters>
-	for (LLVOAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
-		 iter != sAvatarXmlInfo->mDriverInfoList.end(); 
-		 ++iter)
-	{
-		LLDriverParamInfo *info = *iter;
-		LLDriverParam* driver_param = new LLDriverParam( this );
-		if (driver_param->setInfo(info))
-		{
-			addVisualParam( driver_param );
-			LLVisualParam*(LLVOAvatar::*avatar_function)(S32)const = &LLVOAvatar::getVisualParam; 
-			if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLVOAvatar*)this,_1 ), false))
-			{
-				llwarns << "could not link driven params for avatar " << this->getFullname() << " id: " << driver_param->getID() << llendl;
-				continue;
-			}
-		}
-		else
-		{
-			delete driver_param;
-			llwarns << "avatar file: driver_param->parseData() failed" << llendl;
-			return FALSE;
-		}
-	}
-
-	
-	return TRUE;
-}
+	// Only agent avatars should handle the stop motion notifications.
+}
 
 //-----------------------------------------------------------------------------
 // loadSkeletonNode(): loads <skeleton> node from XML tree
 //-----------------------------------------------------------------------------
+//virtual
 BOOL LLVOAvatar::loadSkeletonNode ()
 {
-	mRoot.addChild( &mSkeleton[0] );
-
-	for (std::vector<LLViewerJoint *>::iterator iter = mMeshLOD.begin();
-		 iter != mMeshLOD.end(); 
-		 ++iter)
-	{
-		LLViewerJoint *joint = (LLViewerJoint *) *iter;
-		joint->mUpdateXform = FALSE;
-		joint->setMeshesToChildren();
-	}
-
-	mRoot.addChild(mMeshLOD[MESH_ID_HEAD]);
-	mRoot.addChild(mMeshLOD[MESH_ID_EYELASH]);
-	mRoot.addChild(mMeshLOD[MESH_ID_UPPER_BODY]);
-	mRoot.addChild(mMeshLOD[MESH_ID_LOWER_BODY]);
-	mRoot.addChild(mMeshLOD[MESH_ID_SKIRT]);
-	mRoot.addChild(mMeshLOD[MESH_ID_HEAD]);
-
-	LLViewerJoint *skull = (LLViewerJoint*)mRoot.findJoint("mSkull");
-	if (skull)
-	{
-		skull->addChild(mMeshLOD[MESH_ID_HAIR] );
-	}
-
-	LLViewerJoint *eyeL = (LLViewerJoint*)mRoot.findJoint("mEyeLeft");
-	if (eyeL)
+	if (!LLAvatarAppearance::loadSkeletonNode())
 	{
-		eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] );
-	}
-
-	LLViewerJoint *eyeR = (LLViewerJoint*)mRoot.findJoint("mEyeRight");
-	if (eyeR)
-	{
-		eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] );
+		return FALSE;
 	}
 
-	// SKELETAL DISTORTIONS
-	{
-		LLVOAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter;
-		for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin();
-			 iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end(); 
-			 ++iter)
-		{
-			LLPolySkeletalDistortionInfo *info = *iter;
-			LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this);
-			if (!param->setInfo(info))
-			{
-				delete param;
-				return FALSE;
-			}
-			else
-			{
-				addVisualParam(param);
-			}				
-		}
-	}
-	
 	// ATTACHMENTS
 	{
-		LLVOAvatarXmlInfo::attachment_info_list_t::iterator iter;
+		LLAvatarXmlInfo::attachment_info_list_t::iterator iter;
 		for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin();
 			 iter != sAvatarXmlInfo->mAttachmentInfoList.end(); 
 			 ++iter)
 		{
-			LLVOAvatarXmlInfo::LLVOAvatarAttachmentInfo *info = *iter;
+			LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter;
 			if (!isSelf() && info->mJointName == "mScreen")
 			{ //don't process screen joint for other avatars
 				continue;
@@ -5618,144 +5188,6 @@ BOOL LLVOAvatar::loadSkeletonNode ()
 	return TRUE;
 }
 
-//-----------------------------------------------------------------------------
-// loadMeshNodes(): loads <mesh> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::loadMeshNodes()
-{
-	for (LLVOAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin();
-		 meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end(); 
-		 ++meshinfo_iter)
-	{
-		const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo *info = *meshinfo_iter;
-		const std::string &type = info->mType;
-		S32 lod = info->mLOD;
-
-		LLViewerJointMesh* mesh = NULL;
-		U8 mesh_id = 0;
-		BOOL found_mesh_id = FALSE;
-
-		/* if (type == "hairMesh")
-			switch(lod)
-			  case 0:
-				mesh = &mHairMesh0; */
-		for (LLVOAvatarDictionary::Meshes::const_iterator mesh_iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
-			 mesh_iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
-			 ++mesh_iter)
-		{
-			const EMeshIndex mesh_index = mesh_iter->first;
-			const LLVOAvatarDictionary::MeshEntry *mesh_dict = mesh_iter->second;
-			if (type.compare(mesh_dict->mName) == 0)
-			{
-				mesh_id = mesh_index;
-				found_mesh_id = TRUE;
-				break;
-			}
-		}
-
-		if (found_mesh_id)
-		{
-			if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size())
-			{
-				mesh = mMeshLOD[mesh_id]->mMeshParts[lod];
-			}
-			else
-			{
-				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
-				return FALSE;
-			}
-		}
-		else 
-		{
-			llwarns << "Ignoring unrecognized mesh type: " << type << llendl;
-			return FALSE;
-		}
-
-		//	llinfos << "Parsing mesh data for " << type << "..." << llendl;
-
-		// If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings.
-		// Do not touch!!!
-		mesh->setColor( 1.0f, 1.0f, 1.0f, 1.0f );
-
-		LLPolyMesh *poly_mesh = NULL;
-
-		if (!info->mReferenceMeshName.empty())
-		{
-			polymesh_map_t::const_iterator polymesh_iter = mMeshes.find(info->mReferenceMeshName);
-			if (polymesh_iter != mMeshes.end())
-			{
-				poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second);
-				poly_mesh->setAvatar(this);
-			}
-			else
-			{
-				// This should never happen
-				LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL;
-			}
-		}
-		else
-		{
-			poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName);
-			poly_mesh->setAvatar(this);
-		}
-
-		if( !poly_mesh )
-		{
-			llwarns << "Failed to load mesh of type " << type << llendl;
-			return FALSE;
-		}
-
-		// Multimap insert
-		mMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh));
-	
-		mesh->setMesh( poly_mesh );
-		mesh->setLOD( info->mMinPixelArea );
-
-		for (LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin();
-			 xmlinfo_iter != info->mPolyMorphTargetInfoList.end(); 
-			 ++xmlinfo_iter)
-		{
-			const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter);
-			LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh());
-			if (!param->setInfo(info_pair->first))
-			{
-				delete param;
-				return FALSE;
-			}
-			else
-			{
-				if (info_pair->second)
-				{
-					addSharedVisualParam(param);
-				}
-				else
-				{
-					addVisualParam(param);
-				}
-			}				
-		}
-	}
-
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// loadLayerSets()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::loadLayersets()
-{
-	BOOL success = TRUE;
-	for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin();
-		 layerset_iter != sAvatarXmlInfo->mLayerInfoList.end(); 
-		 ++layerset_iter)
-	{
-		// Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
-		LLTexLayerSetInfo *layerset_info = *layerset_iter;
-		layerset_info->createVisualParams(this);
-	}
-	return success;
-}
-
 //-----------------------------------------------------------------------------
 // updateVisualParams()
 //-----------------------------------------------------------------------------
@@ -5769,7 +5201,7 @@ void LLVOAvatar::updateVisualParams()
 	{
 		computeBodySize();
 		mLastSkeletonSerialNum = mSkeletonSerialNum;
-		mRoot.updateWorldMatrixChildren();
+		mRoot->updateWorldMatrixChildren();
 	}
 
 	dirtyMesh();
@@ -5856,7 +5288,12 @@ BOOL LLVOAvatar::updateJointLODs()
 		}
 
 		// now select meshes to render based on adjusted pixel area
-		BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
+		LLViewerJoint* root = dynamic_cast<LLViewerJoint*>(mRoot);
+		BOOL res = FALSE;
+		if (root)
+		{
+			res = root->updateLOD(mAdjustedPixelArea, TRUE);
+		}
  		if (res)
 		{
 			sNumLODChangesThisFrame++;
@@ -5945,6 +5382,15 @@ void LLVOAvatar::dirtyMesh(S32 priority)
 {
 	mDirtyMesh = llmax(mDirtyMesh, priority);
 }
+
+//-----------------------------------------------------------------------------
+// getViewerJoint()
+//-----------------------------------------------------------------------------
+LLViewerJoint*	LLVOAvatar::getViewerJoint(S32 idx)
+{
+	return dynamic_cast<LLViewerJoint*>(mMeshLOD[idx]);
+}
+
 //-----------------------------------------------------------------------------
 // hideSkirt()
 //-----------------------------------------------------------------------------
@@ -6251,9 +5697,9 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
 	// Notice that removing sitDown() from here causes avatars sitting on
 	// objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655.
 	sitDown(TRUE);
-	mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
-	mRoot.setPosition(getPosition());
-	mRoot.updateWorldMatrixChildren();
+	mRoot->getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
+	mRoot->setPosition(getPosition());
+	mRoot->updateWorldMatrixChildren();
 
 	stopMotion(ANIM_AGENT_BODY_NOISE);
 
@@ -6299,10 +5745,10 @@ void LLVOAvatar::getOffObject()
 
 	sitDown(FALSE);
 
-	mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject
-	mRoot.setPosition(cur_position_world);
-	mRoot.setRotation(cur_rotation_world);
-	mRoot.getXform()->update();
+	mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject
+	mRoot->setPosition(cur_position_world);
+	mRoot->setRotation(cur_rotation_world);
+	mRoot->getXform()->update();
 
 	startMotion(ANIM_AGENT_BODY_NOISE);
 
@@ -6350,26 +5796,53 @@ S32 LLVOAvatar::getAttachmentCount()
 	return count;
 }
 
-LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const
+BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
 {
-	if (color_name=="skin_color" && mTexSkinColor)
-	{
-		return mTexSkinColor->getColor();
-	}
-	else if(color_name=="hair_color" && mTexHairColor)
+	if (mIsDummy) return TRUE;
+
+	if (isSelf())
 	{
-		return mTexHairColor->getColor();
+		return LLAvatarAppearance::isWearingWearableType(type);
 	}
-	if(color_name=="eye_color" && mTexEyeColor)
+
+	switch(type)
 	{
-		return mTexEyeColor->getColor();
+		case LLWearableType::WT_SHAPE:
+		case LLWearableType::WT_SKIN:
+		case LLWearableType::WT_HAIR:
+		case LLWearableType::WT_EYES:
+			return TRUE;  // everyone has all bodyparts
+		default:
+			break; // Do nothing
 	}
-	else
+
+	/* switch(type)
+		case LLWearableType::WT_SHIRT:
+			indicator_te = TEX_UPPER_SHIRT; */
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 tex_iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+		 ++tex_iter)
 	{
-		return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;
+		if (texture_dict->mWearableType == type)
+		{
+			// Thus, you must check to see if the corresponding baked texture is defined.
+			// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
+			// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
+			// gets baked into a texture that always exists (upper or lower).
+			if (texture_dict->mIsUsedByBakedTexture)
+			{
+				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+				return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
+			}
+			return FALSE;
+		}
 	}
+	return FALSE;
 }
 
+
+
 // virtual
 void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )
 {
@@ -6379,6 +5852,7 @@ void LLVOAvatar::invalidateAll()
 {
 }
 
+// virtual
 void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake )
 {
 	if (global_color == mTexSkinColor)
@@ -6397,9 +5871,15 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL
 		if (!isTextureDefined(mBakedTextureDatas[BAKED_HAIR].mTextureIndex))
 		{
 			LLColor4 color = mTexHairColor->getColor();
-			for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
+			avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin();
+			avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end();
+			for (; iter != end; ++iter)
 			{
-				mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
+				LLAvatarJointMesh* mesh = (*iter);
+				if (mesh)
+				{
+					mesh->setColor( color );
+				}
 			}
 		}
 	} 
@@ -6442,42 +5922,167 @@ BOOL LLVOAvatar::getIsCloud() const
 
 void LLVOAvatar::updateRezzedStatusTimers()
 {
-	// State machine for rezzed status. Statuses are 0 = cloud, 1 = gray, 2 = textured.
-	// Purpose is to collect time data for each period of cloud or cloud+gray.
+	// State machine for rezzed status. Statuses are -1 on startup, 0
+	// = cloud, 1 = gray, 2 = textured, 3 = textured_and_downloaded.
+	// Purpose is to collect time data for each it takes avatar to reach
+	// various loading landmarks: gray, textured (partial), textured fully.
+
 	S32 rez_status = getRezzedStatus();
 	if (rez_status != mLastRezzedStatus)
 	{
 		LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL;
-		bool is_cloud_or_gray = (rez_status==0 || rez_status==1);
-		bool was_cloud_or_gray = (mLastRezzedStatus==0 || mLastRezzedStatus==1);
-		bool is_cloud = (rez_status==0);
-		bool was_cloud = (mLastRezzedStatus==0);
 
-		// Non-cloud to cloud
-		if (is_cloud && !was_cloud)
+		if (mLastRezzedStatus == -1 && rez_status != -1)
 		{
-			// start cloud timer.
-			getPhases().startPhase("cloud");
+			// First time initialization, start all timers.
+			for (S32 i = 1; i < 4; i++)
+			{
+				startPhase("load_" + LLVOAvatar::rezStatusToString(i));
+				startPhase("first_load_" + LLVOAvatar::rezStatusToString(i));
+			}
 		}
-		else if (was_cloud && !is_cloud)
+		if (rez_status < mLastRezzedStatus)
 		{
-			// stop cloud timer, which will capture stats.
-			getPhases().stopPhase("cloud");
+			// load level has decreased. start phase timers for higher load levels.
+			for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++)
+			{
+				startPhase("load_" + LLVOAvatar::rezStatusToString(i));
+			}
+		}
+		else if (rez_status > mLastRezzedStatus)
+		{
+			// load level has increased. stop phase timers for lower and equal load levels.
+			for (S32 i = llmax(mLastRezzedStatus+1,1); i <= rez_status; i++)
+			{
+				stopPhase("load_" + LLVOAvatar::rezStatusToString(i));
+				stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false);
+			}
+			if (rez_status == 3)
+			{
+				// "fully loaded", mark any pending appearance change complete.
+				selfStopPhase("update_appearance_from_cof");
+				selfStopPhase("wear_inventory_category", false);
+				selfStopPhase("process_initial_wearables_update", false);
+			}
 		}
 
-		// Non-cloud-or-gray to cloud-or-gray
-		if (is_cloud_or_gray && !was_cloud_or_gray)
+		mLastRezzedStatus = rez_status;
+	}
+}
+
+void LLVOAvatar::clearPhases()
+{
+	getPhases().clearPhases();
+}
+
+void LLVOAvatar::startPhase(const std::string& phase_name)
+{
+	F32 elapsed;
+	bool completed;
+	if (getPhases().getPhaseValues(phase_name, elapsed, completed))
+	{
+		if (!completed)
 		{
-			// start cloud-or-gray timer.
-			getPhases().startPhase("cloud-or-gray");
+			LL_DEBUGS("Avatar") << avString() << "no-op, start when started already for " << phase_name << llendl;
+			return;
 		}
-		else if (was_cloud_or_gray && !is_cloud_or_gray)
+	}
+	LL_DEBUGS("Avatar") << "started phase " << phase_name << llendl;
+	getPhases().startPhase(phase_name);
+}
+
+void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)
+{
+	F32 elapsed;
+	bool completed;
+	if (getPhases().getPhaseValues(phase_name, elapsed, completed))
+	{
+		if (!completed)
 		{
-			// stop cloud-or-gray timer, which will capture stats.
-			getPhases().stopPhase("cloud-or-gray");
+			getPhases().stopPhase(phase_name);
+			completed = true;
+			logMetricsTimerRecord(phase_name, elapsed, completed);
+			LL_DEBUGS("Avatar") << avString() << "stopped phase " << phase_name << " elapsed " << elapsed << llendl;
+		}
+		else
+		{
+			if (err_check)
+			{
+				LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << llendl;
+			}
+		}
+	}
+	else
+	{
+		if (err_check)
+		{
+			LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << llendl;
 		}
-		
-		mLastRezzedStatus = rez_status;
+	}
+}
+
+void LLVOAvatar::logPendingPhases()
+{
+	for (LLViewerStats::phase_map_t::iterator it = getPhases().begin();
+		 it != getPhases().end();
+		 ++it)
+	{
+		const std::string& phase_name = it->first;
+		F32 elapsed;
+		bool completed;
+		if (getPhases().getPhaseValues(phase_name, elapsed, completed))
+		{
+			if (!completed)
+			{
+				logMetricsTimerRecord(phase_name, elapsed, completed);
+			}
+		}
+	}
+}
+
+//static
+void LLVOAvatar::logPendingPhasesAllAvatars()
+{
+	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+		 iter != LLCharacter::sInstances.end(); ++iter)
+	{
+		LLVOAvatar* inst = (LLVOAvatar*) *iter;
+		if( inst->isDead() )
+		{
+			continue;
+		}
+		inst->logPendingPhases();
+	}
+}
+
+void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed)
+{
+	LLSD record;
+	record["timer_name"] = phase_name;
+	record["avatar_id"] = getID();
+	record["elapsed"] = elapsed;
+	record["completed"] = completed;
+	U32 grid_x(0), grid_y(0);
+	if (getRegion())
+	{
+		record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion());
+		grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y);
+	}
+	record["grid_x"] = LLSD::Integer(grid_x);
+	record["grid_y"] = LLSD::Integer(grid_y);
+	record["is_using_server_bakes"] = ((bool) isUsingServerBakes());
+	record["is_self"] = isSelf();
+	
+
+#if 0 // verbose logging
+	std::ostringstream ostr;
+	ostr << LLSDNotationStreamer(record);
+	LL_DEBUGS("Avatar") << "record\n" << ostr.str() << llendl;
+#endif
+
+	if (isAgentAvatarValid())
+	{
+		gAgentAvatarp->addMetricsTimerRecord(record);
 	}
 }
 
@@ -6574,24 +6179,49 @@ LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const
 	return mMotionController.findMotion(id);
 }
 
+// This is a semi-deprecated debugging tool - meshes will not show as
+// colorized if using deferred rendering.
+void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color)
+{
+	if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
+	{
+		avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+		avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();
+		for (; iter != end; ++iter)
+		{
+			LLAvatarJointMesh* mesh = (*iter);
+			if (mesh)
+			{
+				{
+					mesh->setColor(color);
+				}
+			}
+		}
+	}
+}
+
 //-----------------------------------------------------------------------------
 // updateMeshTextures()
 // Uses the current TE values to set the meshes' and layersets' textures.
 //-----------------------------------------------------------------------------
+// virtual
 void LLVOAvatar::updateMeshTextures()
 {
-    // llinfos << "updateMeshTextures" << llendl;
+	static S32 update_counter = 0;
+	mBakedTextureDebugText.clear();
+	
 	// if user has never specified a texture, assign the default
 	for (U32 i=0; i < getNumTEs(); i++)
 	{
 		const LLViewerTexture* te_image = getImage(i, 0);
 		if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT))
 		{
-			setImage(i, LLViewerTextureManager::getFetchedTexture(i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR), 0); // IMG_DEFAULT_AVATAR = a special texture that's never rendered.
+			// IMG_DEFAULT_AVATAR = a special texture that's never rendered.
+			const LLUUID& image_id = (i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR);
+			setImage(i, LLViewerTextureManager::getFetchedTexture(image_id), 0); 
 		}
 	}
 
-	const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures
 	const BOOL other_culled = !isSelf() && mCulled;
 	LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
 	BOOL paused = FALSE;
@@ -6607,71 +6237,97 @@ void LLVOAvatar::updateMeshTextures()
 	std::vector<BOOL> use_lkg_baked_layer; // lkg = "last known good"
 	use_lkg_baked_layer.resize(mBakedTextureDatas.size(), false);
 
+	mBakedTextureDebugText += llformat("%06d\n",update_counter++);
+	mBakedTextureDebugText += "indx layerset linvld ltda ilb ulkg ltid\n";
 	for (U32 i=0; i < mBakedTextureDatas.size(); i++)
 	{
 		is_layer_baked[i] = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
-
+		LLViewerTexLayerSet* layerset = NULL;
+		bool layerset_invalid = false;
 		if (!other_culled)
 		{
 			// When an avatar is changing clothes and not in Appearance mode,
-			// use the last-known good baked texture until it finish the first
+			// use the last-known good baked texture until it finishes the first
 			// render of the new layerset.
-			const BOOL layerset_invalid = mBakedTextureDatas[i].mTexLayerSet 
-										  && ( !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized()
-										  || !mBakedTextureDatas[i].mTexLayerSet->isLocalTextureDataAvailable() );
+			layerset = getTexLayerSet(i);
+			layerset_invalid = layerset && ( !layerset->getViewerComposite()->isInitialized()
+											 || !layerset->isLocalTextureDataAvailable() );
 			use_lkg_baked_layer[i] = (!is_layer_baked[i] 
-									  && (mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) 
+									  && (mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR) 
 									  && layerset_invalid);
 			if (use_lkg_baked_layer[i])
 			{
-				mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE);
+				layerset->setUpdatesEnabled(TRUE);
 			}
 		}
 		else
 		{
 			use_lkg_baked_layer[i] = (!is_layer_baked[i] 
-									  && mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR);
-			if (mBakedTextureDatas[i].mTexLayerSet)
-			{
-				mBakedTextureDatas[i].mTexLayerSet->destroyComposite();
-			}
+									  && mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR);
 		}
 
-	}
-
-	// Turn on alpha masking correctly for yourself and other avatars on 1.23+
-	mSupportsAlphaLayers = isSelf() || is_layer_baked[BAKED_HAIR];
-
-	// Baked textures should be requested from the sim this avatar is on. JC
-	const LLHost target_host = getObjectHost();
-	if (!target_host.isOk())
-	{
-		llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl;
+		std::string last_id_string;
+		if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT_AVATAR)
+			last_id_string = "A";
+		else if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT)
+			last_id_string = "D";
+		else if (mBakedTextureDatas[i].mLastTextureID == IMG_INVISIBLE)
+			last_id_string = "I";
+		else
+			last_id_string = "*";
+		bool is_ltda = layerset
+			&& layerset->getViewerComposite()->isInitialized()
+			&& layerset->isLocalTextureDataAvailable();
+		mBakedTextureDebugText += llformat("%4d   %4s     %4d %4d %4d %4d %4s\n",
+										   i,
+										   (layerset?"*":"0"),
+										   layerset_invalid,
+										   is_ltda,
+										   is_layer_baked[i],
+										   use_lkg_baked_layer[i],
+										   last_id_string.c_str());
 	}
 	
 	for (U32 i=0; i < mBakedTextureDatas.size(); i++)
 	{
-		if (use_lkg_baked_layer[i] && !self_customizing )
+		debugColorizeSubMeshes(i, LLColor4::white);
+
+		LLViewerTexLayerSet* layerset = getTexLayerSet(i);
+		if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() )
 		{
-			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host );
+			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);
 			mBakedTextureDatas[i].mIsUsed = TRUE;
-			for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
+
+			debugColorizeSubMeshes(i,LLColor4::red);
+
+			avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+			avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();
+			for (; iter != end; ++iter)
 			{
-				mBakedTextureDatas[i].mMeshes[k]->setTexture( baked_img );
+				LLAvatarJointMesh* mesh = (*iter);
+				if (mesh)
+				{
+					mesh->setTexture( baked_img );
+				}
 			}
 		}
-		else if (!self_customizing && is_layer_baked[i])
+		else if (!isUsingLocalAppearance() && is_layer_baked[i])
 		{
-			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
-			if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureIndex )
+			LLViewerFetchedTexture* baked_img =
+				LLViewerTextureManager::staticCastToFetchedTexture(
+					getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
+			if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureID )
 			{
-				// Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing).
+				// Even though the file may not be finished loading,
+				// we'll consider it loaded and use it (rather than
+				// doing compositing).
 				useBakedTexture( baked_img->getID() );
 			}
 			else
 			{
 				mBakedTextureDatas[i].mIsLoaded = FALSE;
-				if ( (baked_img->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
+				if ( (baked_img->getID() != IMG_INVISIBLE) &&
+					 ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
 				{			
 					baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ), 
 						src_callback_list, paused);	
@@ -6680,40 +6336,59 @@ void LLVOAvatar::updateMeshTextures()
 					src_callback_list, paused );
 			}
 		}
-		else if (mBakedTextureDatas[i].mTexLayerSet 
-				 && !other_culled) 
+		else if (layerset && isUsingLocalAppearance())
 		{
-			mBakedTextureDatas[i].mTexLayerSet->createComposite();
-			mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( TRUE );
+			debugColorizeSubMeshes(i,LLColor4::yellow );
+
+			layerset->createComposite();
+			layerset->setUpdatesEnabled( TRUE );
 			mBakedTextureDatas[i].mIsUsed = FALSE;
-			for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
+
+			avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+			avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();
+			for (; iter != end; ++iter)
 			{
-				mBakedTextureDatas[i].mMeshes[k]->setLayerSet( mBakedTextureDatas[i].mTexLayerSet );
+				LLAvatarJointMesh* mesh = (*iter);
+				if (mesh)
+				{
+					mesh->setLayerSet( layerset );
+				}
 			}
 		}
+		else
+		{
+			debugColorizeSubMeshes(i,LLColor4::blue);
+		}
 	}
 
 	// set texture and color of hair manually if we are not using a baked image.
 	// This can happen while loading hair for yourself, or for clients that did not
 	// bake a hair texture. Still needed for yourself after 1.22 is depricated.
-	if (!is_layer_baked[BAKED_HAIR] || self_customizing)
+	if (!is_layer_baked[BAKED_HAIR] || isEditingAppearance())
 	{
 		const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1);
 		LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 );
-		for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
+		avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin();
+		avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end();
+		for (; iter != end; ++iter)
 		{
-			mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
-			mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setTexture( hair_img );
+			LLAvatarJointMesh* mesh = (*iter);
+			if (mesh)
+			{
+				mesh->setColor( color );
+				mesh->setTexture( hair_img );
+			}
 		}
 	} 
 	
 	
-	for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
+			 LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
 		const EBakedTextureIndex baked_index = baked_iter->first;
-		const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+		const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
 		
 		for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 			 local_tex_iter != baked_dict->mLocalTextures.end();
@@ -6741,7 +6416,7 @@ void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, B
 }
 
 //virtual 
-void LLVOAvatar::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
+void LLVOAvatar::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
 {
 	// invalid for anyone but self
 	llassert(0);
@@ -6776,18 +6451,30 @@ void LLVOAvatar::clearChat()
 	mChats.clear();
 }
 
-// adds a morph mask to the appropriate baked texture structure
-void LLVOAvatar::addMaskedMorph(EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer)
+
+void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index)
 {
-	if (index < BAKED_NUM_INDICES)
+	if (index >= BAKED_NUM_INDICES)
 	{
-		LLMaskedMorph *morph = new LLMaskedMorph(morph_target, invert, layer);
-		mBakedTextureDatas[index].mMaskedMorphs.push_front(morph);
+		llwarns << "invalid baked texture index passed to applyMorphMask" << llendl;
+		return;
+	}
+
+	for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
+		 iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter)
+	{
+		const LLMaskedMorph* maskedMorph = (*iter);
+		LLPolyMorphTarget* morph_target = dynamic_cast<LLPolyMorphTarget*>(maskedMorph->mMorphTarget);
+		if (morph_target)
+		{
+			morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
+		}
 	}
 }
 
+
 // returns TRUE if morph masks are present and not valid for a given baked texture, FALSE otherwise
-BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index)
+BOOL LLVOAvatar::morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index)
 {
 	if (index >= BAKED_NUM_INDICES)
 	{
@@ -6798,7 +6485,7 @@ BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex inde
 	{
 		if (isSelf())
 		{
-			LLTexLayerSet *layer_set = mBakedTextureDatas[index].mTexLayerSet;
+			LLViewerTexLayerSet *layer_set = getTexLayerSet(index);
 			if (layer_set)
 			{
 				return !layer_set->isMorphValid();
@@ -6813,23 +6500,6 @@ BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex inde
 	return FALSE;
 }
 
-void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index)
-{
-	if (index >= BAKED_NUM_INDICES)
-	{
-		llwarns << "invalid baked texture index passed to applyMorphMask" << llendl;
-		return;
-	}
-
-	for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
-		 iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter)
-	{
-		const LLMaskedMorph* maskedMorph = (*iter);
-		maskedMorph->mMorphTarget->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
-	}
-}
-
-
 //-----------------------------------------------------------------------------
 // releaseComponentTextures()
 // release any component texture UUIDs for which we have a baked texture
@@ -6852,7 +6522,7 @@ void LLVOAvatar::releaseComponentTextures()
 
 	for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 	{
-		const LLVOAvatarDictionary::BakedEntry * bakedDicEntry = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+		const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
 		// skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID
 		if (!isTextureDefined(bakedDicEntry->mTextureIndex)
 			&& ( (baked_index != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT) ))
@@ -6868,120 +6538,14 @@ void LLVOAvatar::releaseComponentTextures()
 	}
 }
 
-//static
-BOOL LLVOAvatar::teToColorParams( ETextureIndex te, U32 *param_name )
-{
-	switch( te )
-	{
-		case TEX_UPPER_SHIRT:
-			param_name[0] = 803; //"shirt_red";
-			param_name[1] = 804; //"shirt_green";
-			param_name[2] = 805; //"shirt_blue";
-			break;
-
-		case TEX_LOWER_PANTS:
-			param_name[0] = 806; //"pants_red";
-			param_name[1] = 807; //"pants_green";
-			param_name[2] = 808; //"pants_blue";
-			break;
-
-		case TEX_LOWER_SHOES:
-			param_name[0] = 812; //"shoes_red";
-			param_name[1] = 813; //"shoes_green";
-			param_name[2] = 817; //"shoes_blue";
-			break;
-
-		case TEX_LOWER_SOCKS:
-			param_name[0] = 818; //"socks_red";
-			param_name[1] = 819; //"socks_green";
-			param_name[2] = 820; //"socks_blue";
-			break;
-
-		case TEX_UPPER_JACKET:
-		case TEX_LOWER_JACKET:
-			param_name[0] = 834; //"jacket_red";
-			param_name[1] = 835; //"jacket_green";
-			param_name[2] = 836; //"jacket_blue";
-			break;
-
-		case TEX_UPPER_GLOVES:
-			param_name[0] = 827; //"gloves_red";
-			param_name[1] = 829; //"gloves_green";
-			param_name[2] = 830; //"gloves_blue";
-			break;
-
-		case TEX_UPPER_UNDERSHIRT:
-			param_name[0] = 821; //"undershirt_red";
-			param_name[1] = 822; //"undershirt_green";
-			param_name[2] = 823; //"undershirt_blue";
-			break;
-	
-		case TEX_LOWER_UNDERPANTS:
-			param_name[0] = 824; //"underpants_red";
-			param_name[1] = 825; //"underpants_green";
-			param_name[2] = 826; //"underpants_blue";
-			break;
-
-		case TEX_SKIRT:
-			param_name[0] = 921; //"skirt_red";
-			param_name[1] = 922; //"skirt_green";
-			param_name[2] = 923; //"skirt_blue";
-			break;
-
-		case TEX_HEAD_TATTOO:
-		case TEX_LOWER_TATTOO:
-		case TEX_UPPER_TATTOO:
-			param_name[0] = 1071; //"tattoo_red";
-			param_name[1] = 1072; //"tattoo_green";
-			param_name[2] = 1073; //"tattoo_blue";
-			break;	
-
-		default:
-			llassert(0);
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL upload_bake )
-{
-	U32 param_name[3];
-	if( teToColorParams( te, param_name ) )
-	{
-		setVisualParamWeight( param_name[0], new_color.mV[VX], upload_bake );
-		setVisualParamWeight( param_name[1], new_color.mV[VY], upload_bake );
-		setVisualParamWeight( param_name[2], new_color.mV[VZ], upload_bake );
-	}
-}
-
-LLColor4 LLVOAvatar::getClothesColor( ETextureIndex te )
-{
-	LLColor4 color;
-	U32 param_name[3];
-	if( teToColorParams( te, param_name ) )
-	{
-		color.mV[VX] = getVisualParamWeight( param_name[0] );
-		color.mV[VY] = getVisualParamWeight( param_name[1] );
-		color.mV[VZ] = getVisualParamWeight( param_name[2] );
-	}
-	return color;
-}
-
-// static
-LLColor4 LLVOAvatar::getDummyColor()
-{
-	return DUMMY_COLOR;
-}
-
 void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const
 {	
 	LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL;
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		// TODO: MULTI-WEARABLE: handle multiple textures for self
 		const LLViewerTexture* te_image = getImage(iter->first,0);
 		if( !te_image )
@@ -7007,48 +6571,6 @@ void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const
 	}
 }
 
-// Unlike most wearable functions, this works for both self and other.
-BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
-{
-	if (mIsDummy) return TRUE;
-
-	switch(type)
-	{
-		case LLWearableType::WT_SHAPE:
-		case LLWearableType::WT_SKIN:
-		case LLWearableType::WT_HAIR:
-		case LLWearableType::WT_EYES:
-			return TRUE;  // everyone has all bodyparts
-		default:
-			break; // Do nothing
-	}
-
-	/* switch(type)
-		case LLWearableType::WT_SHIRT:
-			indicator_te = TEX_UPPER_SHIRT; */
-	for (LLVOAvatarDictionary::Textures::const_iterator tex_iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 tex_iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
-		 ++tex_iter)
-	{
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = tex_iter->second;
-		if (texture_dict->mWearableType == type)
-		{
-			// If you're checking another avatar's clothing, you don't have component textures.
-			// Thus, you must check to see if the corresponding baked texture is defined.
-			// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
-			// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
-			// gets baked into a texture that always exists (upper or lower).
-			if (texture_dict->mIsUsedByBakedTexture)
-			{
-				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
-				return isTextureDefined(LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
-			}
-			return FALSE;
-		}
-	}
-	return FALSE;
-}
-
 //-----------------------------------------------------------------------------
 // clampAttachmentPositions()
 //-----------------------------------------------------------------------------
@@ -7129,7 +6651,7 @@ LLBBox LLVOAvatar::getHUDBBox() const
 //-----------------------------------------------------------------------------
 void LLVOAvatar::onFirstTEMessageReceived()
 {
-	LL_INFOS("Avatar") << avString() << LL_ENDL;
+	LL_DEBUGS("Avatar") << avString() << LL_ENDL;
 	if( !mFirstTEMessageReceived )
 	{
 		mFirstTEMessageReceived = TRUE;
@@ -7151,7 +6673,7 @@ void LLVOAvatar::onFirstTEMessageReceived()
 			if (layer_baked)
 			{
 				LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
-				mBakedTextureDatas[i].mLastTextureIndex = image->getID();
+				mBakedTextureDatas[i].mLastTextureID = image->getID();
 				// If we have more than one texture for the other baked layers, we'll want to call this for them too.
 				if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
 				{
@@ -7203,133 +6725,345 @@ bool LLVOAvatar::visualParamWeightsAreDefault()
 	return rtn;
 }
 
+void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)
+{
+	std::string type_string = "unknown";
+	if (dynamic_cast<LLTexLayerParamAlpha*>(viewer_param))
+		type_string = "param_alpha";
+	if (dynamic_cast<LLTexLayerParamColor*>(viewer_param))
+		type_string = "param_color";
+	if (dynamic_cast<LLDriverParam*>(viewer_param))
+		type_string = "param_driver";
+	if (dynamic_cast<LLPolyMorphTarget*>(viewer_param))
+		type_string = "param_morph";
+	if (dynamic_cast<LLPolySkeletalDistortion*>(viewer_param))
+		type_string = "param_skeleton";
+	S32 wtype = -1;
+	LLViewerVisualParam *vparam = dynamic_cast<LLViewerVisualParam*>(viewer_param);
+	if (vparam)
+	{
+		wtype = vparam->getWearableType();
+	}
+	S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight());
+	apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\"/>\n",
+					viewer_param->getID(), viewer_param->getName().c_str(), value, u8_value, type_string.c_str(),
+					LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str()
+//					param_location_name(vparam->getParamLocation()).c_str()
+		);
+}
+
+
+void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,
+	const LLAppearanceMessageContents& contents)
+{
+	std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml");
+	const std::vector<F32>& params_for_dump = contents.mParamWeights;
+	const LLTEContents& tec = contents.mTEContents;
+
+	LLAPRFile outfile;
+	std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+	outfile.open(fullpath, LL_APR_WB );
+	apr_file_t* file = outfile.getFileHandle();
+	if (!file)
+	{
+		return;
+	}
+	else
+	{
+		LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << llendl;
+	}
+
+	apr_file_printf(file, "<header>\n");
+	apr_file_printf(file, "\t\t<cof_version %i />\n", contents.mCOFVersion);
+	apr_file_printf(file, "\t\t<appearance_version %i />\n", contents.mAppearanceVersion);
+	apr_file_printf(file, "</header>\n");
+
+	apr_file_printf(file, "\n<params>\n");
+	LLVisualParam* param = getFirstVisualParam();
+	for (S32 i = 0; i < params_for_dump.size(); i++)
+	{
+		while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
+		{
+			param = getNextVisualParam();
+		}
+		LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+		F32 value = params_for_dump[i];
+		dump_visual_param(file, viewer_param, value);
+		param = getNextVisualParam();
+	}
+	apr_file_printf(file, "</params>\n");
+
+	apr_file_printf(file, "\n<textures>\n");
+	for (U32 i = 0; i < tec.face_count; i++)
+	{
+		std::string uuid_str;
+		((LLUUID*)tec.image_data)[i].toString(uuid_str);
+		apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", i, uuid_str.c_str());
+	}
+	apr_file_printf(file, "</textures>\n");
+}
+
+void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents)
+{
+	parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, contents.mTEContents);
+
+	// Parse the AppearanceData field, if any.
+	if (mesgsys->has(_PREHASH_AppearanceData))
+	{
+		U8 av_u8;
+		mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, av_u8, 0);
+		contents.mAppearanceVersion = av_u8;
+		LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << llendl;
+		mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, contents.mCOFVersion, 0);
+		// For future use:
+		//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);
+	}
+
+	// Parse visual params, if any.
+	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
+	bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
+	if( num_blocks > 1 && !drop_visual_params_debug)
+	{
+		LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;
+		
+		LLVisualParam* param = getFirstVisualParam();
+		llassert(param); // if this ever fires, we should do the same as when num_blocks<=1
+		if (!param)
+		{
+			llwarns << "No visual params!" << llendl;
+		}
+		else
+		{
+			for( S32 i = 0; i < num_blocks; i++ )
+			{
+				while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
+				{
+					param = getNextVisualParam();
+				}
+						
+				if( !param )
+				{
+					// more visual params supplied than expected - just process what we know about
+					break;
+				}
+
+				U8 value;
+				mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i);
+				F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight());
+				contents.mParamWeights.push_back(newWeight);
+				contents.mParams.push_back(param);
+
+				param = getNextVisualParam();
+			}
+		}
+
+		const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
+		if (num_blocks != expected_tweakable_count)
+		{
+			LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << ").  Processing what we can.  object: " << getID() << llendl;
+		}
+	}
+	else
+	{
+		if (drop_visual_params_debug)
+		{
+			llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: "  << getID() << llendl;
+		}
+		else
+		{
+			LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;
+		}
+	}
+
+	LLVisualParam* appearance_version_param = getVisualParam(11000);
+	if (appearance_version_param)
+	{
+		std::vector<LLVisualParam*>::iterator it = std::find(contents.mParams.begin(), contents.mParams.end(),appearance_version_param);
+		if (it != contents.mParams.end())
+		{
+			S32 index = it - contents.mParams.begin();
+			contents.mParamAppearanceVersion = llround(contents.mParamWeights[index]);
+			LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << llendl;
+		}
+	}
+}
+
+bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32& appearance_version)
+{
+	appearance_version = -1;
+	
+	if ((contents.mAppearanceVersion) >= 0 &&
+		(contents.mParamAppearanceVersion >= 0) &&
+		(contents.mAppearanceVersion != contents.mParamAppearanceVersion))
+	{
+		llwarns << "inconsistent appearance_version settings - field: " <<
+			contents.mAppearanceVersion << ", param: " <<  contents.mParamAppearanceVersion << llendl;
+		return false;
+	}
+	if (contents.mParamAppearanceVersion >= 0) // use visual param if available.
+	{
+		appearance_version = contents.mParamAppearanceVersion;
+	}
+	if (contents.mAppearanceVersion >= 0)
+	{
+		appearance_version = contents.mAppearanceVersion;
+	}
+	if (appearance_version < 0) // still not set, go with 0.
+	{
+		appearance_version = 0;
+	}
+	LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion
+						<< " param: " << contents.mParamAppearanceVersion
+						<< " final: " << appearance_version << llendl;
+	return true;
+}
 
 //-----------------------------------------------------------------------------
 // processAvatarAppearance()
 //-----------------------------------------------------------------------------
 void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 {
+	LL_DEBUGS("Avatar") << "starts" << llendl;
+	
+	bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+	std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_";
 	if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages"))
 	{
 		llwarns << "Blocking AvatarAppearance message" << llendl;
 		return;
 	}
-	
-	BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived;
-	mFirstAppearanceMessageReceived = TRUE;
 
-	LL_INFOS("Avatar") << avString() << "processAvatarAppearance start " << mID
-			<< " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL;
+	ESex old_sex = getSex();
 
+	LLAppearanceMessageContents contents;
+	parseAppearanceMessage(mesgsys, contents);
+	if (enable_verbose_dumps)
+	{
+		dumpAppearanceMsgParams(dump_prefix + "appearance_msg", contents);
+	}
 
+	S32 appearance_version;
+	if (!resolve_appearance_version(contents, appearance_version))
+	{
+		llwarns << "bad appearance version info, discarding" << llendl;
+		return;
+	}
+	S32 this_update_cof_version = contents.mCOFVersion;
+	S32 last_update_request_cof_version = mLastUpdateRequestCOFVersion;
+
+	// Only now that we have result of appearance_version can we decide whether to bail out.
 	if( isSelf() )
 	{
-		llwarns << avString() << "Received AvatarAppearance for self" << llendl;
-		if( mFirstTEMessageReceived )
+		LL_DEBUGS("Avatar") << "this_update_cof_version " << this_update_cof_version
+				<< " last_update_request_cof_version " << last_update_request_cof_version
+				<<  " my_cof_version " << LLAppearanceMgr::instance().getCOFVersion() << llendl;
+
+		if (getRegion() && (getRegion()->getCentralBakeVersion()==0))
+		{
+			llwarns << avString() << "Received AvatarAppearance message for self in non-server-bake region" << llendl;
+		}
+		if( mFirstTEMessageReceived && (appearance_version == 0))
 		{
-//			llinfos << "processAvatarAppearance end  " << mID << llendl;
 			return;
 		}
 	}
+	else
+	{
+		LL_DEBUGS("Avatar") << "appearance message received" << llendl;
+	}
 
-	ESex old_sex = getSex();
+	// Check for stale update.
+	if (isSelf()
+		&& (appearance_version>0)
+		&& (this_update_cof_version < last_update_request_cof_version))
+	{
+		llwarns << "Stale appearance update, wanted version " << last_update_request_cof_version
+				<< ", got " << this_update_cof_version << llendl;
+		return;
+	}
 
-//	llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl;
-//	dumpAvatarTEs( "PRE  processAvatarAppearance()" );
-	unpackTEMessage(mesgsys, _PREHASH_ObjectData);
-//	dumpAvatarTEs( "POST processAvatarAppearance()" );
+	if (isSelf() && isEditingAppearance())
+	{
+		LL_DEBUGS("Avatar") << "ignoring appearance message while in appearance edit" << llendl;
+		return;
+	}
+
+	S32 num_params = contents.mParamWeights.size();
+	if (num_params <= 1)
+	{
+		// In this case, we have no reliable basis for knowing
+		// appearance version, which may cause us to look for baked
+		// textures in the wrong place and flag them as missing
+		// assets.
+		LL_DEBUGS("Avatar") << "ignoring appearance message due to lack of params" << llendl;
+		return;
+	}
+
+	mLastUpdateReceivedCOFVersion = this_update_cof_version;
+		
+	setIsUsingServerBakes(appearance_version > 0);
+
+	applyParsedTEMessage(contents.mTEContents);
 
 	// prevent the overwriting of valid baked textures with invalid baked textures
 	for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++)
 	{
 		if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex) 
-			&& mBakedTextureDatas[baked_index].mLastTextureIndex != IMG_DEFAULT
+			&& mBakedTextureDatas[baked_index].mLastTextureID != IMG_DEFAULT
 			&& baked_index != BAKED_SKIRT)
 		{
 			setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, 
-						LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, 
-																TRUE, 
-																LLViewerTexture::BOOST_NONE, 
-																LLViewerTexture::LOD_TEXTURE));
+				LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
 		}
 	}
 
-
 	// runway - was
 	// if (!is_first_appearance_message )
 	// which means it would be called on second appearance message - probably wrong.
+	BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived;
+	mFirstAppearanceMessageReceived = TRUE;
+
+	LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID
+			<< " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL;
+
 	if (is_first_appearance_message )
 	{
 		onFirstTEMessageReceived();
 	}
 
 	setCompositeUpdatesEnabled( FALSE );
-	mMeshTexturesDirty = TRUE;
 	gPipeline.markGLRebuild(this);
 
-	// ! BACKWARDS COMPATIBILITY !
-	// Non-self avatars will no longer have component textures
-	if (!isSelf())
-	{
-		releaseComponentTextures();
-	}
-	
-	// parse visual params
-	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
-	bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
-	if( num_blocks > 1 && !drop_visual_params_debug)
+	// Apply visual params
+	if( num_params > 1)
 	{
-		LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;
+		LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL;
 		BOOL params_changed = FALSE;
-		BOOL interp_params = FALSE;
-		
-		LLVisualParam* param = getFirstVisualParam();
-		llassert(param); // if this ever fires, we should do the same as when num_blocks<=1
-		if (!param)
-		{
-			llwarns << "No visual params!" << llendl;
-		}
-		else
+		BOOL interp_params = FALSE;
+		
+		for( S32 i = 0; i < num_params; i++ )
 		{
-			for( S32 i = 0; i < num_blocks; i++ )
+			LLVisualParam* param = contents.mParams[i];
+			F32 newWeight = contents.mParamWeights[i];
+
+			if (is_first_appearance_message || (param->getWeight() != newWeight))
 			{
-				while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
-				{
-					param = getNextVisualParam();
-				}
-						
-				if( !param )
+				params_changed = TRUE;
+				if(is_first_appearance_message)
 				{
-					// more visual params supplied than expected - just process what we know about
-					break;
+					param->setWeight(newWeight, FALSE);
 				}
-
-				U8 value;
-				mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i);
-				F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight());
-
-				if (is_first_appearance_message || (param->getWeight() != newWeight))
+				else
 				{
-					//llinfos << "Received update for param " << param->getDisplayName() << " at value " << newWeight << llendl;
-					params_changed = TRUE;
-					if(is_first_appearance_message)
-					{
-						param->setWeight(newWeight, FALSE);
-					}
-					else
-					{
-						interp_params = TRUE;
-						param->setAnimationTarget(newWeight, FALSE);
-					}
+					interp_params = TRUE;
+					param->setAnimationTarget(newWeight, FALSE);
 				}
-				param = getNextVisualParam();
 			}
 		}
-
 		const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
-		if (num_blocks != expected_tweakable_count)
+		if (num_params != expected_tweakable_count)
 		{
-			llinfos << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << ").  Processing what we can.  object: " << getID() << llendl;
+			LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_params << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << ").  Processing what we can.  object: " << getID() << llendl;
 		}
 
 		if (params_changed)
@@ -7353,14 +7087,6 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 	{
 		// AvatarAppearance message arrived without visual params
 		LL_DEBUGS("Avatar") << avString() << "no visual params" << LL_ENDL;
-		if (drop_visual_params_debug)
-		{
-			llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: "  << getID() << llendl;
-		}
-		else
-		{
-			llinfos << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;
-		}
 
 		const F32 LOADING_TIMEOUT_SECONDS = 60.f;
 		// this isn't really a problem if we already have a non-default shape
@@ -7383,7 +7109,14 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 	// If all of the avatars are completely baked, release the global image caches to conserve memory.
 	LLVOAvatar::cullAvatarsByPixelArea();
 
-//	llinfos << "processAvatarAppearance end " << mID << llendl;
+	if (isSelf())
+	{
+		mUseLocalAppearance = false;
+	}
+
+	updateMeshTextures();
+
+	//if (enable_verbose_dumps) dumpArchetypeXML(dump_prefix + "process_end");
 }
 
 // static
@@ -7413,6 +7146,7 @@ void LLVOAvatar::getAnimNames( LLDynamicArray<std::string>* names )
 	names->put( "enter_away_from_keyboard_state" );
 }
 
+// static
 void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
 {
 	if (!userdata) return;
@@ -7431,7 +7165,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
 		{
 			if (!aux_src->getData())
 			{
-				llerrs << "No auxiliary source data for onBakedTextureMasksLoaded" << llendl;
+				llerrs << "No auxiliary source (morph mask) data for image id " << id << llendl;
 				return;
 			}
 
@@ -7456,12 +7190,12 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
 					 self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
 					 maskData->mLastDiscardLevel = discard_level; */
 			BOOL found_texture_id = false;
-			for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-				 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+			for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+				 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 				 ++iter)
 			{
 
-				const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+				const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 				if (texture_dict->mIsUsedByBakedTexture)
 				{
 					const ETextureIndex texture_index = iter->first;
@@ -7483,7 +7217,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
 			}
 			if (!found_texture_id)
 			{
-				llinfos << "onBakedTextureMasksLoaded(): unexpected image id: " << id << llendl;
+				llinfos << "unexpected image id: " << id << llendl;
 			}
 			self->dirtyMesh();
 		}
@@ -7491,7 +7225,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
 		{
             // this can happen when someone uses an old baked texture possibly provided by 
             // viewer-side baked texture caching
-			llwarns << "Masks loaded callback but NO aux source!" << llendl;
+			llwarns << "Masks loaded callback but NO aux source, id " << id << llendl;
 		}
 	}
 
@@ -7529,7 +7263,7 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success,
 									  LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src,
 									  S32 discard_level, BOOL final, void* userdata)
 {
-	//llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl;
+	LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL;
 
 	LLUUID id = src_vi->getID();
 	LLUUID *avatar_idp = (LLUUID *)userdata;
@@ -7566,17 +7300,31 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
 		{
 			LL_DEBUGS("Avatar") << avString() << " i " << i << " id " << id << LL_ENDL;
 			mBakedTextureDatas[i].mIsLoaded = true;
-			mBakedTextureDatas[i].mLastTextureIndex = id;
+			mBakedTextureDatas[i].mLastTextureID = id;
 			mBakedTextureDatas[i].mIsUsed = true;
-			for (U32 k = 0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
+
+			if (isUsingLocalAppearance())
 			{
-				mBakedTextureDatas[i].mMeshes[k]->setTexture( image_baked );
+				llinfos << "not changing to baked texture while isUsingLocalAppearance" << llendl;
 			}
-			if (mBakedTextureDatas[i].mTexLayerSet)
+			else
 			{
-				//mBakedTextureDatas[i].mTexLayerSet->destroyComposite();
+				debugColorizeSubMeshes(i,LLColor4::green);
+
+				avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+				avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();
+				for (; iter != end; ++iter)
+				{
+					LLAvatarJointMesh* mesh = (*iter);
+					if (mesh)
+					{
+						mesh->setTexture( image_baked );
+					}
+				}
 			}
-			const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+			
+			const LLAvatarAppearanceDictionary::BakedEntry *baked_dict =
+				LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
 			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 				 local_tex_iter != baked_dict->mLocalTextures.end();
 				 ++local_tex_iter)
@@ -7589,9 +7337,15 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
 			// This is paired with similar code in updateMeshTextures that sets hair mesh color.
 			if (i == BAKED_HAIR)
 			{
-				for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
+				avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+				avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();
+				for (; iter != end; ++iter)
 				{
-					mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( 1.f, 1.f, 1.f, 1.f );
+					LLAvatarJointMesh* mesh = (*iter);
+					if (mesh)
+					{
+						mesh->setColor( LLColor4::white );
+					}
 				}
 			}
 		}
@@ -7600,11 +7354,39 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
 	dirtyMesh();
 }
 
-// static
-void LLVOAvatar::dumpArchetypeXML( void* )
+std::string get_sequential_numbered_file_name(const std::string& prefix,
+											  const std::string& suffix)
+{
+	typedef std::map<std::string,S32> file_num_type;
+	static  file_num_type file_nums;
+	file_num_type::iterator it = file_nums.find(prefix);
+	S32 num = 0;
+	if (it != file_nums.end())
+	{
+		num = it->second;
+	}
+	file_nums[prefix] = num+1;
+	std::string outfilename = prefix + " " + llformat("%04d",num) + ".xml";
+	std::replace(outfilename.begin(),outfilename.end(),' ','_');
+	return outfilename;
+}
+
+void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_wearables )
 {
+	std::string outprefix(prefix);
+	if (outprefix.empty())
+	{
+		outprefix = getFullname() + (isSelf()?"_s":"_o");
+	}
+	if (outprefix.empty())
+	{
+		outprefix = std::string("new_archetype");
+	}
+	std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml");
+	
 	LLAPRFile outfile;
-	outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"new archetype.xml"), LL_APR_WB );
+	std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+	outfile.open(fullpath, LL_APR_WB );
 	apr_file_t* file = outfile.getFileHandle();
 	if (!file)
 	{
@@ -7612,36 +7394,60 @@ void LLVOAvatar::dumpArchetypeXML( void* )
 	}
 	else
 	{
-		llinfos << "xmlfile write handle obtained : " << gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"new archetype.xml") << llendl;
+		llinfos << "xmlfile write handle obtained : " << fullpath << llendl;
 	}
 
 	apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" );
 	apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" );
 	apr_file_printf( file, "\n\t<archetype name=\"???\">\n" );
 
-	// only body parts, not clothing.
-	for (S32 type = LLWearableType::WT_SHAPE; type <= LLWearableType::WT_EYES; type++)
+	if (group_by_wearables)
 	{
-		const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type);
-		apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
-
-		for (LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam())
+		for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++)
 		{
-			LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
-			if( (viewer_param->getWearableType() == type) && 
-				(viewer_param->isTweakable() ) )
+			const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type);
+			apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
+
+			for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
 			{
-				apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\"/>\n",
-								viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight());
+				LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+				if( (viewer_param->getWearableType() == type) && 
+					(viewer_param->isTweakable() ) )
+				{
+					dump_visual_param(file, viewer_param, viewer_param->getWeight());
+				}
+			}
+
+			for (U8 te = 0; te < TEX_NUM_INDICES; te++)
+			{
+				if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type)
+				{
+					// MULTIPLE_WEARABLES: extend to multiple wearables?
+					LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
+					if( te_image )
+					{
+						std::string uuid_str;
+						te_image->getID().toString( uuid_str );
+						apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
+					}
+				}
 			}
 		}
+	}
+	else 
+	{
+		// Just dump all params sequentially.
+		for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
+		{
+			LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+			dump_visual_param(file, viewer_param, viewer_param->getWeight());
+		}
 
 		for (U8 te = 0; te < TEX_NUM_INDICES; te++)
 		{
-			if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te) == type)
 			{
 				// MULTIPLE_WEARABLES: extend to multiple wearables?
-				LLViewerTexture* te_image = ((LLVOAvatar *)(gAgentAvatarp))->getImage((ETextureIndex)te, 0);
+				LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
 				if( te_image )
 				{
 					std::string uuid_str;
@@ -7650,14 +7456,18 @@ void LLVOAvatar::dumpArchetypeXML( void* )
 				}
 			}
 		}
+
 	}
 	apr_file_printf( file, "\t</archetype>\n" );
 	apr_file_printf( file, "\n</linden_genepool>\n" );
-	//explictly close the file if it is still open which it should be
-	if (file)
+
+	bool ultra_verbose = false;
+	if (isSelf() && ultra_verbose)
 	{
-		outfile.close();
+		// show the cloned params inside the wearables as well.
+		gAgentAvatarp->dumpWearableInfo(outfile);
 	}
+	// File will close when handle goes out of scope
 }
 
 
@@ -7739,15 +7549,9 @@ void LLVOAvatar::cullAvatarsByPixelArea()
 		}
 	}
 
-	// runway - this doesn't detect gray/grey state.
-	// think we just need to be checking self av since it's the only
-	// one with lltexlayer stuff.
+	// runway - this doesn't really detect gray/grey state.
 	S32 grey_avatars = 0;
-	if (LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars))
-	{
-		LLVOAvatar::deleteCachedImages(false);
-	}
-	else
+	if (!LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars))
 	{
 		if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame
 		{
@@ -7775,501 +7579,44 @@ void LLVOAvatar::startAppearanceAnimation()
 	}
 }
 
-// virtual
-void LLVOAvatar::removeMissingBakedTextures()
-{	
-}
-
-//-----------------------------------------------------------------------------
-// LLVOAvatarXmlInfo
-//-----------------------------------------------------------------------------
-
-LLVOAvatar::LLVOAvatarXmlInfo::LLVOAvatarXmlInfo()
-	: mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0)
-{
-}
-
-LLVOAvatar::LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo()
-{
-	std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer());
-	std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());		
-	std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer());
-	deleteAndClear(mTexSkinColorInfo);
-	deleteAndClear(mTexHairColorInfo);
-	deleteAndClear(mTexEyeColorInfo);
-	std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());		
-	std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer());
-	std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
-}
-
-////-----------------------------------------------------------------------------
-//// LLVOAvatarBoneInfo::parseXml()
-////-----------------------------------------------------------------------------
-//BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
-//{
-//	if (node->hasName("bone"))
-//	{
-//		mIsJoint = TRUE;
-//		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-//		if (!node->getFastAttributeString(name_string, mName))
-//		{
-//			llwarns << "Bone without name" << llendl;
-//			return FALSE;
-//		}
-//	}
-//	else if (node->hasName("collision_volume"))
-//	{
-//		mIsJoint = FALSE;
-//		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-//		if (!node->getFastAttributeString(name_string, mName))
-//		{
-//			mName = "Collision Volume";
-//		}
-//	}
-//	else
-//	{
-//		llwarns << "Invalid node " << node->getName() << llendl;
-//		return FALSE;
-//	}
-//
-//	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
-//	if (!node->getFastAttributeVector3(pos_string, mPos))
-//	{
-//		llwarns << "Bone without position" << llendl;
-//		return FALSE;
-//	}
-//
-//	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
-//	if (!node->getFastAttributeVector3(rot_string, mRot))
-//	{
-//		llwarns << "Bone without rotation" << llendl;
-//		return FALSE;
-//	}
-//	
-//	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
-//	if (!node->getFastAttributeVector3(scale_string, mScale))
-//	{
-//		llwarns << "Bone without scale" << llendl;
-//		return FALSE;
-//	}
-//
-//	if (mIsJoint)
-//	{
-//		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
-//		if (!node->getFastAttributeVector3(pivot_string, mPivot))
-//		{
-//			llwarns << "Bone without pivot" << llendl;
-//			return FALSE;
-//		}
-//	}
-//
-//	// parse children
-//	LLXmlTreeNode* child;
-//	for( child = node->getFirstChild(); child; child = node->getNextChild() )
-//	{
-//		LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo;
-//		if (!child_info->parseXml(child))
-//		{
-//			delete child_info;
-//			return FALSE;
-//		}
-//		mChildList.push_back(child_info);
-//	}
-//	return TRUE;
-//}
-//
-////-----------------------------------------------------------------------------
-//// LLVOAvatarSkeletonInfo::parseXml()
-////-----------------------------------------------------------------------------
-//BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
-//{
-//	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
-//	if (!node->getFastAttributeS32(num_bones_string, mNumBones))
-//	{
-//		llwarns << "Couldn't find number of bones." << llendl;
-//		return FALSE;
-//	}
-//
-//	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
-//	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
-//
-//	LLXmlTreeNode* child;
-//	for( child = node->getFirstChild(); child; child = node->getNextChild() )
-//	{
-//		LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo;
-//		if (!info->parseXml(child))
-//		{
-//			delete info;
-//			llwarns << "Error parsing bone in skeleton file" << llendl;
-//			return FALSE;
-//		}
-//		mBoneInfoList.push_back(info);
-//	}
-//	return TRUE;
-//}
-
-//-----------------------------------------------------------------------------
-// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)
-{
-	LLXmlTreeNode* node = root->getChildByName( "skeleton" );
-	if( !node )
-	{
-		llwarns << "avatar file: missing <skeleton>" << llendl;
-		return FALSE;
-	}
-
-	LLXmlTreeNode* child;
-
-	// SKELETON DISTORTIONS
-	for (child = node->getChildByName( "param" );
-		 child;
-		 child = node->getNextNamedChild())
-	{
-		if (!child->getChildByName("param_skeleton"))
-		{
-			if (child->getChildByName("param_morph"))
-			{
-				llwarns << "Can't specify morph param in skeleton definition." << llendl;
-			}
-			else
-			{
-				llwarns << "Unknown param type." << llendl;
-			}
-			continue;
-		}
-		
-		LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo;
-		if (!info->parseXml(child))
-		{
-			delete info;
-			return FALSE;
-		}
-
-		mSkeletalDistortionInfoList.push_back(info);
-	}
-
-	// ATTACHMENT POINTS
-	for (child = node->getChildByName( "attachment_point" );
-		 child;
-		 child = node->getNextNamedChild())
-	{
-		LLVOAvatarAttachmentInfo* info = new LLVOAvatarAttachmentInfo();
-
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-		if (!child->getFastAttributeString(name_string, info->mName))
-		{
-			llwarns << "No name supplied for attachment point." << llendl;
-			delete info;
-			continue;
-		}
-
-		static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint");
-		if (!child->getFastAttributeString(joint_string, info->mJointName))
-		{
-			llwarns << "No bone declared in attachment point " << info->mName << llendl;
-			delete info;
-			continue;
-		}
-
-		static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position");
-		if (child->getFastAttributeVector3(position_string, info->mPosition))
-		{
-			info->mHasPosition = TRUE;
-		}
-
-		static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation");
-		if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler))
-		{
-			info->mHasRotation = TRUE;
-		}
-		 static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group");
-		if (child->getFastAttributeS32(group_string, info->mGroup))
-		{
-			if (info->mGroup == -1)
-				info->mGroup = -1111; // -1 = none parsed, < -1 = bad value
-		}
-
-		static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
-		if (!child->getFastAttributeS32(id_string, info->mAttachmentID))
-		{
-			llwarns << "No id supplied for attachment point " << info->mName << llendl;
-			delete info;
-			continue;
-		}
-
-		static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice");
-		child->getFastAttributeS32(slot_string, info->mPieMenuSlice);
-			
-		static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person");
-		child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson);
-
-		static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud");
-		child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment);
-
-		mAttachmentInfoList.push_back(info);
-	}
-
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// parseXmlMeshNodes(): parses <mesh> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root)
+//virtual
+void LLVOAvatar::bodySizeChanged()
 {
-	for (LLXmlTreeNode* node = root->getChildByName( "mesh" );
-		 node;
-		 node = root->getNextNamedChild())
-	{
-		LLVOAvatarMeshInfo *info = new LLVOAvatarMeshInfo;
-
-		// attribute: type
-		static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type");
-		if( !node->getFastAttributeString( type_string, info->mType ) )
-		{
-			llwarns << "Avatar file: <mesh> is missing type attribute.  Ignoring element. " << llendl;
-			delete info;
-			return FALSE;  // Ignore this element
-		}
-		
-		static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod");
-		if (!node->getFastAttributeS32( lod_string, info->mLOD ))
-		{
-			llwarns << "Avatar file: <mesh> is missing lod attribute.  Ignoring element. " << llendl;
-			delete info;
-			return FALSE;  // Ignore this element
-		}
-
-		static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
-		if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) )
-		{
-			llwarns << "Avatar file: <mesh> is missing file_name attribute.  Ignoring: " << info->mType << llendl;
-			delete info;
-			return FALSE;  // Ignore this element
-		}
-
-		static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference");
-		node->getFastAttributeString( reference_string, info->mReferenceMeshName );
-		
-		// attribute: min_pixel_area
-		static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area");
-		static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width");
-		if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea ))
-		{
-			F32 min_pixel_area = 0.1f;
-			if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area ))
-			{
-				// this is square root of pixel area (sensible to use linear space in defining lods)
-				min_pixel_area = min_pixel_area * min_pixel_area;
-			}
-			info->mMinPixelArea = min_pixel_area;
-		}
-		
-		// Parse visual params for this node only if we haven't already
-		for (LLXmlTreeNode* child = node->getChildByName( "param" );
-			 child;
-			 child = node->getNextNamedChild())
-		{
-			if (!child->getChildByName("param_morph"))
-			{
-				if (child->getChildByName("param_skeleton"))
-				{
-					llwarns << "Can't specify skeleton param in a mesh definition." << llendl;
-				}
-				else
-				{
-					llwarns << "Unknown param type." << llendl;
-				}
-				continue;
-			}
-
-			LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo();
-			if (!morphinfo->parseXml(child))
-			{
-				delete morphinfo;
-				delete info;
-				return -1;
-			}
-			BOOL shared = FALSE;
-			static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared");
-			child->getFastAttributeBOOL(shared_string, shared);
-
-			info->mPolyMorphTargetInfoList.push_back(LLVOAvatarMeshInfo::morph_info_pair_t(morphinfo, shared));
-		}
-
-		mMeshInfoList.push_back(info);
+	if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF())
+	{	// notify simulator of change in size
+		// but not if we are in the middle of updating appearance
+		gAgent.sendAgentSetAppearance();
 	}
-	return TRUE;
 }
 
-//-----------------------------------------------------------------------------
-// parseXmlColorNodes(): parses <global_color> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
+BOOL LLVOAvatar::isUsingServerBakes() const
 {
-	for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" );
-		 color_node;
-		 color_node = root->getNextNamedChild())
+#if 1
+	// Sanity check - visual param for appearance version should match mUseServerBakes
+	LLVisualParam* appearance_version_param = getVisualParam(11000);
+	llassert(appearance_version_param);
+	F32 wt = appearance_version_param->getWeight();
+	F32 expect_wt = mUseServerBakes ? 1.0 : 0.0;
+	if (!is_approx_equal(wt,expect_wt))
 	{
-		std::string global_color_name;
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-		if (color_node->getFastAttributeString( name_string, global_color_name ) )
-		{
-			if( global_color_name == "skin_color" )
-			{
-				if (mTexSkinColorInfo)
-				{
-					llwarns << "avatar file: multiple instances of skin_color" << llendl;
-					return FALSE;
-				}
-				mTexSkinColorInfo = new LLTexGlobalColorInfo;
-				if( !mTexSkinColorInfo->parseXml( color_node ) )
-				{
-					deleteAndClear(mTexSkinColorInfo);
-					llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl;
-					return FALSE;
-				}
-			}
-			else if( global_color_name == "hair_color" )
-			{
-				if (mTexHairColorInfo)
-				{
-					llwarns << "avatar file: multiple instances of hair_color" << llendl;
-					return FALSE;
-				}
-				mTexHairColorInfo = new LLTexGlobalColorInfo;
-				if( !mTexHairColorInfo->parseXml( color_node ) )
-				{
-					deleteAndClear(mTexHairColorInfo);
-					llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl;
-					return FALSE;
-				}
-			}
-			else if( global_color_name == "eye_color" )
-			{
-				if (mTexEyeColorInfo)
-				{
-					llwarns << "avatar file: multiple instances of eye_color" << llendl;
-					return FALSE;
-				}
-				mTexEyeColorInfo = new LLTexGlobalColorInfo;
-				if( !mTexEyeColorInfo->parseXml( color_node ) )
-				{
-					llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl;
-					return FALSE;
-				}
-			}
-		}
+		llwarns << "wt " << wt << " differs from expected " << expect_wt << llendl;
 	}
-	return TRUE;
-}
+#endif
 
-//-----------------------------------------------------------------------------
-// parseXmlLayerNodes(): parses <layer_set> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root)
-{
-	for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" );
-		 layer_node;
-		 layer_node = root->getNextNamedChild())
-	{
-		LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo();
-		if( layer_info->parseXml( layer_node ) )
-		{
-			mLayerInfoList.push_back(layer_info);
-		}
-		else
-		{
-			delete layer_info;
-			llwarns << "avatar file: layer_set->parseXml() failed" << llendl;
-			return FALSE;
-		}
-	}
-	return TRUE;
+	return mUseServerBakes;
 }
 
-//-----------------------------------------------------------------------------
-// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root)
+void LLVOAvatar::setIsUsingServerBakes(BOOL newval)
 {
-	LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" );
-	if( driver )
-	{
-		for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" );
-			 grand_child;
-			 grand_child = driver->getNextNamedChild())
-		{
-			if( grand_child->getChildByName( "param_driver" ) )
-			{
-				LLDriverParamInfo* driver_info = new LLDriverParamInfo();
-				if( driver_info->parseXml( grand_child ) )
-				{
-					mDriverInfoList.push_back(driver_info);
-				}
-				else
-				{
-					delete driver_info;
-					llwarns << "avatar file: driver_param->parseXml() failed" << llendl;
-					return FALSE;
-				}
-			}
-		}
-	}
-	return TRUE;
+	mUseServerBakes = newval;
+	LLVisualParam* appearance_version_param = getVisualParam(11000);
+	llassert(appearance_version_param);
+	appearance_version_param->setWeight(newval ? 1.0 : 0.0, false);
 }
 
-//-----------------------------------------------------------------------------
-// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root)
-{
-	LLXmlTreeNode* masks = root->getChildByName( "morph_masks" );
-	if( !masks )
-	{
-		return FALSE;
-	}
-
-	for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" );
-		 grand_child;
-		 grand_child = masks->getNextNamedChild())
-	{
-		LLVOAvatarMorphInfo* info = new LLVOAvatarMorphInfo();
-
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name");
-		if (!grand_child->getFastAttributeString(name_string, info->mName))
-		{
-			llwarns << "No name supplied for morph mask." << llendl;
-			delete info;
-			continue;
-		}
-
-		static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region");
-		if (!grand_child->getFastAttributeString(region_string, info->mRegion))
-		{
-			llwarns << "No region supplied for morph mask." << llendl;
-			delete info;
-			continue;
-		}
-
-		static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer");
-		if (!grand_child->getFastAttributeString(layer_string, info->mLayer))
-		{
-			llwarns << "No layer supplied for morph mask." << llendl;
-			delete info;
-			continue;
-		}
-
-		// optional parameter. don't throw a warning if not present.
-		static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert");
-		grand_child->getFastAttributeBOOL(invert_string, info->mInvert);
-
-		mMorphMaskInfoList.push_back(info);
-	}
-
-	return TRUE;
+// virtual
+void LLVOAvatar::removeMissingBakedTextures()
+{	
 }
 
 //virtual
@@ -8445,7 +7792,7 @@ void LLVOAvatar::idleUpdateRenderCost()
 
 	for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 	{
-		const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+		const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
 		ETextureIndex tex_index = baked_dict->mTextureIndex;
 		if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
 		{
@@ -8525,11 +7872,11 @@ void LLVOAvatar::idleUpdateRenderCost()
 		}
 
 		// print any avatar textures we didn't already know about
-		for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-			 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+		for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+			 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 			 ++iter)
 		{
-			const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+			const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 			// TODO: MULTI-WEARABLE: handle multiple textures for self
 			const LLViewerTexture* te_image = getImage(iter->first,0);
 			if (!te_image)
@@ -8558,26 +7905,26 @@ void LLVOAvatar::idleUpdateRenderCost()
 BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index)
 {
 	if (index < 0 || index >= TEX_NUM_INDICES) return false;
-	return LLVOAvatarDictionary::getInstance()->getTexture(index)->mIsLocalTexture;
+	return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsLocalTexture;
 }
 
 // static
 BOOL LLVOAvatar::isIndexBakedTexture(ETextureIndex index)
 {
 	if (index < 0 || index >= TEX_NUM_INDICES) return false;
-	return LLVOAvatarDictionary::getInstance()->getTexture(index)->mIsBakedTexture;
+	return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsBakedTexture;
 }
 
 const std::string LLVOAvatar::getBakedStatusForPrintout() const
 {
 	std::string line;
 
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
 		const ETextureIndex index = iter->first;
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		if (texture_dict->mIsBakedTexture)
 		{
 			line += texture_dict->mName;
@@ -8609,7 +7956,7 @@ F32 calc_bouncy_animation(F32 x)
 }
 
 //virtual
-BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index ) const
+BOOL LLVOAvatar::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index ) const
 {
 	if (isIndexLocalTexture(te)) 
 	{
@@ -8627,7 +7974,7 @@ BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index
 }
 
 //virtual
-BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
 {
 	if (isIndexLocalTexture(type))
 	{
@@ -8643,9 +7990,11 @@ BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 ind
 }
 
 //virtual
-BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const
+BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const
 {
 	// non-self avatars don't have wearables
 	return FALSE;
 }
 
+
+
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
old mode 100644
new mode 100755
index 9f1f209920860b68609715a63fe23eaea514c1f1..85f6f25009644fd924decf48af9f1fcdc279dcfe
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -25,8 +25,8 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_LLVOAVATAR_H
-#define LL_LLVOAVATAR_H
+#ifndef LL_VOAVATAR_H
+#define LL_VOAVATAR_H
 
 #include <map>
 #include <deque>
@@ -36,6 +36,7 @@
 #include <boost/signals2.hpp>
 
 #include "imageids.h"			// IMG_INVISIBLE
+#include "llavatarappearance.h"
 #include "llchat.h"
 #include "lldrawpoolalpha.h"
 #include "llviewerobject.h"
@@ -44,9 +45,10 @@
 #include "llviewerjointmesh.h"
 #include "llviewerjointattachment.h"
 #include "llrendertarget.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
 #include "lltexglobalcolor.h"
 #include "lldriverparam.h"
+#include "llviewertexlayer.h"
 #include "material_codes.h"		// LL_MCODE_END
 #include "llviewerstats.h"
 
@@ -62,13 +64,15 @@ extern const LLUUID ANIM_AGENT_PELVIS_FIX;
 extern const LLUUID ANIM_AGENT_TARGET;
 extern const LLUUID ANIM_AGENT_WALK_ADJUST;
 
-class LLTexLayerSet;
+class LLViewerWearable;
 class LLVoiceVisualizer;
 class LLHUDNameTag;
 class LLHUDEffectSpiral;
 class LLTexGlobalColor;
 struct LLVOAvatarBoneInfo;
 struct LLVOAvatarChildJoint;
+//class LLViewerJoint;
+struct LLAppearanceMessageContents;
 struct LLVOAvatarSkeletonInfo;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -76,17 +80,14 @@ struct LLVOAvatarSkeletonInfo;
 // 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLVOAvatar :
+	public LLAvatarAppearance,
 	public LLViewerObject,
-	public LLCharacter,
 	public boost::signals2::trackable
 {
 	LOG_CLASS(LLVOAvatar);
 
 public:
 	friend class LLVOAvatarSelf;
-protected:
-	struct LLVOAvatarXmlInfo;
-	struct LLMaskedMorph;
 
 /********************************************************************************
  **                                                                            **
@@ -111,9 +112,6 @@ class LLVOAvatar :
 	virtual void 		initInstance(); // Called after construction to initialize the class.
 protected:
 	virtual				~LLVOAvatar();
-	BOOL				loadSkeletonNode();
-	BOOL				loadMeshNodes();
-	virtual BOOL		loadLayersets();
 
 /**                    Initialization
  **                                                                            **
@@ -128,31 +126,43 @@ class LLVOAvatar :
 	// LLViewerObject interface and related
 	//--------------------------------------------------------------------
 public:
-	virtual void			updateGL();
-	virtual	LLVOAvatar*		asAvatar();
-	virtual U32    	 	 	processUpdateMessage(LLMessageSystem *mesgsys,
+	/*virtual*/ void			updateGL();
+	/*virtual*/ LLVOAvatar*		asAvatar();
+	virtual U32    	 	 		processUpdateMessage(LLMessageSystem *mesgsys,
 													 void **user_data,
 													 U32 block_num,
 													 const EObjectUpdateType update_type,
 													 LLDataPacker *dp);
-	virtual void   	 	 	idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
-	virtual BOOL   	 	 	updateLOD();
-	BOOL  	 	 	 	 	updateJointLODs();
-	void					updateLODRiggedAttachments( void );
-	virtual BOOL   	 	 	isActive() const; // Whether this object needs to do an idleUpdate.
-	virtual void   	 	 	updateTextures();
-	virtual S32    	 	 	setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim.
-	virtual void   	 	 	onShift(const LLVector4a& shift_vector);
-	virtual U32    	 	 	getPartitionType() const;
-	virtual const  	 	 	LLVector3 getRenderPosition() const;
-	virtual void   	 	 	updateDrawable(BOOL force_damped);
-	virtual LLDrawable* 	createDrawable(LLPipeline *pipeline);
-	virtual BOOL   	 	 	updateGeometry(LLDrawable *drawable);
-	virtual void   	 	 	setPixelAreaAndAngle(LLAgent &agent);
-	virtual void   	 	 	updateRegion(LLViewerRegion *regionp);
-	virtual void   	 	 	updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax);
-	virtual void   	 	 	getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
-	virtual BOOL   	 	 	lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+	virtual void   	 	 		idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+	/*virtual*/ BOOL   	 	 	updateLOD();
+	BOOL  	 	 	 	 		updateJointLODs();
+	void						updateLODRiggedAttachments( void );
+	/*virtual*/ BOOL   	 	 	isActive() const; // Whether this object needs to do an idleUpdate.
+	S32 						totalTextureMemForUUIDS(std::set<LLUUID>& ids);
+	bool 						allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const;
+	bool 						allLocalTexturesCompletelyDownloaded() const;
+	bool 						allBakedTexturesCompletelyDownloaded() const;
+	void 						bakedTextureOriginCounts(S32 &sb_count, S32 &host_count,
+														 S32 &both_count, S32 &neither_count);
+	std::string 				bakedTextureOriginInfo();
+	void 						collectLocalTextureUUIDs(std::set<LLUUID>& ids) const;
+	void 						collectBakedTextureUUIDs(std::set<LLUUID>& ids) const;
+	void 						collectTextureUUIDs(std::set<LLUUID>& ids);
+	void						releaseOldTextures();
+	/*virtual*/ void   	 	 	updateTextures();
+	LLViewerFetchedTexture*		getBakedTextureImage(const U8 te, const LLUUID& uuid);
+	/*virtual*/ S32    	 	 	setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim.
+	/*virtual*/ void   	 	 	onShift(const LLVector4a& shift_vector);
+	/*virtual*/ U32    	 	 	getPartitionType() const;
+	/*virtual*/ const  	 	 	LLVector3 getRenderPosition() const;
+	/*virtual*/ void   	 	 	updateDrawable(BOOL force_damped);
+	/*virtual*/ LLDrawable* 	createDrawable(LLPipeline *pipeline);
+	/*virtual*/ BOOL   	 	 	updateGeometry(LLDrawable *drawable);
+	/*virtual*/ void   	 	 	setPixelAreaAndAngle(LLAgent &agent);
+	/*virtual*/ void   	 	 	updateRegion(LLViewerRegion *regionp);
+	/*virtual*/ void   	 	 	updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax);
+	/*virtual*/ void   	 	 	getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
+	/*virtual*/ BOOL   	 	 	lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
 												 S32 face = -1,                    // which face to check, -1 = ALL_SIDES
 												 BOOL pick_transparent = FALSE,
 												 S32* face_hit = NULL,             // which face was hit
@@ -173,16 +183,14 @@ class LLVOAvatar :
 	// LLCharacter interface and related
 	//--------------------------------------------------------------------
 public:
-	virtual LLVector3    	getCharacterPosition();
-	virtual LLQuaternion 	getCharacterRotation();
-	virtual LLVector3    	getCharacterVelocity();
-	virtual LLVector3    	getCharacterAngularVelocity();
-	virtual LLJoint*		getCharacterJoint(U32 num);
-	virtual BOOL			allocateCharacterJoints(U32 num);
-
-	virtual LLUUID			remapMotionID(const LLUUID& id);
-	virtual BOOL			startMotion(const LLUUID& id, F32 time_offset = 0.f);
-	virtual BOOL			stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE);
+	/*virtual*/ LLVector3    	getCharacterPosition();
+	/*virtual*/ LLQuaternion 	getCharacterRotation();
+	/*virtual*/ LLVector3    	getCharacterVelocity();
+	/*virtual*/ LLVector3    	getCharacterAngularVelocity();
+
+	/*virtual*/ LLUUID			remapMotionID(const LLUUID& id);
+	/*virtual*/ BOOL			startMotion(const LLUUID& id, F32 time_offset = 0.f);
+	/*virtual*/ BOOL			stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE);
 	virtual void			stopMotionFromSource(const LLUUID& source_id);
 	virtual void			requestStopMotion(LLMotion* motion);
 	LLMotion*				findMotion(const LLUUID& id) const;
@@ -190,25 +198,18 @@ class LLVOAvatar :
 	void					dumpAnimationState();
 
 	virtual LLJoint*		getJoint(const std::string &name);
-	virtual LLJoint*     	getRootJoint() { return &mRoot; }
 	
 	void					resetJointPositions( void );
 	void					resetJointPositionsToDefault( void );
 	void					resetSpecificJointPosition( const std::string& name );
 	
-	virtual const char*		getAnimationPrefix() { return "avatar"; }
-	virtual const LLUUID&   getID() const;
-	virtual LLVector3		getVolumePos(S32 joint_index, LLVector3& volume_offset);
-	virtual LLJoint*		findCollisionVolume(U32 volume_id);
-	virtual S32				getCollisionVolumeID(std::string &name);
-	virtual void			addDebugText(const std::string& text);
-	virtual F32          	getTimeDilation();
-	virtual void			getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm);
-	virtual F32				getPixelArea() const;
-	virtual LLPolyMesh*		getHeadMesh();
-	virtual LLPolyMesh*		getUpperBodyMesh();
-	virtual LLVector3d		getPosGlobalFromAgent(const LLVector3 &position);
-	virtual LLVector3		getPosAgentFromGlobal(const LLVector3d &position);
+	/*virtual*/ const LLUUID&	getID() const;
+	/*virtual*/ void			addDebugText(const std::string& text);
+	/*virtual*/ F32				getTimeDilation();
+	/*virtual*/ void			getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm);
+	/*virtual*/ F32				getPixelArea() const;
+	/*virtual*/ LLVector3d		getPosGlobalFromAgent(const LLVector3 &position);
+	/*virtual*/ LLVector3		getPosAgentFromGlobal(const LLVector3d &position);
 	virtual void			updateVisualParams();
 
 
@@ -223,14 +224,10 @@ class LLVOAvatar :
 
 public:
 	virtual bool 	isSelf() const { return false; } // True if this avatar is for this viewer's agent
-	bool isBuilt() const { return mIsBuilt; }
 
 private: //aligned members
 	LL_ALIGN_16(LLVector4a	mImpostorExtents[2]);
 
-private:
-	BOOL			mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients
-
 	//--------------------------------------------------------------------
 	// Updates
 	//--------------------------------------------------------------------
@@ -293,17 +290,21 @@ class LLVOAvatar :
 	virtual BOOL	getIsCloud() const;
 	BOOL			isFullyTextured() const;
 	BOOL			hasGray() const; 
-	S32				getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = fully textured.
+	S32				getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded.
 	void			updateRezzedStatusTimers();
 
 	S32				mLastRezzedStatus;
 
-	LLViewerStats::PhaseMap& getPhases()
-	{
-		return mPhases;
-	}
+	
+	void 			startPhase(const std::string& phase_name);
+	void 			stopPhase(const std::string& phase_name, bool err_check = true);
+	void			clearPhases();
+	void 			logPendingPhases();
+	static void 	logPendingPhasesAllAvatars();
+	void 			logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);
 
 protected:
+	LLViewerStats::PhaseMap& getPhases() { return mPhases; }
 	BOOL			updateIsFullyLoaded();
 	BOOL			processFullyLoadedChange(bool loading);
 	void			updateRuthTimer(bool loading);
@@ -318,24 +319,6 @@ class LLVOAvatar :
 	LLFrameTimer	mFullyLoadedTimer;
 	LLFrameTimer	mRuthTimer;
 
-public:
-	class ScopedPhaseSetter
-	{
-	public:
-		ScopedPhaseSetter(LLVOAvatar *avatarp, std::string phase_name):
-			mAvatar(avatarp), mPhaseName(phase_name)
-		{
-			if (mAvatar) { mAvatar->getPhases().startPhase(mPhaseName); }
-		}
-		~ScopedPhaseSetter()
-		{
-			if (mAvatar) { mAvatar->getPhases().stopPhase(mPhaseName); }
-		}
-	private:
-		std::string mPhaseName;
-		LLVOAvatar* mAvatar;
-	};
-
 private:
 	LLViewerStats::PhaseMap mPhases;
 
@@ -345,20 +328,25 @@ class LLVOAvatar :
 /**                    State
  **                                                                            **
  *******************************************************************************/
-
 /********************************************************************************
  **                                                                            **
  **                    SKELETON
  **/
 
+protected:
+	/*virtual*/ LLAvatarJoint*	createAvatarJoint(); // Returns LLViewerJoint
+	/*virtual*/ LLAvatarJoint*	createAvatarJoint(S32 joint_num); // Returns LLViewerJoint
+	/*virtual*/ LLAvatarJointMesh*	createAvatarJointMesh(); // Returns LLViewerJointMesh
 public:
 	void				updateHeadOffset();
-	F32					getPelvisToFoot() const { return mPelvisToFoot; }
 	void				setPelvisOffset( bool hasOffset, const LLVector3& translation, F32 offset ) ;
 	bool				hasPelvisOffset( void ) { return mHasPelvisOffset; }
 	void				postPelvisSetRecalc( void );
 	void				setPelvisOffset( F32 pelvixFixupAmount );
 
+	/*virtual*/ BOOL	loadSkeletonNode();
+	/*virtual*/ void	buildCharacter();
+
 	bool				mHasPelvisOffset;
 	LLVector3			mPelvisOffset;
 	F32					mLastPelvisToFoot;
@@ -367,62 +355,8 @@ class LLVOAvatar :
 	LLVector3			mCurRootToHeadOffset;
 	LLVector3			mTargetRootToHeadOffset;
 
-	LLVector3			mHeadOffset; // current head position
-	LLViewerJoint		mRoot;
-
-	typedef std::map<std::string, LLJoint*> joint_map_t;
-	joint_map_t			mJointMap;
-
-protected:
-	static BOOL			parseSkeletonFile(const std::string& filename);
-	void				buildCharacter();
-	virtual BOOL		loadAvatar();
-
-	BOOL				setupBone(const LLVOAvatarChildJoint& info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
-	BOOL				buildSkeleton(const LLVOAvatarSkeletonInfo *info);
-private:
-	BOOL				mIsBuilt; // state of deferred character building
-	S32					mNumJoints;
-	LLViewerJoint*		mSkeleton;
-	
-	//--------------------------------------------------------------------
-	// Pelvis height adjustment members.
-	//--------------------------------------------------------------------
-public:
-	LLVector3			mBodySize;
 	S32					mLastSkeletonSerialNum;
-private:
-	F32					mPelvisToFoot;
 
-	//--------------------------------------------------------------------
-	// Cached pointers to well known joints
-	//--------------------------------------------------------------------
-public:
-	LLViewerJoint* 		mPelvisp;
-	LLViewerJoint* 		mTorsop;
-	LLViewerJoint* 		mChestp;
-	LLViewerJoint* 		mNeckp;
-	LLViewerJoint* 		mHeadp;
-	LLViewerJoint* 		mSkullp;
-	LLViewerJoint* 		mEyeLeftp;
-	LLViewerJoint* 		mEyeRightp;
-	LLViewerJoint* 		mHipLeftp;
-	LLViewerJoint* 		mHipRightp;
-	LLViewerJoint* 		mKneeLeftp;
-	LLViewerJoint* 		mKneeRightp;
-	LLViewerJoint* 		mAnkleLeftp;
-	LLViewerJoint* 		mAnkleRightp;
-	LLViewerJoint* 		mFootLeftp;
-	LLViewerJoint* 		mFootRightp;
-	LLViewerJoint* 		mWristLeftp;
-	LLViewerJoint* 		mWristRightp;
-
-	//--------------------------------------------------------------------
-	// XML parse tree
-	//--------------------------------------------------------------------
-private:
-	static LLXmlTree 	sXMLTree; // avatar config file
-	static LLXMLNodePtr	sSkeletonXMLTree; // avatar skeleton file
 
 /**                    Skeleton
  **                                                                            **
@@ -445,7 +379,6 @@ class LLVOAvatar :
 	static void	deleteCachedImages(bool clearAll=true);
 	static void	destroyGL();
 	static void	restoreGL();
-	BOOL 		mIsDummy; // for special views
 	S32			mSpecialRenderMode; // special lighting
 	U32			mAttachmentGeometryBytes; //number of bytes in attached geometry
 	F32			mAttachmentSurfaceArea; //estimated surface area of attachments
@@ -463,9 +396,15 @@ class LLVOAvatar :
 	// Morph masks
 	//--------------------------------------------------------------------
 public:
-	BOOL 		morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
-	void 		addMaskedMorph(LLVOAvatarDefines::EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer);
-	void 		applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
+	/*virtual*/ void	applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
+	BOOL 		morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
+
+	
+	//--------------------------------------------------------------------
+	// Global colors
+	//--------------------------------------------------------------------
+public:
+	/*virtual*/void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake);
 
 	//--------------------------------------------------------------------
 	// Visibility
@@ -548,10 +487,10 @@ class LLVOAvatar :
 	// Constants
 	//--------------------------------------------------------------------
 public:
-	virtual LLViewerTexture::EBoostLevel 	getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR; }
-	virtual LLViewerTexture::EBoostLevel 	getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED; }
+	virtual LLViewerTexture::EBoostLevel 	getAvatarBoostLevel() const { return LLGLTexture::BOOST_AVATAR; }
+	virtual LLViewerTexture::EBoostLevel 	getAvatarBakedBoostLevel() const { return LLGLTexture::BOOST_AVATAR_BAKED; }
 	virtual S32 						getTexImageSize() const;
-	virtual S32 						getTexImageArea() const { return getTexImageSize()*getTexImageSize(); }
+	/*virtual*/ S32						getTexImageArea() const { return getTexImageSize()*getTexImageSize(); }
 
 /**                    Rendering
  **                                                                            **
@@ -566,9 +505,9 @@ class LLVOAvatar :
 	// Loading status
 	//--------------------------------------------------------------------
 public:
-	virtual BOOL    isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
-	virtual BOOL	isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
-	virtual BOOL	isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const;
+	virtual BOOL    isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const;
+	virtual BOOL	isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const;
+	virtual BOOL	isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const;
 
 	BOOL			isFullyBaked();
 	static BOOL		areAllNearbyInstancesBaked(S32& grey_avatars);
@@ -579,6 +518,7 @@ class LLVOAvatar :
 	// Baked textures
 	//--------------------------------------------------------------------
 public:
+	/*virtual*/ LLTexLayerSet*	createTexLayerSet(); // Return LLViewerTexLayerSet
 	void			releaseComponentTextures(); // ! BACKWARDS COMPATIBILITY !
 protected:
 	static void		onBakedTextureMasksLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
@@ -586,32 +526,20 @@ class LLVOAvatar :
 	static void		onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
 	virtual void	removeMissingBakedTextures();
 	void			useBakedTexture(const LLUUID& id);
+	LLViewerTexLayerSet*  getTexLayerSet(const U32 index) const { return dynamic_cast<LLViewerTexLayerSet*>(mBakedTextureDatas[index].mTexLayerSet);	}
+
 
-	typedef std::deque<LLMaskedMorph *> 	morph_list_t;
-	struct BakedTextureData
-	{
-		LLUUID								mLastTextureIndex;
-		LLTexLayerSet* 						mTexLayerSet; // Only exists for self
-		bool								mIsLoaded;
-		bool								mIsUsed;
-		LLVOAvatarDefines::ETextureIndex 	mTextureIndex;
-		U32									mMaskTexName;
-		// Stores pointers to the joint meshes that this baked texture deals with
-		std::vector< LLViewerJointMesh * > 	mMeshes;  // std::vector<LLViewerJointMesh> mJoints[i]->mMeshParts
-		morph_list_t						mMaskedMorphs;
-	};
-	typedef std::vector<BakedTextureData> 	bakedtexturedata_vec_t;
-	bakedtexturedata_vec_t 					mBakedTextureDatas;
 	LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ; 
 	BOOL mLoadedCallbacksPaused;
+	std::set<LLUUID>	mTextureIDs;
 	//--------------------------------------------------------------------
 	// Local Textures
 	//--------------------------------------------------------------------
 protected:
-	virtual void	setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0);
-	virtual void	addLocalTextureStats(LLVOAvatarDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0);
+	virtual void	setLocalTexture(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0);
+	virtual void	addLocalTextureStats(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked);
 	// MULTI-WEARABLE: make self-only?
-	virtual void	setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index = 0);
+	virtual void	setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index = 0);
 
 	//--------------------------------------------------------------------
 	// Texture accessors
@@ -619,6 +547,7 @@ class LLVOAvatar :
 private:
 	virtual	void				setImage(const U8 te, LLViewerTexture *imagep, const U32 index); 
 	virtual LLViewerTexture*	getImage(const U8 te, const U32 index) const;
+	const std::string 			getImageURL(const U8 te, const LLUUID &uuid);
 
 	virtual const LLTextureEntry* getTexEntry(const U8 te_num) const;
 	virtual void setTexEntry(const U8 index, const LLTextureEntry &te);
@@ -645,13 +574,11 @@ class LLVOAvatar :
 	// Static texture/mesh/baked dictionary
 	//--------------------------------------------------------------------
 public:
-	static BOOL 	isIndexLocalTexture(LLVOAvatarDefines::ETextureIndex i);
-	static BOOL 	isIndexBakedTexture(LLVOAvatarDefines::ETextureIndex i);
+	static BOOL 	isIndexLocalTexture(LLAvatarAppearanceDefines::ETextureIndex i);
+	static BOOL 	isIndexBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i);
 private:
-	static const LLVOAvatarDefines::LLVOAvatarDictionary *getDictionary() { return sAvatarDictionary; }
-	static LLVOAvatarDefines::LLVOAvatarDictionary* sAvatarDictionary;
-	static LLVOAvatarSkeletonInfo* 					sAvatarSkeletonInfo;
-	static LLVOAvatarXmlInfo* 						sAvatarXmlInfo;
+	static const LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary *getDictionary() { return sAvatarDictionary; }
+	static LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary* sAvatarDictionary;
 
 	//--------------------------------------------------------------------
 	// Messaging
@@ -672,22 +599,20 @@ class LLVOAvatar :
  **/
 
 public:
-	void 			updateMeshTextures();
+	void			debugColorizeSubMeshes(U32 i, const LLColor4& color);
+	virtual void 	updateMeshTextures();
 	void 			updateSexDependentLayerSets(BOOL upload_bake);
-	void 			dirtyMesh(); // Dirty the avatar mesh
+	virtual void	dirtyMesh(); // Dirty the avatar mesh
 	void 			updateMeshData();
 protected:
 	void 			releaseMeshData();
 	virtual void restoreMeshData();
 private:
-	void 			dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority
+	virtual void	dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority
+	LLViewerJoint*	getViewerJoint(S32 idx);
 	S32 			mDirtyMesh; // 0 -- not dirty, 1 -- morphed, 2 -- LOD
 	BOOL			mMeshTexturesDirty;
 
-	typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
-	polymesh_map_t 									mMeshes;
-	std::vector<LLViewerJoint *> 					mMeshLOD;
-
 	//--------------------------------------------------------------------
 	// Destroy invisible mesh
 	//--------------------------------------------------------------------
@@ -705,38 +630,42 @@ class LLVOAvatar :
  **/
 
 public:
+	void 			parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg);
 	void 			processAvatarAppearance(LLMessageSystem* mesgsys);
 	void 			hideSkirt();
 	void			startAppearanceAnimation();
+	/*virtual*/ void bodySizeChanged();
 	
 	//--------------------------------------------------------------------
 	// Appearance morphing
 	//--------------------------------------------------------------------
 public:
 	BOOL			getIsAppearanceAnimating() const { return mAppearanceAnimating; }
+
+	// True if we are computing our appearance via local compositing
+	// instead of baked textures, as for example during wearable
+	// editing or when waiting for a subsequent server rebake.
+	/*virtual*/ BOOL	isUsingLocalAppearance() const { return mUseLocalAppearance; }
+
+	// True if this avatar should fetch its baked textures via the new
+	// appearance mechanism.
+	BOOL				isUsingServerBakes() const;
+	void 				setIsUsingServerBakes(BOOL newval);
+
+
+	// True if we are currently in appearance editing mode. Often but
+	// not always the same as isUsingLocalAppearance().
+	/*virtual*/ BOOL	isEditingAppearance() const { return mIsEditingAppearance; }
+
+	// FIXME review isUsingLocalAppearance uses, some should be isEditing instead.
+
 private:
 	BOOL			mAppearanceAnimating;
 	LLFrameTimer	mAppearanceMorphTimer;
 	F32				mLastAppearanceBlendTime;
-
-	//--------------------------------------------------------------------
-	// Clothing colors (convenience functions to access visual parameters)
-	//--------------------------------------------------------------------
-public:
-	void			setClothesColor(LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);
-	LLColor4		getClothesColor(LLVOAvatarDefines::ETextureIndex te);
-	static BOOL			teToColorParams(LLVOAvatarDefines::ETextureIndex te, U32 *param_name);
-
-	//--------------------------------------------------------------------
-	// Global colors
-	//--------------------------------------------------------------------
-public:
-	LLColor4		getGlobalColor(const std::string& color_name ) const;
-	void			onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake);
-private:
-	LLTexGlobalColor* mTexSkinColor;
-	LLTexGlobalColor* mTexHairColor;
-	LLTexGlobalColor* mTexEyeColor;
+	BOOL			mIsEditingAppearance; // flag for if we're actively in appearance editing mode
+	BOOL			mUseLocalAppearance; // flag for if we're using a local composite
+	BOOL			mUseServerBakes; // flag for if baked textures should be fetched from baking service (false if they're temporary uploads)
 
 	//--------------------------------------------------------------------
 	// Visibility
@@ -746,7 +675,6 @@ class LLVOAvatar :
 	void			setVisibilityRank(U32 rank);
 	U32				getVisibilityRank()  const { return mVisibilityRank; } // unused
 	static S32 		sNumVisibleAvatars; // Number of instances of this class
-	static LLColor4 getDummyColor();
 /**                    Appearance
  **                                                                            **
  *******************************************************************************/
@@ -756,9 +684,6 @@ class LLVOAvatar :
  **                    WEARABLES
  **/
 
-public:
-	virtual BOOL			isWearingWearableType(LLWearableType::EType type ) const;
-	
 	//--------------------------------------------------------------------
 	// Attachments
 	//--------------------------------------------------------------------
@@ -768,6 +693,7 @@ class LLVOAvatar :
 	virtual BOOL 		detachObject(LLViewerObject *viewer_object);
 	void				cleanupAttachedMesh( LLViewerObject* pVO );
 	static LLVOAvatar*  findAvatarFromAttachment(LLViewerObject* obj);
+	/*virtual*/ BOOL	isWearingWearableType(LLWearableType::EType type ) const;
 protected:
 	LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
 	void 				lazyAttach();
@@ -868,15 +794,6 @@ class LLVOAvatar :
 	BOOL 		mTurning; // controls hysteresis on avatar rotation
 	F32			mSpeed; // misc. animation repeated state
 
-	//--------------------------------------------------------------------
-	// Collision volumes
-	//--------------------------------------------------------------------
-public:
-  	S32			mNumCollisionVolumes;
-	LLViewerJointCollisionVolume* mCollisionVolumes;
-protected:
-	BOOL		allocateCollisionVolumes(U32 num);
-
 	//--------------------------------------------------------------------
 	// Dimensions
 	//--------------------------------------------------------------------
@@ -887,7 +804,6 @@ class LLVOAvatar :
 	void 		resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm);
 	void 		slamPosition(); // Slam position to transmitted position (for teleport);
 protected:
-	void 		computeBodySize();
 
 	//--------------------------------------------------------------------
 	// Material being stepped on
@@ -907,9 +823,9 @@ class LLVOAvatar :
  **/
 
 public:
-	virtual BOOL 	setParent(LLViewerObject* parent);
-	virtual void 	addChild(LLViewerObject *childp);
-	virtual void 	removeChild(LLViewerObject *childp);
+	/*virtual*/ BOOL 	setParent(LLViewerObject* parent);
+	/*virtual*/ void 	addChild(LLViewerObject *childp);
+	/*virtual*/ void 	removeChild(LLViewerObject *childp);
 
 	//--------------------------------------------------------------------
 	// Sitting
@@ -1013,7 +929,9 @@ class LLVOAvatar :
 	// General
 	//--------------------------------------------------------------------
 public:
-	static void			dumpArchetypeXML(void*);
+	void				dumpArchetypeXML(const std::string& prefix, bool group_by_wearables = false);
+	void 				dumpAppearanceMsgParams( const std::string& dump_prefix,
+												 const LLAppearanceMessageContents& contents);
 	static void			dumpBakedStatus();
 	const std::string 	getBakedStatusForPrintout() const;
 	void				dumpAvatarTEs(const std::string& context) const;
@@ -1030,6 +948,7 @@ class LLVOAvatar :
 	F32					mMaxPixelArea;
 	F32					mAdjustedPixelArea;
 	std::string  		mDebugText;
+	std::string			mBakedTextureDebugText;
 
 
 	//--------------------------------------------------------------------
@@ -1043,6 +962,17 @@ class LLVOAvatar :
 	LLFrameTimer	mRuthDebugTimer; // For tracking how long it takes for av to rez
 	LLFrameTimer	mDebugExistenceTimer; // Debugging for how long the avatar has been in memory.
 
+	//--------------------------------------------------------------------
+	// COF monitoring
+	//--------------------------------------------------------------------
+
+public:
+	// COF version of last viewer-initiated appearance update request. For non-self avs, this will remain at default.
+	S32 mLastUpdateRequestCOFVersion;
+
+	// COF version of last appearance message received for this av.
+	S32 mLastUpdateReceivedCOFVersion;
+
 /**                    Diagnostics
  **                                                                            **
  *******************************************************************************/
@@ -1054,105 +984,6 @@ class LLVOAvatar :
 
 protected: // Shared with LLVOAvatarSelf
 
-	struct LLVOAvatarXmlInfo
-	{
-		LLVOAvatarXmlInfo();
-		~LLVOAvatarXmlInfo();
-
-		BOOL 	parseXmlSkeletonNode(LLXmlTreeNode* root);
-		BOOL 	parseXmlMeshNodes(LLXmlTreeNode* root);
-		BOOL 	parseXmlColorNodes(LLXmlTreeNode* root);
-		BOOL 	parseXmlLayerNodes(LLXmlTreeNode* root);
-		BOOL 	parseXmlDriverNodes(LLXmlTreeNode* root);
-		BOOL	parseXmlMorphNodes(LLXmlTreeNode* root);
-
-		struct LLVOAvatarMeshInfo
-		{
-			typedef std::pair<LLPolyMorphTargetInfo*,BOOL> morph_info_pair_t;
-			typedef std::vector<morph_info_pair_t> morph_info_list_t;
-
-			LLVOAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {}
-			~LLVOAvatarMeshInfo()
-			{
-				morph_info_list_t::iterator iter;
-				for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++)
-				{
-					delete iter->first;
-				}
-				mPolyMorphTargetInfoList.clear();
-			}
-
-			std::string mType;
-			S32			mLOD;
-			std::string	mMeshFileName;
-			std::string	mReferenceMeshName;
-			F32			mMinPixelArea;
-			morph_info_list_t mPolyMorphTargetInfoList;
-		};
-		typedef std::vector<LLVOAvatarMeshInfo*> mesh_info_list_t;
-		mesh_info_list_t mMeshInfoList;
-
-		typedef std::vector<LLPolySkeletalDistortionInfo*> skeletal_distortion_info_list_t;
-		skeletal_distortion_info_list_t mSkeletalDistortionInfoList;
-	
-		struct LLVOAvatarAttachmentInfo
-		{
-			LLVOAvatarAttachmentInfo()
-				: mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE),
-				  mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {}
-			std::string mName;
-			std::string mJointName;
-			LLVector3 mPosition;
-			LLVector3 mRotationEuler;
-			S32 mGroup;
-			S32 mAttachmentID;
-			S32 mPieMenuSlice;
-			BOOL mVisibleFirstPerson;
-			BOOL mIsHUDAttachment;
-			BOOL mHasPosition;
-			BOOL mHasRotation;
-		};
-		typedef std::vector<LLVOAvatarAttachmentInfo*> attachment_info_list_t;
-		attachment_info_list_t mAttachmentInfoList;
-	
-		LLTexGlobalColorInfo *mTexSkinColorInfo;
-		LLTexGlobalColorInfo *mTexHairColorInfo;
-		LLTexGlobalColorInfo *mTexEyeColorInfo;
-
-		typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t;
-		layer_info_list_t mLayerInfoList;
-
-		typedef std::vector<LLDriverParamInfo*> driver_info_list_t;
-		driver_info_list_t mDriverInfoList;
-
-		struct LLVOAvatarMorphInfo
-		{
-			LLVOAvatarMorphInfo()
-				: mInvert(FALSE) {}
-			std::string mName;
-			std::string mRegion;
-			std::string mLayer;
-			BOOL mInvert;
-		};
-
-		typedef std::vector<LLVOAvatarMorphInfo*> morph_info_list_t;
-		morph_info_list_t	mMorphMaskInfoList;
-	};
-
-	struct LLMaskedMorph
-	{
-		LLMaskedMorph(LLPolyMorphTarget *morph_target, BOOL invert, std::string layer) :
-			mMorphTarget(morph_target), 
-			mInvert(invert),
-			mLayer(layer)
-		{
-			morph_target->addPendingMorphMask();
-		}
-	
-		LLPolyMorphTarget	*mMorphTarget;
-		BOOL				mInvert;
-		std::string			mLayer;
-	};
 
 /**                    Support classes
  **                                                                            **
@@ -1162,4 +993,9 @@ class LLVOAvatar :
 extern const F32 SELF_ADDITIONAL_PRI;
 extern const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL;
 
-#endif // LL_VO_AVATAR_H
+std::string get_sequential_numbered_file_name(const std::string& prefix,
+											  const std::string& suffix);
+void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value);
+
+#endif // LL_VOAVATAR_H
+
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
old mode 100644
new mode 100755
index e32fd3c3c896958b770534d9cb8821f8e3770e3c..d54eb5f0400c6f812f23cb1f484e1051de25cdc4
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -55,11 +55,14 @@
 #include "llviewerobjectlist.h"
 #include "llviewerstats.h"
 #include "llviewerregion.h"
+#include "llviewertexlayer.h"
+#include "llviewerwearable.h"
 #include "llappearancemgr.h"
 #include "llmeshrepository.h"
 #include "llvovolume.h"
 #include "llsdutil.h"
 #include "llstartup.h"
+#include "llsdserialize.h"
 
 #if LL_MSVC
 // disable boost::lexical_cast warning
@@ -72,24 +75,22 @@ LLPointer<LLVOAvatarSelf> gAgentAvatarp = NULL;
 
 BOOL isAgentAvatarValid()
 {
-	return (gAgentAvatarp.notNull() &&
-			(gAgentAvatarp->getRegion() != NULL) &&
-			(!gAgentAvatarp->isDead()));
+	return (gAgentAvatarp.notNull() && gAgentAvatarp->isValid());
 }
 
 void selfStartPhase(const std::string& phase_name)
 {
 	if (isAgentAvatarValid())
 	{
-		gAgentAvatarp->getPhases().startPhase(phase_name);
+		gAgentAvatarp->startPhase(phase_name);
 	}
 }
 
-void selfStopPhase(const std::string& phase_name)
+void selfStopPhase(const std::string& phase_name, bool err_check)
 {
 	if (isAgentAvatarValid())
 	{
-		gAgentAvatarp->getPhases().stopPhase(phase_name);
+		gAgentAvatarp->stopPhase(phase_name, err_check);
 	}
 }
 
@@ -97,20 +98,11 @@ void selfClearPhases()
 {
 	if (isAgentAvatarValid())
 	{
-		gAgentAvatarp->getPhases().clearPhases();
-		gAgentAvatarp->mLastRezzedStatus = -1;
+		gAgentAvatarp->clearPhases();
 	}
 }
 
-void selfStopAllPhases()
-{
-	if (isAgentAvatarValid())
-	{
-		gAgentAvatarp->getPhases().stopAllPhases();
-	}
-}
-
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 /*********************************************************************************
  **                                                                             **
@@ -176,6 +168,35 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,
 	lldebugs << "Marking avatar as self " << id << llendl;
 }
 
+// Called periodically for diagnostics, return true when done.
+bool output_self_av_texture_diagnostics()
+{
+	if (!isAgentAvatarValid())
+		return true; // done checking
+
+	gAgentAvatarp->outputRezDiagnostics();
+
+	return false;
+}
+
+bool update_avatar_rez_metrics()
+{
+	if (!isAgentAvatarValid())
+		return true;
+	
+	gAgentAvatarp->updateAvatarRezMetrics(false);
+	return false;
+}
+
+bool check_for_unsupported_baked_appearance()
+{
+	if (!isAgentAvatarValid())
+		return true;
+
+	gAgentAvatarp->checkForUnsupportedServerBakeAppearance();
+	return false;
+}
+
 void LLVOAvatarSelf::initInstance()
 {
 	BOOL status = TRUE;
@@ -188,7 +209,7 @@ void LLVOAvatarSelf::initInstance()
 	llinfos << "Self avatar object created. Starting timer." << llendl;
 	mDebugSelfLoadTimer.reset();
 	// clear all times to -1 for debugging
-	for (U32 i =0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i)
+	for (U32 i =0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i)
 	{
 		for (U32 j = 0; j <= MAX_DISCARD_LEVEL; ++j)
 		{
@@ -196,7 +217,7 @@ void LLVOAvatarSelf::initInstance()
 		}
 	}
 
-	for (U32 i =0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i)
+	for (U32 i =0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i)
 	{
 		mDebugBakedTextureTimes[i][0] = -1.0f;
 		mDebugBakedTextureTimes[i][1] = -1.0f;
@@ -209,6 +230,10 @@ void LLVOAvatarSelf::initInstance()
 		llerrs << "Unable to load user's avatar" << llendl;
 		return;
 	}
+
+	//doPeriodically(output_self_av_texture_diagnostics, 30.0);
+	doPeriodically(update_avatar_rez_metrics, 5.0);
+	doPeriodically(check_for_unsupported_baked_appearance, 120.0);
 }
 
 // virtual
@@ -249,13 +274,11 @@ BOOL LLVOAvatarSelf::loadAvatarSelf()
 		llwarns << "avatar file: buildSkeleton() failed" << llendl;
 		return FALSE;
 	}
-	// TODO: make loadLayersets() called only by self.
-	//success &= loadLayersets();
 
 	return success;
 }
 
-BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info)
+BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLAvatarSkeletonInfo *info)
 {
 	// add special-purpose "screen" joint
 	mScreenp = new LLViewerJoint("mScreen", NULL);
@@ -341,7 +364,6 @@ BOOL LLVOAvatarSelf::buildMenus()
 		}
 		else
 		{
-			BOOL attachment_found = FALSE;
 			for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); 
 				 iter != mAttachmentPoints.end();
 				 ++iter)
@@ -369,7 +391,6 @@ BOOL LLVOAvatarSelf::buildMenus()
 
 					gAttachPieMenu->addChild(item);
 
-					attachment_found = TRUE;
 					break;
 
 				}
@@ -382,7 +403,6 @@ BOOL LLVOAvatarSelf::buildMenus()
 		}
 		else
 		{
-			BOOL attachment_found = FALSE;
 			for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); 
 				 iter != mAttachmentPoints.end();
 				 ++iter)
@@ -409,7 +429,6 @@ BOOL LLVOAvatarSelf::buildMenus()
 
 					gDetachPieMenu->addChild(item);
 						
-					attachment_found = TRUE;
 					break;
 				}
 			}
@@ -583,70 +602,6 @@ LLVOAvatarSelf::~LLVOAvatarSelf()
  **                                                                             **
  *********************************************************************************/
 
-//virtual
-BOOL LLVOAvatarSelf::loadLayersets()
-{
-	BOOL success = TRUE;
-	for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator iter = sAvatarXmlInfo->mLayerInfoList.begin();
-		 iter != sAvatarXmlInfo->mLayerInfoList.end(); 
-		 ++iter)
-	{
-		// Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
-		const LLTexLayerSetInfo *info = *iter;
-		LLTexLayerSet* layer_set = new LLTexLayerSet( this );
-		
-		if (!layer_set->setInfo(info))
-		{
-			stop_glerror();
-			delete layer_set;
-			llwarns << "avatar file: layer_set->parseData() failed" << llendl;
-			return FALSE;
-		}
-
-		// scan baked textures and associate the layerset with the appropriate one
-		EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
-		for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-			 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
-			 ++baked_iter)
-		{
-			const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
-			if (layer_set->isBodyRegion(baked_dict->mName))
-			{
-				baked_index = baked_iter->first;
-				// ensure both structures are aware of each other
-				mBakedTextureDatas[baked_index].mTexLayerSet = layer_set;
-				layer_set->setBakedTexIndex(baked_index);
-				break;
-			}
-		}
-		// if no baked texture was found, warn and cleanup
-		if (baked_index == BAKED_NUM_INDICES)
-		{
-			llwarns << "<layer_set> has invalid body_region attribute" << llendl;
-			delete layer_set;
-			return FALSE;
-		}
-
-		// scan morph masks and let any affected layers know they have an associated morph
-		for (LLVOAvatar::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin();
-			morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end();
-			 ++morph_iter)
-		{
-			LLMaskedMorph *morph = *morph_iter;
-			LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer);
-			if (layer)
-			{
-				layer->setHasMorph(TRUE);
-			}
-			else
-			{
-				llwarns << "Could not find layer named " << morph->mLayer << " to set morph flag" << llendl;
-				success = FALSE;
-			}
-		}
-	}
-	return success;
-}
 // virtual
 BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)
 {
@@ -663,10 +618,16 @@ BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)
 	return LLVOAvatar::updateCharacter(agent);
 }
 
+// virtual
+BOOL LLVOAvatarSelf::isValid() const
+{
+	return ((getRegion() != NULL) && !isDead());
+}
+
 // virtual
 void LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 {
-	if (isAgentAvatarValid())
+	if (isValid())
 	{
 		LLVOAvatar::idleUpdate(agent, world, time);
 		idleUpdateTractorBeam();
@@ -689,7 +650,7 @@ void LLVOAvatarSelf::resetJointPositions( void )
 	return LLVOAvatar::resetJointPositions();
 }
 // virtual
-BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake )
+BOOL LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake )
 {
 	if (!which_param)
 	{
@@ -717,20 +678,28 @@ BOOL LLVOAvatarSelf::setVisualParamWeight(S32 index, F32 weight, BOOL upload_bak
 	return setParamWeight(param,weight,upload_bake);
 }
 
-BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake )
+BOOL LLVOAvatarSelf::setParamWeight(const LLViewerVisualParam *param, F32 weight, BOOL upload_bake )
 {
 	if (!param)
 	{
 		return FALSE;
 	}
 
+#if 0
+	// FIXME DRANO - kludgy way to avoid overwriting avatar state from wearables.
+	if (isUsingServerBakes() && !isUsingLocalAppearance())
+	{
+		return FALSE;
+	}
+#endif
+
 	if (param->getCrossWearable())
 	{
 		LLWearableType::EType type = (LLWearableType::EType)param->getWearableType();
 		U32 size = gAgentWearables.getWearableCount(type);
 		for (U32 count = 0; count < size; ++count)
 		{
-			LLWearable *wearable = gAgentWearables.getWearable(type,count);
+			LLViewerWearable *wearable = gAgentWearables.getViewerWearable(type,count);
 			if (wearable)
 			{
 				wearable->setVisualParamWeight(param->getID(), weight, upload_bake);
@@ -759,7 +728,7 @@ void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
 		LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type);
 		if (wearable)
 		{
-			wearable->writeToAvatar();
+			wearable->writeToAvatar(this);
 		}
 	}
 
@@ -802,18 +771,30 @@ U32  LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,
 {
 	U32 retval = LLVOAvatar::processUpdateMessage(mesgsys,user_data,block_num,update_type,dp);
 
-	if (mInitialBakesLoaded == false && retval == 0x0)
+#if 0
+	// DRANO - it's not clear this does anything useful. If we wait
+	// until an appearance message has been received, we already have
+	// the texture ids. If we don't wait, we don't yet know where to
+	// look for baked textures, because we haven't received the
+	// appearance version data from the appearance message. This looks
+	// like an old optimization that's incompatible with server-side
+	// texture baking.
+	
+	// FIXME DRANO - skipping in the case of !mFirstAppearanceMessageReceived prevents us from trying to
+	// load textures before we know where they come from (ie, from baking service or not);
+	// unknown impact on performance.
+	if (mInitialBakesLoaded == false && retval == 0x0 && mFirstAppearanceMessageReceived)
 	{
 		// call update textures to force the images to be created
 		updateMeshTextures();
 
 		// unpack the texture UUIDs to the texture slots
-		retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
+		retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);
 
 		// need to trigger a few operations to get the avatar to use the new bakes
 		for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 		{
-			const LLVOAvatarDefines::ETextureIndex te = mBakedTextureDatas[i].mTextureIndex;
+			const LLAvatarAppearanceDefines::ETextureIndex te = mBakedTextureDatas[i].mTextureIndex;
 			LLUUID texture_id = getTEImage(te)->getID();
 			setNewBakedTexture(te, texture_id);
 			mInitialBakeIDs[i] = texture_id;
@@ -823,6 +804,7 @@ U32  LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,
 
 		mInitialBakesLoaded = true;
 	}
+#endif
 
 	return retval;
 }
@@ -877,11 +859,15 @@ void LLVOAvatarSelf::removeMissingBakedTextures()
 	{
 		for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 		{
-			mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE);
-			invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, FALSE);
+			LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+			layerset->setUpdatesEnabled(TRUE);
+			invalidateComposite(layerset, FALSE);
 		}
 		updateMeshTextures();
-		requestLayerSetUploads();
+		if (getRegion() && !getRegion()->getCentralBakeVersion())
+		{
+			requestLayerSetUploads();
+		}
 	}
 }
 
@@ -938,7 +924,7 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
 void LLVOAvatarSelf::idleUpdateTractorBeam()
 {
 	// This is only done for yourself (maybe it should be in the agent?)
-	if (!needsRenderBeam() || !mIsBuilt)
+	if (!needsRenderBeam() || !isBuilt())
 	{
 		mBeam = NULL;
 	}
@@ -1051,11 +1037,6 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
 	}
 }
 
-/*virtual*/ BOOL LLVOAvatarSelf::isWearingWearableType(LLWearableType::EType type ) const
-{
-	return gAgentWearables.getWearableCount(type) > 0;
-}
-
 //-----------------------------------------------------------------------------
 // updatedWearable( LLWearableType::EType type )
 // forces an update to any baked textures relevant to type.
@@ -1063,26 +1044,27 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
 //-----------------------------------------------------------------------------
 void LLVOAvatarSelf::wearableUpdated( LLWearableType::EType type, BOOL upload_result )
 {
-	for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
-		const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
-		const LLVOAvatarDefines::EBakedTextureIndex index = baked_iter->first;
+		const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+		const LLAvatarAppearanceDefines::EBakedTextureIndex index = baked_iter->first;
 
 		if (baked_dict)
 		{
-			for (LLVOAvatarDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin();
+			for (LLAvatarAppearanceDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin();
 				type_iter != baked_dict->mWearables.end();
 				 ++type_iter)
 			{
 				const LLWearableType::EType comp_type = *type_iter;
 				if (comp_type == type)
 				{
-					if (mBakedTextureDatas[index].mTexLayerSet)
+					LLViewerTexLayerSet *layerset = getLayerSet(index);
+					if (layerset)
 					{
-						mBakedTextureDatas[index].mTexLayerSet->setUpdatesEnabled(true);
-						invalidateComposite(mBakedTextureDatas[index].mTexLayerSet, upload_result);
+						layerset->setUpdatesEnabled(true);
+						invalidateComposite(layerset, upload_result);
 					}
 					break;
 				}
@@ -1246,7 +1228,7 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
 		// Make sure the inventory is in sync with the avatar.
 
 		// Update COF contents, don't trigger appearance update.
-		if (!isAgentAvatarValid())
+		if (!isValid())
 		{
 			llinfos << "removeItemLinks skipped, avatar is under destruction" << llendl;
 		}
@@ -1287,7 +1269,7 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
 			const LLViewerObject *attached_obj = gAgentAvatarp->getWornAttachment(item_id);
 			if (!attached_obj)
 			{
-				LLAppearanceMgr::instance().removeCOFItemLinks(item_id, false);
+				LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
 			}
 		}
 		return TRUE;
@@ -1295,9 +1277,9 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
 	return FALSE;
 }
 
-U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const
+U32 LLVOAvatarSelf::getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const
 {
-	LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
+	LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i);
 	return gAgentWearables.getWearableCount(type);
 }
 
@@ -1328,11 +1310,8 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr
 			discard_level < local_tex_obj->getDiscard())
 		{
 			local_tex_obj->setDiscard(discard_level);
-			if (isUsingBakedTextures())
-			{
-				requestLayerSetUpdate(index);
-			}
-			else
+			requestLayerSetUpdate(index);
+			if (isEditingAppearance())
 			{
 				LLVisualParamHint::requestHintUpdates();
 			}
@@ -1366,11 +1345,11 @@ BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex
 	{
 		return FALSE;
 	}
-	*tex_pp = local_tex_obj->getImage();
+	*tex_pp = dynamic_cast<LLViewerTexture*> (local_tex_obj->getImage());
 	return TRUE;
 }
 
-LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
 {
 	if (!isIndexLocalTexture(type))
 	{
@@ -1386,7 +1365,7 @@ LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLVOAvatarDefines::ETe
 	{
 		return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
 	}
-	return local_tex_obj->getImage();
+	return dynamic_cast<LLViewerFetchedTexture*> (local_tex_obj->getImage());
 }
 
 const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) const
@@ -1407,29 +1386,30 @@ const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) c
 // Returns true if at least the lowest quality discard level exists for every texture
 // in the layerset.
 //-----------------------------------------------------------------------------
-BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const
+BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* layerset) const
 {
 	/* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
 	   return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
-	for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
 		const EBakedTextureIndex baked_index = baked_iter->first;
 		if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
 		{
 			BOOL ret = true;
-			const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+			const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
 			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 				 local_tex_iter != baked_dict->mLocalTextures.end();
 				 ++local_tex_iter)
 			{
 				const ETextureIndex tex_index = *local_tex_iter;
-				const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+				const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
 				const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 				for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
 				{
-					ret &= (getLocalDiscardLevel(tex_index, wearable_index) >= 0);
+					BOOL tex_avail = (getLocalDiscardLevel(tex_index, wearable_index) >= 0);
+					ret &= tex_avail;
 				}
 			}
 			return ret;
@@ -1445,7 +1425,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset)
 // Returns true if the highest quality discard level exists for every texture
 // in the layerset.
 //-----------------------------------------------------------------------------
-BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) const
+BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset) const
 {
 	const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); 
 	// const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels.
@@ -1454,17 +1434,19 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons
 	{
 		if (layerset == mBakedTextureDatas[i].mTexLayerSet)
 		{
-			const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+			const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
 			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 				 local_tex_iter != baked_dict->mLocalTextures.end();
 				 ++local_tex_iter)
 			{
 				const ETextureIndex tex_index = *local_tex_iter;
-				const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+				const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
 				const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 				for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
 				{
-					if (getLocalDiscardLevel(*local_tex_iter, wearable_index) > (S32)(desired_tex_discard_level))
+					S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index);
+					if ((local_discard_level > (S32)(desired_tex_discard_level)) ||
+						(local_discard_level < 0 ))
 					{
 						return FALSE;
 					}
@@ -1477,6 +1459,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons
 	return FALSE;
 }
 
+
 BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
 {
 	const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); 
@@ -1484,17 +1467,19 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
 
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+		const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
 		for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 			 local_tex_iter != baked_dict->mLocalTextures.end();
 			 ++local_tex_iter)
 		{
 			const ETextureIndex tex_index = *local_tex_iter;
-			const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+			const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
 			const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 			for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
 			{
-				if (getLocalDiscardLevel(*local_tex_iter, wearable_index) > (S32)(desired_tex_discard_level))
+				S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index);
+				if ((local_discard_level > (S32)(desired_tex_discard_level)) ||
+					(local_discard_level < 0 ))
 				{
 					return FALSE;
 				}
@@ -1504,22 +1489,22 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
 	return TRUE;
 }
 
-BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const
+BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLAvatarAppearanceDefines::EBakedTextureIndex index) const
 {
-	const LLTexLayerSet *layerset = mBakedTextureDatas[index].mTexLayerSet;
+	const LLViewerTexLayerSet *layerset = getLayerSet(index);
 	if (!layerset) return FALSE;
-	const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+	const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
 	if (!layerset_buffer) return FALSE;
 	return !layerset_buffer->uploadNeeded();
 }
 
-BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+BOOL LLVOAvatarSelf::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
 {
 	LLUUID id;
 	BOOL isDefined = TRUE;
 	if (isIndexLocalTexture(type))
 	{
-		const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(type);
+		const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(type);
 		const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 		if (index >= wearable_count)
 		{
@@ -1546,7 +1531,7 @@ BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32
 }
 
 //virtual
-BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
 {
 	if (isIndexBakedTexture(type))
 	{
@@ -1559,7 +1544,7 @@ BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32
 }
 
 //virtual
-BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const
+BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const
 {
 	if (isIndexBakedTexture(type))
 	{
@@ -1582,13 +1567,14 @@ void LLVOAvatarSelf::requestLayerSetUploads()
 	}
 }
 
-void LLVOAvatarSelf::requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i)
+void LLVOAvatarSelf::requestLayerSetUpload(LLAvatarAppearanceDefines::EBakedTextureIndex i)
 {
 	ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex;
 	const BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index));
-	if (!layer_baked && mBakedTextureDatas[i].mTexLayerSet)
+	LLViewerTexLayerSet *layerset = getLayerSet(i);
+	if (!layer_baked && layerset)
 	{
-		mBakedTextureDatas[i].mTexLayerSet->requestUpload();
+		layerset->requestUpload();
 	}
 }
 
@@ -1602,8 +1588,8 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const
 {
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		LLTexLayerSet* layerset = mBakedTextureDatas[i].mTexLayerSet;
-		if (layerset && layerset->getComposite() && layerset->getComposite()->uploadPending())
+		LLViewerTexLayerSet* layerset = getTexLayerSet(i);
+		if (layerset && layerset->getViewerComposite() && layerset->getViewerComposite()->uploadPending())
 		{
 			return true;
 		}
@@ -1613,22 +1599,23 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const
 
 void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )
 {
-	if( !layerset || !layerset->getUpdatesEnabled() )
+	LLViewerTexLayerSet *layer_set = dynamic_cast<LLViewerTexLayerSet*>(layerset);
+	if( !layer_set || !layer_set->getUpdatesEnabled() )
 	{
 		return;
 	}
 	// llinfos << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegionName() << llendl;
 
-	layerset->requestUpdate();
-	layerset->invalidateMorphMasks();
+	layer_set->requestUpdate();
+	layer_set->invalidateMorphMasks();
 
-	if( upload_result )
+	if( upload_result  && (getRegion() && !getRegion()->getCentralBakeVersion()))
 	{
 		llassert(isSelf());
 
-		ETextureIndex baked_te = getBakedTE( layerset );
+		ETextureIndex baked_te = getBakedTE( layer_set );
 		setTEImage( baked_te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR) );
-		layerset->requestUpload();
+		layer_set->requestUpload();
 		updateMeshTextures();
 	}
 }
@@ -1637,7 +1624,8 @@ void LLVOAvatarSelf::invalidateAll()
 {
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, TRUE);
+		LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+		invalidateComposite(layerset, TRUE);
 	}
 	//mDebugSelfLoadTimer.reset();
 }
@@ -1655,17 +1643,19 @@ void LLVOAvatarSelf::setCompositeUpdatesEnabled( bool b )
 
 void LLVOAvatarSelf::setCompositeUpdatesEnabled(U32 index, bool b)
 {
-	if (mBakedTextureDatas[index].mTexLayerSet )
+	LLViewerTexLayerSet *layerset = getTexLayerSet(index);
+	if (layerset )
 	{
-		mBakedTextureDatas[index].mTexLayerSet->setUpdatesEnabled( b );
+		layerset->setUpdatesEnabled( b );
 	}
 }
 
 bool LLVOAvatarSelf::isCompositeUpdateEnabled(U32 index)
 {
-	if (mBakedTextureDatas[index].mTexLayerSet)
+	LLViewerTexLayerSet *layerset = getTexLayerSet(index);
+	if (layerset)
 	{
-		return mBakedTextureDatas[index].mTexLayerSet->getUpdatesEnabled();
+		return layerset->getUpdatesEnabled();
 	}
 	return false;
 }
@@ -1676,9 +1666,10 @@ void LLVOAvatarSelf::setupComposites()
 	{
 		ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex;
 		BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index));
-		if (mBakedTextureDatas[i].mTexLayerSet)
+		LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+		if (layerset)
 		{
-			mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(!layer_baked);
+			layerset->setUpdatesEnabled(!layer_baked);
 		}
 	}
 }
@@ -1687,10 +1678,11 @@ void LLVOAvatarSelf::updateComposites()
 {
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		if (mBakedTextureDatas[i].mTexLayerSet 
+		LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+		if (layerset 
 			&& ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT)))
 		{
-			mBakedTextureDatas[i].mTexLayerSet->updateComposite();
+			layerset->updateComposite();
 		}
 	}
 }
@@ -1703,11 +1695,12 @@ S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 wearable_index)
 	const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, wearable_index);
 	if (local_tex_obj)
 	{
+		const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
 		if (type >= 0
 			&& local_tex_obj->getID() != IMG_DEFAULT_AVATAR
-			&& !local_tex_obj->getImage()->isMissingAsset())
+			&& !image->isMissingAsset())
 		{
-			return local_tex_obj->getImage()->getDiscardLevel();
+			return image->getDiscardLevel();
 		}
 		else
 		{
@@ -1732,7 +1725,7 @@ void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const
 			const LLLocalTextureObject *local_tex_obj = getLocalTextureObject((ETextureIndex) type, num);
 			if (local_tex_obj)
 			{
-				const LLViewerFetchedTexture* image_gl = local_tex_obj->getImage();
+				const LLViewerFetchedTexture* image_gl = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
 				if (image_gl)
 				{
 					S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
@@ -1767,8 +1760,8 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
 			llerrs << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << llendl;
 			return;
 		}
-		LLWearableType::EType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType(type);
-		if (!gAgentWearables.getWearable(wearable_type,index))
+		LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(type);
+		if (!gAgentWearables.getViewerWearable(wearable_type,index))
 		{
 			// no wearable is loaded, cannot set the texture.
 			return;
@@ -1781,10 +1774,10 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
 			return;
 		}
 		
-		LLTexLayerSet *layer_set = getLayerSet(type);
+		LLViewerTexLayerSet *layer_set = getLayerSet(type);
 		if (layer_set)
 		{
-			layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getWearable(wearable_type,index));
+			layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getViewerWearable(wearable_type,index));
 		}
 
 	}
@@ -1803,17 +1796,14 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
 				{
 					local_tex_obj->setDiscard(tex_discard);
 					if (isSelf())
-					{
-						if (gAgentAvatarp->isUsingBakedTextures())
 					{
 						requestLayerSetUpdate(type);
-					}
-						else
-					{
-						LLVisualParamHint::requestHintUpdates();
+						if (isEditingAppearance())
+						{
+							LLVisualParamHint::requestHintUpdates();
+						}
 					}
 				}
-				}
 				else
 				{					
 					tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL);
@@ -1826,8 +1816,9 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
 	local_tex_obj->setID(tex->getID());
 	setBakedReady(type,baked_version_ready,index);
 }
+
 //virtual
-void LLVOAvatarSelf::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
+void LLVOAvatarSelf::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
 {
 	if (!isIndexLocalTexture(type)) return;
 	LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index);
@@ -1846,16 +1837,16 @@ void LLVOAvatarSelf::dumpLocalTextures() const
 	/* ETextureIndex baked_equiv[] = {
 	   TEX_UPPER_BAKED,
 	   if (isTextureDefined(baked_equiv[i])) */
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
 			continue;
 
 		const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
-		const ETextureIndex baked_equiv = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex;
+		const ETextureIndex baked_equiv = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex;
 
 		const std::string &name = texture_dict->mName;
 		const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0);
@@ -1878,7 +1869,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
 			}
 			else
 			{
-				const LLViewerFetchedTexture* image = local_tex_obj->getImage();
+				const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
 
 				llinfos << "LocTex " << name << ": "
 						<< "Discard " << image->getDiscardLevel() << ", "
@@ -1955,35 +1946,63 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount()
 
 BOOL LLVOAvatarSelf::getIsCloud() const
 {
+	// Let people know why they're clouded without spamming them into oblivion.
+	bool do_warn = false;
+	static LLTimer time_since_notice;
+	F32 update_freq = 30.0;
+	if (time_since_notice.getElapsedTimeF32() > update_freq)
+	{
+		time_since_notice.reset();
+		do_warn = true;
+	}
+	
 	// do we have our body parts?
-	if (gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE) == 0 ||
-		gAgentWearables.getWearableCount(LLWearableType::WT_HAIR) == 0 ||
-		gAgentWearables.getWearableCount(LLWearableType::WT_EYES) == 0 ||
-		gAgentWearables.getWearableCount(LLWearableType::WT_SKIN) == 0)	
+	S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE);
+	S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR);
+	S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES);
+	S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN);
+	if (!shape_count || !hair_count || !eye_count || !skin_count)
 	{
-		lldebugs << "No body parts" << llendl;
+		if (do_warn)
+		{
+			llinfos << "Self is clouded due to missing one or more required body parts: "
+					<< (shape_count ? "" : "SHAPE ")
+					<< (hair_count ? "" : "HAIR ")
+					<< (eye_count ? "" : "EYES ")
+					<< (skin_count ? "" : "SKIN ")
+					<< llendl;
+		}
 		return TRUE;
 	}
 
 	if (!isTextureDefined(TEX_HAIR, 0))
 	{
-		lldebugs << "No hair texture" << llendl;
+		if (do_warn)
+		{
+			llinfos << "Self is clouded because of no hair texture" << llendl;
+		}
 		return TRUE;
 	}
 
 	if (!mPreviousFullyLoaded)
 	{
-		if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_LOWER].mTexLayerSet) &&
+		if (!isLocalTextureDataAvailable(getLayerSet(BAKED_LOWER)) &&
 			(!isTextureDefined(TEX_LOWER_BAKED, 0)))
 		{
-			lldebugs << "Lower textures not baked" << llendl;
+			if (do_warn)
+			{
+				llinfos << "Self is clouded because lower textures not baked" << llendl;
+			}
 			return TRUE;
 		}
 
-		if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_UPPER].mTexLayerSet) &&
+		if (!isLocalTextureDataAvailable(getLayerSet(BAKED_UPPER)) &&
 			(!isTextureDefined(TEX_UPPER_BAKED, 0)))
 		{
-			lldebugs << "Upper textures not baked" << llendl;
+			if (do_warn)
+			{
+				llinfos << "Self is clouded because upper textures not baked" << llendl;
+			}
 			return TRUE;
 		}
 
@@ -2000,7 +2019,11 @@ BOOL LLVOAvatarSelf::getIsCloud() const
 			const LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex, 0 );
 			if (!baked_img || !baked_img->hasGLTexture())
 			{
-				lldebugs << "Texture at index " << i << " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << llendl;
+				if (do_warn)
+				{
+					llinfos << "Self is clouded because texture at index " << i
+							<< " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << llendl;
+				}
 				return TRUE;
 			}
 		}
@@ -2051,7 +2074,85 @@ void LLVOAvatarSelf::debugBakedTextureUpload(EBakedTextureIndex index, BOOL fini
 	mDebugBakedTextureTimes[index][done] = mDebugSelfLoadTimer.getElapsedTimeF32();
 }
 
-const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const
+const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const
+{
+	std::ostringstream outbuf;
+	for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
+			 LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+		 ++baked_iter)
+	{
+		const EBakedTextureIndex baked_index = baked_iter->first;
+		if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
+		{
+			outbuf << "baked_index: " << baked_index << "\n";
+			const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+				 local_tex_iter != baked_dict->mLocalTextures.end();
+				 ++local_tex_iter)
+			{
+				const ETextureIndex tex_index = *local_tex_iter;
+				const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(tex_index)->mName;
+				outbuf << "  tex_index " << (S32) tex_index << " name " << tex_name << "\n";
+				const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+				const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
+				if (wearable_count > 0)
+				{
+					for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
+					{
+						outbuf << "    " << LLWearableType::getTypeName(wearable_type) << " " << wearable_index << ":";
+						const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(tex_index, wearable_index);
+						if (local_tex_obj)
+						{
+							LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
+							if (tex_index >= 0
+								&& local_tex_obj->getID() != IMG_DEFAULT_AVATAR
+								&& !image->isMissingAsset())
+							{
+								outbuf << " id: " << image->getID()
+									   << " refs: " << image->getNumRefs()
+									   << " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index)
+									   << " discard: " << image->getDiscardLevel()
+									   << " desired: " << image->getDesiredDiscardLevel()
+									   << " decode: " << image->getDecodePriority()
+									   << " addl: " << image->getAdditionalDecodePriority()
+									   << " ts: " << image->getTextureState()
+									   << " bl: " << image->getBoostLevel()
+									   << " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there.
+									   << " cl: " << (image->isFullyLoaded() && image->getDiscardLevel()==0) // "completely loaded"
+									   << " mvs: " << image->getMaxVirtualSize()
+									   << " mvsc: " << image->getMaxVirtualSizeResetCounter()
+									   << " mem: " << image->getTextureMemory();
+							}
+						}
+						outbuf << "\n";
+					}
+				}
+			}
+			break;
+		}
+	}
+	return outbuf.str();
+}
+
+void LLVOAvatarSelf::dumpAllTextures() const
+{
+	std::string vd_text = "Local textures per baked index and wearable:\n";
+	for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+		 ++baked_iter)
+	{
+		const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
+		const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index);
+		if (!layerset) continue;
+		const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
+		if (!layerset_buffer) continue;
+		vd_text += verboseDebugDumpLocalTextureDataInfo(layerset);
+	}
+	LL_DEBUGS("Avatar") << vd_text << llendl;
+}
+
+const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const
 {
 	std::string text="";
 
@@ -2059,21 +2160,21 @@ const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLTexLayer
 
 	/* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
 	   return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
-	for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
 		const EBakedTextureIndex baked_index = baked_iter->first;
 		if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
 		{
-			const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+			const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
 			text += llformat("%d-%s ( ",baked_index, baked_dict->mName.c_str());
 			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 				 local_tex_iter != baked_dict->mLocalTextures.end();
 				 ++local_tex_iter)
 			{
 				const ETextureIndex tex_index = *local_tex_iter;
-				const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+				const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
 				const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 				if (wearable_count > 0)
 				{
@@ -2100,14 +2201,14 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
 
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+		const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
 		BOOL is_texture_final = TRUE;
 		for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 			 local_tex_iter != baked_dict->mLocalTextures.end();
 			 ++local_tex_iter)
 		{
 			const ETextureIndex tex_index = *local_tex_iter;
-			const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+			const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
 			const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 			for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
 			{
@@ -2119,20 +2220,14 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
 	return text;
 }
 
+
+#if 0
 // Dump avatar metrics data.
 LLSD LLVOAvatarSelf::metricsData()
 {
 	// runway - add region info
 	LLSD result;
 	result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
-	std::vector<S32> rez_counts;
-	LLVOAvatar::getNearbyRezzedStats(rez_counts);
-	result["nearby"] = LLSD::emptyMap();
-	for (S32 i=0; i<rez_counts.size(); ++i)
-	{
-		std::string rez_status_name = LLVOAvatar::rezStatusToString(i);
-		result["nearby"][rez_status_name] = rez_counts[i];
-	}
 	result["timers"]["debug_existence"] = mDebugExistenceTimer.getElapsedTimeF32();
 	result["timers"]["ruth_debug"] = mRuthDebugTimer.getElapsedTimeF32();
 	result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32();
@@ -2142,6 +2237,7 @@ LLSD LLVOAvatarSelf::metricsData()
 	
 	return result;
 }
+#endif
 
 class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
 {
@@ -2159,6 +2255,7 @@ class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
 						   const std::string& reason,
 						   const LLSD& content)
 	{
+		gPendingMetricsUploads--; // if we add retry, this should be moved to the isGoodStatus case.
 		if (isGoodStatus(status))
 		{
 			LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
@@ -2167,15 +2264,10 @@ class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
 		else
 		{
 			LL_WARNS("Avatar") << "Failed " << status << " reason " << reason << LL_ENDL;
-			error(status,reason);
+			errorWithContent(status,reason,content);
 		}
 	}
 
-	// virtual
-	void error(U32 status_num, const std::string & reason)
-	{
-	}
-
 	// virtual
 	void result(const LLSD & content)
 	{
@@ -2191,19 +2283,121 @@ class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
 	volatile bool & mReportingStarted;
 };
 
-void LLVOAvatarSelf::sendAppearanceChangeMetrics()
+bool LLVOAvatarSelf::updateAvatarRezMetrics(bool force_send)
+{
+	const F32 AV_METRICS_INTERVAL_QA = 30.0;
+	F32 send_period = 300.0;
+	if (gSavedSettings.getBOOL("QAModeMetrics"))
+	{
+		send_period = AV_METRICS_INTERVAL_QA;
+	}
+
+	if (force_send || mTimeSinceLastRezMessage.getElapsedTimeF32() > send_period)
+	{
+		// Stats for completed phases have been getting logged as they
+		// complete.  This will give us stats for any timers that
+		// haven't finished as of the metric's being sent.
+		
+		if (force_send)
+		{
+			LLVOAvatar::logPendingPhasesAllAvatars();
+		}
+		sendViewerAppearanceChangeMetrics();
+	}
+
+	return false;
+}
+
+void LLVOAvatarSelf::addMetricsTimerRecord(const LLSD& record)
+{
+	mPendingTimerRecords.push_back(record);
+}
+
+bool operator<(const LLSD& a, const LLSD& b)
+{
+	std::ostringstream aout, bout;
+	aout << LLSDNotationStreamer(a);
+	bout << LLSDNotationStreamer(b);
+	std::string astring = aout.str();
+	std::string bstring = bout.str();
+
+	return astring < bstring;
+
+}
+
+// Given a vector of LLSD records, return an LLSD array of bucketed stats for val_field.
+LLSD summarize_by_buckets(std::vector<LLSD> in_records,
+						  std::vector<std::string> by_fields,
+						  std::string val_field)
+{
+	LLSD result = LLSD::emptyArray();
+	std::map<LLSD,LLViewerStats::StatsAccumulator> accum;
+	for (std::vector<LLSD>::iterator in_record_iter = in_records.begin();
+		 in_record_iter != in_records.end(); ++in_record_iter)
+	{
+		LLSD& record = *in_record_iter;
+		LLSD key;
+		for (std::vector<std::string>::iterator field_iter = by_fields.begin();
+			 field_iter != by_fields.end(); ++field_iter)
+		{
+			const std::string& field = *field_iter;
+			key[field] = record[field];
+		}
+		LLViewerStats::StatsAccumulator& stats = accum[key];
+		F32 value = record[val_field].asReal();
+		stats.push(value);
+	}
+	for (std::map<LLSD,LLViewerStats::StatsAccumulator>::iterator accum_it = accum.begin();
+		 accum_it != accum.end(); ++accum_it)
+	{
+		LLSD out_record = accum_it->first;
+		out_record["stats"] = accum_it->second.getData();
+		result.append(out_record);
+	}
+	return result;
+}
+
+void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics()
 {
 	// gAgentAvatarp->stopAllPhases();
 	static volatile bool reporting_started(false);
 	static volatile S32 report_sequence(0);
 
-	LLSD msg = metricsData();
+	LLSD msg; // = metricsData();
 	msg["message"] = "ViewerAppearanceChangeMetrics";
 	msg["session_id"] = gAgentSessionID;
 	msg["agent_id"] = gAgentID;
 	msg["sequence"] = report_sequence;
 	msg["initial"] = !reporting_started;
 	msg["break"] = false;
+	msg["duration"] = mTimeSinceLastRezMessage.getElapsedTimeF32();
+
+	// Status of our own rezzing.
+	msg["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
+
+	// Status of all nearby avs including ourself.
+	msg["nearby"] = LLSD::emptyArray();
+	std::vector<S32> rez_counts;
+	LLVOAvatar::getNearbyRezzedStats(rez_counts);
+	for (S32 rez_stat=0; rez_stat < rez_counts.size(); ++rez_stat)
+	{
+		std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
+		msg["nearby"][rez_status_name] = rez_counts[rez_stat];
+	}
+
+	//	std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");
+	std::vector<std::string> by_fields;
+	by_fields.push_back("timer_name");
+	by_fields.push_back("completed");
+	by_fields.push_back("grid_x");
+	by_fields.push_back("grid_y");
+	by_fields.push_back("is_using_server_bakes");
+	by_fields.push_back("is_self");
+	by_fields.push_back("central_bake_version");
+	LLSD summary = summarize_by_buckets(mPendingTimerRecords, by_fields, std::string("elapsed"));
+	msg["timers"] = summary;
+
+	mPendingTimerRecords.clear();
 
 	// Update sequence number
 	if (S32_MAX == ++report_sequence)
@@ -2218,20 +2412,79 @@ void LLVOAvatarSelf::sendAppearanceChangeMetrics()
 	}
 	if (!caps_url.empty())
 	{
+		gPendingMetricsUploads++;
 		LLCurlRequest::headers_t headers;
 		LLHTTPClient::post(caps_url,
 						   msg,
 						   new ViewerAppearanceChangeMetricsResponder(report_sequence,
 																	  report_sequence,
 																	  reporting_started));
+		mTimeSinceLastRezMessage.reset();
 	}
 }
 
+class CheckAgentAppearanceServiceResponder: public LLHTTPClient::Responder
+{
+public:
+	CheckAgentAppearanceServiceResponder()
+	{
+	}
+	
+	virtual ~CheckAgentAppearanceServiceResponder()
+	{
+	}
+
+	/* virtual */ void result(const LLSD& content)
+	{
+		LL_DEBUGS("Avatar") << "status OK" << llendl;
+	}
+
+	// Error
+	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	{
+		if (isAgentAvatarValid())
+		{
+			LL_DEBUGS("Avatar") << "failed, will rebake [status:"
+					<< status << "]: " << content << llendl;
+			forceAppearanceUpdate();
+		}
+	}	
+
+	static void forceAppearanceUpdate()
+	{
+		// Trying to rebake immediately after crossing region boundary
+		// seems to be failure prone; adding a delay factor. Yes, this
+		// fix is ad-hoc and not guaranteed to work in all cases.
+		doAfterInterval(boost::bind(&LLVOAvatarSelf::forceBakeAllTextures,
+									gAgentAvatarp.get(), true), 5.0);
+	}
+};
+
+void LLVOAvatarSelf::checkForUnsupportedServerBakeAppearance()
+{
+	// Need to check only if we have a server baked appearance and are
+	// in a non-baking region.
+	if (!gAgentAvatarp->isUsingServerBakes())
+		return;
+	if (!gAgent.getRegion() || gAgent.getRegion()->getCentralBakeVersion()!=0)
+		return;
+
+	// if baked image service is unknown, need to refresh.
+	if (LLAppearanceMgr::instance().getAppearanceServiceURL().empty())
+	{
+		CheckAgentAppearanceServiceResponder::forceAppearanceUpdate();
+	}
+	// query baked image service to check status.
+	std::string image_url = gAgentAvatarp->getImageURL(TEX_HEAD_BAKED,
+													   getTE(TEX_HEAD_BAKED)->getID());
+	LLHTTPClient::head(image_url, new CheckAgentAppearanceServiceResponder);
+}
+
 const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const
 {
 	if (canGrabBakedTexture(baked_index))
 	{
-		ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index);
+		ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index);
 		if (tex_index == TEX_NUM_INDICES)
 		{
 			return LLUUID::null;
@@ -2243,7 +2496,7 @@ const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) c
 
 BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
 {
-	ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index);
+	ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index);
 	if (tex_index == TEX_NUM_INDICES)
 	{
 		return FALSE;
@@ -2262,19 +2515,19 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
 	// baked texture.  We don't want people copying people's
 	// work via baked textures.
 
-	const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
+	const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index);
 	for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin();
 		 iter != baked_dict->mLocalTextures.end();
 		 ++iter)
 	{
 		const ETextureIndex t_index = (*iter);
-		LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(t_index);
+		LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(t_index);
 		U32 count = gAgentWearables.getWearableCount(wearable_type);
 		lldebugs << "Checking index " << (U32) t_index << " count: " << count << llendl;
 		
 		for (U32 wearable_index = 0; wearable_index < count; ++wearable_index)
 		{
-			LLWearable *wearable = gAgentWearables.getWearable(wearable_type, wearable_index);
+			LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, wearable_index);
 			if (wearable)
 			{
 				const LLLocalTextureObject *texture = wearable->getLocalTextureObject((S32)t_index);
@@ -2316,26 +2569,34 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
 }
 
 void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTexture* imagep,
-										   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index )
+										   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)
 {
 	if (!isIndexLocalTexture(type)) return;
 
-	if (!covered_by_baked)
+	// Sunshine - ignoring covered_by_baked will force local textures
+	// to always load.  Fix for SH-4001 and many related issues.  Do
+	// not restore this without some more targetted fix for the local
+	// textures failing to load issue.
+	//if (!covered_by_baked)
 	{
-		if (getLocalTextureID(type, index) != IMG_DEFAULT_AVATAR && imagep->getDiscardLevel() != 0)
+		if (imagep->getID() != IMG_DEFAULT_AVATAR)
 		{
-			F32 desired_pixels;
-			desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
-			imagep->setBoostLevel(getAvatarBoostLevel());
-
-			imagep->resetTextureStats();
-			imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
-			imagep->addTextureStats( desired_pixels / texel_area_ratio );
-			imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
-			imagep->forceUpdateBindStats() ;
-			if (imagep->getDiscardLevel() < 0)
+			imagep->setNoDelete();
+			if (imagep->getDiscardLevel() != 0)
 			{
-				mHasGrey = TRUE; // for statistics gathering
+				F32 desired_pixels;
+				desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
+				
+				imagep->setBoostLevel(getAvatarBoostLevel());
+				imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
+				imagep->resetTextureStats();
+				imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
+				imagep->addTextureStats( desired_pixels / texel_area_ratio );
+				imagep->forceUpdateBindStats() ;
+				if (imagep->getDiscardLevel() < 0)
+				{
+					mHasGrey = TRUE; // for statistics gathering
+				}
 			}
 		}
 		else
@@ -2346,10 +2607,10 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
 	}
 }
 
-LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 wearable_index) const
+LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 wearable_index) const
 {
-	LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
-	LLWearable* wearable = gAgentWearables.getWearable(type, wearable_index);
+	LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i);
+	LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_index);
 	if (wearable)
 	{
 		return wearable->getLocalTextureObject(i);
@@ -2362,7 +2623,7 @@ LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLVOAvatarDefines::E
 // getBakedTE()
 // Used by the LayerSet.  (Layer sets don't in general know what textures depend on them.)
 //-----------------------------------------------------------------------------
-ETextureIndex LLVOAvatarSelf::getBakedTE( const LLTexLayerSet* layerset ) const
+ETextureIndex LLVOAvatarSelf::getBakedTE( const LLViewerTexLayerSet* layerset ) const
 {
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
@@ -2376,9 +2637,9 @@ ETextureIndex LLVOAvatarSelf::getBakedTE( const LLTexLayerSet* layerset ) const
 }
 
 
-void LLVOAvatarSelf::setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid)
+void LLVOAvatarSelf::setNewBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex i, const LLUUID &uuid)
 {
-	ETextureIndex index = LLVOAvatarDictionary::bakedToLocalTextureIndex(i);
+	ETextureIndex index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(i);
 	setNewBakedTexture(index, uuid);
 }
 
@@ -2391,7 +2652,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
 {
 	// Baked textures live on other sims.
 	LLHost target_host = getObjectHost();	
-	setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, target_host ) );
+	setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, FTT_HOST_BAKE, target_host ) );
 	updateMeshTextures();
 	dirtyMesh();
 
@@ -2400,7 +2661,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
 	/* switch(te)
 		case TEX_HEAD_BAKED:
 			llinfos << "New baked texture: HEAD" << llendl; */
-	const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(te);
+	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(te);
 	if (texture_dict->mIsBakedTexture)
 	{
 		debugBakedTextureUpload(texture_dict->mBakedTextureIndex, TRUE); // FALSE for start of upload, TRUE for finish.
@@ -2465,7 +2726,7 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
 	LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl;
 	LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl;
 	LL_DEBUGS("Avatar") << "\t Load time for each texture: " << llendl;
-	for (U32 i = 0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i)
+	for (U32 i = 0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i)
 	{
 		std::stringstream out;
 		out << "\t\t (" << i << ") ";
@@ -2493,27 +2754,29 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
 		}
 	}
 	LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << llendl;
-	for (U32 i = 0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i)
+	for (U32 i = 0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i)
 	{
 		LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl;
 	}
 
-	for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
-		const LLVOAvatarDefines::EBakedTextureIndex baked_index = baked_iter->first;
-		const LLTexLayerSet *layerset = debugGetLayerSet(baked_index);
+		const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
+		const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index);
 		if (!layerset) continue;
-		const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+		const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
 		if (!layerset_buffer) continue;
 		LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << llendl;
 	}
+
+	dumpAllTextures();
 }
 
 void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const
 {
-	LL_INFOS("Avatar")
+	LL_DEBUGS("Avatar")
 		<< avString()
 		<< llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32())
 		<< LL_ENDL;
@@ -2538,7 +2801,8 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid
 				mHeadLayerSet->cancelUpload(); */
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		if ( mBakedTextureDatas[i].mTextureIndex == te && mBakedTextureDatas[i].mTexLayerSet)
+		LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+		if ( mBakedTextureDatas[i].mTextureIndex == te && layerset)
 		{
 			if (mInitialBakeIDs[i] != LLUUID::null)
 			{
@@ -2552,7 +2816,7 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid
 				}
 				mInitialBakeIDs[i] = LLUUID::null;
 			}
-			mBakedTextureDatas[i].mTexLayerSet->cancelUpload();
+			layerset->cancelUpload();
 		}
 	}
 }
@@ -2571,17 +2835,17 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
 	/* ETextureIndex baked_texture_indices[BAKED_NUM_INDICES] =
 			TEX_HEAD_BAKED,
 			TEX_UPPER_BAKED, */
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
 		const ETextureIndex index = iter->first;
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		if (texture_dict->mIsBakedTexture)
 		{
 			if (texture_id == gAgentAvatarp->getTEImage(index)->getID())
 			{
-				LLTexLayerSet* layer_set = gAgentAvatarp->getLayerSet(index);
+				LLViewerTexLayerSet* layer_set = gAgentAvatarp->getLayerSet(index);
 				if (layer_set)
 				{
 					llinfos << "TAT: rebake - matched entry " << (S32)index << llendl;
@@ -2605,15 +2869,6 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
 	}
 }
 
-BOOL LLVOAvatarSelf::isUsingBakedTextures() const
-{
-	// Composite textures are used during appearance mode.
-	if (gAgentCamera.cameraCustomizeAvatar())
-		return FALSE;
-
-	return TRUE;
-}
-
 
 void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
 {
@@ -2622,7 +2877,7 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
 		ETextureIndex baked_index = mBakedTextureDatas[i].mTextureIndex;
-		LLTexLayerSet* layer_set = getLayerSet(baked_index);
+		LLViewerTexLayerSet* layer_set = getLayerSet(baked_index);
 		if (layer_set)
 		{
 			if (slam_for_debug)
@@ -2654,7 +2909,7 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
 		case LOCTEX_UPPER_SHIRT:
 			if( mUpperBodyLayerSet )
 				mUpperBodyLayerSet->requestUpdate(); */
-	const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
+	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
 	if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
 		return;
 	const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
@@ -2664,22 +2919,22 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
 	}
 }
 
-LLTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
+LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
 {
-	/* switch(index)
-		case TEX_HEAD_BAKED:
-		case TEX_HEAD_BODYPAINT:
-			return mHeadLayerSet; */
-	const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
-	if (texture_dict->mIsUsedByBakedTexture)
-	{
-		const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
-		return mBakedTextureDatas[baked_index].mTexLayerSet;
-	}
-	return NULL;
+       /* switch(index)
+               case TEX_HEAD_BAKED:
+               case TEX_HEAD_BODYPAINT:
+                       return mHeadLayerSet; */
+       const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+       if (texture_dict->mIsUsedByBakedTexture)
+       {
+               const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+               return getLayerSet(baked_index);
+       }
+       return NULL;
 }
 
-LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const
+LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const
 {
        /* switch(index)
                case TEX_HEAD_BAKED:
@@ -2687,26 +2942,60 @@ LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const
                        return mHeadLayerSet; */
        if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES)
        {
-                       return mBakedTextureDatas[baked_index].mTexLayerSet;
+		   return  getTexLayerSet(baked_index);
        }
        return NULL;
 }
 
 
+
+
 // static
-void LLVOAvatarSelf::onCustomizeStart()
+void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)
 {
-	// We're no longer doing any baking or invalidating on entering 
-	// appearance editing mode. Leaving function in place in case 
-	// further changes require us to do something at this point - Nyx
+	if (isAgentAvatarValid())
+	{
+		gAgentAvatarp->mIsEditingAppearance = true;
+		gAgentAvatarp->mUseLocalAppearance = true;
+
+		if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
+		{
+			gAgentCamera.changeCameraToCustomizeAvatar();
+		}
+
+#if 0
+		gAgentAvatarp->clearVisualParamWeights();
+		gAgentAvatarp->idleUpdateAppearanceAnimation();
+#endif
+		
+		gAgentAvatarp->invalidateAll(); // mark all bakes as dirty, request updates
+		gAgentAvatarp->updateMeshTextures(); // make sure correct textures are applied to the avatar mesh.
+		gAgentAvatarp->updateTextures(); // call updateTextureStats
+	}
 }
 
 // static
-void LLVOAvatarSelf::onCustomizeEnd()
+void LLVOAvatarSelf::onCustomizeEnd(bool disable_camera_switch)
 {
+
 	if (isAgentAvatarValid())
 	{
+		gAgentAvatarp->mIsEditingAppearance = false;
+		if (gAgentAvatarp->getRegion() && !gAgentAvatarp->getRegion()->getCentralBakeVersion())
+		{
+			// FIXME DRANO - move to sendAgentSetAppearance, make conditional on upload complete.
+			gAgentAvatarp->mUseLocalAppearance = false;
+		}
+
 		gAgentAvatarp->invalidateAll();
+
+		if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
+		{
+			gAgentCamera.changeCameraToDefault();
+			gAgentCamera.resetView();
+		}
+	
+		LLAppearanceMgr::instance().updateAppearanceFromCOF();	
 	}
 }
 
@@ -2719,12 +3008,12 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
 {
 	LLUUID texture_id[TEX_NUM_INDICES];
 	// pack away current TEs to make sure we don't send them out
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
 		const ETextureIndex index = iter->first;
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		if (!texture_dict->mIsBakedTexture)
 		{
 			LLTextureEntry* entry = getTE((U8) index);
@@ -2736,12 +3025,12 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
 	bool success = packTEMessage(mesgsys);
 
 	// unpack TEs to make sure we don't re-trigger a bake
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
 		const ETextureIndex index = iter->first;
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		if (!texture_dict->mIsBakedTexture)
 		{
 			LLTextureEntry* entry = getTE((U8) index);
@@ -2797,3 +3086,36 @@ void LLVOAvatarSelf::dumpScratchTextureByteCount()
 {
 	llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl;
 }
+
+void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile)
+{
+	apr_file_t* file = outfile.getFileHandle();
+	if (!file)
+	{
+		return;
+	}
+
+	
+	apr_file_printf( file, "\n<wearable_info>\n" );
+
+	LLWearableData *wd = getWearableData();
+	for (S32 type = 0; type < LLWearableType::WT_COUNT; type++)
+	{
+		const std::string& type_name = LLWearableType::getTypeName((LLWearableType::EType)type);
+		for (U32 j=0; j< wd->getWearableCount((LLWearableType::EType)type); j++)
+		{
+			LLViewerWearable *wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)type,j);
+			apr_file_printf( file, "\n\t    <wearable type=\"%s\" name=\"%s\"/>\n",
+							 type_name.c_str(), wearable->getName().c_str() );
+			LLWearable::visual_param_vec_t v_params;
+			wearable->getVisualParams(v_params);
+			for (LLWearable::visual_param_vec_t::iterator it = v_params.begin();
+				 it != v_params.end(); ++it)
+			{
+				LLVisualParam *param = *it;
+				dump_visual_param(file, param, param->getWeight());
+			}
+		}
+	}
+	apr_file_printf( file, "\n</wearable_info>\n" );
+}
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 7bd0c0bf93428af3743a90d030b4dab725f577d4..3b7b6bac64a07ed801ef9aa9b4f5905cc687ff02 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -67,9 +67,8 @@ class LLVOAvatarSelf :
 protected:
 	/*virtual*/ BOOL		loadAvatar();
 	BOOL					loadAvatarSelf();
-	BOOL					buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info);
+	BOOL					buildSkeletonSelf(const LLAvatarSkeletonInfo *info);
 	BOOL					buildMenus();
-	/*virtual*/ BOOL		loadLayersets();
 
 /**                    Initialization
  **                                                                            **
@@ -97,7 +96,7 @@ class LLVOAvatarSelf :
 	
 				void		resetJointPositions( void );
 	
-	/*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
+	/*virtual*/ BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
 	/*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );
 	/*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );
 	/*virtual*/ void updateVisualParams();
@@ -111,7 +110,7 @@ class LLVOAvatarSelf :
 
 private:
 	// helper function. Passed in param is assumed to be in avatar's parameter list.
-	BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE );
+	BOOL setParamWeight(const LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE );
 
 
 
@@ -131,6 +130,7 @@ class LLVOAvatarSelf :
 
 public:
 	/*virtual*/ bool 	isSelf() const { return true; }
+	/*virtual*/ BOOL	isValid() const;
 
 	//--------------------------------------------------------------------
 	// Updates
@@ -177,8 +177,8 @@ class LLVOAvatarSelf :
 	// LLVOAvatar Constants
 	//--------------------------------------------------------------------
 public:
-	/*virtual*/ LLViewerTexture::EBoostLevel 	getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_SELF; }
-	/*virtual*/ LLViewerTexture::EBoostLevel 	getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED_SELF; }
+	/*virtual*/ LLViewerTexture::EBoostLevel 	getAvatarBoostLevel() const { return LLGLTexture::BOOST_AVATAR_SELF; }
+	/*virtual*/ LLViewerTexture::EBoostLevel 	getAvatarBakedBoostLevel() const { return LLGLTexture::BOOST_AVATAR_BAKED_SELF; }
 	/*virtual*/ S32 						getTexImageSize() const { return LLVOAvatar::getTexImageSize()*4; }
 
 /**                    Rendering
@@ -195,32 +195,32 @@ class LLVOAvatarSelf :
 	//--------------------------------------------------------------------
 public:
 	/*virtual*/ bool	hasPendingBakedUploads() const;
-	S32					getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
+	S32					getLocalDiscardLevel(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
 	bool				areTexturesCurrent() const;
-	BOOL				isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const;
-	BOOL				isLocalTextureDataFinal(const LLTexLayerSet* layerset) const;
-	BOOL				isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const;
+	BOOL				isLocalTextureDataAvailable(const LLViewerTexLayerSet* layerset) const;
+	BOOL				isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset) const;
+	BOOL				isBakedTextureFinal(const LLAvatarAppearanceDefines::EBakedTextureIndex index) const;
 	// If you want to check all textures of a given type, pass gAgentWearables.getWearableCount() for index
-	/*virtual*/ BOOL    isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
-	/*virtual*/ BOOL	isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
-	/*virtual*/ BOOL	isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const;
+	/*virtual*/ BOOL    isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
+	/*virtual*/ BOOL	isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const;
+	/*virtual*/ BOOL	isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const;
 
 
 	//--------------------------------------------------------------------
 	// Local Textures
 	//--------------------------------------------------------------------
 public:
-	BOOL				getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index) const;
-	LLViewerFetchedTexture*	getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
-	const LLUUID&		getLocalTextureID(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
+	BOOL				getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index) const;
+	LLViewerFetchedTexture*	getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
+	const LLUUID&		getLocalTextureID(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
 	void				setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index);
-	/*virtual*/ void	setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index);
+	/*virtual*/ void	setLocalTexture(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index);
 protected:
-	/*virtual*/ void	setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index);
+	/*virtual*/ void	setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index);
 	void				localTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
 	void				getLocalTextureByteCount(S32* gl_byte_count) const;
-	/*virtual*/ void	addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index);
-	LLLocalTextureObject* getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 index) const;
+	/*virtual*/ void	addLocalTextureStats(LLAvatarAppearanceDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked);
+	LLLocalTextureObject* getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 index) const;
 
 private:
 	static void			onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
@@ -233,13 +233,12 @@ class LLVOAvatarSelf :
 	// Baked textures
 	//--------------------------------------------------------------------
 public:
-	LLVOAvatarDefines::ETextureIndex getBakedTE(const LLTexLayerSet* layerset ) const;
-	void				setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid);
-	void				setNewBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
-	void				setCachedBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
+	LLAvatarAppearanceDefines::ETextureIndex getBakedTE(const LLViewerTexLayerSet* layerset ) const;
+	void				setNewBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex i, const LLUUID &uuid);
+	void				setNewBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i, const LLUUID& uuid);
+	void				setCachedBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i, const LLUUID& uuid);
 	void				forceBakeAllTextures(bool slam_for_debug = false);
 	static void			processRebakeAvatarTextures(LLMessageSystem* msg, void**);
-	BOOL				isUsingBakedTextures() const; // e.g. false if in appearance edit mode
 protected:
 	/*virtual*/ void	removeMissingBakedTextures();
 
@@ -248,10 +247,11 @@ class LLVOAvatarSelf :
 	//--------------------------------------------------------------------
 public:
 	void 				requestLayerSetUploads();
-	void				requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i);
-	void				requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i);
-	LLTexLayerSet*		getLayerSet(LLVOAvatarDefines::ETextureIndex index) const;
-	LLTexLayerSet* 		getLayerSet(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;
+	void				requestLayerSetUpload(LLAvatarAppearanceDefines::EBakedTextureIndex i);
+	void				requestLayerSetUpdate(LLAvatarAppearanceDefines::ETextureIndex i);
+	LLViewerTexLayerSet* getLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
+	LLViewerTexLayerSet* getLayerSet(LLAvatarAppearanceDefines::ETextureIndex index) const;
+
 	
 	//--------------------------------------------------------------------
 	// Composites
@@ -265,8 +265,8 @@ class LLVOAvatarSelf :
 	void				setupComposites();
 	void				updateComposites();
 
-	const LLUUID&		grabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;
-	BOOL				canGrabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;
+	const LLUUID&		grabBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
+	BOOL				canGrabBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
 
 
 	//--------------------------------------------------------------------
@@ -300,10 +300,9 @@ class LLVOAvatarSelf :
  **/
 
 public:
-	/*virtual*/ BOOL	isWearingWearableType(LLWearableType::EType type) const;
 	void				wearableUpdated(LLWearableType::EType type, BOOL upload_result);
 protected:
-	U32 getNumWearables(LLVOAvatarDefines::ETextureIndex i) const;
+	U32 getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const;
 
 	//--------------------------------------------------------------------
 	// Attachments
@@ -340,8 +339,8 @@ class LLVOAvatarSelf :
  **/
 
 public:
-	static void		onCustomizeStart();
-	static void		onCustomizeEnd();
+	static void		onCustomizeStart(bool disable_camera_switch = false);
+	static void		onCustomizeEnd(bool disable_camera_switch = false);
 
 	//--------------------------------------------------------------------
 	// Visibility
@@ -365,6 +364,7 @@ class LLVOAvatarSelf :
 	static void		dumpTotalLocalTextureByteCount();
 	void			dumpLocalTextures() const;
 	static void		dumpScratchTextureByteCount();
+	void			dumpWearableInfo(LLAPRFile& outfile);
 
 	//--------------------------------------------------------------------
 	// Avatar Rez Metrics
@@ -372,34 +372,43 @@ class LLVOAvatarSelf :
 public:	
 	struct LLAvatarTexData
 	{
-		LLAvatarTexData(const LLUUID& id, LLVOAvatarDefines::ETextureIndex index) : 
+		LLAvatarTexData(const LLUUID& id, LLAvatarAppearanceDefines::ETextureIndex index) : 
 			mAvatarID(id), 
 			mIndex(index) 
 		{}
 		LLUUID			mAvatarID;
-		LLVOAvatarDefines::ETextureIndex	mIndex;
+		LLAvatarAppearanceDefines::ETextureIndex	mIndex;
 	};
+
+	LLTimer					mTimeSinceLastRezMessage;
+	bool					updateAvatarRezMetrics(bool force_send);
+
+	std::vector<LLSD>		mPendingTimerRecords;
+	void 					addMetricsTimerRecord(const LLSD& record);
+	
 	void 					debugWearablesLoaded() { mDebugTimeWearablesLoaded = mDebugSelfLoadTimer.getElapsedTimeF32(); }
 	void 					debugAvatarVisible() { mDebugTimeAvatarVisible = mDebugSelfLoadTimer.getElapsedTimeF32(); }
 	void 					outputRezDiagnostics() const;
 	void					outputRezTiming(const std::string& msg) const;
 	void					reportAvatarRezTime() const;
-	void 					debugBakedTextureUpload(LLVOAvatarDefines::EBakedTextureIndex index, BOOL finished);
+	void 					debugBakedTextureUpload(LLAvatarAppearanceDefines::EBakedTextureIndex index, BOOL finished);
 	static void				debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
 
 	BOOL					isAllLocalTextureDataFinal() const;
 
-	const LLTexLayerSet*  	debugGetLayerSet(LLVOAvatarDefines::EBakedTextureIndex index) const { return mBakedTextureDatas[index].mTexLayerSet; }
-	const std::string		debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer
+	const LLViewerTexLayerSet*	debugGetLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex index) const { return (LLViewerTexLayerSet*)(mBakedTextureDatas[index].mTexLayerSet); }
+	const std::string		verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer
+	void					dumpAllTextures() const;
+	const std::string		debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer
 	const std::string		debugDumpAllLocalTextureDataInfo() const; // Lists out which baked textures are at highest LOD
-	LLSD					metricsData();
-	void					sendAppearanceChangeMetrics(); // send data associated with completing a change.
+	void					sendViewerAppearanceChangeMetrics(); // send data associated with completing a change.
+	void 					checkForUnsupportedServerBakeAppearance();
 private:
 	LLFrameTimer    		mDebugSelfLoadTimer;
 	F32						mDebugTimeWearablesLoaded;
 	F32 					mDebugTimeAvatarVisible;
-	F32 					mDebugTextureLoadTimes[LLVOAvatarDefines::TEX_NUM_INDICES][MAX_DISCARD_LEVEL+1]; // load time for each texture at each discard level
-	F32 					mDebugBakedTextureTimes[LLVOAvatarDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture
+	F32 					mDebugTextureLoadTimes[LLAvatarAppearanceDefines::TEX_NUM_INDICES][MAX_DISCARD_LEVEL+1]; // load time for each texture at each discard level
+	F32 					mDebugBakedTextureTimes[LLAvatarAppearanceDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture
 	void					debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
 
 /**                    Diagnostics
@@ -413,8 +422,7 @@ extern LLPointer<LLVOAvatarSelf> gAgentAvatarp;
 BOOL isAgentAvatarValid();
 
 void selfStartPhase(const std::string& phase_name);
-void selfStopPhase(const std::string& phase_name);
-void selfStopAllPhases();
+void selfStopPhase(const std::string& phase_name, bool err_check = true);
 void selfClearPhases();
 
 #endif // LL_VO_AVATARSELF_H
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 4dca87652da8d7135ceadeb01acc6a0df8d579d7..6a25b765cf86a4c43492a086481a1d817040aea0 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -102,7 +102,7 @@ void LLVOGrass::updateSpecies()
 		SpeciesMap::const_iterator it = sSpeciesTable.begin();
 		mSpecies = (*it).first;
 	}
-	setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+	setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
 }
 
 
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index ceff75a0cc29e4722e5e076c99d373460655a894..ac2a34ba1e90fdc399a0fd9278a394db58ca2c58 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -56,7 +56,8 @@ class LLVoiceCallCapResponder : public LLHTTPClient::Responder
 public:
 	LLVoiceCallCapResponder(const LLUUID& session_id) : mSessionID(session_id) {};
 
-	virtual void error(U32 status, const std::string& reason);	// called with bad status codes
+	// called with bad status codes
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	virtual void result(const LLSD& content);
 
 private:
@@ -64,11 +65,10 @@ class LLVoiceCallCapResponder : public LLHTTPClient::Responder
 };
 
 
-void LLVoiceCallCapResponder::error(U32 status, const std::string& reason)
+void LLVoiceCallCapResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	LL_WARNS("Voice") << "LLVoiceCallCapResponder::error("
-		<< status << ": " << reason << ")"
-		<< LL_ENDL;
+	LL_WARNS("Voice") << "LLVoiceCallCapResponder error [status:"
+		<< status << "]: " << content << LL_ENDL;
 	LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
 	if ( channelp )
 	{
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index b497f80560fbc6c82d72ae920445d2d43c7168b5..9281334d813146ad4e1738084fc27e65385e1d1a 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -125,7 +125,7 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
 	for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
 	{
 		mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
-		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
+		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FTT_LOCAL_FILE, FALSE, LLGLTexture::BOOST_UI);
 		mSoundSymbol.mWaveActive			[i] = false;
 		mSoundSymbol.mWaveOpacity			[i] = 1.0f;
 		mSoundSymbol.mWaveExpansion			[i] = 1.0f;
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index c3cc90f040567c7c596c55e7e84825069427e6aa..9b5d981aa5ccfc7cf5a62cfd119474a2bfdb5a96 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -130,17 +130,18 @@ class LLVivoxVoiceAccountProvisionResponder :
 		mRetries = retries;
 	}
 
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
+		LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, "
+			<<  ( (mRetries > 0) ? "retrying" : "too many retries (giving up)" )
+			<< status << "]: " << content << LL_ENDL;
+
 		if ( mRetries > 0 )
 		{
-			LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, retrying.  status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL;
-			LLVivoxVoiceClient::getInstance()->requestVoiceAccountProvision(
-				mRetries - 1);
+			LLVivoxVoiceClient::getInstance()->requestVoiceAccountProvision(mRetries - 1);
 		}
 		else
 		{
-			LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, too many retries (giving up).  status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL;
 			LLVivoxVoiceClient::getInstance()->giveUp();
 		}
 	}
@@ -199,18 +200,18 @@ class LLVivoxVoiceClientCapResponder : public LLHTTPClient::Responder
 public:
 	LLVivoxVoiceClientCapResponder(LLVivoxVoiceClient::state requesting_state) : mRequestingState(requesting_state) {};
 
-	virtual void error(U32 status, const std::string& reason);	// called with bad status codes
+	// called with bad status codes
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	virtual void result(const LLSD& content);
 
 private:
 	LLVivoxVoiceClient::state mRequestingState;  // state 
 };
 
-void LLVivoxVoiceClientCapResponder::error(U32 status, const std::string& reason)
+void LLVivoxVoiceClientCapResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	LL_WARNS("Voice") << "LLVivoxVoiceClientCapResponder::error("
-		<< status << ": " << reason << ")"
-		<< LL_ENDL;
+	LL_WARNS("Voice") << "LLVivoxVoiceClientCapResponder error [status:"
+		<< status << "]: " << content << LL_ENDL;
 	LLVivoxVoiceClient::getInstance()->sessionTerminate();
 }
 
@@ -2249,7 +2250,8 @@ void LLVivoxVoiceClient::giveUp()
 
 static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVector3d &pos, LLVector3 &vel)
 {
-	F32 nat[3], nup[3], nl[3], nvel[3]; // the new at, up, left vectors and the  new position and velocity
+	F32 nat[3], nup[3], nl[3]; // the new at, up, left vectors and the  new position and velocity
+//	F32 nvel[3]; 
 	F64 npos[3];
 	
 	// The original XML command was sent like this:
@@ -2299,9 +2301,9 @@ static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVe
 	npos[1] = pos.mdV[VZ];
 	npos[2] = pos.mdV[VY];
 
-	nvel[0] = vel.mV[VX];
-	nvel[1] = vel.mV[VZ];
-	nvel[2] = vel.mV[VY];
+//	nvel[0] = vel.mV[VX];
+//	nvel[1] = vel.mV[VZ];
+//	nvel[2] = vel.mV[VY];
 
 	for(int i=0;i<3;++i) {
 		at.mV[i] = nat[i];
@@ -3938,7 +3940,6 @@ void LLVivoxVoiceClient::messageEvent(
 			bool is_do_not_disturb = gAgent.isDoNotDisturb();
 			bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat);
 			bool is_linden = LLMuteList::getInstance()->isLinden(session->mName);
-			bool quiet_chat = false;
 			LLChat chat;
 
 			chat.mMuted = is_muted && !is_linden;
@@ -3951,7 +3952,6 @@ void LLVivoxVoiceClient::messageEvent(
 
 				if(is_do_not_disturb && !is_linden)
 				{
-					quiet_chat = true;
 					// TODO: Question: Return do not disturb mode response here?  Or maybe when session is started instead?
 				}
 				
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 31358df85fc082e5bc9c660489d80a93251374ff..36793017ed903e96c0f8b65e20b784df6bf35a5f 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -298,7 +298,7 @@ void LLSkyTex::create(const F32 brightness)
 
 void LLSkyTex::createGLImage(S32 which)
 {	
-	mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLViewerTexture::LOCAL);
+	mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL);
 	mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
 }
 
@@ -384,9 +384,9 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
 	mSun.setIntensity(SUN_INTENSITY);
 	mMoon.setIntensity(0.1f * SUN_INTENSITY);
 
-	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
-	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
 	mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
 	mBloomTexturep->setNoDelete() ;
@@ -478,9 +478,9 @@ void LLVOSky::restoreGL()
 	{
 		mSkyTex[i].restoreGL();
 	}
-	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
-	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
 	mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
 	mBloomTexturep->setNoDelete() ;
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index cb905d02da0dd458f2490b45a7490e749943a73f..de15f0ef43f68cfeabc30996e9a4ac14f689bd77 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -467,7 +467,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
 	S32 vertex_count = 0;
 	S32 i, x, y;
 
-	S32 num_vertices, num_indices;
+	S32 num_vertices;
 
 	U32 render_stride = mLastStride;
 	S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
@@ -485,7 +485,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
 	if (north_stride == render_stride)
 	{
 		num_vertices = 2 * length + 1;
-		num_indices = length * 6 - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
 
@@ -536,7 +535,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
 	{
 		// North stride is longer (has less vertices)
 		num_vertices = length + length/2 + 1;
-		num_indices = half_length*9 - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
 
@@ -595,7 +593,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
 		length = patch_size / north_stride;
 		half_length = length / 2;
 		num_vertices = length + half_length + 1;
-		num_indices = 9*half_length - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
 
@@ -666,7 +663,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
 {
 	S32 i, x, y;
 
-	S32 num_vertices, num_indices;
+	S32 num_vertices;
 
 	U32 render_stride = mLastStride;
 	S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
@@ -679,7 +676,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
 	if (east_stride == render_stride)
 	{
 		num_vertices = 2 * length + 1;
-		num_indices = length * 6 - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
 
@@ -728,7 +724,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
 	{
 		// East stride is longer (has less vertices)
 		num_vertices = length + half_length + 1;
-		num_indices = half_length*9 - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
 
@@ -783,7 +778,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
 		length = patch_size / east_stride;
 		half_length = length / 2;
 		num_vertices = length + length/2 + 1;
-		num_indices = 9*(length/2) - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
 
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 6687ce432fadaade4b53250b167e49d369312cf5..145a0380d6891d611e7e3494251a627fce71c76d 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -316,7 +316,7 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys,
 	//  Load Species-Specific data 
 	//
 	static const S32 MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 32 ; //frames.
-	mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 	mTreeImagep->setMaxVirtualSizeResetInterval(MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); //allow to wait for at most 16 frames to reset virtual size.
 
 	mBranchLength = sSpeciesTable[mSpecies]->mBranchLength;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index d94cd01a0b793c182b97d7ea95c6b973960da868..8730ef66bbaa503fcbbc7ed00efac0bf5edbed03 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -370,7 +370,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
 		// Unpack texture entry data
 		//
 
-		S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
+		S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);
 		if (result & teDirtyBits)
 		{
 			updateTEData();
@@ -747,7 +747,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 		{
 			F32 area = (F32) camera->getScreenPixelArea();
 			vsize = area;
-			imagep->setBoostLevel(LLViewerTexture::BOOST_HUD);
+			imagep->setBoostLevel(LLGLTexture::BOOST_HUD);
  			face->setPixelArea(area); // treat as full screen
 			face->setVirtualSize(vsize);
 		}
@@ -803,7 +803,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 		if (mSculptTexture.notNull())
 		{
 			mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
-												(S32)LLViewerTexture::BOOST_SCULPTED));
+												(S32)LLGLTexture::BOOST_SCULPTED));
 			mSculptTexture->setForSculpt() ;
 			
 			if(!mSculptTexture->isCachedRawImageReady())
@@ -1006,7 +1006,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
 	
 	if (is404)
 	{
-		setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", TRUE, LLViewerTexture::BOOST_UI));
+		setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI));
 		//render prim proxy when mesh loading attempts give up
 		volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_NONE);
 
@@ -1090,7 +1090,7 @@ void LLVOVolume::updateSculptTexture()
 		LLUUID id =  sculpt_params->getSculptTexture();
 		if (id.notNull())
 		{
-			mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+			mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 		}
 	}
 	else
@@ -2743,7 +2743,7 @@ void LLVOVolume::updateSpotLightPriority()
 	if (mLightTexture.notNull())
 	{
 		mLightTexture->addTextureStats(mSpotLightPriority);
-		mLightTexture->setBoostLevel(LLViewerTexture::BOOST_CLOUDS);
+		mLightTexture->setBoostLevel(LLGLTexture::BOOST_CLOUDS);
 	}
 }
 
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 7f17fd3e5626efe95d9a38314b70cbe6ecdb3607..4e265871848befe736aa18b897751deeba71e994 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -724,8 +724,8 @@ void LLVOWLSky::updateStarColors()
 
 	const F32 var = 0.15f;
 	const F32 min = 0.5f; //0.75f;
-	const F32 sunclose_max = 0.6f;
-	const F32 sunclose_range = 1 - sunclose_max;
+	//const F32 sunclose_max = 0.6f;
+	//const F32 sunclose_range = 1 - sunclose_max;
 
 	//F32 below_horizon = - llmin(0.0f, gSky.mVOSkyp->getToSunLast().mV[2]);
 	//F32 brightness_factor = llmin(1.0f, below_horizon * 20);
@@ -739,14 +739,14 @@ void LLVOWLSky::updateStarColors()
 		U32 x;
 		for (x = 0; x < getStarsNumVerts(); ++x)
 		{
-			F32 sundir_factor = 1;
+			//F32 sundir_factor = 1;
 			LLVector3 tostar = *v_p;
 			tostar.normVec();
-			const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast();
-			if (how_close_to_sun > sunclose_max)
-			{
-				sundir_factor = (1 - how_close_to_sun) / sunclose_range;
-			}
+			//const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast();
+			//if (how_close_to_sun > sunclose_max)
+			//{
+			//	sundir_factor = (1 - how_close_to_sun) / sunclose_range;
+			//}
 			intensity = *(v_i);
 			F32 alpha = v_c->mV[VALPHA] + (ll_frand() - 0.5f) * var * intensity;
 			if (alpha < min * intensity)
diff --git a/indra/newview/llwaterparamset.cpp b/indra/newview/llwaterparamset.cpp
index 39d366b0238f00f99b087c13686188411d61d3ed..9cc91d2246ac2f3ee6021e5cb27e3c0840c24ef0 100644
--- a/indra/newview/llwaterparamset.cpp
+++ b/indra/newview/llwaterparamset.cpp
@@ -185,8 +185,6 @@ LLVector3 LLWaterParamSet::getVector3(const std::string& paramName, bool& error)
 LLVector2 LLWaterParamSet::getVector2(const std::string& paramName, bool& error) 
 {
 	// test to see if right type
-	int ttest;
-	ttest = mParamValues.size();
 	LLSD cur_val = mParamValues.get(paramName);
 	if (!cur_val.isArray() || cur_val.size() != 2) 
 	{
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
deleted file mode 100644
index 402504933cd9e3ea8e4e5fdb5ccb5da7f94cceeb..0000000000000000000000000000000000000000
--- a/indra/newview/llwearable.cpp
+++ /dev/null
@@ -1,1285 +0,0 @@
-/** 
- * @file llwearable.cpp
- * @brief LLWearable class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llagentwearables.h"
-#include "lldictionary.h"
-#include "llfloatersidepanelcontainer.h"
-#include "lllocaltextureobject.h"
-#include "llnotificationsutil.h"
-#include "llviewertexturelist.h"
-#include "llinventorymodel.h"
-#include "llinventoryobserver.h"
-#include "llsidepanelappearance.h"
-#include "lltexlayer.h"
-#include "lltexglobalcolor.h"
-#include "lltrans.h"
-#include "llviewerregion.h"
-#include "llvisualparam.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "llvoavatardefines.h"
-#include "llwearable.h"
-#include "llviewercontrol.h"
-
-using namespace LLVOAvatarDefines;
-
-// static
-S32 LLWearable::sCurrentDefinitionVersion = 1;
-
-// support class - remove for 2.1 (hackity hack hack)
-class LLOverrideBakedTextureUpdate
-{
-public:
-	LLOverrideBakedTextureUpdate(bool temp_state)
-	{
-		U32 num_bakes = (U32) LLVOAvatarDefines::BAKED_NUM_INDICES;
-		for( U32 index = 0; index < num_bakes; ++index )
-		{
-			composite_enabled[index] = gAgentAvatarp->isCompositeUpdateEnabled(index);
-		}
-		gAgentAvatarp->setCompositeUpdatesEnabled(temp_state);
-	}
-
-	~LLOverrideBakedTextureUpdate()
-	{
-		U32 num_bakes = (U32)LLVOAvatarDefines::BAKED_NUM_INDICES;		
-		for( U32 index = 0; index < num_bakes; ++index )
-		{
-			gAgentAvatarp->setCompositeUpdatesEnabled(index, composite_enabled[index]);
-		}
-	}
-private:
-	bool composite_enabled[LLVOAvatarDefines::BAKED_NUM_INDICES];
-};
-
-// Private local functions
-static std::string terse_F32_to_string(F32 f);
-static std::string asset_id_to_filename(const LLUUID &asset_id);
-
-LLWearable::LLWearable(const LLTransactionID& transaction_id) :
-	mDefinitionVersion(LLWearable::sCurrentDefinitionVersion),
-	mType(LLWearableType::WT_INVALID)
-{
-	mTransactionID = transaction_id;
-	mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
-}
-
-LLWearable::LLWearable(const LLAssetID& asset_id) :
-	mDefinitionVersion( LLWearable::sCurrentDefinitionVersion ),
-	mType(LLWearableType::WT_INVALID)
-{
-	mAssetID = asset_id;
-	mTransactionID.setNull();
-}
-
-LLWearable::~LLWearable()
-{
-}
-
-const std::string& LLWearable::getTypeLabel() const
-{
-	return LLWearableType::getTypeLabel(mType);
-}
-
-const std::string& LLWearable::getTypeName() const
-{
-	return LLWearableType::getTypeName(mType);
-}
-
-LLAssetType::EType LLWearable::getAssetType() const
-{
-	return LLWearableType::getAssetType(mType);
-}
-
-BOOL LLWearable::exportFile(LLFILE* file) const
-{
-	// header and version
-	if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 )
-	{
-		return FALSE;
-	}
-
-	// name
-	if( fprintf( file, "%s\n", mName.c_str() ) < 0 )
-	{
-		return FALSE;
-	}
-
-	// description
-	if( fprintf( file, "%s\n", mDescription.c_str() ) < 0 )
-	{
-		return FALSE;
-	}
-	
-	// permissions
-	if( !mPermissions.exportFile( file ) )
-	{
-		return FALSE;
-	}
-
-	// sale info
-	if( !mSaleInfo.exportFile( file ) )
-	{
-		return FALSE;
-	}
-
-	// wearable type
-	S32 type = (S32)mType;
-	if( fprintf( file, "type %d\n", type ) < 0 )
-	{
-		return FALSE;
-	}
-
-	// parameters
-	S32 num_parameters = mVisualParamIndexMap.size();
-	if( fprintf( file, "parameters %d\n", num_parameters ) < 0 )
-	{
-		return FALSE;
-	}
-
-	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
-		 iter != mVisualParamIndexMap.end(); 
-		 ++iter)
-	{
-		S32 param_id = iter->first;
-		const LLVisualParam* param = iter->second;
-		F32 param_weight = param->getWeight();
-		if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 )
-		{
-			return FALSE;
-		}
-	}
-
-	// texture entries
-	S32 num_textures = mTEMap.size();
-	if( fprintf( file, "textures %d\n", num_textures ) < 0 )
-	{
-		return FALSE;
-	}
-	
-	for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
-	{
-		S32 te = iter->first;
-		const LLUUID& image_id = iter->second->getID();
-		if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 )
-		{
-			return FALSE;
-		}
-	}
-	return TRUE;
-}
-
-
-void LLWearable::createVisualParams()
-{
-	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
-		 param;
-		 param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam())
-	{
-		if (param->getWearableType() == mType)
-		{
-			addVisualParam(param->cloneParam(this));
-		}
-	}
-
-	// resync driver parameters to point to the newly cloned driven parameters
-	for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin(); 
-		 param_iter != mVisualParamIndexMap.end(); 
-		 ++param_iter)
-	{
-		LLVisualParam* param = param_iter->second;
-		LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam; 
-		// need this line to disambiguate between versions of LLCharacter::getVisualParam()
-		LLVisualParam*(LLVOAvatarSelf::*avatar_function)(S32)const = &LLVOAvatarSelf::getVisualParam; 
-		param->resetDrivenParams();
-		if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false))
-		{
-			if( !param->linkDrivenParams(boost::bind(avatar_function,gAgentAvatarp.get(),_1 ), true))
-			{
-				llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl;
-				continue;
-			}
-		}
-	}
-}
-
-BOOL LLWearable::importFile( LLFILE* file )
-{
-	// *NOTE: changing the type or size of this buffer will require
-	// changes in the fscanf() code below. You would be better off
-	// rewriting this to use streams and not require an open FILE.
-	char text_buffer[2048];		/* Flawfinder: ignore */
-	S32 fields_read = 0;
-
-	// suppress texlayerset updates while wearables are being imported. Layersets will be updated
-	// when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.
-	LLOverrideBakedTextureUpdate stop_bakes(false);
-
-	// read header and version 
-	fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion );
-	if( fields_read != 1 )
-	{
-		// Shouldn't really log the asset id for security reasons, but
-		// we need it in this case.
-		llwarns << "Bad Wearable asset header: " << mAssetID << llendl;
-		//gVFS->dumpMap();
-		return FALSE;
-	}
-
-
-	// Temoprary hack to allow wearables with definition version 24 to still load.
-	// This should only affect lindens and NDA'd testers who have saved wearables in 2.0
-	// the extra check for version == 24 can be removed before release, once internal testers
-	// have loaded these wearables again. See hack pt 2 at bottom of function to ensure that
-	// these wearables get re-saved with version definition 22.
-	if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 )
-	{
-		llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
-		return FALSE;
-	}
-
-	// name
-	int next_char = fgetc( file );		/* Flawfinder: ignore */
-	if( '\n' == next_char )
-	{
-		// no name
-		mName = "";
-	}
-	else
-	{
-		ungetc( next_char, file );
-		fields_read = fscanf(	/* Flawfinder: ignore */
-			file,
-			"%2047[^\n]",
-			text_buffer);
-		if( (1 != fields_read) || (fgetc( file ) != '\n') )		/* Flawfinder: ignore */
-		{
-			llwarns << "Bad Wearable asset: early end of file" << llendl;
-			return FALSE;
-		}
-		mName = text_buffer;
-		LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );
-	}
-
-	// description
-	next_char = fgetc( file );		/* Flawfinder: ignore */
-	if( '\n' == next_char )
-	{
-		// no description
-		mDescription = "";
-	}
-	else
-	{
-		ungetc( next_char, file );
-		fields_read = fscanf(	/* Flawfinder: ignore */
-			file,
-			"%2047[^\n]",
-			text_buffer );
-		if( (1 != fields_read) || (fgetc( file ) != '\n') )		/* Flawfinder: ignore */
-		{
-			llwarns << "Bad Wearable asset: early end of file" << llendl;
-			return FALSE;
-		}
-		mDescription = text_buffer;
-		LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN );
-	}
-
-	// permissions
-	S32 perm_version;
-	fields_read = fscanf( file, " permissions %d\n", &perm_version );
-	if( (fields_read != 1) || (perm_version != 0) )
-	{
-		llwarns << "Bad Wearable asset: missing permissions" << llendl;
-		return FALSE;
-	}
-	if( !mPermissions.importFile( file ) )
-	{
-		return FALSE;
-	}
-
-	// sale info
-	S32 sale_info_version;
-	fields_read = fscanf( file, " sale_info %d\n", &sale_info_version );
-	if( (fields_read != 1) || (sale_info_version != 0) )
-	{
-		llwarns << "Bad Wearable asset: missing sale_info" << llendl;
-		return FALSE;
-	}
-	// Sale info used to contain next owner perm. It is now in the
-	// permissions. Thus, we read that out, and fix legacy
-	// objects. It's possible this op would fail, but it should pick
-	// up the vast majority of the tasks.
-	BOOL has_perm_mask = FALSE;
-	U32 perm_mask = 0;
-	if( !mSaleInfo.importFile(file, has_perm_mask, perm_mask) )
-	{
-		return FALSE;
-	}
-	if(has_perm_mask)
-	{
-		// fair use fix.
-		if(!(perm_mask & PERM_COPY))
-		{
-			perm_mask |= PERM_TRANSFER;
-		}
-		mPermissions.setMaskNext(perm_mask);
-	}
-
-	// wearable type
-	S32 type = -1;
-	fields_read = fscanf( file, "type %d\n", &type );
-	if( fields_read != 1 )
-	{
-		llwarns << "Bad Wearable asset: bad type" << llendl;
-		return FALSE;
-	}
-	if( 0 <= type && type < LLWearableType::WT_COUNT )
-	{
-		setType((LLWearableType::EType)type);
-	}
-	else
-	{
-		mType = LLWearableType::WT_COUNT;
-		llwarns << "Bad Wearable asset: bad type #" << type <<  llendl;
-		return FALSE;
-	}
-
-	// parameters header
-	S32 num_parameters = 0;
-	fields_read = fscanf( file, "parameters %d\n", &num_parameters );
-	if( fields_read != 1 )
-	{
-		llwarns << "Bad Wearable asset: missing parameters block" << llendl;
-		return FALSE;
-	}
-
-	if( num_parameters != mVisualParamIndexMap.size() )
-	{
-		llwarns << "Wearable parameter mismatch. Reading in " << num_parameters << " from file, but created " << mVisualParamIndexMap.size() << " from avatar parameters. type: " <<  mType << llendl;
-	}
-
-	// parameters
-	S32 i;
-	for( i = 0; i < num_parameters; i++ )
-	{
-		S32 param_id = 0;
-		F32 param_weight = 0.f;
-		fields_read = fscanf( file, "%d %f\n", &param_id, &param_weight );
-		if( fields_read != 2 )
-		{
-			llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
-			return FALSE;
-		}
-		mSavedVisualParamMap[param_id] = param_weight;
-	}
-
-	// textures header
-	S32 num_textures = 0;
-	fields_read = fscanf( file, "textures %d\n", &num_textures);
-	if( fields_read != 1 )
-	{
-		llwarns << "Bad Wearable asset: missing textures block" << llendl;
-		return FALSE;
-	}
-
-	// textures
-	for( i = 0; i < num_textures; i++ )
-	{
-		S32 te = 0;
-		fields_read = fscanf(	/* Flawfinder: ignore */
-			file,
-			"%d %2047s\n",
-			&te, text_buffer);
-		if( fields_read != 2 )
-		{
-			llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
-			return FALSE;
-		}
-
-		if( !LLUUID::validate( text_buffer ) )
-		{
-			llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl;
-			return FALSE;
-		}
-		LLUUID id = LLUUID(text_buffer);
-		LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( id );
-		if( mTEMap.find(te) != mTEMap.end() )
-		{
-			delete mTEMap[te];
-		}
-		if( mSavedTEMap.find(te) != mSavedTEMap.end() )
-		{
-			delete mSavedTEMap[te];
-		}
-
-		if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
-		{
-			image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(id, (LLVOAvatarDefines::ETextureIndex)te), NULL);
-		}
-		LLUUID textureid(text_buffer);
-		mTEMap[te] = new LLLocalTextureObject(image, textureid);
-		mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
-		createLayers(te);
-	}
-
-	// copy all saved param values to working params
-	revertValues();
-
-	return TRUE;
-}
-
-
-// Avatar parameter and texture definitions can change over time.
-// This function returns true if parameters or textures have been added or removed
-// since this wearable was created.
-BOOL LLWearable::isOldVersion() const
-{
-	if (!isAgentAvatarValid()) return FALSE;
-
-	if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion )
-	{
-		llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
-		llassert(0);
-	}
-
-	if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion )
-	{
-		return TRUE;
-	}
-
-	S32 param_count = 0;
-	for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
-		param;
-		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
-	{
-		if( (param->getWearableType() == mType) && (param->isTweakable() ) )
-		{
-			param_count++;
-			if( !is_in_map(mVisualParamIndexMap, param->getID() ) )
-			{
-				return TRUE;
-			}
-		}
-	}
-	if( param_count != mVisualParamIndexMap.size() )
-	{
-		return TRUE;
-	}
-
-
-	S32 te_count = 0;
-	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			te_count++;
-			if( !is_in_map(mTEMap, te ) )
-			{
-				return TRUE;
-			}
-		}
-	}
-	if( te_count != mTEMap.size() )
-	{
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-// Avatar parameter and texture definitions can change over time.
-// * If parameters or textures have been REMOVED since the wearable was created,
-// they're just ignored, so we consider the wearable clean even though isOldVersion()
-// will return true. 
-// * If parameters or textures have been ADDED since the wearable was created,
-// they are taken to have default values, so we consider the wearable clean
-// only if those values are the same as the defaults.
-BOOL LLWearable::isDirty() const
-{
-	if (!isAgentAvatarValid()) return FALSE;
-
-	for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
-		param;
-		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
-	{
-		if( (param->getWearableType() == mType) 
-			&& (param->isTweakable() ) 
-			&& !param->getCrossWearable())
-		{
-			F32 current_weight = getVisualParamWeight(param->getID());
-			current_weight = llclamp( current_weight, param->getMinWeight(), param->getMaxWeight() );
-			F32 saved_weight = get_if_there(mSavedVisualParamMap, param->getID(), param->getDefaultWeight());
-			saved_weight = llclamp( saved_weight, param->getMinWeight(), param->getMaxWeight() );
-			
-			U8 a = F32_to_U8( saved_weight, param->getMinWeight(), param->getMaxWeight() );
-			U8 b = F32_to_U8( current_weight, param->getMinWeight(), param->getMaxWeight() );
-			if( a != b  )
-			{
-				return TRUE;
-			}
-		}
-	}
-
-	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			te_map_t::const_iterator current_iter = mTEMap.find(te);
-			if(current_iter != mTEMap.end())
-			{
- 				const LLUUID& current_image_id = current_iter->second->getID();
-				te_map_t::const_iterator saved_iter = mSavedTEMap.find(te);
-				if(saved_iter != mSavedTEMap.end())
-				{
-					const LLUUID& saved_image_id = saved_iter->second->getID();
-					if (saved_image_id != current_image_id)
-					{
-						// saved vs current images are different, wearable is dirty
-						return TRUE;
-					}
-				}
-				else
-				{
-					// image found in current image list but not saved image list
-					return TRUE;
-				}
-			}
-		}
-	}
-
-	return FALSE;
-}
-
-
-void LLWearable::setParamsToDefaults()
-{
-	if (!isAgentAvatarValid()) return;
-
-	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
-	{
-		if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->isTweakable() ) )
-		{
-			setVisualParamWeight(param->getID(),param->getDefaultWeight(), FALSE);
-		}
-	}
-}
-
-void LLWearable::setTexturesToDefaults()
-{
-	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			LLUUID id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
-			LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id );
-			if( mTEMap.find(te) == mTEMap.end() )
-			{
-				mTEMap[te] = new LLLocalTextureObject(image, id);
-				createLayers(te);
-			}
-			else
-			{
-				// Local Texture Object already created, just set image and UUID
-				LLLocalTextureObject *lto = mTEMap[te];
-				lto->setID(id);
-				lto->setImage(image);
-			}
-		}
-	}
-}
-
-// Updates the user's avatar's appearance
-void LLWearable::writeToAvatar()
-{
-	if (!isAgentAvatarValid()) return;
-
-	ESex old_sex = gAgentAvatarp->getSex();
-
-	// Pull params
-	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
-	{
-		// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
-		// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
-		if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) )
-		{
-			S32 param_id = param->getID();
-			F32 weight = getVisualParamWeight(param_id);
-
-			gAgentAvatarp->setVisualParamWeight( param_id, weight, FALSE );
-		}
-	}
-
-	// Pull texture entries
-	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			te_map_t::const_iterator iter = mTEMap.find(te);
-			LLUUID image_id;
-			if(iter != mTEMap.end())
-			{
-				image_id = iter->second->getID();
-			}
-			else
-			{	
-				image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
-			}
-			LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE );
-			// MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this.
-			gAgentAvatarp->setLocalTextureTE(te, image, 0);
-		}
-	}
-
-	ESex new_sex = gAgentAvatarp->getSex();
-	if( old_sex != new_sex )
-	{
-		gAgentAvatarp->updateSexDependentLayerSets( FALSE );
-	}	
-	
-//	if( upload_bake )
-//	{
-//		gAgent.sendAgentSetAppearance();
-//	}
-}
-
-
-// Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values.
-// static 
-void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake )
-{
-	if (!isAgentAvatarValid()) return;
-
-	// You can't just remove body parts.
-	if( (type == LLWearableType::WT_SHAPE) ||
-		(type == LLWearableType::WT_SKIN) ||
-		(type == LLWearableType::WT_HAIR) ||
-		(type == LLWearableType::WT_EYES) )
-	{
-		return;
-	}
-
-	// Pull params
-	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
-	{
-		if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->isTweakable() ) )
-		{
-			S32 param_id = param->getID();
-			gAgentAvatarp->setVisualParamWeight( param_id, param->getDefaultWeight(), upload_bake );
-		}
-	}
-
-	if(gAgentCamera.cameraCustomizeAvatar())
-	{
-		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
-	}
-
-	gAgentAvatarp->updateVisualParams();
-	gAgentAvatarp->wearableUpdated(type, FALSE);
-
-//	if( upload_bake )
-//	{
-//		gAgent.sendAgentSetAppearance();
-//	}
-}
-
-// Does not copy mAssetID.
-// Definition version is current: removes obsolete enties and creates default values for new ones.
-void LLWearable::copyDataFrom(const LLWearable* src)
-{
-	if (!isAgentAvatarValid()) return;
-
-	mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
-
-	mName = src->mName;
-	mDescription = src->mDescription;
-	mPermissions = src->mPermissions;
-	mSaleInfo = src->mSaleInfo;
-
-	setType(src->mType);
-
-	mSavedVisualParamMap.clear();
-	// Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed)
-	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
-		param;
-		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
-	{
-		if( (param->getWearableType() == mType) )
-		{
-			S32 id = param->getID();
-			F32 weight = src->getVisualParamWeight(id);
-			mSavedVisualParamMap[id] = weight;
-		}
-	}
-
-	destroyTextures();
-	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
-	for (S32 te = 0; te < TEX_NUM_INDICES; te++)
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			te_map_t::const_iterator iter = src->mTEMap.find(te);
-			LLUUID image_id;
-			LLViewerFetchedTexture *image = NULL;
-			if(iter != src->mTEMap.end())
-			{
-				image = src->getLocalTextureObject(te)->getImage();
-				image_id = src->getLocalTextureObject(te)->getID();
-				mTEMap[te] = new LLLocalTextureObject(image, image_id);
-				mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
-				mTEMap[te]->setBakedReady(src->getLocalTextureObject(te)->getBakedReady());
-				mTEMap[te]->setDiscard(src->getLocalTextureObject(te)->getDiscard());
-			}
-			else
-			{
-				image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
-				image = LLViewerTextureManager::getFetchedTexture( image_id );
-				mTEMap[te] = new LLLocalTextureObject(image, image_id);
-				mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
-			}
-			createLayers(te);
-		}
-	}
-
-	// 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();
-}
-
-void LLWearable::setItemID(const LLUUID& item_id)
-{
-	mItemID = item_id;
-}
-
-const LLUUID& LLWearable::getItemID() const
-{
-	return mItemID;
-}
-
-void LLWearable::setType(LLWearableType::EType type) 
-{ 
-	mType = type; 
-	createVisualParams();
-}
-
-LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index)
-{
-	te_map_t::iterator iter = mTEMap.find(index);
-	if( iter != mTEMap.end() )
-	{
-		LLLocalTextureObject* lto = iter->second;
-		return lto;
-	}
-	return NULL;
-}
-
-const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const
-{
-	te_map_t::const_iterator iter = mTEMap.find(index);
-	if( iter != mTEMap.end() )
-	{
-		const LLLocalTextureObject* lto = iter->second;
-		return lto;
-	}
-	return NULL;
-}
-
-std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq()
-{
-	std::vector<LLLocalTextureObject*> result;
-
-	for(te_map_t::const_iterator iter = mTEMap.begin();
-		iter != mTEMap.end(); iter++)
-	{
-		LLLocalTextureObject* lto = iter->second;
-		result.push_back(lto);
-	}
-
-	return result;
-}
-
-void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
-{
-	if( mTEMap.find(index) != mTEMap.end() )
-	{
-		mTEMap.erase(index);
-	}
-	mTEMap[index] = new LLLocalTextureObject(lto);
-}
-
-
-void LLWearable::addVisualParam(LLVisualParam *param)
-{
-	if( mVisualParamIndexMap[param->getID()] )
-	{
-		delete mVisualParamIndexMap[param->getID()];
-	}
-	param->setIsDummy(FALSE);
-	mVisualParamIndexMap[param->getID()] = param;
-	mSavedVisualParamMap[param->getID()] = param->getDefaultWeight();
-}
-
-void LLWearable::setVisualParams()
-{
-	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		LLVisualParam *wearable_param = iter->second;
-		F32 value = wearable_param->getWeight();
-		gAgentAvatarp->setVisualParamWeight(id, value, FALSE);
-	}
-}
-
-
-void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake)
-{
-	if( is_in_map(mVisualParamIndexMap, param_index ) )
-	{
-		LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
-		wearable_param->setWeight(value, upload_bake);
-	}
-	else
-	{
-		llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
-	}
-}
-
-F32 LLWearable::getVisualParamWeight(S32 param_index) const
-{
-	if( is_in_map(mVisualParamIndexMap, param_index ) )
-	{
-		const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second;
-		return wearable_param->getWeight();
-	}
-	else
-	{
-		llwarns << "LLWerable::getVisualParam passed invalid parameter index: "  << param_index << " for wearable type: " << this->getName() << llendl;
-	}
-	return (F32)-1.0;
-}
-
-LLVisualParam* LLWearable::getVisualParam(S32 index) const
-{
-	visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index);
-	return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second;
-}
-
-
-void LLWearable::getVisualParams(visual_param_vec_t &list)
-{
-	visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
-	visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
-
-	// add all visual params to the passed-in vector
-	for( ; iter != end; ++iter )
-	{
-		list.push_back(iter->second);
-	}
-}
-
-void LLWearable::animateParams(F32 delta, BOOL upload_bake)
-{
-	for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
-		 iter != mVisualParamIndexMap.end();
-		 ++iter)
-	{
-		LLVisualParam *param = (LLVisualParam*) iter->second;
-		param->animate(delta, upload_bake);
-	}
-}
-
-LLColor4 LLWearable::getClothesColor(S32 te) const
-{
-	LLColor4 color;
-	U32 param_name[3];
-	if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) )
-	{
-		for( U8 index = 0; index < 3; index++ )
-		{
-			color.mV[index] = getVisualParamWeight(param_name[index]);
-		}
-	}
-	return color;
-}
-
-void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake )
-{
-	U32 param_name[3];
-	if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) )
-	{
-		for( U8 index = 0; index < 3; index++ )
-		{
-			setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake);
-		}
-	}
-}
-
-void LLWearable::revertValues()
-{
-	//update saved settings so wearable is no longer dirty
-	// non-driver params first
-	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		F32 value = iter->second;
-		LLVisualParam *param = getVisualParam(id);
-		if(param &&  !dynamic_cast<LLDriverParam*>(param) )
-		{
-			setVisualParamWeight(id, value, TRUE);
-		}
-	}
-
-	//then driver params
-	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		F32 value = iter->second;
-		LLVisualParam *param = getVisualParam(id);
-		if(param &&  dynamic_cast<LLDriverParam*>(param) )
-		{
-			setVisualParamWeight(id, value, TRUE);
-		}
-	}
-
-	// make sure that saved values are sane
-	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		LLVisualParam *param = getVisualParam(id);
-		if( param )
-		{
-			mSavedVisualParamMap[id] = param->getWeight();
-		}
-	}
-
-	syncImages(mSavedTEMap, mTEMap);
-
-
-	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
-	if( panel )
-	{
-		panel->updateScrollingPanelList();
-	}
-}
-
-BOOL LLWearable::isOnTop() const
-{ 
-	return (this == gAgentWearables.getTopWearable(mType));
-}
-
-void LLWearable::createLayers(S32 te)
-{
-	LLTexLayerSet *layer_set = gAgentAvatarp->getLayerSet((ETextureIndex)te);
-	if (layer_set)
-	{
-		layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
-	}
-	else
-	{
-		llerrs << "could not find layerset for LTO in wearable!" << llendl;
-	}
-}
-
-void LLWearable::saveValues()
-{
-	//update saved settings so wearable is no longer dirty
-	mSavedVisualParamMap.clear();
-	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
-	{
-		S32 id = iter->first;
-		LLVisualParam *wearable_param = iter->second;
-		F32 value = wearable_param->getWeight();
-		mSavedVisualParamMap[id] = value;
-	}
-
-	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
-	syncImages(mTEMap, mSavedTEMap);
-
-
-	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
-	if( panel )
-	{
-		panel->updateScrollingPanelList();
-	}
-}
-
-void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
-{
-	// Deep copy of src (copies only those tes that are current, filling in defaults where needed)
-	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			te_map_t::const_iterator iter = src.find(te);
-			LLUUID image_id;
-			LLViewerFetchedTexture *image = NULL;
-			LLLocalTextureObject *lto = NULL;
-			if(iter != src.end())
-			{
-				// there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map.
-				lto = iter->second;
-				image = lto->getImage();
-				image_id = lto->getID();
-			}
-			else
-			{
-				// there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map.
-				image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
-				image = LLViewerTextureManager::getFetchedTexture( image_id );
-			}
-
-			if( dst.find(te) != dst.end() )
-			{
-				// there's already an entry in the destination map for the texture. Just update its values.
-				dst[te]->setImage(image);
-				dst[te]->setID(image_id);
-			}
-			else
-			{
-				// no entry found in the destination map, we need to create a new Local Texture Object
-				dst[te] = new LLLocalTextureObject(image, image_id);
-			}
-
-			if( lto )
-			{
-				// If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map.
-				dst[te]->setBakedReady(lto->getBakedReady());
-				dst[te]->setDiscard(lto->getDiscard());
-			}
-		}
-	}
-}
-
-void LLWearable::destroyTextures()
-{
-	for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
-	{
-		LLLocalTextureObject *lto = iter->second;
-		delete lto;
-	}
-	mTEMap.clear();
-	for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
-	{
-		LLLocalTextureObject *lto = iter->second;
-		delete lto;
-	}
-	mSavedTEMap.clear();
-}
-
-void LLWearable::pullCrossWearableValues()
-{
-	// scan through all of the avatar's visual parameters
-	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
-		 param;
-		 param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam())
-	{
-		if( param )
-		{
-			LLDriverParam *driver_param = dynamic_cast<LLDriverParam*>(param);
-			if(driver_param)
-			{
-				// parameter is a driver parameter, have it update its 
-				driver_param->updateCrossDrivenParams(getType());
-			}
-		}
-	}
-}
-
-
-void LLWearable::setLabelUpdated() const
-{ 
-	gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID());
-}
-
-void LLWearable::refreshName()
-{
-	LLUUID item_id = getItemID();
-	LLInventoryItem* item = gInventory.getItem(item_id);
-	if( item )
-	{
-		mName = item->getName();
-	}
-}
-
-struct LLWearableSaveData
-{
-	LLWearableType::EType mType;
-};
-
-void LLWearable::saveNewAsset() const
-{
-//	llinfos << "LLWearable::saveNewAsset() type: " << getTypeName() << llendl;
-	//llinfos << *this << llendl;
-
-	const std::string filename = asset_id_to_filename(mAssetID);
-	LLFILE* fp = LLFile::fopen(filename, "wb");		/* Flawfinder: ignore */
-	BOOL successful_save = FALSE;
-	if(fp && exportFile(fp))
-	{
-		successful_save = TRUE;
-	}
-	if(fp)
-	{
-		fclose(fp);
-		fp = NULL;
-	}
-	if(!successful_save)
-	{
-		std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str());
-		llwarns << buffer << llendl;
-		
-		LLSD args;
-		args["NAME"] = mName;
-		LLNotificationsUtil::add("CannotSaveWearableOutOfSpace", args);
-		return;
-	}
-
-	// save it out to database
-	if( gAssetStorage )
-	{
-		 /*
-		std::string url = gAgent.getRegion()->getCapability("NewAgentInventory");
-		if (!url.empty())
-		{
-			llinfos << "Update Agent Inventory via capability" << llendl;
-			LLSD body;
-			body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::assetToFolderType(getAssetType()));
-			body["asset_type"] = LLAssetType::lookup(getAssetType());
-			body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE);
-			body["name"] = getName();
-			body["description"] = getDescription();
-			LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename));
-		}
-		else
-		{
-		}
-		 */
-		 LLWearableSaveData* data = new LLWearableSaveData;
-		 data->mType = mType;
-		 gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(),
-                                     &LLWearable::onSaveNewAssetComplete,
-                                     (void*)data);
-	}
-}
-
-// static
-void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
-{
-	LLWearableSaveData* data = (LLWearableSaveData*)userdata;
-	const std::string& type_name = LLWearableType::getTypeName(data->mType);
-	if(0 == status)
-	{
-		// Success
-		llinfos << "Saved wearable " << type_name << llendl;
-	}
-	else
-	{
-		std::string buffer = llformat("Unable to save %s to central asset store.", type_name.c_str());
-		llwarns << buffer << " Status: " << status << llendl;
-		LLSD args;
-		args["NAME"] = type_name;
-		LLNotificationsUtil::add("CannotSaveToAssetStore", args);
-	}
-
-	// Delete temp file
-	const std::string src_filename = asset_id_to_filename(new_asset_id);
-	LLFile::remove(src_filename);
-
-	// delete the context data
-	delete data;
-
-}
-
-std::ostream& operator<<(std::ostream &s, const LLWearable &w)
-{
-	s << "wearable " << LLWearableType::getTypeName(w.mType) << "\n";
-	s << "    Name: " << w.mName << "\n";
-	s << "    Desc: " << w.mDescription << "\n";
-	//w.mPermissions
-	//w.mSaleInfo
-
-	s << "    Params:" << "\n";
-	for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin();
-		 iter != w.mVisualParamIndexMap.end(); ++iter)
-	{
-		S32 param_id = iter->first;
-		LLVisualParam *wearable_param = iter->second;
-		F32 param_weight = wearable_param->getWeight();
-		s << "        " << param_id << " " << param_weight << "\n";
-	}
-
-	s << "    Textures:" << "\n";
-	for (LLWearable::te_map_t::const_iterator iter = w.mTEMap.begin();
-		 iter != w.mTEMap.end(); ++iter)
-	{
-		S32 te = iter->first;
-		const LLUUID& image_id = iter->second->getID();
-		s << "        " << te << " " << image_id << "\n";
-	}
-	return s;
-}
-
-
-std::string terse_F32_to_string(F32 f)
-{
-	std::string r = llformat("%.2f", f);
-	S32 len = r.length();
-
-    // "1.20"  -> "1.2"
-    // "24.00" -> "24."
-	while (len > 0 && ('0' == r[len - 1]))
-	{
-		r.erase(len-1, 1);
-		len--;
-	}
-	if ('.' == r[len - 1])
-	{
-		// "24." -> "24"
-		r.erase(len-1, 1);
-	}
-	else if (('-' == r[0]) && ('0' == r[1]))
-	{
-		// "-0.59" -> "-.59"
-		r.erase(1, 1);
-	}
-	else if ('0' == r[0])
-	{
-		// "0.59" -> ".59"
-		r.erase(0, 1);
-	}
-	return r;
-}
-
-std::string asset_id_to_filename(const LLUUID &asset_id)
-{
-	std::string asset_id_string;
-	asset_id.toString(asset_id_string);
-	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl";	
-	return filename;
-}
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 92697fb2eb8334b4023801342cb168dd25d6b103..c196d70617d7d69aade31e05ea392cd6b3afbc3b 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -34,6 +34,7 @@
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "lltransutil.h"
 #include "llviewerattachmenu.h"
 #include "llvoavatarself.h"
@@ -788,23 +789,24 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
 	const uuid_vec_t& ids = mUUIDs;		// selected items IDs
 	LLUUID selected_id = ids.front();	// ID of the first selected item
 
-	functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
-
 	// Register handlers common for all wearable types.
 	registrar.add("Wearable.Wear", boost::bind(wear_multiple, ids, true));
 	registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, false));
 	registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids));
 	registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));
 	registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id));
-	registrar.add("Wearable.TakeOffDetach", boost::bind(handleMultiple, take_off, ids));
+	registrar.add("Wearable.TakeOffDetach", 
+				  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
 
 	// Register handlers for clothing.
-	registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, ids));
+	registrar.add("Clothing.TakeOff", 
+				  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
 
 	// Register handlers for body parts.
 
 	// Register handlers for attachments.
-	registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, ids));
+	registrar.add("Attachment.Detach", 
+				  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
 	registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id));
 	registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2));
 
diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp
index 6f6411ce3cc5337a841b7ba573cef9da803ae76d..ef1a953f59d5c2d7ec47115dd50edc17fd57e8a0 100644
--- a/indra/newview/llwearablelist.cpp
+++ b/indra/newview/llwearablelist.cpp
@@ -42,20 +42,23 @@ struct LLWearableArrivedData
 {
 	LLWearableArrivedData(LLAssetType::EType asset_type,
 		const std::string& wearable_name,
-		void(*asset_arrived_callback)(LLWearable*, void* userdata),
+		LLAvatarAppearance* avatarp,
+		void(*asset_arrived_callback)(LLViewerWearable*, void* userdata),
 						  void* userdata) :
 		mAssetType( asset_type ),
 		mCallback( asset_arrived_callback ), 
 		mUserdata( userdata ),
 		mName( wearable_name ),
-		mRetries(0)
+		mRetries(0),
+		mAvatarp(avatarp)
 		{}
 
 	LLAssetType::EType mAssetType;
-	void	(*mCallback)(LLWearable*, void* userdata);
+	void	(*mCallback)(LLViewerWearable*, void* userdata);
 	void*	mUserdata;
 	std::string mName;
 	S32	mRetries;
+	LLAvatarAppearance *mAvatarp;
 };
 
 ////////////////////////////////////////////////////////////////////////////
@@ -72,10 +75,10 @@ void LLWearableList::cleanup()
 	mList.clear();
 }
 
-void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLWearable*, void* userdata), void* userdata)
+void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAvatarAppearance* avatarp, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLViewerWearable*, void* userdata), void* userdata)
 {
 	llassert( (asset_type == LLAssetType::AT_CLOTHING) || (asset_type == LLAssetType::AT_BODYPART) );
-	LLWearable* instance = get_if_there(mList, assetID, (LLWearable*)NULL );
+	LLViewerWearable* instance = get_if_there(mList, assetID, (LLViewerWearable*)NULL );
 	if( instance )
 	{
 		asset_arrived_callback( instance, userdata );
@@ -85,7 +88,7 @@ void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& weara
 		gAssetStorage->getAssetData(assetID,
 			asset_type,
 			LLWearableList::processGetAssetReply,
-			(void*)new LLWearableArrivedData( asset_type, wearable_name, asset_arrived_callback, userdata ),
+			(void*)new LLWearableArrivedData( asset_type, wearable_name, avatarp, asset_arrived_callback, userdata ),
 			TRUE);
 	}
 }
@@ -95,25 +98,31 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 {
 	BOOL isNewWearable = FALSE;
 	LLWearableArrivedData* data = (LLWearableArrivedData*) userdata;
-	LLWearable* wearable = NULL; // NULL indicates failure
+	LLViewerWearable* wearable = NULL; // NULL indicates failure
+	LLAvatarAppearance *avatarp = data->mAvatarp;
 	
 	if( !filename )
 	{
 		LL_WARNS("Wearable") << "Bad Wearable Asset: missing file." << LL_ENDL;
 	}
+	else if(!avatarp)
+	{
+		LL_WARNS("Wearable") << "Bad asset request: missing avatar pointer." << LL_ENDL;
+	}
 	else if (status >= 0)
 	{
 		// read the file
-		LLFILE* fp = LLFile::fopen(std::string(filename), "rb");		/*Flawfinder: ignore*/
-		if( !fp )
+		llifstream ifs(filename, llifstream::binary);
+		if( !ifs.is_open() )
 		{
 			LL_WARNS("Wearable") << "Bad Wearable Asset: unable to open file: '" << filename << "'" << LL_ENDL;
 		}
 		else
 		{
-			wearable = new LLWearable(uuid);
-			bool res = wearable->importFile( fp );
-			if (!res)
+			wearable = new LLViewerWearable(uuid);
+			LLWearable::EImportResult result = wearable->importStream(
+												ifs, avatarp );
+			if (LLWearable::SUCCESS != result)
 			{
 				if (wearable->getType() == LLWearableType::WT_COUNT)
 				{
@@ -123,9 +132,12 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 				wearable = NULL;
 			}
 
-			fclose( fp );
 			if(filename)
 			{
+				if (ifs.is_open())
+				{
+					ifs.close();
+				}
 				LLFile::remove(std::string(filename));
 			}
 		}
@@ -203,11 +215,11 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 }
 
 
-LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std::string& new_name)
+LLViewerWearable* LLWearableList::createCopy(const LLViewerWearable* old_wearable, const std::string& new_name)
 {
 	lldebugs << "LLWearableList::createCopy()" << llendl;
 
-	LLWearable *wearable = generateNewWearable();
+	LLViewerWearable *wearable = generateNewWearable();
 	wearable->copyDataFrom(old_wearable);
 
 	LLPermissions perm(old_wearable->getPermissions());
@@ -222,12 +234,12 @@ LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std
 	return wearable;
 }
 
-LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
+LLViewerWearable* LLWearableList::createNewWearable( LLWearableType::EType type, LLAvatarAppearance *avatarp )
 {
 	lldebugs << "LLWearableList::createNewWearable()" << llendl;
 
-	LLWearable *wearable = generateNewWearable();
-	wearable->setType( type );
+	LLViewerWearable *wearable = generateNewWearable();
+	wearable->setType( type, avatarp );
 	
 	std::string name = LLTrans::getString( LLWearableType::getTypeDefaultNewName(wearable->getType()) );
 	wearable->setName( name );
@@ -237,6 +249,8 @@ LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
 	perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER);
 	wearable->setPermissions(perm);
 
+	wearable->setDefinitionVersion(LLWearable::getCurrentDefinitionVersion());
+
 	// Description and sale info have default values.
 	wearable->setParamsToDefaults();
 	wearable->setTexturesToDefaults();
@@ -251,13 +265,13 @@ LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
 	return wearable;
 }
 
-LLWearable *LLWearableList::generateNewWearable()
+LLViewerWearable *LLWearableList::generateNewWearable()
 {
 	LLTransactionID tid;
 	tid.generate();
 	LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
 
-	LLWearable* wearable = new LLWearable(tid);
+	LLViewerWearable* wearable = new LLViewerWearable(tid);
 	mList[new_asset_id] = wearable;
 	return wearable;
 }
diff --git a/indra/newview/llwearablelist.h b/indra/newview/llwearablelist.h
index 12d0037aee443c6969818a24f752307690ce9119..d6f0fd09a6d5c0376c78ad8ff2327e3c06c9e747 100644
--- a/indra/newview/llwearablelist.h
+++ b/indra/newview/llwearablelist.h
@@ -28,7 +28,7 @@
 #define LL_LLWEARABLELIST_H
 
 #include "llmemory.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
 #include "lluuid.h"
 #include "llassetstorage.h"
 
@@ -50,20 +50,21 @@ class LLWearableList : public LLSingleton<LLWearableList>
 
 	void				getAsset(const LLAssetID& assetID,
 								 const std::string& wearable_name,
+								 LLAvatarAppearance *avatarp,
 								 LLAssetType::EType asset_type,
-								 void(*asset_arrived_callback)(LLWearable*, void* userdata),
+								 void(*asset_arrived_callback)(LLViewerWearable*, void* userdata),
 								 void* userdata);
 
-	LLWearable*			createCopy(const LLWearable* old_wearable, const std::string& new_name = std::string());
-	LLWearable*			createNewWearable(LLWearableType::EType type);
+	LLViewerWearable*			createCopy(const LLViewerWearable* old_wearable, const std::string& new_name = std::string());
+	LLViewerWearable*			createNewWearable(LLWearableType::EType type, LLAvatarAppearance *avatarp);
 	
 	// Callback
 	static void	 	    processGetAssetReply(const char* filename, const LLAssetID& assetID, void* user_data, S32 status, LLExtStat ext_status);
 
 protected:
-	LLWearable* generateNewWearable(); // used for the create... functions
+	LLViewerWearable* generateNewWearable(); // used for the create... functions
 private:
-	std::map<LLUUID, LLWearable*> mList;
+	std::map<LLUUID, LLViewerWearable*> mList;
 };
 
 #endif  // LL_LLWEARABLELIST_H
diff --git a/indra/newview/llwebsharing.cpp b/indra/newview/llwebsharing.cpp
index 43b1a320c34b2d3b2f4751e50b39aa49e029aa06..3a80051b9b7896a06ac604ae025d3d5750b23db3 100644
--- a/indra/newview/llwebsharing.cpp
+++ b/indra/newview/llwebsharing.cpp
@@ -68,9 +68,9 @@ class LLWebSharingConfigResponder : public LLHTTPClient::Responder
 		}
 	}
 
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
 	}
 
 	virtual void result(const LLSD& content)
@@ -99,7 +99,7 @@ class LLWebSharingOpenIDAuthResponder : public LLHTTPClient::Responder
 		/// Left empty to override the default LLSD parsing behaviour.
 	}
 
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
 		if (HTTP_UNAUTHORIZED == status)
 		{
@@ -108,7 +108,7 @@ class LLWebSharingOpenIDAuthResponder : public LLHTTPClient::Responder
 		}
 		else
 		{
-			LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+			LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
 			LLWebSharing::instance().retryOpenIDAuth();
 		}
 
@@ -152,9 +152,9 @@ class LLWebSharingSecurityTokenResponder : public LLHTTPClient::Responder
 		}
 	}
 
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
 		LLWebSharing::instance().retryOpenIDAuth();
 	}
 
@@ -221,9 +221,9 @@ class LLWebSharingUploadResponder : public LLHTTPClient::Responder
 		}
 	}
 
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
 	}
 
 	virtual void result(const LLSD& content)
diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp
index be3e3ff30e0cb6c4ba8c260d72c82f571ebfb05e..93eba5b6048aeddcf4552df38f76c295fee5eef0 100644
--- a/indra/newview/llwlhandlers.cpp
+++ b/indra/newview/llwlhandlers.cpp
@@ -121,9 +121,11 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder()
 
 	LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content);
 }
-/*virtual*/ void LLEnvironmentRequestResponder::error(U32 status, const std::string& reason)
+/*virtual*/
+void LLEnvironmentRequestResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	LL_INFOS("WindlightCaps") << "Got an error, not using region windlight..." << LL_ENDL;
+	LL_INFOS("WindlightCaps") << "Got an error, not using region windlight... [status:" 
+		<< status << "]: " << content << LL_ENDL;
 	LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
 }
 
@@ -190,14 +192,15 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)
 		LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
 	}
 }
-/*virtual*/ void LLEnvironmentApplyResponder::error(U32 status, const std::string& reason)
+/*virtual*/
+void LLEnvironmentApplyResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	std::stringstream msg;
-	msg << reason << " (Code " << status << ")";
-
-	LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region!  Reason: " << msg << LL_ENDL;
+	LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region!  [status:"
+		<< status << "]: " << content << LL_ENDL;
 
 	LLSD args(LLSD::emptyMap());
+	std::stringstream msg;
+	msg << reason << " (Code " << status << ")";
 	args["FAIL_REASON"] = msg.str();
 	LLNotificationsUtil::add("WLRegionApplyFail", args);
 }
diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h
index 23558876da73678891775d1ff033be897778007b..598ce6d52ac52c6c54989ce6d5498237564b92b5 100644
--- a/indra/newview/llwlhandlers.h
+++ b/indra/newview/llwlhandlers.h
@@ -47,7 +47,7 @@ class LLEnvironmentRequestResponder: public LLHTTPClient::Responder
 	LOG_CLASS(LLEnvironmentRequestResponder);
 public:
 	virtual void result(const LLSD& content);
-	virtual void error(U32 status, const std::string& reason);
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 
 private:
 	friend class LLEnvironmentRequest;
@@ -89,7 +89,8 @@ class LLEnvironmentApplyResponder: public LLHTTPClient::Responder
 	 */
 	virtual void result(const LLSD& content);
 
-	virtual void error(U32 status, const std::string& reason); // non-200 errors only
+	// non-200 errors only
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 
 private:
 	friend class LLEnvironmentApply;
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 350ba39b45cdcde3173b2803318982872ae0d33b..5fa380e0e3a920e8ef6a726a4d5b196e089c38d0 100644
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -34,6 +34,7 @@
 #include "lluistring.h"
 #include "llviewertexturelist.h"
 #include "lltrans.h"
+#include "llgltexture.h"
 
 // Timers to temporise database requests
 const F32 AGENTS_UPDATE_TIMER = 60.0;			// Seconds between 2 agent requests for a region
@@ -78,7 +79,7 @@ void LLSimInfo::setLandForSaleImage (LLUUID image_id)
 	// Fetch the image
 	if (mMapImageID.notNull())
 	{
-		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
+		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
 		mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP);
 	}
 	else
@@ -92,13 +93,13 @@ LLPointer<LLViewerFetchedTexture> LLSimInfo::getLandForSaleImage ()
 	if (mOverlayImage.isNull() && mMapImageID.notNull())
 	{
 		// Fetch the image if it hasn't been done yet (unlikely but...)
-		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
+		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
 		mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP);
 	}
 	if (!mOverlayImage.isNull())
 	{
 		// Boost the fetch level when we try to access that image
-		mOverlayImage->setBoostLevel(LLViewerTexture::BOOST_MAP);
+		mOverlayImage->setBoostLevel(LLGLTexture::BOOST_MAP);
 	}
 	return mOverlayImage;
 }
diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h
index 73530b96940456c618d6769ab866012f89b2d68c..d514b2f14c3eafd5c6291a59f68536f27cac3a52 100644
--- a/indra/newview/llworldmap.h
+++ b/indra/newview/llworldmap.h
@@ -36,6 +36,7 @@
 #include "llsingleton.h"
 #include "llviewerregion.h"
 #include "llviewertexture.h"
+#include "llgltexture.h"
 
 // Description of objects like hubs, events, land for sale, people and more (TBD).
 // Note: we don't store a "type" in there so we need to store instances of this class in 
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 11b2770ec007e4382513da4ffb89363a61e246b6..1940cf541ece1e631284083c6b2f8c8d209ed657 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -421,7 +421,7 @@ void LLWorldMapView::draw()
 			{
 				// Inform the fetch mechanism of the size we need
 				S32 draw_size = llround(sMapScale);
-				overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY]));
+				overlayimage->setKnownDrawSize(llround(draw_size * LLUI::getScaleFactor().mV[VX]), llround(draw_size * LLUI::getScaleFactor().mV[VY]));
 				// Draw something whenever we have enough info
 				if (overlayimage->hasGLTexture())
 				{
@@ -1317,7 +1317,7 @@ void LLWorldMapView::drawTrackingCircle( const LLRect& rect, S32 x, S32 y, const
 
 	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
-	gGL.translatef((F32)x * LLUI::sGLScaleFactor.mV[VX], (F32)y * LLUI::sGLScaleFactor.mV[VY], 0.f);
+	gGL.translatef((F32)x * LLUI::getScaleFactor().mV[VX], (F32)y * LLUI::getScaleFactor().mV[VY], 0.f);
 	gl_washer_segment_2d(inner_radius, outer_radius, start_theta, end_theta, 40, color, color);
 	gGL.popMatrix();
 
diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp
index 74ed844376e2fb58e2382ae82cfa1fddb38d15a8..895ccaef5a1fafe98d02b6bf21af16b8fc3e4ed3 100644
--- a/indra/newview/llworldmipmap.cpp
+++ b/indra/newview/llworldmipmap.cpp
@@ -74,21 +74,21 @@ void LLWorldMipmap::equalizeBoostLevels()
 		{
 			LLPointer<LLViewerFetchedTexture> img = iter->second;
 			S32 current_boost_level = img->getBoostLevel();
-			if (current_boost_level == LLViewerTexture::BOOST_MAP_VISIBLE)
+			if (current_boost_level == LLGLTexture::BOOST_MAP_VISIBLE)
 			{
 				// If level was BOOST_MAP_VISIBLE, the tile has been used in the last draw so keep it high
-				img->setBoostLevel(LLViewerTexture::BOOST_MAP);
+				img->setBoostLevel(LLGLTexture::BOOST_MAP);
 			}
 			else
 			{
 				// If level was BOOST_MAP only (or anything else...), the tile wasn't used in the last draw 
 				// so we drop its boost level to BOOST_NONE.
-				img->setBoostLevel(LLViewerTexture::BOOST_NONE);
+				img->setBoostLevel(LLGLTexture::BOOST_NONE);
 			}
 #if DEBUG_TILES_STAT
 			// Increment some stats if compile option on
 			nb_tiles++;
-			if (current_boost_level == LLViewerTexture::BOOST_MAP_VISIBLE)
+			if (current_boost_level == LLGLTexture::BOOST_MAP_VISIBLE)
 			{
 				nb_visible++;
 			}
@@ -115,7 +115,7 @@ void LLWorldMipmap::dropBoostLevels()
 		for (sublevel_tiles_t::iterator iter = level_mipmap.begin(); iter != level_mipmap.end(); iter++)
 		{
 			LLPointer<LLViewerFetchedTexture> img = iter->second;
-			img->setBoostLevel(LLViewerTexture::BOOST_NONE);
+			img->setBoostLevel(LLGLTexture::BOOST_NONE);
 		}
 	}
 }
@@ -172,7 +172,7 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32
 		// Boost the tile level so to mark it's in use *if* load on
 		if (load)
 		{
-			img->setBoostLevel(LLViewerTexture::BOOST_MAP_VISIBLE);
+			img->setBoostLevel(LLGLTexture::BOOST_MAP_VISIBLE);
 		}
 		return img;
 	}
@@ -189,8 +189,8 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32
 	// END DEBUG
 	//LL_INFOS("World Map") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL;
 
-	LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-	img->setBoostLevel(LLViewerTexture::BOOST_MAP);
+	LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	img->setBoostLevel(LLGLTexture::BOOST_MAP);
 
 	// Return the smart pointer
 	return img;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 9f0e2906d0cb257711c18db523087a028296cc0a..f320f34f6eadb364399c931c9692573111c29f55 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -71,6 +71,7 @@
 #include "llhudtext.h"
 #include "lllightconstants.h"
 #include "llmeshrepository.h"
+#include "llpipelinelistener.h"
 #include "llresmgr.h"
 #include "llselectmgr.h"
 #include "llsky.h"
@@ -377,6 +378,8 @@ BOOL    LLPipeline::sMemAllocationThrottled = FALSE;
 S32		LLPipeline::sVisibleLightCount = 0;
 F32		LLPipeline::sMinRenderSize = 0.f;
 
+// EventHost API LLPipeline listener.
+static LLPipelineListener sPipelineListener;
 
 static LLCullResult* sCull = NULL;
 
@@ -491,19 +494,29 @@ void LLPipeline::init()
 	LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
 	resetFrameStats();
 
-	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+	if (gSavedSettings.getBOOL("DisableAllRenderFeatures"))
 	{
-		mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled
+		clearAllRenderDebugFeatures();
 	}
+	else
+	{
+		setAllRenderDebugFeatures(); // By default, all debugging features on
+	}
+	clearAllRenderDebugDisplays(); // All debug displays off
 
-	mRenderDebugFeatureMask = 0xffffffff; // All debugging features on
-	mRenderDebugMask = 0;	// All debug starts off
-
-	// Don't turn on ground when this is set
-	// Mac Books with intel 950s need this
-	if(!gSavedSettings.getBOOL("RenderGround"))
+	if (gSavedSettings.getBOOL("DisableAllRenderTypes"))
+	{
+		clearAllRenderTypes();
+	}
+	else
 	{
-		toggleRenderType(RENDER_TYPE_GROUND);
+		setAllRenderTypes(); // By default, all rendering types start enabled
+		// Don't turn on ground when this is set
+		// Mac Books with intel 950s need this
+		if(!gSavedSettings.getBOOL("RenderGround"))
+		{
+			toggleRenderType(RENDER_TYPE_GROUND);
+		}
 	}
 
 	// make sure RenderPerformanceTest persists (hackity hack hack)
@@ -5917,7 +5930,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 			if (light->isLightSpotlight() // directional (spot-)light
 			    && (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on
 			{
-				LLVector3 spotparams = light->getSpotLightParams();
 				LLQuaternion quat = light->getRenderRotation();
 				LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction
 				at_axis *= quat;
@@ -6448,6 +6460,22 @@ void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value)
 	}
 }
 
+void LLPipeline::pushRenderDebugFeatureMask()
+{
+	mRenderDebugFeatureStack.push(mRenderDebugFeatureMask);
+}
+
+void LLPipeline::popRenderDebugFeatureMask()
+{
+	if (mRenderDebugFeatureStack.empty())
+	{
+		llerrs << "Depleted render feature stack." << llendl;
+	}
+
+	mRenderDebugFeatureMask = mRenderDebugFeatureStack.top();
+	mRenderDebugFeatureStack.pop();
+}
+
 // static
 void LLPipeline::setRenderScriptedBeacons(BOOL val)
 {
@@ -9081,9 +9109,6 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
 		3,7	
 	};
 
-	LLVector3 center = (max+min)*0.5f;
-	LLVector3 size = (max-min)*0.5f;
-	
 	for (U32 i = 0; i < 12; i++)
 	{
 		for (U32 j = 0; j < 6; ++j)
@@ -9309,7 +9334,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 	mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
 
 	//currently used for amount to extrude frusta corners for constructing shadow frusta
-	LLVector3 n = RenderShadowNearDist;
+	//LLVector3 n = RenderShadowNearDist;
 	//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
 
 	//put together a universal "near clip" plane for shadow frusta
@@ -10414,6 +10439,22 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...)
 	}
 }
 
+void LLPipeline::setAllRenderTypes()
+{
+	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+	{
+		mRenderTypeEnabled[i] = TRUE;
+	}
+}
+
+void LLPipeline::clearAllRenderTypes()
+{
+	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+	{
+		mRenderTypeEnabled[i] = FALSE;
+	}
+}
+
 void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color)
 {
 	DebugBlip blip(position, color);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 36abeca295a25a22ec773a07bebf02f3bfd50e24..a8db93585e66aa8c22ae37f8446e32dcd3629ec0 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -324,20 +324,28 @@ class LLPipeline
 
 	BOOL hasRenderDebugFeatureMask(const U32 mask) const	{ return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }
 	BOOL hasRenderDebugMask(const U32 mask) const			{ return (mRenderDebugMask & mask) ? TRUE : FALSE; }
-	
-
+	void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; }
+	void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; }
+	void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffff; }
+	void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; }
 
 	BOOL hasRenderType(const U32 type) const;
 	BOOL hasAnyRenderType(const U32 type, ...) const;
 
 	void setRenderTypeMask(U32 type, ...);
-	void orRenderTypeMask(U32 type, ...);
+	// This is equivalent to 'setRenderTypeMask'
+	//void orRenderTypeMask(U32 type, ...);
 	void andRenderTypeMask(U32 type, ...);
 	void clearRenderTypeMask(U32 type, ...);
+	void setAllRenderTypes();
+	void clearAllRenderTypes();
 	
 	void pushRenderTypeMask();
 	void popRenderTypeMask();
 
+	void pushRenderDebugFeatureMask();
+	void popRenderDebugFeatureMask();
+
 	static void toggleRenderType(U32 type);
 
 	// For UI control of render features
@@ -634,6 +642,7 @@ class LLPipeline
 
 	U32						mRenderDebugFeatureMask;
 	U32						mRenderDebugMask;
+	std::stack<U32>			mRenderDebugFeatureStack;
 
 	U32						mOldRenderDebugMask;
 	
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index df75f3f697f7fd2adc591037ca33c56d38d4d920..471a896019d86937f4bcb42e7da9f191a64189f9 100644
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
@@ -135,8 +135,8 @@ TOOLNO                  CURSOR                  "llno.cur"
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,1,0
- PRODUCTVERSION 2,1,1,0
+ FILEVERSION 3,4,1,264760
+ PRODUCTVERSION 3,4,1,264760
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -153,12 +153,12 @@ BEGIN
         BEGIN
             VALUE "CompanyName", "Linden Lab"
             VALUE "FileDescription", "Second Life"
-            VALUE "FileVersion", "2.1.1.0"
+            VALUE "FileVersion", "3.4.1.264760"
             VALUE "InternalName", "Second Life"
             VALUE "LegalCopyright", "Copyright � 2001-2010, Linden Research, Inc."
             VALUE "OriginalFilename", "SecondLife.exe"
             VALUE "ProductName", "Second Life"
-            VALUE "ProductVersion", "2.1.1.0"
+            VALUE "ProductVersion", "3.4.1.264760"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 93c9cb02cb0e769c15c94a1b634c4193c2249530..fcab966dee78df48b26057a4b3457de3a6dc4ad8 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -724,9 +724,6 @@ with the same filename but different name
   <texture name="icon_for_sale.tga" file_name="icons/Icon_For_Sale.png" />
   <texture name="icon_top_pick.tga" />
 
-  <texture name="inv_folder_mesh.tga"/>
-  <texture name="inv_item_mesh.tga"/>
-
   <texture name="lag_status_critical.tga" />
   <texture name="lag_status_good.tga" />
   <texture name="lag_status_warning.tga" />
diff --git a/indra/newview/skins/default/xui/en/floater_im_session.xml b/indra/newview/skins/default/xui/en/floater_im_session.xml
index 3b56e974d21dadbc2a70b0fe17a82b9742b73071..2152a9f6e9acc944660c5ef7b3c1ae95d010e90c 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -70,23 +70,26 @@
      top="0"
      left="0"
      right="-1"
-     bottom="-1">
+     bottom="-3">
         <layout_stack
          animate="false" 
          default_tab_group="2"
          follows="all"
          right="-5"
          bottom="-1"
+         top="0"
+         left="5"
+         border_size="0"
          layout="topleft"
          orientation="vertical"
          name="main_stack"
-         tab_group="1"
-         top="0"
-         left="5">
+         tab_group="1">
             <layout_panel
              auto_resize="false"
              name="toolbar_panel"
-             height="35">
+             height="35"
+             right="-1"
+             left="1">
                 <menu_button
                  menu_filename="menu_im_session_showmodes.xml"
                  follows="top|left"
@@ -164,7 +167,7 @@
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
                  top="5"
-                 right="-70"
+                 right="-67"
                  name="close_btn"
                  tool_tip="End this conversation"
                  width="31" />
@@ -196,7 +199,8 @@
             </layout_panel>
             <layout_panel
              name="body_panel"
-             height="235">
+             top="1"
+             bottom="-1">
                 <layout_stack
                  default_tab_group="2"
                  follows="all"
@@ -213,12 +217,14 @@
                      min_dim="0"
                      width="150" 
                      user_resize="true"
-                     auto_resize="false" />
+                     auto_resize="false" 
+                     bottom="-1" />
                     <layout_panel
                      default_tab_group="3"
                      tab_group="2"
                      name="right_part_holder"
-                     min_width="221">
+                     min_width="221"
+                     bottom="-1">
                         <layout_stack
                          animate="true" 
                          default_tab_group="2"
@@ -262,21 +268,28 @@
                 </layout_stack>
             </layout_panel>
             <layout_panel
-             height="35"
+             top_delta="0"
+             top="0"
+             height="26"
+             bottom="-1"
              auto_resize="false"
              name="chat_layout_panel">
                 <layout_stack
                  animate="false"
                  default_tab_group="2"
                  follows="all"
-                 right="-1"
                  orientation="horizontal"
                  name="input_panels"
                  top="0"
-                 bottom="-1"
-                 left="0">
+                 bottom="-2"
+                 left="0"
+                 right="-1">
                     <layout_panel
-                     name="input_editor_layout_panel">
+                     name="input_editor_layout_panel"
+                     auto_resize="true"
+                     user_resize="false"
+                     top="0"
+                     bottom="-1">
                         <chat_editor
                          layout="topleft"
                          expand_lines_count="5"
@@ -289,27 +302,32 @@
                          max_length="1023"
                          spellcheck="true"
                          tab_group="3"
-                         bottom="-8"
-                         left="5"
-                         right="-5"
+                         top="1"
+                         bottom="-2"
+                         left="4"
+                         right="-4"
                          wrap="true" />
                     </layout_panel>
                     <layout_panel
                      auto_resize="false"
+                     user_resize="false"
                      name="input_button_layout_panel"
-                     width="32">
+                     width="30"
+                     top="0"
+                     bottom="-1">
                         <button
+                         layout="topleft"
                          left="1"
-                         top="4"
+                         right="-1"
+                         top="1"
+                         height="22"
                          follows="left|right|top"
-                         height="25"
                          image_hover_unselected="Toolbar_Middle_Over"
                          image_overlay="Conv_expand_one_line"
                          image_selected="Toolbar_Middle_Selected"
                          image_unselected="Toolbar_Middle_Off"
                          name="minz_btn"
-                         tool_tip="Shows/hides message panel"
-                         width="28" />
+                         tool_tip="Shows/hides message panel" />
                     </layout_panel>
                 </layout_stack>
             </layout_panel>
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index b46b62ec4d18e69f5a174b883953467977d8fd87..46ba4bd29d2786bf2c0ac1f7835dffb4765eac06 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -79,6 +79,14 @@
             <menu_item_call.on_visible
              function="IsGodCustomerService"/>
         </menu_item_call>
+    <menu_item_call
+		 label="Dump XML"
+         name="Dump XML">
+            <menu_item_call.on_click
+             function="Advanced.AppearanceToXML" />
+            <menu_item_call.on_visible
+             function="Advanced.EnableAppearanceToXML"/>
+    </menu_item_call>
 	    <menu_item_call
          label="Zoom In"
           name="Zoom In">
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index b8128da358631e2885fae37b4ebd0d72ba49eb66..28e032ce5f0e4f90c4eaf1c016efbb3d9003bfce 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -123,6 +123,14 @@ name="Edit Outfit">
     <menu_item_call.on_visible
      function="IsGodCustomerService"/>
   </menu_item_call>
+    <menu_item_call
+		 label="Dump XML"
+         name="Dump XML">
+            <menu_item_call.on_click
+             function="Advanced.AppearanceToXML" />
+            <menu_item_call.on_visible
+             function="Advanced.EnableAppearanceToXML"/>
+    </menu_item_call>
   <menu_item_separator
   layout="topleft" />
   <menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
index 276b5f106f785799b6b829be611030b47b3e65c3..e7c2b80da27f45f8b69c8297352885aab5d5a87c 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -79,6 +79,14 @@
             <menu_item_call.on_visible
              function="IsGodCustomerService"/>
         </menu_item_call>
+    <menu_item_call
+		 label="Dump XML"
+         name="Dump XML">
+            <menu_item_call.on_click
+             function="Advanced.AppearanceToXML" />
+            <menu_item_call.on_visible
+             function="Advanced.EnableAppearanceToXML"/>
+    </menu_item_call>
 	    <menu_item_call
          label="Zoom In"
           name="Zoom In">
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
index d9bdfece383b82c4f4188628694e1e0275c71a2e..c1ff026a74e51fb856db513c20fe177cc6882d12 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -261,4 +261,12 @@
             <menu_item_call.on_visible
              function="IsGodCustomerService"/>
     </menu_item_call>
+    <menu_item_call
+		 label="Dump XML"
+         name="Dump XML">
+            <menu_item_call.on_click
+             function="Advanced.AppearanceToXML" />
+            <menu_item_call.on_visible
+             function="Advanced.EnableAppearanceToXML"/>
+    </menu_item_call>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 101e104eabfd499389bd5149f71dea1badf0d30c..52c4fb1613f135181fcc5f8910d26c1938a58531 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -180,7 +180,8 @@
        name="Set Logging Level"
        tear_off="true">
         <menu_item_check
-          label="Debug">
+         name="Debug"
+         label="Debug">
           <menu_item_check.on_check
             function="Develop.CheckLoggingLevel"
             parameter="0" />
@@ -189,7 +190,8 @@
            parameter="0" />
         </menu_item_check>
         <menu_item_check
-          label="Info">
+         name="Info"
+         label="Info">
           <menu_item_check.on_check
             function="Develop.CheckLoggingLevel"
             parameter="1" />
@@ -198,7 +200,8 @@
            parameter="1" />
         </menu_item_check>
         <menu_item_check
-          label="Warning">
+         name="Warning"
+         label="Warning">
           <menu_item_check.on_check
             function="Develop.CheckLoggingLevel"
             parameter="2" />
@@ -207,7 +210,8 @@
            parameter="2" />
         </menu_item_check>
         <menu_item_check
-          label="Error">
+         name="Error"
+         label="Error">
           <menu_item_check.on_check
             function="Develop.CheckLoggingLevel"
             parameter="3" />
@@ -216,7 +220,8 @@
            parameter="3" />
         </menu_item_check>
         <menu_item_check
-          label="None">
+         name="None"
+         label="None">
           <menu_item_check.on_check
             function="Develop.CheckLoggingLevel"
             parameter="4" />
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index 544f06ac0c4a2d2bb85c09bcbe00a5af26403ac7..a11cd13fdbb5c9c0436cad7af6524e467e5f47cc 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -131,6 +131,7 @@
        name="Status"
        tear_off="true">
         <menu_item_check
+         name="Away"
          label="Away">
           <menu_item_check.on_check
            function="View.Status.CheckAway" />
@@ -138,6 +139,7 @@
            function="World.SetAway" />
         </menu_item_check>
         <menu_item_check
+         name="Do Not Disturb"
          label="Do Not Disturb">
           <menu_item_check.on_check
            function="View.Status.CheckDoNotDisturb" />
@@ -257,6 +259,7 @@
              parameter="speak" />
         </menu_item_check>
         <menu_item_check
+         name="Conversation Log..."
          label="Conversation Log...">
             <menu_item_check.on_check
              function="Floater.Visible"
@@ -352,6 +355,7 @@
         </menu_item_call>
       <menu_item_separator/>
       <menu_item_check
+       name="Do Not Disturb"
        label="Do Not Disturb">
         <menu_item_check.on_check
          function="View.Status.CheckDoNotDisturb" />
@@ -3051,13 +3055,6 @@
                 <menu_item_call.on_click
                  function="Advanced.PrintAgentInfo" />
             </menu_item_call>
-            <menu_item_call
-             label="Memory Stats"
-             name="Memory Stats"
-             shortcut="control|alt|shift|M">
-                <menu_item_call.on_click
-                 function="Advanced.PrintTextureMemoryStats" />
-            </menu_item_call>
             <menu_item_check
              label="Region Debug Console"
              name="Region Debug Console"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 5aa743b32d22c1769e0eae25f1e30109f12de699..7c08aef65e3ac9ef5f3c2d5f44a392c81d65df50 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2987,6 +2987,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
 <string name="Higher">Higher</string>
 <string name="Hip Length">Hip Length</string>
 <string name="Hip Width">Hip Width</string>
+<string name="Hover">Hover</string>
 <string name="In">In</string>
 <string name="In Shdw Color">Inner Shadow Color</string>
 <string name="In Shdw Opacity">Inner Shadow Opacity</string>
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 0254c5881f76c8bfba620aaab54b80575774e05e..41cb344808371cf9dc9c87fe31c28b7f09a9782d 100644
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -126,7 +126,9 @@ void LLHTTPClient::post(
 	result[LLTextureEntry::OBJECT_ID_KEY] = body[LLTextureEntry::OBJECT_ID_KEY];
 	if ( url == FAKE_OBJECT_MEDIA_CAP_URL_503 )
 	{
-		responder->error(HTTP_SERVICE_UNAVAILABLE, "fake reason");
+		LLSD content;
+		content["reason"] = "fake reason";
+		responder->errorWithContent(HTTP_SERVICE_UNAVAILABLE, "fake reason", content);
 		return;
 	}
 	else if (url == FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR) 
diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp
old mode 100644
new mode 100755
index f8923b986814dcd4c80692859e06b6a08d6d7f34..a331d9aa9e5bde8f3582527ef761495fb3b0d3b4
--- a/indra/newview/tests/llviewerassetstats_test.cpp
+++ b/indra/newview/tests/llviewerassetstats_test.cpp
@@ -37,30 +37,6 @@
 #include "llregionhandle.h"
 #include "../llvoavatar.h"
 
-void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts)
-{
-	counts.resize(3);
-	counts[0] = 0;
-	counts[1] = 0;
-	counts[2] = 1;
-}
-
-// static
-std::string LLVOAvatar::rezStatusToString(S32 rez_status)
-{
-	if (rez_status==0) return "cloud";
-	if (rez_status==1) return "gray";
-	if (rez_status==2) return "textured";
-	return "unknown";
-}
-
-// static
-LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)
-{
-	static LLViewerStats::StatsAccumulator junk;
-	return junk;
-}
-
 static const char * all_keys[] = 
 {
 	"duration",
@@ -123,31 +99,34 @@ is_empty_map(const LLSD & sd)
 {
 	return sd.isMap() && 0 == sd.size();
 }
+#endif
 
+#if 0
 static bool
 is_single_key_map(const LLSD & sd, const std::string & key)
 {
 	return sd.isMap() && 1 == sd.size() && sd.has(key);
 }
+#endif
 
 static bool
 is_double_key_map(const LLSD & sd, const std::string & key1, const std::string & key2)
 {
 	return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2);
 }
-#endif
 
+#if 0
 static bool
 is_triple_key_map(const LLSD & sd, const std::string & key1, const std::string & key2, const std::string& key3)
 {
 	return sd.isMap() && 3 == sd.size() && sd.has(key1) && sd.has(key2) && sd.has(key3);
 }
-
+#endif
 
 static bool
 is_no_stats_map(const LLSD & sd)
 {
-	return is_triple_key_map(sd, "duration", "regions", "avatar");
+	return is_double_key_map(sd, "duration", "regions");
 }
 
 static bool
@@ -258,7 +237,7 @@ namespace tut
 		// Once the region is set, we will get a response even with no data collection
 		it->setRegion(region1_handle);
 		sd_full = it->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd_full, "duration", "regions", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd_full, "duration", "regions"));
 		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd_full["regions"], region1_handle));
 		
 		LLSD sd = sd_full["regions"][0];
@@ -299,7 +278,7 @@ namespace tut
 		it->setRegion(region1_handle);
 		
 		LLSD sd = it->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
 		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
 		sd = sd[0];
 		
@@ -324,7 +303,7 @@ namespace tut
 		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
 
 		LLSD sd = gViewerAssetStatsMain->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
 		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
 		sd = sd["regions"][0];
 		
@@ -364,7 +343,7 @@ namespace tut
 		LLSD sd = gViewerAssetStatsThread1->asLLSD(false);
 		ensure("Other collector is empty", is_no_stats_map(sd));
 		sd = gViewerAssetStatsMain->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
 		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
 		sd = sd["regions"][0];
 		
@@ -414,7 +393,7 @@ namespace tut
 
 		// std::cout << sd << std::endl;
 		
-		ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));
+		ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
 		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));
 		LLSD sd1 = get_region(sd, region1_handle);
 		LLSD sd2 = get_region(sd, region2_handle);
@@ -437,7 +416,7 @@ namespace tut
 		// Reset leaves current region in place
 		gViewerAssetStatsMain->reset();
 		sd = gViewerAssetStatsMain->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
 		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
 		sd2 = sd["regions"][0];
 		
@@ -486,7 +465,7 @@ namespace tut
 
 		LLSD sd = gViewerAssetStatsMain->asLLSD(false);
 
-		ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));
+		ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
 		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));
 		LLSD sd1 = get_region(sd, region1_handle);
 		LLSD sd2 = get_region(sd, region2_handle);
@@ -509,7 +488,7 @@ namespace tut
 		// Reset leaves current region in place
 		gViewerAssetStatsMain->reset();
 		sd = gViewerAssetStatsMain->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
 		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
 		sd2 = get_region(sd, region2_handle);
 		ensure("Region2 is present in results", sd2.isMap());
@@ -555,7 +534,7 @@ namespace tut
 		LLSD sd = gViewerAssetStatsThread1->asLLSD(false);
 		ensure("Other collector is empty", is_no_stats_map(sd));
 		sd = gViewerAssetStatsMain->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
 		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
 		sd = get_region(sd, region1_handle);
 		ensure("Region1 is present in results", sd.isMap());
diff --git a/indra/newview/tests/llviewertexture_stub.cpp b/indra/newview/tests/llviewertexture_stub.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..889ab9bea559dcb7aef6e4e2db769daab6530129
--- /dev/null
+++ b/indra/newview/tests/llviewertexture_stub.cpp
@@ -0,0 +1,34 @@
+/** 
+ * @file llviewertexture_stub.cpp
+ * @brief  stub class to allow unit testing
+ *
+ * $LicenseInfo:firstyear=2012&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$
+ */
+
+#include "linden_common.h"
+#include "../llviewertexture.h"
+#include "../../llrender/llgltexture.h"
+
+void LLViewerTexture::setBoostLevel(int level)
+{
+}
+
diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp
index acc6e814bc7a196d1f071cc6c79d4a15b9f68123..84194adb5df409a78544dd0d8f70ac6de4878910 100644
--- a/indra/newview/tests/llworldmap_test.cpp
+++ b/indra/newview/tests/llworldmap_test.cpp
@@ -47,9 +47,9 @@
 // * A simulator for a class can be implemented here. Please comment and document thoroughly.
 
 // Stub image calls
-void LLViewerTexture::setBoostLevel(S32 ) { }
-void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode ) { }
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID&, BOOL, LLViewerTexture::EBoostLevel, S8,
+void LLGLTexture::setBoostLevel(S32 ) { }
+void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode ) { }
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID&, FTType, BOOL, LLGLTexture::EBoostLevel, S8,
 																  LLGLint, LLGLenum, LLHost ) { return NULL; }
 
 // Stub related map calls
diff --git a/indra/newview/tests/llworldmipmap_test.cpp b/indra/newview/tests/llworldmipmap_test.cpp
index e7ef0177608558651de83f6fa2d27a8d05dbf6c7..142d75bcfd523689f275f60091377f13c6e164a0 100644
--- a/indra/newview/tests/llworldmipmap_test.cpp
+++ b/indra/newview/tests/llworldmipmap_test.cpp
@@ -42,8 +42,8 @@
 // * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
 // * A simulator for a class can be implemented here. Please comment and document thoroughly.
 
-void LLViewerTexture::setBoostLevel(S32 ) { }
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string&, BOOL, LLViewerTexture::EBoostLevel, S8, 
+void LLGLTexture::setBoostLevel(S32 ) { }
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string&, FTType, BOOL, LLGLTexture::EBoostLevel, S8, 
 																		 LLGLint, LLGLenum, const LLUUID& ) { return NULL; }
 
 LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) { }
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index e7108141ee84fca85c4d6aad80ff770a1906536f..69248e26bcbc4a663cc29573f1d3e52cf62729b5 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1081,7 +1081,7 @@ def construct(self):
             self.path("libcrypto.so.*")
             self.path("libexpat.so.*")
             self.path("libssl.so.1.0.0")
-            self.path("libglod.so")
+            self.path("libGLOD.so")
             self.path("libminizip.so")
             self.path("libuuid.so*")
             self.path("libSDL-1.2.so.*")
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index 816f1d7175ebd177c5b3efe114d1bfef9af0d8b0..31e1d89c6839757246ae08e60b6472089281ea8f 100644
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -28,6 +28,10 @@ include_directories(
     ${GOOGLEMOCK_INCLUDE_DIRS}
     ${TUT_INCLUDE_DIR}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(test_SOURCE_FILES
     io.cpp
diff --git a/indra/test/io.cpp b/indra/test/io.cpp
index ce747f667d2d53e0ed78b4d1640b5432877309cd..47a67deed00c80957fbfdc0136cbfe8417125581 100644
--- a/indra/test/io.cpp
+++ b/indra/test/io.cpp
@@ -1140,7 +1140,7 @@ namespace tut
 		bool connected = client->blockingConnect(server_host);
 		ensure("Connected to server", connected);
 		lldebugs << "connected" << llendl;
-		F32 elapsed = pump_loop(mPump,0.1f);
+		pump_loop(mPump,0.1f);
 		count = mPump->runningChains();
 		ensure_equals("server chain onboard", count, 2);
 		lldebugs << "** Client is connected." << llendl;
@@ -1156,20 +1156,20 @@ namespace tut
 		chain.clear();
 
 		// pump for a bit and make sure all 3 chains are running
-		elapsed = pump_loop(mPump,0.1f);
+		pump_loop(mPump,0.1f);
 		count = mPump->runningChains();
 		ensure_equals("client chain onboard", count, 3);
 		lldebugs << "** request should have been sent." << llendl;
 
 		// pump for long enough the the client socket closes, and the
 		// server socket should not be closed yet.
-		elapsed = pump_loop(mPump,0.2f);
+		pump_loop(mPump,0.2f);
 		count = mPump->runningChains();
 		ensure_equals("client chain timed out ", count, 2);
 		lldebugs << "** client chain should be closed." << llendl;
 
 		// At this point, the socket should be closed by the timeout
-		elapsed = pump_loop(mPump,1.0f);
+		pump_loop(mPump,1.0f);
 		count = mPump->runningChains();
 		ensure_equals("accepted socked close", count, 1);
 		lldebugs << "** Sleeper should have timed out.." << llendl;
diff --git a/indra/test/llpermissions_tut.cpp b/indra/test/llpermissions_tut.cpp
index bf6766424c60264fe999ca7d4d2cf18c9bc663fb..bc2c87ba46db351af3f15daf5f7cc1548d476330 100644
--- a/indra/test/llpermissions_tut.cpp
+++ b/indra/test/llpermissions_tut.cpp
@@ -407,7 +407,7 @@ namespace tut
 		LLFILE* fp = LLFile::fopen("linden_file.dat","w+");
 		if(!fp)
 		{
-			llerrs << "file coudnt be opened\n" << llendl;
+			llerrs << "file couldn't be opened\n" << llendl;
 			return;
 		}
 		LLPermissions perm,perm1;
@@ -425,15 +425,15 @@ namespace tut
 
 		perm.initMasks(base, ownerp, everyone, groupp, next);
 
-		perm.exportFile(fp);
+		ensure("Permissions export failed", perm.exportFile(fp));
 		fclose(fp);	
 		fp = LLFile::fopen("linden_file.dat","r+");
 		if(!fp)
 		{
-			llerrs << "file coudnt be opened\n" << llendl;
+			llerrs << "file couldn't be opened\n" << llendl;
 			return;
 		}
-		perm1.importFile(fp);
+		ensure("Permissions import failed", perm1.importFile(fp));
 		fclose(fp);
 		ensure_equals("exportFile()/importFile():failed to export and import the data ", perm1, perm);	
 }
@@ -461,7 +461,7 @@ namespace tut
 		std::istringstream istream(ostream.str());
 		perm1.importLegacyStream(istream);
 
-		ensure_equals("exportLegacyStream()/importLegacyStream():failed to export and import the data ", perm1, perm);
+		ensure_equals("exportStream()/importStream():failed to export and import the data ", perm1, perm);
 	}
 
 	template<> template<>
diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/test/llsaleinfo_tut.cpp
index 09fca2abbab19013063aaf558fd511c6f861f680..2689eaa15e5f0088e72e9918ae5adf75a78a25ae 100644
--- a/indra/test/llsaleinfo_tut.cpp
+++ b/indra/test/llsaleinfo_tut.cpp
@@ -154,8 +154,9 @@ namespace tut
 		BOOL has_perm_mask = FALSE;
 		llsaleinfo1.importLegacyStream(istream, has_perm_mask, perm_mask);
 					
-		ensure("importLegacyStream() fn failed ", llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() &&
-										       llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());		
+		ensure("importStream() fn failed ",
+			llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() &&
+			llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());
 	}
 
 	template<> template<>
diff --git a/indra/test/llstreamtools_tut.cpp b/indra/test/llstreamtools_tut.cpp
index a93f2e8f65e992001e06fadb88383cdd20c522bb..0f6436f0f4a8b51e5d517ff85d2840c4895126da 100644
--- a/indra/test/llstreamtools_tut.cpp
+++ b/indra/test/llstreamtools_tut.cpp
@@ -385,16 +385,15 @@ namespace tut
 		std::string expected_result;
 		std::string actual_result;
 		std::istringstream is;
-		bool ret;
 
 		is.clear();
 		is.str(str = "  First Second \t \r  \n Third  Fourth-ShouldThisBePartOfFourth  Fifth\n");
 		actual_result = "";
-		ret = get_word(actual_result, is); // First
+		get_word(actual_result, is); // First
 		actual_result = "";
-		ret = get_word(actual_result, is); // Second
+		get_word(actual_result, is); // Second
 		actual_result = "";
-		ret = get_word(actual_result, is); // Third
+		get_word(actual_result, is); // Third
 
 		// the current implementation of get_word seems inconsistent with
 		// skip_to_next_word. skip_to_next_word treats any character other
@@ -403,22 +402,22 @@ namespace tut
 		// carriage  return ('\r'), horizontal tab ('\t'), and vertical tab ('\v')
 		// as delimiters 
 		actual_result = "";
-		ret = get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth
+		get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth
 
 		actual_result = "";
-		ret = get_word(actual_result, is); // will copy Fifth
+		get_word(actual_result, is); // will copy Fifth
 
 		is.clear();
 		is.str(str = "  First Second \t \r  \n Third  Fourth_ShouldThisBePartOfFourth Fifth\n");
-		ret = skip_to_next_word(is);  // should now point to First
-		ret = skip_to_next_word(is);  // should now point to Second
-		ret = skip_to_next_word(is);  // should now point to Third
-		ret = skip_to_next_word(is);  // should now point to Fourth
-		ret = skip_to_next_word(is);  // should now point to ShouldThisBePartOfFourth
+		skip_to_next_word(is);  // should now point to First
+		skip_to_next_word(is);  // should now point to Second
+		skip_to_next_word(is);  // should now point to Third
+		skip_to_next_word(is);  // should now point to Fourth
+		skip_to_next_word(is);  // should now point to ShouldThisBePartOfFourth
 		expected_result = "";
 		// will copy ShouldThisBePartOfFourth, the fifth word, 
 		// while using get_word above five times result in getting "Fifth"
-		ret = get_word(expected_result, is); 
+		get_word(expected_result, is); 
 		ensure_equals("get_word: skip_to_next_word compatibility", actual_result, expected_result);
 	}
 
@@ -480,39 +479,38 @@ namespace tut
 		std::string expected_result;
 		std::string actual_result;
 		std::istringstream is;
-		bool ret;
 
 		is.clear();
 		is.str(str = "First Second \t \r\n Third  Fourth-ShouldThisBePartOfFourth  IsThisFifth\n");
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "First Second \t \r\n";
 		ensure_equals("get_line: 1", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = " Third  Fourth-ShouldThisBePartOfFourth  IsThisFifth\n";
 		ensure_equals("get_line: 2", actual_result, expected_result);
 
 		is.clear();
 		is.str(str = "\nFirst Line.\n\nSecond Line.\n");
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "\n";
 		ensure_equals("get_line: First char as newline", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "First Line.\n";
 		ensure_equals("get_line: 3", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "\n";
 		ensure_equals("get_line: 4", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "Second Line.\n";
 		ensure_equals("get_line: 5", actual_result, expected_result);
 	}	
@@ -544,13 +542,12 @@ namespace tut
 		std::string expected_result;
 		std::string actual_result;
 		std::istringstream is;
-		bool ret;
 
 		// need to be check if this test case is wrong or the implementation is wrong.
 		is.clear();
 		is.str(str = "Should not skip lone \r.\r\n");
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "Should not skip lone \r.\r\n";
 		ensure_equals("get_line: carriage return skipped even though not followed by newline", actual_result, expected_result);
 	}
@@ -563,12 +560,11 @@ namespace tut
 		std::string expected_result;
 		std::string actual_result;
 		std::istringstream is;
-		bool ret;
 
 		is.clear();
 		is.str(str = "\n");
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "\n";
 		ensure_equals("get_line: Just newline", actual_result, expected_result);
 	}
@@ -582,36 +578,35 @@ namespace tut
 		std::string expected_result;
 		std::string actual_result;
 		std::istringstream is;
-		bool ret;
 
 		is.clear();
 		is.str(str = "First Line.\nSecond Line.\n");
 		actual_result = "";
-		ret = get_line(actual_result, is, 255);
+		get_line(actual_result, is, 255);
 		expected_result = "First Line.\n";
 		ensure_equals("get_line: Basic Operation", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is, sizeof("Second")-1);
+		get_line(actual_result, is, sizeof("Second")-1);
 		expected_result = "Second\n";
 		ensure_equals("get_line: Insufficient length 1", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is, 255);
+		get_line(actual_result, is, 255);
 		expected_result = " Line.\n";
 		ensure_equals("get_line: Remainder after earlier insufficient length", actual_result, expected_result);
 
 		is.clear();
 		is.str(str = "One Line only with no newline with limited length");
 		actual_result = "";
-		ret = get_line(actual_result, is, sizeof("One Line only with no newline with limited length")-1);
+		get_line(actual_result, is, sizeof("One Line only with no newline with limited length")-1);
 		expected_result = "One Line only with no newline with limited length\n";
 		ensure_equals("get_line: No newline with limited length", actual_result, expected_result);
 
 		is.clear();
 		is.str(str = "One Line only with no newline");
 		actual_result = "";
-		ret = get_line(actual_result, is, 255);
+		get_line(actual_result, is, 255);
 		expected_result = "One Line only with no newline";
 		ensure_equals("get_line: No newline", actual_result, expected_result);
 	}
diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/test/lltemplatemessagebuilder_tut.cpp
index 6e1c82bb2464949a99ef34854bade4aa8df3d25e..6c0b70edd2e15690186dfd30af42fefa7d02b0ac 100644
--- a/indra/test/lltemplatemessagebuilder_tut.cpp
+++ b/indra/test/lltemplatemessagebuilder_tut.cpp
@@ -937,7 +937,7 @@ namespace tut
 		// build message with single block
 		LLMessageTemplate messageTemplate = defaultTemplate();
 		messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
-		U32 outValue, outValue2, inValue = 0xbbbbbbbb;
+		U32 outValue, inValue = 0xbbbbbbbb;
 		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
 		builder->addU32(_PREHASH_Test0, inValue);
 		const U32 bufferSize = 1024;
@@ -962,7 +962,6 @@ namespace tut
 		memset(buffer, 0xcc, bufferSize);
 		reader->getString(_PREHASH_Test1, _PREHASH_Test0, bufferSize, 
 						  outBuffer);
-		outValue2 = reader->getNumberOfBlocks(_PREHASH_Test1);
 		ensure_equals("Ensure present value ", outValue, inValue);
 		ensure_equals("Ensure unchanged buffer ", strlen(outBuffer), 0);
 		delete reader;
diff --git a/indra/test_apps/llplugintest/CMakeLists.txt b/indra/test_apps/llplugintest/CMakeLists.txt
index 1211bb7e5a35bb1724bd52c7de0b5c5f117138bf..8179be66f51ce194e1433c6735391a5af1ef68ee 100644
--- a/indra/test_apps/llplugintest/CMakeLists.txt
+++ b/indra/test_apps/llplugintest/CMakeLists.txt
@@ -2,7 +2,7 @@
 project(llplugintest)
 
 include(00-Common)
-include(FindOpenGL)
+include(OpenGL)
 include(LLCommon)
 include(LLPlugin)
 include(Linking)
@@ -25,6 +25,9 @@ include_directories(
     ${LLRENDER_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 if (DARWIN)
     include(CMakeFindFrameworks)
diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt
index 7720619df3017a718a3ba393f086fbb67d8db768..658f167c2e2802e7c4318d012003e1e8cd309aaa 100644
--- a/indra/viewer_components/login/CMakeLists.txt
+++ b/indra/viewer_components/login/CMakeLists.txt
@@ -15,6 +15,10 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(login_SOURCE_FILES
     lllogin.cpp
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index ef82290b4719d9213f25722d007d01d17890c118..de7e3363414a937f2d8ed05285bf8dfae33809fa 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -20,6 +20,9 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${CURL_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(updater_service_SOURCE_FILES
     llupdaterservice.cpp
diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt
index 5329c89554298df4d4ea21d319b7b13332508b0c..aa35c3b05ea885aa6a13abc02cde879a21c28a3f 100644
--- a/indra/win_crash_logger/CMakeLists.txt
+++ b/indra/win_crash_logger/CMakeLists.txt
@@ -21,6 +21,10 @@ include_directories(
     ${LLXML_INCLUDE_DIRS}
     ${LLVFS_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(win_crash_logger_SOURCE_FILES
     win_crash_logger.cpp
diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg
index 2cb0a833d4cfd94a926b7f4477be4b4a20cb8059..6702de9b4a7a98eea4dbb7d2ddea0b8c1a6574e7 100644
--- a/scripts/messages/message_template.msg
+++ b/scripts/messages/message_template.msg
@@ -2939,6 +2939,10 @@ version 2.0
 		PidStat Single
 		{	PID					S32				}
 	}
+	{
+		RegionInfo Variable
+		{	RegionFlagsExtended	U64				}
+	}
 }
 
 // viewer -> sim
@@ -2991,6 +2995,10 @@ version 2.0
 		{	HardMaxAgents		U32			}
 		{	HardMaxObjects		U32			}
 	}
+	{
+		RegionInfo3		Variable
+		{	RegionFlagsExtended	U64			}
+	}
 }
 
 // GodUpdateRegionInfo
@@ -3016,6 +3024,10 @@ version 2.0
 		{	RedirectGridX 		S32			}
 		{	RedirectGridY 		S32			}
 	}
+	{
+		RegionInfo2	Variable
+		{	RegionFlagsExtended	U64			}
+	}
 }
 
 //NearestLandingRegionRequest
@@ -3116,6 +3128,11 @@ version 2.0
 		{	ProductSKU				Variable	1	}	// string
 		{	ProductName				Variable	1	}	// string
 	}
+	{
+		RegionInfo4		Variable
+		{	RegionFlagsExtended	U64			}
+		{	RegionProtocols		U64			}
+	}
 }
 
 // RegionHandshakeReply
@@ -3571,6 +3588,12 @@ version 2.0
 		VisualParam			Variable
 		{	ParamValue		U8	}
 	}
+	{
+		AppearanceData		Variable
+		{	AppearanceVersion	U8	}
+		{	CofVersion			S32	}
+		{	Flags				U32	}
+	}
 }
 
 // AvatarSitResponse - response to a request to sit on an object
diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1
index 6486d92851a7590ef7ba205c7a40390290562e82..7a31177f118ecd39a32866c51b3664e62e8affe6 100644
--- a/scripts/messages/message_template.msg.sha1
+++ b/scripts/messages/message_template.msg.sha1
@@ -1 +1 @@
-465164e1a07f63d68c4ad1f00c19805dfb6ee2d7
\ No newline at end of file
+4dbf88396c3188ad4c54c4f847a7d8817793668d
\ No newline at end of file